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
;
14 import java
.util
.HashSet
;
17 import org
.apache
.log4j
.Logger
;
18 import org
.eclipse
.core
.commands
.operations
.IUndoContext
;
19 import org
.eclipse
.core
.commands
.operations
.IUndoableOperation
;
20 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
21 import org
.eclipse
.jface
.dialogs
.IMessageProvider
;
22 import org
.eclipse
.swt
.dnd
.DND
;
23 import org
.eclipse
.swt
.dnd
.DropTarget
;
24 import org
.eclipse
.swt
.dnd
.DropTargetAdapter
;
25 import org
.eclipse
.swt
.dnd
.DropTargetEvent
;
26 import org
.eclipse
.swt
.dnd
.Transfer
;
27 import org
.eclipse
.swt
.events
.ControlAdapter
;
28 import org
.eclipse
.swt
.events
.ControlEvent
;
29 import org
.eclipse
.swt
.widgets
.Composite
;
30 import org
.eclipse
.swt
.widgets
.Control
;
31 import org
.eclipse
.ui
.IEditorInput
;
32 import org
.eclipse
.ui
.IEditorSite
;
33 import org
.eclipse
.ui
.PartInitException
;
35 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
36 import eu
.etaxonomy
.cdm
.model
.name
.HomotypicalGroup
;
37 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
38 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
39 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
40 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
41 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
42 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationship
;
43 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationshipType
;
44 import eu
.etaxonomy
.taxeditor
.ITaxEditorConstants
;
45 import eu
.etaxonomy
.taxeditor
.actions
.WidgetTransfer
;
46 import eu
.etaxonomy
.taxeditor
.controller
.EditorController
;
47 import eu
.etaxonomy
.taxeditor
.controller
.GlobalController
;
48 import eu
.etaxonomy
.taxeditor
.editor
.AbstractTaxonEditor
;
49 import eu
.etaxonomy
.taxeditor
.editor
.FreeTextElementFactory
;
50 import eu
.etaxonomy
.taxeditor
.editor
.INameEditorCompositeRepository
;
51 import eu
.etaxonomy
.taxeditor
.operations
.name
.ChangeHomotypicGroupOperation
;
52 import eu
.etaxonomy
.taxeditor
.operations
.name
.ChangeMisappliedNameToSynonymOperation
;
59 public class TaxonNameEditor
extends AbstractTaxonEditor
60 implements INameEditorCompositeRepository
{
61 private static final Logger logger
= Logger
.getLogger(TaxonNameEditor
.class);
64 * Shared listener that sets dirty state to true
65 * when any registered property changes
67 private PropertyChangeListener taxonChangeListener
= new PropertyChangeListener() {
68 public void propertyChange(PropertyChangeEvent event
) {
69 if (event
.getPropertyName().equals(ITaxEditorConstants
.PROPERTY_SHEET_CHANGE
)) {
70 firePropertyChange(PROP_DIRTY
);
75 private Composite partComposite
;
78 public void doSave(IProgressMonitor monitor
) {}
81 public void doSaveAs() {}
84 public void init(IEditorSite site
, IEditorInput input
)
85 throws PartInitException
{
87 super.init(site
, input
);
89 Taxon taxon
= getTaxon();
91 EditorController
.addEditor(taxon
, this);
93 // Register listeners for any change in accepted name or set of relations
94 taxon
.getName().addPropertyChangeListener(taxonChangeListener
);
95 taxon
.addPropertyChangeListener(taxonChangeListener
);
99 public boolean isDirty() {
104 public boolean isSaveAsAllowed() {
109 public void createPartControl(final Composite composite
) {
111 this.partComposite
= composite
;
113 super.createPartControl(composite
);
115 Taxon taxon
= getTaxon();
117 NameComposite acceptedNameComposite
=
118 (NameComposite
) FreeTextElementFactory
.getDefault().
119 createAcceptedTaxon(managedForm
, taxon
);
121 for (TaxonBase taxonBase
: new IterableSynonymyList(taxon
)) {
122 if (taxonBase
instanceof Synonym
) {
123 FreeTextElementFactory
.getDefault().createSynonym(taxon
, (Synonym
) taxonBase
);
125 FreeTextElementFactory
.getDefault().createMisappliedName(taxon
, (Taxon
) taxonBase
);
129 Set
<TaxonRelationship
> taxonRelations
= taxon
.getTaxonRelations();
130 for (TaxonRelationship relationship
: taxonRelations
) {
132 if (relationship
.getType().equals(TaxonRelationshipType
.MISAPPLIED_NAME_FOR()) ||
133 relationship
.getType().equals(TaxonRelationshipType
.TAXONOMICALLY_INCLUDED_IN())) {
137 FreeTextElementFactory
.getDefault().createConcept(taxon
, relationship
);
140 // Listen for names being dragged outside of existing homotypic groups -
141 // user wants to create a new group
142 Transfer
[] types
= new Transfer
[] {WidgetTransfer
.getInstance()};
143 int operations
= DND
.DROP_MOVE
| DND
.DROP_COPY
| DND
.DROP_DEFAULT
;
144 DropTarget target
= new DropTarget(parent
, operations
);
145 target
.setTransfer(types
);
146 target
.addDropListener(new DropTargetAdapter() {
148 public void drop(DropTargetEvent event
) {
150 IUndoContext undoContext
= EditorController
.getUndoContext(getTaxon());
151 IUndoableOperation operation
= null;
153 // Synonym being dropped
154 if(event
.data
instanceof SynonymComposite
){
155 Synonym synonym
= ((SynonymComposite
)event
.data
).getSynonym();
156 operation
= new ChangeHomotypicGroupOperation
157 ("change type", undoContext
,
158 getTaxon(), synonym
, HomotypicalGroup
.NewInstance());
161 // Misapplied name being dropped
162 if(event
.data
instanceof MisappliedNameComposite
){
163 Taxon misapplication
= ((MisappliedNameComposite
)event
.data
).getMisappliedName();
164 operation
= new ChangeMisappliedNameToSynonymOperation
165 ("change misapplied name to synonym", undoContext
,
166 getTaxon(), misapplication
, HomotypicalGroup
.NewInstance());
169 // Execute operation if it's been init'ed
170 if (operation
== null) {
171 logger
.warn("User unsuccessfully tried to drop " + event
.data
.getClass());
173 GlobalController
.executeOperation(operation
);
178 // We've added elements to the managed form, so redraw it
179 scrolledForm
.reflow(true);
181 setSelection(acceptedNameComposite
);
182 acceptedNameComposite
.drawBorder();
185 public boolean redraw(){
187 managedForm
.getForm().dispose();
189 createManagedForm(partComposite
);
191 Taxon taxon
= getTaxon();
193 this.selectedObject
= null;
195 // Create accepted name
196 NameComposite acceptedNameComposite
= (NameComposite
) FreeTextElementFactory
.getDefault().
197 createAcceptedTaxon(managedForm
, taxon
);
199 for (TaxonBase taxonBase
: new IterableSynonymyList(taxon
)) {
200 if (taxonBase
instanceof Synonym
) {
201 FreeTextElementFactory
.getDefault().createSynonym(taxon
, (Synonym
) taxonBase
);
203 FreeTextElementFactory
.getDefault().createMisappliedName(taxon
, (Taxon
) taxonBase
);
207 Set
<TaxonRelationship
> taxonRelations
= taxon
.getTaxonRelations();
208 for (TaxonRelationship relationship
: taxonRelations
) {
210 if (relationship
.getType().equals(TaxonRelationshipType
.MISAPPLIED_NAME_FOR()) ||
211 relationship
.getType().equals(TaxonRelationshipType
.TAXONOMICALLY_INCLUDED_IN())) {
215 FreeTextElementFactory
.getDefault().createConcept(taxon
, relationship
);
218 acceptedNameComposite
.drawBorder();
220 partComposite
.layout();
228 private HashSet
<Composite
> getAllComposites(){
229 HashSet
<Composite
> composites
= new HashSet
<Composite
>();
230 composites
.add(parent
);
231 composites
.addAll(getComposites(parent
));
235 private HashSet
<Composite
> getComposites(Composite composite
){
236 HashSet
<Composite
> composites
= new HashSet
<Composite
>();
237 for(Control child
: composite
.getChildren()){
238 if(child
instanceof Composite
){
239 composites
.add((Composite
)child
);
240 composites
.addAll(getComposites((Composite
)child
));
248 public Composite
getAcceptedName() {
250 for(Composite c
: getAllComposites()){
251 if(c
instanceof AcceptedNameComposite
){
259 public Composite
getHomotypicGroup(HomotypicalGroup group
) {
260 for(Composite c
: getAllComposites()){
261 if(c
instanceof HomotypicalGroupComposite
){
263 ((HomotypicalGroupComposite
) c
).getGroup())) {
272 public Composite
getMisappliedGroup() {
273 for(Composite c
: getAllComposites()){
274 if(c
instanceof MisappliedGroupComposite
){
282 public Composite
getMisappliedName(Taxon misappliedName
) {
283 for(Composite c
: getAllComposites()){
284 if(c
instanceof MisappliedNameComposite
){
285 if (misappliedName
.equals(
286 ((MisappliedNameComposite
) c
).getMisappliedName())) {
295 public Composite
getSynonym(Synonym synonym
) {
296 for(Composite c
: getAllComposites()){
297 if(c
instanceof SynonymComposite
){
299 (((SynonymComposite
) c
).getSynonym())) {
308 public Composite
getConceptGroup() {
309 for(Composite c
: getAllComposites()){
310 if(c
instanceof ConceptGroupComposite
){
318 public Composite
getConcept(Taxon relatedConcept
) {
319 for(Composite c
: getAllComposites()){
320 if(c
instanceof ConceptComposite
){
321 if (relatedConcept
.equals
322 (((ConceptComposite
) c
).getRelatedTaxon())) {
330 private NameComposite
warnIfNameConflictWithParent(NameComposite nameComposite
) {
332 // TODO put this into annotations
334 String message
= null;
335 Taxon taxon
= getTaxon();
337 if (nameComposite
.getData() instanceof Taxon
) {
338 taxon
= (Taxon
) nameComposite
.getData();
339 Taxon parentTaxon
= taxon
.getTaxonomicParent();
341 if (parentTaxon
!= null && taxon
.getName() instanceof NonViralName
342 && parentTaxon
.getName() instanceof NonViralName
) {
343 NonViralName name
= (NonViralName
) taxon
.getName();
344 NonViralName parentName
= (NonViralName
) parentTaxon
.getName();
346 Rank rank
= name
.getRank();
348 if (rank
.equals(Rank
.SPECIES())) {
349 String genus
= name
.getGenusOrUninomial();
350 String parentGenus
= parentName
.getGenusOrUninomial();
352 // If either taxon has a problem, name fields will be null
353 if (genus
!= null && parentGenus
!= null) {
354 if (!parentGenus
.equals(genus
)) {
355 message
= "Warning: taxon's genus does not match parent taxon's genus.";
360 if (rank
.equals(Rank
.SUBSPECIES())) {
361 String specificEpithet
= name
.getSpecificEpithet();
362 String parentSpecificEpithet
= parentName
.getSpecificEpithet();
364 // If either taxon has a problem, name fields will be null
365 if (specificEpithet
!= null && parentSpecificEpithet
!= null) {
366 if (!parentSpecificEpithet
.equals(specificEpithet
)) {
367 message
= "Warning: taxon's specific epithet does not match parent taxon's specific epithet.";
376 if (message
!= null && nameComposite
.getTextViewer() != null) {
377 managedForm
.getMessageManager().addMessage
378 ("TEST2", message
, null, IMessageProvider
.WARNING
,
379 nameComposite
.getTextViewer().getTextWidget());
380 scrolledForm
.setMessage(null, 0, null);
382 return nameComposite
;