X-Git-Url: https://dev.e-taxonomy.eu/gitweb/taxeditor.git/blobdiff_plain/021fa6b55017cd6df3d92bbc791ea5e71c7e82f6..97623d1d8b0c5a56c6fa5140e04045985c44beb8:/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/section/AbstractEntityCollectionSection.java diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/section/AbstractEntityCollectionSection.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/section/AbstractEntityCollectionSection.java index 69f4921f0..81ece03c2 100644 --- a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/section/AbstractEntityCollectionSection.java +++ b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/section/AbstractEntityCollectionSection.java @@ -1,15 +1,20 @@ /** - * + * */ package eu.etaxonomy.taxeditor.ui.section; import java.util.Collection; +import java.util.EnumSet; +import java.util.Observable; +import java.util.Observer; -import org.apache.commons.collections.CollectionUtils; import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.ToolBarManager; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; @@ -20,120 +25,159 @@ import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.ui.forms.events.ExpansionEvent; import org.eclipse.ui.forms.events.IExpansionListener; -import org.eclipse.ui.forms.widgets.Section; +import org.eclipse.ui.forms.widgets.ExpandableComposite; import eu.etaxonomy.cdm.api.conversation.ConversationHolder; import eu.etaxonomy.cdm.common.CdmUtils; +import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD; +import eu.etaxonomy.taxeditor.model.AbstractUtility; import eu.etaxonomy.taxeditor.model.ImageResources; import eu.etaxonomy.taxeditor.preference.IPreferenceKeys; import eu.etaxonomy.taxeditor.preference.PreferencesUtil; 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.forms.AbstractFormSection; -import eu.etaxonomy.taxeditor.ui.forms.CdmFormFactory; -import eu.etaxonomy.taxeditor.ui.forms.ICdmFormElement; +import eu.etaxonomy.taxeditor.ui.element.AbstractFormSection; +import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory; +import eu.etaxonomy.taxeditor.ui.element.ICdmFormElement; /** - *

Abstract AbstractEntityCollectionSection class.

