<CR> in name relation - select name now the same as clicking the "Search" button.
[taxeditor.git] / eclipseprojects / eu.etaxonomy.taxeditor / src / eu / etaxonomy / taxeditor / UiUtil.java
index 03a6f8d5563fa7cb78f34ca07c52bcb707a234ac..8d9c5a0d8f9fd38e37d00fd1c67aacffd0caac95 100644 (file)
@@ -9,12 +9,22 @@
 \r
 package eu.etaxonomy.taxeditor;\r
 \r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
 import org.apache.log4j.Logger;\r
 import org.eclipse.core.commands.operations.IOperationHistory;\r
 import org.eclipse.core.commands.operations.IUndoContext;\r
 import org.eclipse.core.commands.operations.OperationHistoryFactory;\r
-import org.eclipse.jface.viewers.TreeViewer;\r
+import org.eclipse.jface.preference.IPreferenceStore;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Display;\r
 import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.swt.widgets.Tree;\r
+import org.eclipse.swt.widgets.TreeItem;\r
+import org.eclipse.ui.IActionBars;\r
 import org.eclipse.ui.IEditorInput;\r
 import org.eclipse.ui.IEditorPart;\r
 import org.eclipse.ui.IEditorReference;\r
@@ -24,13 +34,27 @@ import org.eclipse.ui.IViewReference;
 import org.eclipse.ui.IWorkbench;\r
 import org.eclipse.ui.IWorkbenchPage;\r
 import org.eclipse.ui.PartInitException;\r
+import org.eclipse.ui.forms.IManagedForm;\r
 import org.eclipse.ui.operations.IWorkbenchOperationSupport;\r
 import org.eclipse.ui.views.properties.PropertySheet;\r
+import org.eclipse.ui.views.properties.PropertySheetPage;\r
 \r
+import eu.etaxonomy.cdm.model.description.Feature;\r
+import eu.etaxonomy.cdm.model.name.BotanicalName;\r
+import eu.etaxonomy.cdm.model.name.NomenclaturalCode;\r
+import eu.etaxonomy.cdm.model.name.NonViralName;\r
+import eu.etaxonomy.cdm.model.name.Rank;\r
+import eu.etaxonomy.cdm.model.name.ZoologicalName;\r
 import eu.etaxonomy.cdm.model.taxon.Taxon;\r
+import eu.etaxonomy.taxeditor.editor.CompositeBorderDecorator;\r
+import eu.etaxonomy.taxeditor.editor.EditorGroupComposite;\r
+import eu.etaxonomy.taxeditor.editor.MultiPageTaxonEditor;\r
+import eu.etaxonomy.taxeditor.editor.WarningAnnotation;\r
+import eu.etaxonomy.taxeditor.model.CdmUtil;\r
 import eu.etaxonomy.taxeditor.model.NameEditorInput;\r
