automated build configuration is on its way
[taxeditor.git] / taxeditor-editor / src / main / java / 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.util.ArrayList;
13 import java.util.HashSet;
14 import java.util.List;
15 import java.util.Set;
16
17 import org.apache.commons.lang.StringUtils;
18 import org.eclipse.core.commands.operations.IUndoContext;
19 import org.eclipse.core.runtime.IAdaptable;
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.eclipse.core.runtime.OperationCanceledException;
22 import org.eclipse.jface.action.MenuManager;
23 import org.eclipse.jface.viewers.ISelection;
24 import org.eclipse.jface.viewers.ISelectionProvider;
25 import org.eclipse.jface.viewers.StructuredSelection;
26 import org.eclipse.swt.dnd.DND;
27 import org.eclipse.swt.dnd.DropTarget;
28 import org.eclipse.swt.dnd.Transfer;
29 import org.eclipse.swt.widgets.Composite;
30 import org.eclipse.swt.widgets.Menu;
31 import org.eclipse.ui.IEditorInput;
32 import org.eclipse.ui.IEditorSite;
33 import org.eclipse.ui.ISelectionListener;
34 import org.eclipse.ui.ISelectionService;
35 import org.eclipse.ui.IWorkbenchPart;
36 import org.eclipse.ui.IWorkbenchPartReference;
37 import org.eclipse.ui.PartInitException;
38 import org.eclipse.ui.forms.ManagedForm;
39 import org.eclipse.ui.forms.widgets.FormToolkit;
40 import org.eclipse.ui.forms.widgets.ScrolledForm;
41 import org.eclipse.ui.forms.widgets.TableWrapLayout;
42 import org.eclipse.ui.part.EditorPart;
43
44 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
45 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
46 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
47 import eu.etaxonomy.cdm.model.common.CdmBase;
48 import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
49 import eu.etaxonomy.cdm.model.taxon.Taxon;
50 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
51 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
52 import eu.etaxonomy.taxeditor.editor.CdmDataTransfer;
53 import eu.etaxonomy.taxeditor.editor.EditorUtil;
54 import eu.etaxonomy.taxeditor.editor.IDropTargetable;
55 import eu.etaxonomy.taxeditor.editor.IMultiPageTaxonEditorPage;
56 import eu.etaxonomy.taxeditor.editor.MultiPageTaxonEditor;
57 import eu.etaxonomy.taxeditor.editor.SimpleSelectionProvider;
58 import eu.etaxonomy.taxeditor.editor.TaxonEditorInput;
59 import eu.etaxonomy.taxeditor.editor.name.container.AbstractGroup;
60 import eu.etaxonomy.taxeditor.editor.name.container.AbstractGroupedContainer;
61 import eu.etaxonomy.taxeditor.editor.name.container.AcceptedGroup;
62 import eu.etaxonomy.taxeditor.editor.name.container.AcceptedNameContainer;
63 import eu.etaxonomy.taxeditor.editor.name.container.ConceptGroup;
64 import eu.etaxonomy.taxeditor.editor.name.container.ContainerFactory;
65 import eu.etaxonomy.taxeditor.editor.name.container.HomotypicalSynonymGroup;
66 import eu.etaxonomy.taxeditor.editor.name.container.MisappliedGroup;
67 import eu.etaxonomy.taxeditor.editor.name.dnd.NameEditorDropTargetListener;
68 import eu.etaxonomy.taxeditor.model.IPartChangeListener;
69 import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
70 import eu.etaxonomy.taxeditor.model.TaxeditorPartService;
71 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
72 import eu.etaxonomy.taxeditor.preference.Resources;
73
74 /**
75 * <p>TaxonNameEditor class.</p>
76 *
77 * @author p.ciardelli
78 * @author n.hoffmann
79 * @created 15.05.2008
80 * @version 1.0
81 */
82 public class TaxonNameEditor extends EditorPart implements IMultiPageTaxonEditorPage, IAdaptable, IConversationEnabled, IPostOperationEnabled, IPartContentHasDetails, IPartChangeListener
83 , ISelectionListener, IDropTargetable {
84
85 /** Constant <code>ID="eu.etaxonomy.taxeditor.editor.taxon.name"</code> */
86 public static final String ID = "eu.etaxonomy.taxeditor.editor.taxon.name";
87
88 private Taxon taxon;
89
90 private ManagedForm managedForm;
91 private ScrolledForm scrolledForm;
92 private Composite parent;
93 private ISelectionProvider provider;
94
95 private MultiPageTaxonEditor editor;
96
97 private TaxonBase selection;
98
99 private ConversationHolder conversation;
100
101 private MenuManager menuManager;
102
103 private Menu menu;
104
105 private MisappliedGroup misappliedGroup;
106
107 private ConceptGroup conceptGroup;
108
109 private List<HomotypicalSynonymGroup> heterotypicSynonymGroups = new ArrayList<HomotypicalSynonymGroup>();
110
111 private DropTarget target;
112
113 private ISelectionService selectionService;
114
115 private AcceptedGroup acceptedGroup;
116
117 private TaxonBase objectAffectedByLastOperation;
118
119 /**
120 * <p>Constructor for TaxonNameEditor.</p>
121 *
122 * @param editor a {@link eu.etaxonomy.taxeditor.editor.MultiPageTaxonEditor} object.
123 */
124 public TaxonNameEditor(MultiPageTaxonEditor editor){
125 this.editor = editor;
126 conversation = editor.getConversationHolder();
127 }
128
129
130
131 /**
132 * <p>getUndoContext</p>
133 *
134 * @return a {@link org.eclipse.core.commands.operations.IUndoContext} object.
135 */
136 public IUndoContext getUndoContext() {
137 return editor.getUndoContext();
138 }
139
140 /* (non-Javadoc)
141 * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
142 */
143 /** {@inheritDoc} */
144 public void createPartControl(Composite composite) {
145 selectionService = getSite().getWorkbenchWindow().getSelectionService();
146 selectionService.addSelectionListener(this);
147
148 createManagedForm(composite);
149
150 TaxeditorPartService.getInstance().addListener(TaxeditorPartService.PART_ACTIVATED, this);
151 }
152
153 /**
154 * <p>createManagedForm</p>
155 *
156 * @param composite a {@link org.eclipse.swt.widgets.Composite} object.
157 */
158 protected void createManagedForm(Composite composite) {
159
160 managedForm = new ManagedForm(composite) {
161
162 public void dirtyStateChanged() {
163 firePropertyChange(PROP_DIRTY);
164 }
165 public boolean setInput(Object input) {
166 if (input instanceof AbstractGroupedContainer) {
167 selection = ((AbstractGroupedContainer) input).getData();
168 provider.setSelection(new StructuredSelection(selection));
169 }
170 return super.setInput(input);
171 }
172 };
173
174
175 scrolledForm = managedForm.getForm();
176 parent = scrolledForm.getBody();
177
178 // register the context menu
179 menuManager = new MenuManager();
180 ISelectionProvider selectionProvider = getSite().getSelectionProvider();
181 getSite().registerContextMenu(TaxonNameEditor.ID, menuManager, selectionProvider);
182
183 parent.setData(taxon);
184
185 TableWrapLayout layout = new TableWrapLayout();
186 layout.leftMargin = 0;
187 layout.rightMargin = 0;
188 layout.topMargin = 0;
189 layout.bottomMargin = 0;
190
191 layout.verticalSpacing = 0;
192 layout.horizontalSpacing = 0;
193
194 parent.setLayout(layout);
195 parent.setBackground(EditorUtil.getColor(Resources.COLOR_COMPOSITE_BACKGROUND));
196
197 createOrUpdateNameComposites();
198
199 createDragSupport();
200
201 setFocus();
202 }
203
204 /**
205 * <p>createNameComposites</p>
206 */
207 public void createOrUpdateNameComposites(){
208
209 ContainerFactory.createOrUpdateAcceptedTaxonsHomotypicGroup(this);
210 ContainerFactory.createOrUpdateHeterotypicSynonymyGroups(this);
211 ContainerFactory.createOrUpdateMisapplicationsGroup(this);
212 ContainerFactory.createOrUpdateConceptGroup(this);
213
214 // Redraw composite
215 managedForm.reflow(true);
216 }
217
218
219
220
221 /**
222 * <p>Getter for the field <code>taxon</code>.</p>
223 *
224 * @return a {@link eu.etaxonomy.cdm.model.taxon.Taxon} object.
225 */
226 public Taxon getTaxon() {
227 return (Taxon) HibernateProxyHelper.deproxy(taxon);
228 }
229
230 /**
231 * <p>setDirty</p>
232 */
233 public void setDirty() {
234 managedForm.dirtyStateChanged();
235 }
236
237
238 /*
239 * (non-Javadoc)
240 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
241 */
242 /** {@inheritDoc} */
243 @Override
244 public void setFocus(){
245 if(getSelectedContainer() == null){
246 throw new IllegalStateException("There should always be a selected object.");
247 }
248 getSelectedContainer().setSelected();
249 }
250
251 /** {@inheritDoc} */
252 public void setInput(IEditorInput input){
253 this.setInputWithNotify(input);
254 }
255
256 /*
257 * (non-Javadoc)
258 * @see eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder()
259 */
260 /**
261 * <p>getConversationHolder</p>
262 *
263 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
264 */
265 public ConversationHolder getConversationHolder(){
266 return conversation;
267 }
268
269 /*
270 * (non-Javadoc)
271 * @see eu.etaxonomy.cdm.persistence.hibernate.ICdmPostCrudObserver#update(eu.etaxonomy.cdm.persistence.hibernate.CdmCrudEvent)
272 */
273 /** {@inheritDoc} */
274 public void update(CdmDataChangeMap events) {
275 //redraw();
276 }
277
278 /**
279 * Redraws this editor
280 * return true on success
281 *
282 * @return a boolean.
283 */
284 public boolean redraw(){
285 return redraw(true);
286 }
287
288 /**
289 * {@inheritDoc}
290 *
291 * Redraws the editor controls
292 */
293 public boolean redraw(boolean focus) {
294
295 createOrUpdateNameComposites();
296
297 if(focus){
298 setFocus();
299 }
300
301 return true;
302 }
303
304
305 /**
306 * <p>getMultiPageTaxonEditor</p>
307 *
308 * @return a {@link eu.etaxonomy.taxeditor.editor.MultiPageTaxonEditor} object.
309 */
310 public MultiPageTaxonEditor getMultiPageTaxonEditor() {
311 return editor;
312 }
313
314
315 /*
316 * (non-Javadoc)
317 * @see eu.etaxonomy.taxeditor.store.operations.IPostOperationEnabled#postOperation()
318 */
319 /** {@inheritDoc} */
320 public boolean postOperation(CdmBase objectAffectedByOperation) {
321
322 editor.changed(objectAffectedByOperation);
323
324 redraw(false);
325
326 if(objectAffectedByOperation instanceof TaxonBase){
327 objectAffectedByLastOperation = (TaxonBase) objectAffectedByOperation;
328 }
329
330 return true;
331 }
332
333 /**
334 * <p>Getter for the field <code>managedForm</code>.</p>
335 *
336 * @return the managedForm
337 */
338 public ManagedForm getManagedForm() {
339 return managedForm;
340 }
341
342 /**
343 * <p>getControl</p>
344 *
345 * @return a {@link org.eclipse.swt.widgets.Composite} object.
346 */
347 public Composite getControl() {
348 return this.getManagedForm().getForm().getBody();
349 }
350
351
352 /**
353 * <p>Getter for the field <code>menu</code>.</p>
354 *
355 * @return the menu
356 */
357 public Menu getMenu() {
358 if(menu == null || menu.isDisposed()){
359 // Creating the menu because it was either not initialised or disposed while refreshing the editor
360 menu = menuManager.createContextMenu(parent);
361 }
362 return menu;
363 }
364
365 /**
366 * <p>checkForEmptyNames</p>
367 *
368 * @return true if there are empty names
369 */
370 public boolean checkForEmptyNames() {
371 for(AbstractGroupedContainer container : getGroupedContainers()){
372 if(container.getName() == null || StringUtils.isEmpty(container.getName().getTitleCache())){
373 return true;
374 }
375 }
376 return false;
377 }
378
379
380 public Set<AbstractGroupedContainer> getEmptyContainers(){
381 Set<AbstractGroupedContainer> containersWithEmptyNames = new HashSet<AbstractGroupedContainer>();
382
383 for(AbstractGroupedContainer container : getGroupedContainers()){
384 if(container.getName() == null || StringUtils.isEmpty(container.getName().getTitleCache())){
385 containersWithEmptyNames.add(container);
386 }
387 }
388
389 return containersWithEmptyNames;
390 }
391
392 /** {@inheritDoc} */
393 @Override
394 public void doSave(IProgressMonitor monitor) {
395
396 monitor.beginTask("Saving names", getGroupedContainers().size());
397
398 try {
399 // check for empty names
400 for(AbstractGroupedContainer container : getGroupedContainers()){
401
402 monitor.subTask("Saving composite: " + container.getTaxonBase().getTitleCache());
403 container.persistName();
404
405 // In case the progress monitor was canceled throw an exception.
406 if (monitor.isCanceled()) {
407 throw new OperationCanceledException();
408 }
409
410 // Otherwise declare this step as done.
411 monitor.worked(1);
412 }
413 }
414 finally {
415
416 // Stop the progress monitor.
417 monitor.done();
418 }
419
420 }
421
422 /** {@inheritDoc} */
423 @Override
424 public void doSaveAs() {}
425
426 /** {@inheritDoc} */
427 @Override
428 public void init(IEditorSite site, IEditorInput input)
429 throws PartInitException {
430
431 if (!(input instanceof IEditorInput))
432 throw new PartInitException(
433 "Invalid Input: Must be IEditorInput");
434
435 if (input.getAdapter(Taxon.class) != null) {
436 taxon = (Taxon) input.getAdapter(Taxon.class);
437 } else {
438 throw new PartInitException(
439 "Invalid Input: Taxon cannot be null");
440 }
441
442 setSite(site);
443 setInput(input);
444
445 provider = new SimpleSelectionProvider();
446 getSite().setSelectionProvider(provider);
447 }
448
449 /**
450 *
451 */
452 private void createDragSupport() {
453 // Listen for names being dragged outside of existing homotypic groups -
454 // user wants to create a new group
455 Transfer[] types = new Transfer[] {CdmDataTransfer.getInstance()};
456 int operations = DND.DROP_MOVE;
457 if(target == null){
458 target = new DropTarget(parent, operations);
459 target.setTransfer(types);
460 target.addDropListener(new NameEditorDropTargetListener(this));
461 }
462 }
463
464 /**
465 * <p>Getter for the field <code>acceptedNameContainer</code>.</p>
466 *
467 * @return a {@link eu.etaxonomy.taxeditor.editor.name.container.AcceptedNameContainer} object.
468 */
469 public AcceptedNameContainer getAcceptedNameContainer() {
470 return getAcceptedGroup().getAcceptedNameContainer();
471 }
472
473 /**
474 * <p>getSynonymGroup</p>
475 *
476 * @param homotypicalGroup a {@link eu.etaxonomy.cdm.model.name.HomotypicalGroup} object.
477 * @return a {@link eu.etaxonomy.taxeditor.editor.name.container.HomotypicalSynonymGroup} object.
478 */
479 public HomotypicalSynonymGroup getHomotypicalGroupContainer(HomotypicalGroup homotypicalGroup) {
480 for(HomotypicalSynonymGroup group : getHeterotypicSynonymGroups()){
481 if(group.getGroup().equals(homotypicalGroup)){
482 return group;
483 }
484 }
485
486 return null;
487 }
488
489 /**
490 * <p>Getter for the field <code>conceptGroup</code>.</p>
491 *
492 * @return a {@link eu.etaxonomy.taxeditor.editor.name.container.ConceptGroup} object.
493 */
494 public ConceptGroup getConceptGroup() {
495 return conceptGroup;
496 }
497
498 /**
499 * <p>getDirtyNames</p>
500 *
501 * @return a Set containing all composites that have been edited
502 */
503 public Set<AbstractGroupedContainer> getDirtyNames(){
504 Set<AbstractGroupedContainer> dirtyNames = new HashSet<AbstractGroupedContainer>();
505
506 for(AbstractGroupedContainer composite : getGroupedContainers()){
507 if(composite.isDirty()){
508 dirtyNames.add(composite);
509 }
510 }
511
512 return dirtyNames;
513 }
514
515 /**
516 * <p>getGroupedContainers</p>
517 *
518 * @return a {@link java.util.List} object.
519 */
520 public List<AbstractGroupedContainer> getGroupedContainers(){
521 List<AbstractGroupedContainer> groupedComposites = new ArrayList<AbstractGroupedContainer>();
522
523 for(AbstractGroup group : getAllGroups()){
524 groupedComposites.addAll(group.getGroupedContainers());
525 }
526
527 return groupedComposites;
528 }
529
530 /**
531 * <p>getAllGroups</p>
532 *
533 * @return a {@link java.util.List} object.
534 */
535 public List<AbstractGroup> getAllGroups(){
536 List<AbstractGroup> allGroups = new ArrayList<AbstractGroup>();
537
538 allGroups.add(getAcceptedGroup());
539
540 allGroups.addAll(getHeterotypicSynonymGroups());
541
542 if(misappliedGroup != null){
543 allGroups.add(misappliedGroup);
544 }
545
546 if(conceptGroup != null){
547 allGroups.add(conceptGroup);
548 }
549
550 return allGroups;
551 }
552
553 /* (non-Javadoc)
554 * @see org.eclipse.ui.part.EditorPart#isDirty()
555 */
556 /** {@inheritDoc} */
557 @Override
558 public boolean isDirty() {
559 return editor.isDirty();
560 }
561
562 /* (non-Javadoc)
563 * @see org.eclipse.ui.part.WorkbenchPart#dispose()
564 */
565 /** {@inheritDoc} */
566 @Override
567 public void dispose() {
568 super.dispose();
569 }
570
571 /* (non-Javadoc)
572 * @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed()
573 */
574 /** {@inheritDoc} */
575 @Override
576 public boolean isSaveAsAllowed() {
577 return false;
578 }
579
580 /*
581 * (non-Javadoc)
582 * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
583 */
584 /** {@inheritDoc} */
585 public void selectionChanged(IWorkbenchPart part, ISelection selection) {
586
587 }
588
589 /**
590 * <p>getNameEditor</p>
591 *
592 * @return a {@link eu.etaxonomy.taxeditor.editor.name.TaxonNameEditor} object.
593 */
594 public TaxonNameEditor getEditor() {
595 return this;
596 }
597
598 /**
599 * <p>Getter for the field <code>selectedObject</code>.</p>
600 *
601 * @return a {@link eu.etaxonomy.taxeditor.editor.name.container.AbstractGroupedContainer} object.
602 */
603 public AbstractGroupedContainer getSelectedContainer(){
604
605 TaxonBase selectedTaxonBase = null;
606
607 TaxonEditorInput input = (TaxonEditorInput) editor.getEditorInput();
608 if(input.getInitiallySelectedTaxonBase() != null){
609 selectedTaxonBase = input.getInitiallySelectedTaxonBase();
610 }else{
611 if(selection != null){
612 selectedTaxonBase = selection;
613 }
614 }
615
616 return (selectedTaxonBase != null) ? getContainer(selectedTaxonBase) : getAcceptedNameContainer();
617 }
618
619 /**
620 * <p>dragEntered</p>
621 */
622 public void dragEntered() {
623 // TODO change this
624 getControl().setBackground(EditorUtil.getColor(Resources.COLOR_DRAG_ENTER));
625 }
626
627 /**
628 * <p>dragLeft</p>
629 */
630 public void dragLeft() {
631 getControl().setBackground(EditorUtil.getColor(Resources.COLOR_COMPOSITE_BACKGROUND));
632 }
633
634 /**
635 * <p>Setter for the field <code>conceptGroup</code>.</p>
636 *
637 * @param conceptGroup a {@link eu.etaxonomy.taxeditor.editor.name.container.ConceptGroup} object.
638 */
639 public void setConceptGroup(ConceptGroup conceptGroup) {
640 this.conceptGroup = conceptGroup;
641 }
642
643 /**
644 * <p>setMisapplicationsGroup</p>
645 *
646 * @param misappliedGroup a {@link eu.etaxonomy.taxeditor.editor.name.container.MisappliedGroup} object.
647 */
648 public void setMisapplicationsGroup(MisappliedGroup misappliedGroup) {
649 this.misappliedGroup = misappliedGroup;
650 }
651
652 /*
653 * (non-Javadoc)
654 * @see eu.etaxonomy.taxeditor.editor.IMultiPageTaxonEditorPage#isRedrawing()
655 */
656 /**
657 * <p>isRedrawing</p>
658 *
659 * @return a boolean.
660 */
661 public boolean isRedrawing() {
662 return false;
663 }
664
665 /**
666 * <p>getToolkit</p>
667 *
668 * @return a {@link org.eclipse.ui.forms.widgets.FormToolkit} object.
669 */
670 public FormToolkit getToolkit() {
671 return managedForm.getToolkit();
672 }
673
674 /**
675 * <p>getHeterotypicSynonymGroups</p>
676 *
677 * @return a {@link java.util.List} object.
678 */
679 public List<HomotypicalSynonymGroup> getHeterotypicSynonymGroups(){
680 return heterotypicSynonymGroups;
681 }
682
683
684 /**
685 * <p>addHeterotypicSynonymGroup</p>
686 *
687 * @param group a {@link eu.etaxonomy.taxeditor.editor.name.container.HomotypicalSynonymGroup} object.
688 */
689 public void addHeterotypicSynonymGroup(HomotypicalSynonymGroup group) {
690 heterotypicSynonymGroups.add(group);
691 }
692
693 /**
694 * <p>getHomotypicSynonymGroup</p>
695 *
696 * @return a {@link eu.etaxonomy.taxeditor.editor.name.container.HomotypicalSynonymGroup} object.
697 */
698 public AcceptedGroup getAcceptedGroup() {
699 return acceptedGroup;
700 }
701
702
703
704 /**
705 *
706 * @param acceptedGroup
707 */
708 public void setAcceptedGroup(
709 AcceptedGroup acceptedGroup) {
710 this.acceptedGroup = acceptedGroup;
711 }
712
713 /**
714 * <p>Getter for the field <code>misappliedGroup</code>.</p>
715 *
716 * @return a {@link eu.etaxonomy.taxeditor.editor.name.container.MisappliedGroup} object.
717 */
718 public MisappliedGroup getMisappliedGroup() {
719 return misappliedGroup;
720 }
721
722 // TODO not very useful at the moment
723 /**
724 * <p>isActive</p>
725 *
726 * @return a boolean.
727 */
728 public boolean isActive(){
729 IWorkbenchPart activePart = EditorUtil.getActivePart();
730 return editor.equals(activePart);
731 }
732
733 /**
734 * <p>onComplete</p>
735 *
736 * @return a boolean.
737 */
738 public boolean onComplete() {
739 getContainer(objectAffectedByLastOperation).setSelected();
740 return true;
741 }
742
743
744
745 /** {@inheritDoc} */
746 public void partChanged(Integer eventType, IWorkbenchPartReference partRef) {
747 if(! partRef.getPart(false).equals(editor)){
748 // getSelectedObject().colorSelected(AbstractGroupedContainer.SELECTED_NO_FOCUS);
749 }
750 }
751
752
753
754 /**
755 * @param retainedGroup
756 */
757 public void removeGroup(AbstractGroup group) {
758 if(group != null){
759 group.dispose();
760 getHeterotypicSynonymGroups().remove(group);
761 }
762 }
763
764 /**
765 * @param element
766 * @return
767 */
768 public AbstractGroupedContainer getContainer(TaxonBase taxonBase) {
769 List<AbstractGroupedContainer> groupedContainers = getGroupedContainers();
770 for(AbstractGroupedContainer container : groupedContainers){
771 if(container.getData().equals(taxonBase) && container.getNameViewer().getTextWidget() != null){
772 return container;
773 }
774 }
775 return getAcceptedNameContainer();
776 }
777 }