// executed when the menu command is clicked void MenuItemCallback(object sender, EventArgs e) { if (!csRange.HasValue) { return; } var range = csRange.Value; // get the text in the range var text = VsUtils.GetTextForTextView(VsUtils.GetActiveTextView(), range.topLine, range.topCol, range.bottomLine, range.bottomCol); // default values resource file var resFile = Resourcer.GetResourcePath(Resourcer.GetStringsResName()); string normalized = Strings.Normalize(text); bool resourceExisted = StringsXMLEditor.ContainsValue(resFile, normalized); var result = resourceExisted ? // if a key with this value already exists, use it new KeyValuePair <string, string>(StringsXMLEditor.GetKeyByValue(resFile, normalized), normalized) : // else, prompt a new dialog asking for a key ExtractStringCmdForm.PromptDialog(resFile, normalized); // if the result has value, replace the string with the method call if (result.HasValue) // replace the old string with the new method call { ((TextDocument)VsUtils.GetDTE().ActiveDocument.Object()) .ReplacePattern(text, Resourcer.AddString( result.Value, VsUtils.GetActiveDocumentLanguage() == LANGUAGE_XAML, resourceExisted)); } }
// update the translations grid so the user can manage the strings void updateTranslationsList() { usingLocale = Resourcer.ExistsLocale(localeCB.Text); if (lastWasNoLocale && !usingLocale) { return; // don't update everything if nothing changed } lastWasNoLocale = !usingLocale; // current locale string locale = usingLocale ? localeCB.Text : null; // current locale strings Dictionary <string, string> localeDict = usingLocale ? Resourcer.GetStrings(locale) : null; StringResources = new List <StringResource>(); foreach (var kvp in Resourcer.GetStrings()) { if (usingLocale) // if we're using a locale, add locale values too { string localeValue; if (localeDict.TryGetValue(kvp.Key, out localeValue)) { StringResources.Add(new StringResource( kvp.Key, kvp.Value, locale, localeValue)); } else { StringResources.Add(new StringResource( kvp.Key, kvp.Value, locale, string.Empty)); } } else // only add string resources { StringResources.Add(new StringResource(kvp.Key, kvp.Value)); } } // update the source updateSource(); // make sure to set the translation column (in)visible if required if (stringsResDGV.Columns.Count >= 2) { stringsResDGV.Columns[2].Visible = usingLocale; } checkTranslationBoxes(false); }
// add all the .xaml dictionaries to the App.xaml resources public static void EnsureAppXaml(Project project = null) { try { if (project == null) { project = VsUtils.GetCurrentProject(); } var appXaml = VsUtils.GetFullPath(project, "App.xaml"); if (string.IsNullOrEmpty(appXaml)) { return; // should never happen... } var doc = XDocument.Load(appXaml); var appResources = getNode(doc.Root, "Application.Resources"); var resDictionary = getNode(appResources, "ResourceDictionary"); var mergedDictionaries = getNode(resDictionary, "ResourceDictionary.MergedDictionaries"); var resFolder = Resourcer.GetResourcesFolderPath(); if (Directory.Exists(resFolder)) { // clear all resources mergedDictionaries.RemoveAll(); // add them again foreach (var file in VsUtils.GetProjectItemsInFolder(project, resFolder)) { // perhaps it's not a dictionary (.xaml) file if (!file.Name.EndsWith(".xaml")) { continue; } // perhaps it is a folder if (!File.Exists(file.Properties.Item("FullPath").Value.ToString())) { continue; } mergedDictionaries.Add(new XElement( mergedDictionaries.Name.Namespace + "ResourceDictionary", new XAttribute("Source", Settings.ResourcesFolderName + "/" + file.Name) )); } } StringsXMLEditor.SaveDocument(doc, appXaml); } catch { /* nobody likes errors (which shouldn't happen) :( */ } }
void delTranslationLL_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { if (Resourcer.ExistsLocale(localeCB.Text)) { if (MessageBox.Show($"The {localeCB.Text} locale will be lost forever. Are you sure you want to continue?", $"{localeCB.Text} will be lost", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes) { // delete the strings resources file and reload the locales Resourcer.DeleteStrings(localeCB.Text); statusCSL.SetStatus($"The locale {localeCB.Text} have been deleted from disk"); loadLocales(); } } }
void addTranslationLL_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { var result = InputTextBox.Show("Enter the locale code you wish to use for your new translation", "Enter locale code", "es-ES", 5); if (string.IsNullOrEmpty(result)) { statusCSL.SetWarn("Adding locale operation cancelled"); } else // if the result is not null, add it { addTranslation(Resourcer.GetStringsResName(result)); } }
// ensure the strings.xml file exists public static void EnsureStringResources(Project project = null) { if (project == null) { project = VsUtils.GetCurrentProject(); } var resFile = Resourcer.GetResourcePath(Resourcer.GetStringsResName()); if (!File.Exists(resFile)) // if the file doesn't exist, create it { StringsXMLEditor.CreateDocument(resFile); } VsUtils.AddFileIfUnexisting(VsUtils.GetCurrentProject(), resFile); }
public static void EnsureResourcesFolder(Project project = null) { if (project == null) { project = VsUtils.GetCurrentProject(); } var resFolder = Resourcer.GetResourcesFolderPath(); if (!Directory.Exists(resFolder)) // if the directory doesn't exist, create it { Directory.CreateDirectory(resFolder); } VsUtils.AddDirectoryIfUnexisting(project, resFolder); }
// executed before the menu is open void menuCommand_BeforeQueryStatus(object sender, EventArgs e) { if (sender == null) { return; } string filePath; VsUtils.GetSingleProjectItemSelection(out filePath); var menuCommand = (OleMenuCommand)sender; menuCommand.Visible = menuCommand.Enabled = // visible if we selected the resources folder path Resourcer.GetResourcesFolderPath().Equals(filePath); }
// load all the available locales to the locales combo box void loadLocales() { localeCB.Items.Clear(); foreach (var locale in Resourcer.GetStringsResLocales()) { localeCB.Items.Add(locale); } if (localeCB.Items.Count > 0) { localeCB.SelectedIndex = 0; // select first checkTranslationBoxes(true); // enable stuff statusCSL.SetStatus("Ready to manage string resources and translations"); } else { checkTranslationBoxes(false); // disable stuff statusCSL.SetWarn("There are no translations yet! Consider adding some"); } }
// TODO use Code.cs and CodeLine.cs #endregion #region Everything // ensure everything and save the project public static void EnsureEverything() { var project = VsUtils.GetCurrentProject(); // omit these checks, perform them manually //EnsureResourcesFolder(project); //EnsureStringResources(project); // only if res dir contains resources if (Resourcer.AnyResource()) { EnsureResourceManager(project); EnsureAppXaml(project); } // only if there are translations added if (Resourcer.AnyLocale()) { EnsureAppXamlCs(project); } VsUtils.SaveProject(VsUtils.GetCurrentProject()); }
void addTranslation(string localeCode) { if (!string.IsNullOrWhiteSpace(localeCode)) { var path = Resourcer.GetXamlResPath(localeCode); if (File.Exists(path)) // get the strings res path and check if it exists { MessageBox.Show("This locale code was already added", "Existing locale", MessageBoxButtons.YesNo, MessageBoxIcon.Error); statusCSL.SetError("Could not add an already existing locale"); return; } // create the xaml resources file and reload the available locales Resourcer.CreateXamlRes(path, false); Ensurer.EnsureAppXamlCs(); loadLocales(); statusCSL.SetStatus($"New locale {localeCode} has been added successfully"); } }
public static void ShowAddCustomResource() { // sanitized path string sanitized = string.Empty; DialogResult retry; do { retry = DialogResult.No; var result = InputTextBox.Show( "Enter the name of the new custom resources XAML file", "Enter a name", sanitized, MAX_PATH_LENGTH - Resourcer.GetResourcesFolderPath().Length - 7); // -7 = -(@"\.xaml".Length + 1) // it must be LESS than, not less or equal ^ (so substract 1 extra) if (string.IsNullOrEmpty(result)) { return; } sanitized = string.Join("_", result.Split(Path.GetInvalidFileNameChars(), StringSplitOptions.RemoveEmptyEntries)).TrimEnd('.'); if (!string.IsNullOrWhiteSpace(sanitized)) { var path = Resourcer.GetXamlResPath(result); if (File.Exists(path)) { retry = MessageBox.Show("A file with this name already exists! Do you want to change it?", "Existing file", MessageBoxButtons.YesNo, MessageBoxIcon.Error); continue; } Resourcer.CreateXamlRes(path, true); } }while (retry == DialogResult.Yes); }
// ensure that the resource manager class exists, or that it's coplete public static void EnsureResourceManager(Project project = null) { var managerFile = Resourcer.GetResourcesManagerPath(); if (File.Exists(managerFile)) // if the file exists, ensure it has the required methods { var source = File.ReadAllText(managerFile, Encoding.UTF8); var rc1 = source.Contains(resCheck1); var rc2 = source.Contains(resCheck2); var rc3 = source.Contains(resCheck3); if (!rc1 || !rc2 || !rc3) // seems like it doesn't have everything! { var bracketRegex = new Regex(Settings.ResourcesManagerName + @"\s*{"); var match = bracketRegex.Match(source); // the class may exist var newFile = new StringBuilder(); if (match.Success) // there's a match, append only the missing code to the existing class { var bracket = match.Index + match.Length; newFile.Append(source.Substring(0, bracket)); if (!rc1) { newFile.AppendLine(resPart1); } if (!rc2) { newFile.AppendLine(resPart2); } if (!rc3) { newFile.AppendLine(resPart3); } newFile.Append(source.Substring(bracket)); } else // no match (no resourcemanager class), append the entire code { if (!source.Contains(resManagerUsing)) { newFile.AppendLine(resManagerUsing); } newFile.AppendLine(source); newFile.AppendLine(getResManagerSource()); } File.WriteAllText(managerFile, newFile.ToString()); } } else // file doesn't exist, just create it { createResourceManagerFile(managerFile); } if (project == null) { project = VsUtils.GetCurrentProject(); } VsUtils.AddFileIfUnexisting(project, managerFile); }