Cleaned up / renamed.
[taxeditor.git] / eclipseprojects / eu.etaxonomy.taxeditor / src / eu / etaxonomy / taxeditor / view / NameEditorView.java
1 package eu.etaxonomy.taxeditor.view;
2
3 import java.beans.PropertyChangeEvent;
4 import java.beans.PropertyChangeListener;
5 import java.util.ArrayList;
6 import java.util.List;
7
8 import org.eclipse.core.databinding.beans.BeansObservables;
9 import org.eclipse.core.databinding.observable.set.ISetChangeListener;
10 import org.eclipse.core.databinding.observable.set.SetChangeEvent;
11 import org.eclipse.core.runtime.IProgressMonitor;
12 import org.eclipse.jface.text.source.SourceViewer;
13 import org.eclipse.swt.SWT;
14 import org.eclipse.swt.dnd.DND;
15 import org.eclipse.swt.dnd.DropTarget;
16 import org.eclipse.swt.dnd.DropTargetAdapter;
17 import org.eclipse.swt.dnd.DropTargetEvent;
18 import org.eclipse.swt.dnd.Transfer;
19 import org.eclipse.swt.events.FocusEvent;
20 import org.eclipse.swt.events.FocusListener;
21 import org.eclipse.swt.events.MouseEvent;
22 import org.eclipse.swt.events.MouseListener;
23 import org.eclipse.swt.events.SelectionAdapter;
24 import org.eclipse.swt.events.SelectionEvent;
25 import org.eclipse.swt.events.SelectionListener;
26 import org.eclipse.swt.graphics.Point;
27 import org.eclipse.swt.graphics.Rectangle;
28 import org.eclipse.swt.layout.FillLayout;
29 import org.eclipse.swt.layout.GridData;
30 import org.eclipse.swt.layout.GridLayout;
31 import org.eclipse.swt.widgets.Composite;
32 import org.eclipse.swt.widgets.CoolBar;
33 import org.eclipse.swt.widgets.CoolItem;
34 import org.eclipse.swt.widgets.Display;
35 import org.eclipse.swt.widgets.Event;
36 import org.eclipse.swt.widgets.Label;
37 import org.eclipse.swt.widgets.Link;
38 import org.eclipse.swt.widgets.Listener;
39 import org.eclipse.swt.widgets.Menu;
40 import org.eclipse.swt.widgets.MenuItem;
41 import org.eclipse.swt.widgets.ToolBar;
42 import org.eclipse.swt.widgets.ToolItem;
43 import org.eclipse.ui.IEditorInput;
44 import org.eclipse.ui.IEditorSite;
45 import org.eclipse.ui.PartInitException;
46 import org.eclipse.ui.part.EditorPart;
47
48 import com.swtdesigner.ResourceManager;
49 import com.swtdesigner.SWTResourceManager;
50
51 import eu.etaxonomy.cdm.model.name.BotanicalName;
52 import eu.etaxonomy.cdm.model.name.Rank;
53 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
54 import eu.etaxonomy.cdm.model.taxon.Synonym;
55 import eu.etaxonomy.cdm.model.taxon.Taxon;
56 import eu.etaxonomy.taxeditor.Activator;
57 import eu.etaxonomy.taxeditor.controller.ActionDeleteTaxon;
58 import eu.etaxonomy.taxeditor.controller.ActionOpenNameEditor;
59 import eu.etaxonomy.taxeditor.controller.ActionOpenNewChildNameEditor;
60 import eu.etaxonomy.taxeditor.controller.ActionSaveTaxon;
61 import eu.etaxonomy.taxeditor.controller.TaxonTransfer;
62 import eu.etaxonomy.taxeditor.model.PropertySheetNode;
63 import eu.etaxonomy.taxeditor.view.nameviewersupport.GroupComposite;
64 import eu.etaxonomy.taxeditor.view.nameviewersupport.NameComposite;
65 import eu.etaxonomy.taxeditor.view.nameviewersupport.TesterooWritableSet;
66 import eu.etaxonomy.taxeditor.view.propertysheetsupport.PropertySheetContentProvider;
67 import eu.etaxonomy.taxeditor.view.propertysheetsupport.PropertySheetValueEditingSupport;
68 import eu.etaxonomy.taxeditor.view.propertysheetsupport.PropertySheetValueLabelProvider;
69
70 /**
71 * TODO: user should always know what kind of name - BotanicalName,
72 * ZoologicalName, etc. - he will be editing when a new taxon
73 * is created
74 *
75 * @author p.ciardelli
76 *
77 */
78 public class NameEditorView extends EditorPart {
79 /**
80 * The taxon the editor is editing
81 */
82 private Taxon taxon;
83 /**
84 * The higher taxon of the taxon the editor is editing
85 */
86 private Taxon higherTaxon = null;
87 /**
88 * Shared listener that sets dirty state to true
89 * when any registered property changes
90 */
91 private PropertyChangeListener taxonChangeListener = new PropertyChangeListener() {
92 public void propertyChange(PropertyChangeEvent arg0) {
93 dirty = true;
94 firePropertyChange(PROP_DIRTY);
95 }
96 };
97 /**
98 * Arrays for the creation of synonyms - text and images
99 */
100 String [] relTypes = {"a synonym (type unknown)",
101 "a homotypic synonym",
102 "a heterotypic synoynm",
103 "a basionym",
104 "a replaced synonym",
105 "a homonym",
106 "an orthographic variant",
107 "a misapplied name",
108 "a concept relation"};
109 String [] relImgs = {"unknown_no_bg.gif",
110 "homosyn_no_bg.gif",
111 "heterosyn_no_bg.gif",
112 "basionym_no_bg.gif",
113 "repsyn_no_bg.gif",
114 "homonym_no_bg.gif",
115 "orthovariant_no_bg.gif",
116 "misapplied_no_bg.gif",
117 "concept_no_bg.gif"};
118 String [] conceptTypes = {"congruent","included in","includes","overlaps","excludes","doubtful"};
119 /**
120 * If true, show "save" prompt before closing editor
121 */
122 public boolean dirty = false;
123 String clickText;
124
125 private Composite nameComposite;
126 private Composite contentComposite;
127
128 private PropertySheetViewer propertySheetViewer;
129 private Composite parent;
130
131 public static final String ID = "eu.etaxonomy.taxeditor.view.nameeditorview"; //$NON-NLS-1$
132
133 public NameEditorView() {
134
135 }
136 /**
137 * Create contents of the editor part
138 * @param parent
139 */
140 @Override
141 public void createPartControl(Composite parent) {
142
143 this.parent = parent;
144 parent.setLayout(new GridLayout());
145 parent.setRedraw(true);
146
147
148 createHigherTaxon();
149
150
151 final CoolBar coolBar = new CoolBar(parent, SWT.NONE);
152 new CoolItem(coolBar, SWT.PUSH).setImage(ResourceManager.getPluginImage(Activator.getDefault(), "icons/save_edit.gif"));
153
154 final ToolBar toolBar = new ToolBar(parent, SWT.NONE);
155 // toolBar.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY));
156
157 final ToolItem itemSave = new ToolItem(toolBar, SWT.PUSH);
158 itemSave.setToolTipText("Save taxon");
159 itemSave.setImage(ResourceManager.getPluginImage(Activator.getDefault(), "icons/save_edit.gif"));
160 itemSave.addSelectionListener(new SelectionListener() {
161 public void widgetDefaultSelected(SelectionEvent e) {
162 dirty = false;
163 new ActionSaveTaxon(taxon).run();
164 }
165 public void widgetSelected(SelectionEvent e) {
166 dirty = false;
167 new ActionSaveTaxon(taxon).run();
168 }
169 });
170
171 final ToolItem itemMove = new ToolItem(toolBar, SWT.DROP_DOWN);
172 itemMove.setToolTipText("Move taxon");
173
174 final Menu menuMove = new Menu(toolBar);
175 addDropDown(itemMove, menuMove);
176
177 final MenuItem moveTaxonMenuItem = new MenuItem(menuMove, SWT.NONE);
178 moveTaxonMenuItem.setText("Move taxon to another higher taxon");
179 moveTaxonMenuItem.addSelectionListener(new SelectionAdapter() {
180 public void widgetSelected(final SelectionEvent e) {
181 new MoveDialogView(getSite().getShell());
182 MoveDialogView dialog = new MoveDialogView(getSite().getShell());
183 dialog.open(taxon);
184 }
185 });
186
187 final MenuItem taxonToSynonymMenuItem = new MenuItem(menuMove, SWT.NONE);
188 taxonToSynonymMenuItem.setSelection(true);
189 taxonToSynonymMenuItem.setText("Turn taxon's accepted name into a synonym");
190 taxonToSynonymMenuItem.addSelectionListener(new SelectionAdapter() {
191 public void widgetSelected(final SelectionEvent e) {
192 new MoveDialogView(getSite().getShell());
193 MoveDialogView dialog = new MoveDialogView(getSite().getShell());
194 dialog.open(taxon);
195 }
196 });
197
198 itemMove.setImage(ResourceManager.getPluginImage(Activator.getDefault(), "icons/correction_change.gif"));
199
200 final ToolItem itemDelete = new ToolItem(toolBar, SWT.NONE);
201 itemDelete.setToolTipText("Delete taxon");
202 itemDelete.setImage(ResourceManager.getPluginImage(Activator.getDefault(), "icons/delete_edit.gif"));
203 itemDelete.addSelectionListener(new SelectionListener() {
204
205 public void widgetDefaultSelected(SelectionEvent e) {
206 // TODO Auto-generated method stub
207
208 }
209 public void widgetSelected(SelectionEvent e) {
210 new ActionDeleteTaxon(taxon).run();
211 }
212 });
213
214 new ToolItem(toolBar, SWT.SEPARATOR);
215
216 final ToolItem itemAddRelationship = new ToolItem(toolBar, SWT.DROP_DOWN);
217 itemAddRelationship.setToolTipText("Add nom. or tax. relation to taxon");
218 itemAddRelationship.setImage(ResourceManager.getPluginImage(Activator.getDefault(), "icons/rel_no_bg.gif"));
219
220 /*
221 * Create menu to add relations to the taxon
222 */
223 final Menu menuAddRel = new Menu(toolBar);
224 addDropDown(itemAddRelationship, menuAddRel);
225
226 for (int i = 0; i < relTypes.length; i++) {
227 final MenuItem menuItem;
228 if (relTypes[i].contains("concept")) {
229 menuItem = new MenuItem(menuAddRel, SWT.CASCADE);
230
231 final Menu conceptMenu = new Menu(menuItem);
232 menuItem.setMenu(conceptMenu);
233
234 for (int j = 0; j < conceptTypes.length; j++) {
235 final MenuItem conceptMenuItem = new MenuItem(conceptMenu, SWT.CHECK);
236 conceptMenuItem.setText(conceptTypes[j]);
237 }
238 } else {
239 menuItem = new MenuItem(menuAddRel, SWT.NONE);
240 }
241
242 menuItem.setImage(ResourceManager.getPluginImage(Activator.getDefault(), "icons/" + relImgs[i]));
243 menuItem.setText("Add " + relTypes[i]);
244 }
245
246 new ToolItem(toolBar, SWT.SEPARATOR);
247
248 final ToolItem itemAddTaxon = new ToolItem(toolBar, SWT.DROP_DOWN);
249 itemAddTaxon.setImage(ResourceManager.getPluginImage(Activator.getDefault(), "icons/add_edit.gif"));
250 itemAddTaxon.setToolTipText("Add new taxon");
251
252 /*
253 * drop-down to add new "included in" taxon
254 */
255 final Menu menuAdd = new Menu(toolBar);
256 addDropDown(itemAddTaxon, menuAdd);
257
258 if (higherTaxon != null) {
259 final MenuItem addToHigherTaxonItem = new MenuItem(menuAdd, SWT.NONE);
260 addToHigherTaxonItem.setText("Add new taxon to \"" + higherTaxon.getName().getTitleCache() + "\"");
261 addToHigherTaxonItem.addSelectionListener(new SelectionListener() {
262 public void widgetDefaultSelected(SelectionEvent e) {
263 // TODO Auto-generated method stub
264
265 }
266 public void widgetSelected(SelectionEvent e) {
267 new ActionOpenNewChildNameEditor(higherTaxon).run();
268 }
269 });
270 }
271 final MenuItem addTaxonItem = new MenuItem(menuAdd, SWT.NONE);
272 addTaxonItem.setText("Add new taxon to this taxon");
273 addTaxonItem.addSelectionListener(new SelectionListener() {
274 public void widgetDefaultSelected(SelectionEvent e) {
275 // TODO Auto-generated method stub
276
277 }
278 public void widgetSelected(SelectionEvent e) {
279 new ActionOpenNewChildNameEditor(taxon).run();
280 }
281 });
282
283 contentComposite = new Composite(parent, SWT.NONE);
284 contentComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
285 contentComposite.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
286 final GridLayout gridLayout_2 = new GridLayout();
287 gridLayout_2.marginHeight = 0;
288 gridLayout_2.marginWidth = 0;
289 gridLayout_2.numColumns = 2;
290 contentComposite.setLayout(gridLayout_2);
291 contentComposite.setRedraw(true);
292
293
294 nameComposite = new Composite(contentComposite, SWT.NONE);
295 nameComposite.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
296 nameComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, true));
297 GridLayout gridLayout = new GridLayout();
298 gridLayout.verticalSpacing = 10;
299 nameComposite.setLayout(gridLayout);
300 nameComposite.setRedraw(true);
301
302
303 // clickText = "Click here to start entering accepted name or enter its individual fields in the property sheet to the right";
304 // NameViewer_ acceptedNameViewer = new AcceptedNameViewer(taxon, bindingContext, nameComposite);
305 // acceptedNameViewer.setBindingContext(bindingContext);
306 // acceptedNameViewer.configure(new NameViewerConfig());
307
308 GroupComposite homoGroupComposite = new GroupComposite(nameComposite);
309 homoGroupComposite.setTaxon(taxon);
310 homoGroupComposite.setNameEditorView(this);
311
312 new NameComposite(homoGroupComposite, taxon).setNameEditorView(this);
313
314 TesterooWritableSet.getInstance().addSetChangeListener
315 (new ISetChangeListener() {
316 public void handleSetChange(SetChangeEvent event) {
317 for ( Object addition: event.diff.getAdditions()) {
318 if (addition instanceof Synonym)
319 createHeterotypicalGroup((Synonym) addition);
320 }
321 nameComposite.layout();
322 contentComposite.layout();
323 }
324 });
325
326 // Listen for names being dragged outside of existing homotypic groups -
327 // user wants to create a new group
328 // Drop functionality
329 Transfer[] types = new Transfer[] {TaxonTransfer.getInstance()};
330 int operations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT;
331 DropTarget target = new DropTarget(nameComposite, operations);
332 target.setTransfer(types);
333 target.addDropListener(dropTargetAdapter);
334
335 /*
336 * construct PropertySheetViewer, with bindings to model layer
337 */
338 propertySheetViewer = new PropertySheetViewer(contentComposite);
339
340 propertySheetViewer.setContentProvider(
341 new PropertySheetContentProvider());
342 propertySheetViewer.getPropertyValueColumn().setLabelProvider(
343 new PropertySheetValueLabelProvider(propertySheetViewer));
344 propertySheetViewer.getPropertyValueColumn().setEditingSupport(
345 new PropertySheetValueEditingSupport(propertySheetViewer));
346
347 setPropertySheetNodes(taxon.getName());
348 }
349
350 /**
351 * Display hyperlinked higher taxon, if there is one
352 */
353 private void createHigherTaxon() {
354 Composite higherTaxonComposite = new Composite(parent, SWT.NONE);
355 higherTaxonComposite.setLayout(new FillLayout());
356 (new Label(higherTaxonComposite, SWT.NONE)).setText("Higher taxon: ");
357 if (higherTaxon == null)
358 (new Label(higherTaxonComposite, SWT.NONE)).setText("none");
359 else {
360 Link higherTaxonLink = new Link(higherTaxonComposite, SWT.NONE);
361 higherTaxonLink.setText("<a href=\"#\">" + higherTaxon.getName().getTitleCache() + "</a>");
362 higherTaxonLink.addMouseListener(new MouseListener() {
363 public void mouseDoubleClick(MouseEvent e) {
364 new ActionOpenNameEditor(higherTaxon).run();
365 }
366 public void mouseDown(MouseEvent e) {
367 new ActionOpenNameEditor(higherTaxon).run();
368 }
369 public void mouseUp(MouseEvent e) {
370 }
371 });
372 }
373 }
374 public void setPropertySheetNodes(TaxonNameBase taxonname) {
375 propertySheetViewer.setInput(getPropertySheetNodes(taxonname));
376 propertySheetViewer.setExpandedState(fullTitleNode, true);
377 }
378
379 private SourceViewer createAcceptedName_() {
380
381 // Method[] methods = BotanicalName.class.getMethods();
382 // for (int i = 0; i < methods.length; i++) {
383 // System.out.println("Annotations:");
384 // for (int j = 0; i < methods[j].getAnnotations().length; j++)
385 // System.out.println("\t" + methods[i].getAnnotations()[j]);
386 // System.out.println("Type: " + methods[i].getReturnType().toString());
387 // System.out.println("Name:" + methods[i].getName());
388 // System.out.println();
389 // }
390 // use annotations to find persistent methods
391
392
393 // PropertyDescriptor descriptor;
394 // try {
395 // descriptor = new PropertyDescriptor("genus", taxonname.getClass());
396 // try {
397 // System.out.println("Property desc. test in createAcceptedName: "
398 // + descriptor.getReadMethod().invoke(taxonname, null));
399 // } catch (IllegalArgumentException e) {
400 // // TODO Auto-generated catch block
401 // e.printStackTrace();
402 // } catch (IllegalAccessException e) {
403 // // TODO Auto-generated catch block
404 // e.printStackTrace();
405 // } catch (InvocationTargetException e) {
406 // // TODO Auto-generated catch block
407 // e.printStackTrace();
408 // }
409 // } catch (IntrospectionException e) {
410 // // TODO Auto-generated catch block
411 // e.printStackTrace();
412 // }
413
414 final SourceViewer sourceViewer = new SourceViewer(nameComposite, null, 0); // createSourceViewer(taxon.getName());
415
416 sourceViewer.getTextWidget().setLayoutData(
417 new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
418 sourceViewer.getTextWidget().setFont(
419 SWTResourceManager.getFont("Georgia", 12, SWT.NONE));
420
421 /*
422 * if this is a new name, show text prompt to start entering data
423 */
424 if (taxon.getName().getNameCache() == null) {
425 clickText = "Click here to start entering accepted name or enter individual fields in the property sheet to the right";
426
427 sourceViewer.getTextWidget().setText(clickText);
428 sourceViewer.getTextWidget().setFont(SWTResourceManager.getFont("Georgia", 12, SWT.ITALIC));
429 sourceViewer.getTextWidget().setForeground(SWTResourceManager.getColor(192, 192, 192));
430 sourceViewer.getTextWidget().addFocusListener(new FocusListener() {
431 public void focusGained(FocusEvent e) {
432 if (!dirty) {
433 sourceViewer.getTextWidget().setText("");
434 sourceViewer.getTextWidget().setFont(SWTResourceManager.getFont("Georgia", 12, SWT.NONE));
435 sourceViewer.getTextWidget().setForeground(SWTResourceManager.getColor(0, 0, 0));
436 // dirty = true;
437 // firePropertyChange(PROP_DIRTY);
438 }
439 }
440 public void focusLost(FocusEvent e) {
441 if (sourceViewer.getTextWidget().getText() == "") {
442 sourceViewer.getTextWidget().setForeground(SWTResourceManager.getColor(192, 192, 192));
443 sourceViewer.getTextWidget().setText(clickText);
444 sourceViewer.getTextWidget().setFont(SWTResourceManager.getFont("Georgia", 12, SWT.ITALIC));
445 dirty = false;
446 } else {
447 dirty = true;
448 }
449 }
450 });
451 }
452
453 return sourceViewer;
454 }
455
456
457
458 /**
459 * Creates the drop-down menu next to every synonym for changing relationship type
460 *
461 * @param label
462 * @param name
463 */
464 // private void createRelationMenu(Control control, BotanicalName name) {
465 private void createRelationMenu(final Label label) {
466
467 final Menu menu = new Menu(label);
468 label.setMenu(menu);
469
470 // context menu usually only shows up w/ right menu click -
471 // this listener lets the left click activate it as well
472 label.addMouseListener(new MouseListener() {
473 public void mouseDown(MouseEvent e) {
474 menu.setVisible(true);
475 }
476 public void mouseDoubleClick(MouseEvent e) { }
477 public void mouseUp(MouseEvent e) { }
478 });
479
480 createRelationMenuItem(menu, "delete_edit.gif", "Delete synonym from this taxon");
481 createRelationMenuItem(menu, "correction_change.gif", "Move synonym to another taxon");
482
483 new MenuItem(menu, SWT.SEPARATOR);
484
485 for (int i= 0; i < relTypes.length; i++) {
486 final String relImg = relImgs[i];
487 String relText = "Turn this synonym into " + relTypes[i];
488 createRelationMenuItem(menu, relImg, relText).addSelectionListener(new SelectionListener() {
489 public void widgetDefaultSelected(SelectionEvent e) {
490 }
491 public void widgetSelected(SelectionEvent e) {
492 label.setImage(ResourceManager.getPluginImage(Activator.getDefault(), "icons/" + relImg));
493 }
494 });
495 }
496 }
497
498 private MenuItem createRelationMenuItem(Menu menu, String img, String text) {
499 final MenuItem menuItem = new MenuItem(menu, SWT.NONE);
500 menuItem.setImage(ResourceManager.getPluginImage(Activator.getDefault(), "icons/" + img));
501 menuItem.setText(text);
502 return menuItem;
503 }
504
505 @Override
506 public void setFocus() {
507 // Set the focus
508 }
509
510 @Override
511 public void doSave(IProgressMonitor monitor) {
512 // Do the Save operation
513 }
514
515 @Override
516 public void doSaveAs() {
517 // Do the Save As operation
518 }
519
520 @Override
521 public void init(IEditorSite site, IEditorInput input) throws PartInitException {
522
523 if (!(input instanceof IEditorInput))
524 throw new PartInitException(
525 "Invalid Input: Must be IFileEditorInput");
526
527 if (input.getAdapter(Taxon.class) != null) {
528 taxon = (Taxon) input.getAdapter(Taxon.class);
529 } else {
530
531 taxon = null;
532 }
533
534 // Get parent taxon
535 if (taxon.getTaxonomicParent() != null)
536 higherTaxon = taxon.getTaxonomicParent();
537
538 // Register listeners for any change in accepted name or set of relations
539 taxon.getName().addPropertyChangeListener("titleCache", taxonChangeListener);
540 taxon.addPropertyChangeListener("synonyms", taxonChangeListener);
541
542 setSite(site);
543 setInput(input);
544
545 }
546
547 PropertySheetNode fullTitleNode;
548 /**
549 * @param taxonName
550 * @return
551 */
552 private List<PropertySheetNode> getPropertySheetNodes(TaxonNameBase taxonName) {
553
554 BotanicalName botName = (BotanicalName) taxonName;
555
556 List<PropertySheetNode> propertySheetNodes = new ArrayList<PropertySheetNode>();
557 fullTitleNode = new PropertySheetNode("Full Title", BeansObservables.observeValue(botName, "titleCache"),
558 null, PropertySheetNode.EDITABLE);
559 propertySheetNodes.add(fullTitleNode);
560
561 // Note: only top-level nodes are "add"-ed - otherwise, they are
562 // instantiated with their parent node
563 if (botName.getRank() == null) botName.setRank(Rank.GENUS());
564 new PropertySheetNode("Rank", botName.getRank().getLabel(),
565 fullTitleNode, PropertySheetNode.NOT_EDITABLE);
566 new PropertySheetNode("Genus", BeansObservables.observeValue(botName, "uninomial"),
567 fullTitleNode, PropertySheetNode.EDITABLE);
568 new PropertySheetNode("Species Epithet", BeansObservables.observeValue(botName, "specificEpithet"),
569 fullTitleNode, PropertySheetNode.EDITABLE);
570
571 String author =
572 botName.getCombinationAuthorTeam() == null ? "" :
573 botName.getCombinationAuthorTeam().getTitleCache();
574 new PropertySheetNode("Author", author,
575 fullTitleNode, PropertySheetNode.NOT_EDITABLE);
576
577 return propertySheetNodes;
578 }
579
580 @Override
581 public boolean isDirty() {
582 return dirty;
583 }
584
585 @Override
586 public boolean isSaveAsAllowed() {
587 return false;
588 }
589
590 private static void addDropDown(final ToolItem item, final Menu menu) {
591 item.addListener(SWT.Selection, new Listener() {
592 public void handleEvent(Event event) {
593 if (event.detail == SWT.ARROW) {
594 Rectangle rect = item.getBounds();
595 Point pt = new Point(rect.x, rect.y + rect.height);
596 pt = item.getParent().toDisplay(pt);
597 menu.setLocation(pt.x, pt.y);
598 menu.setVisible(true);
599 }
600 }
601 });
602 }
603
604 private void createHeterotypicalGroup(Synonym heterosyn) {
605
606 GroupComposite heteroGroupComposite = new GroupComposite(nameComposite);
607 heteroGroupComposite.setTaxon(taxon);
608 heteroGroupComposite.setNameEditorView(this);
609
610 NameComposite nameComposite = new NameComposite(heteroGroupComposite, heterosyn, taxon);
611 nameComposite.setNameEditorView(this);
612 nameComposite.setFocus();
613 }
614
615 /**
616 * Creates a new homotypic group when a name composite is dropped outside of all existing
617 * homotypic groups
618 */
619 DropTargetAdapter dropTargetAdapter = new DropTargetAdapter() {
620
621 public void drop(DropTargetEvent event) {
622
623 Synonym synonym = (Synonym) event.data;
624
625 GroupComposite homotypicGroupComposite = new GroupComposite(nameComposite);
626 homotypicGroupComposite.setTaxon(taxon);
627 homotypicGroupComposite.setNameEditorView(NameEditorView.this);
628
629 new NameComposite(homotypicGroupComposite, synonym, taxon).setFocus();
630
631 NameEditorView.this.contentComposite.layout();
632 }
633 };
634 }