About to redo createPartControl() and createManagedForm(). Checking in in case rollba...
[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 import java.util.Set;
16
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;
34
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;
53
54 /**
55 * @author p.ciardelli
56 * @created 15.05.2008
57 * @version 1.0
58 */
59 public class TaxonNameEditor extends AbstractTaxonEditor
60 implements INameEditorCompositeRepository{
61 private static final Logger logger = Logger.getLogger(TaxonNameEditor.class);
62
63 /**
64 * Shared listener that sets dirty state to true
65 * when any registered property changes
66 */
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);
71 }
72 }
73 };
74
75 private Composite partComposite;
76
77 @Override
78 public void doSave(IProgressMonitor monitor) {}
79
80 @Override
81 public void doSaveAs() {}
82
83 @Override
84 public void init(IEditorSite site, IEditorInput input)
85 throws PartInitException {
86
87 super.init(site, input);
88
89 Taxon taxon = getTaxon();
90
91 EditorController.addEditor(taxon, this);
92
93 // Register listeners for any change in accepted name or set of relations
94 taxon.getName().addPropertyChangeListener(taxonChangeListener);
95 taxon.addPropertyChangeListener(taxonChangeListener);
96 }
97
98 @Override
99 public boolean isDirty() {
100 return false;
101 }
102
103 @Override
104 public boolean isSaveAsAllowed() {
105 return false;
106 }
107
108 @Override
109 public void createPartControl(final Composite composite) {
110
111 this.partComposite = composite;
112
113 super.createPartControl(composite);
114
115 Taxon taxon = getTaxon();
116
117 NameComposite acceptedNameComposite =
118 (NameComposite) FreeTextElementFactory.getDefault().
119 createAcceptedTaxon(managedForm, taxon);
120
121 for (TaxonBase taxonBase : new IterableSynonymyList(taxon)) {
122 if (taxonBase instanceof Synonym) {
123 FreeTextElementFactory.getDefault().createSynonym(taxon, (Synonym) taxonBase);
124 } else {
125 FreeTextElementFactory.getDefault().createMisappliedName(taxon, (Taxon) taxonBase);
126 }
127 }
128
129 Set<TaxonRelationship> taxonRelations = taxon.getTaxonRelations();
130 for (TaxonRelationship relationship : taxonRelations) {
131
132 if (relationship.getType().equals(TaxonRelationshipType.MISAPPLIED_NAME_FOR()) ||
133 relationship.getType().equals(TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN())) {
134 continue;
135 }
136
137 FreeTextElementFactory.getDefault().createConcept(taxon, relationship);
138 }
139
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() {
147
148 public void drop(DropTargetEvent event) {
149
150 IUndoContext undoContext = EditorController.getUndoContext(getTaxon());
151 IUndoableOperation operation = null;
152
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());
159 }
160
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());
167 }
168
169 // Execute operation if it's been init'ed
170 if (operation == null) {
171 logger.warn("User unsuccessfully tried to drop " + event.data.getClass());
172 } else {
173 GlobalController.executeOperation(operation);
174 }
175 }
176 });
177
178 // We've added elements to the managed form, so redraw it
179 scrolledForm.reflow(true);
180
181 setSelection(acceptedNameComposite);
182 acceptedNameComposite.drawBorder();
183 }
184
185 public boolean redraw(){
186
187 managedForm.getForm().dispose();
188
189 createManagedForm(partComposite);
190
191 Taxon taxon = getTaxon();
192
193 this.selectedObject = null;
194
195 // Create accepted name
196 NameComposite acceptedNameComposite = (NameComposite) FreeTextElementFactory.getDefault().
197 createAcceptedTaxon(managedForm, taxon);
198
199 for (TaxonBase taxonBase : new IterableSynonymyList(taxon)) {
200 if (taxonBase instanceof Synonym) {
201 FreeTextElementFactory.getDefault().createSynonym(taxon, (Synonym) taxonBase);
202 } else {
203 FreeTextElementFactory.getDefault().createMisappliedName(taxon, (Taxon) taxonBase);
204 }
205 }
206
207 Set<TaxonRelationship> taxonRelations = taxon.getTaxonRelations();
208 for (TaxonRelationship relationship : taxonRelations) {
209
210 if (relationship.getType().equals(TaxonRelationshipType.MISAPPLIED_NAME_FOR()) ||
211 relationship.getType().equals(TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN())) {
212 continue;
213 }
214
215 FreeTextElementFactory.getDefault().createConcept(taxon, relationship);
216 }
217
218 acceptedNameComposite.drawBorder();
219
220 partComposite.layout();
221
222 return true;
223 }
224
225
226
227
228 private HashSet<Composite> getAllComposites(){
229 HashSet<Composite> composites = new HashSet<Composite>();
230 composites.add(parent);
231 composites.addAll(getComposites(parent));
232 return composites;
233 }
234
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));
241 }
242 }
243 return composites;
244 }
245
246
247 @Override
248 public Composite getAcceptedName() {
249
250 for(Composite c : getAllComposites()){
251 if(c instanceof AcceptedNameComposite){
252 return c;
253 }
254 }
255 return null;
256 }
257
258 @Override
259 public Composite getHomotypicGroup(HomotypicalGroup group) {
260 for(Composite c : getAllComposites()){
261 if(c instanceof HomotypicalGroupComposite){
262 if (group.equals(
263 ((HomotypicalGroupComposite) c).getGroup())) {
264 return c;
265 }
266 }
267 }
268 return null;
269 }
270
271 @Override
272 public Composite getMisappliedGroup() {
273 for(Composite c : getAllComposites()){
274 if(c instanceof MisappliedGroupComposite){
275 return c;
276 }
277 }
278 return null;
279 }
280
281 @Override
282 public Composite getMisappliedName(Taxon misappliedName) {
283 for(Composite c : getAllComposites()){
284 if(c instanceof MisappliedNameComposite){
285 if (misappliedName.equals(
286 ((MisappliedNameComposite) c).getMisappliedName())) {
287 return c;
288 }
289 }
290 }
291 return null;
292 }
293
294 @Override
295 public Composite getSynonym(Synonym synonym) {
296 for(Composite c : getAllComposites()){
297 if(c instanceof SynonymComposite){
298 if (synonym.equals
299 (((SynonymComposite) c).getSynonym())) {
300 return c;
301 }
302 }
303 }
304 return null;
305 }
306
307 @Override
308 public Composite getConceptGroup() {
309 for(Composite c : getAllComposites()){
310 if(c instanceof ConceptGroupComposite){
311 return c;
312 }
313 }
314 return null;
315 }
316
317 @Override
318 public Composite getConcept(Taxon relatedConcept) {
319 for(Composite c : getAllComposites()){
320 if(c instanceof ConceptComposite){
321 if (relatedConcept.equals
322 (((ConceptComposite) c).getRelatedTaxon())) {
323 return c;
324 }
325 }
326 }
327 return null;
328 }
329
330 private NameComposite warnIfNameConflictWithParent(NameComposite nameComposite) {
331
332 // TODO put this into annotations
333
334 String message = null;
335 Taxon taxon = getTaxon();
336
337 if (nameComposite.getData() instanceof Taxon) {
338 taxon = (Taxon) nameComposite.getData();
339 Taxon parentTaxon = taxon.getTaxonomicParent();
340
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();
345
346 Rank rank = name.getRank();
347 if (rank != null) {
348 if (rank.equals(Rank.SPECIES())) {
349 String genus = name.getGenusOrUninomial();
350 String parentGenus = parentName.getGenusOrUninomial();
351
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.";
356 }
357 }
358 }
359
360 if (rank.equals(Rank.SUBSPECIES())) {
361 String specificEpithet = name.getSpecificEpithet();
362 String parentSpecificEpithet = parentName.getSpecificEpithet();
363
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.";
368 }
369 }
370 }
371 }
372
373 }
374 }
375
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);
381 }
382 return nameComposite;
383 }
384 }