10
|
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 * Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation bug 154329
|
|
11 * - fixes in bug 170381, 198665
|
|
12 * Port to the D programming language:
|
|
13 * Frank Benoit <benoit@tionex.de>
|
|
14 *******************************************************************************/
|
|
15
|
|
16 module dwtx.jface.viewers.AbstractTableViewer;
|
|
17
|
|
18 import dwtx.jface.viewers.ColumnViewer;
|
|
19 import dwtx.jface.viewers.ViewerRow;
|
|
20 import dwtx.jface.viewers.IBaseLabelProvider;
|
|
21 import dwtx.jface.viewers.IContentProvider;
|
|
22 import dwtx.jface.viewers.ILazyContentProvider;
|
|
23 import dwtx.jface.viewers.ViewerColumn;
|
|
24 import dwtx.jface.viewers.ViewerCell;
|
|
25 import dwtx.jface.viewers.ViewerComparator;
|
|
26 import dwtx.jface.viewers.IStructuredContentProvider;
|
|
27
|
|
28 import tango.util.collection.model.SeqView;
|
|
29 import tango.util.collection.ArraySeq;
|
|
30 import tango.util.collection.HashSet;
|
|
31
|
|
32 import dwt.DWT;
|
|
33 import dwt.widgets.Control;
|
|
34 import dwt.widgets.Event;
|
|
35 import dwt.widgets.Item;
|
|
36 import dwt.widgets.Listener;
|
|
37 import dwt.widgets.Widget;
|
|
38 import dwtx.core.runtime.Assert;
|
|
39
|
|
40 import dwt.dwthelper.utils;
|
|
41 import dwt.dwthelper.Runnable;
|
|
42 import tango.core.Array;
|
|
43
|
|
44 /**
|
|
45 * This is a widget independent class implementors of
|
|
46 * {@link dwt.widgets.Table} like widgets can use to provide a
|
|
47 * viewer on top of their widget implementations.
|
|
48 *
|
|
49 * @since 3.3
|
|
50 */
|
|
51 public abstract class AbstractTableViewer : ColumnViewer {
|
|
52
|
|
53 private class VirtualManager {
|
|
54
|
|
55 /**
|
|
56 * The currently invisible elements as provided by the content provider
|
|
57 * or by addition. This will not be populated by an
|
|
58 * ILazyStructuredContentProvider as an ILazyStructuredContentProvider
|
|
59 * is only queried on the virtual callback.
|
|
60 */
|
|
61 private Object[] cachedElements = null;
|
|
62
|
|
63 /**
|
|
64 * Create a new instance of the receiver.
|
|
65 *
|
|
66 */
|
|
67 public this() {
|
|
68 addTableListener();
|
|
69 }
|
|
70
|
|
71 /**
|
|
72 * Add the listener for SetData on the table
|
|
73 */
|
|
74 private void addTableListener() {
|
|
75 getControl().addListener(DWT.SetData, new class Listener {
|
|
76 /*
|
|
77 * (non-Javadoc)
|
|
78 *
|
|
79 * @see dwt.widgets.Listener#handleEvent(dwt.widgets.Event)
|
|
80 */
|
|
81 public void handleEvent(Event event) {
|
|
82 Item item = cast(Item) event.item;
|
|
83 final int index = doIndexOf(item);
|
|
84 Object element = resolveElement(index);
|
|
85 if (element is null) {
|
|
86 // Didn't find it so make a request
|
|
87 // Keep looking if it is not in the cache.
|
|
88 IContentProvider contentProvider = getContentProvider();
|
|
89 // If we are building lazily then request lookup now
|
|
90 if (auto lcp = cast(ILazyContentProvider)contentProvider ) {
|
|
91 lcp.updateElement(index);
|
|
92 return;
|
|
93 }
|
|
94 }
|
|
95
|
|
96 associate(element, item);
|
|
97 updateItem(item, element);
|
|
98 }
|
|
99
|
|
100 });
|
|
101 }
|
|
102
|
|
103 /**
|
|
104 * Get the element at index.Resolve it lazily if this is available.
|
|
105 *
|
|
106 * @param index
|
|
107 * @return Object or <code>null</code> if it could not be found
|
|
108 */
|
|
109 protected Object resolveElement(int index) {
|
|
110
|
|
111 Object element = null;
|
|
112 if (index < cachedElements.length) {
|
|
113 element = cachedElements[index];
|
|
114 }
|
|
115
|
|
116 return element;
|
|
117 }
|
|
118
|
|
119 /**
|
|
120 * A non visible item has been added.
|
|
121 *
|
|
122 * @param element
|
|
123 * @param index
|
|
124 */
|
|
125 public void notVisibleAdded(Object element, int index) {
|
|
126
|
|
127 int requiredCount = doGetItemCount() + 1;
|
|
128
|
|
129 Object[] newCache = new Object[requiredCount];
|
|
130 System.arraycopy(cachedElements, 0, newCache, 0, index);
|
|
131 if (index < cachedElements.length) {
|
|
132 System.arraycopy(cachedElements, index, newCache, index + 1,
|
|
133 cachedElements.length - index);
|
|
134 }
|
|
135 newCache[index] = element;
|
|
136 cachedElements = newCache;
|
|
137
|
|
138 doSetItemCount(requiredCount);
|
|
139 }
|
|
140
|
|
141 /**
|
|
142 * The elements with the given indices need to be removed from the
|
|
143 * cache.
|
|
144 *
|
|
145 * @param indices
|
|
146 */
|
|
147 public void removeIndices(int[] indices) {
|
|
148 if (indices.length is 1) {
|
|
149 removeIndicesFromTo(indices[0], indices[0]);
|
|
150 }
|
|
151 int requiredCount = doGetItemCount() - indices.length;
|
|
152
|
|
153 tango.core.Array.sort( indices );
|
|
154 Object[] newCache = new Object[requiredCount];
|
|
155 int indexInNewCache = 0;
|
|
156 int nextToSkip = 0;
|
|
157 for (int i = 0; i < cachedElements.length; i++) {
|
|
158 if (nextToSkip < indices.length && i is indices[nextToSkip]) {
|
|
159 nextToSkip++;
|
|
160 } else {
|
|
161 newCache[indexInNewCache++] = cachedElements[i];
|
|
162 }
|
|
163 }
|
|
164 cachedElements = newCache;
|
|
165 }
|
|
166
|
|
167 /**
|
|
168 * The elements between the given indices (inclusive) need to be removed
|
|
169 * from the cache.
|
|
170 *
|
|
171 * @param from
|
|
172 * @param to
|
|
173 */
|
|
174 public void removeIndicesFromTo(int from, int to) {
|
|
175 int indexAfterTo = to + 1;
|
|
176 Object[] newCache = new Object[cachedElements.length
|
|
177 - (indexAfterTo - from)];
|
|
178 System.arraycopy(cachedElements, 0, newCache, 0, from);
|
|
179 if (indexAfterTo < cachedElements.length) {
|
|
180 System.arraycopy(cachedElements, indexAfterTo, newCache, from,
|
|
181 cachedElements.length - indexAfterTo);
|
|
182 }
|
|
183 }
|
|
184
|
|
185 /**
|
|
186 * @param element
|
|
187 * @return the index of the element in the cache, or null
|
|
188 */
|
|
189 public int find(Object element) {
|
|
190 int res = tango.core.Array.find( cachedElements, element );
|
|
191 if( res is cachedElements.length ) res = -1;
|
|
192 return res;
|
|
193 }
|
|
194
|
|
195 /**
|
|
196 * @param count
|
|
197 */
|
|
198 public void adjustCacheSize(int count) {
|
|
199 if (count is cachedElements.length) {
|
|
200 return;
|
|
201 } else if (count < cachedElements.length) {
|
|
202 Object[] newCache = new Object[count];
|
|
203 System.arraycopy(cachedElements, 0, newCache, 0, count);
|
|
204 cachedElements = newCache;
|
|
205 } else {
|
|
206 Object[] newCache = new Object[count];
|
|
207 System.arraycopy(cachedElements, 0, newCache, 0,
|
|
208 cachedElements.length);
|
|
209 cachedElements = newCache;
|
|
210 }
|
|
211 }
|
|
212
|
|
213 }
|
|
214
|
|
215 private VirtualManager virtualManager;
|
|
216
|
|
217 /**
|
|
218 * Create the new viewer for table like widgets
|
|
219 */
|
|
220 public this() {
|
|
221 super();
|
|
222 }
|
|
223
|
|
224 protected void hookControl(Control control) {
|
|
225 super.hookControl(control);
|
|
226 initializeVirtualManager(getControl().getStyle());
|
|
227 }
|
|
228
|
|
229 /**
|
|
230 * Initialize the virtual manager to manage the virtual state if the table
|
|
231 * is VIRTUAL. If not use the default no-op version.
|
|
232 *
|
|
233 * @param style
|
|
234 */
|
|
235 private void initializeVirtualManager(int style) {
|
|
236 if ((style & DWT.VIRTUAL) is 0) {
|
|
237 return;
|
|
238 }
|
|
239
|
|
240 virtualManager = new VirtualManager();
|
|
241 }
|
|
242
|
|
243 /**
|
|
244 * Adds the given elements to this table viewer. If this viewer does not
|
|
245 * have a sorter, the elements are added at the end in the order given;
|
|
246 * otherwise the elements are inserted at appropriate positions.
|
|
247 * <p>
|
|
248 * This method should be called (by the content provider) when elements have
|
|
249 * been added to the model, in order to cause the viewer to accurately
|
|
250 * reflect the model. This method only affects the viewer, not the model.
|
|
251 * </p>
|
|
252 *
|
|
253 * @param elements
|
|
254 * the elements to add
|
|
255 */
|
|
256 public void add(Object[] elements) {
|
|
257 assertElementsNotNull(elements);
|
|
258 if (isBusy())
|
|
259 return;
|
|
260 Object[] filtered = filter(elements);
|
|
261
|
|
262 for (int i = 0; i < filtered.length; i++) {
|
|
263 Object element = filtered[i];
|
|
264 int index = indexForElement(element);
|
|
265 createItem(element, index);
|
|
266 }
|
|
267 }
|
|
268
|
|
269 /**
|
|
270 * Create a new TableItem at index if required.
|
|
271 *
|
|
272 * @param element
|
|
273 * @param index
|
|
274 *
|
|
275 * @since 3.1
|
|
276 */
|
|
277 private void createItem(Object element, int index) {
|
|
278 if (virtualManager is null) {
|
|
279 updateItem(internalCreateNewRowPart(DWT.NONE, index).getItem(),
|
|
280 element);
|
|
281 } else {
|
|
282 virtualManager.notVisibleAdded(element, index);
|
|
283
|
|
284 }
|
|
285 }
|
|
286
|
|
287 /**
|
|
288 * Create a new row. Callers can only use the returned object locally and before
|
|
289 * making the next call on the viewer since it may be re-used for subsequent method
|
|
290 * calls.
|
|
291 *
|
|
292 * @param style
|
|
293 * the style for the new row
|
|
294 * @param rowIndex
|
|
295 * the index of the row or -1 if the row is appended at the end
|
|
296 * @return the newly created row
|
|
297 */
|
|
298 protected abstract ViewerRow internalCreateNewRowPart(int style,
|
|
299 int rowIndex);
|
|
300
|
|
301 /**
|
|
302 * Adds the given element to this table viewer. If this viewer does not have
|
|
303 * a sorter, the element is added at the end; otherwise the element is
|
|
304 * inserted at the appropriate position.
|
|
305 * <p>
|
|
306 * This method should be called (by the content provider) when a single
|
|
307 * element has been added to the model, in order to cause the viewer to
|
|
308 * accurately reflect the model. This method only affects the viewer, not
|
|
309 * the model. Note that there is another method for efficiently processing
|
|
310 * the simultaneous addition of multiple elements.
|
|
311 * </p>
|
|
312 *
|
|
313 * @param element
|
|
314 * the element to add
|
|
315 */
|
|
316 public void add(Object element) {
|
|
317 add([ element ]);
|
|
318 }
|
|
319
|
|
320 /*
|
|
321 * (non-Javadoc)
|
|
322 *
|
|
323 * @see dwtx.jface.viewers.StructuredViewer#doFindInputItem(java.lang.Object)
|
|
324 */
|
|
325 protected Widget doFindInputItem(Object element) {
|
|
326 if (opEquals(element, getRoot())) {
|
|
327 return getControl();
|
|
328 }
|
|
329 return null;
|
|
330 }
|
|
331
|
|
332 /*
|
|
333 * (non-Javadoc)
|
|
334 *
|
|
335 * @see dwtx.jface.viewers.StructuredViewer#doFindItem(java.lang.Object)
|
|
336 */
|
|
337 protected Widget doFindItem(Object element) {
|
|
338
|
|
339 Item[] children = doGetItems();
|
|
340 for (int i = 0; i < children.length; i++) {
|
|
341 Item item = children[i];
|
|
342 Object data = item.getData();
|
|
343 if (data !is null && opEquals(data, element)) {
|
|
344 return item;
|
|
345 }
|
|
346 }
|
|
347
|
|
348 return null;
|
|
349 }
|
|
350
|
|
351 /*
|
|
352 * (non-Javadoc)
|
|
353 *
|
|
354 * @see dwtx.jface.viewers.StructuredViewer#doUpdateItem(dwt.widgets.Widget,
|
|
355 * java.lang.Object, bool)
|
|
356 */
|
|
357 protected void doUpdateItem(Widget widget, Object element, bool fullMap) {
|
|
358 bool oldBusy = busy;
|
|
359 busy = true;
|
|
360 try {
|
|
361 if ( auto item = cast(Item)widget ) {
|
|
362
|
|
363 // remember element we are showing
|
|
364 if (fullMap) {
|
|
365 associate(element, item);
|
|
366 } else {
|
|
367 Object data = item.getData();
|
|
368 if (data !is null) {
|
|
369 unmapElement(data, item);
|
|
370 }
|
|
371 item.setData(element);
|
|
372 mapElement(element, item);
|
|
373 }
|
|
374
|
|
375 int columnCount = doGetColumnCount();
|
|
376 if (columnCount is 0)
|
|
377 columnCount = 1;// If there are no columns do the first one
|
|
378
|
|
379 ViewerRow viewerRowFromItem = getViewerRowFromItem(item);
|
|
380
|
|
381 bool isVirtual = (getControl().getStyle() & DWT.VIRTUAL) !is 0;
|
|
382
|
|
383 // If the control is virtual, we cannot use the cached viewer row object. See bug 188663.
|
|
384 if (isVirtual) {
|
|
385 viewerRowFromItem = cast(ViewerRow) viewerRowFromItem.clone();
|
|
386 }
|
|
387
|
|
388 // Also enter loop if no columns added. See 1G9WWGZ: JFUIF:WINNT -
|
|
389 // TableViewer with 0 columns does not work
|
|
390 for (int column = 0; column < columnCount || column is 0; column++) {
|
|
391 ViewerColumn columnViewer = getViewerColumn(column);
|
|
392 ViewerCell cellToUpdate = updateCell(viewerRowFromItem,
|
|
393 column, element);
|
|
394
|
|
395 // If the control is virtual, we cannot use the cached cell object. See bug 188663.
|
|
396 if (isVirtual) {
|
|
397 cellToUpdate = new ViewerCell(cellToUpdate.getViewerRow(), cellToUpdate.getColumnIndex(), element);
|
|
398 }
|
|
399
|
|
400 columnViewer.refresh(cellToUpdate);
|
|
401
|
|
402 // clear cell (see bug 201280)
|
|
403 updateCell(null, 0, null);
|
|
404
|
|
405 // As it is possible for user code to run the event
|
|
406 // loop check here.
|
|
407 if (item.isDisposed()) {
|
|
408 unmapElement(element, item);
|
|
409 return;
|
|
410 }
|
|
411
|
|
412 }
|
|
413
|
|
414 }
|
|
415 } finally {
|
|
416 busy = oldBusy;
|
|
417 }
|
|
418 }
|
|
419
|
|
420 /*
|
|
421 * (non-Javadoc)
|
|
422 *
|
|
423 * @see dwtx.jface.viewers.ColumnViewer#getColumnViewerOwner(int)
|
|
424 */
|
|
425 protected Widget getColumnViewerOwner(int columnIndex) {
|
|
426 int columnCount = doGetColumnCount();
|
|
427
|
|
428 if (columnIndex < 0
|
|
429 || (columnIndex > 0 && columnIndex >= columnCount)) {
|
|
430 return null;
|
|
431 }
|
|
432
|
|
433 if (columnCount is 0)// Hang it off the table if it
|
|
434 return getControl();
|
|
435
|
|
436 return doGetColumn(columnIndex);
|
|
437 }
|
|
438
|
|
439 /**
|
|
440 * Returns the element with the given index from this table viewer. Returns
|
|
441 * <code>null</code> if the index is out of range.
|
|
442 * <p>
|
|
443 * This method is internal to the framework.
|
|
444 * </p>
|
|
445 *
|
|
446 * @param index
|
|
447 * the zero-based index
|
|
448 * @return the element at the given index, or <code>null</code> if the
|
|
449 * index is out of range
|
|
450 */
|
|
451 public Object getElementAt(int index) {
|
|
452 if (index >= 0 && index < doGetItemCount()) {
|
|
453 Item i = doGetItem(index);
|
|
454 if (i !is null) {
|
|
455 return i.getData();
|
|
456 }
|
|
457 }
|
|
458 return null;
|
|
459 }
|
|
460
|
|
461 /**
|
|
462 * The table viewer implementation of this <code>Viewer</code> framework
|
|
463 * method returns the label provider, which in the case of table viewers
|
|
464 * will be an instance of either <code>ITableLabelProvider</code> or
|
|
465 * <code>ILabelProvider</code>. If it is an
|
|
466 * <code>ITableLabelProvider</code>, then it provides a separate label
|
|
467 * text and image for each column. If it is an <code>ILabelProvider</code>,
|
|
468 * then it provides only the label text and image for the first column, and
|
|
469 * any remaining columns are blank.
|
|
470 */
|
|
471 public IBaseLabelProvider getLabelProvider() {
|
|
472 return super.getLabelProvider();
|
|
473 }
|
|
474
|
|
475 /*
|
|
476 * (non-Javadoc)
|
|
477 *
|
|
478 * @see dwtx.jface.viewers.StructuredViewer#getSelectionFromWidget()
|
|
479 */
|
|
480 protected SeqView!(Object) getSelectionFromWidget() {
|
|
481 if (virtualManager !is null) {
|
|
482 return getVirtualSelection();
|
|
483 }
|
|
484 Widget[] items = doGetSelection();
|
|
485 auto list = new ArraySeq!(Object);
|
|
486 list.capacity(items.length);
|
|
487 for (int i = 0; i < items.length; i++) {
|
|
488 Widget item = items[i];
|
|
489 Object e = item.getData();
|
|
490 if (e !is null) {
|
|
491 list.append(e);
|
|
492 }
|
|
493 }
|
|
494 return list;
|
|
495 }
|
|
496
|
|
497 /**
|
|
498 * Get the virtual selection. Avoid calling DWT whenever possible to prevent
|
|
499 * extra widget creation.
|
|
500 *
|
|
501 * @return List of Object
|
|
502 */
|
|
503
|
|
504 private SeqView!(Object) getVirtualSelection() {
|
|
505
|
|
506 auto result = new ArraySeq!(Object);
|
|
507 int[] selectionIndices = doGetSelectionIndices();
|
|
508 if (auto lazy_ = cast(ILazyContentProvider) getContentProvider() ) {
|
|
509 for (int i = 0; i < selectionIndices.length; i++) {
|
|
510 int selectionIndex = selectionIndices[i];
|
|
511 lazy_.updateElement(selectionIndex);// Start the update
|
|
512 Object element = doGetItem(selectionIndex).getData();
|
|
513 // Only add the element if it got updated.
|
|
514 // If this is done deferred the selection will
|
|
515 // be incomplete until selection is finished.
|
|
516 if (element !is null) {
|
|
517 result.append(element);
|
|
518 }
|
|
519 }
|
|
520 } else {
|
|
521 for (int i = 0; i < selectionIndices.length; i++) {
|
|
522 Object element = null;
|
|
523 // See if it is cached
|
|
524 int selectionIndex = selectionIndices[i];
|
|
525 if (selectionIndex < virtualManager.cachedElements.length) {
|
|
526 element = virtualManager.cachedElements[selectionIndex];
|
|
527 }
|
|
528 if (element is null) {
|
|
529 // Not cached so try the item's data
|
|
530 Item item = doGetItem(selectionIndex);
|
|
531 element = item.getData();
|
|
532 }
|
|
533 if (element !is null) {
|
|
534 result.append(element);
|
|
535 }
|
|
536 }
|
|
537
|
|
538 }
|
|
539 return result;
|
|
540 }
|
|
541
|
|
542 /**
|
|
543 * @param element
|
|
544 * the element to insert
|
|
545 * @return the index where the item should be inserted.
|
|
546 */
|
|
547 protected int indexForElement(Object element) {
|
|
548 ViewerComparator comparator = getComparator();
|
|
549 if (comparator is null) {
|
|
550 return doGetItemCount();
|
|
551 }
|
|
552 int count = doGetItemCount();
|
|
553 int min = 0, max = count - 1;
|
|
554 while (min <= max) {
|
|
555 int mid = (min + max) / 2;
|
|
556 Object data = doGetItem(mid).getData();
|
|
557 int compare = comparator.compare(this, data, element);
|
|
558 if (compare is 0) {
|
|
559 // find first item > element
|
|
560 while (compare is 0) {
|
|
561 ++mid;
|
|
562 if (mid >= count) {
|
|
563 break;
|
|
564 }
|
|
565 data = doGetItem(mid).getData();
|
|
566 compare = comparator.compare(this, data, element);
|
|
567 }
|
|
568 return mid;
|
|
569 }
|
|
570 if (compare < 0) {
|
|
571 min = mid + 1;
|
|
572 } else {
|
|
573 max = mid - 1;
|
|
574 }
|
|
575 }
|
|
576 return min;
|
|
577 }
|
|
578
|
|
579 /*
|
|
580 * (non-Javadoc)
|
|
581 *
|
|
582 * @see dwtx.jface.viewers.Viewer#inputChanged(java.lang.Object,
|
|
583 * java.lang.Object)
|
|
584 */
|
|
585 protected void inputChanged(Object input, Object oldInput) {
|
|
586 getControl().setRedraw(false);
|
|
587 try {
|
|
588 preservingSelection(new class Runnable {
|
|
589 public void run() {
|
|
590 internalRefresh(getRoot());
|
|
591 }
|
|
592 });
|
|
593 } finally {
|
|
594 getControl().setRedraw(true);
|
|
595 }
|
|
596 }
|
|
597
|
|
598 /**
|
|
599 * Inserts the given element into this table viewer at the given position.
|
|
600 * If this viewer has a sorter, the position is ignored and the element is
|
|
601 * inserted at the correct position in the sort order.
|
|
602 * <p>
|
|
603 * This method should be called (by the content provider) when elements have
|
|
604 * been added to the model, in order to cause the viewer to accurately
|
|
605 * reflect the model. This method only affects the viewer, not the model.
|
|
606 * </p>
|
|
607 *
|
|
608 * @param element
|
|
609 * the element
|
|
610 * @param position
|
|
611 * a 0-based position relative to the model, or -1 to indicate
|
|
612 * the last position
|
|
613 */
|
|
614 public void insert(Object element, int position) {
|
|
615 applyEditorValue();
|
|
616 if (getComparator() !is null || hasFilters()) {
|
|
617 add(element);
|
|
618 return;
|
|
619 }
|
|
620 if (position is -1) {
|
|
621 position = doGetItemCount();
|
|
622 }
|
|
623 if (isBusy())
|
|
624 return;
|
|
625 createItem(element, position);
|
|
626 }
|
|
627
|
|
628 /*
|
|
629 * (non-Javadoc)
|
|
630 *
|
|
631 * @see dwtx.jface.viewers.StructuredViewer#internalRefresh(java.lang.Object)
|
|
632 */
|
|
633 protected void internalRefresh(Object element) {
|
|
634 internalRefresh(element, true);
|
|
635 }
|
|
636
|
|
637 /*
|
|
638 * (non-Javadoc)
|
|
639 *
|
|
640 * @see dwtx.jface.viewers.StructuredViewer#internalRefresh(java.lang.Object,
|
|
641 * bool)
|
|
642 */
|
|
643 protected void internalRefresh(Object element, bool updateLabels) {
|
|
644 applyEditorValue();
|
|
645 if (element is null || opEquals(element, getRoot())) {
|
|
646 if (virtualManager is null) {
|
|
647 internalRefreshAll(updateLabels);
|
|
648 } else {
|
|
649 internalVirtualRefreshAll();
|
|
650 }
|
|
651 } else {
|
|
652 Widget w = findItem(element);
|
|
653 if (w !is null) {
|
|
654 updateItem(w, element);
|
|
655 }
|
|
656 }
|
|
657 }
|
|
658
|
|
659 /**
|
|
660 * Refresh all with virtual elements.
|
|
661 *
|
|
662 * @since 3.1
|
|
663 */
|
|
664 private void internalVirtualRefreshAll() {
|
|
665
|
|
666 Object root = getRoot();
|
|
667 IContentProvider contentProvider = getContentProvider();
|
|
668
|
|
669 // Invalidate for lazy
|
|
670 if (!(cast(ILazyContentProvider)contentProvider )
|
|
671 && cast(IStructuredContentProvider)contentProvider ) {
|
|
672 // Don't cache if the root is null but cache if it is not lazy.
|
|
673 if (root !is null) {
|
|
674 virtualManager.cachedElements = getSortedChildren(root);
|
|
675 doSetItemCount(virtualManager.cachedElements.length);
|
|
676 }
|
|
677 }
|
|
678 doClearAll();
|
|
679 }
|
|
680
|
|
681 /**
|
|
682 * Refresh all of the elements of the table. update the labels if
|
|
683 * updatLabels is true;
|
|
684 *
|
|
685 * @param updateLabels
|
|
686 *
|
|
687 * @since 3.1
|
|
688 */
|
|
689 private void internalRefreshAll(bool updateLabels) {
|
|
690 // the parent
|
|
691
|
|
692 // in the code below, it is important to do all disassociates
|
|
693 // before any associates, since a later disassociate can undo an
|
|
694 // earlier associate
|
|
695 // e.g. if (a, b) is replaced by (b, a), the disassociate of b to
|
|
696 // item 1 could undo
|
|
697 // the associate of b to item 0.
|
|
698
|
|
699 Object[] children = getSortedChildren(getRoot());
|
|
700 Item[] items = doGetItems();
|
|
701 int min = Math.min(children.length, items.length);
|
|
702 for (int i = 0; i < min; ++i) {
|
|
703
|
|
704 Item item = items[i];
|
|
705
|
|
706 // if the element is unchanged, update its label if appropriate
|
|
707 if (opEquals(children[i], item.getData())) {
|
|
708 if (updateLabels) {
|
|
709 updateItem(item, children[i]);
|
|
710 } else {
|
|
711 // associate the new element, even if equal to the old
|
|
712 // one,
|
|
713 // to remove stale references (see bug 31314)
|
|
714 associate(children[i], item);
|
|
715 }
|
|
716 } else {
|
|
717 // updateItem does an associate(...), which can mess up
|
|
718 // the associations if the order of elements has changed.
|
|
719 // E.g. (a, b) -> (b, a) first replaces a->0 with b->0, then
|
|
720 // replaces b->1 with a->1, but this actually removes b->0.
|
|
721 // So, if the object associated with this item has changed,
|
|
722 // just disassociate it for now, and update it below.
|
|
723 // we also need to reset the item (set its text,images etc. to
|
|
724 // default values) because the label decorators rely on this
|
|
725 disassociate(item);
|
|
726 doClear(i);
|
|
727 }
|
|
728 }
|
|
729 // dispose of all items beyond the end of the current elements
|
|
730 if (min < items.length) {
|
|
731 for (int i = items.length; --i >= min;) {
|
|
732
|
|
733 disassociate(items[i]);
|
|
734 }
|
|
735 if (virtualManager !is null) {
|
|
736 virtualManager.removeIndicesFromTo(min, items.length - 1);
|
|
737 }
|
|
738 doRemove(min, items.length - 1);
|
|
739 }
|
|
740 // Workaround for 1GDGN4Q: ITPUI:WIN2000 - TableViewer icons get
|
|
741 // scrunched
|
|
742 if (doGetItemCount() is 0) {
|
|
743 doRemoveAll();
|
|
744 }
|
|
745 // Update items which were disassociated above
|
|
746 for (int i = 0; i < min; ++i) {
|
|
747
|
|
748 Item item = items[i];
|
|
749 if (item.getData() is null) {
|
|
750 updateItem(item, children[i]);
|
|
751 }
|
|
752 }
|
|
753 // add any remaining elements
|
|
754 for (int i = min; i < children.length; ++i) {
|
|
755 createItem(children[i], i);
|
|
756 }
|
|
757 }
|
|
758
|
|
759 /**
|
|
760 * Removes the given elements from this table viewer.
|
|
761 *
|
|
762 * @param elements
|
|
763 * the elements to remove
|
|
764 */
|
|
765 private void internalRemove(Object[] elements) {
|
|
766 Object input = getInput();
|
|
767 for (int i = 0; i < elements.length; ++i) {
|
|
768 if (opEquals(elements[i], input)) {
|
|
769 bool oldBusy = busy;
|
|
770 busy = false;
|
|
771 try {
|
|
772 setInput(null);
|
|
773 } finally {
|
|
774 busy = oldBusy;
|
|
775 }
|
|
776 return;
|
|
777 }
|
|
778 }
|
|
779 // use remove(int[]) rather than repeated TableItem.dispose() calls
|
|
780 // to allow DWT to optimize multiple removals
|
|
781 int[] indices = new int[elements.length];
|
|
782 int count = 0;
|
|
783 for (int i = 0; i < elements.length; ++i) {
|
|
784 Widget w = findItem(elements[i]);
|
|
785 if (w is null && virtualManager !is null) {
|
|
786 int index = virtualManager.find(elements[i]);
|
|
787 if (index !is -1) {
|
|
788 indices[count++] = index;
|
|
789 }
|
|
790 } else if (auto item = cast(Item) w ) {
|
|
791 disassociate(item);
|
|
792 indices[count++] = doIndexOf(item);
|
|
793 }
|
|
794 }
|
|
795 if (count < indices.length) {
|
|
796 System.arraycopy(indices, 0, indices = new int[count], 0, count);
|
|
797 }
|
|
798 if (virtualManager !is null) {
|
|
799 virtualManager.removeIndices(indices);
|
|
800 }
|
|
801 doRemove(indices);
|
|
802
|
|
803 // Workaround for 1GDGN4Q: ITPUI:WIN2000 - TableViewer icons get
|
|
804 // scrunched
|
|
805 if (doGetItemCount() is 0) {
|
|
806 doRemoveAll();
|
|
807 }
|
|
808 }
|
|
809
|
|
810 /**
|
|
811 * Removes the given elements from this table viewer. The selection is
|
|
812 * updated if required.
|
|
813 * <p>
|
|
814 * This method should be called (by the content provider) when elements have
|
|
815 * been removed from the model, in order to cause the viewer to accurately
|
|
816 * reflect the model. This method only affects the viewer, not the model.
|
|
817 * </p>
|
|
818 *
|
|
819 * @param elements
|
|
820 * the elements to remove
|
|
821 */
|
|
822 public void remove( Object[] elements) {
|
|
823 assertElementsNotNull(elements);
|
|
824 if (isBusy())
|
|
825 return;
|
|
826 if (elements.length is 0) {
|
|
827 return;
|
|
828 }
|
|
829 preservingSelection(new class Runnable {
|
|
830 Object[] elements_;
|
|
831 this(){
|
|
832 elements_=elements;
|
|
833 }
|
|
834 public void run() {
|
|
835 internalRemove(elements_);
|
|
836 }
|
|
837 });
|
|
838 }
|
|
839
|
|
840 /**
|
|
841 * Removes the given element from this table viewer. The selection is
|
|
842 * updated if necessary.
|
|
843 * <p>
|
|
844 * This method should be called (by the content provider) when a single
|
|
845 * element has been removed from the model, in order to cause the viewer to
|
|
846 * accurately reflect the model. This method only affects the viewer, not
|
|
847 * the model. Note that there is another method for efficiently processing
|
|
848 * the simultaneous removal of multiple elements.
|
|
849 * </p>
|
|
850 * <strong>NOTE:</strong> removing an object from a virtual table will
|
|
851 * decrement the itemCount.
|
|
852 *
|
|
853 * @param element
|
|
854 * the element
|
|
855 */
|
|
856 public void remove(Object element) {
|
|
857 remove([ element ]);
|
|
858 }
|
|
859
|
|
860 /*
|
|
861 * (non-Javadoc)
|
|
862 *
|
|
863 * @see dwtx.jface.viewers.StructuredViewer#reveal(java.lang.Object)
|
|
864 */
|
|
865 public void reveal(Object element) {
|
|
866 Assert.isNotNull(element);
|
|
867 Widget w = findItem(element);
|
|
868 if (auto i = cast(Item)w ) {
|
|
869 doShowItem(i);
|
|
870 }
|
|
871 }
|
|
872
|
|
873 /*
|
|
874 * (non-Javadoc)
|
|
875 *
|
|
876 * @see dwtx.jface.viewers.StructuredViewer#setSelectionToWidget(java.util.List,
|
|
877 * bool)
|
|
878 */
|
|
879 protected void setSelectionToWidget(SeqView!(Object) list, bool reveal) {
|
|
880 if (list is null) {
|
|
881 doDeselectAll();
|
|
882 return;
|
|
883 }
|
|
884
|
|
885 if (virtualManager !is null) {
|
|
886 virtualSetSelectionToWidget(list, reveal);
|
|
887 return;
|
|
888 }
|
|
889
|
|
890 // This is vital to use doSetSelection because on DWT-Table on Win32 this will also
|
|
891 // move the focus to this row (See bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=198665)
|
|
892 if (reveal) {
|
|
893 int size = list.size();
|
|
894 Item[] items = new Item[size];
|
|
895 int count = 0;
|
|
896 foreach( o; list ) {
|
|
897 Widget w = findItem(o);
|
|
898 if (auto item = cast(Item)w ) {
|
|
899 items[count++] = item;
|
|
900 }
|
|
901 }
|
|
902 if (count < size) {
|
|
903 System.arraycopy(items, 0, items = new Item[count], 0, count);
|
|
904 }
|
|
905 doSetSelection(items);
|
|
906 } else {
|
|
907 doDeselectAll(); // Clear the selection
|
|
908 if( ! list.drained() ) {
|
|
909 int[] indices = new int[list.size()];
|
|
910
|
|
911 Item[] items = doGetItems();
|
|
912
|
|
913 int count = 0;
|
|
914 foreach( modelElement; list ){
|
|
915 bool found = false;
|
|
916 for (int i = 0; i < items.length && !found; i++) {
|
|
917 if (opEquals(modelElement, items[i].getData())) {
|
|
918 indices[count++] = i;
|
|
919 found = true;
|
|
920 }
|
|
921 }
|
|
922 }
|
|
923
|
|
924 if (count < indices.length) {
|
|
925 System.arraycopy(indices, 0, indices = new int[count], 0, count);
|
|
926 }
|
|
927
|
|
928 doSelect(indices);
|
|
929 }
|
|
930 }
|
|
931 }
|
|
932
|
|
933 /**
|
|
934 * Set the selection on a virtual table
|
|
935 *
|
|
936 * @param list
|
|
937 * The elements to set
|
|
938 * @param reveal
|
|
939 * Whether or not reveal the first item.
|
|
940 */
|
|
941 private void virtualSetSelectionToWidget(SeqView!(Object) list, bool reveal) {
|
|
942 int size = list.size();
|
|
943 int[] indices = new int[list.size()];
|
|
944
|
|
945 Item firstItem = null;
|
|
946 int count = 0;
|
|
947 auto virtualElements = new HashSet!(Object);
|
|
948 foreach( o; list ){
|
|
949 Widget w = findItem(o);
|
|
950 if (auto item = cast(Item)w ) {
|
|
951 indices[count++] = doIndexOf(item);
|
|
952 if (firstItem is null) {
|
|
953 firstItem = item;
|
|
954 }
|
|
955 } else {
|
|
956 virtualElements.add(o);
|
|
957 }
|
|
958 }
|
|
959
|
|
960 if ( auto provider = cast(ILazyContentProvider) getContentProvider() ) {
|
|
961
|
|
962 // Now go through it again until all is done or we are no longer
|
|
963 // virtual
|
|
964 // This may create all items so it is not a good
|
|
965 // idea in general.
|
|
966 // Use #setSelection (int [] indices,bool reveal) instead
|
|
967 for (int i = 0; virtualElements.size() > 0 && i < doGetItemCount(); i++) {
|
|
968 provider.updateElement(i);
|
|
969 Item item = doGetItem(i);
|
|
970 if (virtualElements.contains(item.getData())) {
|
|
971 indices[count++] = i;
|
|
972 virtualElements.remove(item.getData());
|
|
973 if (firstItem is null) {
|
|
974 firstItem = item;
|
|
975 }
|
|
976 }
|
|
977 }
|
|
978 } else {
|
|
979
|
|
980 if (count !is list.size()) {// As this is expensive skip it if all
|
|
981 // have been found
|
|
982 // If it is not lazy we can use the cache
|
|
983 for (int i = 0; i < virtualManager.cachedElements.length; i++) {
|
|
984 Object element = virtualManager.cachedElements[i];
|
|
985 if (virtualElements.contains(element)) {
|
|
986 Item item = doGetItem(i);
|
|
987 item.getText();// Be sure to fire the update
|
|
988 indices[count++] = i;
|
|
989 virtualElements.remove(element);
|
|
990 if (firstItem is null) {
|
|
991 firstItem = item;
|
|
992 }
|
|
993 }
|
|
994 }
|
|
995 }
|
|
996 }
|
|
997
|
|
998 if (count < size) {
|
|
999 System.arraycopy(indices, 0, indices = new int[count], 0, count);
|
|
1000 }
|
|
1001 doSetSelection(indices);
|
|
1002
|
|
1003 if (reveal && firstItem !is null) {
|
|
1004 doShowItem(firstItem);
|
|
1005 }
|
|
1006 }
|
|
1007
|
|
1008 /**
|
|
1009 * Set the item count of the receiver.
|
|
1010 *
|
|
1011 * @param count
|
|
1012 * the new table size.
|
|
1013 *
|
|
1014 * @since 3.1
|
|
1015 */
|
|
1016 public void setItemCount(int count) {
|
|
1017 if (isBusy())
|
|
1018 return;
|
|
1019 int oldCount = doGetItemCount();
|
|
1020 if (count < oldCount) {
|
|
1021 // need to disassociate elements that are being disposed
|
|
1022 for (int i = count; i < oldCount; i++) {
|
|
1023 Item item = doGetItem(i);
|
|
1024 if (item.getData() !is null) {
|
|
1025 disassociate(item);
|
|
1026 }
|
|
1027 }
|
|
1028 }
|
|
1029 doSetItemCount(count);
|
|
1030 if (virtualManager !is null) {
|
|
1031 virtualManager.adjustCacheSize(count);
|
|
1032 }
|
|
1033 getControl().redraw();
|
|
1034 }
|
|
1035
|
|
1036 /**
|
|
1037 * Replace the entries starting at index with elements. This method assumes
|
|
1038 * all of these values are correct and will not call the content provider to
|
|
1039 * verify. <strong>Note that this method will create a TableItem for all of
|
|
1040 * the elements provided</strong>.
|
|
1041 *
|
|
1042 * @param element
|
|
1043 * @param index
|
|
1044 * @see ILazyContentProvider
|
|
1045 *
|
|
1046 * @since 3.1
|
|
1047 */
|
|
1048 public void replace(Object element, int index) {
|
|
1049 if (isBusy())
|
|
1050 return;
|
|
1051 Item item = doGetItem(index);
|
|
1052 refreshItem(item, element);
|
|
1053 }
|
|
1054
|
|
1055 /**
|
|
1056 * Clear the table item at the specified index
|
|
1057 *
|
|
1058 * @param index
|
|
1059 * the index of the table item to be cleared
|
|
1060 *
|
|
1061 * @since 3.1
|
|
1062 */
|
|
1063 public void clear(int index) {
|
|
1064 Item item = doGetItem(index);
|
|
1065 if (item.getData() !is null) {
|
|
1066 disassociate(item);
|
|
1067 }
|
|
1068 doClear(index);
|
|
1069 }
|
|
1070
|
|
1071 /*
|
|
1072 * (non-Javadoc)
|
|
1073 *
|
|
1074 * @see dwtx.jface.viewers.StructuredViewer#getRawChildren(java.lang.Object)
|
|
1075 */
|
|
1076 protected Object[] getRawChildren(Object parent) {
|
|
1077
|
|
1078 Assert.isTrue(!( null !is cast(ILazyContentProvider) getContentProvider() ),
|
|
1079 "Cannot get raw children with an ILazyContentProvider");//$NON-NLS-1$
|
|
1080 return super.getRawChildren(parent);
|
|
1081
|
|
1082 }
|
|
1083
|
|
1084 /*
|
|
1085 * (non-Javadoc)
|
|
1086 *
|
|
1087 * @see dwtx.jface.viewers.StructuredViewer#assertContentProviderType(dwtx.jface.viewers.IContentProvider)
|
|
1088 */
|
|
1089 protected void assertContentProviderType(IContentProvider provider) {
|
|
1090 Assert.isTrue(null !is cast(IStructuredContentProvider)provider
|
|
1091 || null !is cast(ILazyContentProvider)provider );
|
|
1092 }
|
|
1093
|
|
1094 /**
|
|
1095 * Searches the receiver's list starting at the first item (index 0) until
|
|
1096 * an item is found that is equal to the argument, and returns the index of
|
|
1097 * that item. If no item is found, returns -1.
|
|
1098 *
|
|
1099 * @param item
|
|
1100 * the search item
|
|
1101 * @return the index of the item
|
|
1102 *
|
|
1103 * @since 3.3
|
|
1104 */
|
|
1105 protected abstract int doIndexOf(Item item);
|
|
1106
|
|
1107 /**
|
|
1108 * Returns the number of items contained in the receiver.
|
|
1109 *
|
|
1110 * @return the number of items
|
|
1111 *
|
|
1112 * @since 3.3
|
|
1113 */
|
|
1114 protected abstract int doGetItemCount();
|
|
1115
|
|
1116 /**
|
|
1117 * Sets the number of items contained in the receiver.
|
|
1118 *
|
|
1119 * @param count
|
|
1120 * the number of items
|
|
1121 *
|
|
1122 * @since 3.3
|
|
1123 */
|
|
1124 protected abstract void doSetItemCount(int count);
|
|
1125
|
|
1126 /**
|
|
1127 * Returns a (possibly empty) array of TableItems which are the items in the
|
|
1128 * receiver.
|
|
1129 *
|
|
1130 * @return the items in the receiver
|
|
1131 *
|
|
1132 * @since 3.3
|
|
1133 */
|
|
1134 protected abstract Item[] doGetItems();
|
|
1135
|
|
1136 /**
|
|
1137 * Returns the column at the given, zero-relative index in the receiver.
|
|
1138 * Throws an exception if the index is out of range. Columns are returned in
|
|
1139 * the order that they were created. If no TableColumns were created by the
|
|
1140 * programmer, this method will throw ERROR_INVALID_RANGE despite the fact
|
|
1141 * that a single column of data may be visible in the table. This occurs
|
|
1142 * when the programmer uses the table like a list, adding items but never
|
|
1143 * creating a column.
|
|
1144 *
|
|
1145 * @param index
|
|
1146 * the index of the column to return
|
|
1147 * @return the column at the given index
|
|
1148 * @exception IllegalArgumentException -
|
|
1149 * if the index is not between 0 and the number of elements
|
|
1150 * in the list minus 1 (inclusive)
|
|
1151 *
|
|
1152 * @since 3.3
|
|
1153 */
|
|
1154 protected abstract Widget doGetColumn(int index);
|
|
1155
|
|
1156 /**
|
|
1157 * Returns the item at the given, zero-relative index in the receiver.
|
|
1158 * Throws an exception if the index is out of range.
|
|
1159 *
|
|
1160 * @param index
|
|
1161 * the index of the item to return
|
|
1162 * @return the item at the given index
|
|
1163 * @exception IllegalArgumentException -
|
|
1164 * if the index is not between 0 and the number of elements
|
|
1165 * in the list minus 1 (inclusive)
|
|
1166 *
|
|
1167 * @since 3.3
|
|
1168 */
|
|
1169 protected abstract Item doGetItem(int index);
|
|
1170
|
|
1171 /**
|
|
1172 * Returns an array of {@link Item} that are currently selected in the
|
|
1173 * receiver. The order of the items is unspecified. An empty array indicates
|
|
1174 * that no items are selected.
|
|
1175 *
|
|
1176 * @return an array representing the selection
|
|
1177 *
|
|
1178 * @since 3.3
|
|
1179 */
|
|
1180 protected abstract Item[] doGetSelection();
|
|
1181
|
|
1182 /**
|
|
1183 * Returns the zero-relative indices of the items which are currently
|
|
1184 * selected in the receiver. The order of the indices is unspecified. The
|
|
1185 * array is empty if no items are selected.
|
|
1186 *
|
|
1187 * @return an array representing the selection
|
|
1188 *
|
|
1189 * @since 3.3
|
|
1190 */
|
|
1191 protected abstract int[] doGetSelectionIndices();
|
|
1192
|
|
1193 /**
|
|
1194 * Clears all the items in the receiver. The text, icon and other attributes
|
|
1195 * of the items are set to their default values. If the table was created
|
|
1196 * with the <code>DWT.VIRTUAL</code> style, these attributes are requested
|
|
1197 * again as needed.
|
|
1198 *
|
|
1199 * @since 3.3
|
|
1200 */
|
|
1201 protected abstract void doClearAll();
|
|
1202
|
|
1203 /**
|
|
1204 * Resets the given item in the receiver. The text, icon and other attributes
|
|
1205 * of the item are set to their default values.
|
|
1206 *
|
|
1207 * @param item the item to reset
|
|
1208 *
|
|
1209 * @since 3.3
|
|
1210 */
|
|
1211 protected abstract void doResetItem(Item item);
|
|
1212
|
|
1213 /**
|
|
1214 * Removes the items from the receiver which are between the given
|
|
1215 * zero-relative start and end indices (inclusive).
|
|
1216 *
|
|
1217 * @param start
|
|
1218 * the start of the range
|
|
1219 * @param end
|
|
1220 * the end of the range
|
|
1221 *
|
|
1222 * @exception IllegalArgumentException -
|
|
1223 * if either the start or end are not between 0 and the
|
|
1224 * number of elements in the list minus 1 (inclusive)
|
|
1225 *
|
|
1226 * @since 3.3
|
|
1227 */
|
|
1228 protected abstract void doRemove(int start, int end);
|
|
1229
|
|
1230 /**
|
|
1231 * Removes all of the items from the receiver.
|
|
1232 *
|
|
1233 * @since 3.3
|
|
1234 */
|
|
1235 protected abstract void doRemoveAll();
|
|
1236
|
|
1237 /**
|
|
1238 * Removes the items from the receiver's list at the given zero-relative
|
|
1239 * indices.
|
|
1240 *
|
|
1241 * @param indices
|
|
1242 * the array of indices of the items
|
|
1243 *
|
|
1244 * @exception IllegalArgumentException -
|
|
1245 * if the array is null, or if any of the indices is not
|
|
1246 * between 0 and the number of elements in the list minus 1
|
|
1247 * (inclusive)
|
|
1248 *
|
|
1249 * @since 3.3
|
|
1250 */
|
|
1251 protected abstract void doRemove(int[] indices);
|
|
1252
|
|
1253 /**
|
|
1254 * Shows the item. If the item is already showing in the receiver, this
|
|
1255 * method simply returns. Otherwise, the items are scrolled until the item
|
|
1256 * is visible.
|
|
1257 *
|
|
1258 * @param item
|
|
1259 * the item to be shown
|
|
1260 *
|
|
1261 * @exception IllegalArgumentException -
|
|
1262 * if the item is null
|
|
1263 *
|
|
1264 * @since 3.3
|
|
1265 */
|
|
1266 protected abstract void doShowItem(Item item);
|
|
1267
|
|
1268 /**
|
|
1269 * Deselects all selected items in the receiver.
|
|
1270 *
|
|
1271 * @since 3.3
|
|
1272 */
|
|
1273 protected abstract void doDeselectAll();
|
|
1274
|
|
1275 /**
|
|
1276 * Sets the receiver's selection to be the given array of items. The current
|
|
1277 * selection is cleared before the new items are selected.
|
|
1278 * <p>
|
|
1279 * Items that are not in the receiver are ignored. If the receiver is
|
|
1280 * single-select and multiple items are specified, then all items are
|
|
1281 * ignored.
|
|
1282 * </p>
|
|
1283 *
|
|
1284 * @param items
|
|
1285 * the array of items
|
|
1286 *
|
|
1287 * @exception IllegalArgumentException -
|
|
1288 * if the array of items is null
|
|
1289 *
|
|
1290 * @since 3.3
|
|
1291 */
|
|
1292 protected abstract void doSetSelection(Item[] items);
|
|
1293
|
|
1294 /**
|
|
1295 * Shows the selection. If the selection is already showing in the receiver,
|
|
1296 * this method simply returns. Otherwise, the items are scrolled until the
|
|
1297 * selection is visible.
|
|
1298 *
|
|
1299 * @since 3.3
|
|
1300 */
|
|
1301 protected abstract void doShowSelection();
|
|
1302
|
|
1303 /**
|
|
1304 * Selects the items at the given zero-relative indices in the receiver. The
|
|
1305 * current selection is cleared before the new items are selected.
|
|
1306 * <p>
|
|
1307 * Indices that are out of range and duplicate indices are ignored. If the
|
|
1308 * receiver is single-select and multiple indices are specified, then all
|
|
1309 * indices are ignored.
|
|
1310 * </p>
|
|
1311 *
|
|
1312 * @param indices
|
|
1313 * the indices of the items to select
|
|
1314 *
|
|
1315 * @exception IllegalArgumentException -
|
|
1316 * if the array of indices is null
|
|
1317 *
|
|
1318 * @since 3.3
|
|
1319 */
|
|
1320 protected abstract void doSetSelection(int[] indices);
|
|
1321
|
|
1322 /**
|
|
1323 * Clears the item at the given zero-relative index in the receiver. The
|
|
1324 * text, icon and other attributes of the item are set to the default value.
|
|
1325 * If the table was created with the <code>DWT.VIRTUAL</code> style, these
|
|
1326 * attributes are requested again as needed.
|
|
1327 *
|
|
1328 * @param index
|
|
1329 * the index of the item to clear
|
|
1330 *
|
|
1331 * @exception IllegalArgumentException -
|
|
1332 * if the index is not between 0 and the number of elements
|
|
1333 * in the list minus 1 (inclusive)
|
|
1334 *
|
|
1335 * @see DWT#VIRTUAL
|
|
1336 * @see DWT#SetData
|
|
1337 *
|
|
1338 * @since 3.3
|
|
1339 */
|
|
1340 protected abstract void doClear(int index);
|
|
1341
|
|
1342
|
|
1343
|
|
1344 /**
|
|
1345 * Selects the items at the given zero-relative indices in the receiver.
|
|
1346 * The current selection is not cleared before the new items are selected.
|
|
1347 * <p>
|
|
1348 * If the item at a given index is not selected, it is selected.
|
|
1349 * If the item at a given index was already selected, it remains selected.
|
|
1350 * Indices that are out of range and duplicate indices are ignored.
|
|
1351 * If the receiver is single-select and multiple indices are specified,
|
|
1352 * then all indices are ignored.
|
|
1353 * </p>
|
|
1354 *
|
|
1355 * @param indices the array of indices for the items to select
|
|
1356 *
|
|
1357 * @exception IllegalArgumentException - if the array of indices is null
|
|
1358 *
|
|
1359 */
|
|
1360 protected abstract void doSelect(int[] indices);
|
|
1361
|
|
1362 }
|