Browse Source

Fix HighlightingColorizer.OnHighlightStateChanged ignoring some change notifications.

newNRvisualizers
Daniel Grunwald 13 years ago
parent
commit
cfa01c3986
  1. 4
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpSemanticHighlighter.cs
  2. 2
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/IssueManager.cs
  3. 4
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditorControlService.cs
  4. 57
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CustomizingHighlighter.cs
  5. 5
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/DiffControl.xaml.cs
  6. 4
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Options/HighlightingOptions.xaml.cs
  7. 5
      src/AddIns/DisplayBindings/XmlEditor/Test/Utils/MockDocument.cs
  8. 5
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/DocumentHighlighter.cs
  9. 29
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightingColorizer.cs
  10. 25
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/IHighlighter.cs
  11. 4
      src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/ProjectOptions/ApplicationSettings.xaml.cs
  12. 4
      src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/ProjectOptions/Signing.xaml.cs

4
src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpSemanticHighlighter.cs

@ -167,7 +167,7 @@ namespace CSharpBinding @@ -167,7 +167,7 @@ namespace CSharpBinding
cachedLines.Clear();
invalidLines.Clear();
forceParseOnNextRefresh = true;
OnHighlightingStateChanged(0, document.LineCount);
OnHighlightingStateChanged(1, document.LineCount);
}
void ParserService_ParseInformationUpdated(object sender, ParseInformationEventArgs e)
@ -190,7 +190,7 @@ namespace CSharpBinding @@ -190,7 +190,7 @@ namespace CSharpBinding
protected virtual void OnHighlightingStateChanged(int fromLineNumber, int toLineNumber)
{
if (HighlightingStateChanged != null) {
HighlightingStateChanged(this, fromLineNumber, toLineNumber);
HighlightingStateChanged(fromLineNumber, toLineNumber);
}
}

2
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/IssueManager.cs

@ -3,7 +3,6 @@ @@ -3,7 +3,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@ -17,7 +16,6 @@ using ICSharpCode.NRefactory.CSharp.Refactoring; @@ -17,7 +16,6 @@ using ICSharpCode.NRefactory.CSharp.Refactoring;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Parser;
using ICSharpCode.SharpDevelop.Refactoring;

4
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditorControlService.cs

@ -52,9 +52,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -52,9 +52,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
// add additional highlighters
highlighters.AddRange(SD.AddInTree.BuildItems<IHighlighter>(HighlighterDoozer.AddInPath, document, false));
var multiHighlighter = new MultiHighlighter(document, highlighters.ToArray());
return new CustomizingHighlighter(
document, CustomizedHighlightingColor.FetchCustomizations(def.Name),
multiHighlighter);
return new CustomizingHighlighter(multiHighlighter, CustomizedHighlightingColor.FetchCustomizations(def.Name));
}
}

57
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CustomizingHighlighter.cs

