DND-triggered operations now executed after drag end.
[taxeditor.git] / eclipseprojects / eu.etaxonomy.taxeditor / src / eu / etaxonomy / taxeditor / editor / name / NameComposite.java
index 0da60e492e61d4a98a966e0d98acc221d0ccae7b..61d3954db1545520d6878001e92e5aeab5405e59 100644 (file)
@@ -9,52 +9,59 @@
 \r
 package eu.etaxonomy.taxeditor.editor.name;\r
 \r
+import java.beans.PropertyChangeEvent;\r
+import java.beans.PropertyChangeListener;\r
+\r
 import org.apache.log4j.Logger;\r
+import org.eclipse.core.commands.operations.IUndoContext;\r
+import org.eclipse.core.commands.operations.IUndoableOperation;\r
+import org.eclipse.core.runtime.Assert;\r
 import org.eclipse.jface.action.Action;\r
-import org.eclipse.jface.util.IPropertyChangeListener;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.StyledText;\r
 import org.eclipse.swt.events.FocusAdapter;\r
 import org.eclipse.swt.events.FocusEvent;\r
+import org.eclipse.swt.events.KeyAdapter;\r
+import org.eclipse.swt.events.KeyEvent;\r
+import org.eclipse.swt.graphics.Color;\r
 import org.eclipse.swt.graphics.Font;\r
 import org.eclipse.swt.graphics.Image;\r
 import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
 import org.eclipse.ui.forms.IManagedForm;\r
+import org.eclipse.ui.forms.widgets.TableWrapData;\r
+import org.eclipse.ui.forms.widgets.TableWrapLayout;\r
+import org.eclipse.ui.views.properties.IPropertySource;\r
 \r
-import eu.etaxonomy.cdm.model.name.HomotypicalGroup;\r
+import eu.etaxonomy.cdm.model.name.BotanicalName;\r
 import eu.etaxonomy.cdm.model.name.NonViralName;\r
 import eu.etaxonomy.cdm.model.name.TaxonNameBase;\r
-import eu.etaxonomy.cdm.model.taxon.Synonym;\r
-import eu.etaxonomy.cdm.model.taxon.Taxon;\r
+import eu.etaxonomy.cdm.model.name.ZoologicalName;\r
+import eu.etaxonomy.cdm.model.reference.StrictReferenceBase;\r
 import eu.etaxonomy.cdm.model.taxon.TaxonBase;\r
 import eu.etaxonomy.taxeditor.ITaxEditorConstants;\r
 import eu.etaxonomy.taxeditor.TaxEditorPlugin;\r
-import eu.etaxonomy.taxeditor.actions.ui.AdaptCompositeToGroupAction;\r
-import eu.etaxonomy.taxeditor.actions.ui.AddBasionymCompositeAction;\r
-import eu.etaxonomy.taxeditor.actions.ui.ChangeCompositeToMisappliedNameAction;\r
-import eu.etaxonomy.taxeditor.actions.ui.ChangeCompositeToNewTaxonAction;\r
-import eu.etaxonomy.taxeditor.actions.ui.ChangeTaxonToSynonymAction;\r
-import eu.etaxonomy.taxeditor.actions.ui.CreateNewHeterotypicCompositeAction;\r
-import eu.etaxonomy.taxeditor.actions.ui.DeleteMisappliedNameCompositeAction;\r
-import eu.etaxonomy.taxeditor.actions.ui.DeleteSynonymCompositeAction;\r
-import eu.etaxonomy.taxeditor.actions.ui.MoveCompositeToMisappliedCompositeAction;\r
-import eu.etaxonomy.taxeditor.actions.ui.MoveTaxonDialogAction;\r
-import eu.etaxonomy.taxeditor.actions.ui.RemoveBasionymCompositeAction;\r
+import eu.etaxonomy.taxeditor.controller.EditorController;\r
+import eu.etaxonomy.taxeditor.controller.GlobalController;\r
 import eu.etaxonomy.taxeditor.editor.ContextMenu;\r
-import eu.etaxonomy.taxeditor.editor.EmptyTextViewerPrompt;\r
-import eu.etaxonomy.taxeditor.editor.NameViewer;\r
+import eu.etaxonomy.taxeditor.editor.GroupedComposite;\r
+import eu.etaxonomy.taxeditor.editor.LineBreakListener;\r
+import eu.etaxonomy.taxeditor.editor.ParseListener;\r
 import eu.etaxonomy.taxeditor.model.CdmUtil;\r
