From 4c0a1d18fec336694f82ce302abdbfcc7d2cb397 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Fri, 10 Jan 2014 21:55:56 +0100 Subject: [PATCH] add XmlDoc to Insight tooltips --- .../Project/CSharpBinding.csproj | 4 ++ .../Src/Completion/CSharpInsightItem.cs | 54 +++++++++++++++---- .../Utils/DocumentPrinter.cs | 48 +++++++++++++---- .../Project/Editor/DocumentationUIBuilder.cs | 15 ++++++ 4 files changed, 99 insertions(+), 22 deletions(-) diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj index dac7e045bc..eb1f315630 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj @@ -180,6 +180,10 @@ ICSharpCode.NRefactory.CSharp False + + {DC393B66-92ED-4CAD-AB25-CFEF23F3D7C6} + ICSharpCode.NRefactory.Xml + {3B2A5653-EC97-4001-BB9B-D90F1AF2C371} ICSharpCode.NRefactory diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpInsightItem.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpInsightItem.cs index 3ff19aafe6..cd46f7fee9 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpInsightItem.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpInsightItem.cs @@ -10,6 +10,8 @@ using System.Windows.Controls; using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.NRefactory.Xml; +using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Editor.CodeCompletion; namespace CSharpBinding.Completion @@ -23,13 +25,12 @@ namespace CSharpBinding.Completion this.Method = method; } - TextBlock header; + FlowDocumentScrollViewer header; public object Header { get { if (header == null) { - header = new TextBlock(); - GenerateHeader(); + header = GenerateHeader(); } return header; } @@ -43,25 +44,56 @@ namespace CSharpBinding.Completion return; this.highlightedParameterIndex = parameterIndex; if (header != null) - GenerateHeader(); + header = GenerateHeader(); } - void GenerateHeader() + FlowDocumentScrollViewer GenerateHeader() { CSharpAmbience ambience = new CSharpAmbience(); ambience.ConversionFlags = ConversionFlags.StandardConversionFlags; var stringBuilder = new StringBuilder(); var formatter = new ParameterHighlightingOutputFormatter(stringBuilder, highlightedParameterIndex); ambience.ConvertEntity(Method, formatter, FormattingOptionsFactory.CreateSharpDevelop()); - string code = stringBuilder.ToString(); - var inlineBuilder = new RichTextModel(); - inlineBuilder.SetFontWeight(formatter.parameterStartOffset, formatter.parameterLength, FontWeights.Bold); - header.Inlines.Clear(); - header.Inlines.AddRange(new RichText(code, inlineBuilder).CreateRuns()); + + var documentation = XmlDocumentationElement.Get(Method); + ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList; + + DocumentationUIBuilder b = new DocumentationUIBuilder(ambience); + string parameterName = null; + if (Method.Parameters.Count > highlightedParameterIndex) + parameterName = Method.Parameters[highlightedParameterIndex].Name; + b.AddSignatureBlock(stringBuilder.ToString(), formatter.parameterStartOffset, formatter.parameterLength, parameterName); + + DocumentationUIBuilder b2 = new DocumentationUIBuilder(ambience); + b2.ParameterName = parameterName; + b2.ShowAllParameters = false; + + if (documentation != null) { + foreach (var child in documentation.Children) { + b2.AddDocumentationElement(child); + } + } + + content = new FlowDocumentScrollViewer { + Document = b2.CreateFlowDocument(), + VerticalScrollBarVisibility = ScrollBarVisibility.Auto + }; + + return new FlowDocumentScrollViewer { + Document = b.CreateFlowDocument(), + VerticalScrollBarVisibility = ScrollBarVisibility.Auto + }; } + FlowDocumentScrollViewer content; + public object Content { - get { return null; } + get { + if (content == null) { + GenerateHeader(); + } + return content; + } } sealed class ParameterHighlightingOutputFormatter : TextWriterTokenWriter diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/DocumentPrinter.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/DocumentPrinter.cs index 44fef34e19..819e1f906a 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/DocumentPrinter.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/DocumentPrinter.cs @@ -2,6 +2,7 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using System.Collections.Generic; using System.IO; using System.IO.Packaging; using System.Printing; @@ -35,28 +36,18 @@ namespace ICSharpCode.AvalonEdit.Utils } /// - /// Converts a readonly TextDocument to a Block and applies the provided highlighter. + /// Converts an IDocument to a Block and applies the provided highlighter. /// public static Block ConvertTextDocumentToBlock(IDocument document, IHighlighter highlighter) { if (document == null) throw new ArgumentNullException("document"); -// Table table = new Table(); -// table.Columns.Add(new TableColumn { Width = GridLength.Auto }); -// table.Columns.Add(new TableColumn { Width = new GridLength(1, GridUnitType.Star) }); -// TableRowGroup trg = new TableRowGroup(); -// table.RowGroups.Add(trg); Paragraph p = new Paragraph(); p.TextAlignment = TextAlignment.Left; for (int lineNumber = 1; lineNumber <= document.LineCount; lineNumber++) { if (lineNumber > 1) p.Inlines.Add(new LineBreak()); var line = document.GetLineByNumber(lineNumber); -// TableRow row = new TableRow(); -// trg.Rows.Add(row); -// row.Cells.Add(new TableCell(new Paragraph(new Run(lineNumber.ToString()))) { TextAlignment = TextAlignment.Right }); -// Paragraph p = new Paragraph(); -// row.Cells.Add(new TableCell(p)); if (highlighter != null) { HighlightedLine highlightedLine = highlighter.HighlightLine(lineNumber); p.Inlines.AddRange(highlightedLine.ToRichText().CreateRuns()); @@ -67,6 +58,41 @@ namespace ICSharpCode.AvalonEdit.Utils return p; } + /// + /// Converts a readonly TextDocument to a RichText and applies the provided highlighting definition. + /// + public static RichText ConvertTextDocumentToRichText(ReadOnlyDocument document, IHighlightingDefinition highlightingDefinition) + { + IHighlighter highlighter; + if (highlightingDefinition != null) + highlighter = new DocumentHighlighter(document, highlightingDefinition); + else + highlighter = null; + return ConvertTextDocumentToRichText(document, highlighter); + } + + /// + /// Converts an IDocument to a RichText and applies the provided highlighter. + /// + public static RichText ConvertTextDocumentToRichText(IDocument document, IHighlighter highlighter) + { + if (document == null) + throw new ArgumentNullException("document"); + var texts = new List(); + for (int lineNumber = 1; lineNumber <= document.LineCount; lineNumber++) { + var line = document.GetLineByNumber(lineNumber); + if (lineNumber > 1) + texts.Add(line.PreviousLine.DelimiterLength == 2 ? "\r\n" : "\n"); + if (highlighter != null) { + HighlightedLine highlightedLine = highlighter.HighlightLine(lineNumber); + texts.Add(highlightedLine.ToRichText()); + } else { + texts.Add(document.GetText(line)); + } + } + return RichText.Concat(texts.ToArray()); + } + /// /// Creates a flow document from the editor's contents. /// diff --git a/src/Main/Base/Project/Editor/DocumentationUIBuilder.cs b/src/Main/Base/Project/Editor/DocumentationUIBuilder.cs index e5e0a0552c..9d09c3883d 100644 --- a/src/Main/Base/Project/Editor/DocumentationUIBuilder.cs +++ b/src/Main/Base/Project/Editor/DocumentationUIBuilder.cs @@ -214,6 +214,21 @@ namespace ICSharpCode.SharpDevelop.Editor AddBlock(block); } + public void AddSignatureBlock(string signature, int currentParameterOffset, int currentParameterLength, string currentParameterName) + { + ParameterName = currentParameterName; + var document = new ReadOnlyDocument(signature); + var highlightingDefinition = HighlightingManager.Instance.GetDefinition("C#"); + + var richText = DocumentPrinter.ConvertTextDocumentToRichText(document, highlightingDefinition).ToRichTextModel(); + richText.SetFontWeight(currentParameterOffset, currentParameterLength, FontWeights.Bold); + var block = new Paragraph(); + block.Inlines.AddRange(new RichText(signature, richText).CreateRuns()); // TODO richText.CreateRuns(document) + block.FontFamily = GetCodeFont(); + block.TextAlignment = TextAlignment.Left; + AddBlock(block); + } + bool? ParseBool(string input) { bool result;