acf2931cad1bcd39e5fd8fdc92d2bb73eb4eff25
[taxeditor.git] / eclipseprojects / eu.etaxonomy.taxeditor / src / eu / etaxonomy / taxeditor / editor / name / TaxonNameEditor.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
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.
8 */
9
10 package eu.etaxonomy.taxeditor.editor.name;
11
12 import java.beans.PropertyChangeEvent;
13 import java.beans.PropertyChangeListener;
14 import java.util.HashSet;
15
16 import org.apache.log4j.Logger;
17 import org.eclipse.core.commands.ExecutionException;
18 import org.eclipse.core.commands.operations.IOperationHistory;
19 import org.eclipse.core.commands.operations.IUndoContext;
20 import org.eclipse.core.commands.operations.IUndoableOperation;
21 import org.eclipse.core.runtime.IProgressMonitor;
22 import org.eclipse.core.runtime.IStatus;
23 import org.eclipse.jface.dialogs.IMessageProvider;
24 import org.eclipse.swt.dnd.DND;
25 import org.eclipse.swt.dnd.DropTarget;
26 import org.eclipse.swt.dnd.DropTargetAdapter;
27 import org.eclipse.swt.dnd.DropTargetEvent;
28 import org.eclipse.swt.dnd.Transfer;
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;
34
35 import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
36 import eu.etaxonomy.cdm.model.name.NonViralName;
37 import eu.etaxonomy.cdm.model.name.Rank;
38 import eu.etaxonomy.cdm.model.taxon.Synonym;
39 import eu.etaxonomy.cdm.model.taxon.Taxon;
40 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
41 import eu.etaxonomy.taxeditor.ITaxEditorConstants;
42 import eu.etaxonomy.taxeditor.UiUtil;
43 import eu.etaxonomy.taxeditor.actions.WidgetTransfer;
44 import eu.etaxonomy.taxeditor.actions.ui.AdaptCompositeToGroupAction;
45 import eu.etaxonomy.taxeditor.editor.AbstractTaxonEditor;
46 import eu.etaxonomy.taxeditor.editor.EditorGroupComposite;
47 import eu.etaxonomy.taxeditor.editor.FreeTextElementFactory;
48 import eu.etaxonomy.taxeditor.editor.INameEditorCompositeRepository;
49 import eu.etaxonomy.taxeditor.operations.name.ChangeHomotypicGroupOperation;
50
51 /**
52 * @author p.ciardelli
53 * @created 15.05.2008
54 * @version 1.0
55 */
56 public class TaxonNameEditor extends AbstractTaxonEditor
57 implements INameEditorCompositeRepository{
58 private static final Logger logger = Logger.getLogger(TaxonNameEditor.class);
59
60 /**
61 * Shared listener that sets dirty state to true
62 * when any registered property changes
63 */
64 private PropertyChangeListener taxonChangeListener = new PropertyChangeListener() {
65 public void propertyChange(PropertyChangeEvent event) {
66 if (event.getPropertyName().equals(ITaxEditorConstants.PROPERTY_SHEET_CHANGE)) {
67 firePropertyChange(PROP_DIRTY);
68 }
69 }
70 };
71
72 @Override
73 public void doSave(IProgressMonitor monitor) {}
74
75 @Override
76 public void doSaveAs() {}
77
78 @Override
79 public void init(IEditorSite site, IEditorInput input)
80 throws PartInitException {
81
82 super.init(site, input);
83
84 Taxon taxon = getTaxon();
85
86 UiUtil.addTaxonNameEditor(taxon, this);
87
88 // Register listeners for any change in accepted name or set of relations
89 taxon.getName().addPropertyChangeListener(taxonChangeListener);
90 taxon.addPropertyChangeListener(taxonChangeListener);
91 }
92
93 @Override
94 public boolean isDirty() {
95 return false;
96 }
97
98 @Override
99 public boolean isSaveAsAllowed() {
100 return false;
101 }
102
103 @Override
104 public void createPartControl(final Composite composite) {
105
106 super.createPartControl(composite);
107
108 Taxon taxon = getTaxon();
109
110 NameComposite acceptedNameComposite =
111 (NameComposite) FreeTextElementFactory.getDefault().
112 createAcceptedTaxon(managedForm, taxon);
113
114 for (TaxonBase taxonBase : new IterableSynonymyList(taxon)) {
115 if (taxonBase instanceof Synonym) {
116 FreeTextElementFactory.getDefault().createSynonym((Synonym) taxonBase, taxon);
117 } else {
118 FreeTextElementFactory.getDefault().createMisappliedName((Taxon) taxonBase, taxon);
119 }
120 }
121
122 // // Create a homotypic group composite for the accepted taxon
123 // HomotypicalGroup homotypicGroup = taxon.getHomotypicGroup();
124 // EditorGroupComposite homotypicGroupComposite = new EditorGroupComposite(parent, managedForm, homotypicGroup);
125 // homotypicGroupComposite.setData(ITaxEditorConstants.TAXON, taxon);
126 //
127 // NameComposite nameCompositeWithWarning = null;
128 //
129 // // Add accepted taxon to the group
130 // NameComposite acceptedNameComposite = new NameComposite(homotypicGroupComposite, managedForm, NameComposite.ACCEPTED_TAXON, taxon);
131 //
132 // warnIfNameConflictWithParent(acceptedNameComposite);
133 //
134 // IterableSynonymyList synonymyList = new IterableSynonymyList(taxon);
135 // HomotypicalGroup lastHeterotypicGroup = null;
136 // HomotypicalGroup currentHeterotypicGroup = null;
137 // EditorGroupComposite heterotypicGroupComposite = null;
138 // EditorGroupComposite misappliedNameGroupComposite = null;
139 //
140 // for (TaxonBase synonymOrMisName : synonymyList) {
141 // if (synonymOrMisName instanceof Synonym) {
142 //
143 // Synonym synonym = (Synonym) synonymOrMisName;
144 // currentHeterotypicGroup = synonym.getHomotypicGroup();
145 //
146 // if (currentHeterotypicGroup.equals(homotypicGroup)) {
147 //
148 // NameComposite homotypicSynonymComposite = new NameComposite(homotypicGroupComposite, managedForm, NameComposite.HOMOTYPIC_SYNONYM, synonym);
149 //
150 // } else {
151 //
152 // if (!currentHeterotypicGroup.equals(lastHeterotypicGroup)) {
153 //
154 // // Create a new group composite
155 // heterotypicGroupComposite = new EditorGroupComposite(parent, managedForm, currentHeterotypicGroup);
156 // heterotypicGroupComposite.setData(ITaxEditorConstants.TAXON, taxon);
157 // lastHeterotypicGroup = currentHeterotypicGroup;
158 // }
159 //
160 // NameComposite heterotypicSynonymComposite = new NameComposite(heterotypicGroupComposite, managedForm, NameComposite.HETEROTYPIC_SYNONYM, synonym);
161 // }
162 // } else {
163 //
164 // Taxon misappliedName = (Taxon) synonymOrMisName;
165 // if (UiUtil.getMisappliedNameGroupComposite(managedForm) == null) {
166 // misappliedNameGroupComposite = UiUtil.createMisappliedNameGroupComposite(managedForm);
167 // }
168 // NameComposite misappliedNameComposite = new NameComposite(misappliedNameGroupComposite, managedForm, NameComposite.MISAPPLIED_NAME, misappliedName);
169 // }
170 // }
171
172 // Listen for names being dragged outside of existing homotypic groups -
173 // user wants to create a new group
174 Transfer[] types = new Transfer[] {WidgetTransfer.getInstance()};
175 int operations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT;
176 DropTarget target = new DropTarget(parent, operations);
177 target.setTransfer(types);
178 target.addDropListener(new DropTargetAdapter() {
179
180 public void drop(DropTargetEvent event) {
181
182 IOperationHistory operationHistory = UiUtil.getOperationHistory();
183
184 Synonym synonym = null;
185 if(event.data instanceof SynonymComposite){
186 synonym = ((SynonymComposite)event.data).getSynonym();
187 }
188
189 IUndoContext undoContext = UiUtil.getTaxonNameEditorUndoContext(getTaxon());
190 IUndoableOperation operation = new ChangeHomotypicGroupOperation
191 ("change type", undoContext,
192 getTaxon(), synonym, HomotypicalGroup.NewInstance());
193
194 try {
195 IStatus status = operationHistory.execute(operation, null, null);
196 } catch (ExecutionException e) {
197 // TODO Auto-generated catch block
198 e.printStackTrace();
199 }
200
201 }
202 });
203
204 // We've added elements to the managed form, so redraw it
205 scrolledForm.reflow(true);
206
207 setSelection(acceptedNameComposite);
208 acceptedNameComposite.drawBorder();
209 }
210
211
212
213 public boolean redraw(){
214
215 Taxon taxon = getTaxon();
216
217 for (Control child : parent.getChildren()){
218 child.dispose();
219 }
220
221 this.selectedObject = null;
222
223 NameComposite acceptedNameComposite =
224 (NameComposite) FreeTextElementFactory.getDefault().
225 createAcceptedTaxon(managedForm, taxon);
226
227 for (TaxonBase taxonBase : new IterableSynonymyList(taxon)) {
228 if (taxonBase instanceof Synonym) {
229 FreeTextElementFactory.getDefault().createSynonym((Synonym) taxonBase, taxon);
230 } else {
231 FreeTextElementFactory.getDefault().createMisappliedName((Taxon) taxonBase, taxon);
232 }
233 }
234
235 scrolledForm.reflow(true);
236
237 return true;
238 }
239
240 private NameComposite warnIfNameConflictWithParent(NameComposite nameComposite) {
241
242 String message = null;
243 Taxon taxon = getTaxon();
244
245 if (nameComposite.getData() instanceof Taxon) {
246 taxon = (Taxon) nameComposite.getData();
247 Taxon parentTaxon = taxon.getTaxonomicParent();
248
249 if (parentTaxon != null && taxon.getName() instanceof NonViralName
250 && parentTaxon.getName() instanceof NonViralName) {
251 NonViralName name = (NonViralName) taxon.getName();
252 NonViralName parentName = (NonViralName) parentTaxon.getName();
253
254 Rank rank = name.getRank();
255 if (rank != null) {
256 if (rank.equals(Rank.SPECIES())) {
257 String genus = name.getGenusOrUninomial();
258 String parentGenus = parentName.getGenusOrUninomial();
259
260 // If either taxon has a problem, name fields will be null
261 if (genus != null && parentGenus != null) {
262 if (!parentGenus.equals(genus)) {
263 message = "Warning: taxon's genus does not match parent taxon's genus.";
264 }
265 }
266 }
267
268 if (rank.equals(Rank.SUBSPECIES())) {
269 String specificEpithet = name.getSpecificEpithet();
270 String parentSpecificEpithet = parentName.getSpecificEpithet();
271
272 // If either taxon has a problem, name fields will be null
273 if (specificEpithet != null && parentSpecificEpithet != null) {
274 if (!parentSpecificEpithet.equals(specificEpithet)) {
275 message = "Warning: taxon's specific epithet does not match parent taxon's specific epithet.";
276 }
277 }
278 }
279 }
280
281 }
282 }
283
284 if (message != null && nameComposite.getTextViewer() != null) {
285 managedForm.getMessageManager().addMessage
286 ("TEST2", message, null, IMessageProvider.WARNING,
287 nameComposite.getTextViewer().getTextWidget());
288 scrolledForm.setMessage(null, 0, null);
289 }
290 return nameComposite;
291 }
292
293
294 private HashSet<Composite> getAllComposites(){
295 HashSet<Composite> composites = new HashSet<Composite>();
296 composites.add(parent);
297 composites.addAll(getComposites(parent));
298 return composites;
299 }
300
301 private HashSet<Composite> getComposites(Composite composite){
302 HashSet<Composite> composites = new HashSet<Composite>();
303 for(Control child : composite.getChildren()){
304 if(child instanceof Composite){
305 composites.add((Composite)child);
306 composites.addAll(getComposites((Composite)child));
307 }
308 }
309 return composites;
310 }
311
312
313 @Override
314 public Composite getAcceptedName() {
315
316 for(Composite c : getAllComposites()){
317 if(c instanceof AcceptedNameComposite){
318 return c;
319 }
320 }
321 return null;
322 }
323
324 @Override
325 public Composite getHomotypicGroup(HomotypicalGroup group) {
326 for(Composite c : getAllComposites()){
327 if(c instanceof HomotypicalGroupComposite){
328 if (group.equals(
329 ((HomotypicalGroupComposite) c).getGroup())) {
330 return c;
331 }
332 }
333 }
334 return null;
335 }
336
337 @Override
338 public Composite getMisappliedGroup() {
339 for(Composite c : getAllComposites()){
340 if(c instanceof MisappliedGroupComposite){
341 return c;
342 }
343 }
344 return null;
345 }
346
347 @Override
348 public Composite getMisappliedName(Taxon misappliedName) {
349 for(Composite c : getAllComposites()){
350 if(c instanceof MisappliedNameComposite){
351 if (misappliedName.equals(
352 ((MisappliedNameComposite) c).getMisappliedName())) {
353 return c;
354 }
355 }
356 }
357 return null;
358 }
359
360 @Override
361 public Composite getSynonym(Synonym synonym) {
362 for(Composite c : getAllComposites()){
363 if(c instanceof SynonymComposite){
364 if (synonym.equals
365 (((SynonymComposite) c).getSynonym())) {
366 return c;
367 }
368 }
369 }
370 return null;
371 }
372 }