Merge branch 'release/5.11.0'
[taxeditor.git] / eu.etaxonomy.taxeditor.bulkeditor / src / main / java / eu / etaxonomy / taxeditor / bulkeditor / e4 / BulkEditorE4.java
index db7156d199e982848653d86e3dd3415712cc0028..35b950d86eecab7f372106e82e57e41085e8c64a 100644 (file)
@@ -9,92 +9,58 @@
 
 package eu.etaxonomy.taxeditor.bulkeditor.e4;
 
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.HashMap;
+import java.io.FileOutputStream;
+import java.io.IOException;
 import java.util.List;
-import java.util.Map;
 
 import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
 import javax.inject.Inject;
 
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.e4.core.contexts.ContextInjectionFactory;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.core.di.annotations.Optional;
 import org.eclipse.e4.core.services.events.IEventBroker;
 import org.eclipse.e4.ui.di.Focus;
 import org.eclipse.e4.ui.di.Persist;
+import org.eclipse.e4.ui.di.UIEventTopic;
 import org.eclipse.e4.ui.model.application.ui.MDirtyable;
 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
-import org.eclipse.e4.ui.services.EMenuService;
-import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.layout.GridDataFactory;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.nebula.widgets.nattable.NatTable;
-import org.eclipse.nebula.widgets.nattable.command.VisualRefreshCommand;
-import org.eclipse.nebula.widgets.nattable.command.VisualRefreshCommandHandler;
-import org.eclipse.nebula.widgets.nattable.config.AbstractUiBindingConfiguration;
-import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry;
-import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration;
-import org.eclipse.nebula.widgets.nattable.data.IRowIdAccessor;
-import org.eclipse.nebula.widgets.nattable.data.ListDataProvider;
-import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsEventLayer;
-import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsSortModel;
-import org.eclipse.nebula.widgets.nattable.grid.GridRegion;
-import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider;
-import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider;
-import org.eclipse.nebula.widgets.nattable.grid.data.DefaultRowHeaderDataProvider;
-import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer;
-import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer;
-import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer;
-import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer;
-import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
-import org.eclipse.nebula.widgets.nattable.layer.stack.DefaultBodyLayerStack;
-import org.eclipse.nebula.widgets.nattable.selection.RowSelectionModel;
-import org.eclipse.nebula.widgets.nattable.selection.RowSelectionProvider;
-import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
-import org.eclipse.nebula.widgets.nattable.sort.SortHeaderLayer;
-import org.eclipse.nebula.widgets.nattable.sort.config.SingleClickSortConfiguration;
-import org.eclipse.nebula.widgets.nattable.style.theme.ModernNatTableThemeConfiguration;
-import org.eclipse.nebula.widgets.nattable.ui.binding.UiBindingRegistry;
-import org.eclipse.nebula.widgets.nattable.ui.matcher.MouseEventMatcher;
-import org.eclipse.nebula.widgets.nattable.ui.menu.PopupMenuAction;
-import org.eclipse.nebula.widgets.nattable.ui.menu.PopupMenuBuilder;
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.dnd.Clipboard;
-import org.eclipse.swt.dnd.TextTransfer;
-import org.eclipse.swt.dnd.Transfer;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Menu;
 
-import ca.odell.glazedlists.SortedList;
 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
 import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;
 import eu.etaxonomy.cdm.model.common.CdmBase;
-import eu.etaxonomy.cdm.model.description.SpecimenDescription;
+import eu.etaxonomy.cdm.model.description.DescriptionBase;
+import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
+import eu.etaxonomy.cdm.model.description.TaxonDescription;
+import eu.etaxonomy.cdm.model.description.TaxonNameDescription;
+import eu.etaxonomy.cdm.model.name.TaxonName;
 import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
 import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
+import eu.etaxonomy.cdm.model.permission.Group;
+import eu.etaxonomy.cdm.model.permission.User;
 import eu.etaxonomy.cdm.model.taxon.Taxon;
+import eu.etaxonomy.cdm.model.taxon.TaxonNode;
 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
 import eu.etaxonomy.taxeditor.bulkeditor.BulkEditorQuery;
 import eu.etaxonomy.taxeditor.bulkeditor.input.AbstractBulkEditorInput;
-import eu.etaxonomy.taxeditor.bulkeditor.input.sortprovider.TitleCacheComparator;
+import eu.etaxonomy.taxeditor.bulkeditor.input.GroupEditorInput;
+import eu.etaxonomy.taxeditor.bulkeditor.input.TaxonEditorInput;
 import eu.etaxonomy.taxeditor.editor.ITaxonEditor;
 import eu.etaxonomy.taxeditor.event.WorkbenchEventConstants;
