/// <summary> /// This is used to get the content to add to the quick info by looking up the given topic ID to get its /// title and filename if possible. /// </summary> /// <param name="elementName">The element name for which to create content</param> /// <param name="id">The ID to look up if necessary</param> /// <returns>The content to add to the quick info (a text block element containing the additional info /// about the element)</returns> private UIElement CreateInfoText(string elementName, string id) { if(String.IsNullOrWhiteSpace(elementName) || String.IsNullOrWhiteSpace(id)) return null; var textBlock = new TextBlock(); switch(elementName) { case "conceptualLink": var projectFileSearcher = new ProjectFileSearcher(serviceProvider, null); string title, filename, relativePath; bool found = projectFileSearcher.GetInfoFor(ProjectFileSearcher.IdType.Link, id, out title, out filename, out relativePath); textBlock.Inlines.AddRange(new Inline[] { new Bold(new Run("Title: ")), new Run(title), new LineBreak(), new Bold(new Run("Filename: ")), new Run(relativePath) }); if(found && ctrlClickEnabled) textBlock.Inlines.AddRange(new Inline[] { new LineBreak(), new Run("Ctrl+Click to open the file") }); break; case "cref": if(!ctrlClickEnabled) return null; if(!IntelliSense.RoslynHacks.RoslynUtilities.IsFinalRoslyn) textBlock.Inlines.Add(new Run("Ctrl+Click to go to definition (within solution only)")); else textBlock.Inlines.Add(new Run("Ctrl+Click to go to definition")); break; default: if(!ctrlClickEnabled) return null; textBlock.Inlines.Add(new Run("Ctrl+Click to open the containing file")); break; } // Set the styles in order to support other themes textBlock.SetResourceReference(TextBlock.BackgroundProperty, EnvironmentColors.ToolTipBrushKey); textBlock.SetResourceReference(TextBlock.ForegroundProperty, EnvironmentColors.ToolTipTextBrushKey); return textBlock; }
/// <summary> /// This is used to get the content to add to the quick info by looking up the given topic ID to get its /// title and filename if possible. /// </summary> /// <param name="elementName">The element name for which to create content</param> /// <param name="id">The ID to look up if necessary</param> /// <returns>The content to add to the quick info (a text block element containing the additional info /// about the element)</returns> private UIElement CreateInfoText(string elementName, string id) { if (String.IsNullOrWhiteSpace(elementName) || String.IsNullOrWhiteSpace(id)) { return(null); } var textBlock = new TextBlock(); switch (elementName) { case "conceptualLink": var projectFileSearcher = new ProjectFileSearcher(serviceProvider, null); string title, filename, relativePath; #pragma warning disable VSTHRD010 bool found = projectFileSearcher.GetInfoFor(ProjectFileSearcher.IdType.Link, id, out title, out filename, out relativePath); #pragma warning restore VSTHRD010 textBlock.Inlines.AddRange(new Inline[] { new Bold(new Run("Title: ")), new Run(title), new LineBreak(), new Bold(new Run("Filename: ")), new Run(relativePath) }); if (found && ctrlClickEnabled) { textBlock.Inlines.AddRange(new Inline[] { new LineBreak(), new Run("Ctrl+Click to open the file") }); } break; default: if (!ctrlClickEnabled) { return(null); } textBlock.Inlines.Add(new Run("Ctrl+Click to open the containing file")); break; } // Set the styles in order to support other themes textBlock.SetResourceReference(TextBlock.BackgroundProperty, EnvironmentColors.ToolTipBrushKey); textBlock.SetResourceReference(TextBlock.ForegroundProperty, EnvironmentColors.ToolTipTextBrushKey); return(textBlock); }
/// <summary> /// This is used to get the content to add to the quick info by looking up the given topic ID to get its /// title and filename if possible. /// </summary> /// <param name="elementName">The element name for which to create content</param> /// <param name="id">The ID to look up if necessary</param> /// <returns>The content to add to the quick info (a text block element containing the additional info /// about the element)</returns> private UIElement CreateInfoText(string elementName, string id) { if (String.IsNullOrWhiteSpace(elementName) || String.IsNullOrWhiteSpace(id)) { return(null); } var textBlock = new TextBlock(); switch (elementName) { case "image": case "link": case "topic": var projectFileSearcher = new ProjectFileSearcher(serviceProvider, null); string title, filename, relativePath; bool found = projectFileSearcher.GetInfoFor(elementName == "image" ? ProjectFileSearcher.IdType.Image : ProjectFileSearcher.IdType.Link, id, out title, out filename, out relativePath); textBlock.Inlines.AddRange(new Inline[] { new Bold(new Run(elementName == "image" ? "Alternate Text: " : "Title: ")), new Run(title), new LineBreak(), new Bold(new Run("Filename: ")), new Run(relativePath) }); break; case "codeEntityReference": break; default: break; } // Set the styles in order to support other themes in VS 2012 and later object themeKey = Utility.GetThemeKey("ToolTipBrushKey", SystemColors.ControlLightBrushKey); if (themeKey != null) { textBlock.SetResourceReference(TextBlock.BackgroundProperty, themeKey); textBlock.SetResourceReference(TextBlock.ForegroundProperty, Utility.GetThemeKey("ToolTipTextBrushKey", SystemColors.ControlTextBrushKey)); } return(textBlock); }
/// <inheritdoc /> protected override void GoToDefinition(string id, string definitionType) { switch(definitionType) { case "codeEntityReference": if(!IntelliSense.RoslynHacks.RoslynUtilities.IsFinalRoslyn || (id.Length > 2 && id[1] == ':')) { var entitySearcher = new CodeEntitySearcher(this.ServiceProvider); if(!entitySearcher.GotoDefinitionFor(id)) { Guid clsid = Guid.Empty; int result; var uiShell = this.ServiceProvider.GetService(typeof(SVsUIShell)) as IVsUIShell; if(uiShell != null) uiShell.ShowMessageBox(0, ref clsid, "Unable to navigate to XML comments member " + "definition.", String.Format(CultureInfo.CurrentCulture, "Member ID: {0}\r\n\r\n" + "If valid, the most likely cause is that it is not a member of a C# project " + "within the current solution. Navigating to members in non-C# projects and " + ".NET Framework or reference assemblies is not supported.", id), String.Empty, 0, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, OLEMSGICON.OLEMSGICON_INFO, 0, out result); System.Diagnostics.Debug.WriteLine("Unable to go to declaration for member ID: " + id); } } else { // VS2015 and later do support actual Go To Definition on cref targets in XML comments Guid cmdGroup = VSConstants.GUID_VSStandardCommandSet97; var shellCommandDispatcher = this.ServiceProvider.GetService( typeof(SUIHostCommandDispatcher)) as IOleCommandTarget; shellCommandDispatcher.Exec(ref cmdGroup, (uint)VSConstants.VSStd97CmdID.GotoDefn, (uint)OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT, System.IntPtr.Zero, System.IntPtr.Zero); } break; case "link": case "token": var projectFileSearcher = new ProjectFileSearcher(this.ServiceProvider, this.TextView); ProjectFileSearcher.IdType idType; if(!Enum.TryParse(definitionType, true, out idType)) idType = ProjectFileSearcher.IdType.Unknown; if(!projectFileSearcher.OpenFileFor(idType, id)) { if(idType == ProjectFileSearcher.IdType.Link) definitionType = "conceptualLink"; Guid clsid = Guid.Empty; int result; var uiShell = this.ServiceProvider.GetService(typeof(SVsUIShell)) as IVsUIShell; if(uiShell != null) uiShell.ShowMessageBox(0, ref clsid, "Unable to open file for XML comments element " + "target.", String.Format(CultureInfo.CurrentCulture, "Type: {0}\r\nID: {1}\r\n\r\n" + "If valid, it may not be a part of a help file builder project within this " + "solution.", definitionType, id), String.Empty, 0, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, OLEMSGICON.OLEMSGICON_INFO, 0, out result); System.Diagnostics.Debug.WriteLine("Unable to go to open file for ID '{0}' ({1}): ", id, definitionType); } break; default: break; } }
/// <summary> /// This is used to go to the definition based on the span under the cursor /// </summary> /// <param name="id">The ID of the definition to go to</param> /// <param name="definitionType">A definition type to further classify the ID</param> private void GoToDefinition(string id, string definitionType) { switch (definitionType) { case "codeEntityReference": if (!IntelliSense.RoslynHacks.RoslynUtilities.IsFinalRoslyn || !isCodeFile || (id.Length > 2 && id[1] == ':')) { var entitySearcher = new CodeEntitySearcher(provider.ServiceProvider); if (!entitySearcher.GotoDefinitionFor(id)) { Guid clsid = Guid.Empty; int result; var uiShell = provider.ServiceProvider.GetService(typeof(SVsUIShell)) as IVsUIShell; if (uiShell != null) { uiShell.ShowMessageBox(0, ref clsid, "Unable to navigate to XML comments member " + "definition.", String.Format(CultureInfo.CurrentCulture, "Member ID: {0}\r\n\r\n" + "If valid, the most likely cause is that it is not a member of a C# project " + "within the current solution. Navigating to members in non-C# projects and " + ".NET Framework or reference assemblies is not supported.", id), String.Empty, 0, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, OLEMSGICON.OLEMSGICON_INFO, 0, out result); } System.Diagnostics.Debug.WriteLine("Unable to go to declaration for member ID: " + id); } } else { // VS2015 and later do support actual Go To Definition on cref targets in XML comments Guid cmdGroup = VSConstants.GUID_VSStandardCommandSet97; var shellCommandDispatcher = provider.ServiceProvider.GetService( typeof(SUIHostCommandDispatcher)) as IOleCommandTarget; shellCommandDispatcher.Exec(ref cmdGroup, (uint)VSConstants.VSStd97CmdID.GotoDefn, (uint)OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT, System.IntPtr.Zero, System.IntPtr.Zero); } break; case "codeReference": case "conceptualLink": case "image": case "link": case "token": var projectFileSearcher = new ProjectFileSearcher(provider.ServiceProvider, textView); ProjectFileSearcher.IdType idType; if (definitionType == "conceptualLink") { idType = ProjectFileSearcher.IdType.Link; } else if (!Enum.TryParse(definitionType, true, out idType)) { idType = ProjectFileSearcher.IdType.Unknown; } if (!projectFileSearcher.OpenFileFor(idType, id)) { Guid clsid = Guid.Empty; int result; var uiShell = provider.ServiceProvider.GetService(typeof(SVsUIShell)) as IVsUIShell; if (uiShell != null) { uiShell.ShowMessageBox(0, ref clsid, "Unable to open file for element target.", String.Format(CultureInfo.CurrentCulture, "Type: {0}\r\nID: {1}\r\n\r\nIf " + "valid, it may not be a part of a help file builder project within this " + "solution.", definitionType, id), String.Empty, 0, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, OLEMSGICON.OLEMSGICON_INFO, 0, out result); } System.Diagnostics.Debug.WriteLine("Unable to go to open file for ID '{0}' ({1}): ", id, definitionType); } break; default: break; } }
private void GoToDefinition(string id, string definitionType) { switch (definitionType) { case "codeEntityReference": var entitySearcher = new CodeEntitySearcher(_provider.ServiceProvider); if (!entitySearcher.GotoDefinitionFor(id)) { Guid clsid = Guid.Empty; int result; var uiShell = _provider.ServiceProvider.GetService(typeof(SVsUIShell)) as IVsUIShell; if (uiShell != null) { uiShell.ShowMessageBox(0, ref clsid, "Unable to navigate to code entity reference " + "definition.", String.Format(CultureInfo.CurrentCulture, "Member ID: {0}\r\n\r\n" + "If valid, the most likely cause is that it is not a member of a C# project " + "within the current solution. Navigating to members in non-C# projects and " + ".NET Framework or reference assemblies is not supported.", id), String.Empty, 0, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, OLEMSGICON.OLEMSGICON_INFO, 0, out result); } System.Diagnostics.Debug.WriteLine("Unable to go to declaration for member ID: " + id); } break; case "codeReference": case "image": case "link": case "token": var projectFileSearcher = new ProjectFileSearcher(_provider.ServiceProvider, _textView); ProjectFileSearcher.IdType idType; if (!Enum.TryParse(definitionType, true, out idType)) { idType = ProjectFileSearcher.IdType.Unknown; } if (!projectFileSearcher.OpenFileFor(idType, id)) { if (idType == ProjectFileSearcher.IdType.Link) { definitionType = "conceptualLink"; } Guid clsid = Guid.Empty; int result; var uiShell = _provider.ServiceProvider.GetService(typeof(SVsUIShell)) as IVsUIShell; if (uiShell != null) { uiShell.ShowMessageBox(0, ref clsid, "Unable to open file for element target.", String.Format(CultureInfo.CurrentCulture, "Type: {0}\r\nID: {1}\r\n\r\nIf " + "valid, it may not be a part of a help file builder project within this " + "solution.", definitionType, id), String.Empty, 0, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, OLEMSGICON.OLEMSGICON_INFO, 0, out result); } System.Diagnostics.Debug.WriteLine("Unable to go to open file for ID '{0}' ({1}): ", id, definitionType); } break; default: break; } }
/// <summary> /// This is used to get the content to add to the quick info by looking up the given topic ID to get its /// title and filename if possible. /// </summary> /// <param name="elementName">The element name for which to create content</param> /// <param name="id">The ID to look up if necessary</param> /// <returns>The content to add to the quick info (a text block element containing the additional info /// about the element)</returns> private UIElement CreateInfoText(string elementName, string id) { if(String.IsNullOrWhiteSpace(elementName) || String.IsNullOrWhiteSpace(id)) return null; var textBlock = new TextBlock(); switch(elementName) { case "conceptualLink": var projectFileSearcher = new ProjectFileSearcher(serviceProvider, null); string title, filename, relativePath; bool found = projectFileSearcher.GetInfoFor(ProjectFileSearcher.IdType.Link, id, out title, out filename, out relativePath); textBlock.Inlines.AddRange(new Inline[] { new Bold(new Run("Title: ")), new Run(title), new LineBreak(), new Bold(new Run("Filename: ")), new Run(relativePath) }); break; case "cref": break; default: break; } // Set the styles in order to support other themes in VS 2012 and later object themeKey = Utility.GetThemeKey("ToolTipBrushKey", SystemColors.ControlLightBrushKey); if(themeKey != null) { textBlock.SetResourceReference(TextBlock.BackgroundProperty, themeKey); textBlock.SetResourceReference(TextBlock.ForegroundProperty, Utility.GetThemeKey("ToolTipTextBrushKey", SystemColors.ControlTextBrushKey)); } return textBlock; }
/// <inheritdoc /> protected override void GoToDefinition(string id, string definitionType) { switch(definitionType) { case "codeEntityReference": var entitySearcher = new CodeEntitySearcher(this.ServiceProvider); if(!entitySearcher.GotoDefinitionFor(id)) { Guid clsid = Guid.Empty; int result; var uiShell = this.ServiceProvider.GetService(typeof(SVsUIShell)) as IVsUIShell; if(uiShell != null) uiShell.ShowMessageBox(0, ref clsid, "Unable to navigate to code entity reference " + "definition.", String.Format(CultureInfo.CurrentCulture, "Member ID: {0}\r\n\r\n" + "If valid, the most likely cause is that it is not a member of a C# project " + "within the current solution. Navigating to members in non-C# projects and " + ".NET Framework or reference assemblies is not supported.", id), String.Empty, 0, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, OLEMSGICON.OLEMSGICON_INFO, 0, out result); System.Diagnostics.Debug.WriteLine("Unable to go to declaration for member ID: " + id); } break; case "codeReference": case "image": case "link": case "token": var projectFileSearcher = new ProjectFileSearcher(this.ServiceProvider, this.TextView); ProjectFileSearcher.IdType idType; if(!Enum.TryParse(definitionType, true, out idType)) idType = ProjectFileSearcher.IdType.Unknown; if(!projectFileSearcher.OpenFileFor(idType, id)) { Guid clsid = Guid.Empty; int result; var uiShell = this.ServiceProvider.GetService(typeof(SVsUIShell)) as IVsUIShell; if(uiShell != null) uiShell.ShowMessageBox(0, ref clsid, "Unable to open file for element target.", String.Format(CultureInfo.CurrentCulture, "Type: {0}\r\nID: {1}\r\n\r\nIf " + "valid, it may not be a part of a help file builder project within this " + "solution.", definitionType, id), String.Empty, 0, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, OLEMSGICON.OLEMSGICON_INFO, 0, out result); System.Diagnostics.Debug.WriteLine("Unable to go to open file for ID '{0}' ({1}): ", id, definitionType); } break; default: break; } }
/// <summary> /// This is used to get the content to add to the quick info by looking up the given topic ID to get its /// title and filename if possible. /// </summary> /// <param name="elementName">The element name for which to create content</param> /// <param name="id">The ID to look up if necessary</param> /// <returns>The content to add to the quick info (a text block element containing the additional info /// about the element)</returns> private UIElement CreateInfoText(string elementName, string id) { if(String.IsNullOrWhiteSpace(elementName) || String.IsNullOrWhiteSpace(id)) return null; var textBlock = new TextBlock(); switch(elementName) { case "image": case "link": case "topic": var projectFileSearcher = new ProjectFileSearcher(serviceProvider, null); string title, filename, relativePath; bool found = projectFileSearcher.GetInfoFor(elementName == "image" ? ProjectFileSearcher.IdType.Image : ProjectFileSearcher.IdType.Link, id, out title, out filename, out relativePath); textBlock.Inlines.AddRange(new Inline[] { new Bold(new Run(elementName == "image" ? "Alternate Text: " : "Title: ")), new Run(title), new LineBreak(), new Bold(new Run("Filename: ")), new Run(relativePath) }); if(elementName != "topic" && found & ctrlClickEnabled) textBlock.Inlines.AddRange(new Inline[] { new LineBreak(), new Run("Ctrl+Click to open the file") }); break; case "codeEntityReference": if(!ctrlClickEnabled) return null; textBlock.Inlines.Add(new Run("Ctrl+Click to go to definition (within solution only)")); break; default: if(!ctrlClickEnabled) return null; textBlock.Inlines.Add(new Run("Ctrl+Click to open the containing file")); break; } // Set the styles in order to support other themes textBlock.SetResourceReference(TextBlock.BackgroundProperty, EnvironmentColors.ToolTipBrushKey); textBlock.SetResourceReference(TextBlock.ForegroundProperty, EnvironmentColors.ToolTipTextBrushKey); return textBlock; }
/// <summary> /// This is used to get the content to add to the quick info by looking up the given topic ID to get its /// title and filename if possible. /// </summary> /// <param name="elementName">The element name for which to create content</param> /// <param name="id">The ID to look up if necessary</param> /// <returns>The content to add to the quick info (a text block element containing the additional info /// about the element)</returns> private UIElement CreateInfoText(string elementName, string id) { if (String.IsNullOrWhiteSpace(elementName) || String.IsNullOrWhiteSpace(id)) { return(null); } var textBlock = new TextBlock(); switch (elementName) { case "image": case "link": case "topic": var projectFileSearcher = new ProjectFileSearcher(serviceProvider, null); string title, filename, relativePath; bool found = projectFileSearcher.GetInfoFor(elementName == "image" ? ProjectFileSearcher.IdType.Image : ProjectFileSearcher.IdType.Link, id, out title, out filename, out relativePath); textBlock.Inlines.AddRange(new Inline[] { new Bold(new Run(elementName == "image" ? "Alternate Text: " : "Title: ")), new Run(title), new LineBreak(), new Bold(new Run("Filename: ")), new Run(relativePath) }); if (elementName != "topic" && found & ctrlClickEnabled) { textBlock.Inlines.AddRange(new Inline[] { new LineBreak(), new Run("Ctrl+Click to open the file") }); } break; case "codeEntityReference": if (!ctrlClickEnabled) { return(null); } textBlock.Inlines.Add(new Run("Ctrl+Click to go to definition (within solution only)")); break; default: if (!ctrlClickEnabled) { return(null); } textBlock.Inlines.Add(new Run("Ctrl+Click to open the containing file")); break; } // Set the styles in order to support other themes textBlock.SetResourceReference(TextBlock.BackgroundProperty, EnvironmentColors.ToolTipBrushKey); textBlock.SetResourceReference(TextBlock.ForegroundProperty, EnvironmentColors.ToolTipTextBrushKey); return(textBlock); }