Pre-select country as named area type for country selection for
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / ui / selection / EntitySelectionElement.java
index ac75ba86b7a4caa422922aae28183125c2fb982c..6f87d5e634a1e55e677a1b44656a0b7b0657b89b 100644 (file)
@@ -1,9 +1,14 @@
 /**
- * 
+ *
  */
 package eu.etaxonomy.taxeditor.ui.selection;
 
+import java.util.EnumSet;
+import java.util.Observable;
+import java.util.Observer;
+
 import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.jface.wizard.WizardDialog;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.SelectionAdapter;
@@ -14,17 +19,43 @@ import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
 import org.springframework.security.core.GrantedAuthority;
 
 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
+import eu.etaxonomy.cdm.api.service.IAgentService;
+import eu.etaxonomy.cdm.api.service.ICollectionService;
+import eu.etaxonomy.cdm.api.service.INameService;
+import eu.etaxonomy.cdm.api.service.IOccurrenceService;
+import eu.etaxonomy.cdm.api.service.IReferenceService;
+import eu.etaxonomy.cdm.api.service.IService;
+import eu.etaxonomy.cdm.api.service.IUserService;
+import eu.etaxonomy.cdm.api.service.molecular.IAmplificationService;
+import eu.etaxonomy.cdm.api.service.molecular.IPrimerService;
 import eu.etaxonomy.cdm.common.CdmUtils;
+import eu.etaxonomy.cdm.model.agent.Institution;
+import eu.etaxonomy.cdm.model.agent.Person;
+import eu.etaxonomy.cdm.model.agent.Team;
+import eu.etaxonomy.cdm.model.common.CdmBase;
 import eu.etaxonomy.cdm.model.common.Group;
 import eu.etaxonomy.cdm.model.common.ICdmBase;
 import eu.etaxonomy.cdm.model.common.IIdentifiableEntity;
+import eu.etaxonomy.cdm.model.common.User;
+import eu.etaxonomy.cdm.model.molecular.Amplification;
+import eu.etaxonomy.cdm.model.molecular.Primer;
+import eu.etaxonomy.cdm.model.name.NonViralName;
+import eu.etaxonomy.cdm.model.occurrence.Collection;
+import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
+import eu.etaxonomy.cdm.model.reference.Reference;
 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
+import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
+import eu.etaxonomy.taxeditor.model.AbstractUtility;
 import eu.etaxonomy.taxeditor.model.ImageResources;
+import eu.etaxonomy.taxeditor.model.MessagingUtils;
 import eu.etaxonomy.taxeditor.preference.Resources;
+import eu.etaxonomy.taxeditor.store.CdmStore;
+import eu.etaxonomy.taxeditor.store.LoginManager;
 import eu.etaxonomy.taxeditor.store.StoreUtil;
 import eu.etaxonomy.taxeditor.ui.dialog.selection.SelectionDialogFactory;
 import eu.etaxonomy.taxeditor.ui.element.AbstractCdmFormElement;
@@ -34,25 +65,27 @@ import eu.etaxonomy.taxeditor.ui.element.ICdmFormElement;
 import eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement;
 import eu.etaxonomy.taxeditor.ui.element.IEntityElement;
 import eu.etaxonomy.taxeditor.ui.element.ILabeledElement;
-import eu.etaxonomy.taxeditor.ui.element.ISelectable;
 import eu.etaxonomy.taxeditor.ui.element.ISelectableElement;
 import eu.etaxonomy.taxeditor.ui.element.LayoutConstants;
 import eu.etaxonomy.taxeditor.ui.element.SelectionArbitrator;
+import eu.etaxonomy.taxeditor.ui.section.grantedAuthority.GrantedAuthorityLabelTextProvider;
 
 /**
  * <p>
  * Abstract AbstractSelectionElement class.
  * </p>
- * 
+ *
  * @author n.hoffmann
  * @created Nov 17, 2009
  * @version 1.0
  * @param <T>
  */
 public class EntitySelectionElement<T extends ICdmBase> extends
