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
.beans
.PropertyChangeEvent
;
13 import java
.beans
.PropertyChangeListener
;
15 import org
.apache
.log4j
.Logger
;
16 import org
.eclipse
.core
.runtime
.Assert
;
17 import org
.eclipse
.jface
.action
.Action
;
18 import org
.eclipse
.jface
.util
.IPropertyChangeListener
;
19 import org
.eclipse
.swt
.events
.DisposeEvent
;
20 import org
.eclipse
.swt
.events
.DisposeListener
;
21 import org
.eclipse
.swt
.events
.FocusAdapter
;
22 import org
.eclipse
.swt
.events
.FocusEvent
;
23 import org
.eclipse
.swt
.graphics
.Font
;
24 import org
.eclipse
.swt
.graphics
.Image
;
25 import org
.eclipse
.swt
.widgets
.Composite
;
26 import org
.eclipse
.ui
.forms
.IManagedForm
;
28 import eu
.etaxonomy
.cdm
.model
.name
.HomotypicalGroup
;
29 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
30 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
31 import eu
.etaxonomy
.cdm
.model
.reference
.StrictReferenceBase
;
32 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
33 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
34 import eu
.etaxonomy
.taxeditor
.ITaxEditorConstants
;
35 import eu
.etaxonomy
.taxeditor
.TaxEditorPlugin
;
36 import eu
.etaxonomy
.taxeditor
.UiUtil
;
37 import eu
.etaxonomy
.taxeditor
.actions
.ui
.AdaptCompositeToGroupAction
;
38 import eu
.etaxonomy
.taxeditor
.actions
.ui
.AddBasionymCompositeAction
;
39 import eu
.etaxonomy
.taxeditor
.actions
.ui
.ChangeCompositeToMisappliedNameAction
;
40 import eu
.etaxonomy
.taxeditor
.actions
.ui
.ChangeCompositeToNewTaxonAction
;
41 import eu
.etaxonomy
.taxeditor
.actions
.ui
.ChangeSynonymToTaxonUiAction
;
42 import eu
.etaxonomy
.taxeditor
.actions
.ui
.ChangeTaxonToSynonymAction
;
43 import eu
.etaxonomy
.taxeditor
.actions
.ui
.CreateNewHeterotypicCompositeAction
;
44 import eu
.etaxonomy
.taxeditor
.actions
.ui
.DeleteMisappliedNameCompositeAction
;
45 import eu
.etaxonomy
.taxeditor
.actions
.ui
.DeleteSynonymCompositeAction
;
46 import eu
.etaxonomy
.taxeditor
.actions
.ui
.MoveCompositeToMisappliedCompositeAction
;
47 import eu
.etaxonomy
.taxeditor
.actions
.ui
.MoveTaxonDialogAction
;
48 import eu
.etaxonomy
.taxeditor
.actions
.ui
.RemoveBasionymCompositeAction
;
49 import eu
.etaxonomy
.taxeditor
.editor
.ContextMenu
;
50 import eu
.etaxonomy
.taxeditor
.editor
.EditorGroupComposite
;
51 import eu
.etaxonomy
.taxeditor
.editor
.EditorGroupedComposite
;
52 import eu
.etaxonomy
.taxeditor
.editor
.LineBreakListener
;
53 import eu
.etaxonomy
.taxeditor
.editor
.ParseListener
;
54 import eu
.etaxonomy
.taxeditor
.model
.CdmUtil
;
57 * Formats an <code>EditorGroupedComposite</code> to display <code>TaxonNameBase</code> elements
58 * in a <code>NameViewer</code>.
60 * <code>Composite.getData()</code> returns <code>TaxonBase</code>. Therefore, the method
61 * <code>setSelection()</code> is overriden to send the property sheet <code>TaxonBase.getName()</code>.
67 public class NameComposite
extends EditorGroupedComposite
{
68 private static final Logger logger
= Logger
.getLogger(NameComposite
.class);
71 * ************ COMPOSITE TYPES ************
73 public String compositeType
;
74 public static final String ACCEPTED_TAXON
= "accepted_name_composite";
75 public static final String HOMOTYPIC_SYNONYM
= "homotypic_name_composite";
76 public static final String HETEROTYPIC_SYNONYM
= "heterotypic_name_composite";
77 public static final String MISAPPLIED_NAME
= "misappliedname_name_composite";
80 * ************ INDENTATIONS ************
82 public static final int ACCEPTED_INDENT
= 0;
83 public static final int SYNONYM_INDENT
= 15;
84 public static final int MISAPPLIEDNAME_INDENT
= 15;
87 * ************ FONTS ************
89 public static final Font ACCEPTED_FONT
= TaxEditorPlugin
.getDefault()
90 .getFont(ITaxEditorConstants
.ACCEPTED_TAXON_FONT
);
91 public static final Font SYNONYM_FONT
= TaxEditorPlugin
.getDefault()
92 .getFont(ITaxEditorConstants
.SYNONYM_FONT
);
93 public static final Font MISAPPLIEDNAME_FONT
= TaxEditorPlugin
.getDefault()
94 .getFont(ITaxEditorConstants
.MISAPPLIEDNAME_FONT
);
97 * ************ ICONS ************
99 public static final Image ACCEPTED_ICON
= TaxEditorPlugin
.getDefault()
100 .getImage(ITaxEditorConstants
.BLACK_SQUARE_ICON
);
101 public static final Image HOMOTYPIC_SYNONYM_ICON
= TaxEditorPlugin
102 .getDefault().getImage(ITaxEditorConstants
.HOMOTYPIC_SYN_ICON
);
103 public static final Image HOMOTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
= TaxEditorPlugin
104 .getDefault().getImage(
105 ITaxEditorConstants
.HOMOTYPIC_SYN_ORIGINAL_ICON
);
106 public static final Image HETEROTYPIC_SYNONYM_ICON
= TaxEditorPlugin
107 .getDefault().getImage(ITaxEditorConstants
.HETEROTYPIC_SYN_ICON
);
108 public static final Image HETEROTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
= TaxEditorPlugin
109 .getDefault().getImage(
110 ITaxEditorConstants
.HETEROTYPIC_SYN_ORIGINAL_ICON
);
111 public static final Image MISAPPLIEDNAME_ICON
= TaxEditorPlugin
112 .getDefault().getImage(ITaxEditorConstants
.MISAPPLIED_NAME_ICON
);
113 public static final Image AUTONYM_ICON
= TaxEditorPlugin
.getDefault()
114 .getImage(ITaxEditorConstants
.AUTONYM_ICON
);
115 public static final Image BASIONYM_ICON
= TaxEditorPlugin
.getDefault()
116 .getImage(ITaxEditorConstants
.BASIONYM_ICON
);
117 public static final Image MOVE
= TaxEditorPlugin
.getDefault().getImage(
118 ITaxEditorConstants
.MOVE_ICON
);
121 * ************ TRANSFORMATIONS ************
123 public static final String ADD_GROUP_BASIONYM
= "add_group_basionym";
124 public static final String REMOVE_GROUP_BASIONYM
= "remove_group_basionym";
127 * ************ MENU ACTIONS ************
129 public Action CHANGE_TAXON_TO_SYNONYM_ACTION
;
131 private static final String EMPTY_NAME_PROMPT
= "Click to add name";
133 // private NameViewer nameViewer;
134 // private NameViewer textViewer;
137 * Used to turn parser on and off.
139 * @see activateParser
140 * @see deactivateParser
142 private boolean isUseParser
= false;
144 protected boolean isParsing
;
146 private NameViewer nameViewer
;
149 * The constructor for a DescriptionElementComposite. Takes a parent Composite on which to
150 * create itself, and an IManagedForm for Composite life cycle methods, i.e.
151 * drawing borders, creating other Composites, creating line wrap support,
157 public NameComposite(Composite parent
, IManagedForm managedForm
, String compositeType
, TaxonBase data
) {
158 super(parent
, managedForm
);
161 createBorderSupport();
162 createLineWrapSupport();
166 createNameListener(data
);
168 transform(compositeType
);
170 createEmptyViewerPrompt(EMPTY_NAME_PROMPT
);
177 * Listens for changes to this name's <code>fullTitleCache</code>.
181 private void createNameListener(TaxonBase taxonBase
) {
182 if (taxonBase
.getName() == null) {
186 final TaxonNameBase name
= taxonBase
.getName();
188 final PropertyChangeListener listener
= new PropertyChangeListener() {
189 public void propertyChange(PropertyChangeEvent evt
) {
196 ((NameViewer
) getTextViewer()).setText(name
.getFullTitleCache());
201 name
.addPropertyChangeListener("fullTitleCache", listener
);
202 name
.addPropertyChangeListener("nomenclaturalMicroReference", listener
);
204 name
.addPropertyChangeListener(ITaxEditorConstants
.REFRESH_NAMEVIEWER
, listener
);
206 StrictReferenceBase reference
= (StrictReferenceBase
) name
.getNomenclaturalReference();
207 if (reference
!= null) {
208 reference
.addPropertyChangeListener("titleCache", listener
);
211 this.addDisposeListener(new DisposeListener() {
213 public void widgetDisposed(DisposeEvent e
) {
214 // name.removePropertyChangeListener(listener);
220 * All cosmetic - non-data-related, i.e. icons, fonts, etc. -
221 * transformations take place in this method.
223 * @param transformation
225 public void transform(String transformation
) {
227 if (transformation
.equals(ADD_GROUP_BASIONYM
)) {
228 if (compositeType
.equals(HOMOTYPIC_SYNONYM
)) {
229 setIcon(HOMOTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
);
231 setIcon(HETEROTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
);
235 if (transformation
.equals(REMOVE_GROUP_BASIONYM
)) {
236 if (compositeType
.equals(HOMOTYPIC_SYNONYM
)) {
237 setIcon(HOMOTYPIC_SYNONYM_ICON
);
239 setIcon(HETEROTYPIC_SYNONYM_ICON
);
243 if (transformation
.equals(ACCEPTED_TAXON
)) {
245 setIcon(ACCEPTED_ICON
);
246 setFont(ACCEPTED_FONT
);
247 setIndent(ACCEPTED_INDENT
);
249 createAcceptedMenu();
251 compositeType
= ACCEPTED_TAXON
;
254 if (transformation
.equals(HOMOTYPIC_SYNONYM
)
255 || transformation
.equals(HETEROTYPIC_SYNONYM
)) {
257 setFont(SYNONYM_FONT
);
258 setIndent(SYNONYM_INDENT
);
263 if (transformation
.equals(HOMOTYPIC_SYNONYM
)) {
264 if (!(getData() instanceof Synonym
)) {
267 Synonym synonym
= (Synonym
) getData();
268 if (CdmUtil
.isNameGroupBasionym(synonym
.getName())) {
269 setIcon(HOMOTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
);
271 setIcon(HOMOTYPIC_SYNONYM_ICON
);
273 compositeType
= HOMOTYPIC_SYNONYM
;
276 if (transformation
.equals(HETEROTYPIC_SYNONYM
)) {
277 if (!(getData() instanceof Synonym
)) {
280 Synonym synonym
= (Synonym
) getData();
281 if (CdmUtil
.isNameGroupBasionym(synonym
.getName())) {
282 setIcon(HETEROTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
);
284 setIcon(HETEROTYPIC_SYNONYM_ICON
);
286 compositeType
= HETEROTYPIC_SYNONYM
;
289 if (transformation
.equals(MISAPPLIED_NAME
)) {
292 setIcon(MISAPPLIEDNAME_ICON
);
293 setFont(MISAPPLIEDNAME_FONT
);
294 setIndent(MISAPPLIEDNAME_INDENT
);
296 createMisappliedNameMenu();
298 compositeType
= MISAPPLIED_NAME
;
302 managedForm
.getForm().layout();
306 * Override of Composite.setData() which passes data along to
307 * <code>NameComposite</code>'s <code>TextViewer</code> where appropriate.
309 * @see org.eclipse.swt.widgets.Widget#setData(java.lang.Object)
311 public void setData(Object data
) {
314 Assert
.isTrue((data
instanceof TaxonBase
),
315 "NameComposite's data field must contain a TaxonBase object");
317 String text
= CdmUtil
.getDisplayNameAndRef((TaxonBase
) data
);
318 getTextViewer().getTextWidget().setText(text
);
320 if (getTextViewer() instanceof NameViewer
) {
321 ((NameViewer
) getTextViewer()).setCursorToEOL();
323 if (((TaxonBase
) data
).getName() != null) {
324 boolean hasProblem
= ((TaxonBase
) data
).getName()
326 ((NameViewer
) getTextViewer()).setShowError(hasProblem
);
333 * @see eu.etaxonomy.taxeditor.editor.name.EditorGroupedComposite#setSelection()
335 protected void setSelection() {
336 if (getData() instanceof TaxonBase
) {
338 Object selectionInput
= null;
340 if (compositeType
.equals(MISAPPLIED_NAME
)) {
342 // A misapplied name's property sheet must display both name and sec. ref.
343 selectionInput
= getData();
346 // All other composite types display only their name in property sheet
347 selectionInput
= ((TaxonBase
) getData()).getName();
350 // Send input to the property sheet via the managed form
351 managedForm
.setInput(selectionInput
);
353 super.setSelection();
357 private void createParser() {
358 ((NameViewer
) getTextViewer()).setParseListener(new ParseListener() {
361 public void parse(String text
) {
369 TaxonBase taxonBase
= (TaxonBase
) getData();
370 NonViralName nonViralName
= (NonViralName
) taxonBase
.getName();
372 if (nonViralName
!= null) {
373 CdmUtil
.parseFullReference(nonViralName
, text
, null, true);
374 ((NameViewer
) getTextViewer()).setShowError(nonViralName
.getHasProblem());
381 UiUtil
.getPropertySheetPage().refresh();
387 public void activateParser() {
391 public void deactivateParser() {
395 private NameViewer
createNameViewer() {
396 // nameViewer = new NameViewer(this);
397 // nameViewer.setLineBreakListener(new LineBreakListener() {
399 setTextViewer(new NameViewer(this));
400 getTextViewer().setLineBreakListener(new LineBreakListener() {
403 public void handleSplitText(String text
) {
405 Composite parent
= getParent();
406 final Composite grandParent
= parent
.getParent();
408 new CreateNewHeterotypicCompositeAction(text
, managedForm
)
416 // nameViewer.getTextWidget().addFocusListener(new FocusAdapter() {
417 getTextViewer().getTextWidget().addFocusListener(new FocusAdapter() {
418 public void focusGained(FocusEvent e
) {
423 // createLineWrapSupport(nameViewer);
425 // this.textViewer = nameViewer;
426 // nameViewer.getTextWidget().setBackground(TaxEditorPlugin.getDefault().
427 // getColor(ITaxEditorConstants.GROUP_GRAY_BKG_COLOR));
428 getTextViewer().getTextWidget().setBackground(TaxEditorPlugin
.getDefault().
429 getColor(ITaxEditorConstants
.GROUP_GRAY_BKG_COLOR
));
431 return (NameViewer
) getTextViewer();
435 * @param nameComposite
437 private void createSynonymMenu() {
439 if (!(getData() instanceof Synonym
)) {
443 Synonym synonym
= (Synonym
) getData();
444 ContextMenu contextMenu
= createContextMenu();
446 Action misappliedNameAction
= new MoveCompositeToMisappliedCompositeAction(
448 contextMenu
.addAction(misappliedNameAction
);
450 Action deleteSynonymAction
= new DeleteSynonymCompositeAction(this,
452 contextMenu
.addAction(deleteSynonymAction
);
454 contextMenu
.addSeparator();
456 final Action addBasionymAction
= new AddBasionymCompositeAction(this);
457 contextMenu
.addAction(addBasionymAction
);
459 final Action removeBasionymAction
= new RemoveBasionymCompositeAction(
461 contextMenu
.addAction(removeBasionymAction
);
464 .addPropertyChangeListener(new IPropertyChangeListener() {
465 public void propertyChange(
466 org
.eclipse
.jface
.util
.PropertyChangeEvent event
) {
467 if (event
.getProperty().equals(
468 ITaxEditorConstants
.BASIONYM
)) {
469 removeBasionymAction
.setEnabled(true);
470 transform(NameComposite
.ADD_GROUP_BASIONYM
);
476 .addPropertyChangeListener(new IPropertyChangeListener() {
477 public void propertyChange(
478 org
.eclipse
.jface
.util
.PropertyChangeEvent event
) {
479 if (event
.getProperty().equals(
480 ITaxEditorConstants
.BASIONYM
)) {
481 addBasionymAction
.setEnabled(true);
482 transform(NameComposite
.REMOVE_GROUP_BASIONYM
);
487 contextMenu
.addSeparator();
489 Action changeToThisTaxon
= new ChangeSynonymToTaxonUiAction(synonym
,
491 contextMenu
.addAction(changeToThisTaxon
);
493 Action changeToNewAccepted
= new ChangeCompositeToNewTaxonAction(this,
495 contextMenu
.addAction(changeToNewAccepted
);
499 * @param nameComposite
501 private void createAcceptedMenu() {
503 ContextMenu contextMenu
= createContextMenu();
505 // TODO Make action "Create autonym and subspecies"
507 Action changeTaxonAction
= new ChangeTaxonToSynonymAction(getTaxon());
508 contextMenu
.addAction(changeTaxonAction
);
510 Action moveTaxonAction
= new MoveTaxonDialogAction(getTaxon());
511 contextMenu
.addAction(moveTaxonAction
);
515 * @param nameComposite
517 private void createMisappliedNameMenu() {
519 ContextMenu contextMenu
= createContextMenu();
521 Action deleteMisappliedNameAction
= new DeleteMisappliedNameCompositeAction(
523 contextMenu
.addAction(deleteMisappliedNameAction
);
526 public boolean setParent(Composite parent
) {
528 if (super.setParent(parent
)) {
530 // Has this been moved to the misapplied names group?
531 if (parent
.getData(ITaxEditorConstants
.MISAPPLIED_NAME
) != null) {
532 new ChangeCompositeToMisappliedNameAction(this, managedForm
)
536 // Has this been moved to a HomotypicalGroup?
537 if (parent
.getData() instanceof HomotypicalGroup
) {
538 new AdaptCompositeToGroupAction(this,
539 (EditorGroupComposite
) parent
).run();
547 public void setText(String text
) {
548 Assert
.isNotNull(getTextViewer(),
549 "Cannot set text for a TextViewer that has not yet been initialized.");
550 Assert
.isNotNull(getTextViewer().getDocument(),
551 "Cannot set text for a TextViewer whose Document has not yet been initialized.");
552 getTextViewer().getDocument().set(text
);
555 public NameViewer
getTextViewer() {
556 return this.nameViewer
;
559 public void setTextViewer(NameViewer textViewer
) {
560 this.nameViewer
= textViewer
;