Mercurial > projects > dwt-mac
comparison dwt/widgets/Table.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.Table; | |
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.Font; | |
22 import dwt.graphics.GC; | |
23 import dwt.graphics.Image; | |
24 import dwt.graphics.Point; | |
25 import dwt.graphics.Rectangle; | |
26 import dwt.internal.cocoa.NSBrowserCell; | |
27 import dwt.internal.cocoa.NSButtonCell; | |
28 import dwt.internal.cocoa.NSCell; | |
29 import dwt.internal.cocoa.NSIndexSet; | |
30 import dwt.internal.cocoa.NSMutableIndexSet; | |
31 import dwt.internal.cocoa.NSNumber; | |
32 import dwt.internal.cocoa.NSPoint; | |
33 import dwt.internal.cocoa.NSRange; | |
34 import dwt.internal.cocoa.NSRect; | |
35 import dwt.internal.cocoa.NSString; | |
36 import dwt.internal.cocoa.NSTableColumn; | |
37 import dwt.internal.cocoa.NSTableHeaderView; | |
38 import dwt.internal.cocoa.NSTableView; | |
39 import dwt.internal.cocoa.OS; | |
40 import dwt.internal.cocoa.SWTScrollView; | |
41 import dwt.internal.cocoa.SWTTableView; | |
42 | |
43 /** | |
44 * Instances of this class implement a selectable user interface | |
45 * object that displays a list of images and strings and issues | |
46 * notification when selected. | |
47 * <p> | |
48 * The item children that may be added to instances of this class | |
49 * must be of type <code>TableItem</code>. | |
50 * </p><p> | |
51 * Style <code>VIRTUAL</code> is used to create a <code>Table</code> whose | |
52 * <code>TableItem</code>s are to be populated by the client on an on-demand basis | |
53 * instead of up-front. This can provide significant performance improvements for | |
54 * tables that are very large or for which <code>TableItem</code> population is | |
55 * expensive (for example, retrieving values from an external source). | |
56 * </p><p> | |
57 * Here is an example of using a <code>Table</code> with style <code>VIRTUAL</code>: | |
58 * <code><pre> | |
59 * final Table table = new Table (parent, DWT.VIRTUAL | DWT.BORDER); | |
60 * table.setItemCount (1000000); | |
61 * table.addListener (DWT.SetData, new Listener () { | |
62 * public void handleEvent (Event event) { | |
63 * TableItem item = (TableItem) event.item; | |
64 * int index = table.indexOf (item); | |
65 * item.setText ("Item " + index); | |
66 * System.out.println (item.getText ()); | |
67 * } | |
68 * }); | |
69 * </pre></code> | |
70 * </p><p> | |
71 * Note that although this class is a subclass of <code>Composite</code>, | |
72 * it does not make sense to add <code>Control</code> children to it, | |
73 * or set a layout on it. | |
74 * </p><p> | |
75 * <dl> | |
76 * <dt><b>Styles:</b></dt> | |
77 * <dd>SINGLE, MULTI, CHECK, FULL_SELECTION, HIDE_SELECTION, VIRTUAL</dd> | |
78 * <dt><b>Events:</b></dt> | |
79 * <dd>Selection, DefaultSelection, SetData, MeasureItem, EraseItem, PaintItem</dd> | |
80 * </dl> | |
81 * </p><p> | |
82 * Note: Only one of the styles SINGLE, and MULTI may be specified. | |
83 * </p><p> | |
84 * IMPORTANT: This class is <em>not</em> intended to be subclassed. | |
85 * </p> | |
86 */ | |
87 public class Table extends Composite { | |
88 TableItem [] items; | |
89 TableColumn [] columns; | |
90 TableColumn sortColumn; | |
91 TableItem currentItem; | |
92 NSTableHeaderView headerView; | |
93 NSTableColumn firstColumn, checkColumn; | |
94 int columnCount, itemCount, lastIndexOf, sortDirection; | |
95 bool ignoreSelect; | |
96 | |
97 /** | |
98 * Constructs a new instance of this class given its parent | |
99 * and a style value describing its behavior and appearance. | |
100 * <p> | |
101 * The style value is either one of the style constants defined in | |
102 * class <code>DWT</code> which is applicable to instances of this | |
103 * class, or must be built by <em>bitwise OR</em>'ing together | |
104 * (that is, using the <code>int</code> "|" operator) two or more | |
105 * of those <code>DWT</code> style constants. The class description | |
106 * lists the style constants that are applicable to the class. | |
107 * Style bits are also inherited from superclasses. | |
108 * </p> | |
109 * | |
110 * @param parent a composite control which will be the parent of the new instance (cannot be null) | |
111 * @param style the style of control to construct | |
112 * | |
113 * @exception IllegalArgumentException <ul> | |
114 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
115 * </ul> | |
116 * @exception DWTException <ul> | |
117 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | |
118 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | |
119 * </ul> | |
120 * | |
121 * @see DWT#SINGLE | |
122 * @see DWT#MULTI | |
123 * @see DWT#CHECK | |
124 * @see DWT#FULL_SELECTION | |
125 * @see DWT#HIDE_SELECTION | |
126 * @see DWT#VIRTUAL | |
127 * @see Widget#checkSubclass | |
128 * @see Widget#getStyle | |
129 */ | |
130 public Table (Composite parent, int style) { | |
131 super (parent, checkStyle (style)); | |
132 } | |
133 | |
134 /** | |
135 * Adds the listener to the collection of listeners who will | |
136 * be notified when the user changes the receiver's selection, by sending | |
137 * it one of the messages defined in the <code>SelectionListener</code> | |
138 * interface. | |
139 * <p> | |
140 * When <code>widgetSelected</code> is called, the item field of the event object is valid. | |
141 * If the receiver has the <code>DWT.CHECK</code> style and the check selection changes, | |
142 * the event object detail field contains the value <code>DWT.CHECK</code>. | |
143 * <code>widgetDefaultSelected</code> is typically called when an item is double-clicked. | |
144 * The item field of the event object is valid for default selection, but the detail field is not used. | |
145 * </p> | |
146 * | |
147 * @param listener the listener which should be notified when the user changes the receiver's selection | |
148 * | |
149 * @exception IllegalArgumentException <ul> | |
150 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
151 * </ul> | |
152 * @exception DWTException <ul> | |
153 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
154 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
155 * </ul> | |
156 * | |
157 * @see SelectionListener | |
158 * @see #removeSelectionListener | |
159 * @see SelectionEvent | |
160 */ | |
161 public void addSelectionListener (SelectionListener listener) { | |
162 checkWidget (); | |
163 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
164 TypedListener typedListener = new TypedListener (listener); | |
165 addListener (DWT.Selection, typedListener); | |
166 addListener (DWT.DefaultSelection, typedListener); | |
167 } | |
168 | |
169 TableItem _getItem (int index) { | |
170 if ((style & DWT.VIRTUAL) is 0) return items [index]; | |
171 if (items [index] !is null) return items [index]; | |
172 return items [index] = new TableItem (this, DWT.NULL, -1, false); | |
173 } | |
174 | |
175 bool checkData (TableItem item, bool redraw) { | |
176 if (item.cached) return true; | |
177 if ((style & DWT.VIRTUAL) !is 0) { | |
178 item.cached = true; | |
179 Event event = new Event (); | |
180 event.item = item; | |
181 event.index = indexOf (item); | |
182 currentItem = item; | |
183 sendEvent (DWT.SetData, event); | |
184 //widget could be disposed at this point | |
185 currentItem = null; | |
186 if (isDisposed () || item.isDisposed ()) return false; | |
187 if (redraw) { | |
188 // if (!setScrollWidth (item)) item.redraw (OS.kDataBrowserNoItem); | |
189 } | |
190 } | |
191 return true; | |
192 } | |
193 | |
194 static int checkStyle (int style) { | |
195 /* | |
196 * Feature in Windows. Even when WS_HSCROLL or | |
197 * WS_VSCROLL is not specified, Windows creates | |
198 * trees and tables with scroll bars. The fix | |
199 * is to set H_SCROLL and V_SCROLL. | |
200 * | |
201 * NOTE: This code appears on all platforms so that | |
202 * applications have consistent scroll bar behavior. | |
203 */ | |
204 if ((style & DWT.NO_SCROLL) is 0) { | |
205 style |= DWT.H_SCROLL | DWT.V_SCROLL; | |
206 } | |
207 return checkBits (style, DWT.SINGLE, DWT.MULTI, 0, 0, 0, 0); | |
208 } | |
209 | |
210 protected void checkSubclass () { | |
211 if (!isValidSubclass ()) error (DWT.ERROR_INVALID_SUBCLASS); | |
212 } | |
213 | |
214 /** | |
215 * Clears the item at the given zero-relative index in the receiver. | |
216 * The text, icon and other attributes of the item are set to the default | |
217 * value. If the table was created with the <code>DWT.VIRTUAL</code> style, | |
218 * these attributes are requested again as needed. | |
219 * | |
220 * @param index the index of the item to clear | |
221 * | |
222 * @exception IllegalArgumentException <ul> | |
223 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li> | |
224 * </ul> | |
225 * @exception DWTException <ul> | |
226 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
227 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
228 * </ul> | |
229 * | |
230 * @see DWT#VIRTUAL | |
231 * @see DWT#SetData | |
232 * | |
233 * @since 3.0 | |
234 */ | |
235 public void clear (int index) { | |
236 checkWidget(); | |
237 if (!(0 <= index && index < itemCount)) error (DWT.ERROR_INVALID_RANGE); | |
238 TableItem item = items [index]; | |
239 if (item !is null) { | |
240 if (currentItem !is item) item.clear (); | |
241 if (currentItem is null && drawCount is 0) { | |
242 int [] id = new int [] {index + 1}; | |
243 // OS.UpdateDataBrowserItems (handle, 0, id.length, id, OS.kDataBrowserItemNoProperty, OS.kDataBrowserNoItem); | |
244 } | |
245 // setScrollWidth (item); | |
246 } | |
247 } | |
248 | |
249 /** | |
250 * Removes the items from the receiver which are between the given | |
251 * zero-relative start and end indices (inclusive). The text, icon | |
252 * and other attributes of the items are set to their default values. | |
253 * If the table was created with the <code>DWT.VIRTUAL</code> style, | |
254 * these attributes are requested again as needed. | |
255 * | |
256 * @param start the start index of the item to clear | |
257 * @param end the end index of the item to clear | |
258 * | |
259 * @exception IllegalArgumentException <ul> | |
260 * <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> | |
261 * </ul> | |
262 * @exception DWTException <ul> | |
263 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
264 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
265 * </ul> | |
266 * | |
267 * @see DWT#VIRTUAL | |
268 * @see DWT#SetData | |
269 * | |
270 * @since 3.0 | |
271 */ | |
272 public void clear (int start, int end) { | |
273 checkWidget(); | |
274 if (start > end) return; | |
275 if (!(0 <= start && start <= end && end < itemCount)) { | |
276 error (DWT.ERROR_INVALID_RANGE); | |
277 } | |
278 if (start is 0 && end is itemCount - 1) { | |
279 clearAll (); | |
280 } else { | |
281 for (int i=start; i<=end; i++) { | |
282 clear (i); | |
283 } | |
284 } | |
285 } | |
286 | |
287 /** | |
288 * Clears the items at the given zero-relative indices in the receiver. | |
289 * The text, icon and other attributes of the items are set to their default | |
290 * values. If the table was created with the <code>DWT.VIRTUAL</code> style, | |
291 * these attributes are requested again as needed. | |
292 * | |
293 * @param indices the array of indices of the items | |
294 * | |
295 * @exception IllegalArgumentException <ul> | |
296 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li> | |
297 * <li>ERROR_NULL_ARGUMENT - if the indices array is null</li> | |
298 * </ul> | |
299 * @exception DWTException <ul> | |
300 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
301 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
302 * </ul> | |
303 * | |
304 * @see DWT#VIRTUAL | |
305 * @see DWT#SetData | |
306 * | |
307 * @since 3.0 | |
308 */ | |
309 public void clear (int [] indices) { | |
310 checkWidget(); | |
311 if (indices is null) error (DWT.ERROR_NULL_ARGUMENT); | |
312 if (indices.length is 0) return; | |
313 for (int i=0; i<indices.length; i++) { | |
314 if (!(0 <= indices [i] && indices [i] < itemCount)) { | |
315 error (DWT.ERROR_INVALID_RANGE); | |
316 } | |
317 } | |
318 for (int i=0; i<indices.length; i++) { | |
319 clear (indices [i]); | |
320 } | |
321 } | |
322 | |
323 /** | |
324 * Clears all the items in the receiver. The text, icon and other | |
325 * attributes of the items are set to their default values. If the | |
326 * table was created with the <code>DWT.VIRTUAL</code> style, these | |
327 * attributes are requested again as needed. | |
328 * | |
329 * @exception DWTException <ul> | |
330 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
331 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
332 * </ul> | |
333 * | |
334 * @see DWT#VIRTUAL | |
335 * @see DWT#SetData | |
336 * | |
337 * @since 3.0 | |
338 */ | |
339 public void clearAll () { | |
340 checkWidget(); | |
341 for (int i=0; i<itemCount; i++) { | |
342 TableItem item = items [i]; | |
343 if (item !is null) item.clear (); | |
344 } | |
345 if (currentItem is null && drawCount is 0) { | |
346 // OS.UpdateDataBrowserItems (handle, 0, 0, null, OS.kDataBrowserItemNoProperty, OS.kDataBrowserNoItem); | |
347 } | |
348 // setScrollWidth (items, true); | |
349 } | |
350 | |
351 public Point computeSize (int wHint, int hHint, bool changed) { | |
352 checkWidget(); | |
353 int width = 0; | |
354 if (wHint is DWT.DEFAULT) { | |
355 if (columnCount !is 0) { | |
356 for (int i=0; i<columnCount; i++) { | |
357 width += columns [i].getWidth (); | |
358 } | |
359 } else { | |
360 int columnWidth = 0; | |
361 GC gc = new GC (this); | |
362 for (int i=0; i<itemCount; i++) { | |
363 TableItem item = items [i]; | |
364 if (item !is null) { | |
365 columnWidth = Math.max (columnWidth, item.calculateWidth (0, gc)); | |
366 } | |
367 } | |
368 gc.dispose (); | |
369 width += columnWidth + getInsetWidth (); | |
370 } | |
371 if ((style & DWT.CHECK) !is 0) width += getCheckColumnWidth (); | |
372 } else { | |
373 width = wHint; | |
374 } | |
375 if (width <= 0) width = DEFAULT_WIDTH; | |
376 int height = 0; | |
377 if (hHint is DWT.DEFAULT) { | |
378 height = itemCount * getItemHeight () + getHeaderHeight(); | |
379 } else { | |
380 height = hHint; | |
381 } | |
382 if (height <= 0) height = DEFAULT_HEIGHT; | |
383 Rectangle rect = computeTrim (0, 0, width, height); | |
384 return new Point (rect.width, rect.height); | |
385 } | |
386 | |
387 void createHandle () { | |
388 //TODO - DWT.CHECK | |
389 SWTScrollView scrollWidget = (SWTScrollView)new SWTScrollView().alloc(); | |
390 scrollWidget.initWithFrame(new NSRect ()); | |
391 scrollWidget.setHasHorizontalScroller(true); | |
392 scrollWidget.setHasVerticalScroller(true); | |
393 scrollWidget.setAutohidesScrollers(true); | |
394 scrollWidget.setBorderType(hasBorder() ? OS.NSBezelBorder : OS.NSNoBorder); | |
395 scrollWidget.setTag(jniRef); | |
396 | |
397 NSTableView widget = (NSTableView)new SWTTableView().alloc(); | |
398 widget.initWithFrame(new NSRect()); | |
399 widget.setAllowsMultipleSelection((style & DWT.MULTI) !is 0); | |
400 widget.setDataSource(widget); | |
401 widget.setDelegate(widget); | |
402 widget.setDoubleAction(OS.sel_sendDoubleSelection); | |
403 if (!hasBorder()) widget.setFocusRingType(OS.NSFocusRingTypeNone); | |
404 widget.setTag(jniRef); | |
405 | |
406 headerView = widget.headerView(); | |
407 headerView.retain(); | |
408 widget.setHeaderView(null); | |
409 | |
410 NSString str = NSString.stringWith(""); | |
411 if ((style & DWT.CHECK) !is 0) { | |
412 checkColumn = (NSTableColumn)new NSTableColumn().alloc(); | |
413 checkColumn.initWithIdentifier(str); | |
414 checkColumn.headerCell().setTitle(str); | |
415 widget.addTableColumn (checkColumn); | |
416 NSButtonCell cell = (NSButtonCell)new NSButtonCell().alloc().init(); | |
417 checkColumn.setDataCell(cell); | |
418 cell.setButtonType(OS.NSSwitchButton); | |
419 cell.setImagePosition(OS.NSImageOnly); | |
420 cell.setAllowsMixedState(true); | |
421 cell.release(); | |
422 checkColumn.setWidth(getCheckColumnWidth()); | |
423 checkColumn.setResizingMask(OS.NSTableColumnNoResizing); | |
424 checkColumn.setEditable(false); | |
425 } | |
426 | |
427 firstColumn = (NSTableColumn)new NSTableColumn().alloc(); | |
428 firstColumn.initWithIdentifier(str); | |
429 //column.setResizingMask(OS.NSTableColumnAutoresizingMask); | |
430 NSCell cell = (NSBrowserCell)new NSBrowserCell().alloc().init(); | |
431 firstColumn.setDataCell(cell); | |
432 cell.release(); | |
433 widget.addTableColumn (firstColumn); | |
434 | |
435 scrollView = scrollWidget; | |
436 view = widget; | |
437 scrollView.setDocumentView(widget); | |
438 parent.contentView().addSubview_(scrollView); | |
439 } | |
440 | |
441 void createItem (TableColumn column, int index) { | |
442 if (!(0 <= index && index <= columnCount)) error (DWT.ERROR_INVALID_RANGE); | |
443 if (columnCount is columns.length) { | |
444 TableColumn [] newColumns = new TableColumn [columnCount + 4]; | |
445 System.arraycopy (columns, 0, newColumns, 0, columns.length); | |
446 columns = newColumns; | |
447 } | |
448 NSTableColumn nsColumn; | |
449 if (columnCount is 0) { | |
450 //TODO - clear attributes, alignment etc. | |
451 nsColumn = firstColumn; | |
452 firstColumn = null; | |
453 } else { | |
454 //TODO - set attributes, alignment etc. | |
455 nsColumn = (NSTableColumn)new NSTableColumn().alloc(); | |
456 nsColumn.initWithIdentifier(NSString.stringWith("")); | |
457 ((NSTableView)view).addTableColumn (nsColumn); | |
458 int checkColumn = (style & DWT.CHECK) !is 0 ? 1 : 0; | |
459 ((NSTableView)view).moveColumn (columnCount + checkColumn, index + checkColumn); | |
460 NSCell cell = (NSBrowserCell)new NSBrowserCell().alloc().init(); | |
461 nsColumn.setDataCell(cell); | |
462 cell.release(); | |
463 } | |
464 column.nsColumn = nsColumn; | |
465 nsColumn.headerCell().setTitle(NSString.stringWith("")); | |
466 nsColumn.setWidth(0); | |
467 System.arraycopy (columns, index, columns, index + 1, columnCount++ - index); | |
468 columns [index] = column; | |
469 if (columnCount > 1) { | |
470 for (int i=0; i<itemCount; i++) { | |
471 TableItem item = items [i]; | |
472 if (item !is null) { | |
473 String [] strings = item.strings; | |
474 if (strings !is null) { | |
475 String [] temp = new String [columnCount]; | |
476 System.arraycopy (strings, 0, temp, 0, index); | |
477 System.arraycopy (strings, index, temp, index+1, columnCount-index-1); | |
478 temp [index] = ""; | |
479 item.strings = temp; | |
480 } | |
481 if (index is 0) item.text = ""; | |
482 Image [] images = item.images; | |
483 if (images !is null) { | |
484 Image [] temp = new Image [columnCount]; | |
485 System.arraycopy (images, 0, temp, 0, index); | |
486 System.arraycopy (images, index, temp, index+1, columnCount-index-1); | |
487 item.images = temp; | |
488 } | |
489 if (index is 0) item.image = null; | |
490 Color [] cellBackground = item.cellBackground; | |
491 if (cellBackground !is null) { | |
492 Color [] temp = new Color [columnCount]; | |
493 System.arraycopy (cellBackground, 0, temp, 0, index); | |
494 System.arraycopy (cellBackground, index, temp, index+1, columnCount-index-1); | |
495 item.cellBackground = temp; | |
496 } | |
497 Color [] cellForeground = item.cellForeground; | |
498 if (cellForeground !is null) { | |
499 Color [] temp = new Color [columnCount]; | |
500 System.arraycopy (cellForeground, 0, temp, 0, index); | |
501 System.arraycopy (cellForeground, index, temp, index+1, columnCount-index-1); | |
502 item.cellForeground = temp; | |
503 } | |
504 Font [] cellFont = item.cellFont; | |
505 if (cellFont !is null) { | |
506 Font [] temp = new Font [columnCount]; | |
507 System.arraycopy (cellFont, 0, temp, 0, index); | |
508 System.arraycopy (cellFont, index, temp, index+1, columnCount-index-1); | |
509 item.cellFont = temp; | |
510 } | |
511 } | |
512 } | |
513 } | |
514 } | |
515 | |
516 void createItem (TableItem item, int index) { | |
517 if (!(0 <= index && index <= itemCount)) error (DWT.ERROR_INVALID_RANGE); | |
518 if (itemCount is items.length) { | |
519 /* Grow the array faster when redraw is off */ | |
520 int length = drawCount is 0 ? items.length + 4 : Math.max (4, items.length * 3 / 2); | |
521 TableItem [] newItems = new TableItem [length]; | |
522 System.arraycopy (items, 0, newItems, 0, items.length); | |
523 items = newItems; | |
524 } | |
525 System.arraycopy (items, index, items, index + 1, itemCount++ - index); | |
526 items [index] = item; | |
527 //TODO - use noteNumberOfRowsChanged? | |
528 ((NSTableView)view).reloadData(); | |
529 } | |
530 | |
531 void createWidget () { | |
532 super.createWidget (); | |
533 items = new TableItem [4]; | |
534 columns = new TableColumn [4]; | |
535 } | |
536 | |
537 Color defaultBackground () { | |
538 return display.getSystemColor (DWT.COLOR_LIST_BACKGROUND); | |
539 } | |
540 | |
541 Color defaultForeground () { | |
542 return display.getSystemColor (DWT.COLOR_LIST_FOREGROUND); | |
543 } | |
544 | |
545 /** | |
546 * Deselects the item at the given zero-relative index in the receiver. | |
547 * If the item at the index was already deselected, it remains | |
548 * deselected. Indices that are out of range are ignored. | |
549 * | |
550 * @param index the index of the item to deselect | |
551 * | |
552 * @exception DWTException <ul> | |
553 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
554 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
555 * </ul> | |
556 */ | |
557 public void deselect (int index) { | |
558 checkWidget(); | |
559 if (0 <= index && index < itemCount) { | |
560 NSTableView widget = (NSTableView)view; | |
561 ignoreSelect = true; | |
562 widget.deselectRow (index); | |
563 ignoreSelect = false; | |
564 } | |
565 } | |
566 | |
567 /** | |
568 * Deselects the items at the given zero-relative indices in the receiver. | |
569 * If the item at the given zero-relative index in the receiver | |
570 * is selected, it is deselected. If the item at the index | |
571 * was not selected, it remains deselected. The range of the | |
572 * indices is inclusive. Indices that are out of range are ignored. | |
573 * | |
574 * @param start the start index of the items to deselect | |
575 * @param end the end index of the items to deselect | |
576 * | |
577 * @exception DWTException <ul> | |
578 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
579 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
580 * </ul> | |
581 */ | |
582 public void deselect (int start, int end) { | |
583 checkWidget(); | |
584 //TODO - check range | |
585 if (start is 0 && end is itemCount - 1) { | |
586 deselectAll (); | |
587 } else { | |
588 int length = end - start + 1; | |
589 NSTableView widget = (NSTableView)view; | |
590 ignoreSelect = true; | |
591 for (int i=0; i<length; i++) { | |
592 widget.deselectRow (i); | |
593 } | |
594 ignoreSelect = false; | |
595 } | |
596 } | |
597 | |
598 /** | |
599 * Deselects the items at the given zero-relative indices in the receiver. | |
600 * If the item at the given zero-relative index in the receiver | |
601 * is selected, it is deselected. If the item at the index | |
602 * was not selected, it remains deselected. Indices that are out | |
603 * of range and duplicate indices are ignored. | |
604 * | |
605 * @param indices the array of indices for the items to deselect | |
606 * | |
607 * @exception IllegalArgumentException <ul> | |
608 * <li>ERROR_NULL_ARGUMENT - if the set of indices 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 void deselect (int [] indices) { | |
616 checkWidget(); | |
617 if (indices is null) error (DWT.ERROR_NULL_ARGUMENT); | |
618 NSTableView widget = (NSTableView)view; | |
619 ignoreSelect = true; | |
620 for (int i=0; i<indices.length; i++) { | |
621 widget.deselectRow (indices [i]); | |
622 } | |
623 ignoreSelect = false; | |
624 } | |
625 | |
626 /** | |
627 * Deselects all selected items in the receiver. | |
628 * | |
629 * @exception DWTException <ul> | |
630 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
631 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
632 * </ul> | |
633 */ | |
634 public void deselectAll () { | |
635 checkWidget (); | |
636 NSTableView widget = (NSTableView)view; | |
637 ignoreSelect = true; | |
638 widget.deselectAll(null); | |
639 ignoreSelect = false; | |
640 } | |
641 | |
642 void destroyItem (TableColumn column) { | |
643 int index = 0; | |
644 while (index < columnCount) { | |
645 if (columns [index] is column) break; | |
646 index++; | |
647 } | |
648 for (int i=0; i<itemCount; i++) { | |
649 TableItem item = items [i]; | |
650 if (item !is null) { | |
651 if (columnCount <= 1) { | |
652 item.strings = null; | |
653 item.images = null; | |
654 item.cellBackground = null; | |
655 item.cellForeground = null; | |
656 item.cellFont = null; | |
657 } else { | |
658 if (item.strings !is null) { | |
659 String [] strings = item.strings; | |
660 if (index is 0) { | |
661 item.text = strings [1] !is null ? strings [1] : ""; | |
662 } | |
663 String [] temp = new String [columnCount - 1]; | |
664 System.arraycopy (strings, 0, temp, 0, index); | |
665 System.arraycopy (strings, index + 1, temp, index, columnCount - 1 - index); | |
666 item.strings = temp; | |
667 } else { | |
668 if (index is 0) item.text = ""; | |
669 } | |
670 if (item.images !is null) { | |
671 Image [] images = item.images; | |
672 if (index is 0) item.image = images [1]; | |
673 Image [] temp = new Image [columnCount - 1]; | |
674 System.arraycopy (images, 0, temp, 0, index); | |
675 System.arraycopy (images, index + 1, temp, index, columnCount - 1 - index); | |
676 item.images = temp; | |
677 } else { | |
678 if (index is 0) item.image = null; | |
679 } | |
680 if (item.cellBackground !is null) { | |
681 Color [] cellBackground = item.cellBackground; | |
682 Color [] temp = new Color [columnCount - 1]; | |
683 System.arraycopy (cellBackground, 0, temp, 0, index); | |
684 System.arraycopy (cellBackground, index + 1, temp, index, columnCount - 1 - index); | |
685 item.cellBackground = temp; | |
686 } | |
687 if (item.cellForeground !is null) { | |
688 Color [] cellForeground = item.cellForeground; | |
689 Color [] temp = new Color [columnCount - 1]; | |
690 System.arraycopy (cellForeground, 0, temp, 0, index); | |
691 System.arraycopy (cellForeground, index + 1, temp, index, columnCount - 1 - index); | |
692 item.cellForeground = temp; | |
693 } | |
694 if (item.cellFont !is null) { | |
695 Font [] cellFont = item.cellFont; | |
696 Font [] temp = new Font [columnCount - 1]; | |
697 System.arraycopy (cellFont, 0, temp, 0, index); | |
698 System.arraycopy (cellFont, index + 1, temp, index, columnCount - 1 - index); | |
699 item.cellFont = temp; | |
700 } | |
701 } | |
702 } | |
703 } | |
704 if (columnCount is 1) { | |
705 //TODO - reset attributes | |
706 firstColumn = column.nsColumn; | |
707 firstColumn.setWidth (0); | |
708 } else { | |
709 ((NSTableView)view).removeTableColumn(column.nsColumn); | |
710 } | |
711 System.arraycopy (columns, index + 1, columns, index, --columnCount - index); | |
712 columns [columnCount] = null; | |
713 for (int i=index; i<columnCount; i++) { | |
714 columns [i].sendEvent (DWT.Move); | |
715 } | |
716 } | |
717 | |
718 void destroyItem (TableItem item) { | |
719 int index = 0; | |
720 while (index < itemCount) { | |
721 if (items [index] is item) break; | |
722 index++; | |
723 } | |
724 if (index !is itemCount - 1) fixSelection (index, false); | |
725 System.arraycopy (items, index + 1, items, index, --itemCount - index); | |
726 items [itemCount] = null; | |
727 ((NSTableView)view).noteNumberOfRowsChanged(); | |
728 if (itemCount is 0) { | |
729 setTableEmpty (); | |
730 } else { | |
731 // fixScrollBar (); | |
732 } | |
733 } | |
734 | |
735 void fixSelection (int index, bool add) { | |
736 int [] selection = getSelectionIndices (); | |
737 if (selection.length is 0) return; | |
738 int newCount = 0; | |
739 bool fix = false; | |
740 for (int i = 0; i < selection.length; i++) { | |
741 if (!add && selection [i] is index) { | |
742 fix = true; | |
743 } else { | |
744 int newIndex = newCount++; | |
745 selection [newIndex] = selection [i] + 1; | |
746 if (selection [newIndex] - 1 >= index) { | |
747 selection [newIndex] += add ? 1 : -1; | |
748 fix = true; | |
749 } | |
750 } | |
751 } | |
752 if (fix) select (selection, newCount, true); | |
753 } | |
754 | |
755 int getCheckColumnWidth () { | |
756 return 20; //TODO - compute width | |
757 } | |
758 | |
759 /** | |
760 * Returns the column at the given, zero-relative index in the | |
761 * receiver. Throws an exception if the index is out of range. | |
762 * Columns are returned in the order that they were created. | |
763 * If no <code>TableColumn</code>s were created by the programmer, | |
764 * this method will throw <code>ERROR_INVALID_RANGE</code> despite | |
765 * the fact that a single column of data may be visible in the table. | |
766 * This occurs when the programmer uses the table like a list, adding | |
767 * items but never creating a column. | |
768 * | |
769 * @param index the index of the column to return | |
770 * @return the column at the given index | |
771 * | |
772 * @exception IllegalArgumentException <ul> | |
773 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li> | |
774 * </ul> | |
775 * @exception DWTException <ul> | |
776 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
777 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
778 * </ul> | |
779 * | |
780 * @see Table#getColumnOrder() | |
781 * @see Table#setColumnOrder(int[]) | |
782 * @see TableColumn#getMoveable() | |
783 * @see TableColumn#setMoveable(bool) | |
784 * @see DWT#Move | |
785 */ | |
786 public TableColumn getColumn (int index) { | |
787 checkWidget (); | |
788 if (!(0 <=index && index < columnCount)) error (DWT.ERROR_INVALID_RANGE); | |
789 return columns [index]; | |
790 } | |
791 | |
792 /** | |
793 * Returns the number of columns contained in the receiver. | |
794 * If no <code>TableColumn</code>s were created by the programmer, | |
795 * this value is zero, despite the fact that visually, one column | |
796 * of items may be visible. This occurs when the programmer uses | |
797 * the table like a list, adding items but never creating a column. | |
798 * | |
799 * @return the number of columns | |
800 * | |
801 * @exception DWTException <ul> | |
802 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
803 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
804 * </ul> | |
805 */ | |
806 public int getColumnCount () { | |
807 checkWidget (); | |
808 return columnCount; | |
809 } | |
810 | |
811 /** | |
812 * Returns an array of zero-relative integers that map | |
813 * the creation order of the receiver's items to the | |
814 * order in which they are currently being displayed. | |
815 * <p> | |
816 * Specifically, the indices of the returned array represent | |
817 * the current visual order of the items, and the contents | |
818 * of the array represent the creation order of the items. | |
819 * </p><p> | |
820 * Note: This is not the actual structure used by the receiver | |
821 * to maintain its list of items, so modifying the array will | |
822 * not affect the receiver. | |
823 * </p> | |
824 * | |
825 * @return the current visual order of the receiver's items | |
826 * | |
827 * @exception DWTException <ul> | |
828 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
829 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
830 * </ul> | |
831 * | |
832 * @see Table#setColumnOrder(int[]) | |
833 * @see TableColumn#getMoveable() | |
834 * @see TableColumn#setMoveable(bool) | |
835 * @see DWT#Move | |
836 * | |
837 * @since 3.1 | |
838 */ | |
839 public int [] getColumnOrder () { | |
840 checkWidget (); | |
841 int [] order = new int [columnCount]; | |
842 int [] position = new int [1]; | |
843 for (int i=0; i<columnCount; i++) { | |
844 TableColumn column = columns [i]; | |
845 // OS.GetDataBrowserTableViewColumnPosition (handle, column.id, position); | |
846 // if ((style & DWT.CHECK) !is 0) position [0] -= 1; | |
847 order [position [0]] = i; | |
848 } | |
849 return order; | |
850 } | |
851 | |
852 /** | |
853 * Returns an array of <code>TableColumn</code>s which are the | |
854 * columns in the receiver. Columns are returned in the order | |
855 * that they were created. If no <code>TableColumn</code>s were | |
856 * created by the programmer, the array is empty, despite the fact | |
857 * that visually, one column of items may be visible. This occurs | |
858 * when the programmer uses the table like a list, adding items but | |
859 * never creating a column. | |
860 * <p> | |
861 * Note: This is not the actual structure used by the receiver | |
862 * to maintain its list of items, so modifying the array will | |
863 * not affect the receiver. | |
864 * </p> | |
865 * | |
866 * @return the items in the receiver | |
867 * | |
868 * @exception DWTException <ul> | |
869 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
870 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
871 * </ul> | |
872 * | |
873 * @see Table#getColumnOrder() | |
874 * @see Table#setColumnOrder(int[]) | |
875 * @see TableColumn#getMoveable() | |
876 * @see TableColumn#setMoveable(bool) | |
877 * @see DWT#Move | |
878 */ | |
879 public TableColumn [] getColumns () { | |
880 checkWidget (); | |
881 TableColumn [] result = new TableColumn [columnCount]; | |
882 System.arraycopy (columns, 0, result, 0, columnCount); | |
883 return result; | |
884 } | |
885 | |
886 /** | |
887 * Returns the width in pixels of a grid line. | |
888 * | |
889 * @return the width of a grid line in pixels | |
890 * | |
891 * @exception DWTException <ul> | |
892 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
893 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
894 * </ul> | |
895 */ | |
896 public int getGridLineWidth () { | |
897 checkWidget (); | |
898 return 0; | |
899 } | |
900 | |
901 /** | |
902 * Returns the height of the receiver's header | |
903 * | |
904 * @return the height of the header or zero if the header is not visible | |
905 * | |
906 * @exception DWTException <ul> | |
907 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
908 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
909 * </ul> | |
910 * | |
911 * @since 2.0 | |
912 */ | |
913 public int getHeaderHeight () { | |
914 checkWidget (); | |
915 NSTableHeaderView headerView = ((NSTableView)view).headerView(); | |
916 if (headerView is null) return 0; | |
917 return (int)headerView.bounds().height; | |
918 } | |
919 | |
920 /** | |
921 * Returns <code>true</code> if the receiver's header is visible, | |
922 * and <code>false</code> otherwise. | |
923 * <p> | |
924 * If one of the receiver's ancestors is not visible or some | |
925 * other condition makes the receiver not visible, this method | |
926 * may still indicate that it is considered visible even though | |
927 * it may not actually be showing. | |
928 * </p> | |
929 * | |
930 * @return the receiver's header's visibility state | |
931 * | |
932 * @exception DWTException <ul> | |
933 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
934 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
935 * </ul> | |
936 */ | |
937 public bool getHeaderVisible () { | |
938 checkWidget (); | |
939 return ((NSTableView)view).headerView() !is null; | |
940 } | |
941 | |
942 int getInsetWidth () { | |
943 //TODO - wrong | |
944 return 20; | |
945 } | |
946 | |
947 /** | |
948 * Returns the item at the given, zero-relative index in the | |
949 * receiver. Throws an exception if the index is out of range. | |
950 * | |
951 * @param index the index of the item to return | |
952 * @return the item at the given index | |
953 * | |
954 * @exception IllegalArgumentException <ul> | |
955 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li> | |
956 * </ul> | |
957 * @exception DWTException <ul> | |
958 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
959 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
960 * </ul> | |
961 */ | |
962 public TableItem getItem (int index) { | |
963 checkWidget (); | |
964 if (!(0 <= index && index < itemCount)) error (DWT.ERROR_INVALID_RANGE); | |
965 return _getItem (index); | |
966 } | |
967 | |
968 /** | |
969 * Returns the item at the given point in the receiver | |
970 * or null if no such item exists. The point is in the | |
971 * coordinate system of the receiver. | |
972 * <p> | |
973 * The item that is returned represents an item that could be selected by the user. | |
974 * For example, if selection only occurs in items in the first column, then null is | |
975 * returned if the point is outside of the item. | |
976 * Note that the DWT.FULL_SELECTION style hint, which specifies the selection policy, | |
977 * determines the extent of the selection. | |
978 * </p> | |
979 * | |
980 * @param point the point used to locate the item | |
981 * @return the item at the given point, or null if the point is not in a selectable item | |
982 * | |
983 * @exception IllegalArgumentException <ul> | |
984 * <li>ERROR_NULL_ARGUMENT - if the point is null</li> | |
985 * </ul> | |
986 * @exception DWTException <ul> | |
987 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
988 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
989 * </ul> | |
990 */ | |
991 public TableItem getItem (Point point) { | |
992 checkWidget (); | |
993 // checkItems (true); | |
994 // if (point is null) error (DWT.ERROR_NULL_ARGUMENT); | |
995 // Rect rect = new Rect (); | |
996 // dwt.internal.carbon.Point pt = new dwt.internal.carbon.Point (); | |
997 // OS.SetPt (pt, (short) point.x, (short) point.y); | |
998 // if (0 < lastHittest && lastHittest <= itemCount && lastHittestColumn !is 0) { | |
999 // if (OS.GetDataBrowserItemPartBounds (handle, lastHittest, lastHittestColumn, OS.kDataBrowserPropertyEnclosingPart, rect) is OS.noErr) { | |
1000 // if (rect.top <= pt.v && pt.v <= rect.bottom) { | |
1001 // if ((style & DWT.FULL_SELECTION) !is 0) { | |
1002 // return _getItem (lastHittest - 1); | |
1003 // } else { | |
1004 // return OS.PtInRect (pt, rect) ? _getItem (lastHittest - 1) : null; | |
1005 // } | |
1006 // } | |
1007 // } | |
1008 // | |
1009 // } | |
1010 // int [] top = new int [1], left = new int [1]; | |
1011 // OS.GetDataBrowserScrollPosition(handle, top, left); | |
1012 // short [] height = new short [1]; | |
1013 // OS.GetDataBrowserTableViewRowHeight (handle, height); | |
1014 // short [] header = new short [1]; | |
1015 // OS.GetDataBrowserListViewHeaderBtnHeight (handle, header); | |
1016 // int [] offsets = new int [] {0, 1, -1}; | |
1017 // for (int i = 0; i < offsets.length; i++) { | |
1018 // int index = (top[0] - header [0] + point.y) / height [0] + offsets [i]; | |
1019 // if (0 <= index && index < itemCount) { | |
1020 // if (columnCount is 0) { | |
1021 // if (OS.GetDataBrowserItemPartBounds (handle, index + 1, column_id, OS.kDataBrowserPropertyEnclosingPart, rect) is OS.noErr) { | |
1022 // if (rect.top <= pt.v && pt.v <= rect.bottom) { | |
1023 // if ((style & DWT.FULL_SELECTION) !is 0) { | |
1024 // return _getItem (index); | |
1025 // } else { | |
1026 // return OS.PtInRect (pt, rect) ? _getItem (index) : null; | |
1027 // } | |
1028 // } | |
1029 // } | |
1030 // } else { | |
1031 // for (int j = 0; j < columnCount; j++) { | |
1032 // if (OS.GetDataBrowserItemPartBounds (handle, index + 1, columns [j].id, OS.kDataBrowserPropertyEnclosingPart, rect) is OS.noErr) { | |
1033 // if (rect.top <= pt.v && pt.v <= rect.bottom) { | |
1034 // if ((style & DWT.FULL_SELECTION) !is 0) { | |
1035 // return _getItem (index); | |
1036 // } else { | |
1037 // return OS.PtInRect (pt, rect) ? _getItem (index) : null; | |
1038 // } | |
1039 // } | |
1040 // } | |
1041 // } | |
1042 // } | |
1043 // } | |
1044 // } | |
1045 // //TODO - optimize | |
1046 // for (int i=0; i<itemCount; i++) { | |
1047 // if (columnCount is 0) { | |
1048 // if (OS.GetDataBrowserItemPartBounds (handle, i + 1, column_id, OS.kDataBrowserPropertyEnclosingPart, rect) is OS.noErr) { | |
1049 // if (rect.top <= pt.v && pt.v <= rect.bottom) { | |
1050 // if ((style & DWT.FULL_SELECTION) !is 0) { | |
1051 // return _getItem (i); | |
1052 // } else { | |
1053 // return OS.PtInRect (pt, rect) ? _getItem (i) : null; | |
1054 // } | |
1055 // } | |
1056 // } | |
1057 // } else { | |
1058 // for (int j = 0; j < columnCount; j++) { | |
1059 // if (OS.GetDataBrowserItemPartBounds (handle, i + 1, columns [j].id, OS.kDataBrowserPropertyEnclosingPart, rect) is OS.noErr) { | |
1060 // if (rect.top <= pt.v && pt.v <= rect.bottom) { | |
1061 // if ((style & DWT.FULL_SELECTION) !is 0) { | |
1062 // return _getItem (i); | |
1063 // } else { | |
1064 // return OS.PtInRect (pt, rect) ? _getItem (i) : null; | |
1065 // } | |
1066 // } | |
1067 // } | |
1068 // } | |
1069 // } | |
1070 // } | |
1071 return null; | |
1072 } | |
1073 | |
1074 /** | |
1075 * Returns the number of items contained in the receiver. | |
1076 * | |
1077 * @return the number of items | |
1078 * | |
1079 * @exception DWTException <ul> | |
1080 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1081 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1082 * </ul> | |
1083 */ | |
1084 public int getItemCount () { | |
1085 checkWidget (); | |
1086 return itemCount; | |
1087 } | |
1088 | |
1089 /** | |
1090 * Returns the height of the area which would be used to | |
1091 * display <em>one</em> of the items in the receiver's. | |
1092 * | |
1093 * @return the height of one item | |
1094 * | |
1095 * @exception DWTException <ul> | |
1096 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1097 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1098 * </ul> | |
1099 */ | |
1100 public int getItemHeight () { | |
1101 checkWidget (); | |
1102 return (int)((NSTableView)view).rowHeight(); | |
1103 } | |
1104 | |
1105 /** | |
1106 * Returns a (possibly empty) array of <code>TableItem</code>s which | |
1107 * are the items in the receiver. | |
1108 * <p> | |
1109 * Note: This is not the actual structure used by the receiver | |
1110 * to maintain its list of items, so modifying the array will | |
1111 * not affect the receiver. | |
1112 * </p> | |
1113 * | |
1114 * @return the items in the receiver | |
1115 * | |
1116 * @exception DWTException <ul> | |
1117 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1118 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1119 * </ul> | |
1120 */ | |
1121 public TableItem [] getItems () { | |
1122 checkWidget (); | |
1123 TableItem [] result = new TableItem [itemCount]; | |
1124 if ((style & DWT.VIRTUAL) !is 0) { | |
1125 for (int i=0; i<itemCount; i++) { | |
1126 result [i] = _getItem (i); | |
1127 } | |
1128 } else { | |
1129 System.arraycopy (items, 0, result, 0, itemCount); | |
1130 } | |
1131 return result; | |
1132 } | |
1133 | |
1134 /** | |
1135 * Returns <code>true</code> if the receiver's lines are visible, | |
1136 * and <code>false</code> otherwise. | |
1137 * <p> | |
1138 * If one of the receiver's ancestors is not visible or some | |
1139 * other condition makes the receiver not visible, this method | |
1140 * may still indicate that it is considered visible even though | |
1141 * it may not actually be showing. | |
1142 * </p> | |
1143 * | |
1144 * @return the visibility state of the lines | |
1145 * | |
1146 * @exception DWTException <ul> | |
1147 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1148 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1149 * </ul> | |
1150 */ | |
1151 public bool getLinesVisible () { | |
1152 checkWidget (); | |
1153 // if (OS.VERSION >= 0x1040) { | |
1154 // int [] attrib = new int [1]; | |
1155 // OS.DataBrowserGetAttributes (handle, attrib); | |
1156 // return (attrib [0] & (OS.kDataBrowserAttributeListViewAlternatingRowColors | OS.kDataBrowserAttributeListViewDrawColumnDividers)) !is 0; | |
1157 // } | |
1158 return false; | |
1159 } | |
1160 | |
1161 /** | |
1162 * Returns an array of <code>TableItem</code>s that are currently | |
1163 * selected in the receiver. The order of the items is unspecified. | |
1164 * An empty array indicates that no items are selected. | |
1165 * <p> | |
1166 * Note: This is not the actual structure used by the receiver | |
1167 * to maintain its selection, so modifying the array will | |
1168 * not affect the receiver. | |
1169 * </p> | |
1170 * @return an array representing the selection | |
1171 * | |
1172 * @exception DWTException <ul> | |
1173 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1174 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1175 * </ul> | |
1176 */ | |
1177 public TableItem [] getSelection () { | |
1178 checkWidget (); | |
1179 NSTableView widget = (NSTableView)view; | |
1180 if (widget.numberOfSelectedRows() is 0) { | |
1181 return new TableItem [0]; | |
1182 } | |
1183 NSIndexSet selection = widget.selectedRowIndexes(); | |
1184 int count = selection.count(); | |
1185 int [] indexBuffer = new int [count]; | |
1186 selection.getIndexes(indexBuffer, count, 0); | |
1187 TableItem [] result = new TableItem [count]; | |
1188 for (int i=0; i<count; i++) { | |
1189 result [i] = _getItem (indexBuffer [i]); | |
1190 } | |
1191 return result; | |
1192 } | |
1193 | |
1194 /** | |
1195 * Returns the number of selected items contained in the receiver. | |
1196 * | |
1197 * @return the number of selected items | |
1198 * | |
1199 * @exception DWTException <ul> | |
1200 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1201 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1202 * </ul> | |
1203 */ | |
1204 public int getSelectionCount () { | |
1205 checkWidget (); | |
1206 return ((NSTableView)view).numberOfSelectedRows(); | |
1207 } | |
1208 | |
1209 /** | |
1210 * Returns the zero-relative index of the item which is currently | |
1211 * selected in the receiver, or -1 if no item is selected. | |
1212 * | |
1213 * @return the index of the selected item | |
1214 * | |
1215 * @exception DWTException <ul> | |
1216 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1217 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1218 * </ul> | |
1219 */ | |
1220 public int getSelectionIndex () { | |
1221 checkWidget(); | |
1222 //TODO - check empty selection case | |
1223 return ((NSTableView)view).selectedRow(); | |
1224 } | |
1225 | |
1226 /** | |
1227 * Returns the zero-relative indices of the items which are currently | |
1228 * selected in the receiver. The order of the indices is unspecified. | |
1229 * The array is empty if no items are selected. | |
1230 * <p> | |
1231 * Note: This is not the actual structure used by the receiver | |
1232 * to maintain its selection, so modifying the array will | |
1233 * not affect the receiver. | |
1234 * </p> | |
1235 * @return the array of indices of the selected items | |
1236 * | |
1237 * @exception DWTException <ul> | |
1238 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1239 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1240 * </ul> | |
1241 */ | |
1242 public int [] getSelectionIndices () { | |
1243 checkWidget (); | |
1244 NSTableView widget = (NSTableView)view; | |
1245 if (widget.numberOfSelectedRows() is 0) { | |
1246 return new int [0]; | |
1247 } | |
1248 NSIndexSet selection = widget.selectedRowIndexes(); | |
1249 int count = selection.count(); | |
1250 int [] result = new int [count]; | |
1251 selection.getIndexes(result, count, 0); | |
1252 return result; | |
1253 } | |
1254 | |
1255 /** | |
1256 * Returns the column which shows the sort indicator for | |
1257 * the receiver. The value may be null if no column shows | |
1258 * the sort indicator. | |
1259 * | |
1260 * @return the sort indicator | |
1261 * | |
1262 * @exception DWTException <ul> | |
1263 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1264 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1265 * </ul> | |
1266 * | |
1267 * @see #setSortColumn(TableColumn) | |
1268 * | |
1269 * @since 3.2 | |
1270 */ | |
1271 public TableColumn getSortColumn () { | |
1272 checkWidget (); | |
1273 return sortColumn; | |
1274 } | |
1275 | |
1276 /** | |
1277 * Returns the direction of the sort indicator for the receiver. | |
1278 * The value will be one of <code>UP</code>, <code>DOWN</code> | |
1279 * or <code>NONE</code>. | |
1280 * | |
1281 * @return the sort direction | |
1282 * | |
1283 * @exception DWTException <ul> | |
1284 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1285 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1286 * </ul> | |
1287 * | |
1288 * @see #setSortDirection(int) | |
1289 * | |
1290 * @since 3.2 | |
1291 */ | |
1292 public int getSortDirection () { | |
1293 checkWidget (); | |
1294 return sortDirection; | |
1295 } | |
1296 | |
1297 /** | |
1298 * Returns the zero-relative index of the item which is currently | |
1299 * at the top of the receiver. This index can change when items are | |
1300 * scrolled or new items are added or removed. | |
1301 * | |
1302 * @return the index of the top item | |
1303 * | |
1304 * @exception DWTException <ul> | |
1305 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1306 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1307 * </ul> | |
1308 */ | |
1309 public int getTopIndex () { | |
1310 checkWidget(); | |
1311 //TODO - partial item at the top | |
1312 NSRect rect = scrollView.documentVisibleRect(); | |
1313 NSPoint point = new NSPoint(); | |
1314 point.x = rect.x; | |
1315 point.y = rect.y; | |
1316 return ((NSTableView)view).rowAtPoint(point); | |
1317 } | |
1318 | |
1319 | |
1320 /** | |
1321 * Searches the receiver's list starting at the first column | |
1322 * (index 0) until a column is found that is equal to the | |
1323 * argument, and returns the index of that column. If no column | |
1324 * is found, returns -1. | |
1325 * | |
1326 * @param column the search column | |
1327 * @return the index of the column | |
1328 * | |
1329 * @exception IllegalArgumentException <ul> | |
1330 * <li>ERROR_NULL_ARGUMENT - if the column is null</li> | |
1331 * </ul> | |
1332 * @exception DWTException <ul> | |
1333 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1334 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1335 * </ul> | |
1336 */ | |
1337 public int indexOf (TableColumn column) { | |
1338 checkWidget (); | |
1339 if (column is null) error (DWT.ERROR_NULL_ARGUMENT); | |
1340 for (int i=0; i<columnCount; i++) { | |
1341 if (columns [i] is column) return i; | |
1342 } | |
1343 return -1; | |
1344 } | |
1345 | |
1346 /** | |
1347 * Searches the receiver's list starting at the first item | |
1348 * (index 0) until an item is found that is equal to the | |
1349 * argument, and returns the index of that item. If no item | |
1350 * is found, returns -1. | |
1351 * | |
1352 * @param item the search item | |
1353 * @return the index of the item | |
1354 * | |
1355 * @exception IllegalArgumentException <ul> | |
1356 * <li>ERROR_NULL_ARGUMENT - if the item is null</li> | |
1357 * </ul> | |
1358 * @exception DWTException <ul> | |
1359 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1360 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1361 * </ul> | |
1362 */ | |
1363 public int indexOf (TableItem item) { | |
1364 checkWidget (); | |
1365 if (item is null) error (DWT.ERROR_NULL_ARGUMENT); | |
1366 if (1 <= lastIndexOf && lastIndexOf < itemCount - 1) { | |
1367 if (items [lastIndexOf] is item) return lastIndexOf; | |
1368 if (items [lastIndexOf + 1] is item) return ++lastIndexOf; | |
1369 if (items [lastIndexOf - 1] is item) return --lastIndexOf; | |
1370 } | |
1371 if (lastIndexOf < itemCount / 2) { | |
1372 for (int i=0; i<itemCount; i++) { | |
1373 if (items [i] is item) return lastIndexOf = i; | |
1374 } | |
1375 } else { | |
1376 for (int i=itemCount - 1; i>=0; --i) { | |
1377 if (items [i] is item) return lastIndexOf = i; | |
1378 } | |
1379 } | |
1380 return -1; | |
1381 } | |
1382 | |
1383 /** | |
1384 * Returns <code>true</code> if the item is selected, | |
1385 * and <code>false</code> otherwise. Indices out of | |
1386 * range are ignored. | |
1387 * | |
1388 * @param index the index of the item | |
1389 * @return the selection state of the item at the index | |
1390 * | |
1391 * @exception DWTException <ul> | |
1392 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1393 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1394 * </ul> | |
1395 */ | |
1396 public bool isSelected (int index) { | |
1397 checkWidget(); | |
1398 //TODO - range check | |
1399 return ((NSTableView)view).isRowSelected(index); | |
1400 } | |
1401 | |
1402 int numberOfRowsInTableView(int aTableView) { | |
1403 return itemCount; | |
1404 } | |
1405 | |
1406 void releaseChildren (bool destroy) { | |
1407 if (items !is null) { | |
1408 for (int i=0; i<itemCount; i++) { | |
1409 TableItem item = items [i]; | |
1410 if (item !is null && !item.isDisposed ()) { | |
1411 item.release (false); | |
1412 } | |
1413 } | |
1414 items = null; | |
1415 } | |
1416 if (columns !is null) { | |
1417 for (int i=0; i<columnCount; i++) { | |
1418 TableColumn column = columns [i]; | |
1419 if (column !is null && !column.isDisposed ()) { | |
1420 column.release (false); | |
1421 } | |
1422 } | |
1423 columns = null; | |
1424 } | |
1425 super.releaseChildren (destroy); | |
1426 } | |
1427 | |
1428 void releaseHandle () { | |
1429 super.releaseHandle (); | |
1430 if (headerView !is null) headerView.release(); | |
1431 headerView = null; | |
1432 if (firstColumn !is null) firstColumn.release(); | |
1433 firstColumn = null; | |
1434 if (checkColumn !is null) checkColumn.release(); | |
1435 checkColumn = null; | |
1436 } | |
1437 | |
1438 void releaseWidget () { | |
1439 super.releaseWidget (); | |
1440 currentItem = null; | |
1441 sortColumn = null; | |
1442 } | |
1443 | |
1444 /** | |
1445 * Removes the item from the receiver at the given | |
1446 * zero-relative index. | |
1447 * | |
1448 * @param index the index for the item | |
1449 * | |
1450 * @exception IllegalArgumentException <ul> | |
1451 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li> | |
1452 * </ul> | |
1453 * @exception DWTException <ul> | |
1454 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1455 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1456 * </ul> | |
1457 */ | |
1458 public void remove (int index) { | |
1459 checkWidget(); | |
1460 if (!(0 <= index && index < itemCount)) error (DWT.ERROR_INVALID_RANGE); | |
1461 TableItem item = items [index]; | |
1462 if (item !is null) item.release (false); | |
1463 if (index !is itemCount - 1) fixSelection (index, false); | |
1464 System.arraycopy (items, index + 1, items, index, --itemCount - index); | |
1465 items [itemCount] = null; | |
1466 ((NSTableView)view).noteNumberOfRowsChanged(); | |
1467 if (itemCount is 0) { | |
1468 setTableEmpty (); | |
1469 } else { | |
1470 // fixScrollBar (); | |
1471 } | |
1472 } | |
1473 | |
1474 /** | |
1475 * Removes the items from the receiver which are | |
1476 * between the given zero-relative start and end | |
1477 * indices (inclusive). | |
1478 * | |
1479 * @param start the start of the range | |
1480 * @param end the end of the range | |
1481 * | |
1482 * @exception IllegalArgumentException <ul> | |
1483 * <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> | |
1484 * </ul> | |
1485 * @exception DWTException <ul> | |
1486 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1487 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1488 * </ul> | |
1489 */ | |
1490 public void remove (int start, int end) { | |
1491 checkWidget(); | |
1492 if (start > end) return; | |
1493 if (!(0 <= start && start <= end && end < itemCount)) { | |
1494 error (DWT.ERROR_INVALID_RANGE); | |
1495 } | |
1496 if (start is 0 && end is itemCount - 1) { | |
1497 removeAll (); | |
1498 } else { | |
1499 int length = end - start + 1; | |
1500 for (int i=0; i<length; i++) remove (start); | |
1501 } | |
1502 } | |
1503 | |
1504 /** | |
1505 * Removes the items from the receiver's list at the given | |
1506 * zero-relative indices. | |
1507 * | |
1508 * @param indices the array of indices of the items | |
1509 * | |
1510 * @exception IllegalArgumentException <ul> | |
1511 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li> | |
1512 * <li>ERROR_NULL_ARGUMENT - if the indices array is null</li> | |
1513 * </ul> | |
1514 * @exception DWTException <ul> | |
1515 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1516 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1517 * </ul> | |
1518 */ | |
1519 public void remove (int [] indices) { | |
1520 checkWidget (); | |
1521 if (indices is null) error (DWT.ERROR_NULL_ARGUMENT); | |
1522 if (indices.length is 0) return; | |
1523 int [] newIndices = new int [indices.length]; | |
1524 System.arraycopy (indices, 0, newIndices, 0, indices.length); | |
1525 sort (newIndices); | |
1526 int start = newIndices [newIndices.length - 1], end = newIndices [0]; | |
1527 if (!(0 <= start && start <= end && end < itemCount)) { | |
1528 error (DWT.ERROR_INVALID_RANGE); | |
1529 } | |
1530 int last = -1; | |
1531 for (int i=0; i<newIndices.length; i++) { | |
1532 int index = newIndices [i]; | |
1533 if (index !is last) { | |
1534 remove (index); | |
1535 last = index; | |
1536 } | |
1537 } | |
1538 } | |
1539 | |
1540 /** | |
1541 * Removes all of the items from the receiver. | |
1542 * | |
1543 * @exception DWTException <ul> | |
1544 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1545 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1546 * </ul> | |
1547 */ | |
1548 public void removeAll () { | |
1549 checkWidget(); | |
1550 for (int i=0; i<itemCount; i++) { | |
1551 TableItem item = items [i]; | |
1552 if (item !is null && !item.isDisposed ()) item.release (false); | |
1553 } | |
1554 setTableEmpty (); | |
1555 ((NSTableView)view).noteNumberOfRowsChanged(); | |
1556 } | |
1557 | |
1558 /** | |
1559 * Removes the listener from the collection of listeners who will | |
1560 * be notified when the user changes the receiver's selection. | |
1561 * | |
1562 * @param listener the listener which should no longer be notified | |
1563 * | |
1564 * @exception IllegalArgumentException <ul> | |
1565 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
1566 * </ul> | |
1567 * @exception DWTException <ul> | |
1568 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1569 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1570 * </ul> | |
1571 * | |
1572 * @see SelectionListener | |
1573 * @see #addSelectionListener(SelectionListener) | |
1574 */ | |
1575 public void removeSelectionListener(SelectionListener listener) { | |
1576 checkWidget (); | |
1577 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
1578 if (eventTable is null) return; | |
1579 eventTable.unhook (DWT.Selection, listener); | |
1580 eventTable.unhook (DWT.DefaultSelection,listener); | |
1581 } | |
1582 | |
1583 /** | |
1584 * Selects the item at the given zero-relative index in the receiver. | |
1585 * If the item at the index was already selected, it remains | |
1586 * selected. Indices that are out of range are ignored. | |
1587 * | |
1588 * @param index the index of the item to select | |
1589 * | |
1590 * @exception DWTException <ul> | |
1591 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1592 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1593 * </ul> | |
1594 */ | |
1595 public void select (int index) { | |
1596 checkWidget(); | |
1597 if (0 <= index && index < itemCount) { | |
1598 NSIndexSet indexes = (NSIndexSet)new NSIndexSet().alloc(); | |
1599 indexes.initWithIndex(index); | |
1600 NSTableView widget = (NSTableView)view; | |
1601 ignoreSelect = true; | |
1602 ((NSTableView)view).selectRowIndexes(indexes, true); | |
1603 ignoreSelect = false; | |
1604 } | |
1605 } | |
1606 | |
1607 /** | |
1608 * Selects the items in the range specified by the given zero-relative | |
1609 * indices in the receiver. The range of indices is inclusive. | |
1610 * The current selection is not cleared before the new items are selected. | |
1611 * <p> | |
1612 * If an item in the given range is not selected, it is selected. | |
1613 * If an item in the given range was already selected, it remains selected. | |
1614 * Indices that are out of range are ignored and no items will be selected | |
1615 * if start is greater than end. | |
1616 * If the receiver is single-select and there is more than one item in the | |
1617 * given range, then all indices are ignored. | |
1618 * </p> | |
1619 * | |
1620 * @param start the start of the range | |
1621 * @param end the end of the range | |
1622 * | |
1623 * @exception DWTException <ul> | |
1624 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1625 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1626 * </ul> | |
1627 * | |
1628 * @see Table#setSelection(int,int) | |
1629 */ | |
1630 public void select (int start, int end) { | |
1631 checkWidget (); | |
1632 if (end < 0 || start > end || ((style & DWT.SINGLE) !is 0 && start !is end)) return; | |
1633 if (itemCount is 0 || start >= itemCount) return; | |
1634 if (start is 0 && end is itemCount - 1) { | |
1635 selectAll (); | |
1636 } else { | |
1637 start = Math.max (0, start); | |
1638 end = Math.min (end, itemCount - 1); | |
1639 int length = end - start + 1; | |
1640 NSIndexSet indexes = (NSIndexSet)new NSIndexSet().alloc(); | |
1641 NSRange range = new NSRange(); | |
1642 range.location = start; | |
1643 range.length = length; | |
1644 indexes.initWithIndexesInRange(range); | |
1645 NSTableView widget = (NSTableView)view; | |
1646 ignoreSelect = true; | |
1647 widget.selectRowIndexes(indexes, true); | |
1648 ignoreSelect = false; | |
1649 } | |
1650 } | |
1651 | |
1652 /** | |
1653 * Selects the items at the given zero-relative indices in the receiver. | |
1654 * The current selection is not cleared before the new items are selected. | |
1655 * <p> | |
1656 * If the item at a given index is not selected, it is selected. | |
1657 * If the item at a given index was already selected, it remains selected. | |
1658 * Indices that are out of range and duplicate indices are ignored. | |
1659 * If the receiver is single-select and multiple indices are specified, | |
1660 * then all indices are ignored. | |
1661 * </p> | |
1662 * | |
1663 * @param indices the array of indices for the items to select | |
1664 * | |
1665 * @exception IllegalArgumentException <ul> | |
1666 * <li>ERROR_NULL_ARGUMENT - if the array of indices is null</li> | |
1667 * </ul> | |
1668 * @exception DWTException <ul> | |
1669 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1670 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1671 * </ul> | |
1672 * | |
1673 * @see Table#setSelection(int[]) | |
1674 */ | |
1675 public void select (int [] indices) { | |
1676 checkWidget (); | |
1677 if (indices is null) error (DWT.ERROR_NULL_ARGUMENT); | |
1678 int length = indices.length; | |
1679 if (length is 0 || ((style & DWT.SINGLE) !is 0 && length > 1)) return; | |
1680 int count = 0; | |
1681 NSMutableIndexSet indexes = (NSMutableIndexSet)new NSMutableIndexSet().alloc().init(); | |
1682 for (int i=0; i<length; i++) { | |
1683 int index = indices [length - i - 1]; | |
1684 if (index >= 0 && index < itemCount) { | |
1685 indexes.addIndex (indices [i]); | |
1686 count++; | |
1687 } | |
1688 } | |
1689 if (count > 0) { | |
1690 NSTableView widget = (NSTableView)view; | |
1691 ignoreSelect = true; | |
1692 widget.selectRowIndexes(indexes, true); | |
1693 ignoreSelect = false; | |
1694 } | |
1695 } | |
1696 | |
1697 void select (int [] ids, int count, bool clear) { | |
1698 NSMutableIndexSet indexes = (NSMutableIndexSet)new NSMutableIndexSet().alloc().init(); | |
1699 for (int i=0; i<count; i++) indexes.addIndex (ids [i] - 1); //WRONG -1 | |
1700 NSTableView widget = (NSTableView)view; | |
1701 ignoreSelect = true; | |
1702 widget.selectRowIndexes(indexes, !clear); | |
1703 ignoreSelect = false; | |
1704 } | |
1705 | |
1706 /** | |
1707 * Selects all of the items in the receiver. | |
1708 * <p> | |
1709 * If the receiver is single-select, do nothing. | |
1710 * </p> | |
1711 * | |
1712 * @exception DWTException <ul> | |
1713 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1714 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1715 * </ul> | |
1716 */ | |
1717 public void selectAll () { | |
1718 checkWidget (); | |
1719 if ((style & DWT.SINGLE) !is 0) return; | |
1720 NSTableView widget = (NSTableView)view; | |
1721 ignoreSelect = true; | |
1722 widget.selectAll(null); | |
1723 ignoreSelect = false; | |
1724 } | |
1725 | |
1726 /** | |
1727 * Sets the order that the items in the receiver should | |
1728 * be displayed in to the given argument which is described | |
1729 * in terms of the zero-relative ordering of when the items | |
1730 * were added. | |
1731 * | |
1732 * @param order the new order to display the items | |
1733 * | |
1734 * @exception DWTException <ul> | |
1735 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1736 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1737 * </ul> | |
1738 * @exception IllegalArgumentException <ul> | |
1739 * <li>ERROR_NULL_ARGUMENT - if the item order is null</li> | |
1740 * <li>ERROR_INVALID_ARGUMENT - if the item order is not the same length as the number of items</li> | |
1741 * </ul> | |
1742 * | |
1743 * @see Table#getColumnOrder() | |
1744 * @see TableColumn#getMoveable() | |
1745 * @see TableColumn#setMoveable(bool) | |
1746 * @see DWT#Move | |
1747 * | |
1748 * @since 3.1 | |
1749 */ | |
1750 public void setColumnOrder (int [] order) { | |
1751 checkWidget (); | |
1752 if (order is null) error (DWT.ERROR_NULL_ARGUMENT); | |
1753 if (columnCount is 0) { | |
1754 if (order.length !is 0) error (DWT.ERROR_INVALID_ARGUMENT); | |
1755 return; | |
1756 } | |
1757 if (order.length !is columnCount) error (DWT.ERROR_INVALID_ARGUMENT); | |
1758 int [] oldOrder = getColumnOrder (); | |
1759 bool reorder = false; | |
1760 bool [] seen = new bool [columnCount]; | |
1761 for (int i=0; i<order.length; i++) { | |
1762 int index = order [i]; | |
1763 if (index < 0 || index >= columnCount) error (DWT.ERROR_INVALID_ARGUMENT); | |
1764 if (seen [index]) error (DWT.ERROR_INVALID_ARGUMENT); | |
1765 seen [index] = true; | |
1766 if (order [i] !is oldOrder [i]) reorder = true; | |
1767 } | |
1768 if (reorder) { | |
1769 int x = 0; | |
1770 short [] width = new short [1]; | |
1771 int [] oldX = new int [oldOrder.length]; | |
1772 for (int i=0; i<oldOrder.length; i++) { | |
1773 int index = oldOrder [i]; | |
1774 TableColumn column = columns [index]; | |
1775 oldX [index] = x; | |
1776 // OS.GetDataBrowserTableViewNamedColumnWidth(handle, column.id, width); | |
1777 x += width [0]; | |
1778 } | |
1779 x = 0; | |
1780 int [] newX = new int [order.length]; | |
1781 for (int i=0; i<order.length; i++) { | |
1782 int index = order [i]; | |
1783 TableColumn column = columns [index]; | |
1784 int position = (style & DWT.CHECK) !is 0 ? i + 1 : i; | |
1785 // OS.SetDataBrowserTableViewColumnPosition(handle, column.id, position); | |
1786 // column.lastPosition = position; | |
1787 newX [index] = x; | |
1788 // OS.GetDataBrowserTableViewNamedColumnWidth(handle, column.id, width); | |
1789 x += width [0]; | |
1790 } | |
1791 TableColumn[] newColumns = new TableColumn [columnCount]; | |
1792 System.arraycopy (columns, 0, newColumns, 0, columnCount); | |
1793 for (int i=0; i<columnCount; i++) { | |
1794 TableColumn column = newColumns [i]; | |
1795 if (!column.isDisposed ()) { | |
1796 if (newX [i] !is oldX [i]) { | |
1797 column.sendEvent (DWT.Move); | |
1798 } | |
1799 } | |
1800 } | |
1801 } | |
1802 } | |
1803 | |
1804 /** | |
1805 * Marks the receiver's header as visible if the argument is <code>true</code>, | |
1806 * and marks it invisible otherwise. | |
1807 * <p> | |
1808 * If one of the receiver's ancestors is not visible or some | |
1809 * other condition makes the receiver not visible, marking | |
1810 * it visible may not actually cause it to be displayed. | |
1811 * </p> | |
1812 * | |
1813 * @param show the new visibility state | |
1814 * | |
1815 * @exception DWTException <ul> | |
1816 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1817 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1818 * </ul> | |
1819 */ | |
1820 public void setHeaderVisible (bool show) { | |
1821 checkWidget (); | |
1822 ((NSTableView)view).setHeaderView (show ? headerView : null); | |
1823 } | |
1824 | |
1825 /** | |
1826 * Sets the number of items contained in the receiver. | |
1827 * | |
1828 * @param count the number of items | |
1829 * | |
1830 * @exception DWTException <ul> | |
1831 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1832 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1833 * </ul> | |
1834 * | |
1835 * @since 3.0 | |
1836 */ | |
1837 public void setItemCount (int count) { | |
1838 checkWidget (); | |
1839 // checkItems (true); | |
1840 // count = Math.max (0, count); | |
1841 // if (count is itemCount) return; | |
1842 // setRedraw (false); | |
1843 // int[] top = new int [1], left = new int [1]; | |
1844 // OS.GetDataBrowserScrollPosition (handle, top, left); | |
1845 // DataBrowserCallbacks callbacks = new DataBrowserCallbacks (); | |
1846 // OS.GetDataBrowserCallbacks (handle, callbacks); | |
1847 // callbacks.v1_itemNotificationCallback = 0; | |
1848 // callbacks.v1_itemCompareCallback = 0; | |
1849 // OS.SetDataBrowserCallbacks (handle, callbacks); | |
1850 // if (count < itemCount) { | |
1851 // int index = count; | |
1852 // int[] id = new int [itemCount - count]; | |
1853 // while (index < itemCount) { | |
1854 // TableItem item = items [index]; | |
1855 // if (item !is null) item.release (false); | |
1856 // id [index-count] = index + 1; | |
1857 // index++; | |
1858 // } | |
1859 // OS.RemoveDataBrowserItems (handle, OS.kDataBrowserNoItem, id.length, id, 0); | |
1860 // int [] newItemCount = new int [1]; | |
1861 // if (OS.GetDataBrowserItemCount (handle, OS.kDataBrowserNoItem, true, OS.kDataBrowserItemAnyState, newItemCount) !is OS.noErr) { | |
1862 // error (DWT.ERROR_CANNOT_GET_COUNT); | |
1863 // } | |
1864 // if (count !is newItemCount[0]) error (DWT.ERROR_ITEM_NOT_REMOVED); | |
1865 // } | |
1866 // int length = Math.max (4, (count + 3) / 4 * 4); | |
1867 // TableItem [] newItems = new TableItem [length]; | |
1868 // System.arraycopy (items, 0, newItems, 0, Math.min (count, itemCount)); | |
1869 // items = newItems; | |
1870 // if ((style & DWT.VIRTUAL) is 0) { | |
1871 // for (int i=itemCount; i<count; i++) { | |
1872 // items [i] = new TableItem (this, DWT.NONE, i, false); | |
1873 // } | |
1874 // } | |
1875 // itemCount = count; | |
1876 // OS.AddDataBrowserItems (handle, 0, itemCount, null, OS.kDataBrowserItemNoProperty); | |
1877 // callbacks.v1_itemNotificationCallback = display.itemNotificationProc; | |
1878 // callbacks.v1_itemCompareCallback = itemCompareProc (); | |
1879 // OS.SetDataBrowserCallbacks (handle, callbacks); | |
1880 // fixScrollBar (); | |
1881 // setRedraw (true); | |
1882 } | |
1883 | |
1884 /*public*/ void setItemHeight (int itemHeight) { | |
1885 checkWidget (); | |
1886 if (itemHeight < -1) error (DWT.ERROR_INVALID_ARGUMENT); | |
1887 if (itemHeight is -1) { | |
1888 //TODO - reset item height, ensure other API's such as setFont don't do this | |
1889 } else { | |
1890 // OS.SetDataBrowserTableViewRowHeight (handle, (short) itemHeight); | |
1891 } | |
1892 } | |
1893 | |
1894 /** | |
1895 * Marks the receiver's lines as visible if the argument is <code>true</code>, | |
1896 * and marks it invisible otherwise. | |
1897 * <p> | |
1898 * If one of the receiver's ancestors is not visible or some | |
1899 * other condition makes the receiver not visible, marking | |
1900 * it visible may not actually cause it to be displayed. | |
1901 * </p> | |
1902 * | |
1903 * @param show the new visibility state | |
1904 * | |
1905 * @exception DWTException <ul> | |
1906 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1907 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1908 * </ul> | |
1909 */ | |
1910 public void setLinesVisible (bool show) { | |
1911 checkWidget (); | |
1912 ((NSTableView)view).setUsesAlternatingRowBackgroundColors(show); | |
1913 } | |
1914 | |
1915 bool setScrollWidth (TableItem item) { | |
1916 if (columnCount !is 0) return false; | |
1917 if (currentItem !is null) { | |
1918 // if (currentItem !is item) fixScrollWidth = true; | |
1919 return false; | |
1920 } | |
1921 if (drawCount !is 0) return false; | |
1922 GC gc = new GC (this); | |
1923 int newWidth = item.calculateWidth (0, gc); | |
1924 gc.dispose (); | |
1925 newWidth += getInsetWidth (); | |
1926 // short [] width = new short [1]; | |
1927 // OS.GetDataBrowserTableViewNamedColumnWidth (handle, column_id, width); | |
1928 // if (width [0] < newWidth) { | |
1929 // OS.SetDataBrowserTableViewNamedColumnWidth (handle, column_id, (short) newWidth); | |
1930 // return true; | |
1931 // } | |
1932 if (firstColumn.width() < newWidth) { | |
1933 firstColumn.setWidth (newWidth); | |
1934 } | |
1935 return false; | |
1936 } | |
1937 | |
1938 bool setScrollWidth (TableItem [] items, bool set) { | |
1939 if (columnCount !is 0) return false; | |
1940 if (currentItem !is null) { | |
1941 // fixScrollWidth = true; | |
1942 return false; | |
1943 } | |
1944 if (drawCount !is 0) return false; | |
1945 GC gc = new GC (this); | |
1946 int newWidth = 0; | |
1947 for (int i = 0; i < items.length; i++) { | |
1948 TableItem item = items [i]; | |
1949 if (item !is null) { | |
1950 newWidth = Math.max (newWidth, item.calculateWidth (0, gc)); | |
1951 } | |
1952 } | |
1953 gc.dispose (); | |
1954 newWidth += getInsetWidth (); | |
1955 // if (!set) { | |
1956 // short [] width = new short [1]; | |
1957 // OS.GetDataBrowserTableViewNamedColumnWidth (handle, column_id, width); | |
1958 // if (width [0] >= newWidth) return false; | |
1959 // } | |
1960 // OS.SetDataBrowserTableViewNamedColumnWidth (handle, column_id, (short) newWidth); | |
1961 if (!set) { | |
1962 if (firstColumn.width() > newWidth) return false; | |
1963 } | |
1964 firstColumn.setWidth (newWidth); | |
1965 return true; | |
1966 } | |
1967 | |
1968 /** | |
1969 * Selects the item at the given zero-relative index in the receiver. | |
1970 * The current selection is first cleared, then the new item is selected. | |
1971 * | |
1972 * @param index the index of the item to select | |
1973 * | |
1974 * @exception DWTException <ul> | |
1975 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1976 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1977 * </ul> | |
1978 * | |
1979 * @see Table#deselectAll() | |
1980 * @see Table#select(int) | |
1981 */ | |
1982 public void setSelection (int index) { | |
1983 checkWidget(); | |
1984 //TODO - optimize to use expand flag | |
1985 deselectAll (); | |
1986 setSelection (index, false); | |
1987 } | |
1988 | |
1989 void setSelection (int index, bool notify) { | |
1990 // checkWidget(); | |
1991 if (0 <= index && index < itemCount) { | |
1992 select (index); | |
1993 showIndex (index); | |
1994 if (notify) { | |
1995 Event event = new Event (); | |
1996 event.item = _getItem (index); | |
1997 postEvent (DWT.Selection, event); | |
1998 } | |
1999 } | |
2000 } | |
2001 | |
2002 /** | |
2003 * Selects the items in the range specified by the given zero-relative | |
2004 * indices in the receiver. The range of indices is inclusive. | |
2005 * The current selection is cleared before the new items are selected. | |
2006 * <p> | |
2007 * Indices that are out of range are ignored and no items will be selected | |
2008 * if start is greater than end. | |
2009 * If the receiver is single-select and there is more than one item in the | |
2010 * given range, then all indices are ignored. | |
2011 * </p> | |
2012 * | |
2013 * @param start the start index of the items to select | |
2014 * @param end the end index of the items to select | |
2015 * | |
2016 * @exception DWTException <ul> | |
2017 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2018 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2019 * </ul> | |
2020 * | |
2021 * @see Table#deselectAll() | |
2022 * @see Table#select(int,int) | |
2023 */ | |
2024 public void setSelection (int start, int end) { | |
2025 checkWidget (); | |
2026 //TODO - optimize to use expand flag | |
2027 deselectAll (); | |
2028 if (end < 0 || start > end || ((style & DWT.SINGLE) !is 0 && start !is end)) return; | |
2029 if (itemCount is 0 || start >= itemCount) return; | |
2030 start = Math.max (0, start); | |
2031 end = Math.min (end, itemCount - 1); | |
2032 select (start, end); | |
2033 showIndex (start); | |
2034 } | |
2035 | |
2036 /** | |
2037 * Selects the items at the given zero-relative indices in the receiver. | |
2038 * The current selection is cleared before the new items are selected. | |
2039 * <p> | |
2040 * Indices that are out of range and duplicate indices are ignored. | |
2041 * If the receiver is single-select and multiple indices are specified, | |
2042 * then all indices are ignored. | |
2043 * </p> | |
2044 * | |
2045 * @param indices the indices of the items to select | |
2046 * | |
2047 * @exception IllegalArgumentException <ul> | |
2048 * <li>ERROR_NULL_ARGUMENT - if the array of indices is null</li> | |
2049 * </ul> | |
2050 * @exception DWTException <ul> | |
2051 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2052 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2053 * </ul> | |
2054 * | |
2055 * @see Table#deselectAll() | |
2056 * @see Table#select(int[]) | |
2057 */ | |
2058 public void setSelection (int [] indices) { | |
2059 checkWidget (); | |
2060 if (indices is null) error (DWT.ERROR_NULL_ARGUMENT); | |
2061 //TODO - optimize to use expand flag | |
2062 deselectAll (); | |
2063 int length = indices.length; | |
2064 if (length is 0 || ((style & DWT.SINGLE) !is 0 && length > 1)) return; | |
2065 select (indices); | |
2066 showIndex (indices [0]); | |
2067 } | |
2068 | |
2069 /** | |
2070 * Sets the receiver's selection to the given item. | |
2071 * The current selection is cleared before the new item is selected. | |
2072 * <p> | |
2073 * If the item is not in the receiver, then it is ignored. | |
2074 * </p> | |
2075 * | |
2076 * @param item the item to select | |
2077 * | |
2078 * @exception IllegalArgumentException <ul> | |
2079 * <li>ERROR_NULL_ARGUMENT - if the item is null</li> | |
2080 * <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li> | |
2081 * </ul> | |
2082 * @exception DWTException <ul> | |
2083 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2084 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2085 * </ul> | |
2086 * | |
2087 * @since 3.2 | |
2088 */ | |
2089 public void setSelection (TableItem item) { | |
2090 checkWidget (); | |
2091 if (item is null) error (DWT.ERROR_NULL_ARGUMENT); | |
2092 setSelection (new TableItem [] {item}); | |
2093 } | |
2094 | |
2095 /** | |
2096 * Sets the receiver's selection to be the given array of items. | |
2097 * The current selection is cleared before the new items are selected. | |
2098 * <p> | |
2099 * Items that are not in the receiver are ignored. | |
2100 * If the receiver is single-select and multiple items are specified, | |
2101 * then all items are ignored. | |
2102 * </p> | |
2103 * | |
2104 * @param items the array of items | |
2105 * | |
2106 * @exception IllegalArgumentException <ul> | |
2107 * <li>ERROR_NULL_ARGUMENT - if the array of items is null</li> | |
2108 * <li>ERROR_INVALID_ARGUMENT - if one of the items has been disposed</li> | |
2109 * </ul> | |
2110 * @exception DWTException <ul> | |
2111 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2112 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2113 * </ul> | |
2114 * | |
2115 * @see Table#deselectAll() | |
2116 * @see Table#select(int[]) | |
2117 * @see Table#setSelection(int[]) | |
2118 */ | |
2119 public void setSelection (TableItem [] items) { | |
2120 checkWidget (); | |
2121 if (items is null) error (DWT.ERROR_NULL_ARGUMENT); | |
2122 //TODO - optimize to use expand flag | |
2123 deselectAll (); | |
2124 int length = items.length; | |
2125 if (length is 0 || ((style & DWT.SINGLE) !is 0 && length > 1)) return; | |
2126 int [] indices = new int [length]; | |
2127 int count = 0; | |
2128 for (int i=0; i<length; i++) { | |
2129 int index = indexOf (items [length - i - 1]); | |
2130 if (index !is -1) { | |
2131 indices [count++] = index; | |
2132 } | |
2133 } | |
2134 if (count > 0) { | |
2135 select (indices); | |
2136 showIndex (indices [0] - 1); | |
2137 } | |
2138 } | |
2139 | |
2140 /** | |
2141 * Sets the column used by the sort indicator for the receiver. A null | |
2142 * value will clear the sort indicator. The current sort column is cleared | |
2143 * before the new column is set. | |
2144 * | |
2145 * @param column the column used by the sort indicator or <code>null</code> | |
2146 * | |
2147 * @exception IllegalArgumentException <ul> | |
2148 * <li>ERROR_INVALID_ARGUMENT - if the column is disposed</li> | |
2149 * </ul> | |
2150 * @exception DWTException <ul> | |
2151 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2152 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2153 * </ul> | |
2154 * | |
2155 * @since 3.2 | |
2156 */ | |
2157 public void setSortColumn (TableColumn column) { | |
2158 checkWidget (); | |
2159 if (column !is null && column.isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT); | |
2160 if (column is sortColumn) return; | |
2161 // DataBrowserCallbacks callbacks = new DataBrowserCallbacks (); | |
2162 // OS.GetDataBrowserCallbacks (handle, callbacks); | |
2163 // callbacks.v1_itemCompareCallback = display.itemCompareProc; | |
2164 // OS.SetDataBrowserCallbacks (handle, callbacks); | |
2165 // if (column is null) { | |
2166 // if (sortColumn !is null && !sortColumn.isDisposed () && sortDirection !is DWT.NONE) { | |
2167 // OS.SetDataBrowserSortOrder (handle, (short) OS.kDataBrowserOrderIncreasing); | |
2168 // sortColumn = null; | |
2169 // OS.SetDataBrowserSortProperty (handle, 0); | |
2170 // } | |
2171 // } | |
2172 // sortColumn = column; | |
2173 // if (sortColumn !is null && !sortColumn.isDisposed () && sortDirection !is DWT.NONE) { | |
2174 // OS.SetDataBrowserSortProperty (handle, sortColumn.id); | |
2175 // int order = sortDirection is DWT.DOWN ? OS.kDataBrowserOrderDecreasing : OS.kDataBrowserOrderIncreasing; | |
2176 // OS.SetDataBrowserSortOrder (handle, (short) order); | |
2177 // } | |
2178 // callbacks.v1_itemCompareCallback = itemCompareProc (); | |
2179 // OS.SetDataBrowserCallbacks (handle, callbacks); | |
2180 } | |
2181 | |
2182 /** | |
2183 * Sets the direction of the sort indicator for the receiver. The value | |
2184 * can be one of <code>UP</code>, <code>DOWN</code> or <code>NONE</code>. | |
2185 * | |
2186 * @param direction the direction of the sort indicator | |
2187 * | |
2188 * @exception DWTException <ul> | |
2189 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2190 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2191 * </ul> | |
2192 * | |
2193 * @since 3.2 | |
2194 */ | |
2195 public void setSortDirection (int direction) { | |
2196 checkWidget (); | |
2197 if (direction !is DWT.UP && direction !is DWT.DOWN && direction !is DWT.NONE) return; | |
2198 if (direction is sortDirection) return; | |
2199 sortDirection = direction; | |
2200 // DataBrowserCallbacks callbacks = new DataBrowserCallbacks (); | |
2201 // OS.GetDataBrowserCallbacks (handle, callbacks); | |
2202 // callbacks.v1_itemCompareCallback = display.itemCompareProc; | |
2203 // OS.SetDataBrowserCallbacks (handle, callbacks); | |
2204 // if (sortColumn !is null && !sortColumn.isDisposed ()) { | |
2205 // if (sortDirection is DWT.NONE) { | |
2206 // OS.SetDataBrowserSortOrder (handle, (short) OS.kDataBrowserOrderIncreasing); | |
2207 // TableColumn column = sortColumn; | |
2208 // sortColumn = null; | |
2209 // OS.SetDataBrowserSortProperty (handle, 0); | |
2210 // sortColumn = column; | |
2211 // } else { | |
2212 // OS.SetDataBrowserSortProperty (handle, 0); | |
2213 // OS.SetDataBrowserSortProperty (handle, sortColumn.id); | |
2214 // int order = sortDirection is DWT.DOWN ? OS.kDataBrowserOrderDecreasing : OS.kDataBrowserOrderIncreasing; | |
2215 // OS.SetDataBrowserSortOrder (handle, (short) order); | |
2216 // } | |
2217 // } | |
2218 // callbacks.v1_itemCompareCallback = itemCompareProc (); | |
2219 // OS.SetDataBrowserCallbacks (handle, callbacks); | |
2220 } | |
2221 | |
2222 void setTableEmpty () { | |
2223 itemCount = 0; | |
2224 items = new TableItem [4]; | |
2225 } | |
2226 | |
2227 /** | |
2228 * Sets the zero-relative index of the item which is currently | |
2229 * at the top of the receiver. This index can change when items | |
2230 * are scrolled or new items are added and removed. | |
2231 * | |
2232 * @param index the index of the top item | |
2233 * | |
2234 * @exception DWTException <ul> | |
2235 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2236 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2237 * </ul> | |
2238 */ | |
2239 public void setTopIndex (int index) { | |
2240 checkWidget(); | |
2241 NSRect rect = ((NSTableView)view).rectOfRow(index); | |
2242 ((NSTableView)view).scrollRectToVisible(rect); | |
2243 } | |
2244 | |
2245 /** | |
2246 * Shows the column. If the column is already showing in the receiver, | |
2247 * this method simply returns. Otherwise, the columns are scrolled until | |
2248 * the column is visible. | |
2249 * | |
2250 * @param column the column to be shown | |
2251 * | |
2252 * @exception IllegalArgumentException <ul> | |
2253 * <li>ERROR_NULL_ARGUMENT - if the column is null</li> | |
2254 * <li>ERROR_INVALID_ARGUMENT - if the column has been disposed</li> | |
2255 * </ul> | |
2256 * @exception DWTException <ul> | |
2257 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2258 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2259 * </ul> | |
2260 * | |
2261 * @since 3.0 | |
2262 */ | |
2263 public void showColumn (TableColumn column) { | |
2264 checkWidget (); | |
2265 if (column is null) error (DWT.ERROR_NULL_ARGUMENT); | |
2266 if (column.isDisposed()) error(DWT.ERROR_INVALID_ARGUMENT); | |
2267 if (column.parent !is this) return; | |
2268 int index = indexOf (column); | |
2269 if (columnCount <= 1 || !(0 <= index && index < columnCount)) return; | |
2270 ((NSTableView)view).scrollColumnToVisible(index + ((style & DWT.CHECK) !is 0 ? 1 : 0)); | |
2271 } | |
2272 | |
2273 void showIndex (int index) { | |
2274 if (0 <= index && index < itemCount) { | |
2275 ((NSTableView)view).scrollRowToVisible(index); | |
2276 } | |
2277 } | |
2278 | |
2279 /** | |
2280 * Shows the item. If the item is already showing in the receiver, | |
2281 * this method simply returns. Otherwise, the items are scrolled until | |
2282 * the item is visible. | |
2283 * | |
2284 * @param item the item to be shown | |
2285 * | |
2286 * @exception IllegalArgumentException <ul> | |
2287 * <li>ERROR_NULL_ARGUMENT - if the item is null</li> | |
2288 * <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li> | |
2289 * </ul> | |
2290 * @exception DWTException <ul> | |
2291 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2292 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2293 * </ul> | |
2294 * | |
2295 * @see Table#showSelection() | |
2296 */ | |
2297 public void showItem (TableItem item) { | |
2298 checkWidget (); | |
2299 if (item is null) error (DWT.ERROR_NULL_ARGUMENT); | |
2300 if (item.isDisposed()) error(DWT.ERROR_INVALID_ARGUMENT); | |
2301 int index = indexOf (item); | |
2302 if (index !is -1) showIndex (index); | |
2303 } | |
2304 | |
2305 /** | |
2306 * Shows the selection. If the selection is already showing in the receiver, | |
2307 * this method simply returns. Otherwise, the items are scrolled until | |
2308 * the selection is visible. | |
2309 * | |
2310 * @exception DWTException <ul> | |
2311 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2312 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2313 * </ul> | |
2314 * | |
2315 * @see Table#showItem(TableItem) | |
2316 */ | |
2317 public void showSelection () { | |
2318 checkWidget(); | |
2319 int index = getSelectionIndex (); | |
2320 if (index >= 0) showIndex (index); | |
2321 } | |
2322 | |
2323 void sendDoubleSelection() { | |
2324 postEvent (DWT.DefaultSelection); | |
2325 } | |
2326 | |
2327 void tableViewSelectionDidChange (int aNotification) { | |
2328 if (ignoreSelect) return; | |
2329 NSTableView widget = (NSTableView)view; | |
2330 int row = widget.selectedRow(); | |
2331 if(row is -1) | |
2332 postEvent(DWT.Selection); | |
2333 else { | |
2334 TableItem item = _getItem(row); | |
2335 Event event = new Event(); | |
2336 event.item = item; | |
2337 event.index = row; | |
2338 postEvent(DWT.Selection, event); | |
2339 } | |
2340 } | |
2341 | |
2342 int tableView_objectValueForTableColumn_row(int aTableView, int aTableColumn, int rowIndex) { | |
2343 TableItem item = items [rowIndex]; | |
2344 if (checkColumn !is null && aTableColumn is checkColumn.id) { | |
2345 NSNumber value; | |
2346 if (item.checked && item.grayed) { | |
2347 value = NSNumber.numberWithInt(OS.NSMixedState); | |
2348 } else { | |
2349 value = NSNumber.numberWithInt(item.checked ? OS.NSOnState : OS.NSOffState); | |
2350 } | |
2351 return value.id; | |
2352 } | |
2353 for (int i=0; i<columnCount; i++) { | |
2354 if (columns [i].nsColumn.id is aTableColumn) { | |
2355 return item.createString(i).id; | |
2356 } | |
2357 } | |
2358 return item.createString(0).id; | |
2359 } | |
2360 | |
2361 void tableView_setObjectValue_forTableColumn_row(int aTableView, int anObject, int aTableColumn, int rowIndex) { | |
2362 TableItem item = items [rowIndex]; | |
2363 if (checkColumn !is null && aTableColumn is checkColumn.id) { | |
2364 item.checked = !item.checked; | |
2365 Event event = new Event(); | |
2366 event.detail = DWT.CHECK; | |
2367 event.item = item; | |
2368 event.index = rowIndex; | |
2369 postEvent(DWT.Selection, event); | |
2370 } | |
2371 } | |
2372 | |
2373 bool tableView_shouldEditTableColumn_row(int aTableView, int aTableColumn, int rowIndex) { | |
2374 return false; | |
2375 } | |
2376 | |
2377 void tableView_willDisplayCell_forTableColumn_row(int aTableView, int aCell, int aTableColumn, int rowIndex) { | |
2378 if (checkColumn !is null && aTableColumn is checkColumn.id) return; | |
2379 TableItem item = items [rowIndex]; | |
2380 Image image = item.image; | |
2381 for (int i=0; i<columnCount; i++) { | |
2382 if (columns [i].nsColumn.id is aTableColumn) { | |
2383 image = item.getImage(i); | |
2384 } | |
2385 } | |
2386 NSBrowserCell cell = new NSBrowserCell(aCell); | |
2387 cell.setImage(image !is null ? image.handle : null); | |
2388 cell.setLeaf(true); | |
2389 } | |
2390 } |