3 * Copyright (C) 2017 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
10 package eu
.etaxonomy
.taxeditor
.ui
.dialog
.selection
;
14 import java
.util
.ArrayList
;
15 import java
.util
.Collections
;
16 import java
.util
.List
;
18 import org
.eclipse
.core
.commands
.AbstractHandler
;
19 import org
.eclipse
.core
.commands
.ExecutionEvent
;
20 import org
.eclipse
.core
.commands
.IHandler
;
21 import org
.eclipse
.core
.runtime
.Assert
;
22 import org
.eclipse
.core
.runtime
.CoreException
;
23 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
24 import org
.eclipse
.core
.runtime
.IStatus
;
25 import org
.eclipse
.core
.runtime
.ListenerList
;
26 import org
.eclipse
.core
.runtime
.Status
;
27 import org
.eclipse
.core
.runtime
.jobs
.Job
;
28 import org
.eclipse
.jface
.action
.IMenuManager
;
29 import org
.eclipse
.jface
.action
.LegacyActionTools
;
30 import org
.eclipse
.jface
.action
.MenuManager
;
31 import org
.eclipse
.jface
.dialogs
.Dialog
;
32 import org
.eclipse
.jface
.viewers
.DelegatingStyledCellLabelProvider
.IStyledLabelProvider
;
33 import org
.eclipse
.jface
.viewers
.DoubleClickEvent
;
34 import org
.eclipse
.jface
.viewers
.IColorProvider
;
35 import org
.eclipse
.jface
.viewers
.IDoubleClickListener
;
36 import org
.eclipse
.jface
.viewers
.IFontProvider
;
37 import org
.eclipse
.jface
.viewers
.ILabelDecorator
;
38 import org
.eclipse
.jface
.viewers
.ILabelProvider
;
39 import org
.eclipse
.jface
.viewers
.ILabelProviderListener
;
40 import org
.eclipse
.jface
.viewers
.ILazyContentProvider
;
41 import org
.eclipse
.jface
.viewers
.ISelectionChangedListener
;
42 import org
.eclipse
.jface
.viewers
.IStructuredContentProvider
;
43 import org
.eclipse
.jface
.viewers
.LabelProvider
;
44 import org
.eclipse
.jface
.viewers
.LabelProviderChangedEvent
;
45 import org
.eclipse
.jface
.viewers
.SelectionChangedEvent
;
46 import org
.eclipse
.jface
.viewers
.StructuredSelection
;
47 import org
.eclipse
.jface
.viewers
.StyledCellLabelProvider
;
48 import org
.eclipse
.jface
.viewers
.StyledString
;
49 import org
.eclipse
.jface
.viewers
.TableViewer
;
50 import org
.eclipse
.jface
.viewers
.Viewer
;
51 import org
.eclipse
.jface
.viewers
.ViewerCell
;
52 import org
.eclipse
.swt
.SWT
;
53 import org
.eclipse
.swt
.accessibility
.AccessibleAdapter
;
54 import org
.eclipse
.swt
.accessibility
.AccessibleEvent
;
55 import org
.eclipse
.swt
.events
.ModifyEvent
;
56 import org
.eclipse
.swt
.events
.ModifyListener
;
57 import org
.eclipse
.swt
.events
.MouseAdapter
;
58 import org
.eclipse
.swt
.events
.MouseEvent
;
59 import org
.eclipse
.swt
.events
.SelectionAdapter
;
60 import org
.eclipse
.swt
.events
.SelectionEvent
;
61 import org
.eclipse
.swt
.events
.TraverseEvent
;
62 import org
.eclipse
.swt
.events
.TraverseListener
;
63 import org
.eclipse
.swt
.graphics
.Color
;
64 import org
.eclipse
.swt
.graphics
.Font
;
65 import org
.eclipse
.swt
.graphics
.GC
;
66 import org
.eclipse
.swt
.graphics
.Point
;
67 import org
.eclipse
.swt
.graphics
.Rectangle
;
68 import org
.eclipse
.swt
.layout
.GridData
;
69 import org
.eclipse
.swt
.layout
.GridLayout
;
70 import org
.eclipse
.swt
.widgets
.Composite
;
71 import org
.eclipse
.swt
.widgets
.Control
;
72 import org
.eclipse
.swt
.widgets
.Display
;
73 import org
.eclipse
.swt
.widgets
.Event
;
74 import org
.eclipse
.swt
.widgets
.Label
;
75 import org
.eclipse
.swt
.widgets
.Menu
;
76 import org
.eclipse
.swt
.widgets
.Shell
;
77 import org
.eclipse
.swt
.widgets
.Table
;
78 import org
.eclipse
.swt
.widgets
.Text
;
79 import org
.eclipse
.swt
.widgets
.ToolBar
;
80 import org
.eclipse
.swt
.widgets
.ToolItem
;
81 import org
.eclipse
.ui
.IWorkbenchPreferenceConstants
;
82 import org
.eclipse
.ui
.PlatformUI
;
83 import org
.eclipse
.ui
.dialogs
.FilteredItemsSelectionDialog
;
84 import org
.eclipse
.ui
.handlers
.IHandlerService
;
85 import org
.eclipse
.ui
.internal
.IWorkbenchGraphicConstants
;
86 import org
.eclipse
.ui
.internal
.WorkbenchImages
;
87 import org
.eclipse
.ui
.internal
.WorkbenchMessages
;
88 import org
.eclipse
.ui
.internal
.WorkbenchPlugin
;
89 import org
.eclipse
.ui
.progress
.UIJob
;
91 import eu
.etaxonomy
.cdm
.api
.conversation
.IConversationEnabled
;
92 import eu
.etaxonomy
.cdm
.model
.common
.ICdmBase
;
93 import eu
.etaxonomy
.taxeditor
.l10n
.Messages
;
94 import eu
.etaxonomy
.taxeditor
.ui
.dialog
.selection
.CdmFilteredItemsSelectionDialog
.ItemsListSeparator
;
101 public abstract class SearchDialog
<T
extends ICdmBase
> extends Dialog
implements IConversationEnabled
{
103 private TableViewer list
;
106 private Text searchField
;
107 private String title
;
109 // message to show user
110 private String message
= ""; //$NON-NLS-1$
112 protected final ContentProvider contentProvider
;
114 private StructuredSelection currentSelection
;
115 ItemsListLabelProvider itemsListLabelProvider
;
117 private final RefreshCacheJob refreshCacheJob
;
119 private ToolBar toolBar
;
121 private ToolItem toolItem
;
122 private MenuManager menuManager
;
124 private ILabelProvider provider
;
126 private ILabelDecorator selectionDecorator
;
128 // Need to keep our own list of listeners
129 private final ListenerList listeners
= new ListenerList();
132 private static final String EMPTY_STRING
= ""; //$NON-NLS-1$
133 private GridData gd_1
;
135 public SearchDialog(Shell parent
, boolean multi
) {
137 contentProvider
= new ContentProvider();
138 refreshCacheJob
= new RefreshCacheJob();
144 protected Control
createDialogArea(Composite parent
) {
145 Composite container
= (Composite
) super.createDialogArea(parent
);
146 // Composite content = new Composite(container, SWT.NONE);
147 GridData gd
= new GridData(GridData
.FILL_BOTH
);
148 container
.setLayoutData(gd
);
150 GridLayout layout
= new GridLayout();
151 layout
.numColumns
= 1;
152 layout
.marginWidth
= 0;
153 layout
.marginHeight
= 0;
154 container
.setLayout(layout
);
156 final Label headerLabel
= createHeader(container
);
158 searchField
= new Text(container
, SWT
.SINGLE
| SWT
.BORDER
| SWT
.SEARCH
| SWT
.ICON_CANCEL
);
159 searchField
.getAccessible().addAccessibleListener(new AccessibleAdapter() {
161 public void getName(AccessibleEvent e
) {
162 e
.result
= LegacyActionTools
.removeMnemonics(headerLabel
166 searchField
.addModifyListener(new ModifyListener() {
168 public void modifyText(ModifyEvent e
) {
171 fillContentProvider(null);
172 } catch (CoreException coreException
) {
173 // TODO Auto-generated catch block
174 coreException
.printStackTrace();
178 gd_1
= new GridData(GridData
.FILL_HORIZONTAL
);
179 gd_1
.horizontalIndent
= 2;
180 gd_1
.grabExcessHorizontalSpace
= false;
181 gd_1
.horizontalAlignment
= SWT
.CENTER
;
182 gd_1
.widthHint
= 575;
183 searchField
.setLayoutData(gd_1
);
185 // final Label listLabel = createLabels(content);
187 setList(new TableViewer(container
, SWT
.SINGLE
188 | SWT
.BORDER
| SWT
.V_SCROLL
| SWT
.VIRTUAL
));
189 // getList().getTable().getAccessible().addAccessibleListener(
190 // new AccessibleAdapter() {
192 // public void getName(AccessibleEvent e) {
193 // if (e.childID == ACC.CHILDID_SELF) {
194 // e.result = LegacyActionTools
195 // .removeMnemonics(listLabel.getText());
199 getList().setContentProvider(contentProvider
);
200 getList().setLabelProvider(getItemsListLabelProvider());
201 getList().setInput(new Object
[0]);
202 getList().setItemCount(contentProvider
.getNumberOfElements());
203 getList().addSelectionChangedListener(new ISelectionChangedListener() {
205 public void selectionChanged(SelectionChangedEvent event
) {
206 StructuredSelection selection
= (StructuredSelection
) event
208 currentSelection
= selection
;
211 getList().addDoubleClickListener(new IDoubleClickListener() {
213 public void doubleClick(DoubleClickEvent event
) {
217 createExtendedContentArea(container
);
222 protected abstract void search();
225 * Creates an extra content area, which will be located above the details.
228 * parent to create the dialog widgets in
229 * @return an extra content area
231 protected abstract Control
createExtendedContentArea(Composite parent
);
234 * Sets the title for this dialog.
239 public void setTitle(String title
) {
244 * Create a new header which is labelled by headerLabel.
247 * @return Label the label of the header
249 private Label
createHeader(Composite parent
) {
250 Composite header
= new Composite(parent
, SWT
.NONE
);
252 GridLayout layout
= new GridLayout();
253 layout
.numColumns
= 2;
254 layout
.marginWidth
= 0;
255 layout
.marginHeight
= 0;
256 header
.setLayout(layout
);
257 new Label(header
, SWT
.NONE
);
258 new Label(header
, SWT
.NONE
);
259 new Label(header
, SWT
.NONE
);
261 Label headerLabel
= new Label(header
, SWT
.NONE
);
262 headerLabel
.setText((getMessage() != null && getMessage().trim()
263 .length() > 0) ?
getMessage()
264 : Messages
.SearchDialog_patternLabel
);
265 headerLabel
.addTraverseListener(new TraverseListener() {
267 public void keyTraversed(TraverseEvent e
) {
268 if (e
.detail
== SWT
.TRAVERSE_MNEMONIC
&& e
.doit
) {
269 e
.detail
= SWT
.TRAVERSE_NONE
;
270 searchField
.setFocus();
274 GridData gd_headerLabel
= new GridData(GridData
.FILL_HORIZONTAL
);
275 gd_headerLabel
.horizontalAlignment
= SWT
.LEFT
;
276 gd_headerLabel
.grabExcessHorizontalSpace
= false;
277 gd_headerLabel
.verticalAlignment
= SWT
.BOTTOM
;
278 gd_headerLabel
.minimumHeight
= 10;
279 headerLabel
.setLayoutData(gd_headerLabel
);
281 // createViewMenu(header);
287 * Returns the message for this dialog.
289 * @return the message for this dialog
291 protected String
getMessage() {
295 protected void setMessage(String message
){
296 this.message
= message
;
299 public Text
getSearchField() {
304 public void setSearchField(Text searchField
) {
305 this.searchField
= searchField
;
309 * Returns the item list label provider.
311 * @return the item list label provider
313 private ItemsListLabelProvider
getItemsListLabelProvider() {
314 if (itemsListLabelProvider
== null) {
315 itemsListLabelProvider
= new ItemsListLabelProvider(
316 new LabelProvider());
318 return itemsListLabelProvider
;
322 // * Create the labels for the list and the progress. Return the list label.
327 // private Label createLabels(Composite parent) {
328 // Composite labels = new Composite(parent, SWT.NONE);
330 // GridLayout layout = new GridLayout();
331 // layout.numColumns = 2;
332 // layout.marginWidth = 0;
333 // layout.marginHeight = 0;
334 // labels.setLayout(layout);
336 //// Label listLabel = new Label(labels, SWT.NONE);
338 //// .setText(Messages.SearchDialog_listLabel);
340 // listLabel.addTraverseListener(new TraverseListener() {
342 // public void keyTraversed(TraverseEvent e) {
343 // if (e.detail == SWT.TRAVERSE_MNEMONIC && e.doit) {
344 // e.detail = SWT.TRAVERSE_NONE;
345 // getList().getTable().setFocus();
349 // listLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
350 // new Label(labels, SWT.NONE);
357 private void createViewMenu(Composite parent
) {
358 toolBar
= new ToolBar(parent
, SWT
.FLAT
);
359 toolItem
= new ToolItem(toolBar
, SWT
.PUSH
, 0);
361 GridData data
= new GridData();
362 data
.horizontalAlignment
= GridData
.END
;
363 toolBar
.setLayoutData(data
);
365 toolBar
.addMouseListener(new MouseAdapter() {
367 public void mouseDown(MouseEvent e
) {
372 toolItem
.setImage(WorkbenchImages
373 .getImage(IWorkbenchGraphicConstants
.IMG_LCL_VIEW_MENU
));
375 .setToolTipText(WorkbenchMessages
.FilteredItemsSelectionDialog_menu
);
376 toolItem
.addSelectionListener(new SelectionAdapter() {
378 public void widgetSelected(SelectionEvent e
) {
383 menuManager
= new MenuManager();
385 fillViewMenu(menuManager
);
387 IHandlerService service
= PlatformUI
.getWorkbench()
388 .getService(IHandlerService
.class);
389 IHandler handler
= new AbstractHandler() {
391 public Object
execute(ExecutionEvent event
) {
396 // showViewHandler = service.activateHandler(
397 // IWorkbenchCommandConstants.WINDOW_SHOW_VIEW_MENU, handler,
398 // new ActiveShellExpression(getShell()));
402 * Fills the menu of the dialog.
407 protected void fillViewMenu(IMenuManager menuManager
) {
408 // toggleStatusLineAction = new ToggleStatusLineAction();
409 // menuManager.add(toggleStatusLineAction);
412 private void showViewMenu() {
413 Menu menu
= menuManager
.createContextMenu(getShell());
414 Rectangle bounds
= toolItem
.getBounds();
415 Point topLeft
= new Point(bounds
.x
, bounds
.y
+ bounds
.height
);
416 topLeft
= toolBar
.toDisplay(topLeft
);
417 menu
.setLocation(topLeft
.x
, topLeft
.y
);
418 menu
.setVisible(true);
421 public TableViewer
getList() {
425 public void setList(TableViewer list
) {
427 Table table
= list
.getTable();
428 GridData gd_table
= new GridData(SWT
.CENTER
, SWT
.CENTER
, true, true, 1, 1);
429 gd_table
.heightHint
= 231;
430 gd_table
.widthHint
= 543;
431 table
.setLayoutData(gd_table
);
435 * Sets a new label provider for items in the list. If the label provider
436 * also implements {@link
437 * org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider
438 * .IStyledLabelProvider}, the style text labels provided by it will be used
439 * provided that the corresponding preference is set.
441 * @see IWorkbenchPreferenceConstants#USE_COLORED_LABELS
443 * @param listLabelProvider
444 * the label provider for items in the list
446 public void setListLabelProvider(ILabelProvider listLabelProvider
) {
447 getItemsListLabelProvider().setProvider(listLabelProvider
);
453 * Collects filtered elements. Contains one synchronized, sorted set for
454 * collecting filtered elements. All collected elements are sorted using
455 * comparator. Comparator is returned by getElementComparator() method.
456 * Implementation of <code>ItemsFilter</code> is used to filter elements.
457 * The key function of filter used in to filtering is
458 * <code>matchElement(Object item)</code>.
460 * The <code>ContentProvider</code> class also provides item filtering
461 * methods. The filtering has been moved from the standard TableView
462 * <code>getFilteredItems()</code> method to content provider, because
463 * <code>ILazyContentProvider</code> and virtual tables are used. This
464 * class is responsible for adding a separator below history items and
465 * marking each items as duplicate if its name repeats more than once on the
468 class ContentProvider
implements
469 IStructuredContentProvider
, ILazyContentProvider
{
474 * Raw result of the searching (unsorted, unfiltered).
476 * Standard object flow:
477 * <code>items -> lastSortedItems -> lastFilteredItems</code>
483 * Creates new instance of <code>ContentProvider</code>.
485 public ContentProvider() {
486 this.items
= Collections
.synchronizedList(new ArrayList(2048));
493 * Removes all content items and resets progress message.
495 public void reset() {
503 * Adds filtered item.
509 public void add(Object item
) {
510 this.items
.add(item
);
518 public void refresh() {
523 * Schedule refresh job.
525 public void scheduleRefresh() {
526 refreshCacheJob
.cancelAll();
527 refreshCacheJob
.schedule();
534 * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
537 public Object
[] getElements(Object inputElement
) {
538 return items
.toArray();
539 // return lastFilteredItems.toArray();
542 public int getNumberOfElements() {
550 * @see org.eclipse.jface.viewers.IContentProvider#dispose()
553 public void dispose() {
559 * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer,
560 * java.lang.Object, java.lang.Object)
563 public void inputChanged(Viewer viewer
, Object oldInput
, Object newInput
) {
569 * @see org.eclipse.jface.viewers.ILazyContentProvider#updateElement(int)
572 public void updateElement(int index
) {
574 SearchDialog
.this.getList().replace((items
575 .size() > index
) ? items
.get(index
) : null,
583 // protected static boolean showColoredLabels() {
584 // return PlatformUI.getPreferenceStore().getBoolean(IWorkbenchPreferenceConstants.USE_COLORED_LABELS);
587 public StructuredSelection
getCurrentSelection() {
588 return currentSelection
;
592 * Fills the content provider with matching items.
594 * @param contentProvider
595 * collector to add items to.
596 * {@link FilteredItemsSelectionDialog.AbstractContentProvider#add(Object, FilteredItemsSelectionDialog.ItemsFilter)}
597 * only adds items that pass the given <code>itemsFilter</code>.
600 * @param progressMonitor
601 * must be used to report search progress. The state of this
602 * progress monitor reflects the state of the filtering process.
603 * @throws CoreException
605 protected abstract void fillContentProvider(IProgressMonitor progressMonitor
) throws CoreException
;
609 * Refreshes the dialog - has to be called in UI thread.
611 public void refresh() {
612 if (getList() != null && !getList().getTable().isDisposed()) {
614 List lastRefreshSelection
= ((StructuredSelection
) getList()
615 .getSelection()).toList();
616 getList().getTable().deselectAll();
618 getList().setItemCount(contentProvider
.getNumberOfElements());
621 if (getList().getTable().getItemCount() > 0) {
622 // preserve previous selection
623 if ( lastRefreshSelection
!= null
624 && lastRefreshSelection
.size() > 0) {
625 getList().setSelection(new StructuredSelection(
626 lastRefreshSelection
));
629 getList().getTable().setSelection(0);
630 getList().getTable().notifyListeners(SWT
.Selection
, new Event());
633 getList().setSelection(StructuredSelection
.EMPTY
);
638 // scheduleProgressMessageRefresh();
642 * Only refreshes UI on the basis of an already sorted and filtered set of
645 * Standard invocation scenario:
647 * <li>filtering job (<code>FilterJob</code> class extending
648 * <code>Job</code> class)</li>
649 * <li>cache refresh without checking for duplicates (<code>RefreshCacheJob</code>
650 * class extending <code>Job</code> class)</li>
651 * <li>UI refresh (<code>RefreshJob</code> class extending
652 * <code>UIJob</code> class)</li>
653 * <li>cache refresh with checking for duplicates (<cod>CacheRefreshJob</code>
654 * class extending <code>Job</code> class)</li>
655 * <li>UI refresh (<code>RefreshJob</code> class extending <code>UIJob</code>
658 * The scenario is rather complicated, but it had to be applied, because:
660 * <li> refreshing cache is rather a long action and cannot be run in the UI -
661 * cannot be run in a UIJob</li>
662 * <li> refreshing cache checking for duplicates is twice as long as
663 * refreshing cache without checking for duplicates; results of the search
664 * could be displayed earlier</li>
665 * <li> refreshing the UI have to be run in a UIJob</li>
668 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.FilterJob
669 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.RefreshJob
670 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.RefreshCacheJob
672 private class RefreshJob
extends UIJob
{
675 * Creates a new instance of the class.
677 public RefreshJob() {
678 super(SearchDialog
.this.getParentShell()
680 WorkbenchMessages
.FilteredItemsSelectionDialog_refreshJob
);
687 * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
690 public IStatus
runInUIThread(IProgressMonitor monitor
) {
691 if (monitor
.isCanceled()) {
692 return new Status(IStatus
.OK
, WorkbenchPlugin
.PI_WORKBENCH
,
693 IStatus
.OK
, EMPTY_STRING
, null);
696 if (SearchDialog
.this != null) {
697 SearchDialog
.this.refresh();
700 return new Status(IStatus
.OK
, PlatformUI
.PLUGIN_ID
, IStatus
.OK
,
708 * A job responsible for computing filtered items list presented using
709 * <code>RefreshJob</code>.
711 * @see FilteredItemsSelectionDialog.RefreshJob
714 private class RefreshCacheJob
extends Job
{
716 private final RefreshJob refreshJob
= new RefreshJob();
719 * Creates a new instance of the class.
721 public RefreshCacheJob() {
723 WorkbenchMessages
.FilteredItemsSelectionDialog_cacheRefreshJob
);
728 * Stops the job and all sub-jobs.
730 public void cancelAll() {
738 * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
741 protected IStatus
run(IProgressMonitor monitor
) {
742 if (monitor
.isCanceled()) {
743 return new Status(IStatus
.CANCEL
, WorkbenchPlugin
.PI_WORKBENCH
,
744 IStatus
.CANCEL
, EMPTY_STRING
, null);
747 if (SearchDialog
.this != null) {
750 SearchDialog
.this.fillContentProvider(monitor
);
751 } catch (CoreException e
) {
752 // TODO Auto-generated catch block
757 if (!monitor
.isCanceled()) {
758 refreshJob
.schedule();
761 return new Status(IStatus
.OK
, PlatformUI
.PLUGIN_ID
, IStatus
.OK
,
769 * @see org.eclipse.core.runtime.jobs.Job#canceling()
772 protected void canceling() {
774 // contentProvider.stopReloadingCache();
779 private class ItemsListLabelProvider
extends StyledCellLabelProvider
780 implements ILabelProviderListener
{
781 private ILabelProvider provider
;
784 * Creates a new instance of the class.
787 * the label provider for all items, not <code>null</code>
788 * @param selectionDecorator
789 * the decorator for selected items, can be <code>null</code>
791 public ItemsListLabelProvider(ILabelProvider provider
) {
792 Assert
.isNotNull(provider
);
793 this.provider
= provider
;
796 // setOwnerDrawEnabled(showColoredLabels() && provider instanceof IStyledLabelProvider);
798 provider
.addListener(this);
800 if (selectionDecorator
!= null) {
801 selectionDecorator
.addListener(this);
806 * Sets new selection decorator.
808 * @param newSelectionDecorator
809 * new label decorator for selected items in the list
811 public void setSelectionDecorator(ILabelDecorator newSelectionDecorator
) {
812 if (selectionDecorator
!= null) {
813 selectionDecorator
.removeListener(this);
814 selectionDecorator
.dispose();
817 selectionDecorator
= newSelectionDecorator
;
819 if (selectionDecorator
!= null) {
820 selectionDecorator
.addListener(this);
825 * Gets selection decorator.
827 * @return the label decorator for selected items in the list
829 public ILabelDecorator
getSelectionDecorator() {
830 return selectionDecorator
;
834 * Sets new label provider.
837 * new label provider for items in the list, not
840 public void setProvider(ILabelProvider newProvider
) {
841 Assert
.isNotNull(newProvider
);
842 provider
.removeListener(this);
845 provider
= newProvider
;
847 if (provider
!= null) {
848 provider
.addListener(this);
851 // setOwnerDrawEnabled(showColoredLabels() && provider instanceof IStyledLabelProvider);
856 private boolean isSelected(Object element
) {
857 if (element
!= null && getCurrentSelection() != null) {
858 if (element
.equals(getCurrentSelection())) {
868 * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
870 private String
getText(Object element
) {
871 if (element
instanceof ItemsListSeparator
) {
872 return getSeparatorLabel(((ItemsListSeparator
) element
)
876 String str
= provider
.getText(element
);
877 if (selectionDecorator
!= null && isSelected(element
)) {
878 return selectionDecorator
.decorateText(str
.toString(), element
);
884 private StyledString
getStyledText(Object element
,
885 IStyledLabelProvider provider
) {
886 StyledString string
= provider
.getStyledText(element
);
888 if (selectionDecorator
!= null && isSelected(element
)) {
889 String decorated
= selectionDecorator
.decorateText(string
890 .getString(), element
);
891 return StyledCellLabelProvider
.styleDecoratedString(decorated
, null, string
);
892 // no need to add colors when element is selected
898 public void update(ViewerCell cell
) {
899 Object element
= cell
.getElement();
901 if (!(element
instanceof ItemsListSeparator
)
902 && provider
instanceof IStyledLabelProvider
) {
903 IStyledLabelProvider styledLabelProvider
= (IStyledLabelProvider
) provider
;
904 StyledString styledString
= getStyledText(element
,
905 styledLabelProvider
);
907 cell
.setText(styledString
.getString());
908 cell
.setStyleRanges(styledString
.getStyleRanges());
909 cell
.setImage(styledLabelProvider
.getImage(element
));
911 cell
.setText(getText(element
));
914 cell
.setFont(getFont(element
));
915 cell
.setForeground(getForeground(element
));
916 cell
.setBackground(getBackground(element
));
921 private String
getSeparatorLabel(String separatorLabel
) {
922 Rectangle rect
= getList().getTable().getBounds();
924 int borderWidth
= getList().getTable().computeTrim(0, 0, 0, 0).width
;
926 int imageWidth
= WorkbenchImages
.getImage(
927 IWorkbenchGraphicConstants
.IMG_OBJ_SEPARATOR
).getBounds().width
;
929 int width
= rect
.width
- borderWidth
- imageWidth
;
931 GC gc
= new GC(getList().getTable());
932 gc
.setFont(getList().getTable().getFont());
934 int fSeparatorWidth
= gc
.getAdvanceWidth('-');
935 int fMessageLength
= gc
.textExtent(separatorLabel
).x
;
939 StringBuffer dashes
= new StringBuffer();
940 int chars
= (((width
- fMessageLength
) / fSeparatorWidth
) / 2) - 2;
941 for (int i
= 0; i
< chars
; i
++) {
945 StringBuffer result
= new StringBuffer();
946 result
.append(dashes
);
947 result
.append(" " + separatorLabel
+ " "); //$NON-NLS-1$//$NON-NLS-2$
948 result
.append(dashes
);
949 return result
.toString().trim();
955 * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
958 public void addListener(ILabelProviderListener listener
) {
959 listeners
.add(listener
);
965 * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
968 public void dispose() {
969 provider
.removeListener(this);
972 if (selectionDecorator
!= null) {
973 selectionDecorator
.removeListener(this);
974 selectionDecorator
.dispose();
983 * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object,
987 public boolean isLabelProperty(Object element
, String property
) {
988 if (provider
.isLabelProperty(element
, property
)) {
991 if (selectionDecorator
!= null
992 && selectionDecorator
.isLabelProperty(element
, property
)) {
1001 * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
1004 public void removeListener(ILabelProviderListener listener
) {
1005 listeners
.remove(listener
);
1008 private Color
getBackground(Object element
) {
1009 if (element
instanceof ItemsListSeparator
) {
1012 if (provider
instanceof IColorProvider
) {
1013 return ((IColorProvider
) provider
).getBackground(element
);
1018 private Color
getForeground(Object element
) {
1019 if (element
instanceof ItemsListSeparator
) {
1020 return Display
.getCurrent().getSystemColor(
1021 SWT
.COLOR_WIDGET_NORMAL_SHADOW
);
1023 if (provider
instanceof IColorProvider
) {
1024 return ((IColorProvider
) provider
).getForeground(element
);
1029 private Font
getFont(Object element
) {
1030 if (element
instanceof ItemsListSeparator
) {
1033 if (provider
instanceof IFontProvider
) {
1034 return ((IFontProvider
) provider
).getFont(element
);
1042 * @see org.eclipse.jface.viewers.ILabelProviderListener#labelProviderChanged(org.eclipse.jface.viewers.LabelProviderChangedEvent)
1045 public void labelProviderChanged(LabelProviderChangedEvent event
) {
1046 Object
[] l
= listeners
.getListeners();
1047 for (int i
= 0; i
< listeners
.size(); i
++) {
1048 ((ILabelProviderListener
) l
[i
]).labelProviderChanged(event
);
1054 protected Point
getInitialSize() {
1055 return new Point(593, 399);