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 org
.apache
.log4j
.Logger
;
13 import org
.eclipse
.jface
.action
.Action
;
14 import org
.eclipse
.jface
.util
.IPropertyChangeListener
;
15 import org
.eclipse
.swt
.events
.FocusAdapter
;
16 import org
.eclipse
.swt
.events
.FocusEvent
;
17 import org
.eclipse
.swt
.graphics
.Font
;
18 import org
.eclipse
.swt
.graphics
.Image
;
19 import org
.eclipse
.swt
.widgets
.Composite
;
20 import org
.eclipse
.ui
.forms
.IManagedForm
;
22 import eu
.etaxonomy
.cdm
.model
.name
.HomotypicalGroup
;
23 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
24 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
25 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
26 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
27 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
28 import eu
.etaxonomy
.taxeditor
.ITaxEditorConstants
;
29 import eu
.etaxonomy
.taxeditor
.TaxEditorPlugin
;
30 import eu
.etaxonomy
.taxeditor
.actions
.ui
.AdaptCompositeToGroupAction
;
31 import eu
.etaxonomy
.taxeditor
.actions
.ui
.AddBasionymCompositeAction
;
32 import eu
.etaxonomy
.taxeditor
.actions
.ui
.ChangeCompositeToMisappliedNameAction
;
33 import eu
.etaxonomy
.taxeditor
.actions
.ui
.ChangeCompositeToNewTaxonAction
;
34 import eu
.etaxonomy
.taxeditor
.actions
.ui
.ChangeSynonymToTaxonUiAction
;
35 import eu
.etaxonomy
.taxeditor
.actions
.ui
.ChangeTaxonToSynonymAction
;
36 import eu
.etaxonomy
.taxeditor
.actions
.ui
.CreateNewHeterotypicCompositeAction
;
37 import eu
.etaxonomy
.taxeditor
.actions
.ui
.DeleteMisappliedNameCompositeAction
;
38 import eu
.etaxonomy
.taxeditor
.actions
.ui
.DeleteSynonymCompositeAction
;
39 import eu
.etaxonomy
.taxeditor
.actions
.ui
.MoveCompositeToMisappliedCompositeAction
;
40 import eu
.etaxonomy
.taxeditor
.actions
.ui
.MoveTaxonDialogAction
;
41 import eu
.etaxonomy
.taxeditor
.actions
.ui
.RemoveBasionymCompositeAction
;
42 import eu
.etaxonomy
.taxeditor
.editor
.ContextMenu
;
43 import eu
.etaxonomy
.taxeditor
.editor
.EditorGroupComposite
;
44 import eu
.etaxonomy
.taxeditor
.editor
.EditorGroupedComposite
;
45 import eu
.etaxonomy
.taxeditor
.editor
.EmptyTextViewerPrompt
;
46 import eu
.etaxonomy
.taxeditor
.editor
.LineBreakListener
;
47 import eu
.etaxonomy
.taxeditor
.editor
.ParseListener
;
48 import eu
.etaxonomy
.taxeditor
.model
.CdmUtil
;
51 * Formats an <code>EditorGroupedComposite</code> to display <code>TaxonNameBase</code> elements
52 * in a <code>NameViewer</code>.
54 * <code>Composite.getData()</code> returns <code>TaxonBase</code>. Therefore, the method
55 * <code>setSelection()</code> is overriden to send the property sheet <code>TaxonBase.getName()</code>.
61 public class NameComposite
extends EditorGroupedComposite
{
62 private static final Logger logger
= Logger
.getLogger(NameComposite
.class);
65 * ************ COMPOSITE TYPES ************
67 public String compositeType
;
68 public static final String ACCEPTED_TAXON
= "accepted_name_composite";
69 public static final String HOMOTYPIC_SYNONYM
= "homotypic_name_composite";
70 public static final String HETEROTYPIC_SYNONYM
= "heterotypic_name_composite";
71 public static final String MISAPPLIED_NAME
= "misappliedname_name_composite";
74 * ************ INDENTATIONS ************
76 public static final int ACCEPTED_INDENT
= 0;
77 public static final int SYNONYM_INDENT
= 15;
78 public static final int MISAPPLIEDNAME_INDENT
= 15;
81 * ************ FONTS ************
83 public static final Font ACCEPTED_FONT
= TaxEditorPlugin
.getDefault()
84 .getFont(ITaxEditorConstants
.ACCEPTED_TAXON_FONT
);
85 public static final Font SYNONYM_FONT
= TaxEditorPlugin
.getDefault()
86 .getFont(ITaxEditorConstants
.SYNONYM_FONT
);
87 public static final Font MISAPPLIEDNAME_FONT
= TaxEditorPlugin
.getDefault()
88 .getFont(ITaxEditorConstants
.MISAPPLIEDNAME_FONT
);
91 * ************ ICONS ************
93 public static final Image ACCEPTED_ICON
= TaxEditorPlugin
.getDefault()
94 .getImage(ITaxEditorConstants
.BLACK_SQUARE_ICON
);
95 public static final Image HOMOTYPIC_SYNONYM_ICON
= TaxEditorPlugin
96 .getDefault().getImage(ITaxEditorConstants
.HOMOTYPIC_SYN_ICON
);
97 public static final Image HOMOTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
= TaxEditorPlugin
98 .getDefault().getImage(
99 ITaxEditorConstants
.HOMOTYPIC_SYN_ORIGINAL_ICON
);
100 public static final Image HETEROTYPIC_SYNONYM_ICON
= TaxEditorPlugin
101 .getDefault().getImage(ITaxEditorConstants
.HETEROTYPIC_SYN_ICON
);
102 public static final Image HETEROTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
= TaxEditorPlugin
103 .getDefault().getImage(
104 ITaxEditorConstants
.HETEROTYPIC_SYN_ORIGINAL_ICON
);
105 public static final Image MISAPPLIEDNAME_ICON
= TaxEditorPlugin
106 .getDefault().getImage(ITaxEditorConstants
.MISAPPLIED_NAME_ICON
);
107 public static final Image AUTONYM_ICON
= TaxEditorPlugin
.getDefault()
108 .getImage(ITaxEditorConstants
.AUTONYM_ICON
);
109 public static final Image BASIONYM_ICON
= TaxEditorPlugin
.getDefault()
110 .getImage(ITaxEditorConstants
.BASIONYM_ICON
);
111 public static final Image MOVE
= TaxEditorPlugin
.getDefault().getImage(
112 ITaxEditorConstants
.MOVE_ICON
);
115 * ************ TRANSFORMATIONS ************
117 public static final String ADD_GROUP_BASIONYM
= "add_group_basionym";
118 public static final String REMOVE_GROUP_BASIONYM
= "remove_group_basionym";
121 * ************ MENU ACTIONS ************
123 public Action CHANGE_TAXON_TO_SYNONYM_ACTION
;
125 private static final String EMPTY_NAME_PROMPT
= "Click to add name";
128 * The constructor for a DescriptionElementComposite. Takes a parent Composite on which to
129 * create itself, and an IManagedForm for Composite life cycle methods, i.e.
130 * drawing borders, creating other Composites, creating line wrap support,
136 public NameComposite(Composite parent
, IManagedForm managedForm
, String compositeType
, TaxonBase data
) {
137 super(parent
, managedForm
);
140 createBorderSupport();
141 createLineWrapSupport();
144 transform(compositeType
);
146 createEmptyViewerPrompt(EMPTY_NAME_PROMPT
);
151 * All cosmetic - non-data-related, i.e. icons, fonts, etc. -
152 * transformations take place in this method.
154 * @param transformation
156 public void transform(String transformation
) {
158 if (transformation
.equals(ADD_GROUP_BASIONYM
)) {
159 if (compositeType
.equals(HOMOTYPIC_SYNONYM
)) {
160 setIcon(HOMOTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
);
162 setIcon(HETEROTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
);
166 if (transformation
.equals(REMOVE_GROUP_BASIONYM
)) {
167 if (compositeType
.equals(HOMOTYPIC_SYNONYM
)) {
168 setIcon(HOMOTYPIC_SYNONYM_ICON
);
170 setIcon(HETEROTYPIC_SYNONYM_ICON
);
174 if (transformation
.equals(ACCEPTED_TAXON
)) {
176 setIcon(ACCEPTED_ICON
);
177 setFont(ACCEPTED_FONT
);
178 setIndent(ACCEPTED_INDENT
);
180 createAcceptedMenu();
182 compositeType
= ACCEPTED_TAXON
;
185 if (transformation
.equals(HOMOTYPIC_SYNONYM
)
186 || transformation
.equals(HETEROTYPIC_SYNONYM
)) {
188 setFont(SYNONYM_FONT
);
189 setIndent(SYNONYM_INDENT
);
194 if (transformation
.equals(HOMOTYPIC_SYNONYM
)) {
195 if (!(getData() instanceof Synonym
)) {
198 Synonym synonym
= (Synonym
) getData();
199 if (CdmUtil
.isNameGroupBasionym(synonym
.getName())) {
200 setIcon(HOMOTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
);
202 setIcon(HOMOTYPIC_SYNONYM_ICON
);
204 compositeType
= HOMOTYPIC_SYNONYM
;
207 if (transformation
.equals(HETEROTYPIC_SYNONYM
)) {
208 if (!(getData() instanceof Synonym
)) {
211 Synonym synonym
= (Synonym
) getData();
212 if (CdmUtil
.isNameGroupBasionym(synonym
.getName())) {
213 setIcon(HETEROTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
);
215 setIcon(HETEROTYPIC_SYNONYM_ICON
);
217 compositeType
= HETEROTYPIC_SYNONYM
;
220 if (transformation
.equals(MISAPPLIED_NAME
)) {
223 setIcon(MISAPPLIEDNAME_ICON
);
224 setFont(MISAPPLIEDNAME_FONT
);
225 setIndent(MISAPPLIEDNAME_INDENT
);
227 createMisappliedNameMenu();
229 compositeType
= MISAPPLIED_NAME
;
233 managedForm
.getForm().layout();
237 * Override of Composite.setData() which passes data along to
238 * DescriptionElementComposite's TextViewer where appropriate.
240 * @see org.eclipse.swt.widgets.Widget#setData(java.lang.Object)
242 public void setData(Object data
) {
244 if (data
instanceof TaxonBase
) {
246 String text
= CdmUtil
.getDisplayName((TaxonBase
) data
);
247 getTextViewer().getTextWidget().setText(text
);
249 if (getTextViewer() instanceof NameViewer
) {
250 ((NameViewer
) getTextViewer()).setCursorToEOL();
252 if (((TaxonBase
) data
).getName() != null) {
253 boolean hasProblem
= ((TaxonBase
) data
).getName()
255 ((NameViewer
) getTextViewer()).setShowError(hasProblem
);
262 * @see eu.etaxonomy.taxeditor.editor.name.EditorGroupedComposite#setSelection()
264 protected void setSelection() {
265 if (getData() instanceof TaxonBase
) {
266 TaxonNameBase taxonBaseName
= ((TaxonBase
) getData()).getName();
267 managedForm
.setInput(taxonBaseName
);
269 super.setSelection();
273 private NameViewer
createNameViewer() {
274 final NameViewer nameViewer
= new NameViewer(this);
276 nameViewer
.setLineBreakListener(new LineBreakListener() {
279 public void handleSplitText(String text
) {
281 Composite parent
= getParent();
282 final Composite grandParent
= parent
.getParent();
284 new CreateNewHeterotypicCompositeAction(text
, managedForm
)
291 nameViewer
.setParseListener(new ParseListener() {
294 public void parse(String text
) {
296 TaxonBase taxonBase
= (TaxonBase
) getData();
298 NonViralName nonViralName
= (NonViralName
) taxonBase
.getName();
299 if (nonViralName
!= null) {
300 // CdmUtil.parseFullName(nonViralName, text, null, true);
301 CdmUtil
.parseFullReference(nonViralName
, text
, null, true);
303 nameViewer
.setShowError(nonViralName
.getHasProblem());
310 nameViewer
.getTextWidget().addFocusListener(new FocusAdapter() {
311 public void focusGained(FocusEvent e
) {
316 // createLineWrapSupport(nameViewer);
318 this.textViewer
= nameViewer
;
320 nameViewer
.getTextWidget().setBackground(TaxEditorPlugin
.getDefault().
321 getColor(ITaxEditorConstants
.GROUP_GRAY_BKG_COLOR
));
327 * @param nameComposite
329 private void createSynonymMenu() {
331 if (!(getData() instanceof Synonym
)) {
335 Synonym synonym
= (Synonym
) getData();
336 ContextMenu contextMenu
= createContextMenu();
338 Action misappliedNameAction
= new MoveCompositeToMisappliedCompositeAction(
340 contextMenu
.addAction(misappliedNameAction
);
342 Action deleteSynonymAction
= new DeleteSynonymCompositeAction(this,
344 contextMenu
.addAction(deleteSynonymAction
);
346 contextMenu
.addSeparator();
348 final Action addBasionymAction
= new AddBasionymCompositeAction(this);
349 contextMenu
.addAction(addBasionymAction
);
351 final Action removeBasionymAction
= new RemoveBasionymCompositeAction(
353 contextMenu
.addAction(removeBasionymAction
);
356 .addPropertyChangeListener(new IPropertyChangeListener() {
358 public void propertyChange(
359 org
.eclipse
.jface
.util
.PropertyChangeEvent event
) {
360 if (event
.getProperty().equals(
361 ITaxEditorConstants
.BASIONYM
)) {
362 removeBasionymAction
.setEnabled(true);
363 transform(NameComposite
.ADD_GROUP_BASIONYM
);
369 .addPropertyChangeListener(new IPropertyChangeListener() {
371 public void propertyChange(
372 org
.eclipse
.jface
.util
.PropertyChangeEvent event
) {
373 if (event
.getProperty().equals(
374 ITaxEditorConstants
.BASIONYM
)) {
375 addBasionymAction
.setEnabled(true);
376 transform(NameComposite
.REMOVE_GROUP_BASIONYM
);
381 contextMenu
.addSeparator();
383 Action changeToThisTaxon
= new ChangeSynonymToTaxonUiAction(synonym
,
385 contextMenu
.addAction(changeToThisTaxon
);
387 Action changeToNewAccepted
= new ChangeCompositeToNewTaxonAction(this,
389 contextMenu
.addAction(changeToNewAccepted
);
393 * @param nameComposite
395 private void createAcceptedMenu() {
397 ContextMenu contextMenu
= createContextMenu();
399 // TODO Make action "Create autonym and subspecies"
401 Action changeTaxonAction
= new ChangeTaxonToSynonymAction(getTaxon());
402 contextMenu
.addAction(changeTaxonAction
);
404 Action moveTaxonAction
= new MoveTaxonDialogAction(getTaxon());
405 contextMenu
.addAction(moveTaxonAction
);
409 * @param nameComposite
411 private void createMisappliedNameMenu() {
413 ContextMenu contextMenu
= createContextMenu();
415 Action deleteMisappliedNameAction
= new DeleteMisappliedNameCompositeAction(
417 contextMenu
.addAction(deleteMisappliedNameAction
);
421 * The hierarchy of the DescriptionElementComposite should always be:
423 * --------> DescriptionElementComposite.getData() -> Taxon or Synonym
425 * --------> DescriptionElementComposite.getParent().getData() -> HomotypicalGroup or <br>
427 * DescriptionElementComposite.getParent().getData(ITaxEditorConstants.MISAPPLIED_NAME) !=
430 * --------> DescriptionElementComposite.getParent().getParent().getData() -> Taxon
432 * An error will be returned if this is not the case.
436 private Taxon
getTaxon() {
437 Composite parent
= getParent();
438 Composite grandParent
= parent
.getParent();
439 if (grandParent
!= null) {
440 Object parentData
= grandParent
.getData();
441 if (parentData
instanceof Taxon
) {
442 return (Taxon
) parentData
;
445 throw new IllegalArgumentException(
446 "The parent of the DescriptionElementComposite's parent does not have a Taxon in its data field as required.");
449 public boolean setParent(Composite parent
) {
451 if (super.setParent(parent
)) {
453 // Has this been moved to the misapplied names group?
454 if (parent
.getData(ITaxEditorConstants
.MISAPPLIED_NAME
) != null) {
455 new ChangeCompositeToMisappliedNameAction(this, managedForm
)
459 // Has this been moved to a HomotypicalGroup?
460 if (parent
.getData() instanceof HomotypicalGroup
) {
461 new AdaptCompositeToGroupAction(this,
462 (EditorGroupComposite
) parent
).run();