Code Coverage Statistics for Source File

c:\Tools\SD3\src\Libraries\ICSharpCode.TextEditor\Project\Src\Document\LineManager\LineSegment.cs

Sequence Point Coverage
N/A
0 of 0
Branch Coverage
N/A
0 of 0
Lines
251
Highlight: Uncovered Code Covered Code
L V Source
1
// <file>
2
//     <copyright see="prj:///doc/copyright.txt"/>
3
//     <license see="prj:///doc/license.txt"/>
4
//     <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
5
//     <version>$Revision: 2691 $</version>
6
// </file>
7
8
using System;
9
using System.Collections.Generic;
10
using System.Drawing;
11
using System.Diagnostics;
12
using System.Text;
13
14
namespace ICSharpCode.TextEditor.Document
15
{
16
	public sealed class LineSegment : ISegment
17
	{
18
		internal LineSegmentTree.Enumerator treeEntry;
19
		int totalLength, delimiterLength;
20
		
21
		List<TextWord> words;
22
		SpanStack highlightSpanStack;
23
		
24
		public TextWord GetWord(int column)
25
		{
26
			int curColumn = 0;
27
			foreach (TextWord word in words) {
28
				if (column < curColumn + word.Length) {
29
					return word;
30
				}
31
				curColumn += word.Length;
32
			}
33
			return null;
34
		}
35
		
36
		public bool IsDeleted {
37
			get { return !treeEntry.IsValid; }
38
		}
39
		
40
		public int LineNumber {
41
			get { return treeEntry.CurrentIndex; }
42
		}
43
		
44
		public int Offset {
45
			get { return treeEntry.CurrentOffset; }
46
		}
47
		
48
		public int Length {
49
			get	{ return totalLength - delimiterLength; }
50
		}
51
		
52
		int ISegment.Offset {
53
			get { return this.Offset; }
54
			set { throw new NotSupportedException(); }
55
		}
56
		int ISegment.Length {
57
			get { return this.Length; }
58
			set { throw new NotSupportedException(); }
59
		}
60
		
61
		public int TotalLength {
62
			get { return totalLength; }
63
			internal set { totalLength = value; }
64
		}
65
		
66
		public int DelimiterLength {
67
			get { return delimiterLength; }
68
			internal set { delimiterLength = value; }
69
		}
70
		
71
		// highlighting information
72
		public List<TextWord> Words {
73
			get {
74
				return words;
75
			}
76
			set {
77
				words = value;
78
			}
79
		}
80
		
81
		public HighlightColor GetColorForPosition(int x)
82
		{
83
			if (Words != null) {
84
				int xPos = 0;
85
				foreach (TextWord word in Words) {
86
					if (x < xPos + word.Length) {
87
						return word.SyntaxColor;
88
					}
89
					xPos += word.Length;
90
				}
91
			}
92
			return new HighlightColor(Color.Black, false, false);
93
		}
94
		
95
		public SpanStack HighlightSpanStack {
96
			get {
97
				return highlightSpanStack;
98
			}
99
			set {
100
				highlightSpanStack = value;
101
			}
102
		}
103
		
104
		/// <summary>
105
		/// Converts a <see cref="LineSegment"/> instance to string (for debug purposes)
106
		/// </summary>
107
		public override string ToString()
108
		{
109
			if (IsDeleted)
110
				return "[LineSegment: (deleted) Length = " + Length + ", TotalLength = " + TotalLength + ", DelimiterLength = " + delimiterLength + "]";
111
			else
112
				return "[LineSegment: LineNumber=" + LineNumber + ", Offset = "+ Offset +", Length = " + Length + ", TotalLength = " + TotalLength + ", DelimiterLength = " + delimiterLength + "]";
113
		}
114
		
115
		#region Anchor management
116
		Util.WeakCollection<TextAnchor> anchors;
117
		
118
		public TextAnchor CreateAnchor(int column)
119
		{
120
			TextAnchor anchor = new TextAnchor(this, column);
121
			AddAnchor(anchor);
122
			return anchor;
123
		}
124
		
125
		void AddAnchor(TextAnchor anchor)
126
		{
127
			Debug.Assert(anchor.Line == this);
128
			
129
			if (anchors == null)
130
				anchors = new Util.WeakCollection<TextAnchor>();
131
			
132
			anchors.Add(anchor);
133
		}
134
		
135
		/// <summary>
136
		/// Is called when the LineSegment is deleted.
137
		/// </summary>
138
		internal void Deleted()
139
		{
140
			//Console.WriteLine("Deleted");
141
			treeEntry = LineSegmentTree.Enumerator.Invalid;
142
			if (anchors != null) {
143
				foreach (TextAnchor a in anchors) {
144
					a.Deleted();
145
				}
146
				anchors = null;
147
			}
148
		}
149
		
150
		/// <summary>
151
		/// Is called when a part of the line is removed.
152
		/// </summary>
153
		internal void RemovedLinePart(int startColumn, int length)
154
		{
155
			if (length == 0)
156
				return;
157
			Debug.Assert(length > 0);
158
			
159
			//Console.WriteLine("RemovedLinePart " + startColumn + ", " + length);
160
			if (anchors != null) {
161
				List<TextAnchor> deletedAnchors = null;
162
				foreach (TextAnchor a in anchors) {
163
					if (a.ColumnNumber > startColumn) {
164
						if (a.ColumnNumber >= startColumn + length) {
165
							a.ColumnNumber -= length;
166
						} else {
167
							if (deletedAnchors == null)
168
								deletedAnchors = new List<TextAnchor>();
169
							a.Deleted();
170
							deletedAnchors.Add(a);
171
						}
172
					}
173
				}
174
				if (deletedAnchors != null) {
175
					foreach (TextAnchor a in deletedAnchors) {
176
						anchors.Remove(a);
177
					}
178
				}
179
			}
180
		}
181
		
182
		/// <summary>
183
		/// Is called when a part of the line is inserted.
184
		/// </summary>
185
		internal void InsertedLinePart(int startColumn, int length)
186
		{
187
			if (length == 0)
188
				return;
189
			Debug.Assert(length > 0);
190
			
191
			//Console.WriteLine("InsertedLinePart " + startColumn + ", " + length);
192
			if (anchors != null) {
193
				foreach (TextAnchor a in anchors) {
194
					if (a.ColumnNumber >= startColumn) {
195
						a.ColumnNumber += length;
196
					}
197
				}
198
			}
199
		}
200
		
201
		/// <summary>
202
		/// Is called after another line's content is appended to this line because the newline in between
203
		/// was deleted.
204
		/// The DefaultLineManager will call Deleted() on the deletedLine after the MergedWith call.
205
		/// 
206
		/// firstLineLength: the length of the line before the merge.
207
		/// </summary>
208
		internal void MergedWith(LineSegment deletedLine, int firstLineLength)
209
		{
210
			//Console.WriteLine("MergedWith");
211
			
212
			if (deletedLine.anchors != null) {
213
				foreach (TextAnchor a in deletedLine.anchors) {
214
					a.Line = this;
215
					AddAnchor(a);
216
					a.ColumnNumber += firstLineLength;
217
				}
218
				deletedLine.anchors = null;
219
			}
220
		}
221
		
222
		/// <summary>
223
		/// Is called after a newline was inserted into this line, splitting it into this and followingLine.
224
		/// </summary>
225
		internal void SplitTo(LineSegment followingLine)
226
		{
227
			//Console.WriteLine("SplitTo");
228
			
229
			if (anchors != null) {
230
				List<TextAnchor> movedAnchors = null;
231
				foreach (TextAnchor a in anchors) {
232
					if (a.ColumnNumber > this.Length) {
233
						a.Line = followingLine;
234
						followingLine.AddAnchor(a);
235
						a.ColumnNumber -= this.Length;
236
						
237
						if (movedAnchors == null)
238
							movedAnchors = new List<TextAnchor>();
239
						movedAnchors.Add(a);
240
					}
241
				}
242
				if (movedAnchors != null) {
243
					foreach (TextAnchor a in movedAnchors) {
244
						anchors.Remove(a);
245
					}
246
				}
247
			}
248
		}
249
		#endregion
250
	}
251
}