2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
10 package eu
.etaxonomy
.taxeditor
.editor
.name
;
12 import java
.awt
.Color
;
13 import java
.awt
.Composite
;
15 import java
.awt
.dnd
.DropTarget
;
16 import java
.util
.ArrayList
;
17 import java
.util
.HashSet
;
18 import java
.util
.List
;
21 import eu
.etaxonomy
.taxeditor
.editor
.CdmDataTransfer
;
22 import eu
.etaxonomy
.taxeditor
.editor
.IDropTargetable
;
23 import eu
.etaxonomy
.taxeditor
.editor
.IMultiPageTaxonEditorPage
;
24 import eu
.etaxonomy
.taxeditor
.editor
.ISecuredEditor
;
25 import eu
.etaxonomy
.taxeditor
.editor
.MultiPageTaxonEditor
;
26 import eu
.etaxonomy
.taxeditor
.editor
.SimpleSelectionProvider
;
27 import eu
.etaxonomy
.taxeditor
.editor
.TaxonEditorInput
;
28 import eu
.etaxonomy
.taxeditor
.editor
.name
.container
.AbstractGroup
;
29 import eu
.etaxonomy
.taxeditor
.editor
.name
.container
.AbstractGroupedContainer
;
30 import eu
.etaxonomy
.taxeditor
.editor
.name
.container
.AcceptedGroup
;
31 import eu
.etaxonomy
.taxeditor
.editor
.name
.container
.AcceptedNameContainer
;
32 import eu
.etaxonomy
.taxeditor
.editor
.name
.container
.ContainerFactory
;
33 import eu
.etaxonomy
.taxeditor
.editor
.name
.container
.HomotypicalSynonymGroup
;
34 import eu
.etaxonomy
.taxeditor
.editor
.name
.container
.MisappliedGroup
;
35 import eu
.etaxonomy
.taxeditor
.editor
.name
.dnd
.NameEditorDropTargetListener
;
36 import eu
.etaxonomy
.taxeditor
.model
.AbstractUtility
;
37 import eu
.etaxonomy
.taxeditor
.model
.IPartChangeListener
;
38 import eu
.etaxonomy
.taxeditor
.model
.IPartContentHasDetails
;
39 import eu
.etaxonomy
.taxeditor
.model
.TaxeditorPartService
;
40 import eu
.etaxonomy
.taxeditor
.preference
.Resources
;
41 import eu
.etaxonomy
.taxeditor
.security
.RequiredPermissions
;
42 import eu
.etaxonomy
.taxeditor
.store
.CdmStore
;
46 * TaxonNameEditor class.
54 public class TaxonNameEditor
extends EditorPart
implements
55 IMultiPageTaxonEditorPage
, IConversationEnabled
, ICdmEntitySessionEnabled
,
56 IPartContentHasDetails
, IPartChangeListener
,
57 ISelectionListener
, IDropTargetable
, ISecuredEditor
{
59 /** Constant <code>ID="eu.etaxonomy.taxeditor.editor.taxon.name"</code> */
60 public static final String ID
= "eu.etaxonomy.taxeditor.editor.taxon.name";
64 private ManagedForm managedForm
;
65 private ScrolledForm scrolledForm
;
66 private Composite parent
;
67 private ISelectionProvider simpleSelectionProvider
;
69 private final MultiPageTaxonEditor editor
;
71 private TaxonBase selection
;
73 private final ConversationHolder conversation
;
75 private MenuManager menuManager
;
78 private AcceptedGroup acceptedGroup
;
79 private List
<HomotypicalSynonymGroup
> heterotypicSynonymGroups
= new ArrayList
<HomotypicalSynonymGroup
>();
80 private MisappliedGroup misappliedGroup
;
82 private DropTarget target
;
84 private ISelectionService selectionService
;
86 private TaxonBase objectAffectedByLastOperation
;
88 private ICdmEntitySession cdmEntitySession
;
92 * Constructor for TaxonNameEditor.
96 * a {@link eu.etaxonomy.taxeditor.editor.MultiPageTaxonEditor}
99 public TaxonNameEditor(MultiPageTaxonEditor editor
) {
100 this.editor
= editor
;
101 conversation
= editor
.getConversationHolder();
109 * @return a {@link org.eclipse.core.commands.operations.IUndoContext}
112 public IUndoContext
getUndoContext() {
113 return editor
.getUndoContext();
120 * org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets
125 public void createPartControl(Composite composite
) {
126 selectionService
= getSite().getWorkbenchWindow().getSelectionService();
127 selectionService
.addSelectionListener(this);
129 createManagedForm(composite
);
131 TaxeditorPartService
.getInstance().addListener(
132 TaxeditorPartService
.PART_ACTIVATED
, this);
141 * a {@link org.eclipse.swt.widgets.Composite} object.
143 protected void createManagedForm(Composite composite
) {
145 managedForm
= new ManagedForm(composite
) {
148 public void dirtyStateChanged() {
149 firePropertyChange(PROP_DIRTY
);
153 public boolean setInput(Object input
) {
154 if (input
instanceof AbstractGroupedContainer
) {
155 selection
= ((AbstractGroupedContainer
) input
).getData();
156 getSite().getSelectionProvider().setSelection(new StructuredSelection(selection
));
157 }else if(input
== null){
159 getSite().getSelectionProvider().setSelection(new StructuredSelection());
163 return super.setInput(input
);
167 scrolledForm
= managedForm
.getForm();
168 parent
= scrolledForm
.getBody();
170 // register the context menu
171 menuManager
= new MenuManager();
172 ISelectionProvider selectionProvider
= getSite().getSelectionProvider();
173 getSite().registerContextMenu(TaxonNameEditor
.ID
, menuManager
,
176 parent
.setData(taxon
);
178 TableWrapLayout layout
= new TableWrapLayout();
179 layout
.leftMargin
= 0;
180 layout
.rightMargin
= 0;
181 layout
.topMargin
= 0;
182 layout
.bottomMargin
= 0;
184 layout
.verticalSpacing
= 0;
185 layout
.horizontalSpacing
= 0;
187 parent
.setLayout(layout
);
188 parent
.setBackground(AbstractUtility
189 .getColor(Resources
.COLOR_COMPOSITE_BACKGROUND
));
191 createOrUpdateNameComposites();
200 * createNameComposites
203 public void createOrUpdateNameComposites() {
205 //this.taxon = (Taxon)CdmStore.getService(ITaxonService.class).load(this.getTaxon().getUuid());
206 //this.taxon = HibernateProxyHelper.deproxy(this.taxon, Taxon.class);
207 ContainerFactory
.createOrUpdateAcceptedTaxonsHomotypicGroup(this);
208 ContainerFactory
.createOrUpdateHeterotypicSynonymyGroups(this);
209 ContainerFactory
.createOrUpdateMisapplicationsGroup(this);
212 managedForm
.reflow(true);
217 * Getter for the field <code>taxon</code>.
220 * @return a {@link eu.etaxonomy.cdm.model.taxon.Taxon} object.
222 public Taxon
getTaxon() {
223 return (Taxon
) HibernateProxyHelper
.deproxy(taxon
);
231 public void setDirty() {
232 managedForm
.dirtyStateChanged();
238 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
242 public void setFocus() {
243 PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getShell().setFocus();
244 if (getSelectedContainer() == null) {
245 throw new IllegalStateException(
246 "There should always be a selected object.");
248 getSelectedContainer().setSelected();
251 boolean doEnable
= permissionsSatisfied();
252 setEnabled(doEnable
);
256 * @see eu.etaxonomy.taxeditor.editor.name.ISecuredEditorPart#permissionsSatisfied()
259 public boolean permissionsSatisfied() {
260 TaxonNode taxonNode
= ((TaxonEditorInput
)getEditorInput()).getTaxonNode();
261 boolean doEnable
= CdmStore
.currentAuthentiationHasPermission(taxonNode
, RequiredPermissions
.TAXONNODE_EDIT
);
267 public void setInput(IEditorInput input
) {
268 this.setInputWithNotify(input
);
275 * eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder
280 * getConversationHolder
283 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
287 public ConversationHolder
getConversationHolder() {
295 * eu.etaxonomy.cdm.persistence.hibernate.ICdmPostCrudObserver#update(eu
296 * .etaxonomy.cdm.persistence.hibernate.CdmCrudEvent)
300 public void update(CdmDataChangeMap events
) {
305 * Redraws this editor return true on success
310 public boolean redraw() {
317 * Redraws the editor controls
320 public boolean redraw(boolean focus
) {
322 createOrUpdateNameComposites();
333 * getMultiPageTaxonEditor
336 * @return a {@link eu.etaxonomy.taxeditor.editor.MultiPageTaxonEditor}
339 public MultiPageTaxonEditor
getMultiPageTaxonEditor() {
347 * eu.etaxonomy.taxeditor.store.operations.IPostOperationEnabled#postOperation
352 public boolean postOperation(CdmBase objectAffectedByOperation
) {
354 editor
.changed(objectAffectedByOperation
);
358 if (objectAffectedByOperation
instanceof TaxonBase
) {
359 objectAffectedByLastOperation
= (TaxonBase
) objectAffectedByOperation
;
367 * Getter for the field <code>managedForm</code>.
370 * @return the managedForm
372 public ManagedForm
getManagedForm() {
381 * @return a {@link org.eclipse.swt.widgets.Composite} object.
384 public Composite
getControl() {
385 return this.getManagedForm().getForm().getBody();
390 * Getter for the field <code>menu</code>.
395 public Menu
getMenu() {
396 if (menu
== null || menu
.isDisposed()) {
397 // Creating the menu because it was either not initialised or
398 // disposed while refreshing the editor
399 menu
= menuManager
.createContextMenu(parent
);
409 * @return true if there are empty names
411 public boolean checkForEmptyNames() {
412 for (AbstractGroupedContainer container
: getGroupedContainers()) {
413 if (container
.getName() == null
414 || StringUtils
.isEmpty(container
.getName().getTitleCache())) {
421 public Set
<AbstractGroupedContainer
> getEmptyContainers() {
422 Set
<AbstractGroupedContainer
> containersWithEmptyNames
= new HashSet
<AbstractGroupedContainer
>();
424 for (AbstractGroupedContainer container
: getGroupedContainers()) {
425 if (container
.getName() == null
426 || StringUtils
.isEmpty(container
.getName().getTitleCache())) {
427 containersWithEmptyNames
.add(container
);
431 return containersWithEmptyNames
;
436 public void doSave(IProgressMonitor monitor
) {
438 monitor
.beginTask("Saving names", getGroupedContainers().size());
441 // check for empty names
442 for (AbstractGroupedContainer container
: getGroupedContainers()) {
444 monitor
.subTask("Saving composite: "
445 + container
.getTaxonBase().getTitleCache());
446 container
.persistName();
448 // In case the progress monitor was canceled throw an exception.
449 if (monitor
.isCanceled()) {
450 throw new OperationCanceledException();
453 // Otherwise declare this step as done.
458 // Stop the progress monitor.
466 public void doSaveAs() {
471 public void init(IEditorSite site
, IEditorInput input
)
472 throws PartInitException
{
474 if (!(input
!= null)) {
475 throw new PartInitException("Invalid Input: Must be IEditorInput");
478 if (input
.getAdapter(Taxon
.class) != null) {
479 taxon
= CdmBase
.deproxy(input
.getAdapter(Taxon
.class), Taxon
.class);
481 throw new PartInitException("Invalid Input: Taxon cannot be null");
487 simpleSelectionProvider
= new SimpleSelectionProvider();
488 getSite().setSelectionProvider(simpleSelectionProvider
);
495 private void createDragSupport() {
496 // Listen for names being dragged outside of existing homotypic groups -
497 // user wants to create a new group
498 Transfer
[] types
= new Transfer
[] { CdmDataTransfer
.getInstance() };
499 int operations
= DND
.DROP_MOVE
;
500 if (target
== null) {
501 target
= new DropTarget(parent
, operations
);
502 target
.setTransfer(types
);
503 target
.addDropListener(new NameEditorDropTargetListener(this));
509 * Getter for the field <code>acceptedNameContainer</code>.
513 * {@link eu.etaxonomy.taxeditor.editor.name.container.AcceptedNameContainer}
516 public AcceptedNameContainer
getAcceptedNameContainer() {
517 return getAcceptedGroup().getAcceptedNameContainer();
525 * @param homotypicalGroup
526 * a {@link eu.etaxonomy.cdm.model.name.HomotypicalGroup} object.
528 * {@link eu.etaxonomy.taxeditor.editor.name.container.HomotypicalSynonymGroup}
531 public HomotypicalSynonymGroup
getHomotypicalGroupContainer(
532 HomotypicalGroup homotypicalGroup
) {
533 for (HomotypicalSynonymGroup group
: getHeterotypicSynonymGroups()) {
534 if (group
.getGroup().equals(homotypicalGroup
)) {
547 * @return a Set containing all composites that have been edited
549 public Set
<AbstractGroupedContainer
> getDirtyNames() {
550 Set
<AbstractGroupedContainer
> dirtyNames
= new HashSet
<AbstractGroupedContainer
>();
552 for (AbstractGroupedContainer composite
: getGroupedContainers()) {
553 if (composite
.isDirty()) {
554 dirtyNames
.add(composite
);
563 * getGroupedContainers
566 * @return a {@link java.util.List} object.
568 public List
<AbstractGroupedContainer
> getGroupedContainers() {
569 List
<AbstractGroupedContainer
> groupedComposites
= new ArrayList
<AbstractGroupedContainer
>();
571 for (AbstractGroup group
: getAllGroups()) {
572 groupedComposites
.addAll(group
.getGroupedContainers());
575 return groupedComposites
;
583 * @return a {@link java.util.List} object.
585 public List
<AbstractGroup
> getAllGroups() {
586 List
<AbstractGroup
> allGroups
= new ArrayList
<AbstractGroup
>();
588 allGroups
.add(getAcceptedGroup());
590 // List<HomotypicalSynonymGroup> grps = getHeterotypicSynonymGroups(); // UNUSED => remove
592 heterotypicSynonymGroups
= getHeterotypicSynonymGroups();
594 if (heterotypicSynonymGroups
!= null) {
595 allGroups
.addAll(heterotypicSynonymGroups
);
598 if (misappliedGroup
!= null) {
599 allGroups
.add(misappliedGroup
);
608 * @see org.eclipse.ui.part.EditorPart#isDirty()
612 public boolean isDirty() {
613 return editor
.isDirty();
619 * @see org.eclipse.ui.part.WorkbenchPart#dispose()
623 public void dispose() {
624 conversation
.unregisterForDataStoreChanges(this);
631 * @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed()
635 public boolean isSaveAsAllowed() {
642 * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.
643 * IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
647 public void selectionChanged(IWorkbenchPart part
, ISelection selection
) {
656 * @return a {@link eu.etaxonomy.taxeditor.editor.name.TaxonNameEditor}
660 public TaxonNameEditor
getEditor() {
666 * Getter for the field <code>selectedObject</code>.
670 * {@link eu.etaxonomy.taxeditor.editor.name.container.AbstractGroupedContainer}
673 public AbstractGroupedContainer
getSelectedContainer() {
675 TaxonBase selectedTaxonBase
= null;
677 TaxonEditorInput input
= (TaxonEditorInput
) editor
.getEditorInput();
678 if (input
.getInitiallySelectedTaxonBase() != null) {
679 selectedTaxonBase
= input
.getInitiallySelectedTaxonBase();
681 if (selection
!= null) {
682 selectedTaxonBase
= selection
;
686 return (selectedTaxonBase
!= null) ?
getContainer(selectedTaxonBase
)
687 : getAcceptedNameContainer();
696 public void dragEntered() {
698 getControl().setBackground(
699 AbstractUtility
.getColor(Resources
.COLOR_DRAG_ENTER
));
708 public void dragLeft() {
709 getControl().setBackground(
710 AbstractUtility
.getColor(Resources
.COLOR_COMPOSITE_BACKGROUND
));
716 * setMisapplicationsGroup
719 * @param misappliedGroup
721 * {@link eu.etaxonomy.taxeditor.editor.name.container.MisappliedGroup}
724 public void setMisapplicationsGroup(MisappliedGroup misappliedGroup
) {
725 this.misappliedGroup
= misappliedGroup
;
732 * eu.etaxonomy.taxeditor.editor.IMultiPageTaxonEditorPage#isRedrawing()
742 public boolean isRedrawing() {
751 * @return a {@link org.eclipse.ui.forms.widgets.FormToolkit} object.
753 public FormToolkit
getToolkit() {
754 return managedForm
.getToolkit();
759 * getHeterotypicSynonymGroups
762 * @return a {@link java.util.List} object.
764 public List
<HomotypicalSynonymGroup
> getHeterotypicSynonymGroups() {
765 return heterotypicSynonymGroups
;
770 * addHeterotypicSynonymGroup
775 * {@link eu.etaxonomy.taxeditor.editor.name.container.HomotypicalSynonymGroup}
778 public void addHeterotypicSynonymGroup(HomotypicalSynonymGroup group
) {
779 heterotypicSynonymGroups
.add(group
);
784 * getHomotypicSynonymGroup
788 * {@link eu.etaxonomy.taxeditor.editor.name.container.HomotypicalSynonymGroup}
791 public AcceptedGroup
getAcceptedGroup() {
792 return acceptedGroup
;
797 * @param acceptedGroup
799 public void setAcceptedGroup(AcceptedGroup acceptedGroup
) {
800 this.acceptedGroup
= acceptedGroup
;
805 * Getter for the field <code>misappliedGroup</code>.
809 * {@link eu.etaxonomy.taxeditor.editor.name.container.MisappliedGroup}
812 public MisappliedGroup
getMisappliedGroup() {
813 return misappliedGroup
;
816 // TODO not very useful at the moment
824 public boolean isActive() {
825 IWorkbenchPart activePart
= AbstractUtility
.getActivePart();
826 return editor
.equals(activePart
);
837 public boolean onComplete() {
838 getContainer(objectAffectedByLastOperation
).setSelected();
844 public void partChanged(Integer eventType
, IWorkbenchPartReference partRef
) {
845 if (!partRef
.getPart(false).equals(editor
)) {
846 // getSelectedObject().colorSelected(AbstractGroupedContainer.SELECTED_NO_FOCUS);
851 * @param retainedGroup
853 public void removeGroup(AbstractGroup group
) {
857 //if (heterotypicSynonymGroups != null) {
858 heterotypicSynonymGroups
.remove(group
);
867 public AbstractGroupedContainer
getContainer(TaxonBase taxonBase
) {
868 List
<AbstractGroupedContainer
> groupedContainers
= getGroupedContainers();
869 for (AbstractGroupedContainer container
: groupedContainers
) {
870 if (container
.getData().equals(taxonBase
)
871 && container
.getNameViewer().getTextWidget() != null) {
875 return getAcceptedNameContainer();
879 * @see eu.etaxonomy.taxeditor.editor.IMultiPageTaxonEditorPage#setOnError()
882 public void setOnError() {
883 Color disabledColor
= AbstractUtility
.getColor(Resources
.COLOR_EDITOR_ERROR
);
884 setEnabled(false, disabledColor
);
888 * @see eu.etaxonomy.taxeditor.editor.IMultiPageTaxonEditorPage#setDisabled()
891 public void setDisabled(){
892 Color disabledColor
= AbstractUtility
.getColor(Resources
.COLOR_TEXT_DISABLED_BACKGROUND
);
896 protected void setEnabled(boolean enabled
, Color background
) {
898 for(AbstractGroupedContainer groupedContainer
: getGroupedContainers()){
899 groupedContainer
.setEnabled(enabled
);
902 // send an empty selection to the current provider - TODO only on error ???
904 getManagedForm().setInput(null);
906 for (AbstractGroupedContainer groupedContainer
: getGroupedContainers()) {
907 groupedContainer
.setBackground(background
);
910 getControl().setBackground(background
);
914 public void setEnabled(boolean enabled
) {
915 Color background
= AbstractUtility
.getColor(enabled ? Resources
.COLOR_COMPOSITE_BACKGROUND
: Resources
.COLOR_TEXT_DISABLED_BACKGROUND
);
916 setEnabled(enabled
, background
);
920 * @see eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled#getCdmEntitySession()
923 public ICdmEntitySession
getCdmEntitySession() {
924 return editor
.getCdmEntitySession();
928 * @see eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled#getRootEntities()
931 public <T
extends CdmBase
> List
<T
> getRootEntities() {
932 // TODO Auto-generated method stub