comparison org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewer.d @ 12:bc29606a740c

Added dwt-addons in original directory structure of eclipse.org
author Frank Benoit <benoit@tionex.de>
date Sat, 14 Mar 2009 18:23:29 +0100
parents
children
comparison
equal deleted inserted replaced
11:43904fec5dca 12:bc29606a740c
1 /*******************************************************************************
2 * Copyright (c) 2006, 2008 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 153993
11 * fix in bug 163317, 151295, 167323, 167858, 184346, 187826, 201905
12 * Port to the D programming language:
13 * Frank Benoit <benoit@tionex.de>
14 *******************************************************************************/
15
16 module org.eclipse.jface.viewers.ColumnViewer;
17
18 import org.eclipse.jface.viewers.StructuredViewer;
19 import org.eclipse.jface.viewers.CellEditor;
20 import org.eclipse.jface.viewers.ICellModifier;
21 import org.eclipse.jface.viewers.ColumnViewerEditor;
22 import org.eclipse.jface.viewers.ViewerCell;
23 import org.eclipse.jface.viewers.ViewerRow;
24 import org.eclipse.jface.viewers.ViewerColumn;
25 import org.eclipse.jface.viewers.CellLabelProvider;
26 import org.eclipse.jface.viewers.IBaseLabelProvider;
27 import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;
28 import org.eclipse.jface.viewers.EditingSupport;
29 import org.eclipse.jface.viewers.ITableLabelProvider;
30 import org.eclipse.jface.viewers.ILabelProvider;
31 import org.eclipse.jface.viewers.StructuredSelection;
32 import org.eclipse.swt.events.MouseAdapter;
33 import org.eclipse.swt.events.MouseEvent;
34 import org.eclipse.swt.graphics.Point;
35 import org.eclipse.swt.widgets.Control;
36 import org.eclipse.swt.widgets.Item;
37 import org.eclipse.swt.widgets.Widget;
38 import org.eclipse.core.runtime.Assert;
39 import org.eclipse.core.runtime.IStatus;
40 import org.eclipse.core.runtime.Status;
41 import org.eclipse.jface.internal.InternalPolicy;
42 import org.eclipse.jface.util.Policy;
43
44 import java.lang.all;
45 import java.util.Set;
46
47 /**
48 * The ColumnViewer is the abstract superclass of viewers that have columns
49 * (e.g., AbstractTreeViewer and AbstractTableViewer). Concrete subclasses of
50 * {@link ColumnViewer} should implement a matching concrete subclass of {@link
51 * ViewerColumn}.
52 *
53 * <strong> This class is not intended to be subclassed outside of the JFace
54 * viewers framework.</strong>
55 *
56 * @since 3.3
57 *
58 */
59 public abstract class ColumnViewer : StructuredViewer {
60 alias StructuredViewer.getLabelProvider getLabelProvider;
61 alias StructuredViewer.refresh refresh;
62 alias StructuredViewer.update update;
63
64 private CellEditor[] cellEditors;
65
66 private ICellModifier cellModifier;
67
68 private String[] columnProperties;
69
70 /**
71 * The cell is a cached viewer cell used for refreshing.
72 */
73 private ViewerCell cell;
74
75 private ColumnViewerEditor viewerEditor;
76
77 private bool busy;
78 private bool logWhenBusy = true; // initially true, set to false
79
80 // after logging for the first
81 // time
82
83 /**
84 * Create a new instance of the receiver.
85 */
86 public this() {
87 cell = new ViewerCell(null, 0, null);
88 }
89
90 protected override void hookControl(Control control) {
91 super.hookControl(control);
92 viewerEditor = createViewerEditor();
93 hookEditingSupport(control);
94 }
95
96 /**
97 * Hook up the editing support. Subclasses may override.
98 *
99 * @param control
100 * the control you want to hook on
101 */
102 protected void hookEditingSupport(Control control) {
103 // Needed for backwards comp with AbstractTreeViewer and TableTreeViewer
104 // who are not hooked this way others may already overwrite and provide
105 // their
106 // own impl
107 if (viewerEditor !is null) {
108 control.addMouseListener(new class MouseAdapter {
109 public void mouseDown(MouseEvent e) {
110 // Workaround for bug 185817
111 if (e.count !is 2) {
112 handleMouseDown(e);
113 }
114 }
115
116 public void mouseDoubleClick(MouseEvent e) {
117 handleMouseDown(e);
118 }
119 });
120 }
121 }
122
123 /**
124 * Creates the viewer editor used for editing cell contents. To be
125 * implemented by subclasses.
126 *
127 * @return the editor, or <code>null</code> if this viewer does not support
128 * editing cell contents.
129 */
130 protected abstract ColumnViewerEditor createViewerEditor();
131
132 /**
133 * Returns the viewer cell at the given widget-relative coordinates, or
134 * <code>null</code> if there is no cell at that location
135 *
136 * @param point
137 * the widget-relative coordinates
138 * @return the cell or <code>null</code> if no cell is found at the given
139 * point
140 *
141 * @since 3.4
142 */
143 public ViewerCell getCell(Point point) {
144 ViewerRow row = getViewerRow(point);
145 if (row !is null) {
146 return row.getCell(point);
147 }
148
149 return null;
150 }
151
152 /**
153 * Returns the viewer row at the given widget-relative coordinates.
154 *
155 * @param point
156 * the widget-relative coordinates of the viewer row
157 * @return ViewerRow the row or <code>null</code> if no row is found at the
158 * given coordinates
159 */
160 protected ViewerRow getViewerRow(Point point) {
161 Item item = getItemAt(point);
162
163 if (item !is null) {
164 return getViewerRowFromItem(item);
165 }
166
167 return null;
168 }
169 package ViewerRow getViewerRow_package(Point point) {
170 return getViewerRow(point);
171 }
172
173 /**
174 * Returns a {@link ViewerRow} associated with the given row widget.
175 * Implementations may re-use the same instance for different row widgets;
176 * callers can only use the viewer row locally and until the next call to
177 * this method.
178 *
179 * @param item
180 * the row widget
181 * @return ViewerRow a viewer row object
182 */
183 protected abstract ViewerRow getViewerRowFromItem(Widget item);
184 package ViewerRow getViewerRowFromItem_package(Widget item){
185 return getViewerRowFromItem(item);
186 }
187
188 /**
189 * Returns the column widget at the given column index.
190 *
191 * @param columnIndex
192 * the column index
193 * @return Widget the column widget
194 */
195 protected abstract Widget getColumnViewerOwner(int columnIndex);
196
197 /**
198 * Returns the viewer column for the given column index.
199 *
200 * @param columnIndex
201 * the column index
202 * @return the viewer column at the given index, or <code>null</code> if
203 * there is none for the given index
204 */
205 /* package */ViewerColumn getViewerColumn(int columnIndex) {
206
207 ViewerColumn viewer;
208 Widget columnOwner = getColumnViewerOwner(columnIndex);
209
210 if (columnOwner is null || columnOwner.isDisposed()) {
211 return null;
212 }
213
214 viewer = cast(ViewerColumn) columnOwner.getData(ViewerColumn.COLUMN_VIEWER_KEY);
215
216 if (viewer is null) {
217 viewer = createViewerColumn(columnOwner, CellLabelProvider
218 .createViewerLabelProvider(this, getLabelProvider()));
219 setupEditingSupport(columnIndex, viewer);
220 }
221
222 if (viewer.getEditingSupport() is null && getCellModifier() !is null) {
223 setupEditingSupport(columnIndex, viewer);
224 }
225
226 return viewer;
227 }
228
229 /**
230 * Sets up editing support for the given column based on the "old" cell
231 * editor API.
232 *
233 * @param columnIndex
234 * @param viewer
235 */
236 private void setupEditingSupport(int columnIndex, ViewerColumn viewer) {
237 if (getCellModifier() !is null) {
238 viewer.setEditingSupport(new class(this,columnIndex) EditingSupport {
239 int columnIndex_;
240 this(ColumnViewer cv, int ci){
241 super(cv);
242 columnIndex_=ci;
243 }
244 /*
245 * (non-Javadoc)
246 *
247 * @see
248 * org.eclipse.jface.viewers.EditingSupport#canEdit(java.lang
249 * .Object)
250 */
251 public bool canEdit(Object element) {
252 Object[] properties = getColumnProperties();
253
254 if (columnIndex_ < properties.length ) {
255 return getCellModifier().canModify(element,
256 (cast(ArrayWrapperString) getColumnProperties()[columnIndex_]).array);
257 }
258
259 return false;
260 }
261
262 /*
263 * (non-Javadoc)
264 *
265 * @see
266 * org.eclipse.jface.viewers.EditingSupport#getCellEditor(java
267 * .lang.Object)
268 */
269 public CellEditor getCellEditor(Object element) {
270 CellEditor[] editors = getCellEditors();
271 if (columnIndex_ < editors.length ) {
272 return getCellEditors()[columnIndex_];
273 }
274 return null;
275 }
276
277 /*
278 * (non-Javadoc)
279 *
280 * @see
281 * org.eclipse.jface.viewers.EditingSupport#getValue(java.lang
282 * .Object)
283 */
284 public Object getValue(Object element) {
285 Object[] properties = getColumnProperties();
286
287 if (columnIndex_ < properties.length) {
288 return getCellModifier().getValue(element,
289 (cast(ArrayWrapperString) getColumnProperties()[columnIndex_]).array);
290 }
291
292 return null;
293 }
294
295 /*
296 * (non-Javadoc)
297 *
298 * @see
299 * org.eclipse.jface.viewers.EditingSupport#setValue(java.lang
300 * .Object, java.lang.Object)
301 */
302 public void setValue(Object element, Object value) {
303 Object[] properties = getColumnProperties();
304
305 if (columnIndex_ < properties.length) {
306 getCellModifier().modify(findItem(element),
307 (cast(ArrayWrapperString) getColumnProperties()[columnIndex_]).array,
308 value);
309 }
310 }
311
312 bool isLegacySupport() {
313 return true;
314 }
315 });
316 }
317 }
318
319 /**
320 * Creates a generic viewer column for the given column widget, based on the
321 * given label provider.
322 *
323 * @param columnOwner
324 * the column widget
325 * @param labelProvider
326 * the label provider to use for the column
327 * @return ViewerColumn the viewer column
328 */
329 private ViewerColumn createViewerColumn(Widget columnOwner,
330 CellLabelProvider labelProvider) {
331 ViewerColumn column = new class(this, columnOwner) ViewerColumn {
332 this( ColumnViewer cv, Widget co ){
333 super(cv,co);
334 }
335 };
336 column.setLabelProvider(labelProvider, false);
337 return column;
338 }
339
340 /**
341 * Update the cached cell object with the given row and column.
342 *
343 * @param rowItem
344 * @param column
345 * @return ViewerCell
346 */
347 /* package */ViewerCell updateCell(ViewerRow rowItem, int column,
348 Object element) {
349 cell.update(rowItem, column, element);
350 return cell;
351 }
352
353 /**
354 * Returns the {@link Item} at the given widget-relative coordinates, or
355 * <code>null</code> if there is no item at the given coordinates.
356 *
357 * @param point
358 * the widget-relative coordinates
359 * @return the {@link Item} at the coordinates or <code>null</code> if there
360 * is no item at the given coordinates
361 */
362 protected abstract Item getItemAt(Point point);
363
364 /*
365 * (non-Javadoc)
366 *
367 * @see org.eclipse.jface.viewers.StructuredViewer#getItem(int, int)
368 */
369 protected override Item getItem(int x, int y) {
370 return getItemAt(getControl().toControl(x, y));
371 }
372
373 /**
374 * The column viewer implementation of this <code>Viewer</code> framework
375 * method ensures that the given label provider is an instance of
376 * <code>ITableLabelProvider</code>, <code>ILabelProvider</code>, or
377 * <code>CellLabelProvider</code>.
378 * <p>
379 * If the label provider is an {@link ITableLabelProvider} , then it
380 * provides a separate label text and image for each column. Implementers of
381 * <code>ITableLabelProvider</code> may also implement {@link
382 * ITableColorProvider} and/or {@link ITableFontProvider} to provide colors
383 * and/or fonts.
384 * </p>
385 * <p>
386 * If the label provider is an <code>ILabelProvider</code> , then it
387 * provides only the label text and image for the first column, and any
388 * remaining columns are blank. Implementers of <code>ILabelProvider</code>
389 * may also implement {@link IColorProvider} and/or {@link IFontProvider} to
390 * provide colors and/or fonts.
391 * </p>
392 *
393 */
394 public override void setLabelProvider(IBaseLabelProvider labelProvider) {
395 Assert.isTrue( null !is cast(ITableLabelProvider)labelProvider
396 || null !is cast(ILabelProvider)labelProvider
397 || null !is cast(CellLabelProvider)labelProvider );
398 updateColumnParts(labelProvider);// Reset the label providers in the
399 // columns
400 super.setLabelProvider(labelProvider);
401 if ( null !is cast(CellLabelProvider)labelProvider ) {
402 (cast(CellLabelProvider) labelProvider).initialize_package(this, null);
403 }
404 }
405
406 void internalDisposeLabelProvider(IBaseLabelProvider oldProvider) {
407 if (null !is cast(CellLabelProvider)oldProvider ) {
408 (cast(CellLabelProvider) oldProvider).dispose(this, null);
409 } else {
410 super.internalDisposeLabelProvider(oldProvider);
411 }
412 }
413
414 /**
415 * Clear the viewer parts for the columns
416 */
417 private void updateColumnParts(IBaseLabelProvider labelProvider) {
418 ViewerColumn column;
419 int i = 0;
420
421 while ((column = getViewerColumn(i++)) !is null) {
422 column.setLabelProvider(CellLabelProvider
423 .createViewerLabelProvider(this, labelProvider), false);
424 }
425 }
426
427 /**
428 * Cancels a currently active cell editor if one is active. All changes
429 * already done in the cell editor are lost.
430 *
431 * @since 3.1 (in subclasses, added in 3.3 to abstract class)
432 */
433 public void cancelEditing() {
434 if (viewerEditor !is null) {
435 viewerEditor.cancelEditing();
436 }
437 }
438
439 /**
440 * Apply the value of the active cell editor if one is active.
441 *
442 * @since 3.3
443 */
444 protected void applyEditorValue() {
445 if (viewerEditor !is null) {
446 viewerEditor.applyEditorValue();
447 }
448 }
449
450 /**
451 * Starts editing the given element at the given column index.
452 *
453 * @param element
454 * the model element
455 * @param column
456 * the column index
457 * @since 3.1 (in subclasses, added in 3.3 to abstract class)
458 */
459 public void editElement(Object element, int column) {
460 if (viewerEditor !is null) {
461 try {
462 getControl().setRedraw(false);
463 // Set the selection at first because in Tree's
464 // the element might not be materialized
465 setSelection(new StructuredSelection(element), true);
466
467 Widget item = findItem(element);
468 if (item !is null) {
469 ViewerRow row = getViewerRowFromItem(item);
470 if (row !is null) {
471 ViewerCell cell = row.getCell(column);
472 if (cell !is null) {
473 triggerEditorActivationEvent(new ColumnViewerEditorActivationEvent(
474 cell));
475 }
476 }
477 }
478 } finally {
479 getControl().setRedraw(true);
480 }
481 }
482 }
483
484 /**
485 * Return the CellEditors for the receiver, or <code>null</code> if no cell
486 * editors are set.
487 * <p>
488 * Since 3.3, an alternative API is available, see {@link
489 * ViewerColumn#setEditingSupport(EditingSupport)} for a more flexible way
490 * of editing values in a column viewer.
491 * </p>
492 *
493 *
494 * @return CellEditor[]
495 * @since 3.1 (in subclasses, added in 3.3 to abstract class)
496 * @see ViewerColumn#setEditingSupport(EditingSupport)
497 * @see EditingSupport
498 */
499 public CellEditor[] getCellEditors() {
500 return cellEditors;
501 }
502
503 /**
504 * Returns the cell modifier of this viewer, or <code>null</code> if none
505 * has been set.
506 *
507 * <p>
508 * Since 3.3, an alternative API is available, see {@link
509 * ViewerColumn#setEditingSupport(EditingSupport)} for a more flexible way
510 * of editing values in a column viewer.
511 * </p>
512 *
513 * @return the cell modifier, or <code>null</code>
514 * @since 3.1 (in subclasses, added in 3.3 to abstract class)
515 * @see ViewerColumn#setEditingSupport(EditingSupport)
516 * @see EditingSupport
517 */
518 public ICellModifier getCellModifier() {
519 return cellModifier;
520 }
521
522 /**
523 * Returns the column properties of this table viewer. The properties must
524 * correspond with the columns of the table control. They are used to
525 * identify the column in a cell modifier.
526 *
527 * <p>
528 * Since 3.3, an alternative API is available, see {@link
529 * ViewerColumn#setEditingSupport(EditingSupport)} for a more flexible way
530 * of editing values in a column viewer.
531 * </p>
532 *
533 * @return the list of column properties
534 * @since 3.1 (in subclasses, added in 3.3 to abstract class)
535 * @see ViewerColumn#setEditingSupport(EditingSupport)
536 * @see EditingSupport
537 */
538 public Object[] getColumnProperties() {
539 Object[] res;
540 foreach( prop; columnProperties ){
541 res ~= new ArrayWrapperString( prop );
542 }
543 return res;
544 }
545
546 /**
547 * Returns whether there is an active cell editor.
548 *
549 * <p>
550 * Since 3.3, an alternative API is available, see {@link
551 * ViewerColumn#setEditingSupport(EditingSupport)} for a more flexible way
552 * of editing values in a column viewer.
553 * </p>
554 *
555 * @return <code>true</code> if there is an active cell editor, and
556 * <code>false</code> otherwise
557 * @since 3.1 (in subclasses, added in 3.3 to abstract class)
558 * @see ViewerColumn#setEditingSupport(EditingSupport)
559 * @see EditingSupport
560 */
561 public bool isCellEditorActive() {
562 if (viewerEditor !is null) {
563 return viewerEditor.isCellEditorActive();
564 }
565 return false;
566 }
567
568 public override void refresh(Object element) {
569 if (checkBusy())
570 return;
571
572 if (isCellEditorActive()) {
573 cancelEditing();
574 }
575
576 super.refresh(element);
577 }
578
579 public override void refresh(Object element, bool updateLabels) {
580 if (checkBusy())
581 return;
582
583 if (isCellEditorActive()) {
584 cancelEditing();
585 }
586
587 super.refresh(element, updateLabels);
588 }
589
590 public override void update(Object element, String[] properties) {
591 if (checkBusy())
592 return;
593 super.update(element, properties);
594 }
595
596 /**
597 * Sets the cell editors of this column viewer. If editing is not supported
598 * by this viewer the call simply has no effect.
599 *
600 * <p>
601 * Since 3.3, an alternative API is available, see {@link
602 * ViewerColumn#setEditingSupport(EditingSupport)} for a more flexible way
603 * of editing values in a column viewer.
604 * </p>
605 * <p>
606 * Users setting up an editable {@link TreeViewer} or {@link TableViewer} with more than 1 column <b>have</b>
607 * to pass the SWT.FULL_SELECTION style bit
608 * </p>
609 * @param editors
610 * the list of cell editors
611 * @since 3.1 (in subclasses, added in 3.3 to abstract class)
612 * @see ViewerColumn#setEditingSupport(EditingSupport)
613 * @see EditingSupport
614 */
615 public void setCellEditors(CellEditor[] editors) {
616 this.cellEditors = editors;
617 }
618
619 /**
620 * Sets the cell modifier for this column viewer. This method does nothing
621 * if editing is not supported by this viewer.
622 *
623 * <p>
624 * Since 3.3, an alternative API is available, see {@link
625 * ViewerColumn#setEditingSupport(EditingSupport)} for a more flexible way
626 * of editing values in a column viewer.
627 * </p>
628 * <p>
629 * Users setting up an editable {@link TreeViewer} or {@link TableViewer} with more than 1 column <b>have</b>
630 * to pass the SWT.FULL_SELECTION style bit
631 * </p>
632 * @param modifier
633 * the cell modifier
634 * @since 3.1 (in subclasses, added in 3.3 to abstract class)
635 * @see ViewerColumn#setEditingSupport(EditingSupport)
636 * @see EditingSupport
637 */
638 public void setCellModifier(ICellModifier modifier) {
639 this.cellModifier = modifier;
640 }
641
642 /**
643 * Sets the column properties of this column viewer. The properties must
644 * correspond with the columns of the control. They are used to identify the
645 * column in a cell modifier. If editing is not supported by this viewer the
646 * call simply has no effect.
647 *
648 * <p>
649 * Since 3.3, an alternative API is available, see {@link
650 * ViewerColumn#setEditingSupport(EditingSupport)} for a more flexible way
651 * of editing values in a column viewer.
652 * </p>
653 * <p>
654 * Users setting up an editable {@link TreeViewer} or {@link TableViewer} with more than 1 column <b>have</b>
655 * to pass the SWT.FULL_SELECTION style bit
656 * </p>
657 * @param columnProperties
658 * the list of column properties
659 * @since 3.1 (in subclasses, added in 3.3 to abstract class)
660 * @see ViewerColumn#setEditingSupport(EditingSupport)
661 * @see EditingSupport
662 */
663 public void setColumnProperties(String[] columnProperties) {
664 this.columnProperties = columnProperties;
665 }
666
667 /**
668 * Returns the number of columns contained in the receiver. If no columns
669 * were created by the programmer, this value is zero, despite the fact that
670 * visually, one column of items may be visible. This occurs when the
671 * programmer uses the column viewer like a list, adding elements but never
672 * creating a column.
673 *
674 * @return the number of columns
675 *
676 * @since 3.3
677 */
678 protected abstract int doGetColumnCount();
679 package int doGetColumnCount_package(){
680 return doGetColumnCount();
681 }
682
683 /**
684 * Returns the label provider associated with the column at the given index
685 * or <code>null</code> if no column with this index is known.
686 *
687 * @param columnIndex
688 * the column index
689 * @return the label provider associated with the column or
690 * <code>null</code> if no column with this index is known
691 *
692 * @since 3.3
693 */
694 public CellLabelProvider getLabelProvider(int columnIndex) {
695 ViewerColumn column = getViewerColumn(columnIndex);
696 if (column !is null) {
697 auto res = column.getLabelProvider();
698 return res;
699 }
700 return null;
701 }
702
703 private void handleMouseDown(MouseEvent e) {
704 ViewerCell cell = getCell(new Point(e.x, e.y));
705
706 if (cell !is null) {
707 triggerEditorActivationEvent(new ColumnViewerEditorActivationEvent(
708 cell, e));
709 }
710 }
711
712 /**
713 * Invoking this method fires an editor activation event which tries to
714 * enable the editor but before this event is passed to {@link
715 * ColumnViewerEditorActivationStrategy} to see if this event should really
716 * trigger editor activation
717 *
718 * @param event
719 * the activation event
720 */
721 protected void triggerEditorActivationEvent(
722 ColumnViewerEditorActivationEvent event) {
723 viewerEditor.handleEditorActivationEvent(event);
724 }
725 package void triggerEditorActivationEvent_package(
726 ColumnViewerEditorActivationEvent event) {
727 triggerEditorActivationEvent(event);
728 }
729
730 /**
731 * @param columnViewerEditor
732 * the new column viewer editor
733 */
734 public void setColumnViewerEditor(ColumnViewerEditor columnViewerEditor) {
735 Assert.isNotNull(columnViewerEditor);
736 this.viewerEditor = columnViewerEditor;
737 }
738
739 /**
740 * @return the currently attached viewer editor
741 */
742 public ColumnViewerEditor getColumnViewerEditor() {
743 return viewerEditor;
744 }
745
746 protected override Object[] getRawChildren(Object parent) {
747 bool oldBusy = isBusy();
748 setBusy(true);
749 try {
750 return super.getRawChildren(parent);
751 } finally {
752 setBusy(oldBusy);
753 }
754 }
755
756 void clearLegacyEditingSetup() {
757 if (!getControl().isDisposed() && getCellEditors() !is null) {
758 int count = doGetColumnCount();
759
760 for (int i = 0; i < count || i is 0; i++) {
761 Widget owner = getColumnViewerOwner(i);
762 if (owner !is null && !owner.isDisposed()) {
763 ViewerColumn column = cast(ViewerColumn) owner
764 .getData(ViewerColumn.COLUMN_VIEWER_KEY);
765 if (column !is null) {
766 EditingSupport e = column.getEditingSupport();
767 // Ensure that only EditingSupports are wiped that are
768 // setup
769 // for Legacy reasons
770 if (e !is null && e.isLegacySupport()) {
771 column.setEditingSupport(null);
772 }
773 }
774 }
775 }
776 }
777 }
778
779 /**
780 * Checks if this viewer is currently busy, logging a warning and returning
781 * <code>true</code> if it is busy. A column viewer is busy when it is
782 * processing a refresh, add, remove, insert, replace, setItemCount,
783 * expandToLevel, update, setExpandedElements, or similar method that may
784 * make calls to client code. Column viewers are not designed to handle
785 * reentrant calls while they are busy. The method returns <code>true</code>
786 * if the viewer is busy. It is recommended that this method be used by
787 * subclasses to determine whether the viewer is busy to return early from
788 * state-changing methods.
789 *
790 * <p>
791 * This method is not intended to be overridden by subclasses.
792 * </p>
793 *
794 * @return <code>true</code> if the viewer is busy.
795 *
796 * @since 3.4
797 */
798 protected bool checkBusy() {
799 if (isBusy()) {
800 if (logWhenBusy) {
801 String message = "Ignored reentrant call while viewer is busy."; //$NON-NLS-1$
802 if (!InternalPolicy.DEBUG_LOG_REENTRANT_VIEWER_CALLS) {
803 // stop logging after the first
804 logWhenBusy = false;
805 message ~= " This is only logged once per viewer instance," ~ //$NON-NLS-1$
806 " but similar calls will still be ignored."; //$NON-NLS-1$
807 }
808 Policy.getLog().log(
809 new Status(IStatus.WARNING, Policy.JFACE, message,
810 new RuntimeException()));
811 }
812 return true;
813 }
814 return false;
815 }
816
817 /**
818 * Sets the busy state of this viewer. Subclasses MUST use <code>try</code>
819 * ...<code>finally</code> as follows to ensure that the busy flag is reset
820 * to its original value:
821 *
822 * <pre>
823 * bool oldBusy = isBusy();
824 * setBusy(true);
825 * try {
826 * // do work
827 * } finally {
828 * setBusy(oldBusy);
829 * }
830 * </pre>
831 *
832 * <p>
833 * This method is not intended to be overridden by subclasses.
834 * </p>
835 *
836 * @param busy
837 * the new value of the busy flag
838 *
839 * @since 3.4
840 */
841 protected void setBusy(bool busy) {
842 this.busy = busy;
843 }
844
845 /**
846 * Returns <code>true</code> if this viewer is currently busy processing a
847 * refresh, add, remove, insert, replace, setItemCount, expandToLevel,
848 * update, setExpandedElements, or similar method that may make calls to
849 * client code. Column viewers are not designed to handle reentrant calls
850 * while they are busy. It is recommended that clients avoid using this
851 * method if they can ensure by other means that they will not make
852 * reentrant calls to methods like the ones listed above. See bug 184991 for
853 * background discussion.
854 *
855 * <p>
856 * This method is not intended to be overridden by subclasses.
857 * </p>
858 *
859 * @return Returns whether this viewer is busy.
860 *
861 * @since 3.4
862 */
863 public bool isBusy() {
864 return busy;
865 }
866 }