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
.operations
.IUndoContext
;
17 import org
.eclipse
.core
.commands
.operations
.IUndoableOperation
;
18 import org
.eclipse
.core
.runtime
.Assert
;
19 import org
.eclipse
.jface
.action
.Action
;
20 import org
.eclipse
.swt
.SWT
;
21 import org
.eclipse
.swt
.custom
.StyledText
;
22 import org
.eclipse
.swt
.events
.FocusAdapter
;
23 import org
.eclipse
.swt
.events
.FocusEvent
;
24 import org
.eclipse
.swt
.events
.KeyAdapter
;
25 import org
.eclipse
.swt
.events
.KeyEvent
;
26 import org
.eclipse
.swt
.graphics
.Color
;
27 import org
.eclipse
.swt
.graphics
.Font
;
28 import org
.eclipse
.swt
.graphics
.Image
;
29 import org
.eclipse
.swt
.layout
.GridData
;
30 import org
.eclipse
.swt
.widgets
.Composite
;
31 import org
.eclipse
.swt
.widgets
.Label
;
32 import org
.eclipse
.ui
.forms
.IManagedForm
;
33 import org
.eclipse
.ui
.forms
.widgets
.TableWrapData
;
34 import org
.eclipse
.ui
.forms
.widgets
.TableWrapLayout
;
35 import org
.eclipse
.ui
.views
.properties
.IPropertySource
;
37 import eu
.etaxonomy
.cdm
.model
.name
.BotanicalName
;
38 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
39 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
40 import eu
.etaxonomy
.cdm
.model
.name
.ZoologicalName
;
41 import eu
.etaxonomy
.cdm
.model
.reference
.StrictReferenceBase
;
42 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
43 import eu
.etaxonomy
.taxeditor
.ITaxEditorConstants
;
44 import eu
.etaxonomy
.taxeditor
.TaxEditorPlugin
;
45 import eu
.etaxonomy
.taxeditor
.controller
.EditorController
;
46 import eu
.etaxonomy
.taxeditor
.controller
.GlobalController
;
47 import eu
.etaxonomy
.taxeditor
.editor
.ContextMenu
;
48 import eu
.etaxonomy
.taxeditor
.editor
.GroupedComposite
;
49 import eu
.etaxonomy
.taxeditor
.editor
.LineBreakListener
;
50 import eu
.etaxonomy
.taxeditor
.editor
.ParseListener
;
51 import eu
.etaxonomy
.taxeditor
.model
.CdmUtil
;
52 import eu
.etaxonomy
.taxeditor
.operations
.name
.CreateSynonymInNewGroupOperation
;
53 import eu
.etaxonomy
.taxeditor
.propertysheet
.name
.BotanicalNamePropertySource
;
54 import eu
.etaxonomy
.taxeditor
.propertysheet
.name
.NonViralNamePropertySource
;
55 import eu
.etaxonomy
.taxeditor
.propertysheet
.name
.ZoologicalNamePropertySource
;
58 * Formats an <code>GroupedComposite</code> to display <code>TaxonNameBase</code> elements
59 * in a <code>NameViewer</code>.
65 public abstract class NameComposite
extends GroupedComposite
{
66 private static final Logger logger
= Logger
.getLogger(NameComposite
.class);
69 * ************ COMPOSITE TYPES ************
71 public String compositeType
;
72 public static final String ACCEPTED_TAXON
= "accepted_name_composite";
73 public static final String HOMOTYPIC_SYNONYM
= "homotypic_name_composite";
74 public static final String HETEROTYPIC_SYNONYM
= "heterotypic_name_composite";
75 public static final String MISAPPLIED_NAME
= "misappliedname_name_composite";
76 public static final String CONCEPTRELATION
= "concept_name_comcposite";
79 * ************ INDENTATIONS ************
81 public static final int ACCEPTED_INDENT
= 0;
82 public static final int SYNONYM_INDENT
= 15;
83 public static final int MISAPPLIEDNAME_INDENT
= 15;
84 public static final int CONCEPT_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
);
95 public static final Font CONCEPT_FONT
= TaxEditorPlugin
.getDefault()
96 .getFont(ITaxEditorConstants
.CONCEPT_FONT
);
99 * ************ ICONS ************
101 public static final Image ACCEPTED_ICON
= TaxEditorPlugin
.getDefault()
102 .getImage(ITaxEditorConstants
.BLACK_SQUARE_ICON
);
103 public static final Image HOMOTYPIC_SYNONYM_ICON
= TaxEditorPlugin
104 .getDefault().getImage(ITaxEditorConstants
.HOMOTYPIC_SYN_ICON
);
105 public static final Image HOMOTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
= TaxEditorPlugin
106 .getDefault().getImage(
107 ITaxEditorConstants
.HOMOTYPIC_SYN_ORIGINAL_ICON
);
108 public static final Image HETEROTYPIC_SYNONYM_ICON
= TaxEditorPlugin
109 .getDefault().getImage(ITaxEditorConstants
.HETEROTYPIC_SYN_ICON
);
110 public static final Image HETEROTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
= TaxEditorPlugin
111 .getDefault().getImage(
112 ITaxEditorConstants
.HETEROTYPIC_SYN_ORIGINAL_ICON
);
113 public static final Image MISAPPLIEDNAME_ICON
= TaxEditorPlugin
114 .getDefault().getImage(ITaxEditorConstants
.MISAPPLIED_NAME_ICON
);
115 public static final Image CONCEPT_ICON
= TaxEditorPlugin
116 .getDefault().getImage(ITaxEditorConstants
.CONCEPT_ICON
);
117 public static final Image AUTONYM_ICON
= TaxEditorPlugin
.getDefault()
118 .getImage(ITaxEditorConstants
.AUTONYM_ICON
);
119 public static final Image BASIONYM_ICON
= TaxEditorPlugin
.getDefault()
120 .getImage(ITaxEditorConstants
.BASIONYM_ICON
);
121 public static final Image MOVE
= TaxEditorPlugin
.getDefault().getImage(
122 ITaxEditorConstants
.MOVE_ICON
);
125 * ************ TRANSFORMATIONS ************
127 public static final String ADD_GROUP_BASIONYM
= "add_group_basionym";
128 public static final String REMOVE_GROUP_BASIONYM
= "remove_group_basionym";
131 * ************ MENU ACTIONS ************
133 public Action CHANGE_TAXON_TO_SYNONYM_ACTION
;
135 private static final String EMPTY_NAME_PROMPT
= "Click to add name";
138 * Used to turn parser on and off.
140 * @see activateParser
141 * @see deactivateParser
143 private boolean isUseParser
= false;
145 protected boolean isParsing
;
147 protected NameViewer nameViewer
;
150 * The constructor for a DescriptionElementComposite. Takes a parent Composite on which to
151 * create itself, and an IManagedForm for Composite life cycle methods, i.e.
152 * drawing borders, creating other Composites, creating line wrap support,
158 public NameComposite(Composite parent
, IManagedForm managedForm
,
159 String compositeType
, TaxonBase taxonBase
) {
160 super(parent
, managedForm
);
163 createBorderSupport();
164 createLineWrapSupport();
166 setDraggableControl(nameViewer
.getRulerControl());
168 // setData(taxonBase);
171 createEmptyViewerPrompt(EMPTY_NAME_PROMPT
);
174 // NOTE: placing this after setFocus() inexplicably solved a strange bug where if the first action
175 // during a session was to open a new taxon, the empty name prompt didn't work
176 createNameListener(taxonBase
.getName());
179 protected void createContent() {
180 setLayoutData(new TableWrapData(TableWrapData
.FILL_GRAB
));
181 TableWrapLayout layout
= new TableWrapLayout();
182 layout
.leftMargin
= 0;
183 // layout.topMargin = 20;
184 // layout.bottomMargin = 20;
187 Color groupBackgroundColor
= TaxEditorPlugin
.getDefault().
188 getColor(ITaxEditorConstants
.GROUP_GRAY_BKG_COLOR
);
189 setBackground(groupBackgroundColor
);
192 protected String
getEmptyTextPrompt() {
193 return EMPTY_NAME_PROMPT
;
197 * Listens for changes to this name's <code>fullTitleCache</code>.
201 private void createNameListener(final TaxonNameBase name
) {
207 final PropertyChangeListener listener
= new PropertyChangeListener() {
208 public void propertyChange(PropertyChangeEvent evt
) {
214 if (EditorController
.isSaving()) {
219 ((NameViewer
) getTextViewer()).setText(name
.getFullTitleCache());
224 // TODO clean this part up
225 name
.addPropertyChangeListener("fullTitleCache", listener
);
226 name
.addPropertyChangeListener("nomenclaturalMicroReference", listener
);
228 // name.addPropertyChangeListener(ITaxEditorConstants.REFRESH_NAMEVIEWER, listener);
230 StrictReferenceBase reference
= (StrictReferenceBase
) name
.getNomenclaturalReference();
231 if (reference
!= null) {
232 reference
.addPropertyChangeListener("titleCache", listener
);
236 protected void initNameViewer(TaxonBase taxonBase
) {
237 String text
= CdmUtil
.getDisplayNameWithRef(taxonBase
);
238 if (text
.length() == 0) {
241 getTextViewer().getTextWidget().setText(text
);
243 if (getTextViewer() instanceof NameViewer
) {
245 ((NameViewer
) getTextViewer()).setCursorToEOL();
247 TaxonNameBase name
= taxonBase
.getName();
250 // boolean hasProblem = name.getHasProblem();
251 // ((NameViewer) getTextViewer()).setShowError(name);
260 private void createParser() {
261 ((NameViewer
) getTextViewer()).addParseListener(new ParseListener() {
264 public void parse(String text
) {
266 // Either composite is not yet fully built, or
267 // the property sheet is writing to it
272 // Let others know the parser is active
275 // Get the name from the composite's data field
276 // TaxonBase taxonBase = (TaxonBase) getData();
277 // NonViralName nonViralName = (NonViralName) taxonBase.getName();
279 // Parse the name and paint the text field w any errors
280 if (getName() != null) {
281 CdmParserController
.parseFullReference((NonViralName
) getName(), text
);
282 // ((NameViewer) getTextViewer()).setShowError(nonViralName);
285 // Any entry of text means the taxon has been changed
288 // The parser is no longer active
291 // Manually refresh the property sheet to reflect changes
294 // Show any errors in the name viewer
300 public void activateParser() {
304 public void deactivateParser() {
308 protected abstract TaxonNameBase
getName();
310 protected void calculateErrors() {
312 nameViewer
.clearErrors();
314 nameViewer
.setShowParsingError(getName());
318 private NameViewer
createNameViewer() {
320 nameViewer
= new NameViewer(this);
322 StyledText styledText
= nameViewer
.getTextWidget();
323 // nameViewer.setLineBreakListener(new LineBreakListener() {
325 setTextViewer(nameViewer
);
327 nameViewer
.addLineBreakListener(new LineBreakListener() {
330 public void handleSplitText(String text
) {
332 // Create a synonym in a new homotypic group using text as name
333 IUndoContext undoContext
= EditorController
.getUndoContext(taxon
);
334 // IUndoableOperation operation = new CreateSynonymInNewGroupOperation
335 setOperation(new CreateSynonymInNewGroupOperation
336 ("new heterotypic synonym", undoContext
, taxon
, text
)); //$NON-NLS-1$
338 // GlobalController.executeOperation(operation);
340 // getTextViewer().removeLineBreakListener(this);
345 styledText
.addKeyListener(new KeyAdapter(){
348 public void keyReleased(KeyEvent e
) {
349 if (operation
!= null) {
350 GlobalController
.executeOperation(operation
);
357 styledText
.addFocusListener(new FocusAdapter() {
358 public void focusGained(FocusEvent e
) {
363 // createLineWrapSupport(nameViewer);
365 styledText
.setBackground(TaxEditorPlugin
.getDefault().
366 getColor(ITaxEditorConstants
.GROUP_GRAY_BKG_COLOR
));
371 IUndoableOperation operation
;
373 private Label nonEditableInfo
;
375 protected void setOperation(IUndoableOperation operation
) {
376 this.operation
= operation
;
379 public void setText(String text
) {
380 Assert
.isNotNull(getTextViewer(),
381 "Cannot set text for a TextViewer that has not yet been initialized.");
382 Assert
.isNotNull(getTextViewer().getDocument(),
383 "Cannot set text for a TextViewer whose Document has not yet been initialized.");
384 getTextViewer().getDocument().set(text
);
387 public void setNonEditableInfo(String info
) {
388 if (nonEditableInfo
== null) {
389 nonEditableInfo
= new Label(this, SWT
.WRAP
);
390 nonEditableInfo
.setLayoutData(new TableWrapData(TableWrapData
.FILL_GRAB
, TableWrapData
.TOP
));
392 info
= nonEditableInfo
.getText() + ", " + info
;
394 nonEditableInfo
.setText(info
.toUpperCase());
397 public NameViewer
getTextViewer() {
398 return this.nameViewer
;
401 public void setTextViewer(NameViewer textViewer
) {
402 this.nameViewer
= textViewer
;
405 public void createBorderSupport() {
406 super.createBorderSupport();
407 if (nameViewer
!= null) {
408 borderDecorator
.setBorderedComposite(nameViewer
.getTextWidget());
412 public void setIcon(Image icon
) {
413 // super.setIcon(icon);
414 if (nameViewer
!= null) {
415 nameViewer
.setIcon(icon
);
419 protected IPropertySource
getPropertySourceByName(TaxonNameBase name
) {
424 if (name
.getClass() == BotanicalName
.class) {
425 return new BotanicalNamePropertySource((BotanicalName
) name
);
427 if (name
.getClass() == ZoologicalName
.class) {
428 return new ZoologicalNamePropertySource((ZoologicalName
) name
);
430 if (name
instanceof NonViralName
) {
431 return new NonViralNamePropertySource((NonViralName
) name
);
437 protected ContextMenu
createContextMenu() {
438 if (nameViewer
!= null) {
439 ContextMenu contextMenu
= new ContextMenu(nameViewer
.getRulerControl());
440 nameViewer
.getTextWidget().setMenu(contextMenu
.getMenu());
443 logger
.warn("Can't create menu because nameViewer has not been initalized.");