+ * This class visualizes an CDM entity of type ENTITY and additionally provides the functionality to add + * other elements of type ELEMENT to them. + * + * @param A CDM entity which should be visualized by this section. + * @param An element that can be added (multiple times) to this entity. * * @author n.hoffmann * @version $Id: $ */ -public abstract class AbstractEntityCollectionSection extends AbstractFormSection implements IExpansionListener{ - - protected Composite container; - + +public abstract class AbstractEntityCollectionSection extends AbstractFormSection implements IExpansionListener, Observer { + + private static final EnumSet UPDATE = EnumSet.of(CRUD.UPDATE); + + protected Composite container; + private Label label_empty; private String title; - - /** - *

Constructor for AbstractEntityCollectionSection.

- * - * @param conversation - * @param parentElement a {@link eu.etaxonomy.taxeditor.ui.forms.ICdmFormElement} object. - * @param style a int. - * @param formFactory a {@link eu.etaxonomy.taxeditor.ui.forms.CdmFormFactory} object. - * @param title a {@link java.lang.String} object. - * @param a ENTITY object. - * @param a ELEMENT object. - */ + + private AbstractEntityCollectionElement entityCollectionElement; + public AbstractEntityCollectionSection(CdmFormFactory formFactory, ConversationHolder conversation, ICdmFormElement parentElement, String title, int style) { - super(formFactory, parentElement, Section.CLIENT_INDENT | style); + super(formFactory, parentElement, ExpandableComposite.CLIENT_INDENT | style); this.title = title; this.setText(getTitleString()); - showToolbar(); - + updateToolbar(); + addExpansionListener(this); + + CdmStore.getLoginManager().addObserver(this); + addDisposeListener(new DisposeListener() { + @Override + public void widgetDisposed(DisposeEvent e) { + CdmStore.getLoginManager().deleteObserver(AbstractEntityCollectionSection.this); + } + }); } - + protected Control createToolbar() { ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT); - - Action addAction = new Action("add", Action.AS_PUSH_BUTTON){ - /* (non-Javadoc) - * @see org.eclipse.jface.action.Action#run() - */ + + Action addAction = new Action("Add", IAction.AS_PUSH_BUTTON){ @Override public void run() { - ELEMENT element = createNewElement(); - if(element != null){ - addElement(element); - if(! getSection().isExpanded()) - getSection().setExpanded(true); - internalUpdateSection(true); - } + ELEMENT element = createNewElement(); + if(element != null){ + addElement(element); + if(! getSection().isExpanded()) { + getSection().setExpanded(true); + } + internalUpdateSection(true); + } } }; addAction.setImageDescriptor(new ImageDescriptor() { - + @Override public ImageData getImageData() { return ImageResources.getImage(ImageResources.ADD_ICON).getImageData(); } }); addAction.setToolTipText(getTooltipString()); - + + Action browseAction = null; + if(allowAddExisting()){ + browseAction = new Action("Browse", IAction.AS_PUSH_BUTTON){ + @Override + public void run() { + ELEMENT element = addExisting(); + if(element != null){ + addElement(element); + if(! getSection().isExpanded()) { + getSection().setExpanded(true); + } + internalUpdateSection(true); + } + } + }; + browseAction.setImageDescriptor(new ImageDescriptor() { + + @Override + public ImageData getImageData() { + return ImageResources.getImage(ImageResources.BROWSE_ICON).getImageData(); + } + }); + browseAction.setToolTipText("Browse"); + } + toolBarManager.add(addAction); - + if(browseAction!=null){ + toolBarManager.add(browseAction); + } + return toolBarManager.createControl(this); } - + + /** + * using this method is discouraged, use updateToolBar() instead + */ public void showToolbar(){ setTextClient(createToolbar()); } - + + /** + * using this method is discouraged, use updateToolBar() instead + */ public void removeToolbar(){ setTextClient(null); } - - /** - *

setEntity

- * - * @param entity a ENTITY object. - */ + @Override public void setEntity(ENTITY entity) { - if(entity != null && hasCollectionChanged(entity)){ + if(entity != null){ super.setEntity(entity); internalUpdateSection(false); } setSectionTitle(); + updateToolbar(); layout(); - }; - + } + /** * Sets the title for the section. Adds a "+" sign if the collection is not empty for this section. * Override in subclasses if you want to have a different behaviour. */ protected void setSectionTitle() { - if(getCollection(getEntity()) != null && getCollection(getEntity()).size() > 0){ + Collection collection = getCollection(getEntity()); + if(collection != null && collection.size() > 0){ this.setText(getTitleString() + " +"); }else{ this.setText(getTitleString()); } } - + /** * Removes all content from the container */ @@ -144,97 +188,67 @@ public abstract class AbstractEntityCollectionSection extends A } removeElements(); } - + /** * Call this method after dynamically changing the client area. - * If the options changed is set to true, will also fire a state changed + * If the options changed is set to true, will also fire a state changed * event to inform the user of unsaved changes. * * @param changed a boolean. */ protected void internalUpdateSection(boolean changed){ + setSectionTitle(); destroyDynamicContent(); - if(isExpanded() || expandSectionWhenContentAvailable()) - renderContent(isExpanded()); - if(changed) - firePropertyChangeEvent(this); - } - - /** - * Whether the entities specific collection changed - * - * @param newEntity - * @return - */ - private boolean hasCollectionChanged(ENTITY newEntity){ - - // return true on null - if(getEntity() == null || newEntity == null) return true; - - // if the entities differ the collection has changed - if(! getEntity().equals(newEntity)) return true; - - Collection oldCollection = getCollection(getEntity()); - Collection newCollection = getCollection(newEntity); - - // return true on null - if(oldCollection == null || newCollection == null) return true; - - // if the collections are object equal, check if the content is equal, too - if(oldCollection.equals(newCollection)){ - - boolean equal = CollectionUtils.isEqualCollection(oldCollection, newCollection); - // return true when collections are not equal - return equal ? false : true; - } - return true; + if(isExpanded() || expandSectionWhenContentAvailable()) { + renderContent(isExpanded()); + } + if(changed) { + firePropertyChangeEvent(this); + } } /** - * Create the elements to be shown in this seciton client area + * Create the elements to be shown in this section client area */ private void renderContent(boolean forceExpansion) { Collection elements = getCollection(getEntity()); - + if(elements == null || elements.isEmpty()){ createEmptyContent(); }else{ createDynamicContents(elements); forceExpansion = true; } - + this.setExpanded(forceExpansion); - + reflow(); } - - /** - *

createEmptyContent

- */ + protected void createEmptyContent(){ label_empty = formFactory.createLabel(getLayoutComposite(), getEmptyString()); } - + /** * Creates the widgets for the collection * * @param elements a {@link java.util.Collection} object. */ protected void createDynamicContents(Collection elements) - { + { int i = 0; for(final ELEMENT element : elements){ SelectionAdapter removeListener = new SelectionAdapter(){ @Override public void widgetSelected(SelectionEvent e) { - removeElement(element); + removeElement(element); internalUpdateSection(true); } }; boolean modulo = i++%2 == 0; String colorResource = modulo ? Resources.COLOR_LIST_EVEN : Resources.COLOR_LIST_ODD; - createElementComposite(element, removeListener, StoreUtil.getColor(colorResource)); + createElementComposite(element, removeListener, AbstractUtility.getColor(colorResource)); } } @@ -246,12 +260,9 @@ public abstract class AbstractEntityCollectionSection extends A * @param backgroundColor a {@link org.eclipse.swt.graphics.Color} object. */ protected void createElementComposite(ELEMENT element, SelectionListener removeListener, Color backgroundColor){ - AbstractEntityCollectionElement formElement = formFactory.createEntityCollectionElement(this, element, removeListener, backgroundColor, SWT.NULL); + entityCollectionElement = formFactory.createEntityCollectionElement(this, element, removeListener, backgroundColor, SWT.NULL); } - - /* (non-Javadoc) - * @see eu.etaxonomy.taxeditor.forms.section.AbstractEditorFormSection#setBackground(org.eclipse.swt.graphics.Color) - */ + /** {@inheritDoc} */ @Override public void setBackground(Color color) { @@ -269,7 +280,7 @@ public abstract class AbstractEntityCollectionSection extends A public String getTitleString() { return CdmUtils.Nz(title); } - + /** *

setTitleString

* @@ -280,25 +291,57 @@ public abstract class AbstractEntityCollectionSection extends A setSectionTitle(); layout(); } - + /** {@inheritDoc} */ - public void expansionStateChanging(ExpansionEvent e) { + @Override + public void expansionStateChanging(ExpansionEvent e) { // logger.warn("Expansion State Changing"); } - + /** {@inheritDoc} */ - public void expansionStateChanged(ExpansionEvent e) { + @Override + public void expansionStateChanged(ExpansionEvent e) { if(isExpanded()){ renderContent(isExpanded()); }else{ destroyDynamicContent(); } } - + private boolean expandSectionWhenContentAvailable(){ return PreferencesUtil.getPreferenceStore().getBoolean(IPreferenceKeys.SHOULD_EXPAND_SECTION_WHEN_DATA_AVAILABLE); } - + + /** + * Remove an element from the entities collection and update the section + * + * @param element a ELEMENT object. + */ + public void removeElementAndUpdate(ELEMENT element) { + removeElement(element); + internalUpdateSection(true); + } + + @Override + public void update(Observable o, Object arg){ + if(o instanceof LoginManager){ + updateToolbar(); + } + } + + private void updateToolbar() { + if(getEntity() != null && CdmStore.currentAuthentiationHasPermission(StoreUtil.getCdmEntity(getEntity()), UPDATE)){ + showToolbar(); + } else { + removeToolbar(); + } + } + + public AbstractEntityCollectionElement getEntityCollectionElement() { + return entityCollectionElement; + } + + /** * Get the specific collection of this entity * @@ -306,39 +349,56 @@ public abstract class AbstractEntityCollectionSection extends A * @return a {@link java.util.Collection} object. */ public abstract Collection getCollection(ENTITY entity); - + /** * Create a new Element for this collection * * @return a ELEMENT object. */ public abstract ELEMENT createNewElement(); - + /** * Add an element to the entities collection * * @param element a ELEMENT object. */ public abstract void addElement(ELEMENT element); - + + /** + * Add an existing element to the entities collection. + * @return the existing element + */ + public abstract ELEMENT addExisting(); + + /** + * If true the section will also display + * a browse icon to choose from existing elements. + *
+ * Note: when returning true you have to make sure + * to implement the {@link #addExisting()} method + * @return true if existing entities can be added; + * false otherwise + */ + public abstract boolean allowAddExisting(); + /** * Remove an element from the entities collection * * @param element a ELEMENT object. */ public abstract void removeElement(ELEMENT element); - + /** * String to display when the collection is empty * * @return a {@link java.lang.String} object. */ public abstract String getEmptyString(); - + /** *

getTooltipString

* * @return String to display when hovering the add button */ - protected abstract String getTooltipString(); + protected abstract String getTooltipString(); }