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
;
14 import org
.apache
.log4j
.Logger
;
15 import org
.eclipse
.swt
.events
.FocusAdapter
;
16 import org
.eclipse
.swt
.events
.FocusEvent
;
17 import org
.eclipse
.swt
.events
.ModifyEvent
;
18 import org
.eclipse
.swt
.events
.ModifyListener
;
19 import org
.eclipse
.swt
.graphics
.Font
;
20 import org
.eclipse
.swt
.graphics
.Image
;
21 import org
.eclipse
.swt
.widgets
.Composite
;
23 import eu
.etaxonomy
.cdm
.model
.name
.NameRelationship
;
24 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
25 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
26 import eu
.etaxonomy
.taxeditor
.editor
.EditorUtil
;
27 import eu
.etaxonomy
.taxeditor
.editor
.GroupedComposite
;
28 import eu
.etaxonomy
.taxeditor
.labels
.ILabelImageStrategy
;
29 import eu
.etaxonomy
.taxeditor
.labels
.LabelImageProvider
;
30 import eu
.etaxonomy
.taxeditor
.model
.ImageResources
;
31 import eu
.etaxonomy
.taxeditor
.model
.NameHelper
;
32 import eu
.etaxonomy
.taxeditor
.model
.Resources
;
33 import eu
.etaxonomy
.taxeditor
.operations
.CreateSynonymInNewGroupOperation
;
34 import eu
.etaxonomy
.taxeditor
.parser
.ParseHandler
;
37 * Formats an <code>GroupedComposite</code> to display <code>TaxonNameBase</code> elements
38 * in a <code>NameViewer</code>.
44 public abstract class NameComposite
<T
extends TaxonBase
> extends GroupedComposite
{
45 private static final Logger logger
= Logger
46 .getLogger(NameComposite
.class);
48 * ************ COMPOSITE TYPES ************
50 public String compositeType
;
51 public static final String ACCEPTED_TAXON
= "accepted_name_composite";
52 public static final String HOMOTYPIC_SYNONYM
= "homotypic_name_composite";
53 public static final String HETEROTYPIC_SYNONYM
= "heterotypic_name_composite";
54 public static final String MISAPPLIED_NAME
= "misappliedname_name_composite";
55 public static final String CONCEPTRELATION
= "concept_name_comcposite";
58 * ************ INDENTATIONS ************
60 public static final int ACCEPTED_INDENT
= 0;
61 public static final int SYNONYM_INDENT
= 15;
62 public static final int MISAPPLIEDNAME_INDENT
= 15;
63 public static final int CONCEPT_INDENT
= 15;
66 * ************ FONTS ************
68 public static final Font ACCEPTED_FONT
= Resources
69 .getFont(Resources
.ACCEPTED_TAXON_FONT
);
70 public static final Font SYNONYM_FONT
= Resources
71 .getFont(Resources
.SYNONYM_FONT
);
72 public static final Font MISAPPLIEDNAME_FONT
= Resources
73 .getFont(Resources
.MISAPPLIEDNAME_FONT
);
74 public static final Font CONCEPT_FONT
= Resources
75 .getFont(Resources
.CONCEPT_FONT
);
78 * ************ ICONS ************
80 public static final Image ACCEPTED_ICON
= ImageResources
81 .getImage(ImageResources
.BLACK_SQUARE_ICON
);
82 public static final Image HOMOTYPIC_SYNONYM_ICON
= ImageResources
.getImage(ImageResources
.HOMOTYPIC_SYN_ICON
);
83 public static final Image HOMOTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
= ImageResources
.getImage(
84 ImageResources
.HOMOTYPIC_SYN_ORIGINAL_ICON
);
85 public static final Image HETEROTYPIC_SYNONYM_ICON
= ImageResources
.getImage(ImageResources
.HETEROTYPIC_SYN_ICON
);
86 public static final Image HETEROTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
= ImageResources
.getImage(
87 ImageResources
.HETEROTYPIC_SYN_ORIGINAL_ICON
);
88 public static final Image MISAPPLIEDNAME_ICON
= ImageResources
.getImage(ImageResources
.MISAPPLIED_NAME_ICON
);
89 public static final Image CONCEPT_ICON
= ImageResources
.getImage(ImageResources
.CONCEPT_ICON
);
90 public static final Image AUTONYM_ICON
= ImageResources
91 .getImage(ImageResources
.AUTONYM_ICON
);
92 public static final Image MOVE
= ImageResources
.getImage(ImageResources
.MOVE_ICON
);
95 * ************ TRANSFORMATIONS ************
97 public static final String ADD_GROUP_BASIONYM
= "add_group_basionym";
98 public static final String REMOVE_GROUP_BASIONYM
= "remove_group_basionym";
102 private static final String EMPTY_NAME_PROMPT
= "Click to add name";
105 * Used to turn parser on and off.
107 * @see activateParser
108 * @see deactivateParser
110 private boolean isUseParser
= false;
112 protected ParseHandler parseHandler
;
114 protected boolean isParsing
;
116 protected TaxonNameBase parsedName
;
119 * Whether this NameComposite has unsaved changes
121 private boolean isDirty
= false;
123 protected T taxonBase
;
124 private NameCompositeFocusListener nameCompositeFocusListener
;
125 private NameCompositeModifyListener nameCompositeModifyListener
;
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(TaxonNameEditor editor
, Composite parent
, T taxonBase
) {
137 super(editor
, parent
);
139 this.taxonBase
= taxonBase
;
143 // createBorderSupport();
144 createLineWrapSupport();
145 createLineBreakListener();
147 this.setMenu(editor
.getMenu());
149 setDraggableControl(textViewer
.getRulerControl());
151 createEmptyViewerPrompt(EMPTY_NAME_PROMPT
);
153 parseHandler
= ParseHandler
.NewInstance(textViewer
.getTextWidget(), taxonBase
.getName());
155 initializeComposite();
162 protected void createListener(){
163 nameCompositeModifyListener
= new NameCompositeModifyListener();
164 nameCompositeFocusListener
= new NameCompositeFocusListener();
169 private void addListener(){
170 textViewer
.getTextWidget().addModifyListener(nameCompositeModifyListener
);
171 textViewer
.getTextWidget().addFocusListener(nameCompositeFocusListener
);
174 private void removeListener(){
175 textViewer
.getTextWidget().removeModifyListener(nameCompositeModifyListener
);
176 textViewer
.getTextWidget().removeFocusListener(nameCompositeFocusListener
);
180 * Initialize the composite specific code
183 protected abstract void initializeComposite();
185 protected String
getEmptyTextPrompt() {
186 return EMPTY_NAME_PROMPT
;
192 private void showNameRelations() {
193 TaxonNameBase
<?
, ?
> name
= getName();
198 ILabelImageStrategy strategy
= LabelImageProvider
.getLabelStrategy(name
);
199 LabelImageProvider labelProvider
= new LabelImageProvider(strategy
);
201 Set
<NameRelationship
> nameRelations
= name
.getNameRelations();
202 if (nameRelations
.size() == 0) {
205 for (NameRelationship nameRelation
: nameRelations
) {
206 String typeLabel
= null;
207 TaxonNameBase
<?
, ?
> relatedName
= null;
209 if (name
.equals(nameRelation
.getFromName())) {
210 typeLabel
= labelProvider
.getNameRelationTypeLabel(
211 nameRelation
.getType());
212 relatedName
= nameRelation
.getToName();
214 typeLabel
= labelProvider
.getNameRelationTypeInverseLabel(
215 nameRelation
.getType());
216 relatedName
= nameRelation
.getFromName();
219 setNonEditableInfo(typeLabel
+ " " + NameHelper
.getDisplayName(relatedName
));
223 protected void initTextViewer(TaxonBase
<?
> taxonBase
) {
227 String text
= NameHelper
.getDisplayNameWithRef(taxonBase
);
229 if (text
.length() == 0) {
232 textViewer
.getTextWidget().setText(text
);
233 textViewer
.setCursorToEOL();
238 // FIXME we do have a naming conflict here
239 public abstract TaxonNameBase
<?
, ?
> getName();
241 public abstract void setName(TaxonNameBase name
);
243 synchronized protected void calculateErrors() {
244 textViewer
.clearErrors();
246 textViewer
.setShowParsingErrors(getName());
249 protected void handleSplitText(String text
) {
250 // Create a synonym in a new homotypic group using text as name
251 TaxonNameBase synonymName
= ParseHandler
.quickParse(text
);
253 EditorUtil
.executeOperation(new CreateSynonymInNewGroupOperation
254 ("New Heterotypic Synonym", editor
.getUndoContext(), editor
.getTaxon(), synonymName
, editor
));
255 logger
.debug("new heterotypic synonym created through entering of line break");
258 // protected IPropertySource getPropertySourceByName(TaxonNameBase<?, ?> name) {
259 // if (name == null) {
263 // if (name.getClass() == BotanicalName.class) {
264 // return new BotanicalNamePropertySource((BotanicalName) name);
266 // if (name.getClass() == ZoologicalName.class) {
267 // return new ZoologicalNamePropertySource((ZoologicalName) name);
269 // if (name instanceof NonViralName) {
270 // return new NonViralNamePropertySource((NonViralName<?>) name);
277 * @see eu.etaxonomy.taxeditor.editor.GroupedComposite#refresh()
280 public void refresh() {
282 // initTextViewer((TaxonBase) getData());
284 // FIXME this is copied from initTextViewer().
288 String text
= NameHelper
.getDisplayNameWithRef((TaxonBase
) getData());
290 if (text
.length() == 0) {
293 updateTextWidget(text
);
294 // textViewer.setCursorToEOL();
298 private void updateTextWidget(String text
){
300 textViewer
.getTextWidget().setText(text
);
301 parseHandler
.parse();
306 public boolean isDirty(){
311 * @see eu.etaxonomy.taxeditor.editor.GroupedComposite#setDirty(boolean)
314 protected void setDirty(boolean isDirty
) {
315 // TODO Auto-generated method stub
316 super.setDirty(isDirty
);
317 // set the dirty state for this composite
318 this.isDirty
= isDirty
;
322 * @return the taxonBase
324 public T
getTaxonBase() {
329 * @return the parsedName
331 public TaxonNameBase
getParsedName() {
336 * @see eu.etaxonomy.taxeditor.editor.GroupedComposite#dispose()
339 public void dispose() {
341 this.removeFocusListener(nameCompositeFocusListener
);
344 public void persistName(){
346 logger
.warn("Found dirty composite: " + this + ". Name: " + textViewer
.getTextWidget().getText());
347 taxonBase
.setName(parseHandler
.parseAndResolveDuplicates());
349 getTaxonBase().setTitleCache((getTaxonBase().generateTitle()));
354 class NameCompositeModifyListener
implements ModifyListener
{
356 public void modifyText(ModifyEvent e
) {
357 parseHandler
.parse();
359 // getTaxonBase().setName(name);
362 // show errors resulting from parsing
364 // mark the composite dirty
369 class NameCompositeFocusListener
extends FocusAdapter
{
372 * @see org.eclipse.swt.events.FocusAdapter#focusLost(org.eclipse.swt.events.FocusEvent)
375 public void focusLost(FocusEvent e
) {