\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
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
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
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
}\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
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
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
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