diff --git a/AddIns/ICSharpCode.SharpDevelop.addin b/AddIns/ICSharpCode.SharpDevelop.addin index 57efb98044..91bf0925de 100644 --- a/AddIns/ICSharpCode.SharpDevelop.addin +++ b/AddIns/ICSharpCode.SharpDevelop.addin @@ -1675,6 +1675,10 @@ class ="ICSharpCode.SharpDevelop.DefaultEditor.Commands.ShowBufferOptions"/> + + + + diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj index 9fad3eb460..c5322fdea8 100644 --- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj +++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj @@ -776,6 +776,7 @@ + @@ -804,4 +805,4 @@ - \ No newline at end of file + diff --git a/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs b/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs index f496fe98ad..0007a2d7e4 100644 --- a/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs +++ b/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs @@ -21,6 +21,8 @@ using System.Drawing; using System.Windows.Forms; using BM = ICSharpCode.SharpDevelop.Bookmarks; using ITextEditorControlProvider = ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor.ITextEditorControlProvider; +using ITextAreaToolTipProvider = ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor.ITextAreaToolTipProvider; +using ToolTipInfo = ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor.ToolTipInfo; namespace ICSharpCode.Core { @@ -282,6 +284,8 @@ namespace ICSharpCode.Core } #region Tool tips + const string ToolTipProviderAddInTreePath = "/SharpDevelop/ViewContent/DefaultTextEditor/ToolTips"; + static DebuggerGridControl oldToolTipControl; /// @@ -302,39 +306,28 @@ namespace ICSharpCode.Core } if (e.InDocument) { - Point logicPos = e.LogicalPosition; - IDocument doc = textArea.Document; - IExpressionFinder expressionFinder = ParserService.GetExpressionFinder(textArea.MotherTextEditorControl.FileName); - if (expressionFinder == null) - return; - LineSegment seg = doc.GetLineSegment(logicPos.Y); - if (logicPos.X > seg.Length - 1) - return; - string textContent = doc.TextContent; - ExpressionResult expressionResult = expressionFinder.FindFullExpression(textContent, seg.Offset + logicPos.X); - string expression = (expressionResult.Expression ?? "").Trim(); - if (expression.Length > 0) { - // Look if it is variable - ResolveResult result = ParserService.Resolve(expressionResult, logicPos.Y + 1, logicPos.X + 1, textArea.MotherTextEditorControl.FileName, textContent); - bool debuggerCanShowValue; - string toolTipText = GetText(result, expression, out debuggerCanShowValue); - if (toolTipText != null) { - if (Control.ModifierKeys == Keys.Control) { - toolTipText = "expr: " + expressionResult.ToString() + "\n" + toolTipText; - } else if (debuggerCanShowValue && currentDebugger != null) { - toolTipControl = currentDebugger.GetTooltipControl(expressionResult.Expression); - toolTipText = null; - } + + // Query all registered tooltip providers using the AddInTree. + // The first one that does not return null will be used. + ToolTipInfo ti = null; + foreach (ITextAreaToolTipProvider toolTipProvider in AddInTree.BuildItems(ToolTipProviderAddInTreePath, null, false)) { + if ((ti = toolTipProvider.GetToolTipInfo(textArea, e)) != null) { + break; } - if (toolTipText != null) { - e.ShowToolTip(toolTipText); - } - CloseOldToolTip(); - if (toolTipControl != null) { - toolTipControl.ShowForm(textArea, logicPos); + } + + if (ti != null) { + toolTipControl = ti.ToolTipControl; + if (ti.ToolTipText != null) { + e.ShowToolTip(ti.ToolTipText); } - oldToolTipControl = toolTipControl; } + CloseOldToolTip(); + if (toolTipControl != null) { + toolTipControl.ShowForm(textArea, e.LogicalPosition); + } + oldToolTipControl = toolTipControl; + } } catch (Exception ex) { ICSharpCode.Core.MessageService.ShowError(ex); @@ -365,6 +358,43 @@ namespace ICSharpCode.Core CloseOldToolTip(); } + /// + /// Gets debugger tooltip information for the specified position. + /// A descriptive text for the element or a DebuggerGridControl + /// showing its current value (when in debugging mode) can be returned + /// through the ToolTipInfo object. + /// Returns null, if no tooltip information is available. + /// + internal static ToolTipInfo GetToolTipInfo(TextArea textArea, ToolTipRequestEventArgs e) + { + Point logicPos = e.LogicalPosition; + IDocument doc = textArea.Document; + IExpressionFinder expressionFinder = ParserService.GetExpressionFinder(textArea.MotherTextEditorControl.FileName); + if (expressionFinder == null) + return null; + LineSegment seg = doc.GetLineSegment(logicPos.Y); + if (logicPos.X > seg.Length - 1) + return null; + string textContent = doc.TextContent; + ExpressionResult expressionResult = expressionFinder.FindFullExpression(textContent, seg.Offset + logicPos.X); + string expression = (expressionResult.Expression ?? "").Trim(); + if (expression.Length > 0) { + // Look if it is variable + ResolveResult result = ParserService.Resolve(expressionResult, logicPos.Y + 1, logicPos.X + 1, textArea.MotherTextEditorControl.FileName, textContent); + bool debuggerCanShowValue; + string toolTipText = GetText(result, expression, out debuggerCanShowValue); + if (toolTipText != null) { + if (Control.ModifierKeys == Keys.Control) { + toolTipText = "expr: " + expressionResult.ToString() + "\n" + toolTipText; + } else if (debuggerCanShowValue && currentDebugger != null) { + return new ToolTipInfo(currentDebugger.GetTooltipControl(expressionResult.Expression)); + } + return new ToolTipInfo(toolTipText); + } + } + return null; + } + static string GetText(ResolveResult result, string expression, out bool debuggerCanShowValue) { debuggerCanShowValue = false; @@ -464,4 +494,18 @@ namespace ICSharpCode.Core } #endregion } + + /// + /// Provides the default debugger tooltips on the text area. + /// + /// + /// This class must be public because it is accessed via the AddInTree. + /// + public class DebuggerTextAreaToolTipProvider : ITextAreaToolTipProvider + { + public ToolTipInfo GetToolTipInfo(TextArea textArea, ToolTipRequestEventArgs e) + { + return DebuggerService.GetToolTipInfo(textArea, e); + } + } } diff --git a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/ITextAreaToolTipProvider.cs b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/ITextAreaToolTipProvider.cs new file mode 100644 index 0000000000..1339bdcf26 --- /dev/null +++ b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/ITextAreaToolTipProvider.cs @@ -0,0 +1,74 @@ +// +// +// +// +// $Revision$ +// + +using System; + +using ICSharpCode.Core; +using ICSharpCode.TextEditor; + +namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor +{ + /// + /// Describes an object being able to provide tooltip information for + /// the text editor. + /// + public interface ITextAreaToolTipProvider + { + /// + /// Gets tooltip information for the specified position in the text area, + /// if available. + /// + /// null, if no tooltip information is available at this position, otherwise a ToolTipInfo object containing the tooltip information to be displayed. + ToolTipInfo GetToolTipInfo(TextArea textArea, ToolTipRequestEventArgs e); + } + + /// + /// Contains information about a tooltip to be shown on the text area. + /// + public class ToolTipInfo + { + object toolTipObject; + + /// + /// Gets the tool tip text to be displayed. + /// May be null. + /// + public string ToolTipText { + get { + return this.toolTipObject as string; + } + } + + /// + /// Gets the DebuggerGridControl to be shown as tooltip. + /// May be null. + /// + public DebuggerGridControl ToolTipControl { + get { + return this.toolTipObject as DebuggerGridControl; + } + } + + /// + /// Initializes a new instance of the class. + /// + /// The tooltip text to be displayed. + public ToolTipInfo(string toolTipText) + { + this.toolTipObject = toolTipText; + } + + /// + /// Initializes a new instance of the class. + /// + /// The DebuggerGridControl to be shown as tooltip. + public ToolTipInfo(DebuggerGridControl toolTipControl) + { + this.toolTipObject = toolTipControl; + } + } +}