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
.text
.TextViewer
;
19 import org
.eclipse
.jface
.util
.IPropertyChangeListener
;
20 import org
.eclipse
.swt
.events
.DisposeEvent
;
21 import org
.eclipse
.swt
.events
.DisposeListener
;
22 import org
.eclipse
.swt
.events
.FocusAdapter
;
23 import org
.eclipse
.swt
.events
.FocusEvent
;
24 import org
.eclipse
.swt
.graphics
.Font
;
25 import org
.eclipse
.swt
.graphics
.Image
;
26 import org
.eclipse
.swt
.widgets
.Composite
;
27 import org
.eclipse
.ui
.forms
.IManagedForm
;
29 import eu
.etaxonomy
.cdm
.model
.name
.HomotypicalGroup
;
30 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
31 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
32 import eu
.etaxonomy
.cdm
.model
.reference
.StrictReferenceBase
;
33 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
34 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
35 import eu
.etaxonomy
.taxeditor
.ITaxEditorConstants
;
36 import eu
.etaxonomy
.taxeditor
.TaxEditorPlugin
;
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() {
190 public void propertyChange(PropertyChangeEvent evt
) {
197 ((NameViewer
) getTextViewer()).setText(name
.getFullTitleCache());
202 name
.addPropertyChangeListener("fullTitleCache", listener
);
203 name
.addPropertyChangeListener("nomenclaturalMicroReference", listener
);
205 name
.addPropertyChangeListener(ITaxEditorConstants
.REFRESH_NAMEVIEWER
, listener
);
207 StrictReferenceBase reference
= (StrictReferenceBase
) name
.getNomenclaturalReference();
208 if (reference
!= null) {
209 reference
.addPropertyChangeListener("titleCache", listener
);
212 this.addDisposeListener(new DisposeListener() {
215 public void widgetDisposed(DisposeEvent e
) {
216 // name.removePropertyChangeListener(listener);
222 * All cosmetic - non-data-related, i.e. icons, fonts, etc. -
223 * transformations take place in this method.
225 * @param transformation
227 public void transform(String transformation
) {
229 if (transformation
.equals(ADD_GROUP_BASIONYM
)) {
230 if (compositeType
.equals(HOMOTYPIC_SYNONYM
)) {
231 setIcon(HOMOTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
);
233 setIcon(HETEROTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
);
237 if (transformation
.equals(REMOVE_GROUP_BASIONYM
)) {
238 if (compositeType
.equals(HOMOTYPIC_SYNONYM
)) {
239 setIcon(HOMOTYPIC_SYNONYM_ICON
);
241 setIcon(HETEROTYPIC_SYNONYM_ICON
);
245 if (transformation
.equals(ACCEPTED_TAXON
)) {
247 setIcon(ACCEPTED_ICON
);
248 setFont(ACCEPTED_FONT
);
249 setIndent(ACCEPTED_INDENT
);
251 createAcceptedMenu();
253 compositeType
= ACCEPTED_TAXON
;
256 if (transformation
.equals(HOMOTYPIC_SYNONYM
)
257 || transformation
.equals(HETEROTYPIC_SYNONYM
)) {
259 setFont(SYNONYM_FONT
);
260 setIndent(SYNONYM_INDENT
);
265 if (transformation
.equals(HOMOTYPIC_SYNONYM
)) {
266 if (!(getData() instanceof Synonym
)) {
269 Synonym synonym
= (Synonym
) getData();
270 if (CdmUtil
.isNameGroupBasionym(synonym
.getName())) {
271 setIcon(HOMOTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
);
273 setIcon(HOMOTYPIC_SYNONYM_ICON
);
275 compositeType
= HOMOTYPIC_SYNONYM
;
278 if (transformation
.equals(HETEROTYPIC_SYNONYM
)) {
279 if (!(getData() instanceof Synonym
)) {
282 Synonym synonym
= (Synonym
) getData();
283 if (CdmUtil
.isNameGroupBasionym(synonym
.getName())) {
284 setIcon(HETEROTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
);
286 setIcon(HETEROTYPIC_SYNONYM_ICON
);
288 compositeType
= HETEROTYPIC_SYNONYM
;
291 if (transformation
.equals(MISAPPLIED_NAME
)) {
294 setIcon(MISAPPLIEDNAME_ICON
);
295 setFont(MISAPPLIEDNAME_FONT
);
296 setIndent(MISAPPLIEDNAME_INDENT
);
298 createMisappliedNameMenu();
300 compositeType
= MISAPPLIED_NAME
;
304 managedForm
.getForm().layout();
308 * Override of Composite.setData() which passes data along to
309 * <code>NameComposite</code>'s <code>TextViewer</code> where appropriate.
311 * @see org.eclipse.swt.widgets.Widget#setData(java.lang.Object)
313 public void setData(Object data
) {
316 Assert
.isTrue((data
instanceof TaxonBase
),
317 "NameComposite's data field must contain a TaxonBase object");
319 String text
= CdmUtil
.getDisplayNameAndRef((TaxonBase
) data
);
320 getTextViewer().getTextWidget().setText(text
);
322 if (getTextViewer() instanceof NameViewer
) {
323 ((NameViewer
) getTextViewer()).setCursorToEOL();
325 if (((TaxonBase
) data
).getName() != null) {
326 boolean hasProblem
= ((TaxonBase
) data
).getName()
328 ((NameViewer
) getTextViewer()).setShowError(hasProblem
);
335 * @see eu.etaxonomy.taxeditor.editor.name.EditorGroupedComposite#setSelection()
337 protected void setSelection() {
338 if (getData() instanceof TaxonBase
) {
339 TaxonNameBase taxonNameBase
= ((TaxonBase
) getData()).getName();
340 managedForm
.setInput(taxonNameBase
);
342 super.setSelection();
346 private void createParser() {
347 ((NameViewer
) getTextViewer()).setParseListener(new ParseListener() {
350 public void parse(String text
) {
358 TaxonBase taxonBase
= (TaxonBase
) getData();
359 NonViralName nonViralName
= (NonViralName
) taxonBase
.getName();
361 if (nonViralName
!= null) {
362 CdmUtil
.parseFullReference(nonViralName
, text
, null, true);
363 ((NameViewer
) getTextViewer()).setShowError(nonViralName
.getHasProblem());
374 public void activateParser() {
378 public void deactivateParser() {
382 private NameViewer
createNameViewer() {
383 // nameViewer = new NameViewer(this);
384 // nameViewer.setLineBreakListener(new LineBreakListener() {
386 setTextViewer(new NameViewer(this));
387 getTextViewer().setLineBreakListener(new LineBreakListener() {
390 public void handleSplitText(String text
) {
392 Composite parent
= getParent();
393 final Composite grandParent
= parent
.getParent();
395 new CreateNewHeterotypicCompositeAction(text
, managedForm
)
403 // nameViewer.getTextWidget().addFocusListener(new FocusAdapter() {
404 getTextViewer().getTextWidget().addFocusListener(new FocusAdapter() {
405 public void focusGained(FocusEvent e
) {
410 // createLineWrapSupport(nameViewer);
412 // this.textViewer = nameViewer;
413 // nameViewer.getTextWidget().setBackground(TaxEditorPlugin.getDefault().
414 // getColor(ITaxEditorConstants.GROUP_GRAY_BKG_COLOR));
415 getTextViewer().getTextWidget().setBackground(TaxEditorPlugin
.getDefault().
416 getColor(ITaxEditorConstants
.GROUP_GRAY_BKG_COLOR
));
418 return (NameViewer
) getTextViewer();
422 * @param nameComposite
424 private void createSynonymMenu() {
426 if (!(getData() instanceof Synonym
)) {
430 Synonym synonym
= (Synonym
) getData();
431 ContextMenu contextMenu
= createContextMenu();
433 Action misappliedNameAction
= new MoveCompositeToMisappliedCompositeAction(
435 contextMenu
.addAction(misappliedNameAction
);
437 Action deleteSynonymAction
= new DeleteSynonymCompositeAction(this,
439 contextMenu
.addAction(deleteSynonymAction
);
441 contextMenu
.addSeparator();
443 final Action addBasionymAction
= new AddBasionymCompositeAction(this);
444 contextMenu
.addAction(addBasionymAction
);
446 final Action removeBasionymAction
= new RemoveBasionymCompositeAction(
448 contextMenu
.addAction(removeBasionymAction
);
451 .addPropertyChangeListener(new IPropertyChangeListener() {
453 public void propertyChange(
454 org
.eclipse
.jface
.util
.PropertyChangeEvent event
) {
455 if (event
.getProperty().equals(
456 ITaxEditorConstants
.BASIONYM
)) {
457 removeBasionymAction
.setEnabled(true);
458 transform(NameComposite
.ADD_GROUP_BASIONYM
);
464 .addPropertyChangeListener(new IPropertyChangeListener() {
466 public void propertyChange(
467 org
.eclipse
.jface
.util
.PropertyChangeEvent event
) {
468 if (event
.getProperty().equals(
469 ITaxEditorConstants
.BASIONYM
)) {
470 addBasionymAction
.setEnabled(true);
471 transform(NameComposite
.REMOVE_GROUP_BASIONYM
);
476 contextMenu
.addSeparator();
478 Action changeToThisTaxon
= new ChangeSynonymToTaxonUiAction(synonym
,
480 contextMenu
.addAction(changeToThisTaxon
);
482 Action changeToNewAccepted
= new ChangeCompositeToNewTaxonAction(this,
484 contextMenu
.addAction(changeToNewAccepted
);
488 * @param nameComposite
490 private void createAcceptedMenu() {
492 ContextMenu contextMenu
= createContextMenu();
494 // TODO Make action "Create autonym and subspecies"
496 Action changeTaxonAction
= new ChangeTaxonToSynonymAction(getTaxon());
497 contextMenu
.addAction(changeTaxonAction
);
499 Action moveTaxonAction
= new MoveTaxonDialogAction(getTaxon());
500 contextMenu
.addAction(moveTaxonAction
);
504 * @param nameComposite
506 private void createMisappliedNameMenu() {
508 ContextMenu contextMenu
= createContextMenu();
510 Action deleteMisappliedNameAction
= new DeleteMisappliedNameCompositeAction(
512 contextMenu
.addAction(deleteMisappliedNameAction
);
515 public boolean setParent(Composite parent
) {
517 if (super.setParent(parent
)) {
519 // Has this been moved to the misapplied names group?
520 if (parent
.getData(ITaxEditorConstants
.MISAPPLIED_NAME
) != null) {
521 new ChangeCompositeToMisappliedNameAction(this, managedForm
)
525 // Has this been moved to a HomotypicalGroup?
526 if (parent
.getData() instanceof HomotypicalGroup
) {
527 new AdaptCompositeToGroupAction(this,
528 (EditorGroupComposite
) parent
).run();
536 public void setText(String text
) {
537 Assert
.isNotNull(getTextViewer(),
538 "Cannot set text for a TextViewer that has not yet been initialized.");
539 Assert
.isNotNull(getTextViewer().getDocument(),
540 "Cannot set text for a TextViewer whose Document has not yet been initialized.");
541 getTextViewer().getDocument().set(text
);
544 public NameViewer
getTextViewer() {
545 return this.nameViewer
;
548 public void setTextViewer(NameViewer textViewer
) {
549 this.nameViewer
= textViewer
;