-import eu.etaxonomy.taxeditor.l10n.Messages;
 import eu.etaxonomy.taxeditor.model.IDerivedUnitFacadePart;
 import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
 import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
 import eu.etaxonomy.taxeditor.model.IPartContentHasFactualData;
 import eu.etaxonomy.taxeditor.model.IPartContentHasMedia;
 import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
+import eu.etaxonomy.taxeditor.operation.AbstractPostOperation;
 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
 import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
 
@@ -108,40 +74,25 @@ public class BulkEditorE4 implements IPartContentHasDetails, IConversationEnable
         IDirtyMarkable, IDerivedUnitFacadePart, IPartContentHasFactualData,
         IPartContentHasSupplementalData, IPartContentHasMedia, IE4SavablePart, ITaxonEditor {
 
-    public static final String TYPE_PROPERTY = "Type";
-
     @Inject
        private MDirtyable dirty;
 
     private AbstractBulkEditorInput input;
 
-    private Composite topComposite;
-
     private ConversationHolder conversation;
 
-    @Inject
-    private ESelectionService selService;
-
     @Inject
     private IEventBroker eventBroker;
 
-    private ISelectionChangedListener selectionChangedListener;
+    @Inject
+    IEclipseContext context;
 
     @Inject
     private MPart thisPart;
 
     private BulkEditorQuery lastQuery = null;
 
-    private Composite bottomComposite;
-
-    @Inject
-    private EMenuService menuService;
-
-    private NatTable natTable;
-
-    private DefaultBodyLayerStack bodyLayer;
-
-    private ListDataProvider<CdmBase> bodyDataProvider;
+    private BulkEditorE4Composite bulkEditorComposite;
 
     @Inject
     public BulkEditorE4() {
@@ -151,157 +102,16 @@ public class BulkEditorE4 implements IPartContentHasDetails, IConversationEnable
     public void init(AbstractBulkEditorInput<?> input){
            this.input = input;
            this.conversation = input.getConversation();
-
-           new BulkEditorSearchE4(this, topComposite, SWT.NONE);
-           //layout needed because the search bar is added after @PostConstuct method
-           topComposite.getParent().layout();
-
            thisPart.setLabel(input.getEditorName());
 
-        if(input.getEntityUuid()!=null){
-            performSearch(new BulkEditorQuery(input.getEntityUuid().toString()));
-        }
-
-        createTable();
-
-        configureTable();
-
-        styleTable();
-
-        GridDataFactory.fillDefaults().grab(true, true).applyTo(natTable);
-
-        //propagate selection
-        selectionChangedListener = (event -> selService.setSelection(getSelection()));
-        RowSelectionProvider<CdmBase> selectionProvider = new RowSelectionProvider<CdmBase>(bodyLayer.getSelectionLayer(), bodyDataProvider, true);
-        selectionProvider.addSelectionChangedListener(selectionChangedListener);
-       }
-
-       private void createTable(){
-           ConfigRegistry configRegistry = new ConfigRegistry();
-           //property map
-        Map<String, String> propertyToLabels = new HashMap<>();
-        propertyToLabels.put(getEditorInput().getName(), getEditorInput().getName());
-        propertyToLabels.put(TYPE_PROPERTY, TYPE_PROPERTY);
-        String[] propertyNames = new String[] { input.getName(), TYPE_PROPERTY };
-        //sorted list
-        SortedList<CdmBase> sortedList = new SortedList<>(input.getModel(), new TitleCacheComparator());
-        //data provider
-        BulkEditorPropertyAccessor columnPropertyAccessor = new BulkEditorPropertyAccessor(input);
-        bodyDataProvider = new ListDataProvider<CdmBase>(sortedList,
-                columnPropertyAccessor);
-        DefaultColumnHeaderDataProvider colHeaderDataProvider = new DefaultColumnHeaderDataProvider(
-                propertyNames, propertyToLabels);
-        DefaultRowHeaderDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(
-                bodyDataProvider);
-        //body
-        DataLayer dataLayer = new DataLayer(bodyDataProvider);
-        dataLayer.registerCommandHandler(new VisualRefreshCommandHandler());
-        GlazedListsEventLayer<CdmBase> eventLayer = new GlazedListsEventLayer<>(dataLayer, input.getModel());
-        bodyLayer = new DefaultBodyLayerStack(eventLayer);
-        //column
-        DataLayer columnHeaderDataLayer = new DataLayer(colHeaderDataProvider);
-        ColumnHeaderLayer columnHeaderLayer = new ColumnHeaderLayer(
-                columnHeaderDataLayer,
-                bodyLayer, bodyLayer.getSelectionLayer());
-        // add the SortHeaderLayer to the column header layer stack
-        // as we use GlazedLists, we use the GlazedListsSortModel which
-        // delegates the sorting to the SortedList
-        final SortHeaderLayer<SpecimenDescription> sortHeaderLayer = new SortHeaderLayer<>(
-                columnHeaderLayer,
-                new GlazedListsSortModel<>(
-                        sortedList,
-                        columnPropertyAccessor,
-                        configRegistry,
-                        columnHeaderDataLayer));
-        //row
-        RowHeaderLayer rowHeaderLayer = new RowHeaderLayer(new DataLayer(rowHeaderDataProvider, 50, 20),
-                bodyLayer, bodyLayer.getSelectionLayer());
-        //corner
-        DefaultCornerDataProvider cornerDataProvider = new DefaultCornerDataProvider(
-                colHeaderDataProvider, rowHeaderDataProvider);
-        CornerLayer cornerLayer = new CornerLayer(new DataLayer(
-                cornerDataProvider), rowHeaderLayer, sortHeaderLayer);
-        //grid
-        GridLayer gridLayer = new GridLayer(bodyLayer, sortHeaderLayer,
-                rowHeaderLayer, cornerLayer);
-
-        dataLayer.setColumnPercentageSizing(true);
-
-        natTable = new NatTable(bottomComposite, gridLayer, false);
-        natTable.setConfigRegistry(configRegistry);
-
-        //full row selection
-        bodyLayer.getSelectionLayer().setSelectionModel(new RowSelectionModel<CdmBase>(bodyLayer.getSelectionLayer(), bodyDataProvider, new IRowIdAccessor<CdmBase>() {
-            @Override
-            public Serializable getRowId(CdmBase rowObject) {
-                return input.getModel().indexOf(rowObject);
-            }
-        }));
-       }
-
-       private void configureTable(){
-        //+++CONTEXT MENU+++
-        menuService.registerContextMenu(natTable, "eu.etaxonomy.taxeditor.bulkeditor.popupmenu.bulkeditor"); //$NON-NLS-1$
-        // get the menu registered by EMenuService
-        final Menu e4Menu = natTable.getMenu();
-        // remove the menu reference from NatTable instance
-        natTable.setMenu(null);
-        natTable.addConfiguration(
-                new AbstractUiBindingConfiguration() {
-            @Override
-            public void configureUiBindings(
-                    UiBindingRegistry uiBindingRegistry) {
-                // add e4 menu to NatTable
-                new PopupMenuBuilder(natTable, e4Menu)
-                    .build();
-
-                // register the UI binding for header, corner and body region
-                uiBindingRegistry.registerMouseDownBinding(
-                        new MouseEventMatcher(
-                                SWT.NONE,
-                                GridRegion.BODY,
-                                MouseEventMatcher.RIGHT_BUTTON),
-                        new PopupMenuAction(e4Menu));
-                uiBindingRegistry.registerMouseDownBinding(
-                        new MouseEventMatcher(
-                                SWT.NONE,
-                                GridRegion.COLUMN_HEADER,
-                                MouseEventMatcher.RIGHT_BUTTON),
-                        new PopupMenuAction(e4Menu));
-                uiBindingRegistry.registerMouseDownBinding(
-                        new MouseEventMatcher(
-                                SWT.NONE,
-                                GridRegion.CORNER,
-                                MouseEventMatcher.RIGHT_BUTTON),
-                        new PopupMenuAction(e4Menu));
-            }
-        });
-
-        //enable sorting
-        natTable.addConfiguration(new SingleClickSortConfiguration());
-        //add default configuration because autoconfigure is set to false in constructor
-        natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
-        natTable.configure();
-       }
-
-       private void styleTable(){
-           natTable.setTheme(new ModernNatTableThemeConfiguration());
+           bulkEditorComposite.init(input);
        }
 
        /** {@inheritDoc} */
        @PostConstruct
-       public void createPartControl(Composite parent) {
-               parent.setLayout(new GridLayout());
-
-               topComposite = new Composite(parent, SWT.NONE);
-               topComposite.setLayout(new GridLayout());
-
-               GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
-               topComposite.setLayoutData(gridData);
-
-               bottomComposite = new Composite(parent, SWT.NONE);
-               bottomComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-               bottomComposite.setLayout(new GridLayout());
+       public void createPartControl(Composite parent, IEclipseContext context) {
+           bulkEditorComposite = new BulkEditorE4Composite(this, parent, SWT.NONE);
+           ContextInjectionFactory.inject(bulkEditorComposite, context);
        }
 
        @Override
@@ -310,6 +120,25 @@ public class BulkEditorE4 implements IPartContentHasDetails, IConversationEnable
            save(monitor, true);
        }
 
+    public void save(IProgressMonitor monitor, boolean resetMerge) {
+        if (!input.getCdmEntitySession().isActive()){
+            input.getCdmEntitySession().bind();
+        }
+        input.saveModel(resetMerge);
+
+        IStructuredSelection selection = getSelection();
+
+        dirty.setDirty(false);
+        input.dispose();
+        input.bind();
+        conversation.commit(true);
+
+        if (lastQuery != null){
+            bulkEditorComposite.performSearch(lastQuery, selection);
+        }
+    }
+
+
        @Focus
        public void setFocus() {
         //make sure to bind again if maybe in another view the conversation was unbound
@@ -334,77 +163,48 @@ public class BulkEditorE4 implements IPartContentHasDetails, IConversationEnable
                input.dispose();
            }
            dirty.setDirty(false);
-       }
-
-       public void save(IProgressMonitor monitor, boolean resetMerge) {
-           if (!input.getCdmEntitySession().isActive()){
-            input.getCdmEntitySession().bind();
+           //save table settings
+           if(bulkEditorComposite.getNatTableState()!=null){
+            try (FileOutputStream tableStateStream =
+                    new FileOutputStream(bulkEditorComposite.getStatePropertiesFile())) {
+                bulkEditorComposite.getNatTableState().store(tableStateStream, null);
+            } catch (IOException ioe) {
+                ioe.printStackTrace();
+            }
         }
-           input.saveModel(resetMerge);
+       }
 
-           IStructuredSelection selection = getSelection();
+    @Optional
+    @Inject
+    private void updateAfterSearch(@UIEventTopic(WorkbenchEventConstants.BULK_EDITOR_SEARCH_FINISHED)IStructuredSelection selection){
 
-        dirty.setDirty(false);
-        input.dispose();
-        input.bind();
-        conversation.commit(true);
 
-        if (lastQuery != null){
-            performSearch(lastQuery);
+        if(selection!=null){
             setSelection(selection);
         }
-       }
-
-       /** {@inheritDoc} */
-    public void performSearch(BulkEditorQuery query) {
-        if (query != null) {
-            // TODO check if dirty, prompt save
-            if (isDirty()) {
-                String[] labels = {Messages.BulkEditorE4_SAVE_AND_SEARCH, Messages.BulkEditorE4_DONT_SAVE,Messages.BulkEditorE4_CANCEL};
-                MessageDialog dialog =new MessageDialog(topComposite.getShell(), Messages.BulkEditorE4_SAVE_CHANGES_TITLE, null, Messages.BulkEditorE4_SAVE_CHANGES_MESSAGE, MessageDialog.QUESTION,labels, 0);
-                int result = dialog.open();
-                if (result == 0) {
-                    save(new NullProgressMonitor());
-                } else if (result == 2){
-                    return;
-                }
-            }
-            dirty.setDirty(false);
-            input.performSearch(query);
-            lastQuery = query;
-        }
     }
 
-
     public void refresh(){
-        natTable.doCommand(new VisualRefreshCommand());
+        bulkEditorComposite.refresh();
     }
 
     public IStructuredSelection getSelection(){
-        List<CdmBase> selection = new ArrayList<>();
-        int[] fullySelectedRowPositions = bodyLayer.getSelectionLayer().getFullySelectedRowPositions();
-        for (int i : fullySelectedRowPositions) {
-            Object rowObject = bodyDataProvider.getRowObject(i);
-            if(rowObject instanceof CdmBase){
-                selection.add((CdmBase) rowObject);
-            }
-        }
-        return new StructuredSelection(selection);
+        return bulkEditorComposite.getSelection();
     }
 
     public void setSelection(IStructuredSelection selection){
-        Object[] objects = selection.toArray();
-        for (Object object : objects) {
-            if(object instanceof CdmBase){
-                selectionLayer.selectRow(0, bodyDataProvider.indexOfRowObject((CdmBase) object), false, false);
-            }
-        }
+        bulkEditorComposite.setSelection(selection);
+    }
+
+    public void setDirty(boolean isDirty){
+        dirty.setDirty(isDirty);
     }
 
     public void setDirty(){
-        dirty.setDirty(true);
+        setDirty(true);
     }
 
+    @Override
     public boolean isDirty() {
         return dirty.isDirty();
     }
@@ -414,22 +214,7 @@ public class BulkEditorE4 implements IPartContentHasDetails, IConversationEnable
     }
 
     public void copyDataToClipboard() {
-        String textData = "";
-        IStructuredSelection selection = getSelection();
-        Object[] objects = selection.toArray();
-        for (Object object : objects) {
-            if(object instanceof CdmBase){
-                textData += getEditorInput().getText((CdmBase)object);
-            }
-        }
-        final TextTransfer textTransfer = TextTransfer.getInstance();
-        final Clipboard clipboard = new Clipboard(Display.getDefault());
-        try {
-            clipboard.setContents(new Object[] { textData.toString() },
-                    new Transfer[] { textTransfer });
-        } finally {
-            clipboard.dispose();
-        }
+        bulkEditorComposite.copyDataToClipboard();
     }
 
     @Override
@@ -454,10 +239,38 @@ public class BulkEditorE4 implements IPartContentHasDetails, IConversationEnable
             }
         }
         else if (element instanceof CdmBase) {
-            getEditorInput().addSaveCandidate((CdmBase)element);
-            input.replaceInModel((CdmBase) element);
+            if (element instanceof DescriptionBase){
+                if (element instanceof TaxonNameDescription){
+                    TaxonName changedName = ((TaxonNameDescription)element).getTaxonName();
+                    getEditorInput().addSaveCandidate(changedName);
+                    input.replaceInModel(changedName);
+                }else if (element instanceof TaxonDescription){
+                    Taxon changedTaxon = ((TaxonDescription)element).getTaxon();
+                    getEditorInput().addSaveCandidate(changedTaxon);
+                    input.replaceInModel(changedTaxon);
+                }
+            }else if (element instanceof DescriptionElementBase){
+                if (((DescriptionElementBase)element).getInDescription() instanceof TaxonNameDescription){
+                    TaxonName changedName = ((TaxonNameDescription)((DescriptionElementBase)element).getInDescription()).getTaxonName();
+                    getEditorInput().addSaveCandidate(changedName);
+                    input.replaceInModel(changedName);
+                }else if (((DescriptionElementBase)element).getInDescription() instanceof TaxonDescription){
+                    Taxon changedTaxon = ((TaxonDescription)((DescriptionElementBase)element).getInDescription()).getTaxon();
+                    getEditorInput().addSaveCandidate(changedTaxon);
+                    input.replaceInModel(changedTaxon);
+                }
+            }else if(element instanceof Group){
+                 Group oldGroup = ((GroupEditorInput)input).getEntityFromModel((Group)element);
+                 ((GroupEditorInput)input).getSaveUserCandidates().addAll(oldGroup.getMembers());
+                 getEditorInput().addSaveCandidate((Group)element);
+                 input.replaceInModel((CdmBase) element);
+            }else{
+                getEditorInput().addSaveCandidate((CdmBase)element);
+                input.replaceInModel((CdmBase) element);
+            }
         }
         dirty.setDirty(true);