@ -121,59 +121,34 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -121,59 +121,34 @@ namespace ICSharpCode.AvalonEdit.AddIn
}
#endregion
readonly TextView textView;
readonly IEnumerable<CustomizedHighlightingColor> customizations;
readonly IHighlighter baseHighlighter;
readonly IDocument document;
public CustomizingHighlighter(TextView textView, IEnumerable<CustomizedHighlightingColor> customizations, IHighlighter baseHighlighter)
public CustomizingHighlighter(IHighlighter baseHighlighter, IEnumerable<CustomizedHighlightingColor> customizations)
{
if (textView == null)
throw new ArgumentNullException("textView");
if (customizations == null)
throw new ArgumentNullException("customizations");
if (baseHighlighter == null)
throw new ArgumentNullException("baseHighlighter");
this.textView = textView;
this.document = textView.Document;
this.customizations = customizations;
this.baseHighlighter = baseHighlighter;
baseHighlighter.HighlightingStateChanged += highlighter_HighlightingStateChanged;
}
public CustomizingHighlighter(IDocument document, IEnumerable<CustomizedHighlightingColor> customizations, IHighlighter baseHighlighter)
{
if (document == null)
throw new ArgumentNullException("document");
if (customizations == null)
throw new ArgumentNullException("customizations");
if (baseHighlighter == null)
throw new ArgumentNullException("baseHighlighter");
this.document = document;
this.customizations = customizations;
this.baseHighlighter = baseHighlighter;
baseHighlighter.HighlightingStateChanged += highlighter_HighlightingStateChanged;
}
public IDocument Document {
get { return baseHighlighter.Document; }
}
public event HighlightingStateChangedEventHandler HighlightingStateChanged;
public event HighlightingStateChangedEventHandler HighlightingStateChanged {
add { baseHighlighter.HighlightingStateChanged += value; }
remove { baseHighlighter.HighlightingStateChanged -= value; }
}
public void UpdateHighlightingState(int lineNumber)
{
baseHighlighter.UpdateHighlightingState(lineNumber);
}
void highlighter_HighlightingStateChanged(IHighlighter sender, int fromLineNumber, int toLineNumber)
{
if (HighlightingStateChanged != null)
HighlightingStateChanged(this, fromLineNumber, toLineNumber);
}
public IEnumerable<string> GetSpanColorNamesFromLineStart(int lineNumber)
{
// delayed evaluation doesn't cause a problem here: GetColorStack is called immediately,
@ -198,25 +173,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -198,25 +173,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
return line;
}
public void InvalidateLine(IDocumentLine line)
{
if (textView == null)
throw new InvalidOperationException("IHighlighter has no TextView assigned!");
textView.Redraw(line, DispatcherPriority.Background);
}
public void InvalidateAll()
{
if (textView == null)
throw new InvalidOperationException("IHighlighter has no TextView assigned!");
textView.Redraw(DispatcherPriority.Background);
}
public event EventHandler VisibleDocumentLinesChanged {
add { textView.VisualLinesChanged += value; }
remove { textView.VisualLinesChanged -= value; }
}
/*
public IEnumerable<IDocumentLine> GetVisibleDocumentLines()
{
if (textView == null)
@ -239,7 +196,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -239,7 +196,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
}
}
return result;
}
}*/
public HighlightingColor GetNamedColor(string name)
{

5
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/DiffControl.xaml.cs

@ -49,9 +49,8 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -49,9 +49,8 @@ namespace ICSharpCode.AvalonEdit.AddIn
string language = source.SyntaxHighlighting != null ? source.SyntaxHighlighting.Name : null;
editor.TextArea.TextView.LineTransformers.RemoveAll(x => x is HighlightingColorizer);
var customizedHighlighter = new CustomizingHighlighter(
editor.TextArea.TextView,
CustomizedHighlightingColor.FetchCustomizations(language),
new DocumentHighlighter(editor.Document, source.SyntaxHighlighting)
new DocumentHighlighter(editor.Document, source.SyntaxHighlighting),
CustomizedHighlightingColor.FetchCustomizations(language)
);
editor.TextArea.TextView.LineTransformers.Insert(0, new HighlightingColorizer(customizedHighlighter));
CustomizingHighlighter.ApplyCustomizationsToDefaultElements(editor, CustomizedHighlightingColor.FetchCustomizations(language));

4
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Options/HighlightingOptions.xaml.cs

@ -557,8 +557,8 @@ namespace ICSharpCode.AvalonEdit.AddIn.Options @@ -557,8 +557,8 @@ namespace ICSharpCode.AvalonEdit.AddIn.Options
if (item != null) {
if (item.ParentDefinition != null) {
var highlighter = new CustomizingHighlighter(
textView, customizationsForCurrentLanguage,
new DocumentHighlighter(textView.Document, item.ParentDefinition)
new DocumentHighlighter(textView.Document, item.ParentDefinition),
customizationsForCurrentLanguage
);
colorizer = new HighlightingColorizer(highlighter);
textView.LineTransformers.Add(colorizer);

5
src/AddIns/DisplayBindings/XmlEditor/Test/Utils/MockDocument.cs

@ -177,7 +177,10 @@ namespace XmlEditor.Tests.Utils @@ -177,7 +177,10 @@ namespace XmlEditor.Tests.Utils
throw new NotImplementedException();
}
public event EventHandler ChangeCompleted;
public event EventHandler ChangeCompleted {
add { throw new NotImplementedException(); }
remove { throw new NotImplementedException(); }
}
public IDocument CreateDocumentSnapshot()
{

5
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/DocumentHighlighter.cs

@ -244,7 +244,8 @@ namespace ICSharpCode.AvalonEdit.Highlighting @@ -244,7 +244,8 @@ namespace ICSharpCode.AvalonEdit.Highlighting
} else {
firstInvalidLine = int.MaxValue;
}
OnHighlightStateChanged(lineNumber, lineNumber);
if (lineNumber + 1 < document.LineCount)
OnHighlightStateChanged(lineNumber + 1, lineNumber + 1);
} else if (firstInvalidLine == lineNumber) {
isValid[lineNumber] = true;
firstInvalidLine = isValid.IndexOf(false);
@ -284,7 +285,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting @@ -284,7 +285,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting
protected virtual void OnHighlightStateChanged(int fromLineNumber, int toLineNumber)
{
if (HighlightingStateChanged != null)
HighlightingStateChanged(this, fromLineNumber, toLineNumber);
HighlightingStateChanged(fromLineNumber, toLineNumber);
}
#region Highlighting Engine

29
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightingColorizer.cs

@ -3,12 +3,9 @@ @@ -3,12 +3,9 @@
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Media;
using System.Windows.Threading;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Rendering;
using ICSharpCode.NRefactory.Editor;
namespace ICSharpCode.AvalonEdit.Highlighting
{
@ -147,11 +144,13 @@ namespace ICSharpCode.AvalonEdit.Highlighting @@ -147,11 +144,13 @@ namespace ICSharpCode.AvalonEdit.Highlighting
if (highlighter != null) {
// Force update of highlighting state up to the position where we start generating visual lines.
// This is necessary in case the document gets modified above the FirstLineInView so that the highlighting state changes.
// We need to detect this case and issue a redraw (through TextViewDocumentHighligher.OnHighlightStateChanged)
// We need to detect this case and issue a redraw (through OnHighlightStateChanged)
// before the visual line construction reuses existing lines that were built using the invalid highlighting state.
lineNumberBeingColorized = e.FirstLineInView.LineNumber - 1;
if (!isInHighlightingGroup) {
// avoid opening group twice if there was an exception during the previous visual line construction
// (not ideal, but better than throwing InvalidOperationException "group already open"
// without any way of recovering)
highlighter.BeginHighlighting();
isInHighlightingGroup = true;
}
@ -254,21 +253,23 @@ namespace ICSharpCode.AvalonEdit.Highlighting @@ -254,21 +253,23 @@ namespace ICSharpCode.AvalonEdit.Highlighting
/// Hey, the user typed "/*". Don't just recreate that line, but also the next one
/// because my highlighting state (at end of line) changed!
/// </remarks>
void OnHighlightStateChanged(IHighlighter sender, int fromlineNumber, int toLineNumber)
void OnHighlightStateChanged(int fromLineNumber, int toLineNumber)
{
if (lineNumberBeingColorized < fromlineNumber || lineNumberBeingColorized > toLineNumber) {
if (lineNumberBeingColorized != 0) {
// Ignore notifications for any line except the one we're interested in.
// This improves the performance as Redraw() can take quite some time when called repeatedly
// while scanning the document (above the visible area) for highlighting changes.
if (toLineNumber <= lineNumberBeingColorized) {
return;
}
}
// The user may have inserted "/*" into the current line, and so far only that line got redrawn.
// So when the highlighting state is changed, we issue a redraw for the line immediately below.
// If the highlighting state change applies to the lines below, too, the construction of each line
// will invalidate the next line, and the construction pass will regenerate all lines.
Debug.WriteLine("OnHighlightStateChanged forces redraw of lines {0} to {1}", fromlineNumber + 1, toLineNumber + 1);
Debug.WriteLine("OnHighlightStateChanged forces redraw of lines {0} to {1}", fromLineNumber, toLineNumber);
// If the VisualLine construction is in progress, we have to avoid sending redraw commands for
// anything above the line currently being constructed.
@ -309,9 +310,17 @@ namespace ICSharpCode.AvalonEdit.Highlighting @@ -309,9 +310,17 @@ namespace ICSharpCode.AvalonEdit.Highlighting
// so it will always invalidate the next visual line when a folded line is constructed
// and the highlighting stack has changed.
for (int lineNumber = fromlineNumber; lineNumber <= toLineNumber; lineNumber++) {
if (lineNumber + 1 <= textView.Document.LineCount)
textView.Redraw(textView.Document.GetLineByNumber(lineNumber + 1), DispatcherPriority.Normal);
if (fromLineNumber == toLineNumber) {
textView.Redraw(textView.Document.GetLineByNumber(fromLineNumber));
} else {
// If there are multiple lines marked as changed; only the first one really matters
// for the highlighting during rendering.
// However this callback is also called outside of the rendering process, e.g. when a highlighter
// decides to re-highlight some section based on external feedback (e.g. semantic highlighting).
var fromLine = textView.Document.GetLineByNumber(fromLineNumber);
var toLine = textView.Document.GetLineByNumber(toLineNumber);
int startOffset = fromLine.Offset;
textView.Redraw(startOffset, toLine.EndOffset - startOffset);
}
/*

25
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/IHighlighter.cs

@ -45,20 +45,29 @@ namespace ICSharpCode.AvalonEdit.Highlighting @@ -45,20 +45,29 @@ namespace ICSharpCode.AvalonEdit.Highlighting
void UpdateHighlightingState(int lineNumber);
/// <summary>
/// Notification when the highlighter detects that the highlighting state at the end of a line
/// has changed.
/// This event gets raised for each line as it is processed by the highlighter
/// unless the highlighting state for the line is equal to the old state (when the same line was highlighted previously).
/// Notification when the highlighter detects that the highlighting state at the
/// <b>beginning</b> of the specified lines has changed.
/// <c>fromLineNumber</c> and <c>toLineNumber</c> are both inclusive;
/// the common case of a single-line change is represented by <c>fromLineNumber == toLineNumber</c>.
///
/// During highlighting, the highlighting of line X will cause this event to be raised
/// for line X+1 if the highlighting state at the end of line X has changed from its previous state.
/// This event may also be raised outside of the highlighting process to signalize that
/// changes to external data (not the document text; but e.g. semantic information)
/// require a re-highlighting of the specified lines.
/// </summary>
/// <remarks>
/// For implementers: there is the requirement that, if there was no state changed reported at line X,
/// and there were no document changes between line X and Y (with Y > X), then
/// this event must not be raised for any line between X and Y.
/// For implementers: there is the requirement that, during highlighting,
/// if there was no state changed reported for the beginning of line X,
/// and there were no document changes between the start of line X and the start of line Y (with Y > X),
/// then this event must not be raised for any line between X and Y (inclusive).
///
/// Equal input state + unchanged line = Equal output state.
///
/// See the comment in the HighlightingColorizer.OnHighlightStateChanged implementation
/// for details about the requirements for a correct custom IHighlighter.
///
/// Outside of the highlighting process, this event can be raised without such restrictions.
/// </remarks>
event HighlightingStateChangedEventHandler HighlightingStateChanged;
@ -94,5 +103,5 @@ namespace ICSharpCode.AvalonEdit.Highlighting @@ -94,5 +103,5 @@ namespace ICSharpCode.AvalonEdit.Highlighting
/// <summary>
/// Event handler for <see cref="IHighlighter.HighlightingStateChanged"/>
/// </summary>
public delegate void HighlightingStateChangedEventHandler(IHighlighter sender, int fromLineNumber, int toLineNumber);
public delegate void HighlightingStateChangedEventHandler(int fromLineNumber, int toLineNumber);
}

4
src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/ProjectOptions/ApplicationSettings.xaml.cs

@ -282,7 +282,7 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels @@ -282,7 +282,7 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels
// Because this event is raised while the combobox is still switching to the "<create>" or "<browse>" value,
// we cannot set comboBox.Text within this event handler.
// To avoid this problem, we invoke the operation after the combobox has finished switching to the new value.
WorkbenchSingleton.SafeThreadAsyncCall(
Dispatcher.BeginInvoke(new Action(
delegate {
if (applicationManifestComboBox.SelectedIndex == applicationManifestComboBox.Items.Count - 2) {
CreateManifest();
@ -292,7 +292,7 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels @@ -292,7 +292,7 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels
// we need to store re-load the changed property value.
applicationManifestComboBox.Text = this.ApplicationManifest.Value;
}
});
}));
}
void CreateManifest()

4
src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/ProjectOptions/Signing.xaml.cs

@ -130,7 +130,7 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels @@ -130,7 +130,7 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels
// Because this event is raised while the combobox is still switching to the "<create>" or "<browse>" value,
// we cannot set comboBox.Text within this event handler.
// To avoid this problem, we invoke the operation after the combobox has finished switching to the new value.
WorkbenchSingleton.SafeThreadAsyncCall(
Dispatcher.BeginInvoke(new Action(
delegate {
if (this.keyFileComboBox.SelectedIndex == keyFile.Count - 1) {
keyFileComboBox.Text = String.Empty;
@ -141,7 +141,7 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels @@ -141,7 +141,7 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels
keyFileComboBox.Text = String.Empty;
CreateKeyFile();
}
});
}));
}
private void CreateKeyFile()

Loading…
Cancel
Save