Merge branch 'release/5.10.0'
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / store / StoreUtil.java
index 1b9c4fdb422772996414d10790184f0e73041f08..dec333f61b7072bf2cf09dc1d45a364dc181c0cf 100644 (file)
@@ -1,4 +1,3 @@
-// $Id$
 /**
 * Copyright (C) 2007 EDIT
 * European Distributed Institute of Taxonomy
@@ -14,14 +13,29 @@ import java.util.UUID;
 
 import org.eclipse.core.commands.operations.IOperationHistory;
 import org.eclipse.core.commands.operations.IUndoContext;
+import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.jface.action.IStatusLineManager;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorPart;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.widgets.ExpandableComposite;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
 
 import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;
+import eu.etaxonomy.cdm.common.CdmUtils;
 import eu.etaxonomy.cdm.model.common.CdmBase;
+import eu.etaxonomy.cdm.model.term.TermNode;
+import eu.etaxonomy.taxeditor.l10n.Messages;
 import eu.etaxonomy.taxeditor.model.AbstractUtility;
+import eu.etaxonomy.taxeditor.model.FeatureNodeContainer;
+import eu.etaxonomy.taxeditor.model.MessagingUtils;
+import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
 import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
+import eu.etaxonomy.taxeditor.ui.element.AbstractFormSection;
+import eu.etaxonomy.taxeditor.view.detail.CdmSectionPart;
+import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
 
 /**
  * <p>StoreUtil class.</p>
@@ -46,21 +60,26 @@ public class StoreUtil extends AbstractUtility {
 
        /**
         * If the object given is already a {@link CdmBase} then it is returned.<br>
-        * If it is a facade then it is asked for its "responsible" CdmBase entity.<br>
+        * If it is a kind of "container" for CDM objects then it is asked for its "responsible" CdmBase entity.<br>
         * Otherwise an exception is thrown.
         * @param object the object to test for CdmBase
         * @return a CdmBase object
-        * @throws IllegalArgumentException if the tested object is neither a CdmBase nor a facade
+        * @throws IllegalArgumentException if the tested object is neither a CdmBase nor a CDM "container"
         */
        public static CdmBase getCdmEntity(Object object){
         // TODO temporary solution for ticket #4091????
-        if(object instanceof DerivedUnitFacade){
+        if (object == null){
+               return null;   //not sure if an object should ever be null at this point, but this needs to be handled in calling methods
+        }else if(object instanceof DerivedUnitFacade){
             return ((DerivedUnitFacade)object).baseUnit();
         }
+        else if(object instanceof FeatureNodeContainer){
+            return ((FeatureNodeContainer) object).getFeatureNode();
+        }
         else if(object instanceof CdmBase){
             return (CdmBase) object;
         }
-        throw new IllegalArgumentException("Object is neither a CdmBase nor an EntityFacade");
+        throw new IllegalArgumentException("Object " + object.toString() + " is neither a CdmBase nor a CDM \"container\"");
        }
 
        /**
@@ -82,6 +101,19 @@ public class StoreUtil extends AbstractUtility {
                statusLineManager = manager;
        }
 
+       public static void reflowParentScrolledForm(Composite composite, boolean flushCashes){
+        ScrolledForm scrolledForm = null;
+        Composite parent = composite;
+        while(parent!=null && !(parent instanceof ScrolledForm)){
+            parent = parent.getParent();
+        }
+        scrolledForm = (ScrolledForm)parent;
+        if(scrolledForm!=null){
+            scrolledForm.reflow(flushCashes);
+            scrolledForm.redraw();
+        }
+    }
+
 
        /**
         * <p>getUndoContext</p>
@@ -101,15 +133,125 @@ public class StoreUtil extends AbstractUtility {
                return TaxeditorStorePlugin.PLUGIN_ID;
        }
 
-       /**
-        *
-        * @return
-        */
-       public static IEditorInput getActiveEditorInput() {
-               IEditorPart activeEditor = getActiveEditor();
-               if (activeEditor != null){
-                       return activeEditor.getEditorInput();
-               }
-               return null;
+    /**
+     * Cleans title string for output in section titles<br>
+     * E.g. escapes '&' with "&&" to avoid mnemonic handling (see
+     * Label.setText() documentation)<br>
+     * see also #4302
+     *
+     * @param title
+     *            the title string to clean
+     * @return the cleaned title string
+     */
+       public static String cleanTitleString(String title){
+           return title.replace("&", "&&");
        }
+
+    public static String getPrefKey(Class<? extends AbstractFormSection> sectionClass, String entity) {
+        return sectionClass.getCanonicalName()+";"+entity;
+    }
+
+    /**
+     * Checks the dirty flag and, if set, prompts the user to optionally save
+     * the editor
+     *
+     * @return <code>false</code> if the editor is not dirty anymore, either
+     *         because it wasn't beforehand or because it has been saved.
+     *         <code>true</code> otherwise
+     */
+    public static boolean promptCheckIsDirty(IE4SavablePart editor){
+        if (editor.isDirty()){
+            boolean proceed = MessageDialog.openQuestion(null,
+                    Messages.DefinedTermEditorE4_SAVE_TITLE, Messages.DefinedTermEditorE4_SAVE_MESSAGE);
+            if (proceed) {
+                editor.save(new NullProgressMonitor());
+                return false;
+            }
+            else{
+                return true;
+            }
+        }
+        else{
+            return false;
+        }
+    }
+
+    public static boolean confirmDelete(){
+        return MessagingUtils.confirmDialog("Confirm deletion", "Do you really want to delete the selected element(s)?");
+    }
+
+    /**
+     * Compares the two given input strings considering the given search string.<br>
+     * Strings will be sorted according to <br>
+     * <ol>
+     * <li> result begins with search string
+     * <li> string length
+     * <li> result contains search string
+     * <li> string length
+     * <li> alphabetically
+     * </ol>
+     */
+    public static int compareBySearchString(String searchString, String string1, String string2) {
+        string1 = string1.toLowerCase();
+        string2 = string2.toLowerCase();
+        //1. search string at the beginning
+        if(string1.startsWith(searchString)){
+            if(!string2.startsWith(searchString)){
+                return -1;
+            }
+            else{
+                return string1.compareTo(string2);
+            }
+        }
+        else if(string2.startsWith(searchString)){
+            return 1;
+        }
+        //2. label that contains search string
+        if(string1.contains(searchString)){
+            if(!string2.contains(searchString)){
+                return -1;
+            }
+        }
+        else if(string2.contains(searchString)){
+            return 1;
+        }
+        return string1.compareTo(string2);
+    }
+
+    public static int getSectionStyle(Class<? extends AbstractFormSection> clazz, String input){
+        return StoreUtil.getSectionStyle(clazz, input, false);
+    }
+
+    public static int getSectionStyle(Class<? extends AbstractFormSection> clazz, String input, boolean initiallyExpanded){
+        int style = ExpandableComposite.TWISTIE;
+        String prefKey = getPrefKey(clazz, input);
+        if(PreferencesUtil.contains(prefKey)){
+            style = PreferencesUtil.getStringValue(prefKey).equals(CdmSectionPart.EXPANDED)?style |= ExpandableComposite.EXPANDED:style;
+        }
+        else{
+            style = initiallyExpanded?style |= ExpandableComposite.EXPANDED:style;
+        }
+        return style;
+    }
+
+    public static String getPath(TermNode node){
+        String path = node.getTerm().getLabel();
+        TermNode parent = node.getParent();
+        while(parent != null && parent.getTerm()!=null){
+            path = parent.getTerm().getLabel() + "/" + path;
+            parent = parent.getParent();
+        }
+        return path;
+    }
+
+    public static void setTextWithoutModifyListeners(Text text, String string){
+        Listener[] listeners = text.getListeners(SWT.Modify);
+        for (Listener listener : listeners) {
+            text.removeListener(SWT.Modify, listener);
+        }
+        text.setText(CdmUtils.Nz(string));
+        for (Listener listener : listeners) {
+            text.addListener(SWT.Modify, listener);
+        }
+    }
 }