Code Coverage Statistics for Source File

c:\Tools\SD3\src\Libraries\ICSharpCode.TextEditor\Project\Src\Gui\CompletionWindow\CodeCompletionListView.cs

Sequence Point Coverage
N/A
0 of 0
Branch Coverage
N/A
0 of 0
Lines
293
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: 2533 $</version>
6
// </file>
7
8
using System;
9
using System.Drawing;
10
using System.Windows.Forms;
11
12
namespace ICSharpCode.TextEditor.Gui.CompletionWindow
13
{
14
	/// <summary>
15
	/// Description of CodeCompletionListView.
16
	/// </summary>
17
	public class CodeCompletionListView : System.Windows.Forms.UserControl
18
	{
19
		ICompletionData[] completionData;
20
		int               firstItem    = 0;
21
		int               selectedItem = -1;
22
		ImageList         imageList;
23
		
24
		public ImageList ImageList {
25
			get {
26
				return imageList;
27
			}
28
			set {
29
				imageList = value;
30
			}
31
		}
32
		
33
		public int FirstItem {
34
			get {
35
				return firstItem;
36
			}
37
			set {
38
				if (firstItem != value) {
39
					firstItem = value;
40
					OnFirstItemChanged(EventArgs.Empty);
41
				}
42
			}
43
		}
44
		
45
		public ICompletionData SelectedCompletionData {
46
			get {
47
				if (selectedItem < 0) {
48
					return null;
49
				}
50
				return completionData[selectedItem];
51
			}
52
		}
53
		
54
		public int ItemHeight {
55
			get {
56
				return Math.Max(imageList.ImageSize.Height, (int)(Font.Height * 1.25));
57
			}
58
		}
59
		
60
		public int MaxVisibleItem {
61
			get {
62
				return Height / ItemHeight;
63
			}
64
		}
65
		
66
		public CodeCompletionListView(ICompletionData[] completionData)
67
		{
68
			Array.Sort(completionData);
69
			this.completionData = completionData;
70
			
71
//			this.KeyDown += new System.Windows.Forms.KeyEventHandler(OnKey);
72
//			SetStyle(ControlStyles.Selectable, false);
73
//			SetStyle(ControlStyles.UserPaint, true);
74
//			SetStyle(ControlStyles.DoubleBuffer, false);
75
		}
76
		
77
		public void Close()
78
		{
79
			if (completionData != null) {
80
				Array.Clear(completionData, 0, completionData.Length);
81
			}
82
			base.Dispose();
83
		}
84
		
85
		public void SelectIndex(int index)
86
		{
87
			int oldSelectedItem = selectedItem;
88
			int oldFirstItem    = firstItem;
89
			
90
			index = Math.Max(0, index);
91
			selectedItem = Math.Max(0, Math.Min(completionData.Length - 1, index));
92
			if (selectedItem < firstItem) {
93
				FirstItem = selectedItem;
94
			}
95
			if (firstItem + MaxVisibleItem <= selectedItem) {
96
				FirstItem = selectedItem - MaxVisibleItem + 1;
97
			}
98
			if (oldSelectedItem != selectedItem) {
99
				if (firstItem != oldFirstItem) {
100
					Invalidate();
101
				} else {
102
					int min = Math.Min(selectedItem, oldSelectedItem) - firstItem;
103
					int max = Math.Max(selectedItem, oldSelectedItem) - firstItem;
104
					Invalidate(new Rectangle(0, 1 + min * ItemHeight, Width, (max - min + 1) * ItemHeight));
105
				}
106
				OnSelectedItemChanged(EventArgs.Empty);
107
			}
108
		}
109
		
110
		public void CenterViewOn(int index)
111
		{
112
			int oldFirstItem = this.FirstItem;
113
			int firstItem = index - MaxVisibleItem / 2;
114
			if (firstItem < 0)
115
				this.FirstItem = 0;
116
			else if (firstItem >= completionData.Length - MaxVisibleItem)
117
				this.FirstItem = completionData.Length - MaxVisibleItem;
118
			else
119
				this.FirstItem = firstItem;
120
			if (this.FirstItem != oldFirstItem) {
121
				Invalidate();
122
			}
123
		}
124
		
125
		public void ClearSelection()
126
		{
127
			if (selectedItem < 0)
128
				return;
129
			int itemNum = selectedItem - firstItem;
130
			selectedItem = -1;
131
			Invalidate(new Rectangle(0, itemNum * ItemHeight, Width, (itemNum + 1) * ItemHeight + 1));
132
			Update();
133
			OnSelectedItemChanged(EventArgs.Empty);
134
		}
135
		
136
		public void PageDown()
137
		{
138
			SelectIndex(selectedItem + MaxVisibleItem);
139
		}
140
		
141
		public void PageUp()
142
		{
143
			SelectIndex(selectedItem - MaxVisibleItem);
144
		}
145
		
146
		public void SelectNextItem()
147
		{
148
			SelectIndex(selectedItem + 1);
149
		}
150
		
151
		public void SelectPrevItem()
152
		{
153
			SelectIndex(selectedItem - 1);
154
		}
155
		
156
		public void SelectItemWithStart(string startText)
157
		{
158
			if (startText == null || startText.Length == 0) return;
159
			string originalStartText = startText;
160
			startText = startText.ToLower();
161
			int bestIndex = -1;
162
			int bestQuality = -1;
163
			// Qualities: 0 = match start
164
			//            1 = match start case sensitive
165
			//            2 = full match
166
			//            3 = full match case sensitive
167
			double bestPriority = 0;
168
			for (int i = 0; i < completionData.Length; ++i) {
169
				string itemText = completionData[i].Text;
170
				string lowerText = itemText.ToLower();
171
				if (lowerText.StartsWith(startText)) {
172
					double priority = completionData[i].Priority;
173
					int quality;
174
					if (lowerText == startText) {
175
						if (itemText == originalStartText)
176
							quality = 3;
177
						else
178
							quality = 2;
179
					} else if (itemText.StartsWith(originalStartText)) {
180
						quality = 1;
181
					} else {
182
						quality = 0;
183
					}
184
					bool useThisItem;
185
					if (bestQuality < quality) {
186
						useThisItem = true;
187
					} else {
188
						if (bestIndex == selectedItem) {
189
							useThisItem = false;
190
						} else if (i == selectedItem) {
191
							useThisItem = bestQuality == quality;
192
						} else {
193
							useThisItem = bestQuality == quality && bestPriority < priority;
194
						}
195
					}
196
					if (useThisItem) {
197
						bestIndex = i;
198
						bestPriority = priority;
199
						bestQuality = quality;
200
					}
201
				}
202
			}
203
			if (bestIndex < 0) {
204
				ClearSelection();
205
			} else {
206
				if (bestIndex < firstItem || firstItem + MaxVisibleItem <= bestIndex) {
207
					SelectIndex(bestIndex);
208
					CenterViewOn(bestIndex);
209
				} else {
210
					SelectIndex(bestIndex);
211
				}
212
			}
213
		}
214
		
215
		protected override void OnPaint(PaintEventArgs pe)
216
		{
217
			float yPos       = 1;
218
			float itemHeight = ItemHeight;
219
			// Maintain aspect ratio
220
			int imageWidth = (int)(itemHeight * imageList.ImageSize.Width / imageList.ImageSize.Height);
221
			
222
			int curItem = firstItem;
223
			Graphics g  = pe.Graphics;
224
			while (curItem < completionData.Length && yPos < Height) {
225
				RectangleF drawingBackground = new RectangleF(1, yPos, Width - 2, itemHeight);
226
				if (drawingBackground.IntersectsWith(pe.ClipRectangle)) {
227
					// draw Background
228
					if (curItem == selectedItem) {
229
						g.FillRectangle(SystemBrushes.Highlight, drawingBackground);
230
					} else {
231
						g.FillRectangle(SystemBrushes.Window, drawingBackground);
232
					}
233
					
234
					// draw Icon
235
					int   xPos   = 0;
236
					if (imageList != null && completionData[curItem].ImageIndex < imageList.Images.Count) {
237
						g.DrawImage(imageList.Images[completionData[curItem].ImageIndex], new RectangleF(1, yPos, imageWidth, itemHeight));
238
						xPos = imageWidth;
239
					}
240
					
241
					// draw text
242
					if (curItem == selectedItem) {
243
						g.DrawString(completionData[curItem].Text, Font, SystemBrushes.HighlightText, xPos, yPos);
244
					} else {
245
						g.DrawString(completionData[curItem].Text, Font, SystemBrushes.WindowText, xPos, yPos);
246
					}
247
				}
248
				
249
				yPos += itemHeight;
250
				++curItem;
251
			}
252
			g.DrawRectangle(SystemPens.Control, new Rectangle(0, 0, Width - 1, Height - 1));
253
		}
254
		
255
		protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs e)
256
		{
257
			float yPos       = 1;
258
			int curItem = firstItem;
259
			float itemHeight = ItemHeight;
260
			
261
			while (curItem < completionData.Length && yPos < Height) {
262
				RectangleF drawingBackground = new RectangleF(1, yPos, Width - 2, itemHeight);
263
				if (drawingBackground.Contains(e.X, e.Y)) {
264
					SelectIndex(curItem);
265
					break;
266
				}
267
				yPos += itemHeight;
268
				++curItem;
269
			}
270
		}
271
		
272
		protected override void OnPaintBackground(PaintEventArgs pe)
273
		{
274
		}
275
		
276
		protected virtual void OnSelectedItemChanged(EventArgs e)
277
		{
278
			if (SelectedItemChanged != null) {
279
				SelectedItemChanged(this, e);
280
			}
281
		}
282
		
283
		protected virtual void OnFirstItemChanged(EventArgs e)
284
		{
285
			if (FirstItemChanged != null) {
286
				FirstItemChanged(this, e);
287
			}
288
		}
289
		
290
		public event EventHandler SelectedItemChanged;
291
		public event EventHandler FirstItemChanged;
292
	}
293
}