+import eu.etaxonomy.taxeditor.operations.name.CreateSynonymInNewGroupOperation;\r
+import eu.etaxonomy.taxeditor.propertysheet.name.BotanicalNamePropertySource;\r
+import eu.etaxonomy.taxeditor.propertysheet.name.NonViralNamePropertySource;\r
+import eu.etaxonomy.taxeditor.propertysheet.name.ZoologicalNamePropertySource;\r
 \r
 /**\r
- * Formats an <code>EditorGroupedComposite</code> to display <code>TaxonNameBase</code> elements\r
+ * Formats an <code>GroupedComposite</code> to display <code>TaxonNameBase</code> elements\r
  * in a <code>NameViewer</code>.\r
  * \r
- * <code>Composite.getData()</code> returns <code>TaxonBase</code>. Therefore, the method   \r
- * <code>setSelection()</code> is overriden to send the property sheet <code>TaxonBase.getName()</code>. \r
- * \r
  * @author p.ciardelli\r
  * @created 02.06.2008\r
  * @version 1.0\r
  */\r
-public class NameComposite extends EditorGroupedComposite {\r
+public abstract class NameComposite extends GroupedComposite {\r
        private static final Logger logger = Logger.getLogger(NameComposite.class);\r
 \r
        /**\r
@@ -65,6 +72,7 @@ public class NameComposite extends EditorGroupedComposite {
        public static final String HOMOTYPIC_SYNONYM = "homotypic_name_composite";\r
        public static final String HETEROTYPIC_SYNONYM = "heterotypic_name_composite";\r
        public static final String MISAPPLIED_NAME = "misappliedname_name_composite";\r
+       public static final String CONCEPTRELATION = "concept_name_comcposite";\r
 \r
        /**\r
         * ************ INDENTATIONS ************\r
@@ -72,6 +80,7 @@ public class NameComposite extends EditorGroupedComposite {
        public static final int ACCEPTED_INDENT = 0;\r
        public static final int SYNONYM_INDENT = 15;\r
        public static final int MISAPPLIEDNAME_INDENT = 15;\r
+       public static final int CONCEPT_INDENT = 15;\r
 \r
        /**\r
         * ************ FONTS ************\r
@@ -82,6 +91,8 @@ public class NameComposite extends EditorGroupedComposite {
                        .getFont(ITaxEditorConstants.SYNONYM_FONT);\r
        public static final Font MISAPPLIEDNAME_FONT = TaxEditorPlugin.getDefault()\r
                        .getFont(ITaxEditorConstants.MISAPPLIEDNAME_FONT);\r
+       public static final Font CONCEPT_FONT = TaxEditorPlugin.getDefault()\r
+                       .getFont(ITaxEditorConstants.CONCEPT_FONT);\r
 \r
        /**\r
         * ************ ICONS ************\r
@@ -100,6 +111,8 @@ public class NameComposite extends EditorGroupedComposite {
                                        ITaxEditorConstants.HETEROTYPIC_SYN_ORIGINAL_ICON);\r
        public static final Image MISAPPLIEDNAME_ICON = TaxEditorPlugin\r
                        .getDefault().getImage(ITaxEditorConstants.MISAPPLIED_NAME_ICON);\r
+       public static final Image CONCEPT_ICON = TaxEditorPlugin\r
+                       .getDefault().getImage(ITaxEditorConstants.CONCEPT_ICON);\r
        public static final Image AUTONYM_ICON = TaxEditorPlugin.getDefault()\r
                        .getImage(ITaxEditorConstants.AUTONYM_ICON);\r
        public static final Image BASIONYM_ICON = TaxEditorPlugin.getDefault()\r
@@ -120,6 +133,18 @@ public class NameComposite extends EditorGroupedComposite {
 \r
        private static final String EMPTY_NAME_PROMPT = "Click to add name";\r
 \r
+       /**\r
+        * Used to turn parser on and off.\r
+        * \r
+        * @see activateParser\r
+        * @see deactivateParser\r
+        */\r
+       private boolean isUseParser = false;\r
+\r
+       protected boolean isParsing;\r
+\r
+       protected NameViewer nameViewer;\r
+\r
        /**\r
         * The constructor for a DescriptionElementComposite. Takes a parent Composite on which to\r
         * create itself, and an IManagedForm for Composite life cycle methods, i.e.\r
@@ -129,338 +154,279 @@ public class NameComposite extends EditorGroupedComposite {
         * @param parent\r
         * @param managedForm\r
         */\r
-       public NameComposite(Composite parent, IManagedForm managedForm, String compositeType, TaxonBase data) {\r
+       public NameComposite(Composite parent, IManagedForm managedForm, \r
+                       String compositeType, TaxonBase taxonBase) {\r
                super(parent, managedForm);\r
 \r
                createNameViewer();\r
                createBorderSupport();\r
                createLineWrapSupport();\r
-\r
-               setData(data);\r
-               transform(compositeType);\r
                \r
+               setDraggableControl(nameViewer.getRulerControl());\r
+               \r
+               createParser();\r
                createEmptyViewerPrompt(EMPTY_NAME_PROMPT);\r
                setFocus();\r
+               \r
+               // NOTE: placing this after setFocus() inexplicably solved a strange bug where if the first action\r
+               //      during a session was to open a new taxon, the empty name prompt didn't work\r
+               createNameListener(taxonBase.getName());\r
        }\r
 \r
+       protected void createContent() {\r
+               setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));\r
+               TableWrapLayout layout = new TableWrapLayout();\r
+               layout.leftMargin = 0;\r
+               layout.topMargin = 0;\r
+               layout.bottomMargin = 0;\r
+               layout.verticalSpacing = 0;\r
+               setLayout(layout);\r
+               \r
+               Color groupBackgroundColor = TaxEditorPlugin.getDefault().\r
+                               getColor(ITaxEditorConstants.GROUP_GRAY_BKG_COLOR);\r
+               setBackground(groupBackgroundColor);\r
+       }\r
+       \r
+       protected String getEmptyTextPrompt() {\r
+               return EMPTY_NAME_PROMPT;\r
+       }\r
+       \r
        /**\r
-        * All cosmetic - non-data-related, i.e. icons, fonts, etc. -\r
-        * transformations take place in this method.\r
+        * Listens for changes to this name's <code>fullTitleCache</code>.\r
         * \r
-        * @param transformation\r
+        * @param data\r
         */\r
-       public void transform(String transformation) {\r
-\r
-               if (transformation.equals(ADD_GROUP_BASIONYM)) {\r
-                       if (compositeType.equals(HOMOTYPIC_SYNONYM)) {\r
-                               setIcon(HOMOTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON);\r
-                       } else {\r
-                               setIcon(HETEROTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON);\r
-                       }\r
-               }\r
-\r
-               if (transformation.equals(REMOVE_GROUP_BASIONYM)) {\r
-                       if (compositeType.equals(HOMOTYPIC_SYNONYM)) {\r
-                               setIcon(HOMOTYPIC_SYNONYM_ICON);\r
-                       } else {\r
-                               setIcon(HETEROTYPIC_SYNONYM_ICON);\r
-                       }\r
-               }\r
-\r
-               if (transformation.equals(ACCEPTED_TAXON)) {\r
-                       setDraggable(false);\r
-                       setIcon(ACCEPTED_ICON);\r
-                       setFont(ACCEPTED_FONT);\r
-                       setIndent(ACCEPTED_INDENT);\r
-\r
-                       createAcceptedMenu();\r
-\r
-                       compositeType = ACCEPTED_TAXON;\r
-               }\r
-\r
-               if (transformation.equals(HOMOTYPIC_SYNONYM)\r
-                               || transformation.equals(HETEROTYPIC_SYNONYM)) {\r
-                       setDraggable(true);\r
-                       setFont(SYNONYM_FONT);\r
-                       setIndent(SYNONYM_INDENT);\r
-\r
-                       createSynonymMenu();\r
-               }\r
-\r
-               if (transformation.equals(HOMOTYPIC_SYNONYM)) {\r
-                       if (!(getData() instanceof Synonym)) {\r
-                               return;\r
-                       }\r
-                       Synonym synonym = (Synonym) getData();\r
-                       if (CdmUtil.isNameGroupBasionym(synonym.getName())) {\r
-                               setIcon(HOMOTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON);\r
-                       } else {\r
-                               setIcon(HOMOTYPIC_SYNONYM_ICON);\r
-                       }\r
-                       compositeType = HOMOTYPIC_SYNONYM;\r
+       private void createNameListener(final TaxonNameBase name) {\r
+               \r
+               if (name == null) {\r
+                       return;\r
                }\r
-\r
-               if (transformation.equals(HETEROTYPIC_SYNONYM)) {\r
-                       if (!(getData() instanceof Synonym)) {\r
-                               return;\r
-                       }\r
-                       Synonym synonym = (Synonym) getData();\r
-                       if (CdmUtil.isNameGroupBasionym(synonym.getName())) {\r
-                               setIcon(HETEROTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON);\r
-                       } else {\r
-                               setIcon(HETEROTYPIC_SYNONYM_ICON);\r
+               \r
+               final PropertyChangeListener listener = new PropertyChangeListener() {\r
+                       public void propertyChange(PropertyChangeEvent evt) {\r
+                               \r
+                               if (isParsing) {\r
+                                       return;\r
+                               }\r
+                               \r
+                               if (EditorController.isSaving()) {\r
+                                       return;\r
+                               }\r
+                               \r
+                               deactivateParser();\r
+                               ((NameViewer) getTextViewer()).setText(name.getFullTitleCache());\r
+                               activateParser();\r
                        }\r
-                       compositeType = HETEROTYPIC_SYNONYM;\r
-               }\r
-\r
-               if (transformation.equals(MISAPPLIED_NAME)) {\r
-\r
-                       setDraggable(true);\r
-                       setIcon(MISAPPLIEDNAME_ICON);\r
-                       setFont(MISAPPLIEDNAME_FONT);\r
-                       setIndent(MISAPPLIEDNAME_INDENT);\r
-\r
-                       createMisappliedNameMenu();\r
+               };\r
+               \r
+               // TODO clean this part up\r
+               name.addPropertyChangeListener("fullTitleCache", listener);\r
+               name.addPropertyChangeListener("nomenclaturalMicroReference", listener);\r
 \r
-                       compositeType = MISAPPLIED_NAME;\r
+//             name.addPropertyChangeListener(ITaxEditorConstants.REFRESH_NAMEVIEWER, listener);\r
+               \r
+               StrictReferenceBase reference = (StrictReferenceBase) name.getNomenclaturalReference();\r
+               if (reference != null) {\r
+                       reference.addPropertyChangeListener("titleCache", listener);\r
                }\r
-\r
-               setDirty(true);\r
-               managedForm.getForm().layout();\r
        }\r
-\r
-       /**\r
-        * Override of Composite.setData() which passes data along to\r
-        * DescriptionElementComposite's TextViewer where appropriate.\r
-        * \r
-        * @see org.eclipse.swt.widgets.Widget#setData(java.lang.Object)\r
-        */\r
-       public void setData(Object data) {\r
-               super.setData(data);\r
-               if (data instanceof TaxonBase) {\r
-\r
-                       String text = CdmUtil.getDisplayName((TaxonBase) data);\r
+       \r
+       protected void initNameViewer(TaxonBase taxonBase) {\r
+               String text = CdmUtil.getDisplayNameWithRef(taxonBase);\r
+               if (text.length() == 0) {\r
+                       initEmptyText();\r
+               } else {\r
                        getTextViewer().getTextWidget().setText(text);\r
 \r
                        if (getTextViewer() instanceof NameViewer) {\r
+                               \r
                                ((NameViewer) getTextViewer()).setCursorToEOL();\r
 \r
-                               if (((TaxonBase) data).getName() != null) {\r
-                                       boolean hasProblem = ((TaxonBase) data).getName()\r
-                                                       .getHasProblem();\r
-                                       ((NameViewer) getTextViewer()).setShowError(hasProblem);\r
+                               TaxonNameBase name = taxonBase.getName();\r
+                               if (name != null) {                                     \r
+                                       calculateErrors();\r
                                }\r
                        }\r
                }\r
-       }\r
-\r
-       /* (non-Javadoc)\r
-        * @see eu.etaxonomy.taxeditor.editor.name.EditorGroupedComposite#setSelection()\r
-        */\r
-       protected void setSelection() {\r
-               if (getData() instanceof TaxonBase) {\r
-                       TaxonNameBase taxonBaseName = ((TaxonBase) getData()).getName();\r
-                       managedForm.setInput(taxonBaseName);\r
-               } else {\r
-                       super.setSelection();\r
-               }\r
+               activateParser();\r
        }\r
        \r
-       private NameViewer createNameViewer() {\r
-               final NameViewer nameViewer = new NameViewer(this);\r
-\r
-               nameViewer.setLineBreakListener(new LineBreakListener() {\r
+       private void createParser() {\r
+               ((NameViewer) getTextViewer()).addParseListener(new ParseListener() {\r
 \r
                        @Override\r
-                       public void handleSplitText(String text) {\r
-\r
-                               Composite parent = getParent();\r
-                               final Composite grandParent = parent.getParent();\r
-\r
-                               new CreateNewHeterotypicCompositeAction(text, managedForm)\r
-                                               .run();\r
+                       public void parse(String text) {\r
+                               \r
+                               // Either composite is not yet fully built, or\r
+                               //      the property sheet is writing to it\r
+                               if (!isUseParser) {\r
+                                       return;\r
+                               }\r
+                               \r
+                               // Let others know the parser is active\r
+                               isParsing = true;\r
+                                                               \r
+                               // Parse the name and paint the text field w any errors\r
+                               if (getName() != null) {\r
+                                       CdmParserController.parseFullReference((NonViralName) getName(), text);\r
+                               }\r
 \r
-                               // setDirty(true);\r
+                               // Any entry of text means the taxon has been changed\r
+                               setDirty(true);\r
+                               \r
+                               // The parser is no longer active\r
+                               isParsing = false;\r
+                               \r
+                               // Manually refresh the property sheet to reflect changes\r
+                               setSelection();\r
+                               \r
+                               // Show any errors in the name viewer\r
+                               calculateErrors();\r
                        }\r
-\r
                });\r
-               nameViewer.setParseListener(new ParseListener() {\r
-\r
-                       @Override\r
-                       public void parse(String text) {\r
-\r
-                               TaxonBase taxonBase = (TaxonBase) getData();\r
+       }\r
 \r
-                               NonViralName nonViralName = (NonViralName) taxonBase.getName();\r
-                               if (nonViralName != null) {\r
-//                                     CdmUtil.parseFullName(nonViralName, text, null, true);\r
-                                       CdmUtil.parseFullReference(nonViralName, text, null, true);\r
-                                       \r
-                                       nameViewer.setShowError(nonViralName.getHasProblem());\r
-                               }\r
+       public void activateParser() {\r
+               isUseParser = true;\r
+       }\r
+       \r
+       public void deactivateParser() {\r
+               isUseParser = false;\r
+       }\r
+       \r
+       protected abstract TaxonNameBase getName();\r
+       \r
+       protected void calculateErrors() {\r
+                               \r
+               nameViewer.clearErrors();\r
+               \r
+               nameViewer.setShowParsingError(getName());\r
+               \r
+       }\r
+       \r
+       private NameViewer createNameViewer() {\r
+               \r
+               nameViewer = new NameViewer(this);\r
+               \r
+               StyledText styledText = nameViewer.getTextWidget();\r
+//             nameViewer.setLineBreakListener(new LineBreakListener() {\r
+               \r
+               setTextViewer(nameViewer);\r
+                               \r
+               nameViewer.addLineBreakListener(new LineBreakListener() {\r
 \r
-                               setDirty(true);\r
+                       @Override\r
+                       public void handleSplitText(String text) {\r
+                               \r
+                               // Create a synonym in a new homotypic group using text as name\r
+                               IUndoContext undoContext = EditorController.getUndoContext(taxon);\r
+                               IUndoableOperation operation = new CreateSynonymInNewGroupOperation\r
+                                               ("new heterotypic synonym", undoContext, taxon, text); //$NON-NLS-1$\r
+//                             setOperation(new CreateSynonymInNewGroupOperation\r
+                               \r
+                               GlobalController.executeOperation(operation);\r
+//                             getTextViewer().removeLineBreakListener(this);\r
                        }\r
+\r
                });\r
 \r
-               nameViewer.getTextWidget().addFocusListener(new FocusAdapter() {\r
+//             styledText.addKeyListener(new KeyAdapter(){\r
+//\r
+//                     @Override\r
+//                     public void keyReleased(KeyEvent e) {\r
+//                             if (operation != null) {\r
+//                                     GlobalController.executeOperation(operation);\r
+//                                     operation = null;\r
+//                             }\r
+//                     }\r
+//                     \r
+//             });\r
+               \r
+               styledText.addFocusListener(new FocusAdapter() {\r
                        public void focusGained(FocusEvent e) {\r
                                setFocus();\r
                        }\r
                });\r
-\r
+               \r
                // createLineWrapSupport(nameViewer);\r
-\r
-               this.textViewer = nameViewer;\r
-\r
-               nameViewer.getTextWidget().setBackground(TaxEditorPlugin.getDefault().\r
-                               getColor(ITaxEditorConstants.GROUP_GRAY_BKG_COLOR));\r
+                       \r
                \r
                return nameViewer;\r
        }\r
+       \r
+//     IUndoableOperation operation;\r
 \r
-       /**\r
-        * @param nameComposite\r
-        */\r
-       private void createSynonymMenu() {\r
-\r
-               if (!(getData() instanceof Synonym)) {\r
-                       return;\r
+       private Label nonEditableInfo;\r
+       \r
+//     protected void setOperation(IUndoableOperation operation) {\r
+//             this.operation = operation;\r
+//     }\r
+\r
+       public void setText(String text) {\r
+               Assert.isNotNull(getTextViewer(), \r
+                               "Cannot set text for a TextViewer that has not yet been initialized.");\r
+               Assert.isNotNull(getTextViewer().getDocument(), \r
+                               "Cannot set text for a TextViewer whose Document has not yet been initialized.");\r
+               getTextViewer().getDocument().set(text);\r
+       }\r
+       \r
+       public void setNonEditableInfo(String info) {\r
+               if (nonEditableInfo == null) {\r
+                       nonEditableInfo = new Label(this, SWT.WRAP);\r
+                       nonEditableInfo.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.TOP));\r
+               } else {\r
+                       info = nonEditableInfo.getText() + ", " + info;\r
                }\r
-\r
-               Synonym synonym = (Synonym) getData();\r
-               ContextMenu contextMenu = createContextMenu();\r
-\r
-               Action misappliedNameAction = new MoveCompositeToMisappliedCompositeAction(\r
-                               this, managedForm);\r
-               contextMenu.addAction(misappliedNameAction);\r
-\r
-               Action deleteSynonymAction = new DeleteSynonymCompositeAction(this,\r
-                               getTaxon());\r
-               contextMenu.addAction(deleteSynonymAction);\r
-\r
-               contextMenu.addSeparator();\r
-\r
-               final Action addBasionymAction = new AddBasionymCompositeAction(this);\r
-               contextMenu.addAction(addBasionymAction);\r
-\r
-               final Action removeBasionymAction = new RemoveBasionymCompositeAction(\r
-                               this);\r
-               contextMenu.addAction(removeBasionymAction);\r
-\r
-               addBasionymAction\r
-                               .addPropertyChangeListener(new IPropertyChangeListener() {\r
-                                       @Override\r
-                                       public void propertyChange(\r
-                                                       org.eclipse.jface.util.PropertyChangeEvent event) {\r
-                                               if (event.getProperty().equals(\r
-                                                               ITaxEditorConstants.BASIONYM)) {\r
-                                                       removeBasionymAction.setEnabled(true);\r
-                                                       transform(NameComposite.ADD_GROUP_BASIONYM);\r
-                                               }\r
-                                       }\r
-                               });\r
-\r
-               removeBasionymAction\r
-                               .addPropertyChangeListener(new IPropertyChangeListener() {\r
-                                       @Override\r
-                                       public void propertyChange(\r
-                                                       org.eclipse.jface.util.PropertyChangeEvent event) {\r
-                                               if (event.getProperty().equals(\r
-                                                               ITaxEditorConstants.BASIONYM)) {\r
-                                                       addBasionymAction.setEnabled(true);\r
-                                                       transform(NameComposite.REMOVE_GROUP_BASIONYM);\r
-                                               }\r
-                                       }\r
-                               });\r
-\r
-               contextMenu.addSeparator();\r
-\r
-               Action changeToThisTaxon = new ChangeSynonymToTaxonUiAction(synonym,\r
-                               getTaxon());\r
-               contextMenu.addAction(changeToThisTaxon);\r
-\r
-               Action changeToNewAccepted = new ChangeCompositeToNewTaxonAction(this,\r
-                               getTaxon());\r
-               contextMenu.addAction(changeToNewAccepted);\r
+               nonEditableInfo.setText(info.toUpperCase());\r
        }\r
-\r
-       /**\r
-        * @param nameComposite\r
-        */\r
-       private void createAcceptedMenu() {\r
-\r
-               ContextMenu contextMenu = createContextMenu();\r
-\r
-               // TODO Make action "Create autonym and subspecies"\r
-\r
-               Action changeTaxonAction = new ChangeTaxonToSynonymAction(getTaxon());\r
-               contextMenu.addAction(changeTaxonAction);\r
-\r
-               Action moveTaxonAction = new MoveTaxonDialogAction(getTaxon());\r
-               contextMenu.addAction(moveTaxonAction);\r
+       \r
+       public NameViewer getTextViewer() {\r
+               return this.nameViewer;\r
        }\r
-\r
-       /**\r
-        * @param nameComposite\r
-        */\r
-       private void createMisappliedNameMenu() {\r
-\r
-               ContextMenu contextMenu = createContextMenu();\r
-\r
-               Action deleteMisappliedNameAction = new DeleteMisappliedNameCompositeAction(\r
-                               this, getTaxon());\r
-               contextMenu.addAction(deleteMisappliedNameAction);\r
+       \r
+       public void setTextViewer(NameViewer textViewer) {\r
+               this.nameViewer = textViewer;\r
        }\r
-\r
-       /**\r
-        * The hierarchy of the DescriptionElementComposite should always be:\r
-        * <p>\r
-        * --------> DescriptionElementComposite.getData() -> Taxon or Synonym\r
-        * <p>\r
-        * --------> DescriptionElementComposite.getParent().getData() -> HomotypicalGroup or <br>\r
-        * -------->\r
-        * DescriptionElementComposite.getParent().getData(ITaxEditorConstants.MISAPPLIED_NAME) !=\r
-        * null\r
-        * <p>\r
-        * --------> DescriptionElementComposite.getParent().getParent().getData() -> Taxon\r
-        * <p>\r
-        * An error will be returned if this is not the case.\r
-        * \r
-        * @return\r
-        */\r
-       private Taxon getTaxon() {\r
-               Composite parent = getParent();\r
-               Composite grandParent = parent.getParent();\r
-               if (grandParent != null) {\r
-                       Object parentData = grandParent.getData();\r
-                       if (parentData instanceof Taxon) {\r
-                               return (Taxon) parentData;\r
-                       }\r
+       \r
+       public void createBorderSupport() {\r
+               super.createBorderSupport();\r
+               if (nameViewer != null) {\r
+                       borderDecorator.setBorderedComposite(nameViewer.getTextWidget());\r
                }\r
-               throw new IllegalArgumentException(\r
-                               "The parent of the DescriptionElementComposite's parent does not have a Taxon in its data field as required.");\r
        }\r
-\r
-       public boolean setParent(Composite parent) {\r
-\r
-               if (super.setParent(parent)) {\r
-\r
-                       // Has this been moved to the misapplied names group?\r
-                       if (parent.getData(ITaxEditorConstants.MISAPPLIED_NAME) != null) {\r
-                               new ChangeCompositeToMisappliedNameAction(this, managedForm)\r
-                                               .run();\r
-                       }\r
-\r
-                       // Has this been moved to a HomotypicalGroup?\r
-                       if (parent.getData() instanceof HomotypicalGroup) {\r
-                               new AdaptCompositeToGroupAction(this,\r
-                                               (EditorGroupComposite) parent).run();\r
-                       }\r
-                       return true;\r
-\r
+       \r
+       public void setIcon(Image icon) {\r
+               if (nameViewer != null) {\r
+                       nameViewer.setIcon(icon);\r
+               }\r
+       }\r
+       \r
+       protected IPropertySource getPropertySourceByName(TaxonNameBase name) {\r
+               if (name == null) {\r
+                       return null;\r
+               }\r
+               \r
+               if (name.getClass() == BotanicalName.class) {\r
+                       return new BotanicalNamePropertySource((BotanicalName) name);\r
+               }\r
+               if (name.getClass() == ZoologicalName.class) {\r
+                       return new ZoologicalNamePropertySource((ZoologicalName) name);\r
+               }\r
+               if (name instanceof NonViralName) {\r
+                       return new NonViralNamePropertySource((NonViralName) name);\r
+               }\r
+               \r
+               return null;\r
+       }\r
+       \r
+       protected ContextMenu createContextMenu() {\r
+               if (nameViewer != null) {\r
+                       ContextMenu contextMenu = new ContextMenu(nameViewer.getRulerControl());\r
+                       nameViewer.getTextWidget().setMenu(contextMenu.getMenu());\r
+                       return contextMenu;\r
+               } else {\r
+                       logger.warn("Can't create menu because nameViewer has not been initalized.");\r
+                       return null;\r
                }\r
-               return false;\r
        }\r
-\r
 }
\ No newline at end of file