Mercurial > projects > dwt-mac
comparison dwt/widgets/List.d @ 0:380af2bdd8e5
Upload of whole dwt tree
author | Jacob Carlborg <doob@me.com> <jacob.carlborg@gmail.com> |
---|---|
date | Sat, 09 Aug 2008 17:00:02 +0200 |
parents | |
children | 649b8e223d5a |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:380af2bdd8e5 |
---|---|
1 /******************************************************************************* | |
2 * Copyright (c) 2000, 2007 IBM Corporation and others. | |
3 * All rights reserved. This program and the accompanying materials | |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
10 *******************************************************************************/ | |
11 module dwt.widgets.List; | |
12 | |
13 import dwt.dwthelper.utils; | |
14 | |
15 | |
16 import dwt.DWT; | |
17 import dwt.DWTException; | |
18 import dwt.events.SelectionEvent; | |
19 import dwt.events.SelectionListener; | |
20 import dwt.graphics.Color; | |
21 import dwt.graphics.GC; | |
22 import dwt.graphics.Point; | |
23 import dwt.graphics.Rectangle; | |
24 import dwt.internal.cocoa.NSAttributedString; | |
25 import dwt.internal.cocoa.NSColor; | |
26 import dwt.internal.cocoa.NSIndexSet; | |
27 import dwt.internal.cocoa.NSMutableDictionary; | |
28 import dwt.internal.cocoa.NSMutableIndexSet; | |
29 import dwt.internal.cocoa.NSPoint; | |
30 import dwt.internal.cocoa.NSRange; | |
31 import dwt.internal.cocoa.NSRect; | |
32 import dwt.internal.cocoa.NSString; | |
33 import dwt.internal.cocoa.NSTableColumn; | |
34 import dwt.internal.cocoa.NSTableView; | |
35 import dwt.internal.cocoa.OS; | |
36 import dwt.internal.cocoa.SWTScrollView; | |
37 import dwt.internal.cocoa.SWTTableView; | |
38 | |
39 /** | |
40 * Instances of this class represent a selectable user interface | |
41 * object that displays a list of strings and issues notification | |
42 * when a string is selected. A list may be single or multi select. | |
43 * <p> | |
44 * <dl> | |
45 * <dt><b>Styles:</b></dt> | |
46 * <dd>SINGLE, MULTI</dd> | |
47 * <dt><b>Events:</b></dt> | |
48 * <dd>Selection, DefaultSelection</dd> | |
49 * </dl> | |
50 * <p> | |
51 * Note: Only one of SINGLE and MULTI may be specified. | |
52 * </p><p> | |
53 * IMPORTANT: This class is <em>not</em> intended to be subclassed. | |
54 * </p> | |
55 */ | |
56 public class List extends Scrollable { | |
57 NSTableColumn column; | |
58 String [] items; | |
59 int itemCount; | |
60 bool ignoreSelect; | |
61 | |
62 /** | |
63 * Constructs a new instance of this class given its parent | |
64 * and a style value describing its behavior and appearance. | |
65 * <p> | |
66 * The style value is either one of the style constants defined in | |
67 * class <code>DWT</code> which is applicable to instances of this | |
68 * class, or must be built by <em>bitwise OR</em>'ing together | |
69 * (that is, using the <code>int</code> "|" operator) two or more | |
70 * of those <code>DWT</code> style constants. The class description | |
71 * lists the style constants that are applicable to the class. | |
72 * Style bits are also inherited from superclasses. | |
73 * </p> | |
74 * | |
75 * @param parent a composite control which will be the parent of the new instance (cannot be null) | |
76 * @param style the style of control to construct | |
77 * | |
78 * @exception IllegalArgumentException <ul> | |
79 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
80 * </ul> | |
81 * @exception DWTException <ul> | |
82 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | |
83 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | |
84 * </ul> | |
85 * | |
86 * @see DWT#SINGLE | |
87 * @see DWT#MULTI | |
88 * @see Widget#checkSubclass | |
89 * @see Widget#getStyle | |
90 */ | |
91 public List (Composite parent, int style) { | |
92 super (parent, checkStyle (style)); | |
93 } | |
94 | |
95 /** | |
96 * Adds the argument to the end of the receiver's list. | |
97 * | |
98 * @param string the new item | |
99 * | |
100 * @exception IllegalArgumentException <ul> | |
101 * <li>ERROR_NULL_ARGUMENT - if the string is null</li> | |
102 * </ul> | |
103 * @exception DWTException <ul> | |
104 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
105 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
106 * </ul> | |
107 * | |
108 * @see #add(String,int) | |
109 */ | |
110 public void add (String string) { | |
111 checkWidget(); | |
112 if (string is null) error (DWT.ERROR_NULL_ARGUMENT); | |
113 if (itemCount is items.length) { | |
114 String [] newItems = new String [itemCount + 4]; | |
115 System.arraycopy (items, 0, newItems, 0, items.length); | |
116 items = newItems; | |
117 } | |
118 items [itemCount++] = string; | |
119 ((NSTableView)view).reloadData(); | |
120 //TODO adjust horizontal scrollbar | |
121 } | |
122 | |
123 /** | |
124 * Adds the argument to the receiver's list at the given | |
125 * zero-relative index. | |
126 * <p> | |
127 * Note: To add an item at the end of the list, use the | |
128 * result of calling <code>getItemCount()</code> as the | |
129 * index or use <code>add(String)</code>. | |
130 * </p> | |
131 * | |
132 * @param string the new item | |
133 * @param index the index for the item | |
134 * | |
135 * @exception IllegalArgumentException <ul> | |
136 * <li>ERROR_NULL_ARGUMENT - if the string is null</li> | |
137 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list (inclusive)</li> | |
138 * </ul> | |
139 * @exception DWTException <ul> | |
140 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
141 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
142 * </ul> | |
143 * | |
144 * @see #add(String) | |
145 */ | |
146 public void add (String string, int index) { | |
147 checkWidget(); | |
148 if (string is null) error (DWT.ERROR_NULL_ARGUMENT); | |
149 if (!(0 <= index && index <= itemCount)) error (DWT.ERROR_INVALID_RANGE); | |
150 if (index !is itemCount) fixSelection (index, true); | |
151 if (itemCount is items.length) { | |
152 String [] newItems = new String [itemCount + 4]; | |
153 System.arraycopy (items, 0, newItems, 0, items.length); | |
154 items = newItems; | |
155 } | |
156 System.arraycopy (items, index, items, index + 1, itemCount++ - index); | |
157 items [index] = string; | |
158 ((NSTableView)view).reloadData(); | |
159 } | |
160 | |
161 /** | |
162 * Adds the listener to the collection of listeners who will | |
163 * be notified when the user changes the receiver's selection, by sending | |
164 * it one of the messages defined in the <code>SelectionListener</code> | |
165 * interface. | |
166 * <p> | |
167 * <code>widgetSelected</code> is called when the selection changes. | |
168 * <code>widgetDefaultSelected</code> is typically called when an item is double-clicked. | |
169 * </p> | |
170 * | |
171 * @param listener the listener which should be notified when the user changes the receiver's selection | |
172 * | |
173 * @exception IllegalArgumentException <ul> | |
174 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
175 * </ul> | |
176 * @exception DWTException <ul> | |
177 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
178 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
179 * </ul> | |
180 * | |
181 * @see SelectionListener | |
182 * @see #removeSelectionListener | |
183 * @see SelectionEvent | |
184 */ | |
185 public void addSelectionListener(SelectionListener listener) { | |
186 checkWidget(); | |
187 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
188 TypedListener typedListener = new TypedListener(listener); | |
189 addListener(DWT.Selection,typedListener); | |
190 addListener(DWT.DefaultSelection,typedListener); | |
191 } | |
192 | |
193 static int checkStyle (int style) { | |
194 return checkBits (style, DWT.SINGLE, DWT.MULTI, 0, 0, 0, 0); | |
195 } | |
196 | |
197 public Point computeSize (int wHint, int hHint, bool changed) { | |
198 checkWidget(); | |
199 int width = 0; | |
200 if (wHint is DWT.DEFAULT) { | |
201 GC gc = new GC (this); | |
202 for (int i=0; i<itemCount; i++) { | |
203 Point extent = gc.stringExtent (items [i]); | |
204 width = Math.max (width, extent.x); | |
205 } | |
206 gc.dispose (); | |
207 // width += EXTRA_WIDTH; | |
208 } else { | |
209 width = wHint; | |
210 } | |
211 if (width <= 0) width = DEFAULT_WIDTH; | |
212 int height = 0; | |
213 if (hHint is DWT.DEFAULT) { | |
214 height = itemCount * getItemHeight (); | |
215 } else { | |
216 height = hHint; | |
217 } | |
218 if (height <= 0) height = DEFAULT_HEIGHT; | |
219 Rectangle rect = computeTrim (0, 0, width, height); | |
220 return new Point (rect.width, rect.height); | |
221 } | |
222 | |
223 void createHandle () { | |
224 SWTScrollView scrollWidget = (SWTScrollView)new SWTScrollView().alloc(); | |
225 scrollWidget.initWithFrame(new NSRect ()); | |
226 if ((style & DWT.H_SCROLL) !is 0) scrollWidget.setHasHorizontalScroller(true); | |
227 if ((style & DWT.V_SCROLL) !is 0) scrollWidget.setHasVerticalScroller(true); | |
228 scrollWidget.setAutohidesScrollers(true); | |
229 scrollWidget.setBorderType((style & DWT.BORDER) !is 0 ? OS.NSBezelBorder : OS.NSNoBorder); | |
230 scrollWidget.setTag(jniRef); | |
231 | |
232 NSTableView widget = (NSTableView)new SWTTableView().alloc(); | |
233 widget.initWithFrame(new NSRect()); | |
234 widget.setAllowsMultipleSelection((style & DWT.MULTI) !is 0); | |
235 widget.setDataSource(widget); | |
236 widget.setHeaderView(null); | |
237 widget.setDelegate(widget); | |
238 widget.setDoubleAction(OS.sel_sendDoubleSelection); | |
239 if (!hasBorder()) widget.setFocusRingType(OS.NSFocusRingTypeNone); | |
240 widget.setTag(jniRef); | |
241 | |
242 column = (NSTableColumn)new NSTableColumn().alloc(); | |
243 column.initWithIdentifier(NSString.stringWith("")); | |
244 widget.addTableColumn (column); | |
245 | |
246 scrollView = scrollWidget; | |
247 view = widget; | |
248 scrollView.setDocumentView(widget); | |
249 parent.contentView().addSubview_(scrollView); | |
250 } | |
251 | |
252 void createWidget () { | |
253 super.createWidget (); | |
254 items = new String [4]; | |
255 } | |
256 | |
257 Color defaultBackground () { | |
258 return display.getSystemColor (DWT.COLOR_LIST_BACKGROUND); | |
259 } | |
260 | |
261 Color defaultForeground () { | |
262 return display.getSystemColor (DWT.COLOR_LIST_FOREGROUND); | |
263 } | |
264 | |
265 /** | |
266 * Deselects the item at the given zero-relative index in the receiver. | |
267 * If the item at the index was already deselected, it remains | |
268 * deselected. Indices that are out of range are ignored. | |
269 * | |
270 * @param index the index of the item to deselect | |
271 * | |
272 * @exception DWTException <ul> | |
273 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
274 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
275 * </ul> | |
276 */ | |
277 public void deselect (int index) { | |
278 checkWidget(); | |
279 if (0 <= index && index < itemCount) { | |
280 NSTableView widget = (NSTableView)view; | |
281 ignoreSelect = true; | |
282 widget.deselectRow (index); | |
283 ignoreSelect = false; | |
284 } | |
285 } | |
286 | |
287 /** | |
288 * Deselects the items at the given zero-relative indices in the receiver. | |
289 * If the item at the given zero-relative index in the receiver | |
290 * is selected, it is deselected. If the item at the index | |
291 * was not selected, it remains deselected. The range of the | |
292 * indices is inclusive. Indices that are out of range are ignored. | |
293 * | |
294 * @param start the start index of the items to deselect | |
295 * @param end the end index of the items to deselect | |
296 * | |
297 * @exception DWTException <ul> | |
298 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
299 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
300 * </ul> | |
301 */ | |
302 public void deselect (int start, int end) { | |
303 checkWidget(); | |
304 if (start > end) return; | |
305 if (end < 0 || start >= itemCount) return; | |
306 start = Math.max (0, start); | |
307 end = Math.min (itemCount - 1, end); | |
308 int length = end - start + 1; | |
309 if (length <= 0) return; | |
310 if (start is 0 && end is itemCount - 1) { | |
311 deselectAll (); | |
312 } else { | |
313 NSTableView widget = (NSTableView)view; | |
314 ignoreSelect = true; | |
315 for (int i=0; i<length; i++) { | |
316 widget.deselectRow (i); | |
317 } | |
318 ignoreSelect = false; | |
319 } | |
320 } | |
321 | |
322 /** | |
323 * Deselects the items at the given zero-relative indices in the receiver. | |
324 * If the item at the given zero-relative index in the receiver | |
325 * is selected, it is deselected. If the item at the index | |
326 * was not selected, it remains deselected. Indices that are out | |
327 * of range and duplicate indices are ignored. | |
328 * | |
329 * @param indices the array of indices for the items to deselect | |
330 * | |
331 * @exception IllegalArgumentException <ul> | |
332 * <li>ERROR_NULL_ARGUMENT - if the set of indices is null</li> | |
333 * </ul> | |
334 * @exception DWTException <ul> | |
335 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
336 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
337 * </ul> | |
338 */ | |
339 public void deselect (int [] indices) { | |
340 checkWidget(); | |
341 if (indices is null) error (DWT.ERROR_NULL_ARGUMENT); | |
342 NSTableView widget = (NSTableView)view; | |
343 ignoreSelect = true; | |
344 for (int i=0; i<indices.length; i++) { | |
345 widget.deselectRow (indices [i]); | |
346 } | |
347 ignoreSelect = false; | |
348 } | |
349 | |
350 /** | |
351 * Deselects all selected items in the receiver. | |
352 * | |
353 * @exception DWTException <ul> | |
354 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
355 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
356 * </ul> | |
357 */ | |
358 public void deselectAll () { | |
359 checkWidget (); | |
360 NSTableView widget = (NSTableView)view; | |
361 ignoreSelect = true; | |
362 widget.deselectAll(null); | |
363 ignoreSelect = false; | |
364 } | |
365 | |
366 void fixSelection (int index, bool add) { | |
367 int [] selection = getSelectionIndices (); | |
368 if (selection.length is 0) return; | |
369 int newCount = 0; | |
370 bool fix = false; | |
371 for (int i = 0; i < selection.length; i++) { | |
372 if (!add && selection [i] is index) { | |
373 fix = true; | |
374 } else { | |
375 int newIndex = newCount++; | |
376 selection [newIndex] = selection [i] + 1; | |
377 if (selection [newIndex] - 1 >= index) { | |
378 selection [newIndex] += add ? 1 : -1; | |
379 fix = true; | |
380 } | |
381 } | |
382 } | |
383 if (fix) select (selection, newCount, true); | |
384 } | |
385 | |
386 /** | |
387 * Returns the zero-relative index of the item which currently | |
388 * has the focus in the receiver, or -1 if no item has focus. | |
389 * | |
390 * @return the index of the selected item | |
391 * | |
392 * @exception DWTException <ul> | |
393 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
394 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
395 * </ul> | |
396 */ | |
397 public int getFocusIndex () { | |
398 checkWidget(); | |
399 // int [] first = new int [1], last = new int [1]; | |
400 // if (OS.GetDataBrowserSelectionAnchor (handle, first, last) !is OS.noErr) return -1; | |
401 // return first [0] - 1; | |
402 return -1; | |
403 } | |
404 | |
405 /** | |
406 * Returns the item at the given, zero-relative index in the | |
407 * receiver. Throws an exception if the index is out of range. | |
408 * | |
409 * @param index the index of the item to return | |
410 * @return the item at the given index | |
411 * | |
412 * @exception IllegalArgumentException <ul> | |
413 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li> | |
414 * </ul> | |
415 * @exception DWTException <ul> | |
416 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
417 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
418 * </ul> | |
419 */ | |
420 public String getItem (int index) { | |
421 checkWidget(); | |
422 if (!(0 <= index && index < itemCount)) error (DWT.ERROR_INVALID_RANGE); | |
423 return items [index]; | |
424 } | |
425 | |
426 /** | |
427 * Returns the number of items contained in the receiver. | |
428 * | |
429 * @return the number of items | |
430 * | |
431 * @exception DWTException <ul> | |
432 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
433 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
434 * </ul> | |
435 */ | |
436 public int getItemCount () { | |
437 checkWidget(); | |
438 return itemCount; | |
439 } | |
440 | |
441 /** | |
442 * Returns the height of the area which would be used to | |
443 * display <em>one</em> of the items in the list. | |
444 * | |
445 * @return the height of one item | |
446 * | |
447 * @exception DWTException <ul> | |
448 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
449 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
450 * </ul> | |
451 */ | |
452 public int getItemHeight () { | |
453 checkWidget (); | |
454 return (int)((NSTableView)view).rowHeight(); | |
455 } | |
456 | |
457 /** | |
458 * Returns a (possibly empty) array of <code>String</code>s which | |
459 * are the items in the receiver. | |
460 * <p> | |
461 * Note: This is not the actual structure used by the receiver | |
462 * to maintain its list of items, so modifying the array will | |
463 * not affect the receiver. | |
464 * </p> | |
465 * | |
466 * @return the items in the receiver's list | |
467 * | |
468 * @exception DWTException <ul> | |
469 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
470 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
471 * </ul> | |
472 */ | |
473 public String [] getItems () { | |
474 checkWidget(); | |
475 String [] result = new String [itemCount]; | |
476 System.arraycopy (items, 0, result, 0, itemCount); | |
477 return result; | |
478 } | |
479 | |
480 /** | |
481 * Returns an array of <code>String</code>s that are currently | |
482 * selected in the receiver. The order of the items is unspecified. | |
483 * An empty array indicates that no items are selected. | |
484 * <p> | |
485 * Note: This is not the actual structure used by the receiver | |
486 * to maintain its selection, so modifying the array will | |
487 * not affect the receiver. | |
488 * </p> | |
489 * @return an array representing the selection | |
490 * | |
491 * @exception DWTException <ul> | |
492 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
493 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
494 * </ul> | |
495 */ | |
496 public String [] getSelection () { | |
497 checkWidget (); | |
498 NSTableView widget = (NSTableView)view; | |
499 if (widget.numberOfSelectedRows() is 0) { | |
500 return new String [0]; | |
501 } | |
502 NSIndexSet selection = widget.selectedRowIndexes(); | |
503 int count = selection.count(); | |
504 int [] indexBuffer = new int [count]; | |
505 selection.getIndexes(indexBuffer, count, 0); | |
506 String [] result = new String [count]; | |
507 for (int i=0; i<count; i++) { | |
508 result [i] = items [indexBuffer [i]]; | |
509 } | |
510 return result; | |
511 } | |
512 | |
513 /** | |
514 * Returns the number of selected items contained in the receiver. | |
515 * | |
516 * @return the number of selected items | |
517 * | |
518 * @exception DWTException <ul> | |
519 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
520 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
521 * </ul> | |
522 */ | |
523 public int getSelectionCount () { | |
524 checkWidget (); | |
525 return ((NSTableView)view).numberOfSelectedRows(); | |
526 } | |
527 | |
528 /** | |
529 * Returns the zero-relative index of the item which is currently | |
530 * selected in the receiver, or -1 if no item is selected. | |
531 * | |
532 * @return the index of the selected item or -1 | |
533 * | |
534 * @exception DWTException <ul> | |
535 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
536 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
537 * </ul> | |
538 */ | |
539 public int getSelectionIndex () { | |
540 checkWidget(); | |
541 //TODO - check empty selection case | |
542 return ((NSTableView)view).selectedRow(); | |
543 } | |
544 | |
545 /** | |
546 * Returns the zero-relative indices of the items which are currently | |
547 * selected in the receiver. The order of the indices is unspecified. | |
548 * The array is empty if no items are selected. | |
549 * <p> | |
550 * Note: This is not the actual structure used by the receiver | |
551 * to maintain its selection, so modifying the array will | |
552 * not affect the receiver. | |
553 * </p> | |
554 * @return the array of indices of the selected items | |
555 * | |
556 * @exception DWTException <ul> | |
557 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
558 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
559 * </ul> | |
560 */ | |
561 public int [] getSelectionIndices () { | |
562 checkWidget (); | |
563 NSTableView widget = (NSTableView)view; | |
564 if (widget.numberOfSelectedRows() is 0) { | |
565 return new int [0]; | |
566 } | |
567 NSIndexSet selection = widget.selectedRowIndexes(); | |
568 int count = selection.count(); | |
569 int [] result = new int [count]; | |
570 selection.getIndexes(result, count, 0); | |
571 return result; | |
572 } | |
573 | |
574 /** | |
575 * Returns the zero-relative index of the item which is currently | |
576 * at the top of the receiver. This index can change when items are | |
577 * scrolled or new items are added or removed. | |
578 * | |
579 * @return the index of the top item | |
580 * | |
581 * @exception DWTException <ul> | |
582 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
583 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
584 * </ul> | |
585 */ | |
586 public int getTopIndex () { | |
587 checkWidget(); | |
588 //TODO - partial item at the top | |
589 NSRect rect = scrollView.documentVisibleRect(); | |
590 NSPoint point = new NSPoint(); | |
591 point.x = rect.x; | |
592 point.y = rect.y; | |
593 return ((NSTableView)view).rowAtPoint(point); | |
594 } | |
595 | |
596 /** | |
597 * Gets the index of an item. | |
598 * <p> | |
599 * The list is searched starting at 0 until an | |
600 * item is found that is equal to the search item. | |
601 * If no item is found, -1 is returned. Indexing | |
602 * is zero based. | |
603 * | |
604 * @param string the search item | |
605 * @return the index of the item | |
606 * | |
607 * @exception IllegalArgumentException <ul> | |
608 * <li>ERROR_NULL_ARGUMENT - if the string is null</li> | |
609 * </ul> | |
610 * @exception DWTException <ul> | |
611 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
612 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
613 * </ul> | |
614 */ | |
615 public int indexOf (String item) { | |
616 checkWidget(); | |
617 if (item is null) error (DWT.ERROR_NULL_ARGUMENT); | |
618 for (int i=0; i<itemCount; i++) { | |
619 if (items [i].equals (item)) return i; | |
620 } | |
621 return -1; | |
622 } | |
623 | |
624 /** | |
625 * Searches the receiver's list starting at the given, | |
626 * zero-relative index until an item is found that is equal | |
627 * to the argument, and returns the index of that item. If | |
628 * no item is found or the starting index is out of range, | |
629 * returns -1. | |
630 * | |
631 * @param string the search item | |
632 * @param start the zero-relative index at which to start the search | |
633 * @return the index of the item | |
634 * | |
635 * @exception IllegalArgumentException <ul> | |
636 * <li>ERROR_NULL_ARGUMENT - if the string is null</li> | |
637 * </ul> | |
638 * @exception DWTException <ul> | |
639 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
640 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
641 * </ul> | |
642 */ | |
643 public int indexOf (String string, int start) { | |
644 checkWidget(); | |
645 if (string is null) error (DWT.ERROR_NULL_ARGUMENT); | |
646 for (int i=start; i<itemCount; i++) { | |
647 if (items [i].equals (string)) return i; | |
648 } | |
649 return -1; | |
650 } | |
651 | |
652 /** | |
653 * Returns <code>true</code> if the item is selected, | |
654 * and <code>false</code> otherwise. Indices out of | |
655 * range are ignored. | |
656 * | |
657 * @param index the index of the item | |
658 * @return the selection state of the item at the index | |
659 * | |
660 * @exception DWTException <ul> | |
661 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
662 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
663 * </ul> | |
664 */ | |
665 public bool isSelected (int index) { | |
666 checkWidget(); | |
667 //TODO - range check | |
668 return ((NSTableView)view).isRowSelected(index); | |
669 } | |
670 | |
671 int numberOfRowsInTableView(int aTableView) { | |
672 return itemCount; | |
673 } | |
674 | |
675 void releaseHandle () { | |
676 super.releaseHandle (); | |
677 if (column !is null) column.release(); | |
678 column = null; | |
679 } | |
680 | |
681 void releaseWidget () { | |
682 super.releaseWidget (); | |
683 items = null; | |
684 } | |
685 | |
686 /** | |
687 * Removes the item from the receiver at the given | |
688 * zero-relative index. | |
689 * | |
690 * @param index the index for the item | |
691 * | |
692 * @exception IllegalArgumentException <ul> | |
693 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li> | |
694 * </ul> | |
695 * @exception DWTException <ul> | |
696 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
697 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
698 * </ul> | |
699 */ | |
700 public void remove (int index) { | |
701 checkWidget(); | |
702 if (!(0 <= index && index < itemCount)) error (DWT.ERROR_INVALID_RANGE); | |
703 if (index !is itemCount - 1) fixSelection (index, false); | |
704 System.arraycopy (items, index + 1, items, index, --itemCount - index); | |
705 items [itemCount] = null; | |
706 ((NSTableView)view).noteNumberOfRowsChanged(); | |
707 } | |
708 | |
709 /** | |
710 * Removes the items from the receiver which are | |
711 * between the given zero-relative start and end | |
712 * indices (inclusive). | |
713 * | |
714 * @param start the start of the range | |
715 * @param end the end of the range | |
716 * | |
717 * @exception IllegalArgumentException <ul> | |
718 * <li>ERROR_INVALID_RANGE - if either the start or end are not between 0 and the number of elements in the list minus 1 (inclusive)</li> | |
719 * </ul> | |
720 * @exception DWTException <ul> | |
721 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
722 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
723 * </ul> | |
724 */ | |
725 public void remove (int start, int end) { | |
726 checkWidget(); | |
727 if (start > end) return; | |
728 if (!(0 <= start && start <= end && end < itemCount)) { | |
729 error (DWT.ERROR_INVALID_RANGE); | |
730 } | |
731 int length = end - start + 1; | |
732 for (int i=0; i<length; i++) remove (start); | |
733 } | |
734 | |
735 /** | |
736 * Searches the receiver's list starting at the first item | |
737 * until an item is found that is equal to the argument, | |
738 * and removes that item from the list. | |
739 * | |
740 * @param string the item to remove | |
741 * | |
742 * @exception IllegalArgumentException <ul> | |
743 * <li>ERROR_NULL_ARGUMENT - if the string is null</li> | |
744 * <li>ERROR_INVALID_ARGUMENT - if the string is not found in the list</li> | |
745 * </ul> | |
746 * @exception DWTException <ul> | |
747 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
748 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
749 * </ul> | |
750 */ | |
751 public void remove (String string) { | |
752 checkWidget(); | |
753 if (string is null) error (DWT.ERROR_NULL_ARGUMENT); | |
754 int index = indexOf (string, 0); | |
755 if (index is -1) error (DWT.ERROR_INVALID_ARGUMENT); | |
756 remove (index); | |
757 } | |
758 | |
759 /** | |
760 * Removes the items from the receiver at the given | |
761 * zero-relative indices. | |
762 * | |
763 * @param indices the array of indices of the items | |
764 * | |
765 * @exception IllegalArgumentException <ul> | |
766 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li> | |
767 * <li>ERROR_NULL_ARGUMENT - if the indices array is null</li> | |
768 * </ul> | |
769 * @exception DWTException <ul> | |
770 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
771 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
772 * </ul> | |
773 */ | |
774 public void remove (int [] indices) { | |
775 checkWidget (); | |
776 if (indices is null) error (DWT.ERROR_NULL_ARGUMENT); | |
777 if (indices.length is 0) return; | |
778 int [] newIndices = new int [indices.length]; | |
779 System.arraycopy (indices, 0, newIndices, 0, indices.length); | |
780 sort (newIndices); | |
781 int start = newIndices [newIndices.length - 1], end = newIndices [0]; | |
782 int count = getItemCount (); | |
783 if (!(0 <= start && start <= end && end < count)) { | |
784 error (DWT.ERROR_INVALID_RANGE); | |
785 } | |
786 int last = -1; | |
787 for (int i=0; i<newIndices.length; i++) { | |
788 int index = newIndices [i]; | |
789 if (index !is last) { | |
790 remove (index); | |
791 last = index; | |
792 } | |
793 } | |
794 } | |
795 | |
796 /** | |
797 * Removes all of the items from the receiver. | |
798 * <p> | |
799 * @exception DWTException <ul> | |
800 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
801 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
802 * </ul> | |
803 */ | |
804 public void removeAll () { | |
805 checkWidget(); | |
806 items = new String [4]; | |
807 itemCount = 0; | |
808 ((NSTableView)view).noteNumberOfRowsChanged(); | |
809 } | |
810 | |
811 /** | |
812 * Removes the listener from the collection of listeners who will | |
813 * be notified when the user changes the receiver's selection. | |
814 * | |
815 * @param listener the listener which should no longer be notified | |
816 * | |
817 * @exception IllegalArgumentException <ul> | |
818 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
819 * </ul> | |
820 * @exception DWTException <ul> | |
821 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
822 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
823 * </ul> | |
824 * | |
825 * @see SelectionListener | |
826 * @see #addSelectionListener | |
827 */ | |
828 public void removeSelectionListener(SelectionListener listener) { | |
829 checkWidget(); | |
830 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
831 if (eventTable is null) return; | |
832 eventTable.unhook(DWT.Selection, listener); | |
833 eventTable.unhook(DWT.DefaultSelection,listener); | |
834 } | |
835 | |
836 /** | |
837 * Selects the item at the given zero-relative index in the receiver's | |
838 * list. If the item at the index was already selected, it remains | |
839 * selected. Indices that are out of range are ignored. | |
840 * | |
841 * @param index the index of the item to select | |
842 * | |
843 * @exception DWTException <ul> | |
844 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
845 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
846 * </ul> | |
847 */ | |
848 public void select (int index) { | |
849 checkWidget(); | |
850 if (0 <= index && index < itemCount) { | |
851 NSIndexSet indexes = (NSIndexSet)new NSIndexSet().alloc(); | |
852 indexes.initWithIndex(index); | |
853 NSTableView widget = (NSTableView)view; | |
854 ignoreSelect = true; | |
855 ((NSTableView)view).selectRowIndexes(indexes, true); | |
856 ignoreSelect = false; | |
857 } | |
858 } | |
859 | |
860 /** | |
861 * Selects the items in the range specified by the given zero-relative | |
862 * indices in the receiver. The range of indices is inclusive. | |
863 * The current selection is not cleared before the new items are selected. | |
864 * <p> | |
865 * If an item in the given range is not selected, it is selected. | |
866 * If an item in the given range was already selected, it remains selected. | |
867 * Indices that are out of range are ignored and no items will be selected | |
868 * if start is greater than end. | |
869 * If the receiver is single-select and there is more than one item in the | |
870 * given range, then all indices are ignored. | |
871 * | |
872 * @param start the start of the range | |
873 * @param end the end of the range | |
874 * | |
875 * @exception DWTException <ul> | |
876 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
877 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
878 * </ul> | |
879 * | |
880 * @see List#setSelection(int,int) | |
881 */ | |
882 public void select (int start, int end) { | |
883 checkWidget (); | |
884 if (end < 0 || start > end || ((style & DWT.SINGLE) !is 0 && start !is end)) return; | |
885 if (itemCount is 0 || start >= itemCount) return; | |
886 if (start is 0 && end is itemCount - 1) { | |
887 selectAll (); | |
888 } else { | |
889 start = Math.max (0, start); | |
890 end = Math.min (end, itemCount - 1); | |
891 int length = end - start + 1; | |
892 NSIndexSet indexes = (NSIndexSet)new NSIndexSet().alloc(); | |
893 NSRange range = new NSRange(); | |
894 range.location = start; | |
895 range.length = length; | |
896 indexes.initWithIndexesInRange(range); | |
897 NSTableView widget = (NSTableView)view; | |
898 ignoreSelect = true; | |
899 widget.selectRowIndexes(indexes, true); | |
900 ignoreSelect = false; | |
901 } | |
902 } | |
903 | |
904 /** | |
905 * Selects the items at the given zero-relative indices in the receiver. | |
906 * The current selection is not cleared before the new items are selected. | |
907 * <p> | |
908 * If the item at a given index is not selected, it is selected. | |
909 * If the item at a given index was already selected, it remains selected. | |
910 * Indices that are out of range and duplicate indices are ignored. | |
911 * If the receiver is single-select and multiple indices are specified, | |
912 * then all indices are ignored. | |
913 * | |
914 * @param indices the array of indices for the items to select | |
915 * | |
916 * @exception IllegalArgumentException <ul> | |
917 * <li>ERROR_NULL_ARGUMENT - if the array of indices is null</li> | |
918 * </ul> | |
919 * @exception DWTException <ul> | |
920 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
921 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
922 * </ul> | |
923 * | |
924 * @see List#setSelection(int[]) | |
925 */ | |
926 public void select (int [] indices) { | |
927 checkWidget (); | |
928 if (indices is null) error (DWT.ERROR_NULL_ARGUMENT); | |
929 int length = indices.length; | |
930 if (length is 0 || ((style & DWT.SINGLE) !is 0 && length > 1)) return; | |
931 int count = 0; | |
932 NSMutableIndexSet indexes = (NSMutableIndexSet)new NSMutableIndexSet().alloc().init(); | |
933 for (int i=0; i<length; i++) { | |
934 int index = indices [length - i - 1]; | |
935 if (index >= 0 && index < itemCount) { | |
936 indexes.addIndex (indices [i]); | |
937 count++; | |
938 } | |
939 } | |
940 if (count > 0) { | |
941 NSTableView widget = (NSTableView)view; | |
942 ignoreSelect = true; | |
943 widget.selectRowIndexes(indexes, true); | |
944 ignoreSelect = false; | |
945 } | |
946 } | |
947 | |
948 void select (int [] ids, int count, bool clear) { | |
949 NSMutableIndexSet indexes = (NSMutableIndexSet)new NSMutableIndexSet().alloc().init(); | |
950 for (int i=0; i<count; i++) indexes.addIndex (ids [i] - 1); //WRONG -1 | |
951 NSTableView widget = (NSTableView)view; | |
952 ignoreSelect = true; | |
953 widget.selectRowIndexes(indexes, !clear); | |
954 ignoreSelect = false; | |
955 } | |
956 | |
957 /** | |
958 * Selects all of the items in the receiver. | |
959 * <p> | |
960 * If the receiver is single-select, do nothing. | |
961 * | |
962 * @exception DWTException <ul> | |
963 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
964 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
965 * </ul> | |
966 */ | |
967 public void selectAll () { | |
968 checkWidget (); | |
969 if ((style & DWT.SINGLE) !is 0) return; | |
970 NSTableView widget = (NSTableView)view; | |
971 ignoreSelect = true; | |
972 widget.selectAll(null); | |
973 ignoreSelect = false; | |
974 } | |
975 | |
976 void sendDoubleSelection() { | |
977 postEvent (DWT.DefaultSelection); | |
978 } | |
979 | |
980 /** | |
981 * Sets the text of the item in the receiver's list at the given | |
982 * zero-relative index to the string argument. | |
983 * | |
984 * @param index the index for the item | |
985 * @param string the new text for the item | |
986 * | |
987 * @exception IllegalArgumentException <ul> | |
988 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li> | |
989 * <li>ERROR_NULL_ARGUMENT - if the string is null</li> | |
990 * </ul> | |
991 * @exception DWTException <ul> | |
992 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
993 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
994 * </ul> | |
995 */ | |
996 public void setItem (int index, String string) { | |
997 checkWidget(); | |
998 if (string is null) error (DWT.ERROR_NULL_ARGUMENT); | |
999 if (!(0 <= index && index < itemCount)) error (DWT.ERROR_INVALID_RANGE); | |
1000 items [index] = string; | |
1001 ((NSTableView)view).reloadData(); | |
1002 } | |
1003 | |
1004 /** | |
1005 * Sets the receiver's items to be the given array of items. | |
1006 * | |
1007 * @param items the array of items | |
1008 * | |
1009 * @exception IllegalArgumentException <ul> | |
1010 * <li>ERROR_NULL_ARGUMENT - if the items array is null</li> | |
1011 * <li>ERROR_INVALID_ARGUMENT - if an item in the items array is null</li> | |
1012 * </ul> | |
1013 * @exception DWTException <ul> | |
1014 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1015 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1016 * </ul> | |
1017 */ | |
1018 public void setItems (String [] items) { | |
1019 checkWidget(); | |
1020 if (items is null) error (DWT.ERROR_NULL_ARGUMENT); | |
1021 for (int i=0; i<items.length; i++) { | |
1022 if (items [i] is null) error (DWT.ERROR_INVALID_ARGUMENT); | |
1023 } | |
1024 this.items = new String [items.length]; | |
1025 System.arraycopy (items, 0, this.items, 0, items.length); | |
1026 itemCount = items.length; | |
1027 ((NSTableView)view).reloadData(); | |
1028 } | |
1029 | |
1030 /** | |
1031 * Selects the item at the given zero-relative index in the receiver. | |
1032 * If the item at the index was already selected, it remains selected. | |
1033 * The current selection is first cleared, then the new item is selected. | |
1034 * Indices that are out of range are ignored. | |
1035 * | |
1036 * @param index the index of the item to select | |
1037 * | |
1038 * @exception DWTException <ul> | |
1039 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1040 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1041 * </ul> | |
1042 * @see List#deselectAll() | |
1043 * @see List#select(int) | |
1044 */ | |
1045 public void setSelection (int index) { | |
1046 checkWidget(); | |
1047 deselectAll (); | |
1048 setSelection (index, false); | |
1049 } | |
1050 | |
1051 void setSelection (int index, bool notify) { | |
1052 // checkWidget(); | |
1053 if (0 <= index && index < itemCount) { | |
1054 int [] ids = new int [] {index + 1}; | |
1055 select (ids, ids.length, true); | |
1056 showIndex (index); | |
1057 if (notify) postEvent (DWT.Selection); | |
1058 } | |
1059 } | |
1060 | |
1061 /** | |
1062 * Selects the items in the range specified by the given zero-relative | |
1063 * indices in the receiver. The range of indices is inclusive. | |
1064 * The current selection is cleared before the new items are selected. | |
1065 * <p> | |
1066 * Indices that are out of range are ignored and no items will be selected | |
1067 * if start is greater than end. | |
1068 * If the receiver is single-select and there is more than one item in the | |
1069 * given range, then all indices are ignored. | |
1070 * | |
1071 * @param start the start index of the items to select | |
1072 * @param end the end index of the items to select | |
1073 * | |
1074 * @exception DWTException <ul> | |
1075 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1076 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1077 * </ul> | |
1078 * | |
1079 * @see List#deselectAll() | |
1080 * @see List#select(int,int) | |
1081 */ | |
1082 public void setSelection (int start, int end) { | |
1083 checkWidget (); | |
1084 deselectAll (); | |
1085 if (end < 0 || start > end || ((style & DWT.SINGLE) !is 0 && start !is end)) return; | |
1086 if (itemCount is 0 || start >= itemCount) return; | |
1087 start = Math.max (0, start); | |
1088 end = Math.min (end, itemCount - 1); | |
1089 int length = end - start + 1; | |
1090 int [] ids = new int [length]; | |
1091 for (int i=0; i<length; i++) ids [i] = end - i + 1; | |
1092 select (ids, length, true); | |
1093 if (ids.length > 0) showIndex (ids [0] - 1); | |
1094 } | |
1095 | |
1096 /** | |
1097 * Selects the items at the given zero-relative indices in the receiver. | |
1098 * The current selection is cleared before the new items are selected. | |
1099 * <p> | |
1100 * Indices that are out of range and duplicate indices are ignored. | |
1101 * If the receiver is single-select and multiple indices are specified, | |
1102 * then all indices are ignored. | |
1103 * | |
1104 * @param indices the indices of the items to select | |
1105 * | |
1106 * @exception IllegalArgumentException <ul> | |
1107 * <li>ERROR_NULL_ARGUMENT - if the array of indices is null</li> | |
1108 * </ul> | |
1109 * @exception DWTException <ul> | |
1110 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1111 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1112 * </ul> | |
1113 * | |
1114 * @see List#deselectAll() | |
1115 * @see List#select(int[]) | |
1116 */ | |
1117 public void setSelection (int [] indices) { | |
1118 checkWidget (); | |
1119 if (indices is null) error (DWT.ERROR_NULL_ARGUMENT); | |
1120 deselectAll (); | |
1121 int length = indices.length; | |
1122 if (length is 0 || ((style & DWT.SINGLE) !is 0 && length > 1)) return; | |
1123 int [] ids = new int [length]; | |
1124 int count = 0; | |
1125 for (int i=0; i<length; i++) { | |
1126 int index = indices [length - i - 1]; | |
1127 if (index >= 0 && index < itemCount) { | |
1128 ids [count++] = index + 1; | |
1129 } | |
1130 } | |
1131 if (count > 0) { | |
1132 select (ids, count, true); | |
1133 showIndex (ids [0] - 1); | |
1134 } | |
1135 } | |
1136 | |
1137 /** | |
1138 * Sets the receiver's selection to be the given array of items. | |
1139 * The current selection is cleared before the new items are selected. | |
1140 * <p> | |
1141 * Items that are not in the receiver are ignored. | |
1142 * If the receiver is single-select and multiple items are specified, | |
1143 * then all items are ignored. | |
1144 * | |
1145 * @param items the array of items | |
1146 * | |
1147 * @exception IllegalArgumentException <ul> | |
1148 * <li>ERROR_NULL_ARGUMENT - if the array of items is null</li> | |
1149 * </ul> | |
1150 * @exception DWTException <ul> | |
1151 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1152 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1153 * </ul> | |
1154 * | |
1155 * @see List#deselectAll() | |
1156 * @see List#select(int[]) | |
1157 * @see List#setSelection(int[]) | |
1158 */ | |
1159 public void setSelection (String [] items) { | |
1160 checkWidget (); | |
1161 if (items is null) error (DWT.ERROR_NULL_ARGUMENT); | |
1162 deselectAll (); | |
1163 int length = items.length; | |
1164 if (length is 0 || ((style & DWT.SINGLE) !is 0 && length > 1)) return; | |
1165 int count = 0; | |
1166 int [] ids = new int [length]; | |
1167 for (int i=0; i<length; i++) { | |
1168 String string = items [length - i - 1]; | |
1169 if ((style & DWT.SINGLE) !is 0) { | |
1170 int index = indexOf (string, 0); | |
1171 if (index !is -1) { | |
1172 count = 1; | |
1173 ids = new int [] {index + 1}; | |
1174 } | |
1175 } else { | |
1176 int index = 0; | |
1177 while ((index = indexOf (string, index)) !is -1) { | |
1178 if (count is ids.length) { | |
1179 int [] newIds = new int [ids.length + 4]; | |
1180 System.arraycopy (ids, 0, newIds, 0, ids.length); | |
1181 ids = newIds; | |
1182 } | |
1183 ids [count++] = index + 1; | |
1184 index++; | |
1185 } | |
1186 } | |
1187 } | |
1188 if (count > 0) { | |
1189 select (ids, count, true); | |
1190 showIndex (ids [0] - 1); | |
1191 } | |
1192 } | |
1193 | |
1194 /** | |
1195 * Sets the zero-relative index of the item which is currently | |
1196 * at the top of the receiver. This index can change when items | |
1197 * are scrolled or new items are added and removed. | |
1198 * | |
1199 * @param index the index of the top item | |
1200 * | |
1201 * @exception DWTException <ul> | |
1202 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1203 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1204 * </ul> | |
1205 */ | |
1206 public void setTopIndex (int index) { | |
1207 checkWidget(); | |
1208 NSRect rect = ((NSTableView)view).rectOfRow(index); | |
1209 ((NSTableView)view).scrollRectToVisible(rect); | |
1210 } | |
1211 | |
1212 void showIndex (int index) { | |
1213 if (0 <= index && index < itemCount) { | |
1214 ((NSTableView)view).scrollRowToVisible(index); | |
1215 } | |
1216 } | |
1217 | |
1218 /** | |
1219 * Shows the selection. If the selection is already showing in the receiver, | |
1220 * this method simply returns. Otherwise, the items are scrolled until | |
1221 * the selection is visible. | |
1222 * | |
1223 * @exception DWTException <ul> | |
1224 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1225 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1226 * </ul> | |
1227 */ | |
1228 public void showSelection () { | |
1229 checkWidget(); | |
1230 int index = getSelectionIndex (); | |
1231 if (index >= 0) showIndex (index); | |
1232 } | |
1233 | |
1234 void tableViewSelectionDidChange (int aNotification) { | |
1235 if (ignoreSelect) return; | |
1236 postEvent (DWT.Selection); | |
1237 } | |
1238 | |
1239 bool tableView_shouldEditTableColumn_row(int aTableView, int aTableColumn, int rowIndex) { | |
1240 return false; | |
1241 } | |
1242 | |
1243 int tableView_objectValueForTableColumn_row(int aTableView, int aTableColumn, int rowIndex) { | |
1244 NSMutableDictionary dict = NSMutableDictionary.dictionaryWithCapacity(4); | |
1245 if (foreground !is null) { | |
1246 NSColor color = NSColor.colorWithDeviceRed(foreground.handle[0], foreground.handle[1], foreground.handle[2], 1); | |
1247 dict.setObject(color, OS.NSForegroundColorAttributeName()); | |
1248 } | |
1249 if (font !is null) { | |
1250 dict.setObject(font.handle, OS.NSFontAttributeName()); | |
1251 } | |
1252 if (background !is null) { | |
1253 NSColor color = NSColor.colorWithDeviceRed(background.handle[0], background.handle[1], background.handle[2], 1); | |
1254 dict.setObject(color, OS.NSBackgroundColorAttributeName()); | |
1255 } | |
1256 String text = items[rowIndex]; | |
1257 int length = text.length(); | |
1258 char[] chars = new char[length]; | |
1259 text.getChars(0, length, chars, 0); | |
1260 NSString str = NSString.stringWithCharacters(chars, length); | |
1261 NSAttributedString attribStr = ((NSAttributedString)new NSAttributedString().alloc()).initWithString_attributes_(str, dict); | |
1262 attribStr.autorelease(); | |
1263 return attribStr.id; | |
1264 } | |
1265 | |
1266 } |