+        setSelection(new StructuredSelection(element));
     }
 
     @Override
@@ -466,7 +279,7 @@ public class BulkEditorE4 implements IPartContentHasDetails, IConversationEnable
     }
 
     @Override
-    public boolean postOperation(CdmBase objectAffectedByOperation) {
+    public boolean postOperation(Object objectAffectedByOperation) {
         return false;
     }
 
@@ -501,4 +314,43 @@ public class BulkEditorE4 implements IPartContentHasDetails, IConversationEnable
         return null;
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void update() {
+        input.performSearch(lastQuery, getSelection());
+    }
+
+    @Override
+    public void addOperation(AbstractPostOperation operation) {
+        // operations not yet used for bulk editor
+    }
+
+    @Inject
+    @Optional
+    private void updateView(@UIEventTopic(WorkbenchEventConstants.REFRESH_NAME_EDITOR) List<CdmBase> cdmBases) {
+        if (getEditorInput() instanceof TaxonEditorInput){
+            for (CdmBase cdmBase: cdmBases){
+                if (getEditorInput().getModel().contains(cdmBase)){
+                    input.performSearch(lastQuery, getSelection());
+                    break;
+                }
+            }
+        }
+    }
+
+    @Inject
+    @Optional
+    private void updatefromDelete(@UIEventTopic(WorkbenchEventConstants.REMOVE_USER) User user) {
+        if (input instanceof GroupEditorInput){
+            ((GroupEditorInput)input).getSaveUserCandidates().add(user);
+        }
+    }
+
+    @Override
+    public TaxonNode getTaxonNode() {
+        return null;
+    }
+
 }