-               AbstractCdmFormElement implements SelectionListener,
-               IEnableableFormElement, ISelectableElement, IEntityElement<T>,
-               ILabeledElement, IConversationEnabled, ISelectable {
+               AbstractCdmFormElement implements  SelectionListener, IEnableableFormElement, ISelectableElement, IEntityElement<T>, ILabeledElement, IConversationEnabled, Observer {
+
+       private static final EnumSet<CRUD> UPDATE = EnumSet.of(CRUD.UPDATE);
+       private static final EnumSet<CRUD> DELETE = EnumSet.of(CRUD.DELETE);
+       private static final EnumSet<CRUD> CREATE = EnumSet.of(CRUD.CREATE);
 
        /**
         * Bitmask for configuring functionality of selection element
@@ -66,7 +99,7 @@ public class EntitySelectionElement<T extends ICdmBase> extends
        protected T entity;
 
        protected Label label;
-       protected Label text;
+       protected Text text;
        protected Button button_selection;
 
        private SelectionArbitrator selectionArbitrator;
@@ -90,7 +123,7 @@ public class EntitySelectionElement<T extends ICdmBase> extends
         * <p>
         * Constructor for AbstractSelectionElement.
         * </p>
-        * 
+        *
         * @param formFactory
         *            a {@link eu.etaxonomy.taxeditor.ui.element.CdmFormFactory}
         *            object.
@@ -122,8 +155,8 @@ public class EntitySelectionElement<T extends ICdmBase> extends
                this.isEditable = (mode & EDITABLE) == EDITABLE;
                this.isDeletable = (mode & DELETABLE) == DELETABLE;
                boolean isSelectable = (mode & SELECTABLE) == SELECTABLE;
-               
-               this.labelString = labelString;
+
+               this.labelString = (labelString == null || labelString.equals("")) ? "" : labelString + " : ";
 
                this.conversation = conversation;
 
@@ -135,7 +168,7 @@ public class EntitySelectionElement<T extends ICdmBase> extends
 
                setEntity(entity);
        }
-       
+
        public EntitySelectionElement(CdmFormFactory formFactory,
                        ConversationHolder conversation, ICdmFormElement parentElement, Class<T> clazz,
                        String labelString, T entity, int mode, int style) {
@@ -145,7 +178,7 @@ public class EntitySelectionElement<T extends ICdmBase> extends
 
        private void createControls(Composite parent, int style) {
 
-               label = formFactory.createLabel(getLayoutComposite(), labelString + " : ",
+               label = formFactory.createLabel(getLayoutComposite(), labelString,
                                SWT.NULL);
 
                addControl(label);
@@ -165,7 +198,8 @@ public class EntitySelectionElement<T extends ICdmBase> extends
 
                addControl(selectableComposite);
 
-               text = formFactory.createLabel(selectableComposite, null, SWT.WRAP);
+               text = formFactory.createText(selectableComposite, null, SWT.WRAP);
+               text.setEditable(false);
                addControl(text);
 
                text.setLayoutData(LayoutConstants.FILL_HORIZONTALLY());
@@ -177,7 +211,7 @@ public class EntitySelectionElement<T extends ICdmBase> extends
                button_selection.setImage(ImageResources
                                .getImage(ImageResources.BROWSE_ICON));
                button_selection.setToolTipText("Browse existing");
-               
+
                addControl(button_selection);
                button_selection.addSelectionListener(this);
 
@@ -202,14 +236,15 @@ public class EntitySelectionElement<T extends ICdmBase> extends
                }
        }
 
-       public void widgetSelected(SelectionEvent e) {
-               T selection = SelectionDialogFactory.getSelectionFromDialog(clazz, getShell(), getConversationHolder(), getEntity());
+       @Override
+    public void widgetSelected(SelectionEvent e) {
+               T selection = SelectionDialogFactory.getSelectionFromDialog(clazz, getShell(), getConversationHolder(), getEntity(), getParentElement());
                setSelectionInternal(selection);
        }
-       
+
        /**
         * Return the selected object
-        * 
+        *
         * @return a T object.
         */
        public T getSelection() {
@@ -218,7 +253,7 @@ public class EntitySelectionElement<T extends ICdmBase> extends
 
        /*
         * (non-Javadoc)
-        * 
+        *
         * @see
         * eu.etaxonomy.taxeditor.forms.IEnableableFormElement#setEnabled(boolean)
         */
@@ -227,15 +262,23 @@ public class EntitySelectionElement<T extends ICdmBase> extends
        public void setEnabled(boolean enabled) {
                button_selection.setEnabled(enabled);
                if (isEditable) {
-                       button_edit.setEnabled(enabled && entity != null);
+                       updateButtonStates();
                }
        }
 
+       /* (non-Javadoc)
+        * @see eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement#isEnabled()
+        */
+       @Override
+       public boolean isEnabled() {
+           return button_selection.isEnabled();
+       }
+
        /**
         * <p>
         * setSelectionInternal
         * </p>
-        * 
+        *
         * @param selection
         *            a T object.
         */
@@ -250,7 +293,7 @@ public class EntitySelectionElement<T extends ICdmBase> extends
         * <p>
         * Setter for the field <code>entity</code>.
         * </p>
-        * 
+        *
         * @param selection
         *            a T object.
         */
@@ -264,21 +307,13 @@ public class EntitySelectionElement<T extends ICdmBase> extends
         */
        protected void updateElement() {
                String title = CdmUtils.Nz(getTitle());
-               // we have to duplicate ampersands otherwise they are treated as
-               // mnenomic (see Label.setText() documentation)
-               title = title.replace("&", "&&");
                text.setText(title); // title can be null
                if (isEditable) {
-                       button_edit.setEnabled(entity != null);
+                       updateButtonStates();
                }
        }
 
-       /**
-        * <p>
-        * updateFromWizard
-        * </p>
-        */
-       protected void updateFromWizard() {
+    public void updateFromWizard() {
                updateElement();
                firePropertyChangeEvent(new CdmPropertyChangeEvent(this, null));
        }
@@ -287,7 +322,7 @@ public class EntitySelectionElement<T extends ICdmBase> extends
         * <p>
         * getTitle
         * </p>
-        * 
+        *
         * @return a {@link java.lang.String} object.
         */
        protected String getTitle() {
@@ -297,8 +332,15 @@ public class EntitySelectionElement<T extends ICdmBase> extends
                        } else if(entity instanceof Group){
                                return ((Group) entity).getName();
                        } else if(entity instanceof GrantedAuthority){
-                               return ((GrantedAuthority) entity).getAuthority();
-                       }
+                               return GrantedAuthorityLabelTextProvider.getText(((GrantedAuthority) entity));
+                       } else if(entity instanceof User){
+                return ((User) entity).getUsername();
+            } else if (entity instanceof Primer){
+                return ((Primer) entity).getLabel();
+            } else if (entity instanceof Amplification){
+                return ((Amplification) entity).getLabelCache();
+            }
+
                }
                return "";
        }
@@ -311,14 +353,14 @@ public class EntitySelectionElement<T extends ICdmBase> extends
 
        /*
         * (non-Javadoc)
-        * 
+        *
         * @see eu.etaxonomy.taxeditor.forms.IEntityElement#getEntity()
         */
        /**
         * <p>
         * Getter for the field <code>entity</code>.
         * </p>
-        * 
+        *
         * @return a T object.
         */
        @Override
@@ -328,7 +370,7 @@ public class EntitySelectionElement<T extends ICdmBase> extends
 
        /*
         * (non-Javadoc)
-        * 
+        *
         * @see eu.etaxonomy.taxeditor.forms.section.cdmdetail.ISelectableElement#
         * getSelectionArbitrator()
         */
@@ -336,7 +378,7 @@ public class EntitySelectionElement<T extends ICdmBase> extends
         * <p>
         * Getter for the field <code>selectionArbitrator</code>.
         * </p>
-        * 
+        *
         * @return a {@link eu.etaxonomy.taxeditor.ui.element.SelectionArbitrator}
         *         object.
         */
@@ -347,10 +389,10 @@ public class EntitySelectionElement<T extends ICdmBase> extends
 
        /**
         * Convenient access to current shell
-        * 
+        *
         * @return a {@link org.eclipse.swt.widgets.Shell} object.
         */
-       protected Shell getShell() {
+    public Shell getShell() {
                return getLayoutComposite().getShell();
        }
 
@@ -382,7 +424,9 @@ public class EntitySelectionElement<T extends ICdmBase> extends
 
        private class EditListener extends SelectionAdapter {
 
-               private final EntitySelectionElement<T> selectionElement;
+        private static final String TRANSIENT_EDITING_WARNING_TEXT = "Warning: All changes for this element are directly reflected in the data base.\nThe \"Cancel\" button has no effect";
+        private static final String TRANSIENT_EDITING_WARNING_TITLE = "CDM element not yet saved.";
+        private final EntitySelectionElement<T> selectionElement;
 
                public EditListener(EntitySelectionElement<T> selectionElement) {
                        this.selectionElement = selectionElement;
@@ -391,11 +435,80 @@ public class EntitySelectionElement<T extends ICdmBase> extends
                /** {@inheritDoc} */
                @Override
                public void widgetSelected(SelectionEvent e) {
+                   T originalEntity = selectionElement.getEntity();
+                   T clonedEntity = null;
+                   IService<T> service = null;
+                   if(originalEntity instanceof CdmBase){
+                       //get corresponding service
+                       if(entity instanceof Reference<?>){
+                           service = (IService<T>) CdmStore.getService(IReferenceService.class);
+                       }
+                       else if (entity instanceof Team || entity instanceof Person || entity instanceof Institution) {
+                           service = (IService<T>) CdmStore.getService(IAgentService.class);
+                       }
+                       else if (entity instanceof NonViralName) {
+                           service = (IService<T>) CdmStore.getService(INameService.class);
+                       }
+                       else if (entity instanceof SpecimenOrObservationBase) {
+                           service = (IService<T>) CdmStore.getService(IOccurrenceService.class);
+                       }
+                       else if (entity instanceof Collection) {
+                           service = (IService<T>) CdmStore.getService(ICollectionService.class);
+                       }
+                       else if (entity instanceof User) {
+                           service = (IService<T>) CdmStore.getService(IUserService.class);
+                       }
+                       else if (entity instanceof Primer) {
+                           service = (IService<T>) CdmStore.getService(IPrimerService.class);
+                       }
+                       else if (entity instanceof Amplification) {
+                           service = (IService<T>) CdmStore.getService(IAmplificationService.class);
+                       }
+                       //check if original already exists in data base. If not then do not clone and all changes will be persisted directly -> Warning to user.
+                if(service !=null && service.find(originalEntity.getUuid())==null && originalEntity.getId() != 0){
+                    if(MessagingUtils.confirmDialog(TRANSIENT_EDITING_WARNING_TITLE, "["+originalEntity.getClass().getSimpleName()+"]"+originalEntity + " has to be saved before it can be edited. Save now?")){
+                        service.save(originalEntity);
+                        AbstractUtility.getActiveEditor().doSave(new NullProgressMonitor());
+                    }
+                    else{
+                        //transient CDM elements should not be edited to avoid merge conflicts
+                        // when the elements are cascaded
+                        return;
+                    }
+                }
+                else{
+                    //FIXME temporarily disabled cloning re-opening bug #2645 (EditFromSelectionWizard persists data even when canceled)
+//                    try {
+//                        //clone original
+//                        clonedEntity = (T) ((CdmBase) originalEntity).clone();
+//                    } catch (CloneNotSupportedException e1) {
+//                        MessagingUtils.warningDialog(TRANSIENT_EDITING_WARNING_TITLE, this, TRANSIENT_EDITING_WARNING_TEXT);
+//                    }
+                }
+
+                   }
+                   if(clonedEntity!=null){
+                       selectionElement.setEntity(clonedEntity);
+                   }
                        WizardDialog dialog = new WizardDialog(selectionElement.getShell(),
                                        new EditFromSelectionWizard(selectionElement));
                        if (dialog.open() == IStatus.OK) {
+                           if(service!=null && clonedEntity!=null){//check if cloning happened
+                               T editedClonedEntity = selectionElement.getEntity();
+                               editedClonedEntity.setId(originalEntity.getId());
+                               editedClonedEntity.setUuid(originalEntity.getUuid());
+
+                               //merge clone and original
+                               service.merge(editedClonedEntity);
+                               originalEntity = service.load(originalEntity.getUuid());
+
+                           }
+                           selectionElement.setEntity(originalEntity);
                                selectionElement.updateFromWizard();
                        }
+                       //be sure to reset to original in all cases
+                       selectionElement.setEntity(originalEntity);
+                       selectionElement.refresh();
                }
        }
 
@@ -409,7 +522,7 @@ public class EntitySelectionElement<T extends ICdmBase> extends
         * <p>
         * getConversationHolder
         * </p>
-        * 
+        *
         * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
         *         object.
         */
@@ -421,7 +534,9 @@ public class EntitySelectionElement<T extends ICdmBase> extends
        /** {@inheritDoc} */
        @Override
        public void setBackground(Color color) {
-               label.setBackground(color);
+           if(!label.isDisposed()){
+               label.setBackground(color);
+           }
        }
 
        /** {@inheritDoc} */
@@ -436,7 +551,7 @@ public class EntitySelectionElement<T extends ICdmBase> extends
         * <p>
         * Getter for the field <code>label</code>.
         * </p>
-        * 
+        *
         * @return a {@link java.lang.String} object.
         */
        @Override
@@ -451,4 +566,27 @@ public class EntitySelectionElement<T extends ICdmBase> extends
        @Override
        public void update(CdmDataChangeMap changeEvents) {
        }
+
+       /* (non-Javadoc)
+        * @see eu.etaxonomy.taxeditor.ui.element.AbstractCdmFormElement#removeElements()
+        */
+       @Override
+    public void removeElements(){
+               super.removeElements();
+               LoginManager loginManager = CdmStore.getLoginManager();
+               loginManager.addObserver(this);
+       }
+
+       @Override
+       public void update(Observable o, Object arg) {
+               if(o instanceof LoginManager){
+                       updateButtonStates();
+               }
+       }
+
+       private void updateButtonStates() {
+           if(button_edit != null && !button_selection.isDisposed()){
+               button_edit.setEnabled(isEditable && button_selection.isEnabled() && getEntity() != null  && CdmStore.currentAuthentiationHasPermission((CdmBase) getEntity(), UPDATE));
+           }
+       }
 }