-import eu.etaxonomy.taxeditor.view.TaxonomicTreeView;\r
-import eu.etaxonomy.taxeditor.view.TaxonomicTreeViewer;\r
+import eu.etaxonomy.taxeditor.navigation.TaxonomicTreeView;\r
+import eu.etaxonomy.taxeditor.navigation.TaxonomicTreeViewer;\r
+import eu.etaxonomy.taxeditor.propertysheet.CustomSortPropertySheetEntry;\r
 \r
 /**\r
  * A collection of useful methods related to the UI.\r
@@ -42,6 +66,10 @@ import eu.etaxonomy.taxeditor.view.TaxonomicTreeViewer;
 public class UiUtil {\r
        private static final Logger logger = Logger.getLogger(UiUtil.class);\r
 \r
+       private static Set<Feature> preferredFeatureSet;\r
+       private static Set<Rank> preferredRankSet;\r
+       private static IViewPart treeView;\r
+       \r
        public static IViewPart getPropertySheet() {\r
                for (IViewReference reference : getActivePage().getViewReferences()) {\r
                        if (reference.getId().equals(IPageLayout.ID_PROP_SHEET)) {\r
@@ -51,6 +79,20 @@ public class UiUtil {
                return null;\r
        }\r
        \r
+       /**\r
+        * By default, property sheet has buttons in the toolbar for \r
+        * "Show advanced properties" and "Show categories".\r
+        * <p>\r
+        * This is confusing for the user, hence a method to remove them\r
+        * until such time as advanced properties or categories are implemented.\r
+        */\r
+       public static void hidePropertySheetToolbar() {\r
+               PropertySheet propertySheet = (PropertySheet) getPropertySheet();\r
+               IActionBars actionBars = propertySheet.getViewSite().getActionBars();\r
+               actionBars.getToolBarManager().removeAll();\r
+               actionBars.getMenuManager().removeAll();\r
+       }\r
+       \r
        /**\r
         * The property sheet listener ensures only property sheets\r
         *      with data cause the Property Sheet to be updated.\r
@@ -78,6 +120,25 @@ public class UiUtil {
                }\r
                return null;\r
        }\r
+       \r
+       /**\r
+        * Returns a set of all currently open \r
+        * <code>MultiPageTaxonEditor</code>s.\r
+        * \r
+        * @return\r
+        */\r
+       public static Set<IEditorPart> getOpenTaxonEditors() {\r
+               \r
+               Set<IEditorPart> taxonEditors = new HashSet<IEditorPart>();\r
+               \r
+               for (IEditorReference reference : getActivePage().getEditorReferences()) {\r
+                       IEditorPart editor = reference.getEditor(false);\r
+                       if (editor instanceof MultiPageTaxonEditor) {\r
+                               taxonEditors.add(editor);\r
+                       }\r
+               }\r
+               return taxonEditors;\r
+       }\r
 \r
        public static IEditorPart getEditorByTaxon(Taxon taxon)\r
                        throws PartInitException {\r
@@ -111,6 +172,17 @@ public class UiUtil {
                getActivePage().openEditor(input, editorId);\r
        }\r
 \r
+       /**\r
+        * @param taxon\r
+        * @param save\r
+        * @throws PartInitException\r
+        */\r
+       public static void closeEditor(Taxon taxon, boolean save)\r
+                       throws PartInitException {\r
+               IEditorPart editor = getEditorByTaxon(taxon);\r
+               closeEditor(editor, save);\r
+       }\r
+       \r
        /**\r
         * @param input\r
         * @param save\r
@@ -139,19 +211,50 @@ public class UiUtil {
                                getActivePage().findView(id);\r
        }\r
        \r
+\r
        /**\r
+        * Returns the <code>TaxonomicTreeViewer</code> used for navigation. Not to \r
+        * be confused with the window that contains it, <code>TaxonomicTreeView</code>. \r
+        * \r
         * @return\r
         */\r
        public static TaxonomicTreeViewer getTreeViewer() {\r
-               IViewPart view = getViewById(TaxonomicTreeView.ID);\r
-               if (view instanceof TaxonomicTreeView) {\r
-                       TreeViewer viewer = ((TaxonomicTreeView) view).getTreeViewer();\r
-                       if (viewer instanceof TaxonomicTreeViewer) {\r
-                               return (TaxonomicTreeViewer) viewer;\r
+               TaxonomicTreeView view = getTreeView();\r
+               if (view == null) {\r
+                       return null;\r
+               }\r
+               return view.getTreeViewer();\r
+       }\r
+\r
+       /**\r
+        * @see eu.etaxonomy.taxeditor.navigation.TaxonomicTreeView#createTreeViewer()\r
+        * \r
+        * @return\r
+        */\r
+       public static TaxonomicTreeViewer createTreeViewer() {\r
+               TaxonomicTreeView view = getTreeView();\r
+               if (view == null) {\r
+                       return null;\r
+               }\r
+               return view.createTreeViewer();\r
+       }\r
+       \r
+       /**\r
+        * Returns the <code>TaxonomicTreeView</code> containing the \r
+        * <code>TaxonomicTreeViewer</code> used for navigation. \r
+        * \r
+        * @return\r
+        */     \r
+       public static TaxonomicTreeView getTreeView() {\r
+               if (treeView == null) {\r
+                       treeView = getViewById(TaxonomicTreeView.ID);\r
+                       if (!(treeView instanceof TaxonomicTreeView)) {\r
+                               treeView = null;\r
                        }\r
-               } \r
-               return null;\r
+               }\r
+               return (TaxonomicTreeView) treeView;\r
        }\r
+       \r
 \r
        public static IWorkbenchOperationSupport getOperationSupport() {\r
                IWorkbench workbench = TaxEditorPlugin.getDefault().getWorkbench();\r
@@ -179,4 +282,356 @@ public class UiUtil {
                        getActivePage().saveEditor(editor, confirm);\r
                }\r
        }\r
+       \r
+\r
+       public static EditorGroupComposite getMisappliedNameGroupComposite(\r
+                       IManagedForm managedForm) {\r
+\r
+               // Iterate through parent's children until we find a composite which has a data field\r
+               //      for MISAPPLIED_NAME\r
+               Composite parent = managedForm.getForm().getBody();\r
+               for (Control groupComposite : parent.getChildren()) {\r
+                       if (groupComposite instanceof EditorGroupComposite) {\r
+                               if (groupComposite.getData(ITaxEditorConstants.MISAPPLIED_NAME) != null) {\r
+                                       return (EditorGroupComposite) groupComposite;\r
+                               }\r
+                       }\r
+               }\r
+               return null;\r
+       }\r
+\r
+       public static EditorGroupComposite createMisappliedNameGroupComposite(\r
+                       IManagedForm managedForm) {\r
+               \r
+               Composite parent = managedForm.getForm().getBody();\r
+               \r
+               EditorGroupComposite composite = new EditorGroupComposite(parent, managedForm);\r
+               composite.setData(ITaxEditorConstants.MISAPPLIED_NAME,"");\r
+               new CompositeBorderDecorator(composite, managedForm);\r
+               return composite;\r
+       }\r
+       \r
+       public static IPreferenceStore getPrefStore() {\r
+               return TaxEditorPlugin.getDefault().getPreferenceStore();\r
+       }\r
+       \r
+       /**\r
+        * Returns a <code>Set</code> of the <code>Feature</code>s that the user has chosen\r
+        * to have shown in preferences.\r
+        * </p>\r
+        * <p>\r
+        * <code>Feature</code>s are shown unless otherwise specified.\r
+        * </p>\r
+        * @return\r
+        */\r
+       public static Set<Feature> getPreferredFeatures() {\r
+               \r
+               // Initialize preferredFeatureSet as necessary\r
+               if (preferredFeatureSet == null) {\r
+                       \r
+                       preferredFeatureSet = new HashSet<Feature>();   \r
+                                               \r
+                       for (Feature feature : CdmUtil.getFeatures()) {\r
+                               \r
+                               // If the feature is set to show, add it to preferredFeatureSet\r
+                               if (getFeaturePreference(feature)) {\r
+                                       preferredFeatureSet.add(feature);\r
+                               }\r
+                       }\r
+                       \r
+               }\r
+               return preferredFeatureSet;\r
+       }\r
+       \r
+       /**\r
+        * True if <code>Feature</code> is set to "show" in preferences.\r
+        * \r
+        * @param feature\r
+        * @return\r
+        */\r
+       public static boolean getFeaturePreference(Feature feature) {\r
+               \r
+               String preferenceKey = getPreferenceKey(feature);\r
+               \r
+               // If feature does not yet have a pref, set it to true\r
+               if (!getPrefStore().contains(preferenceKey)) {\r
+                       getPrefStore().setDefault(preferenceKey, true);\r
+               }\r
+               \r
+               return getPrefStore().getBoolean(preferenceKey);\r
+       }\r
+       \r
+       /**\r
+        * Set the show state of a <code>Feature</code> in the \r
+        * <code>PreferenceStore</code>.\r
+        * <p>\r
+        * Also sets <code>preferredFeatureSet</code> to null to force it be\r
+        * re-populated the next time {@link #getPreferredFeatures()} is called.\r
+        * \r
+        * @param feature\r
+        * @param show\r
+        */\r
+       public static void setFeaturePreference(Feature feature, boolean show) {\r
+               preferredFeatureSet = null;\r
+               getPrefStore().setValue(getPreferenceKey(feature), show);\r
+       }\r
+       \r
+       /**\r
+        * Construct a unique key using <code>Feature</code>'s <code>Uuid</code>\r
+        * \r
+        * @param feature\r
+        * @return\r
+        */\r
+       private static String getPreferenceKey(Feature feature) {\r
+               return ITaxEditorConstants.FEATURE_PREFERENCE \r
+                               . concat(".")\r
+                               . concat(feature.getUuid().toString());\r
+       }\r
+\r
+       /**\r
+        * Returns a <code>Set</code> of the <code>Rank</code>s that the user has chosen\r
+        * to have shown in preferences.\r
+        * </p>\r
+        * <p>\r
+        * <code>Rank</code>s are shown unless otherwise specified.\r
+        * </p>\r
+        * @return\r
+        */\r
+       public static Set<Rank> getPreferredRanks() {\r
+               \r
+               // Initialize preferredFeatureSet as necessary\r
+               if (preferredRankSet == null) {\r
+                       \r
+                       preferredRankSet = new HashSet<Rank>(); \r
+                                               \r
+                       for (Rank rank : CdmUtil.getRanks()) {\r
+                               \r
+                               // If the feature is set to show, add it to preferredFeatureSet\r
+                               if (getRankPreference(rank)) {\r
+                                       preferredRankSet.add(rank);\r
+                               }\r
+                       }\r
+                       \r
+               }\r
+               return preferredRankSet;\r
+       }       \r
+       \r
+       /**\r
+        * True if <code>Rank</code> is set to "show" in preferences.\r
+        * \r
+        * @param rank\r
+        * @return\r
+        */\r
+       public static boolean getRankPreference(Rank rank) {\r
+               \r
+               String preferenceKey = getPreferenceKey(rank);\r
+               \r
+               // If rank does not yet have a pref, set it to true\r
+               if (!getPrefStore().contains(preferenceKey)) {\r
+                       getPrefStore().setDefault(preferenceKey, true);\r
+               }\r
+               \r
+               return getPrefStore().getBoolean(preferenceKey);\r
+       }\r
+       \r
+       /**\r
+        * Set the show state of a <code>Rank</code> in the \r
+        * <code>PreferenceStore</code>.\r
+        * <p>\r
+        * Also sets <code>preferredRankSet</code> to null to force it be\r
+        * re-populated the next time {@link #getPreferredRanks()} is called.\r
+        * \r
+        * @param rank\r
+        * @param show\r
+        */     \r
+       public static void setRankPreference(Rank rank, boolean show) {\r
+               preferredRankSet = null;\r
+               getPrefStore().setValue(getPreferenceKey(rank), show);\r
+               \r
+       }\r
+       \r
+       /**\r
+        * Construct a unique key using <code>Rank</code>'s <code>Uuid</code>\r
+        * \r
+        * @param feature\r
+        * @return\r
+        */\r
+       private static String getPreferenceKey(Rank rank) {\r
+               return ITaxEditorConstants.RANK_PREFERENCE \r
+                               . concat(".")\r
+                               . concat(rank.getUuid().toString());\r
+       }       \r
+       \r
+       /**\r
+        * @return\r
+        */\r
+       public static NonViralName getPreferredNameClassInstance() {\r
+               String nameCodePreference = TaxEditorPlugin.getDefault().getPreferenceStore().getString(ITaxEditorConstants.CODE_PREFERENCE);\r
+               \r
+               // Check whether name code preference needs to be initialized\r
+               if (nameCodePreference == null || nameCodePreference.equals("")) {\r
+                       nameCodePreference = ITaxEditorConstants.DEFAULT_CODE_PREFERENCE;\r
+                       UiUtil.getPrefStore().setValue(ITaxEditorConstants.CODE_PREFERENCE, \r
+                                       nameCodePreference);\r
+               }\r
+               \r
+               if (nameCodePreference.equals(ITaxEditorConstants.CODE_PREFERENCE_ICBN)) {\r
+                       return BotanicalName.NewInstance(null);\r
+               } else if (nameCodePreference.equals(ITaxEditorConstants.CODE_PREFERENCE_ICZN)) {\r
+                       return ZoologicalName.NewInstance(null);                        \r
+               }\r
+               return NonViralName.NewInstance(null);\r
+       }\r
+       \r
+       public static String getNameCodePreference() {\r
+               String nameCodePreference = getPrefStore().getString(ITaxEditorConstants.CODE_PREFERENCE);\r
+               \r
+               // Check whether name code preference needs to be initialized\r
+               if (nameCodePreference == null || nameCodePreference.equals("")) {\r
+                       nameCodePreference = ITaxEditorConstants.DEFAULT_CODE_PREFERENCE;\r
+                       getPrefStore().setValue(ITaxEditorConstants.CODE_PREFERENCE, nameCodePreference);\r
+               }\r
+               \r
+               return nameCodePreference;\r
+       }\r
+       \r
+       /**\r
+        * @return\r
+        */\r
+       public static NomenclaturalCode getPreferredNomenclaturalCode() {\r
+\r
+               String nameCodePreference = getNameCodePreference();\r
+                               \r
+               if (nameCodePreference.equals(ITaxEditorConstants.CODE_PREFERENCE_ICBN)) {\r
+                       return NomenclaturalCode.ICBN();\r
+               } else if (nameCodePreference.equals(ITaxEditorConstants.CODE_PREFERENCE_ICZN)) {\r
+                       return NomenclaturalCode.ICZN();\r
+               }\r
+               return null;\r
+       }\r
+\r
+       /**\r
+        * Appends the code (i.e. ICBN or ICZN) specified in the user preferences\r
+        * to a string. The result is separated by a period: "<code>key.ICBN</code>".\r
+        * \r
+        * @param key\r
+        * @return\r
+        */\r
+       public static String concatCodeMessageSuffix(String key) {\r
+               String code = getNameCodePreference();\r
+               return key + "." + code;\r
+       }\r
+       \r
+       public static void setStatusMessage(String msg) {\r
+               getPropertySheet().getViewSite().getActionBars().getStatusLineManager().setMessage(msg); \r
+       }\r
+\r
+       public static void setPropertySheetTree(Tree tree) {\r
+               TaxEditorPlugin.getDefault().setPropertySheetTree(tree);                \r
+       }\r
+       \r
+       public static Tree getPropertySheetTree() {\r
+               return TaxEditorPlugin.getDefault().getPropertySheetTree();             \r
+       }\r
+\r
+       public static void setPropertySheetPage(PropertySheetPage page) {\r
+               TaxEditorPlugin.getDefault().setPropertySheetPage(page);\r
+       }\r
+       \r
+       public static PropertySheetPage getPropertySheetPage() {\r
+               return TaxEditorPlugin.getDefault().getPropertySheetPage();     \r
+       }\r
+       \r
+       /**\r
+        *              UiUtil.paintPropertySheetRow(P_DATEPUBLISHED, new Color(Display.getDefault(), WarningAnnotation.WARNING_RGB), true);\r
+        *              UiUtil.unpaintPropertySheetRow(P_DATEPUBLISHED);\r
+        * \r
+        * @param id\r
+        * @param color\r
+        * @param doPaintChildren\r
+        */\r
+       public static void paintPropertySheetRow(String id, Color color, boolean doPaintChildren) {\r
+               \r
+               // Catch null property sheet name\r
+               if (id == null) {\r
+                       return;\r
+               }\r
+               \r
+               // Catch uninit'ed property sheet tree\r
+               if (getPropertySheetTree() == null) {\r
+                       return;\r
+               }\r
+               \r
+               paintPropertySheetRow(id, color, doPaintChildren, getPropertySheetTree());\r
+       }\r
+       \r
+       private static void paintPropertySheetRow(String id, Color color, boolean doPaintChildren, Object treeOrItem) {\r
+               \r
+               // Init items w zero-length array\r
+               TreeItem[] items = new TreeItem[]{};\r
+               \r
+               // Get child items depending to class\r
+               if (treeOrItem instanceof Tree) {\r
+                       items = ((Tree) treeOrItem).getItems();\r
+               }\r
+               if (treeOrItem instanceof TreeItem) {\r
+                       items = ((TreeItem) treeOrItem).getItems();\r
+               }\r
+               \r
+               // If array hasn't been populated by the above, return\r
+               if (items.length == 0) {\r
+                       return;\r
+               }\r
+\r
+               // Prop. sheet id's take the form "01:xxxx" for sorting - truncate\r
+               id = CustomSortPropertySheetEntry.truncateDisplayName(id);\r
+               \r
+               // Iterate through child items\r
+               for (TreeItem item : items) {\r
+\r
+                       // Item found, paint it\r
+                       if (id.equals(item.getText())) {\r
+                               paintItem(item, color, doPaintChildren);\r
+                               return;\r
+                       }                       \r
+\r
+                       // Recursively search for item to paint in child items\r
+                       if (item.getItemCount() > 0) {\r
+                               paintPropertySheetRow(id, color, doPaintChildren, item);\r
+                       }\r
+               }       \r
+       }\r
+       \r
+       /**\r
+        * Note: children are only painted if submenu has already been created, i.e. opened once.\r
+        * \r
+        * @param item\r
+        * @param color\r
+        * @param doPaintChildren\r
+        */\r
+       private static void paintItem(TreeItem item, Color color, boolean doPaintChildren) {\r
+               \r
+               // Paint the item\r
+               item.setBackground(color);\r
+               \r
+               // Recursively paint child items if requested\r
+               if (doPaintChildren) {\r
+                       for (TreeItem childItem : item.getItems()) {\r
+                               paintItem(childItem, color, doPaintChildren);\r
+                       }\r
+               }\r
+       }\r
+       \r
+       public static void unpaintPropertySheetRow(String id) {\r
+               \r
+               // Catch uninit'ed property sheet tree\r
+               if (getPropertySheetTree() == null) {\r
+                       return;\r
+               }\r
+               \r
+               // Get tree's background color to "unpaint"\r
+               Color color = getPropertySheetTree().getBackground();\r
+               \r
+               paintPropertySheetRow(id, color, true);\r
+       }\r
 }
\ No newline at end of file