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
.commands
.ExecutionException
;
17 import org
.eclipse
.core
.commands
.operations
.IOperationHistory
;
18 import org
.eclipse
.core
.commands
.operations
.IUndoContext
;
19 import org
.eclipse
.core
.commands
.operations
.IUndoableOperation
;
20 import org
.eclipse
.core
.runtime
.Assert
;
21 import org
.eclipse
.core
.runtime
.IStatus
;
22 import org
.eclipse
.jface
.action
.Action
;
23 import org
.eclipse
.swt
.events
.DisposeEvent
;
24 import org
.eclipse
.swt
.events
.DisposeListener
;
25 import org
.eclipse
.swt
.events
.FocusAdapter
;
26 import org
.eclipse
.swt
.events
.FocusEvent
;
27 import org
.eclipse
.swt
.graphics
.Font
;
28 import org
.eclipse
.swt
.graphics
.Image
;
29 import org
.eclipse
.swt
.widgets
.Composite
;
30 import org
.eclipse
.ui
.forms
.IManagedForm
;
31 import org
.eclipse
.ui
.views
.properties
.IPropertySource
;
33 import eu
.etaxonomy
.cdm
.model
.name
.BotanicalName
;
34 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
35 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
36 import eu
.etaxonomy
.cdm
.model
.name
.ZoologicalName
;
37 import eu
.etaxonomy
.cdm
.model
.reference
.StrictReferenceBase
;
38 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
39 import eu
.etaxonomy
.taxeditor
.ITaxEditorConstants
;
40 import eu
.etaxonomy
.taxeditor
.TaxEditorPlugin
;
41 import eu
.etaxonomy
.taxeditor
.controller
.EditorController
;
42 import eu
.etaxonomy
.taxeditor
.controller
.GlobalController
;
43 import eu
.etaxonomy
.taxeditor
.editor
.EditorGroupedComposite
;
44 import eu
.etaxonomy
.taxeditor
.editor
.LineBreakListener
;
45 import eu
.etaxonomy
.taxeditor
.editor
.ParseListener
;
46 import eu
.etaxonomy
.taxeditor
.model
.CdmUtil
;
47 import eu
.etaxonomy
.taxeditor
.operations
.name
.CreateSynonymInNewGroupOperation
;
48 import eu
.etaxonomy
.taxeditor
.propertysheet
.name
.BotanicalNamePropertySource
;
49 import eu
.etaxonomy
.taxeditor
.propertysheet
.name
.NonViralNamePropertySource
;
50 import eu
.etaxonomy
.taxeditor
.propertysheet
.name
.ZoologicalNamePropertySource
;
53 * Formats an <code>EditorGroupedComposite</code> to display <code>TaxonNameBase</code> elements
54 * in a <code>NameViewer</code>.
60 public abstract class NameComposite
extends EditorGroupedComposite
{
61 private static final Logger logger
= Logger
.getLogger(NameComposite
.class);
64 * ************ COMPOSITE TYPES ************
66 public String compositeType
;
67 public static final String ACCEPTED_TAXON
= "accepted_name_composite";
68 public static final String HOMOTYPIC_SYNONYM
= "homotypic_name_composite";
69 public static final String HETEROTYPIC_SYNONYM
= "heterotypic_name_composite";
70 public static final String MISAPPLIED_NAME
= "misappliedname_name_composite";
73 * ************ INDENTATIONS ************
75 public static final int ACCEPTED_INDENT
= 0;
76 public static final int SYNONYM_INDENT
= 15;
77 public static final int MISAPPLIEDNAME_INDENT
= 15;
80 * ************ FONTS ************
82 public static final Font ACCEPTED_FONT
= TaxEditorPlugin
.getDefault()
83 .getFont(ITaxEditorConstants
.ACCEPTED_TAXON_FONT
);
84 public static final Font SYNONYM_FONT
= TaxEditorPlugin
.getDefault()
85 .getFont(ITaxEditorConstants
.SYNONYM_FONT
);
86 public static final Font MISAPPLIEDNAME_FONT
= TaxEditorPlugin
.getDefault()
87 .getFont(ITaxEditorConstants
.MISAPPLIEDNAME_FONT
);
90 * ************ ICONS ************
92 public static final Image ACCEPTED_ICON
= TaxEditorPlugin
.getDefault()
93 .getImage(ITaxEditorConstants
.BLACK_SQUARE_ICON
);
94 public static final Image HOMOTYPIC_SYNONYM_ICON
= TaxEditorPlugin
95 .getDefault().getImage(ITaxEditorConstants
.HOMOTYPIC_SYN_ICON
);
96 public static final Image HOMOTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
= TaxEditorPlugin
97 .getDefault().getImage(
98 ITaxEditorConstants
.HOMOTYPIC_SYN_ORIGINAL_ICON
);
99 public static final Image HETEROTYPIC_SYNONYM_ICON
= TaxEditorPlugin
100 .getDefault().getImage(ITaxEditorConstants
.HETEROTYPIC_SYN_ICON
);
101 public static final Image HETEROTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
= TaxEditorPlugin
102 .getDefault().getImage(
103 ITaxEditorConstants
.HETEROTYPIC_SYN_ORIGINAL_ICON
);
104 public static final Image MISAPPLIEDNAME_ICON
= TaxEditorPlugin
105 .getDefault().getImage(ITaxEditorConstants
.MISAPPLIED_NAME_ICON
);
106 public static final Image AUTONYM_ICON
= TaxEditorPlugin
.getDefault()
107 .getImage(ITaxEditorConstants
.AUTONYM_ICON
);
108 public static final Image BASIONYM_ICON
= TaxEditorPlugin
.getDefault()
109 .getImage(ITaxEditorConstants
.BASIONYM_ICON
);
110 public static final Image MOVE
= TaxEditorPlugin
.getDefault().getImage(
111 ITaxEditorConstants
.MOVE_ICON
);
114 * ************ TRANSFORMATIONS ************
116 public static final String ADD_GROUP_BASIONYM
= "add_group_basionym";
117 public static final String REMOVE_GROUP_BASIONYM
= "remove_group_basionym";
120 * ************ MENU ACTIONS ************
122 public Action CHANGE_TAXON_TO_SYNONYM_ACTION
;
124 private static final String EMPTY_NAME_PROMPT
= "Click to add name";
127 * Used to turn parser on and off.
129 * @see activateParser
130 * @see deactivateParser
132 private boolean isUseParser
= false;
134 protected boolean isParsing
;
136 private NameViewer nameViewer
;
139 * The constructor for a DescriptionElementComposite. Takes a parent Composite on which to
140 * create itself, and an IManagedForm for Composite life cycle methods, i.e.
141 * drawing borders, creating other Composites, creating line wrap support,
147 public NameComposite(Composite parent
, IManagedForm managedForm
,
148 String compositeType
, TaxonBase taxonBase
) {
149 super(parent
, managedForm
);
152 createBorderSupport();
153 createLineWrapSupport();
158 createEmptyViewerPrompt(EMPTY_NAME_PROMPT
);
161 // NOTE: placing this after setFocus() inexplicably solved a strange bug where if the first action
162 // during a session was to open a new taxon, the empty name prompt didn't work
163 createNameListener(taxonBase
.getName());
166 protected String
getEmptyTextPrompt() {
167 return EMPTY_NAME_PROMPT
;
171 * Listens for changes to this name's <code>fullTitleCache</code>.
175 private void createNameListener(final TaxonNameBase name
) {
181 final PropertyChangeListener listener
= new PropertyChangeListener() {
182 public void propertyChange(PropertyChangeEvent evt
) {
188 if (EditorController
.isSaving()) {
193 ((NameViewer
) getTextViewer()).setText(name
.getFullTitleCache());
198 // TODO clean this part up
199 name
.addPropertyChangeListener("fullTitleCache", listener
);
200 name
.addPropertyChangeListener("nomenclaturalMicroReference", listener
);
202 // name.addPropertyChangeListener(ITaxEditorConstants.REFRESH_NAMEVIEWER, listener);
204 StrictReferenceBase reference
= (StrictReferenceBase
) name
.getNomenclaturalReference();
205 if (reference
!= null) {
206 reference
.addPropertyChangeListener("titleCache", listener
);
210 protected void initNameViewer(TaxonBase taxonBase
) {
211 String text
= CdmUtil
.getDisplayNameWithRef(taxonBase
);
212 if (text
.length() == 0) {
215 getTextViewer().getTextWidget().setText(text
);
217 if (getTextViewer() instanceof NameViewer
) {
219 ((NameViewer
) getTextViewer()).setCursorToEOL();
221 TaxonNameBase name
= taxonBase
.getName();
224 boolean hasProblem
= name
.getHasProblem();
225 ((NameViewer
) getTextViewer()).setShowError(name
);
231 private void createParser() {
232 ((NameViewer
) getTextViewer()).addParseListener(new ParseListener() {
235 public void parse(String text
) {
237 // Either composite is not yet fully built, or
238 // the property sheet is writing to it
243 // Let others know the parser is active
246 // Get the name from the composite's data field
247 TaxonBase taxonBase
= (TaxonBase
) getData();
248 NonViralName nonViralName
= (NonViralName
) taxonBase
.getName();
250 // Parse the name and paint the text field w any errors
251 if (nonViralName
!= null) {
252 CdmParserController
.parseFullReference(nonViralName
, text
);
253 ((NameViewer
) getTextViewer()).setShowError(nonViralName
);
256 // Any entry of text means the taxon has been changed
259 // The parser is no longer active
262 // Manually refresh the property sheet to reflect changes
269 public void activateParser() {
273 public void deactivateParser() {
277 private NameViewer
createNameViewer() {
278 // nameViewer = new NameViewer(this);
279 // nameViewer.setLineBreakListener(new LineBreakListener() {
281 setTextViewer(new NameViewer(this));
282 getTextViewer().addLineBreakListener(new LineBreakListener() {
285 public void handleSplitText(String text
) {
287 // Create a synonym in a new homotypic group using text as name
288 IUndoContext undoContext
= EditorController
.getUndoContext(taxon
);
289 IUndoableOperation operation
= new CreateSynonymInNewGroupOperation
290 ("new heterotypic synonym", undoContext
, taxon
, text
); //$NON-NLS-1$
292 GlobalController
.executeOperation(operation
);
294 // getTextViewer().removeLineBreakListener(this);
299 getTextViewer().getTextWidget().addFocusListener(new FocusAdapter() {
300 public void focusGained(FocusEvent e
) {
305 getTextViewer().getTextWidget().addDisposeListener(new DisposeListener() {
308 public void widgetDisposed(DisposeEvent e
) {
309 logger
.warn("disposing text widget");
313 // createLineWrapSupport(nameViewer);
315 getTextViewer().getTextWidget().setBackground(TaxEditorPlugin
.getDefault().
316 getColor(ITaxEditorConstants
.GROUP_GRAY_BKG_COLOR
));
318 return (NameViewer
) getTextViewer();
321 public void setText(String text
) {
322 Assert
.isNotNull(getTextViewer(),
323 "Cannot set text for a TextViewer that has not yet been initialized.");
324 Assert
.isNotNull(getTextViewer().getDocument(),
325 "Cannot set text for a TextViewer whose Document has not yet been initialized.");
326 getTextViewer().getDocument().set(text
);
329 public NameViewer
getTextViewer() {
330 return this.nameViewer
;
333 public void setTextViewer(NameViewer textViewer
) {
334 this.nameViewer
= textViewer
;
337 protected IPropertySource
getPropertySourceByName(TaxonNameBase name
) {
342 if (name
.getClass() == BotanicalName
.class) {
343 return new BotanicalNamePropertySource((BotanicalName
) name
);
345 if (name
.getClass() == ZoologicalName
.class) {
346 return new ZoologicalNamePropertySource((ZoologicalName
) name
);
348 if (name
instanceof NonViralName
) {
349 return new NonViralNamePropertySource((NonViralName
) name
);