private void Insert(PlaceholderData placeholder) { try { using (IDbConnection connection = this.connectionPool.GetConnection()) using (IDbCommand command = connection.CreateCommand()) { command.CommandText = "INSERT OR REPLACE INTO Placeholder (path, pathType, sha) VALUES (@path, @pathType, @sha);"; command.AddParameter("@path", DbType.String, placeholder.Path); command.AddParameter("@pathType", DbType.Int32, (int)placeholder.PathType); if (placeholder.Sha == null) { command.AddParameter("@sha", DbType.String, DBNull.Value); } else { command.AddParameter("@sha", DbType.String, placeholder.Sha); } lock (this.writerLock) { command.ExecuteNonQuery(); } } } catch (Exception ex) { throw new GVFSDatabaseException($"{nameof(PlaceholderTable)}.{nameof(this.Insert)}({placeholder.Path}, {placeholder.PathType}, {placeholder.Sha}) Exception", ex); } }
public void Equals_ReturnsFalse_WhenPlaceholdersAreNotSame() { // Arrange var phData1 = new PlaceholderData { Index = 4, PlaceholderType = PlaceholderType.Custom }; var phData2 = new PlaceholderData { Index = 4, PlaceholderType = PlaceholderType.SlideNumber }; var phData3 = new PlaceholderData { PlaceholderType = PlaceholderType.Title }; var phData4 = new PlaceholderData { PlaceholderType = PlaceholderType.Custom, Index = 1 }; var phData5 = new PlaceholderData { PlaceholderType = PlaceholderType.Custom, Index = 2 }; var phLocationData1 = new PlaceholderLocationData(phData3); var phLocationData2 = new PlaceholderLocationData(phData4); var phLocationData3 = new PlaceholderLocationData(phData5); // Act var isEqualsCase1 = phLocationData1.Equals(phLocationData2); var isEqualsCase2 = phData1.Equals(phData2); var isEqualsCase3 = phLocationData2.Equals(phLocationData3); // Assert Assert.False(isEqualsCase1); Assert.False(isEqualsCase2); Assert.False(isEqualsCase3); }
public void Equals_Test_Case1() { // ARRANGE var stubPhXml1 = new PlaceholderData { PlaceholderType = PlaceholderType.Title }; var phSl1 = new PlaceholderLocationData(stubPhXml1); var stubPhXml2 = new PlaceholderData { PlaceholderType = PlaceholderType.Title }; var phSl2 = new PlaceholderLocationData(stubPhXml2); var stubPhXml3 = new PlaceholderData { PlaceholderType = PlaceholderType.Custom, Index = 1 }; var phSl3 = new PlaceholderLocationData(stubPhXml3); var phSl4 = new PlaceholderLocationData(stubPhXml3); // ACT var isEquals1 = phSl1.Equals(phSl2); var isEquals2 = phSl1.Equals(phSl3); var isEquals3 = phSl3.Equals(phSl4); // ASSERT Assert.True(isEquals1); Assert.False(isEquals2); Assert.True(isEquals3); }
public HashSet <string> GetAllFilePaths() { try { HashSet <string> filePlaceholderPaths = new HashSet <string>(StringComparer.Ordinal); string error; if (!this.TryLoadFromDisk <string, string>( this.TryParseAddLine, this.TryParseRemoveLine, (key, value) => { if (!PlaceholderData.IsShaAFolder(value)) { filePlaceholderPaths.Add(key); } }, out error)) { throw new InvalidDataException(error); } return(filePlaceholderPaths); } catch (Exception e) { throw new FileBasedCollectionException(e); } }
public Dictionary <string, PlaceholderListDatabase.PlaceholderData> GetAllFileEntries() { try { Dictionary <string, PlaceholderListDatabase.PlaceholderData> filePlaceholdersFromDiskByPath = new Dictionary <string, PlaceholderListDatabase.PlaceholderData>(Math.Max(1, this.EstimatedCount), StringComparer.Ordinal); string error; if (!this.TryLoadFromDisk <string, string>( this.TryParseAddLine, this.TryParseRemoveLine, (key, value) => { if (!PlaceholderData.IsShaAFolder(value)) { filePlaceholdersFromDiskByPath[key] = new PlaceholderData(path: key, fileShaOrFolderValue: value); } }, out error)) { throw new InvalidDataException(error); } return(filePlaceholdersFromDiskByPath); } catch (Exception e) { throw new FileBasedCollectionException(e); } }
private void UpdatePlaceholderName(PlaceholderData pd, string newName) { if (newName != pd.Name) { TranslationText.Text = TranslationText.Text.Replace("{" + pd.Name + "}", "{" + newName + "}"); pd.Name = newName; } }
private void AddParsedPlaceholder(StringBuilder textContent, StringBuilder placeholderContent) { var pd = new PlaceholderData(placeholders.Count + 1, placeholderContent.ToString()); if (pd.Code != "") { placeholders.Add(pd); textContent.Append("{").Append(pd.Name).Append("}"); } placeholderContent.Clear(); }
/// <summary> /// Initializes a new instance of the <see cref="ModuleDocumentationGenerator"/> class. /// </summary> /// <param name="commandAssemblyModules">The assembly containing the commands.</param> /// <param name="outputPath">The output path where documentation files should be written.</param> /// <param name="placeholderData">The placeholder repository.</param> public ModuleDocumentationGenerator ( IEnumerable <ModuleDefinition> commandAssemblyModules, string outputPath, PlaceholderData placeholderData ) { _commandAssemblyModules = commandAssemblyModules; _outputPath = outputPath; _placeholderData = placeholderData; }
private static async Task Main(string[] args) { Parser.Default.ParseArguments <Options>(args) .WithParsed(r => _options = r); if (_options is null) { return; } // Set up the assembly resolver var additionalResolverPaths = _options.AssemblyPaths.Select(Path.GetDirectoryName).Distinct(); var resolver = new DefaultAssemblyResolver(); foreach (var additionalResolverPath in additionalResolverPaths) { resolver.AddSearchDirectory(additionalResolverPath); } var placeholderData = new PlaceholderData(); var modules = _options.AssemblyPaths.Select ( ap => ModuleDefinition.ReadModule(ap, new ReaderParameters { AssemblyResolver = resolver }) ).ToArray(); var placeholderDataAttributes = modules .Where(m => m.Assembly.HasCustomAttributes) .SelectMany(m => m.Assembly.CustomAttributes) .Where(c => c.AttributeType.FullName == typeof(PlaceholderDataAttribute).FullName); foreach (var placeholderDataAttribute in placeholderDataAttributes) { var dataType = ((TypeReference)placeholderDataAttribute.ConstructorArguments[0].Value).Resolve(); var placeholders = ((CustomAttributeArgument[])placeholderDataAttribute.ConstructorArguments[1].Value) .Select(a => (string)a.Value).ToArray(); placeholderData.RegisterPlaceholderData(dataType, placeholders); } var generator = new ModuleDocumentationGenerator(modules, _options.OutputPath, placeholderData); await generator.GenerateDocumentationAsync(); }
/// <summary> /// Gets all entries and prepares the PlaceholderListDatabase for a call to WriteAllEntriesAndFlush. /// </summary> /// <exception cref="InvalidOperationException"> /// GetAllEntries was called (a second time) without first calling WriteAllEntriesAndFlush. /// </exception> /// <remarks> /// Usage notes: /// - All calls to GetAllEntries must be paired with a subsequent call to WriteAllEntriesAndFlush /// - If WriteAllEntriesAndFlush is *not* called entries that were added to the PlaceholderListDatabase after /// calling GetAllEntries will be lost /// </remarks> public void GetAllEntries(out List <IPlaceholderData> filePlaceholders, out List <IPlaceholderData> folderPlaceholders) { try { List <IPlaceholderData> filePlaceholdersFromDisk = new List <IPlaceholderData>(Math.Max(1, this.count)); List <IPlaceholderData> folderPlaceholdersFromDisk = new List <IPlaceholderData>(Math.Max(1, (int)(this.count * .3))); string error; if (!this.TryLoadFromDisk <string, string>( this.TryParseAddLine, this.TryParseRemoveLine, (key, value) => { if (PlaceholderData.IsShaAFolder(value)) { folderPlaceholdersFromDisk.Add(new PlaceholderData(path: key, fileShaOrFolderValue: value)); } else { filePlaceholdersFromDisk.Add(new PlaceholderData(path: key, fileShaOrFolderValue: value)); } }, out error, () => { if (this.placeholderChangesWhileRebuildingList != null) { throw new InvalidOperationException($"PlaceholderListDatabase should always flush queue placeholders using WriteAllEntriesAndFlush before calling {(nameof(this.GetAllEntries))} again."); } this.placeholderChangesWhileRebuildingList = new List <PlaceholderDataEntry>(); })) { throw new InvalidDataException(error); } filePlaceholders = filePlaceholdersFromDisk; folderPlaceholders = folderPlaceholdersFromDisk; } catch (Exception e) { throw new FileBasedCollectionException(e); } }
private static void ReadPlaceholders(IDbCommand command, Action <PlaceholderData> dataHandler) { using (IDataReader reader = command.ExecuteReader()) { while (reader.Read()) { PlaceholderData data = new PlaceholderData(); data.Path = reader.GetString(0); data.PathType = (PlaceholderData.PlaceholderType)reader.GetByte(1); if (!reader.IsDBNull(2)) { data.Sha = reader.GetString(2); } dataHandler(data); } } }
public void Equals_Test_Case2() { // ARRANGE var customIndex4 = new PlaceholderData { Index = 4, PlaceholderType = PlaceholderType.Custom }; var sldNumIndex4 = new PlaceholderData { Index = 4, PlaceholderType = PlaceholderType.SlideNumber }; // ACT var isEquals4 = customIndex4.Equals(sldNumIndex4); // ASSERT Assert.False(isEquals4); }
public void GetAllEntries(out List <IPlaceholderData> filePlaceholders, out List <IPlaceholderData> folderPlaceholders) { try { filePlaceholders = new List <IPlaceholderData>(); folderPlaceholders = new List <IPlaceholderData>(); using (IDbConnection connection = this.connectionPool.GetConnection()) using (IDbCommand command = connection.CreateCommand()) { command.CommandText = "SELECT path, pathType, sha FROM Placeholder;"; using (IDataReader reader = command.ExecuteReader()) { while (reader.Read()) { PlaceholderData data = new PlaceholderData(); data.Path = reader.GetString(0); data.PathType = (PlaceholderData.PlaceholderType)reader.GetByte(1); if (!reader.IsDBNull(2)) { data.Sha = reader.GetString(2); } if (data.PathType == PlaceholderData.PlaceholderType.File) { filePlaceholders.Add(data); } else { folderPlaceholders.Add(data); } } } } } catch (Exception ex) { throw new GVFSDatabaseException($"{nameof(PlaceholderTable)}.{nameof(this.GetAllEntries)} Exception", ex); } }
public void Equals_Test() { // ARRANGE var stubPhXml1 = new PlaceholderData { PlaceholderType = PlaceholderType.Title }; var phSl1 = new PlaceholderLocationData(stubPhXml1); var stubPhXml2 = new PlaceholderData { PlaceholderType = PlaceholderType.Title }; var phSl2 = new PlaceholderLocationData(stubPhXml2); var stubPhXml3 = new PlaceholderData { PlaceholderType = PlaceholderType.Custom, Index = 1 }; var phSl3 = new PlaceholderLocationData(stubPhXml3); var phSl4 = new PlaceholderLocationData(stubPhXml3); var custom = new PlaceholderData { Index = 4, PlaceholderType = PlaceholderType.Custom }; var sldNum = new PlaceholderData { Index = 4, PlaceholderType = PlaceholderType.SlideNumber }; // ACT var isEquals1 = phSl1.Equals(phSl2); var isEquals2 = phSl1.Equals(phSl3); var isEquals3 = phSl3.Equals(phSl4); var isEquals4 = custom.Equals(sldNum); // ASSERT Assert.True(isEquals1); Assert.False(isEquals2); Assert.True(isEquals3); Assert.False(isEquals4); }
public void GetHashCode_Test() { // ARRANGE var stubPhXml1 = new PlaceholderData { PlaceholderType = PlaceholderType.Title }; var phSl1 = new PlaceholderLocationData(stubPhXml1); var stubPhXml2 = new PlaceholderData { PlaceholderType = PlaceholderType.Title }; var phSl2 = new PlaceholderLocationData(stubPhXml2); var stubPhXml3 = new PlaceholderData { PlaceholderType = PlaceholderType.Custom, Index = 1 }; var stubPhXml4 = new PlaceholderData { PlaceholderType = PlaceholderType.Custom, Index = 1 }; var stubPhXml5 = new PlaceholderData { PlaceholderType = PlaceholderType.Custom, Index = 2 }; var phSl3 = new PlaceholderLocationData(stubPhXml3); var phSl4 = new PlaceholderLocationData(stubPhXml4); var phSl5 = new PlaceholderLocationData(stubPhXml5); // ACT var hash1 = phSl1.GetHashCode(); var hash2 = phSl2.GetHashCode(); var hash3 = phSl3.GetHashCode(); var hash4 = phSl4.GetHashCode(); var hash5 = phSl5.GetHashCode(); // ASSERT Assert.Equal(hash1, hash2); Assert.Equal(hash3, hash4); Assert.NotEqual(hash3, hash5); }
private void Reset(bool setTextKey) { // Detect parameters in the code placeholders.Clear(); parsedText = ""; isPartialString = false; if (initialClipboardText != null) { if (SourceCSharpButton.IsChecked == true) { isPartialString = true; if ((initialClipboardText.StartsWith("\"") || initialClipboardText.StartsWith("@\"")) && initialClipboardText.EndsWith("\"")) { isPartialString = false; } bool inStringLiteral = isPartialString; bool isVerbatimString = false; bool inCharLiteral = false; int parensLevel = 0; int bracketsLevel = 0; int bracesLevel = 0; int lastStringEnd = 0; StringBuilder stringContent = new StringBuilder(); for (int pos = 0; pos < initialClipboardText.Length; pos++) { char ch = initialClipboardText[pos]; char nextChar = pos + 1 < initialClipboardText.Length ? initialClipboardText[pos + 1] : '\0'; if (!inStringLiteral && !inCharLiteral && ch == '\'') { // Start char literal inCharLiteral = true; } else if (inCharLiteral && ch == '\\') { // Escape sequence, skip next character pos++; } else if (inCharLiteral && ch == '\'') { // End char literal inCharLiteral = false; } else if (!inStringLiteral && !inCharLiteral && ch == '@' && nextChar == '"') { // Start verbatim string literal inStringLiteral = true; isVerbatimString = true; if (parensLevel == 0 && bracketsLevel == 0 && bracesLevel == 0 && pos > 0) { string code = initialClipboardText.Substring(lastStringEnd, pos - lastStringEnd); var pd = new PlaceholderData(placeholders.Count + 1, code); if (pd.Code != "") { placeholders.Add(pd); parsedText += "{" + pd.Name + "}"; } } // Handled 2 characters pos++; } else if (!inStringLiteral && !inCharLiteral && ch == '"') { // Start string literal inStringLiteral = true; if (parensLevel == 0 && bracketsLevel == 0 && bracesLevel == 0 && pos > 0) { string code = initialClipboardText.Substring(lastStringEnd, pos - lastStringEnd); var pd = new PlaceholderData(placeholders.Count + 1, code); if (pd.Code != "") { placeholders.Add(pd); parsedText += "{" + pd.Name + "}"; } } } else if (inStringLiteral && !isVerbatimString && ch == '\\') { // Escape sequence, skip next character pos++; switch (nextChar) { case '\'': case '"': case '\\': stringContent.Append(nextChar); break; case '0': stringContent.Append('\0'); break; case 'a': stringContent.Append('\a'); break; case 'b': stringContent.Append('\b'); break; case 'f': stringContent.Append('\f'); break; case 'n': stringContent.Append('\n'); break; case 'r': stringContent.Append('\r'); break; case 't': stringContent.Append('\t'); break; case 'U': long value = long.Parse(initialClipboardText.Substring(pos + 1, 8), System.Globalization.NumberStyles.HexNumber); //stringContent.Append(); // TODO: What does that value mean? pos += 8; break; case 'u': int codepoint = int.Parse(initialClipboardText.Substring(pos + 1, 4), System.Globalization.NumberStyles.HexNumber); stringContent.Append((char) codepoint); pos += 4; break; case 'v': stringContent.Append('\v'); break; case 'x': // TODO: variable length hex value! break; } } else if (inStringLiteral && isVerbatimString && ch == '"' && nextChar == '"') { // Escape sequence, skip next character pos++; stringContent.Append(nextChar); } else if (inStringLiteral && ch == '"') { // End string literal inStringLiteral = false; isVerbatimString = false; lastStringEnd = pos + 1; if (parensLevel == 0 && bracketsLevel == 0 && bracesLevel == 0) { parsedText += stringContent.ToString(); } stringContent.Clear(); } else if (inStringLiteral) { // Append character to text stringContent.Append(ch); } else if (!inStringLiteral && !inCharLiteral && ch == '(') { parensLevel++; } else if (!inStringLiteral && !inCharLiteral && ch == ')') { if (parensLevel > 0) parensLevel--; } else if (!inStringLiteral && !inCharLiteral && ch == '[') { bracketsLevel++; } else if (!inStringLiteral && !inCharLiteral && ch == ']') { if (bracketsLevel > 0) bracketsLevel--; } else if (!inStringLiteral && !inCharLiteral && ch == '{') { bracesLevel++; } else if (!inStringLiteral && !inCharLiteral && ch == '}') { if (bracesLevel > 0) bracesLevel--; } } if (!isPartialString && lastStringEnd < initialClipboardText.Length) { // Some non-string content is still left (parameter at the end) string code = initialClipboardText.Substring(lastStringEnd); var pd = new PlaceholderData(placeholders.Count + 1, code); if (pd.Code != "") { placeholders.Add(pd); parsedText += "{" + pd.Name + "}"; } } if (isPartialString && inStringLiteral && stringContent.Length > 0) { // Save the last string part parsedText += stringContent.ToString(); } } if (SourceXamlButton.IsChecked == true) { parsedText = initialClipboardText; // TODO: Any further processing required? } if (SourceAspxButton.IsChecked == true) { // Decode HTML entities parsedText = initialClipboardText .Replace("<", "<") .Replace(">", ">") .Replace(""", "\"") .Replace("&", "&"); } } TranslationText.Text = parsedText; ParametersLabel.Visibility = Visibility.Collapsed; ParametersGrid.Visibility = Visibility.Collapsed; ParametersGrid.Children.Clear(); if (placeholders.Count > 0) { ParametersLabel.Visibility = Visibility.Visible; ParametersGrid.Visibility = Visibility.Visible; int row = 0; foreach (var pd in placeholders) { var localPd = pd; ParametersGrid.RowDefinitions.Add(new RowDefinition()); TextBox nameText = new TextBox(); nameText.Text = pd.Name; nameText.SelectAll(); nameText.Margin = new Thickness(0, row > 0 ? 4 : 0, 0, 0); nameText.LostFocus += (s, e2) => { UpdatePlaceholderName(localPd, nameText.Text); }; ParametersGrid.Children.Add(nameText); Grid.SetRow(nameText, row); Grid.SetColumn(nameText, 0); TextBox codeText = new TextBox(); codeText.Text = pd.Code; codeText.Margin = new Thickness(4, row > 0 ? 4 : 0, 0, 0); codeText.TextChanged += (s, e2) => { localPd.Code = codeText.Text; }; ParametersGrid.Children.Add(codeText); Grid.SetRow(codeText, row); Grid.SetColumn(codeText, 1); CheckBox quotedCheck = new CheckBox(); quotedCheck.Content = "Q"; quotedCheck.IsChecked = pd.IsQuoted; quotedCheck.Margin = new Thickness(4, row > 0 ? 4 : 0, 0, 0); quotedCheck.VerticalAlignment = VerticalAlignment.Center; quotedCheck.Checked += (s, e2) => { localPd.IsQuoted = true; }; quotedCheck.Unchecked += (s, e2) => { localPd.IsQuoted = false; }; ParametersGrid.Children.Add(quotedCheck); Grid.SetRow(quotedCheck, row); Grid.SetColumn(quotedCheck, 2); row++; } } suggestions.Clear(); if (!String.IsNullOrEmpty(TranslationText.Text)) { ScanAllTexts(MainViewModel.Instance.RootTextKey); } bool havePreviousTextKey = !String.IsNullOrEmpty(prevTextKey); bool haveOtherKeys = suggestions.Count > 0; // Order suggestions by relevance (descending), then by text key suggestions.Sort((a, b) => a.ScoreNum != b.ScoreNum ? -a.ScoreNum.CompareTo(b.ScoreNum) : a.TextKey.CompareTo(b.TextKey)); string nearestMatch = suggestions.Count > 0 ? suggestions[0].BaseText : null; bool haveExactMatch = nearestMatch == TranslationText.Text; if (havePreviousTextKey) { // Store the previous text key with the IsDummy flag at the first position suggestions.Insert(0, new SuggestionViewModel(null) { TextKey = prevTextKey, BaseText = "(previous text key)", IsDummy = true }); } // Show the suggestions list if there is at least one other text key and at least two // list items to select from (or the nearest text is not an exact match) //if (haveOtherKeys && // (suggestions.Count > 1 || !haveExactMatch)) //{ OtherKeysLabel.Visibility = Visibility.Visible; OtherKeysList.Visibility = Visibility.Visible; //} //else //{ // OtherKeysLabel.Visibility = Visibility.Collapsed; // OtherKeysList.Visibility = Visibility.Collapsed; //} OtherKeysList.Items.Clear(); foreach (var suggestion in suggestions) { OtherKeysList.Items.Add(suggestion); } // Preset the text key input field if requested and possible if (setTextKey) { if (haveExactMatch) { if (havePreviousTextKey) { // There's the previous key and more suggestions (with an exact match), take // the first suggestion TextKeyText.Text = suggestions[1].TextKey; OtherKeysList.SelectedIndex = 1; } else { // There's only other suggestions (with an exact match), take the first one TextKeyText.Text = suggestions[0].TextKey; OtherKeysList.SelectedIndex = 0; } AutoSelectKeyText(); } else if (havePreviousTextKey) { // There's only the previous key, take that TextKeyText.Text = prevTextKey; OtherKeysList.SelectedIndex = 0; AutoSelectKeyText(); } // else: We have no exact match to suggest at the moment, leave the text key empty } }
private void Reset(bool setTextKey) { // Detect parameters in the code placeholders.Clear(); parsedText = ""; isPartialString = false; if (initialClipboardText != null) { if (SourceCSharpButton.IsChecked == true) { isPartialString = true; if ((initialClipboardText.StartsWith("\"") || initialClipboardText.StartsWith("@\"")) && initialClipboardText.EndsWith("\"")) { isPartialString = false; } bool inStringLiteral = isPartialString; bool isVerbatimString = false; bool inCharLiteral = false; int parensLevel = 0; int bracketsLevel = 0; int bracesLevel = 0; int lastStringEnd = 0; StringBuilder stringContent = new StringBuilder(); for (int pos = 0; pos < initialClipboardText.Length; pos++) { char ch = initialClipboardText[pos]; char nextChar = pos + 1 < initialClipboardText.Length ? initialClipboardText[pos + 1] : '\0'; if (!inStringLiteral && !inCharLiteral && ch == '\'') { // Start char literal inCharLiteral = true; } else if (inCharLiteral && ch == '\\') { // Escape sequence, skip next character pos++; } else if (inCharLiteral && ch == '\'') { // End char literal inCharLiteral = false; } else if (!inStringLiteral && !inCharLiteral && ch == '@' && nextChar == '"') { // Start verbatim string literal inStringLiteral = true; isVerbatimString = true; if (parensLevel == 0 && bracketsLevel == 0 && bracesLevel == 0 && pos > 0) { string code = initialClipboardText.Substring(lastStringEnd, pos - lastStringEnd); var pd = new PlaceholderData(placeholders.Count + 1, code); if (pd.Code != "") { placeholders.Add(pd); parsedText += "{" + pd.Name + "}"; } } // Handled 2 characters pos++; } else if (!inStringLiteral && !inCharLiteral && ch == '"') { // Start string literal inStringLiteral = true; if (parensLevel == 0 && bracketsLevel == 0 && bracesLevel == 0 && pos > 0) { string code = initialClipboardText.Substring(lastStringEnd, pos - lastStringEnd); var pd = new PlaceholderData(placeholders.Count + 1, code); if (pd.Code != "") { placeholders.Add(pd); parsedText += "{" + pd.Name + "}"; } } } else if (inStringLiteral && !isVerbatimString && ch == '\\') { // Escape sequence, skip next character pos++; switch (nextChar) { case '\'': case '"': case '\\': stringContent.Append(nextChar); break; case '0': stringContent.Append('\0'); break; case 'a': stringContent.Append('\a'); break; case 'b': stringContent.Append('\b'); break; case 'f': stringContent.Append('\f'); break; case 'n': stringContent.Append('\n'); break; case 'r': stringContent.Append('\r'); break; case 't': stringContent.Append('\t'); break; case 'U': long value = long.Parse(initialClipboardText.Substring(pos + 1, 8), System.Globalization.NumberStyles.HexNumber); //stringContent.Append(); // TODO: What does that value mean? pos += 8; break; case 'u': int codepoint = int.Parse(initialClipboardText.Substring(pos + 1, 4), System.Globalization.NumberStyles.HexNumber); stringContent.Append((char)codepoint); pos += 4; break; case 'v': stringContent.Append('\v'); break; case 'x': // TODO: variable length hex value! break; } } else if (inStringLiteral && isVerbatimString && ch == '"' && nextChar == '"') { // Escape sequence, skip next character pos++; stringContent.Append(nextChar); } else if (inStringLiteral && ch == '"') { // End string literal inStringLiteral = false; isVerbatimString = false; lastStringEnd = pos + 1; if (parensLevel == 0 && bracketsLevel == 0 && bracesLevel == 0) { parsedText += stringContent.ToString(); } stringContent.Clear(); } else if (inStringLiteral) { // Append character to text stringContent.Append(ch); } else if (!inStringLiteral && !inCharLiteral && ch == '(') { parensLevel++; } else if (!inStringLiteral && !inCharLiteral && ch == ')') { if (parensLevel > 0) { parensLevel--; } } else if (!inStringLiteral && !inCharLiteral && ch == '[') { bracketsLevel++; } else if (!inStringLiteral && !inCharLiteral && ch == ']') { if (bracketsLevel > 0) { bracketsLevel--; } } else if (!inStringLiteral && !inCharLiteral && ch == '{') { bracesLevel++; } else if (!inStringLiteral && !inCharLiteral && ch == '}') { if (bracesLevel > 0) { bracesLevel--; } } } if (!isPartialString && lastStringEnd < initialClipboardText.Length) { // Some non-string content is still left (parameter at the end) string code = initialClipboardText.Substring(lastStringEnd); var pd = new PlaceholderData(placeholders.Count + 1, code); if (pd.Code != "") { placeholders.Add(pd); parsedText += "{" + pd.Name + "}"; } } if (isPartialString && inStringLiteral && stringContent.Length > 0) { // Save the last string part parsedText += stringContent.ToString(); } } if (SourceXamlButton.IsChecked == true) { parsedText = initialClipboardText; // TODO: Any further processing required? } if (SourceAspxButton.IsChecked == true) { // Decode HTML entities parsedText = initialClipboardText .Replace("<", "<") .Replace(">", ">") .Replace(""", "\"") .Replace("&", "&"); } } TranslationText.Text = parsedText; ParametersLabel.Visibility = Visibility.Collapsed; ParametersGrid.Visibility = Visibility.Collapsed; ParametersGrid.Children.Clear(); if (placeholders.Count > 0) { ParametersLabel.Visibility = Visibility.Visible; ParametersGrid.Visibility = Visibility.Visible; int row = 0; foreach (var pd in placeholders) { var localPd = pd; ParametersGrid.RowDefinitions.Add(new RowDefinition()); TextBox nameText = new TextBox(); nameText.Text = pd.Name; nameText.SelectAll(); nameText.Margin = new Thickness(0, row > 0 ? 4 : 0, 0, 0); nameText.LostFocus += (s, e2) => { UpdatePlaceholderName(localPd, nameText.Text); }; ParametersGrid.Children.Add(nameText); Grid.SetRow(nameText, row); Grid.SetColumn(nameText, 0); TextBox codeText = new TextBox(); codeText.Text = pd.Code; codeText.Margin = new Thickness(4, row > 0 ? 4 : 0, 0, 0); codeText.TextChanged += (s, e2) => { localPd.Code = codeText.Text; }; ParametersGrid.Children.Add(codeText); Grid.SetRow(codeText, row); Grid.SetColumn(codeText, 1); CheckBox quotedCheck = new CheckBox(); quotedCheck.Content = "Q"; quotedCheck.IsChecked = pd.IsQuoted; quotedCheck.Margin = new Thickness(4, row > 0 ? 4 : 0, 0, 0); quotedCheck.VerticalAlignment = VerticalAlignment.Center; quotedCheck.Checked += (s, e2) => { localPd.IsQuoted = true; }; quotedCheck.Unchecked += (s, e2) => { localPd.IsQuoted = false; }; ParametersGrid.Children.Add(quotedCheck); Grid.SetRow(quotedCheck, row); Grid.SetColumn(quotedCheck, 2); row++; } } suggestions.Clear(); if (!String.IsNullOrEmpty(TranslationText.Text)) { ScanAllTexts(MainViewModel.Instance.RootTextKey); } bool havePreviousTextKey = !String.IsNullOrEmpty(prevTextKey); bool haveOtherKeys = suggestions.Count > 0; // Order suggestions by relevance (descending), then by text key suggestions.Sort((a, b) => a.ScoreNum != b.ScoreNum ? -a.ScoreNum.CompareTo(b.ScoreNum) : a.TextKey.CompareTo(b.TextKey)); string nearestMatch = suggestions.Count > 0 ? suggestions[0].BaseText : null; bool haveExactMatch = nearestMatch == TranslationText.Text; if (havePreviousTextKey) { // Store the previous text key with the IsDummy flag at the first position suggestions.Insert(0, new SuggestionViewModel(null) { TextKey = prevTextKey, BaseText = "(previous text key)", IsDummy = true }); } // Show the suggestions list if there is at least one other text key and at least two // list items to select from (or the nearest text is not an exact match) //if (haveOtherKeys && // (suggestions.Count > 1 || !haveExactMatch)) //{ OtherKeysLabel.Visibility = Visibility.Visible; OtherKeysList.Visibility = Visibility.Visible; //} //else //{ // OtherKeysLabel.Visibility = Visibility.Collapsed; // OtherKeysList.Visibility = Visibility.Collapsed; //} OtherKeysList.Items.Clear(); foreach (var suggestion in suggestions) { OtherKeysList.Items.Add(suggestion); } // Preset the text key input field if requested and possible if (setTextKey) { if (haveExactMatch) { if (havePreviousTextKey) { // There's the previous key and more suggestions (with an exact match), take // the first suggestion TextKeyText.Text = suggestions[1].TextKey; OtherKeysList.SelectedIndex = 1; } else { // There's only other suggestions (with an exact match), take the first one TextKeyText.Text = suggestions[0].TextKey; OtherKeysList.SelectedIndex = 0; } AutoSelectKeyText(); } else if (havePreviousTextKey) { // There's only the previous key, take that TextKeyText.Text = prevTextKey; OtherKeysList.SelectedIndex = 0; AutoSelectKeyText(); } // else: We have no exact match to suggest at the moment, leave the text key empty } }