Browse Source

Fix RichTextModel.UpdateOffsets()

pull/59/merge
Daniel Grunwald 12 years ago
parent
commit
dbdb75e4a6
  1. 2
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/OffsetChangeMap.cs
  2. 34
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichText.cs
  3. 62
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichTextModel.cs
  4. 4
      src/Main/Base/Project/Src/Gui/Pads/CompilerMessageView/CompilerMessageView.cs

2
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/OffsetChangeMap.cs

@ -108,7 +108,7 @@ namespace ICSharpCode.AvalonEdit.Document
/// <summary> /// <summary>
/// Gets the new offset where the specified offset moves after this document change. /// Gets the new offset where the specified offset moves after this document change.
/// </summary> /// </summary>
public int GetNewOffset(int offset, AnchorMovementType movementType) public int GetNewOffset(int offset, AnchorMovementType movementType = AnchorMovementType.Default)
{ {
IList<OffsetChangeMapEntry> items = this.Items; IList<OffsetChangeMapEntry> items = this.Items;
int count = items.Count; int count = items.Count;

34
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichText.cs

@ -3,10 +3,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Windows.Documents; using System.Windows.Documents;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Utils; using ICSharpCode.AvalonEdit.Utils;
namespace ICSharpCode.AvalonEdit.Highlighting namespace ICSharpCode.AvalonEdit.Highlighting
@ -16,6 +18,11 @@ namespace ICSharpCode.AvalonEdit.Highlighting
/// </summary> /// </summary>
public class RichText public class RichText
{ {
/// <summary>
/// The empty string without any formatting information.
/// </summary>
public static readonly RichText Empty = new RichText(string.Empty);
readonly string text; readonly string text;
internal readonly int[] stateChangeOffsets; internal readonly int[] stateChangeOffsets;
internal readonly HighlightingColor[] stateChanges; internal readonly HighlightingColor[] stateChanges;
@ -53,6 +60,8 @@ namespace ICSharpCode.AvalonEdit.Highlighting
internal RichText(string text, int[] offsets, HighlightingColor[] states) internal RichText(string text, int[] offsets, HighlightingColor[] states)
{ {
this.text = text; this.text = text;
Debug.Assert(offsets[0] == 0);
Debug.Assert(offsets.Last() <= text.Length);
this.stateChangeOffsets = offsets; this.stateChangeOffsets = offsets;
this.stateChanges = states; this.stateChanges = states;
} }
@ -191,9 +200,15 @@ namespace ICSharpCode.AvalonEdit.Highlighting
/// </summary> /// </summary>
public RichText Substring(int offset, int length) public RichText Substring(int offset, int length)
{ {
// if (offset == 0 && length == this.Length) if (offset == 0 && length == this.Length)
// return this; return this;
throw new NotImplementedException(); string newText = text.Substring(offset, length);
RichTextModel model = ToRichTextModel();
OffsetChangeMap map = new OffsetChangeMap(2);
map.Add(new OffsetChangeMapEntry(offset + length, text.Length - offset - length, 0));
map.Add(new OffsetChangeMapEntry(0, offset, 0));
model.UpdateOffsets(map);
return new RichText(newText, model);
} }
/// <summary> /// <summary>
@ -201,7 +216,18 @@ namespace ICSharpCode.AvalonEdit.Highlighting
/// </summary> /// </summary>
public static RichText Concat(params RichText[] texts) public static RichText Concat(params RichText[] texts)
{ {
throw new NotImplementedException(); if (texts == null || texts.Length == 0)
return Empty;
else if (texts.Length == 1)
return texts[0];
string newText = string.Concat(texts.Select(txt => txt.text));
RichTextModel model = texts[0].ToRichTextModel();
int offset = texts[0].Length;
for (int i = 1; i < texts.Length; i++) {
model.Append(offset, texts[i].stateChangeOffsets, texts[i].stateChanges);
offset += texts[i].Length;
}
return new RichText(newText, model);
} }
/// <summary> /// <summary>

62
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichTextModel.cs

@ -4,6 +4,8 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows; using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using ICSharpCode.NRefactory.Editor; using ICSharpCode.NRefactory.Editor;
@ -72,6 +74,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting
/// </summary> /// </summary>
internal RichTextModel(int[] stateChangeOffsets, HighlightingColor[] stateChanges) internal RichTextModel(int[] stateChangeOffsets, HighlightingColor[] stateChanges)
{ {
Debug.Assert(stateChangeOffsets[0] == 0);
this.stateChangeOffsets.AddRange(stateChangeOffsets); this.stateChangeOffsets.AddRange(stateChangeOffsets);
this.stateChanges.AddRange(stateChanges); this.stateChanges.AddRange(stateChanges);
} }
@ -85,9 +88,18 @@ namespace ICSharpCode.AvalonEdit.Highlighting
{ {
if (e == null) if (e == null)
throw new ArgumentNullException("e"); throw new ArgumentNullException("e");
for (int i = 0; i < stateChangeOffsets.Count; i++) { UpdateOffsets(e.GetNewOffset);
stateChangeOffsets[i] = e.GetNewOffset(stateChangeOffsets[i]); }
}
/// <summary>
/// Updates the start and end offsets of all segments stored in this collection.
/// </summary>
/// <param name="change">OffsetChangeMap instance describing the change to the document.</param>
public void UpdateOffsets(OffsetChangeMap change)
{
if (change == null)
throw new ArgumentNullException("change");
UpdateOffsets(change.GetNewOffset);
} }
/// <summary> /// <summary>
@ -96,12 +108,52 @@ namespace ICSharpCode.AvalonEdit.Highlighting
/// <param name="change">OffsetChangeMapEntry instance describing the change to the document.</param> /// <param name="change">OffsetChangeMapEntry instance describing the change to the document.</param>
public void UpdateOffsets(OffsetChangeMapEntry change) public void UpdateOffsets(OffsetChangeMapEntry change)
{ {
for (int i = 0; i < stateChangeOffsets.Count; i++) { UpdateOffsets(change.GetNewOffset);
stateChangeOffsets[i] = change.GetNewOffset(stateChangeOffsets[i]); }
void UpdateOffsets(Func<int, AnchorMovementType, int> updateOffset)
{
int readPos = 1;
int writePos = 1;
while (readPos < stateChangeOffsets.Count) {
Debug.Assert(writePos <= readPos);
int newOffset = updateOffset(stateChangeOffsets[readPos], AnchorMovementType.Default);
if (newOffset == stateChangeOffsets[writePos - 1]) {
// offset moved to same position as previous offset
// -> previous segment has length 0 and gets overwritten with this segment
stateChanges[writePos - 1] = stateChanges[readPos];
} else {
stateChangeOffsets[writePos] = newOffset;
stateChanges[writePos] = stateChanges[readPos];
writePos++;
}
readPos++;
} }
// Delete all entries that were not written to
stateChangeOffsets.RemoveRange(writePos, stateChangeOffsets.Count - writePos);
stateChanges.RemoveRange(writePos, stateChanges.Count - writePos);
} }
#endregion #endregion
/// <summary>
/// Appends another RichTextModel after this one.
/// </summary>
internal void Append(int offset, int[] newOffsets, HighlightingColor[] newColors)
{
Debug.Assert(newOffsets.Length == newColors.Length);
Debug.Assert(newOffsets[0] == 0);
// remove everything before offset:
while (stateChangeOffsets.Count > 0 && stateChangeOffsets.Last() <= offset) {
stateChangeOffsets.RemoveAt(stateChangeOffsets.Count - 1);
stateChanges.RemoveAt(stateChanges.Count - 1);
}
// Append the new segments
for (int i = 0; i < newOffsets.Length; i++) {
stateChangeOffsets.Add(offset + newOffsets[i]);
stateChanges.Add(newColors[i]);
}
}
/// <summary> /// <summary>
/// Gets a copy of the HighlightingColor for the specified offset. /// Gets a copy of the HighlightingColor for the specified offset.
/// </summary> /// </summary>

4
src/Main/Base/Project/Src/Gui/Pads/CompilerMessageView/CompilerMessageView.cs

@ -50,7 +50,9 @@ namespace ICSharpCode.SharpDevelop.Gui
return this.SelectedMessageViewCategory; return this.SelectedMessageViewCategory;
} }
set { set {
throw new NotImplementedException(); int index = messageCategories.IndexOf(value as MessageViewCategory);
if (index >= 0)
SelectedCategoryIndex = index;
} }
} }

Loading…
Cancel
Save