Browse Source

Improve newline handling of XmlDocTooltipProvider.

pull/45/merge
Daniel Grunwald 12 years ago
parent
commit
560265cf61
  1. 97
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/XmlDoc/DocumentationUIBuilder.cs
  2. 4
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/XmlDoc/XmlDocTooltipProvider.cs

97
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/XmlDoc/DocumentationUIBuilder.cs

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text;
using System.Windows; using System.Windows;
using System.Windows.Documents; using System.Windows.Documents;
using System.Windows.Media; using System.Windows.Media;
@ -48,8 +49,10 @@ namespace ICSharpCode.AvalonEdit.AddIn.XmlDoc
this.ShowRemarks = true; this.ShowRemarks = true;
} }
public FlowDocument FlowDocument { public FlowDocument CreateFlowDocument()
get { return flowDocument; } {
FlushAddedText(true);
return flowDocument;
} }
public bool ShowExceptions { get; set; } public bool ShowExceptions { get; set; }
@ -163,6 +166,9 @@ namespace ICSharpCode.AvalonEdit.AddIn.XmlDoc
case "overloads": case "overloads":
// ignore children // ignore children
break; break;
case "br":
AddLineBreak();
break;
default: default:
foreach (var child in element.Children) foreach (var child in element.Children)
AddDocumentationElement(child); AddDocumentationElement(child);
@ -271,10 +277,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.XmlDoc
Inline ConvertReference(IEntity referencedEntity) Inline ConvertReference(IEntity referencedEntity)
{ {
var h = new Hyperlink(new Run(ambience.ConvertEntity(referencedEntity))); var h = new Hyperlink(new Run(ambience.ConvertEntity(referencedEntity)));
h.Click += delegate(object sender, RoutedEventArgs e) { h.Click += CreateNavigateOnClickHandler(referencedEntity);
SharpDevelop.NavigationService.NavigateTo(referencedEntity);
e.Handled = true;
};
return h; return h;
} }
@ -309,10 +312,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.XmlDoc
if (referencedEntity != null) { if (referencedEntity != null) {
if (element.Children.Any()) { if (element.Children.Any()) {
Hyperlink link = new Hyperlink(); Hyperlink link = new Hyperlink();
link.Click += delegate(object sender, RoutedEventArgs e) { link.Click += CreateNavigateOnClickHandler(referencedEntity);
SharpDevelop.NavigationService.NavigateTo(referencedEntity);
e.Handled = true;
};
AddSpan(link, element.Children); AddSpan(link, element.Children);
} else { } else {
AddInline(ConvertReference(referencedEntity)); AddInline(ConvertReference(referencedEntity));
@ -334,6 +334,20 @@ namespace ICSharpCode.AvalonEdit.AddIn.XmlDoc
} }
} }
RoutedEventHandler CreateNavigateOnClickHandler(IEntity referencedEntity)
{
// Don't let the anonymous method capture the referenced entity
// (we don't want to keep the whole compilation in memory)
// Use the IEntityModel instead.
var model = referencedEntity.GetModel();
return delegate(object sender, RoutedEventArgs e) {
IEntity resolvedEntity = model != null ? model.Resolve() : null;
if (resolvedEntity != null)
SharpDevelop.NavigationService.NavigateTo(resolvedEntity);
e.Handled = true;
};
}
void AddSection(string title, IEnumerable<XmlDocumentationElement> children) void AddSection(string title, IEnumerable<XmlDocumentationElement> children)
{ {
AddSection(new Run(title), children); AddSection(new Run(title), children);
@ -351,7 +365,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.XmlDoc
void AddSection(Inline title, Action addChildren) void AddSection(Inline title, Action addChildren)
{ {
var section = new Section(); var section = new Section();
blockCollection.Add(section); AddBlock(section);
var oldBlockCollection = blockCollection; var oldBlockCollection = blockCollection;
try { try {
blockCollection = section.Blocks; blockCollection = section.Blocks;
@ -370,7 +384,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.XmlDoc
void AddParagraph(Paragraph para, IEnumerable<XmlDocumentationElement> children) void AddParagraph(Paragraph para, IEnumerable<XmlDocumentationElement> children)
{ {
blockCollection.Add(para); AddBlock(para);
try { try {
inlineCollection = para.Inlines; inlineCollection = para.Inlines;
@ -414,25 +428,64 @@ namespace ICSharpCode.AvalonEdit.AddIn.XmlDoc
blockCollection.Add(block); blockCollection.Add(block);
} }
string addedText; StringBuilder addedText = new StringBuilder();
bool ignoreWhitespace;
public void AddLineBreak()
{
TrimEndOfAddedText();
addedText.AppendLine();
ignoreWhitespace = true;
}
public void AddText(string textContent) public void AddText(string textContent)
{ {
if (string.IsNullOrEmpty(textContent)) if (string.IsNullOrEmpty(textContent))
return; return;
if (inlineCollection == null && string.IsNullOrWhiteSpace(textContent)) for (int i = 0; i < textContent.Length; i++) {
return; char c = textContent[i];
FlushAddedText(false); if (c == '\n' && IsEmptyLineBefore(textContent, i)) {
addedText = textContent; AddLineBreak(); // empty line -> line break
} else if (char.IsWhiteSpace(c)) {
// any whitespace sequence gets converted to a single space (like HTML)
if (!ignoreWhitespace) {
addedText.Append(' ');
ignoreWhitespace = true;
}
} else {
addedText.Append(c);
ignoreWhitespace = false;
}
}
}
bool IsEmptyLineBefore(string text, int i)
{
// Skip previous whitespace
do {
i--;
} while (i >= 0 && (text[i] == ' ' || text[i] == '\r'));
// Check if previous non-whitespace char is \n
return i >= 0 && text[i] == '\n';
}
void TrimEndOfAddedText()
{
while (addedText.Length > 0 && addedText[addedText.Length - 1] == ' ') {
addedText.Length--;
}
} }
void FlushAddedText(bool trimEnd) void FlushAddedText(bool trim)
{ {
if (addedText == null) if (trim) // trim end of current text element
TrimEndOfAddedText();
if (addedText.Length == 0)
return; return;
string text = addedText; string text = addedText.ToString();
addedText = null; addedText.Length = 0;
AddInline(new Run(trimEnd ? text.TrimEnd() : text)); AddInline(new Run(text));
ignoreWhitespace = trim; // trim start of next text element
} }
} }
} }

4
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/XmlDoc/XmlDocTooltipProvider.cs

@ -91,7 +91,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.XmlDoc
} }
} }
} }
return new FlowDocumentTooltip(b.FlowDocument); return new FlowDocumentTooltip(b.CreateFlowDocument());
} }
object CreateTooltip(IEntity entity) object CreateTooltip(IEntity entity)
@ -109,7 +109,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.XmlDoc
b.AddDocumentationElement(child); b.AddDocumentationElement(child);
} }
} }
return new FlowDocumentTooltip(b.FlowDocument); return new FlowDocumentTooltip(b.CreateFlowDocument());
} }
} }
} }

Loading…
Cancel
Save