public void SelectStringInTextDocument() { StringResource stringResource = this.GetSelectedItem(); if (stringResource == null) { return; } string text = stringResource.Text; System.Drawing.Point location = GetStringLocation(); //bool isAtString = false; m_TextDocument.Selection.MoveToLineAndOffset(location.X, location.Y, false); if (location.Y > 1) { m_TextDocument.Selection.MoveToLineAndOffset(location.X, location.Y - 1, false); m_TextDocument.Selection.CharRight(true, 1); if (m_TextDocument.Selection.Text[0] != '@') { m_TextDocument.Selection.MoveToLineAndOffset(location.X, location.Y, false); } // isAtString = true; } m_TextDocument.Selection.MoveToLineAndOffset(location.X, location.Y + text.Length + 2, true); m_SelectedStringResource = this.GetSelectedItem(); m_SelectedGridRowIndex = this.GetSelectedRowIndex(); if ((m_Window != null) && (m_Window != m_Dte2.ActiveWindow)) { m_Window.Activate(); } }
/// <summary> /// Updates the table and selects next entry. /// </summary> /// <param name="deltaLength">The length delta of the replacement (resource call length minus string literal length).</param> /// <param name="deltaLine">The line delta (when alias has been inserted).</param> private void UpdateTableAndSelectNext(int deltaLength, int deltaLine) { if ((deltaLength != 0) || (deltaLine != 0)) { #region update entries int replacedLocationX = m_SelectedStringResource.Location.X, replacedLocationY = m_SelectedStringResource.Location.Y, startGridRowIndex = (deltaLine != 0) ? 0 : m_SelectedGridRowIndex + 1; //touch all when alias has been inserted //else only the following entries on the same line for (int gridRowIndex = startGridRowIndex; gridRowIndex < m_StringResources.Count; ++gridRowIndex) { if (gridRowIndex == m_SelectedGridRowIndex) { continue; } StringResource stringResource = m_StringResources[gridRowIndex] as StringResource; if ((deltaLength != 0) && (stringResource.Location.X == replacedLocationX) && (stringResource.Location.Y > replacedLocationY)) { //same line as replaced entry -> heed column shift and a possible alias insertion Debug.Print("{0}: col {1} -> {2}, {3}", gridRowIndex, stringResource.Location.ToString(), stringResource.Location.X + deltaLine, stringResource.Location.Y + deltaLength); stringResource.Offset(deltaLine, deltaLength); } else if (deltaLine != 0) { //heed alias insertion Debug.Print("{0}: line {1} -> {2}, {3}", gridRowIndex, stringResource.Location.ToString(), stringResource.Location.X + deltaLine, stringResource.Location.Y + deltaLength); stringResource.Offset(deltaLine, 0); } else { break; //nothing left to update } } //for #if never //[12-10-03 DR]: Indexing no longer in use //[12-10-03 DR]: search for resource names with selected name plus index ("_#") string name = string.Concat(m_SelectedStringResource.Name, "_"); List <StringResource> stringResources = m_StringResources.FindAll(sr => sr.Name.StartsWith(name)); if (stringResources.Count > 0) { //[12-10-03 DR]: calculate new indexes (remove first index entirely) int nameLength = name.Length, firstIndex = -1, index = 1, indexValue; foreach (StringResource item in stringResources) { if (int.TryParse(item.Name.Substring(nameLength), out indexValue)) { if (firstIndex == -1) { firstIndex = indexValue; item.Name = item.Name.Substring(0, nameLength - 1); //remove entire index ("_#") } else { item.Name = item.Name.Substring(0, nameLength); //remove old index number item.Name = string.Concat(item.Name, index.ToString()); //append new index number ++index; } //else } //if } //foreach } //if #endif #endregion } //if #region remove entry and goto next entry //this.ClearGrid(); RemoveStringResource(m_SelectedGridRowIndex); //this.SetGridItemsSource(m_StringResources); this.RefreshGrid(); this.SelectCell(m_SelectedGridRowIndex, this.GetSelectedColIndex()); #endregion SelectStringInTextDocument(); }
/// <summary> /// Find the nearest string literal to the actual cursor location in the table and select it. /// </summary> private void SelectNearestGridRow() { int curLine = m_TextDocument.Selection.ActivePoint.Line, curCol = m_TextDocument.Selection.ActivePoint.LineCharOffset, rowNo = -1, lineNo = -1; List <StringResource> stringResources = GetAllStringResourcesInLine(curLine); if (stringResources.Count > 0) { #region current line if (stringResources[stringResources.Count - 1].Location.Y < curCol) { //same location line (same or previous string) StringResource stringResource = stringResources[stringResources.Count - 1]; rowNo = m_StringResources.IndexOf(stringResource); lineNo = stringResource.Location.X; Debug.Print("> Found at ({0}, {1}): '{2}'", lineNo, stringResource.Location.Y, stringResource.Text); } else { //same location line (same or next string) foreach (StringResource stringResource in stringResources) { int y = stringResource.Location.Y; if (((y <= curCol) && (stringResource.Text.Length + y + 2 >= curCol)) || (y > curCol)) { rowNo = m_StringResources.IndexOf(stringResource); lineNo = stringResource.Location.X; Debug.Print("> Found at ({0}, {1}): '{2}'", lineNo, stringResource.Location.Y, stringResource.Text); break; } //if } //foreach } //else #endregion } else { #region find nearest line (select only in grid) StringResource stringResourceBefore = GetLastStringResourceBeforeLine(curLine), stringResourceBehind = GetFirstStringResourceBehindLine(curLine); if ((stringResourceBefore != null) && ((stringResourceBehind == null) || ((curLine - stringResourceBefore.Location.X) <= (stringResourceBehind.Location.X - curLine)))) { rowNo = m_StringResources.IndexOf(stringResourceBefore); lineNo = stringResourceBefore.Location.X; Debug.Print("> Found at ({0}, {1}): '{2}'", lineNo, stringResourceBefore.Location.Y, stringResourceBefore.Text); } else if (stringResourceBehind != null) { rowNo = m_StringResources.IndexOf(stringResourceBehind); lineNo = stringResourceBehind.Location.X; Debug.Print("> Found at ({0}, {1}): '{2}'", lineNo, stringResourceBehind.Location.Y, stringResourceBehind.Text); } //else #endregion } //else if (rowNo >= 0) { this.SelectCell(rowNo, this.GetSelectedColIndex()); if (lineNo == curLine) { SelectStringInTextDocument(); } } //if }
private void BuildAndUseResource(ProjectItem resourceFilePrjItem) { try { string resxFile = resourceFilePrjItem.Document.FullName; string nameSpace = m_Window.Project.Properties.Item("RootNamespace").Value.ToString(); #region get namespace from ResX designer file foreach (ProjectItem item in resourceFilePrjItem.ProjectItems) { if (item.Name.EndsWith(".resx", StringComparison.InvariantCultureIgnoreCase)) { continue; } foreach (CodeElement element in item.FileCodeModel.CodeElements) { if (element.Kind == vsCMElement.vsCMElementNamespace) { nameSpace = element.FullName; break; } //if } //foreach } //foreach #endregion //close the ResX file to modify it (force a checkout) resourceFilePrjItem.Document.Save(); //[13-07-10 DR]: MS has changed behavior of Close(vsSaveChanges.vsSaveChangesYes) in VS2012 resourceFilePrjItem.Document.Close(vsSaveChanges.vsSaveChangesYes); string name, value, comment = string.Empty; StringResource stringResource = m_SelectedStringResource;// this.dataGrid1.CurrentItem as StringResource; name = stringResource.Name; value = stringResource.Text; if (!m_IsCSharp || (m_TextDocument.Selection.Text.Length > 0) && (m_TextDocument.Selection.Text[0] == '@')) { value = value.Replace("\"\"", "\\\""); // [""] -> [\"] (change VB writing to CSharp) } //add to the resource file (checking for duplicate) if (!AppendStringResource(resxFile, name, value, comment)) { return; } //(re-)create the designer class VSLangProj.VSProjectItem vsPrjItem = resourceFilePrjItem.Object as VSLangProj.VSProjectItem; if (vsPrjItem != null) { vsPrjItem.RunCustomTool(); } //get the length of the selected string literal and replace by resource call int replaceLength = m_TextDocument.Selection.Text.Length; if (replaceLength > 0) { string className = System.IO.Path.GetFileNameWithoutExtension(resxFile).Replace('.', '_'), aliasName = className.Substring(0, className.Length - 6), //..._Resources -> ..._Res resourceCall = string.Concat(aliasName, ".", name); bool isGlobalResourceFile = m_Settings.IsUseGlobalResourceFile && string.IsNullOrEmpty(m_Settings.GlobalResourceFileName), isDontUseResourceUsingAlias = m_Settings.IsUseGlobalResourceFile && m_Settings.IsDontUseResourceAlias; if (isGlobalResourceFile) { //standard global resource file aliasName = string.Concat("Glbl", aliasName); resourceCall = string.Concat("Glbl", resourceCall); } //if int oldRow = m_TextDocument.Selection.ActivePoint.Line; if (!isDontUseResourceUsingAlias) { //insert the resource using alias (if not yet) CheckAndAddAlias(nameSpace, className, aliasName); } else { //create a resource call like "Properties.SRB_Strings_Resources.myResText", "Properties.Resources.myResText", "Resources.myResText" int lastDotPos = nameSpace.LastIndexOf('.'); string resxNameSpace = (lastDotPos >= 0) ? string.Concat(nameSpace.Substring(lastDotPos + 1), ".") : string.Empty; resourceCall = string.Concat(resxNameSpace, className, ".", name); } //else //insert the resource call, replacing the selected string literal m_TextDocument.Selection.Insert(resourceCall, (int)vsInsertFlags.vsInsertFlagsContainNewText); UpdateTableAndSelectNext(resourceCall.Length - replaceLength, m_TextDocument.Selection.ActivePoint.Line - oldRow); } //if } catch (Exception ex) { Trace.WriteLine($"### BuildAndUseResource() - {ex.ToString()}"); } }
private StringResource GetFirstStringResourceBehindLine(int lineNo) { StringResource stringResource = m_StringResources.Find(sr => (sr.Location.X > lineNo)); return(stringResource); }
private StringResource GetLastStringResourceBeforeLine(int lineNo) { StringResource stringResource = m_StringResources.FindLast(sr => (sr.Location.X < lineNo)); return(stringResource); }
public void SelectStringInTextDocument() { StringResource stringResource = this.GetSelectedItem(); if (stringResource == null) { return; } string text = stringResource.Text; System.Drawing.Point location = GetStringLocation(); //bool isAtString = false; m_TextDocument.Selection.MoveToLineAndOffset(location.X, location.Y, false); if (location.Y > 1) { m_TextDocument.Selection.MoveToLineAndOffset(location.X, location.Y - 1, false); m_TextDocument.Selection.CharRight(true, 1); if (m_TextDocument.Selection.Text[0] != '@') { m_TextDocument.Selection.MoveToLineAndOffset(location.X, location.Y, false); } //else // isAtString = true; } //if //from this point 'text' won't be valid anymore (changed for length) //if (!isAtString) //{ // if (text.Contains(@"\")) // text = text.Replace(@"\", "#"); // //if (text.Contains(@"\\")) // // text = text.Replace(@"\\", "##"); // //if (text.Contains(@"\r")) // // text = text.Replace(@"\r", "##"); // //if (text.Contains(@"\n")) // // text = text.Replace(@"\n", "##"); // //if (text.Contains(@"\t")) // // text = text.Replace(@"\t", "##"); // //if (text.Contains(@"\0")) // // text = text.Replace(@"\0", "##"); // //if (text.Contains("\"")) // // text = text.Replace("\"", "##"); //} ////else ////{ //// if (text.Contains("\"")) //// text = text.Replace("\"", "##"); //// if (text.Contains(@"\\")) //// text = text.Replace(@"\\", "##"); ////} //else m_TextDocument.Selection.MoveToLineAndOffset(location.X, location.Y + text.Length + 2, true); m_SelectedStringResource = this.GetSelectedItem(); m_SelectedGridRowIndex = this.GetSelectedRowIndex(); if ((m_Window != null) && (m_Window != m_Dte2.ActiveWindow)) { m_Window.Activate(); } }
/// <summary>Parses for strings by iterating through the FileCodeModel.</summary> /// <param name="startPoint">The start point.</param> /// <param name="endPoint">The end point.</param> /// <param name="lastDocumentLength">Last length of the document.</param> private void ParseForStrings(TextPoint startPoint, TextPoint endPoint, int lastDocumentLength) { //0.35-0.06 seconds (threaded: 2.47-1.77 seconds) List <StringResource> stringResources = new List <StringResource>(); bool isFullDocument = startPoint.AtStartOfDocument && endPoint.AtEndOfDocument, isTextWithStringLiteral = true; int startLine = startPoint.Line, startCol = startPoint.LineCharOffset, endLine = endPoint.Line, endCol = endPoint.LineCharOffset, documentLength = endPoint.Parent.EndPoint.Line, insertIndex = 0; if (isFullDocument) { m_StringResources.Clear(); } else { #region document manipulated -> adapt string resources and locations //determine whether the text between startLine and endLine (including) contains double quotes EditPoint editPoint = startPoint.CreateEditPoint() as EditPoint2; if (!startPoint.AtStartOfLine) { editPoint.StartOfLine(); } isTextWithStringLiteral = editPoint.GetLines(startLine, endLine + 1).Contains("\""); //move trailing locations behind changed lines if needed and //remove string resources on changed lines int lineOffset = documentLength - lastDocumentLength; #if DEBUG_OUTPUT System.Diagnostics.Debug.Print(" Line offset is {0}", lineOffset); #endif for (int i = m_StringResources.Count - 1; i >= 0; --i) { StringResource stringResource = m_StringResources[i]; int lineNo = stringResource.Location.X; if (lineNo + lineOffset > endLine) { if (lineOffset != 0) { #if DEBUG_OUTPUT System.Diagnostics.Debug.Print(" Move string literal from line {0} to {1}", lineNo, lineNo + lineOffset); #endif stringResource.Offset(lineOffset, 0); //move } //if } else if (lineNo >= startLine) { #if DEBUG_OUTPUT System.Diagnostics.Debug.Print(" Remove string literal {0} ({1}): {2}", i, stringResource.Location, stringResource.Text); #endif m_StringResources.RemoveAt(i); //remove changed line } else if (insertIndex == 0) { #if DEBUG_OUTPUT System.Diagnostics.Debug.Print(" List insert index is {0} / {1}", i + 1, m_StringResources.Count - 1); #endif insertIndex = i + 1; } //else if } //for #endregion } //else #if DEBUG_OUTPUT System.Diagnostics.Debug.Print(" Text has{0} string literals.", isTextWithStringLiteral ? string.Empty : " no"); #endif if (isTextWithStringLiteral) { CodeElements elements = m_Window.Document.ProjectItem.FileCodeModel.CodeElements; foreach (CodeElement element in elements) { ParseForStrings(element, m_DoProgress, stringResources, m_Settings, m_IsCSharp, startLine, endLine); #if DEBUG if (element.Kind == vsCMElement.vsCMElementProperty) { CodeProperty prop = element as CodeProperty; if ((prop.Getter == null) && (prop.Setter == null)) { //here we have an expression bodied property //if (m_IVsTextView != null) //{ // m_IVsTextView. //} } } #endif } //foreach #if DEBUG_OUTPUT System.Diagnostics.Debug.Print(" Found {0} string literals", stringResources.Count); #endif if (isFullDocument) { m_StringResources.AddRange(stringResources); } else if (stringResources.Count > 0) { m_StringResources.InsertRange(insertIndex, stringResources); } } //if m_DoCompleted(isFullDocument || (stringResources.Count > 0)); }