2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
10 package eu
.etaxonomy
.taxeditor
;
12 import java
.util
.HashSet
;
15 import org
.apache
.log4j
.Logger
;
16 import org
.eclipse
.core
.commands
.operations
.IOperationHistory
;
17 import org
.eclipse
.core
.commands
.operations
.IUndoContext
;
18 import org
.eclipse
.core
.commands
.operations
.OperationHistoryFactory
;
19 import org
.eclipse
.jface
.preference
.IPreferenceStore
;
20 import org
.eclipse
.swt
.graphics
.Color
;
21 import org
.eclipse
.swt
.widgets
.Composite
;
22 import org
.eclipse
.swt
.widgets
.Control
;
23 import org
.eclipse
.swt
.widgets
.Display
;
24 import org
.eclipse
.swt
.widgets
.Shell
;
25 import org
.eclipse
.swt
.widgets
.Tree
;
26 import org
.eclipse
.swt
.widgets
.TreeItem
;
27 import org
.eclipse
.ui
.IActionBars
;
28 import org
.eclipse
.ui
.IEditorInput
;
29 import org
.eclipse
.ui
.IEditorPart
;
30 import org
.eclipse
.ui
.IEditorReference
;
31 import org
.eclipse
.ui
.IPageLayout
;
32 import org
.eclipse
.ui
.IViewPart
;
33 import org
.eclipse
.ui
.IViewReference
;
34 import org
.eclipse
.ui
.IWorkbench
;
35 import org
.eclipse
.ui
.IWorkbenchPage
;
36 import org
.eclipse
.ui
.PartInitException
;
37 import org
.eclipse
.ui
.forms
.IManagedForm
;
38 import org
.eclipse
.ui
.operations
.IWorkbenchOperationSupport
;
39 import org
.eclipse
.ui
.views
.properties
.PropertySheet
;
40 import org
.eclipse
.ui
.views
.properties
.PropertySheetPage
;
42 import eu
.etaxonomy
.cdm
.model
.description
.Feature
;
43 import eu
.etaxonomy
.cdm
.model
.name
.BotanicalName
;
44 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalCode
;
45 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
46 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
47 import eu
.etaxonomy
.cdm
.model
.name
.ZoologicalName
;
48 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
49 import eu
.etaxonomy
.taxeditor
.editor
.CompositeBorderDecorator
;
50 import eu
.etaxonomy
.taxeditor
.editor
.EditorGroupComposite
;
51 import eu
.etaxonomy
.taxeditor
.editor
.MultiPageTaxonEditor
;
52 import eu
.etaxonomy
.taxeditor
.editor
.WarningAnnotation
;
53 import eu
.etaxonomy
.taxeditor
.model
.CdmUtil
;
54 import eu
.etaxonomy
.taxeditor
.model
.NameEditorInput
;
55 import eu
.etaxonomy
.taxeditor
.navigation
.TaxonomicTreeView
;
56 import eu
.etaxonomy
.taxeditor
.navigation
.TaxonomicTreeViewer
;
57 import eu
.etaxonomy
.taxeditor
.propertysheet
.CustomSortPropertySheetEntry
;
60 * A collection of useful methods related to the UI.
67 private static final Logger logger
= Logger
.getLogger(UiUtil
.class);
69 private static Set
<Feature
> preferredFeatureSet
;
70 private static Set
<Rank
> preferredRankSet
;
71 private static IViewPart treeView
;
73 public static IViewPart
getPropertySheet() {
74 for (IViewReference reference
: getActivePage().getViewReferences()) {
75 if (reference
.getId().equals(IPageLayout
.ID_PROP_SHEET
)) {
76 return reference
.getView(false);
83 * By default, property sheet has buttons in the toolbar for
84 * "Show advanced properties" and "Show categories".
86 * This is confusing for the user, hence a method to remove them
87 * until such time as advanced properties or categories are implemented.
89 public static void hidePropertySheetToolbar() {
90 PropertySheet propertySheet
= (PropertySheet
) getPropertySheet();
91 IActionBars actionBars
= propertySheet
.getViewSite().getActionBars();
92 actionBars
.getToolBarManager().removeAll();
93 actionBars
.getMenuManager().removeAll();
97 * The property sheet listener ensures only property sheets
98 * with data cause the Property Sheet to be updated.
100 public static void addPropertySheetInputListener() {
101 IViewPart propertySheet
= getPropertySheet();
103 PropertySheet ps
= (PropertySheet
) propertySheet
;
104 // ps.addPartPropertyListener(listener)
105 // ps.addPropertyListener(l)
111 * @throws PartInitException
113 public static IEditorPart
getEditorByInput(IEditorInput input
)
114 throws PartInitException
{
115 for (IEditorReference reference
: getActivePage().getEditorReferences()) {
116 if (reference
.getEditorInput().equals(input
)) {
117 IEditorPart editor
= reference
.getEditor(false);
125 * Returns a set of all currently open
126 * <code>MultiPageTaxonEditor</code>s.
130 public static Set
<IEditorPart
> getOpenTaxonEditors() {
132 Set
<IEditorPart
> taxonEditors
= new HashSet
<IEditorPart
>();
134 for (IEditorReference reference
: getActivePage().getEditorReferences()) {
135 IEditorPart editor
= reference
.getEditor(false);
136 if (editor
instanceof MultiPageTaxonEditor
) {
137 taxonEditors
.add(editor
);
143 public static IEditorPart
getEditorByTaxon(Taxon taxon
)
144 throws PartInitException
{
145 IEditorInput input
= new NameEditorInput(taxon
);
146 return getEditorByInput(input
);
152 public static IWorkbenchPage
getActivePage() {
153 return TaxEditorPlugin
.getDefault().getWorkbench()
154 .getActiveWorkbenchWindow().getActivePage();
160 public static Shell
getShell() {
161 return TaxEditorPlugin
.getDefault().getWorkbench()
162 .getActiveWorkbenchWindow().getShell();
168 * @throws PartInitException
170 public static void openEditor(IEditorInput input
, String editorId
)
171 throws PartInitException
{
172 getActivePage().openEditor(input
, editorId
);
178 * @throws PartInitException
180 public static void closeEditor(Taxon taxon
, boolean save
)
181 throws PartInitException
{
182 IEditorPart editor
= getEditorByTaxon(taxon
);
183 closeEditor(editor
, save
);
189 * @throws PartInitException
191 public static void closeEditor(IEditorInput input
, boolean save
)
192 throws PartInitException
{
193 IEditorPart editor
= getEditorByInput(input
);
194 closeEditor(editor
, save
);
200 * @throws PartInitException
202 public static void closeEditor(IEditorPart editor
, boolean save
)
203 throws PartInitException
{
204 if (editor
!= null) {
205 getActivePage().closeEditor(editor
, save
);
209 public static IViewPart
getViewById(String id
) {
210 return TaxEditorPlugin
.getDefault().getWorkbench().getActiveWorkbenchWindow().
211 getActivePage().findView(id
);
216 * Returns the <code>TaxonomicTreeViewer</code> used for navigation. Not to
217 * be confused with the window that contains it, <code>TaxonomicTreeView</code>.
221 public static TaxonomicTreeViewer
getTreeViewer() {
222 TaxonomicTreeView view
= getTreeView();
226 return view
.getTreeViewer();
230 * @see eu.etaxonomy.taxeditor.navigation.TaxonomicTreeView#createTreeViewer()
234 public static TaxonomicTreeViewer
createTreeViewer() {
235 TaxonomicTreeView view
= getTreeView();
239 return view
.createTreeViewer();
243 * Returns the <code>TaxonomicTreeView</code> containing the
244 * <code>TaxonomicTreeViewer</code> used for navigation.
248 public static TaxonomicTreeView
getTreeView() {
249 if (treeView
== null) {
250 treeView
= getViewById(TaxonomicTreeView
.ID
);
251 if (!(treeView
instanceof TaxonomicTreeView
)) {
255 return (TaxonomicTreeView
) treeView
;
259 public static IWorkbenchOperationSupport
getOperationSupport() {
260 IWorkbench workbench
= TaxEditorPlugin
.getDefault().getWorkbench();
261 return workbench
.getOperationSupport();
264 public static IOperationHistory
getOperationHistory() {
265 return OperationHistoryFactory
.getOperationHistory();
266 // return getOperationSupport().getOperationHistory();
269 public static IUndoContext
getWorkbenchUndoContext() {
270 return getOperationSupport().getUndoContext();
273 public static void doEditorSave(Taxon taxon
, boolean confirm
) {
274 IEditorPart editor
= null;
276 editor
= getEditorByTaxon(taxon
);
277 } catch (PartInitException e
) {
278 // TODO Auto-generated catch block
281 if (editor
!= null) {
282 getActivePage().saveEditor(editor
, confirm
);
287 public static EditorGroupComposite
getMisappliedNameGroupComposite(
288 IManagedForm managedForm
) {
290 // Iterate through parent's children until we find a composite which has a data field
291 // for MISAPPLIED_NAME
292 Composite parent
= managedForm
.getForm().getBody();
293 for (Control groupComposite
: parent
.getChildren()) {
294 if (groupComposite
instanceof EditorGroupComposite
) {
295 if (groupComposite
.getData(ITaxEditorConstants
.MISAPPLIED_NAME
) != null) {
296 return (EditorGroupComposite
) groupComposite
;
303 public static EditorGroupComposite
createMisappliedNameGroupComposite(
304 IManagedForm managedForm
) {
306 Composite parent
= managedForm
.getForm().getBody();
308 EditorGroupComposite composite
= new EditorGroupComposite(parent
, managedForm
);
309 composite
.setData(ITaxEditorConstants
.MISAPPLIED_NAME
,"");
310 new CompositeBorderDecorator(composite
, managedForm
);
314 public static IPreferenceStore
getPrefStore() {
315 return TaxEditorPlugin
.getDefault().getPreferenceStore();
319 * Returns a <code>Set</code> of the <code>Feature</code>s that the user has chosen
320 * to have shown in preferences.
323 * <code>Feature</code>s are shown unless otherwise specified.
327 public static Set
<Feature
> getPreferredFeatures() {
329 // Initialize preferredFeatureSet as necessary
330 if (preferredFeatureSet
== null) {
332 preferredFeatureSet
= new HashSet
<Feature
>();
334 for (Feature feature
: CdmUtil
.getFeatures()) {
336 // If the feature is set to show, add it to preferredFeatureSet
337 if (getFeaturePreference(feature
)) {
338 preferredFeatureSet
.add(feature
);
343 return preferredFeatureSet
;
347 * True if <code>Feature</code> is set to "show" in preferences.
352 public static boolean getFeaturePreference(Feature feature
) {
354 String preferenceKey
= getPreferenceKey(feature
);
356 // If feature does not yet have a pref, set it to true
357 if (!getPrefStore().contains(preferenceKey
)) {
358 getPrefStore().setDefault(preferenceKey
, true);
361 return getPrefStore().getBoolean(preferenceKey
);
365 * Set the show state of a <code>Feature</code> in the
366 * <code>PreferenceStore</code>.
368 * Also sets <code>preferredFeatureSet</code> to null to force it be
369 * re-populated the next time {@link #getPreferredFeatures()} is called.
374 public static void setFeaturePreference(Feature feature
, boolean show
) {
375 preferredFeatureSet
= null;
376 getPrefStore().setValue(getPreferenceKey(feature
), show
);
380 * Construct a unique key using <code>Feature</code>'s <code>Uuid</code>
385 private static String
getPreferenceKey(Feature feature
) {
386 return ITaxEditorConstants
.FEATURE_PREFERENCE
388 . concat(feature
.getUuid().toString());
392 * Returns a <code>Set</code> of the <code>Rank</code>s that the user has chosen
393 * to have shown in preferences.
396 * <code>Rank</code>s are shown unless otherwise specified.
400 public static Set
<Rank
> getPreferredRanks() {
402 // Initialize preferredFeatureSet as necessary
403 if (preferredRankSet
== null) {
405 preferredRankSet
= new HashSet
<Rank
>();
407 for (Rank rank
: CdmUtil
.getRanks()) {
409 // If the feature is set to show, add it to preferredFeatureSet
410 if (getRankPreference(rank
)) {
411 preferredRankSet
.add(rank
);
416 return preferredRankSet
;
420 * True if <code>Rank</code> is set to "show" in preferences.
425 public static boolean getRankPreference(Rank rank
) {
427 String preferenceKey
= getPreferenceKey(rank
);
429 // If rank does not yet have a pref, set it to true
430 if (!getPrefStore().contains(preferenceKey
)) {
431 getPrefStore().setDefault(preferenceKey
, true);
434 return getPrefStore().getBoolean(preferenceKey
);
438 * Set the show state of a <code>Rank</code> in the
439 * <code>PreferenceStore</code>.
441 * Also sets <code>preferredRankSet</code> to null to force it be
442 * re-populated the next time {@link #getPreferredRanks()} is called.
447 public static void setRankPreference(Rank rank
, boolean show
) {
448 preferredRankSet
= null;
449 getPrefStore().setValue(getPreferenceKey(rank
), show
);
454 * Construct a unique key using <code>Rank</code>'s <code>Uuid</code>
459 private static String
getPreferenceKey(Rank rank
) {
460 return ITaxEditorConstants
.RANK_PREFERENCE
462 . concat(rank
.getUuid().toString());
468 public static NonViralName
getPreferredNameClassInstance() {
469 String nameCodePreference
= TaxEditorPlugin
.getDefault().getPreferenceStore().getString(ITaxEditorConstants
.CODE_PREFERENCE
);
471 // Check whether name code preference needs to be initialized
472 if (nameCodePreference
== null || nameCodePreference
.equals("")) {
473 nameCodePreference
= ITaxEditorConstants
.DEFAULT_CODE_PREFERENCE
;
474 UiUtil
.getPrefStore().setValue(ITaxEditorConstants
.CODE_PREFERENCE
,
478 if (nameCodePreference
.equals(ITaxEditorConstants
.CODE_PREFERENCE_ICBN
)) {
479 return BotanicalName
.NewInstance(null);
480 } else if (nameCodePreference
.equals(ITaxEditorConstants
.CODE_PREFERENCE_ICZN
)) {
481 return ZoologicalName
.NewInstance(null);
483 return NonViralName
.NewInstance(null);
486 public static String
getNameCodePreference() {
487 String nameCodePreference
= getPrefStore().getString(ITaxEditorConstants
.CODE_PREFERENCE
);
489 // Check whether name code preference needs to be initialized
490 if (nameCodePreference
== null || nameCodePreference
.equals("")) {
491 nameCodePreference
= ITaxEditorConstants
.DEFAULT_CODE_PREFERENCE
;
492 getPrefStore().setValue(ITaxEditorConstants
.CODE_PREFERENCE
, nameCodePreference
);
495 return nameCodePreference
;
501 public static NomenclaturalCode
getPreferredNomenclaturalCode() {
503 String nameCodePreference
= getNameCodePreference();
505 if (nameCodePreference
.equals(ITaxEditorConstants
.CODE_PREFERENCE_ICBN
)) {
506 return NomenclaturalCode
.ICBN();
507 } else if (nameCodePreference
.equals(ITaxEditorConstants
.CODE_PREFERENCE_ICZN
)) {
508 return NomenclaturalCode
.ICZN();
514 * Appends the code (i.e. ICBN or ICZN) specified in the user preferences
515 * to a string. The result is separated by a period: "<code>key.ICBN</code>".
520 public static String
concatCodeMessageSuffix(String key
) {
521 String code
= getNameCodePreference();
522 return key
+ "." + code
;
525 public static void setStatusMessage(String msg
) {
526 getPropertySheet().getViewSite().getActionBars().getStatusLineManager().setMessage(msg
);
529 public static void setPropertySheetTree(Tree tree
) {
530 TaxEditorPlugin
.getDefault().setPropertySheetTree(tree
);
533 public static Tree
getPropertySheetTree() {
534 return TaxEditorPlugin
.getDefault().getPropertySheetTree();
537 public static void setPropertySheetPage(PropertySheetPage page
) {
538 TaxEditorPlugin
.getDefault().setPropertySheetPage(page
);
541 public static PropertySheetPage
getPropertySheetPage() {
542 return TaxEditorPlugin
.getDefault().getPropertySheetPage();
546 * UiUtil.paintPropertySheetRow(P_DATEPUBLISHED, new Color(Display.getDefault(), WarningAnnotation.WARNING_RGB), true);
547 * UiUtil.unpaintPropertySheetRow(P_DATEPUBLISHED);
551 * @param doPaintChildren
553 public static void paintPropertySheetRow(String id
, Color color
, boolean doPaintChildren
) {
555 // Catch null property sheet name
560 // Catch uninit'ed property sheet tree
561 if (getPropertySheetTree() == null) {
565 paintPropertySheetRow(id
, color
, doPaintChildren
, getPropertySheetTree());
568 private static void paintPropertySheetRow(String id
, Color color
, boolean doPaintChildren
, Object treeOrItem
) {
570 // Init items w zero-length array
571 TreeItem
[] items
= new TreeItem
[]{};
573 // Get child items depending to class
574 if (treeOrItem
instanceof Tree
) {
575 items
= ((Tree
) treeOrItem
).getItems();
577 if (treeOrItem
instanceof TreeItem
) {
578 items
= ((TreeItem
) treeOrItem
).getItems();
581 // If array hasn't been populated by the above, return
582 if (items
.length
== 0) {
586 // Prop. sheet id's take the form "01:xxxx" for sorting - truncate
587 id
= CustomSortPropertySheetEntry
.truncateDisplayName(id
);
589 // Iterate through child items
590 for (TreeItem item
: items
) {
592 // Item found, paint it
593 if (id
.equals(item
.getText())) {
594 paintItem(item
, color
, doPaintChildren
);
598 // Recursively search for item to paint in child items
599 if (item
.getItemCount() > 0) {
600 paintPropertySheetRow(id
, color
, doPaintChildren
, item
);
606 * Note: children are only painted if submenu has already been created, i.e. opened once.
610 * @param doPaintChildren
612 private static void paintItem(TreeItem item
, Color color
, boolean doPaintChildren
) {
615 item
.setBackground(color
);
617 // Recursively paint child items if requested
618 if (doPaintChildren
) {
619 for (TreeItem childItem
: item
.getItems()) {
620 paintItem(childItem
, color
, doPaintChildren
);
625 public static void unpaintPropertySheetRow(String id
) {
627 // Catch uninit'ed property sheet tree
628 if (getPropertySheetTree() == null) {
632 // Get tree's background color to "unpaint"
633 Color color
= getPropertySheetTree().getBackground();
635 paintPropertySheetRow(id
, color
, true);