import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+import javax.inject.Named;
+
import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.action.MenuManager;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.ui.di.Focus;
+import org.eclipse.e4.ui.di.Persist;
+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.services.IServiceConstants;
+import org.eclipse.e4.ui.workbench.modeling.EPartService;
+import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
import org.eclipse.jface.util.LocalSelectionTransfer;
import org.eclipse.jface.viewers.AbstractTreeViewer;
import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeNode;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Tree;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IMemento;
-import org.eclipse.ui.ISelectionListener;
-import org.eclipse.ui.ISelectionService;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.part.EditorPart;
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
import eu.etaxonomy.taxeditor.editor.EditorUtil;
-import eu.etaxonomy.taxeditor.editor.Messages;
import eu.etaxonomy.taxeditor.editor.MultiPageTaxonEditor;
+import eu.etaxonomy.taxeditor.editor.l10n.Messages;
import eu.etaxonomy.taxeditor.editor.view.derivate.searchFilter.DerivateSearchCompositeController;
+import eu.etaxonomy.taxeditor.model.AbstractUtility;
import eu.etaxonomy.taxeditor.model.IContextListener;
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.model.MessagingUtils;
import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
import eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled;
import eu.etaxonomy.taxeditor.store.CdmStore;
import eu.etaxonomy.taxeditor.view.derivateSearch.DerivateContentProvider;
import eu.etaxonomy.taxeditor.view.derivateSearch.DerivateLabelProvider;
+import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
/**
* Displays the derivate hierarchy of the specimen specified in the editor input.
*
*/
-public class DerivateView extends EditorPart implements IPartContentHasFactualData, IConversationEnabled,
+public class DerivateView implements IPartContentHasFactualData, IConversationEnabled,
ICdmEntitySessionEnabled, IDirtyMarkable, IPostOperationEnabled, IPartContentHasDetails, IPartContentHasSupplementalData, IPartContentHasMedia,
- IContextListener, ISelectionListener {
+ IContextListener, IE4SavablePart {
+
+ private static final String SPECIMEN_EDITOR = Messages.DerivateView_SPECIMEN_EDITOR;
+
public static final String ID = "eu.etaxonomy.taxeditor.editor.view.derivate.DerivateView"; //$NON-NLS-1$
+ public static final String INPUT_ID = ID+".editorInput"; //$NON-NLS-1$
public static final String YOU_NEED_TO_SAVE_BEFORE_PERFORMING_THIS_ACTION = Messages.DerivateView_YOU_NEED_TO_SAVE;
public static final String VIEW_HAS_UNSAVED_CHANGES = Messages.DerivateView_UNSAVED_CHANGES;
private static final List<String> SPECIMEN_INIT_STRATEGY = Arrays.asList(new String[] {
- "descriptions",
- "annotations",
- "markers",
- "credits",
- "extensions",
- "rights",
- "sources",
- "derivationEvents.derivatives.annotations",
- "derivationEvents.derivatives.markers",
- "derivationEvents.derivatives.credits",
- "derivationEvents.derivatives.extensions",
- "derivationEvents.derivatives.rights",
- "derivationEvents.derivatives.sources"
+ "descriptions", //$NON-NLS-1$
+ "annotations", //$NON-NLS-1$
+ "markers", //$NON-NLS-1$
+ "credits", //$NON-NLS-1$
+ "extensions", //$NON-NLS-1$
+ "rights", //$NON-NLS-1$
+ "sources", //$NON-NLS-1$
+ "derivationEvents.derivatives.annotations", //$NON-NLS-1$
+ "derivationEvents.derivatives.markers", //$NON-NLS-1$
+ "derivationEvents.derivatives.credits", //$NON-NLS-1$
+ "derivationEvents.derivatives.extensions", //$NON-NLS-1$
+ "derivationEvents.derivatives.rights", //$NON-NLS-1$
+ "derivationEvents.derivatives.sources" //$NON-NLS-1$
});
+ private static final int WARN_THRESHOLD = 200;
+
+
private ConversationHolder conversation;
private TreeViewer viewer;
- private boolean isDirty;
-
private final int dndOperations = DND.DROP_MOVE;
private DerivateLabelProvider labelProvider;
private Taxon selectedTaxon;
- private ISelectionService selectionService;
+ @Inject
+ private ESelectionService selService;
+
+ @Inject
+ private MDirtyable dirty;
+
+ @Inject
+ private EPartService partService;
+
+ private ISelectionChangedListener selectionChangedListener;
/**
* Default constructor
*/
+ @Inject
public DerivateView() {
}
-
/**
* {@inheritDoc}
*/
- @Override
- public void init(IEditorSite site, IEditorInput input) throws PartInitException {
- this.setSite(site);
- this.setInput(input);
- this.derivateToRootEntityMap = new HashMap<SpecimenOrObservationBase<?>, SpecimenOrObservationBase<?>>();
- this.rootElements = new HashSet<SpecimenOrObservationBase<?>>();
-
- if (CdmStore.isActive() && conversation == null) {
- conversation = CdmStore.createConversation();
+ public void init(DerivateViewEditorInput editorInput){
+ this.derivateToRootEntityMap = new HashMap<>();
+ this.rootElements = new HashSet<>();
+
+ //init tree
+ Collection<UUID> derivativeUuids = editorInput.getDerivativeUuids();
+ checkWarnThreshold(derivativeUuids);
+ updateRootEntities(derivativeUuids);
+ //set taxon filter
+ derivateSearchCompositeController.setTaxonFilter(editorInput.getTaxonUuid());
+ //reset status bar
+ //TODO e4
+// getEditorSite().getActionBars().getStatusLineManager().setMessage(""); //$NON-NLS-1$
+ }
+
+ @PostConstruct
+ public void createPartControl(Composite parent, EMenuService menuService) {
+ if (CdmStore.isActive()){
+ if(conversation == null){
+ conversation = CdmStore.createConversation();
+ }
+ if(cdmEntitySession!=null){
+ cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true);
+ }
}
- if (CdmStore.isActive()) {
- cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true);
+ else{
+ return;
}
//listen to context changes
CdmStore.getContextManager().addContextListener(this);
- }
-
- @Override
- public void createPartControl(Composite parent) {
parent.setLayout(new GridLayout());
viewer.setLabelProvider(labelProvider);
viewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS);
viewer.getTree().setEnabled(CdmStore.isActive());
- // Propagate selection from viewer
- getSite().setSelectionProvider(viewer);
- //listen to selection changes
- selectionService = getSite().getWorkbenchWindow().getSelectionService();
- selectionService.addSelectionListener(this);
+ //propagate selection
+ selectionChangedListener = (event -> selService.setSelection(AbstractUtility.getElementsFromSelectionChangedEvent(event)));
+ viewer.addSelectionChangedListener(selectionChangedListener);
//create context menu
- MenuManager menuManager = new MenuManager();
- menuManager.setRemoveAllWhenShown(true);
- getSite().registerContextMenu(menuManager, viewer);
- Control control = viewer.getControl();
- Menu menu = menuManager.createContextMenu(control);
- control.setMenu(menu);
-
- //init tree
- updateRootEntities(((DerivateViewEditorInput)getEditorInput()).getDerivativeUuids());
- //reset status bar
- getEditorSite().getActionBars().getStatusLineManager().setMessage("");
+ menuService.registerContextMenu(viewer.getControl(), "eu.etaxonomy.taxeditor.editor.popupmenu.specimeneditor");
//add drag'n'drop support
Transfer[] transfers = new Transfer[] {LocalSelectionTransfer.getTransfer(),};
List<SpecimenOrObservationBase> derivates = null;
if(derivativeUuids!=null){
- this.derivateToRootEntityMap = new HashMap<SpecimenOrObservationBase<?>, SpecimenOrObservationBase<?>>();
- this.rootElements = new HashSet<SpecimenOrObservationBase<?>>();
+ this.derivateToRootEntityMap = new HashMap<>();
+ this.rootElements = new HashSet<>();
derivates = CdmStore.getService(IOccurrenceService.class).load(new ArrayList(derivativeUuids), SPECIMEN_INIT_STRATEGY);
}
updateRootEntities(derivates);
public void updateRootEntities(List<SpecimenOrObservationBase> derivates) {
+ if(derivates!=null){
+ this.derivateToRootEntityMap = new HashMap<>();
+ this.rootElements = new HashSet<>();
+ for (SpecimenOrObservationBase derivate : derivates) {
- if(derivates!=null){
- this.derivateToRootEntityMap = new HashMap<SpecimenOrObservationBase<?>, SpecimenOrObservationBase<?>>();
- this.rootElements = new HashSet<SpecimenOrObservationBase<?>>();
- for (SpecimenOrObservationBase derivate : derivates) {
-
- if(derivate instanceof FieldUnit){
- derivateToRootEntityMap.put(derivate, derivate);
+ if(derivate instanceof FieldUnit){
+ derivateToRootEntityMap.put(derivate, derivate);
+ }
+ else {
+ SpecimenOrObservationBase<?> topMostDerivate = EditorUtil.getTopMostDerivate(derivate);
+ if(topMostDerivate!=null){
+ derivateToRootEntityMap.put(derivate, topMostDerivate);
}
- else {
- SpecimenOrObservationBase<?> topMostDerivate = EditorUtil.getTopMostDerivate(derivate);
- if(topMostDerivate!=null){
- derivateToRootEntityMap.put(derivate, topMostDerivate);
- }
- else{
- derivateToRootEntityMap.put(derivate, derivate);
- }
+ else{
+ derivateToRootEntityMap.put(derivate, derivate);
}
}
- for (SpecimenOrObservationBase<?> specimen : derivateToRootEntityMap.values()) {
- rootElements.add(specimen);
- }
}
- labelProvider.updateLabelCache(rootElements);
- viewer.setInput(rootElements);
+ for (SpecimenOrObservationBase<?> specimen : derivateToRootEntityMap.values()) {
+ rootElements.add(specimen);
+ }
+ }
+ labelProvider.updateLabelCache(rootElements);
+ viewer.setInput(rootElements);
- getEditorSite().getActionBars().getStatusLineManager().setMessage(rootElements.size() +" derivative hierarchies found");
+ //TODO e4
+ // getEditorSite().getActionBars().getStatusLineManager().setMessage(String.format(Messages.DerivateView_CNT_DERIVATIVES_FOUND, rootElements.size()));
- //set selection to derivatives if the filter criteria
- //taxon assignment or or derivative type are set
- if(derivates!=null && !derivateSearchCompositeController.isDefaultSearch()){
- List<TreeNode> nodesToSelect = new ArrayList<TreeNode>();
- for (SpecimenOrObservationBase specimenOrObservationBase : derivates) {
- nodesToSelect.add(new TreeNode(specimenOrObservationBase));
- }
- viewer.setSelection(new StructuredSelection(nodesToSelect));
- }
- else{
- viewer.setSelection(null);
+ //set selection to derivatives if the filter criteria
+ //taxon assignment or derivative type are set
+ if(derivates!=null && !derivateSearchCompositeController.isDefaultSearch()){
+ List<TreeNode> nodesToSelect = new ArrayList<>();
+ for (SpecimenOrObservationBase specimenOrObservationBase : derivates) {
+ nodesToSelect.add(new TreeNode(specimenOrObservationBase));
}
+ setSelection(new StructuredSelection(nodesToSelect));
+ }
+ else{
+ setSelection(null);
+ }
+ }
+ private void setSelection(StructuredSelection selection){
+ viewer.removeSelectionChangedListener(selectionChangedListener);
+ viewer.setSelection(selection);
+ viewer.addSelectionChangedListener(selectionChangedListener);
}
public void updateLabelCache(){
labelProvider.updateLabelCache(rootElements);
}
+ @Persist
@Override
- public void doSave(IProgressMonitor monitor) {
+ public void save(IProgressMonitor monitor) {
String taskName = Messages.DerivateView_SAVING_HIERARCHY;
monitor.beginTask(taskName, 3);
if (!conversation.isBound()) {
// commit the conversation and start a new transaction immediately
conversation.commit(true);
- if(CdmStore.getCurrentSessionManager().isRemoting()) {
- CdmStore.getService(IOccurrenceService.class).merge(new ArrayList<SpecimenOrObservationBase>(rootElements), true);
- }
+ CdmStore.getService(IOccurrenceService.class).merge(new ArrayList<>(rootElements), true);
+
monitor.worked(1);
this.setDirty(false);
monitor.worked(1);
monitor.done();
- firePropertyChange(PROP_DIRTY);
+ dirty.setDirty(false);
refreshTree();
}
- @Override
- public void doSaveAs() {
- }
-
- @Override
- public String getTitleToolTip() {
- return Messages.DerivateView_DERIVATIVE_EDITOR;
- }
-
- @Override
- public boolean isDirty() {
- return isDirty;
- }
-
/**
* @param isDirty the isDirty to set
*/
public void setDirty(boolean isDirty) {
- this.isDirty = isDirty;
- }
-
- @Override
- public boolean isSaveAsAllowed() {
- return false;
+ dirty.setDirty(isDirty);
}
- @Override
+ @Focus
public void setFocus() {
- viewer.getControl().setFocus();
//make sure to bind again if maybe in another view the conversation was unbound
if(conversation!=null && !conversation.isBound()){
conversation.bind();
if(cdmEntitySession != null) {
cdmEntitySession.bind();
}
+ if(derivateSearchCompositeController!=null) {
+ derivateSearchCompositeController.setFocusOnSearchField();
+ }
}
@Override
@Override
public void changed(Object element) {
setDirty(true);
- firePropertyChange(IEditorPart.PROP_DIRTY);
+ //firePropertyChange(IEditorPart.PROP_DIRTY);
viewer.update(new TreeNode(element), null);
}
@Override
public Map<Object, List<String>> getPropertyPathsMap() {
List<String> specimenPropertyPaths = Arrays.asList(new String[] {
- "descriptions",
- "derivationEvents.derivates",
- "annotations",
- "markers",
- "credits",
- "extensions",
- "rights",
- "sources"
+ "descriptions", //$NON-NLS-1$
+ "derivationEvents.derivates", //$NON-NLS-1$
+ "annotations", //$NON-NLS-1$
+ "markers", //$NON-NLS-1$
+ "credits", //$NON-NLS-1$
+ "extensions", //$NON-NLS-1$
+ "rights", //$NON-NLS-1$
+ "sources" //$NON-NLS-1$
});
Map<Object, List<String>> specimenPropertyPathMap =
- new HashMap<Object, List<String>>();
+ new HashMap<>();
specimenPropertyPathMap.put(SpecimenOrObservationBase.class,specimenPropertyPaths);
return specimenPropertyPathMap;
}
* Refreshes the derivate hierarchy tree
*/
public void refreshTree(){
- viewer.refresh();
+ if(!viewer.getTree().isDisposed()){
+ viewer.refresh();
+ }
}
//FIXME:Remoting hack to make this work for remoting
//This should actually be resolved using remoting post operations
public void remove(Object obj) {
+ if (obj instanceof TreeNode){
+ obj = ((TreeNode)obj).getValue();
+ }
rootElements.remove(obj);
+ Object o = this.derivateToRootEntityMap.remove(obj);
viewer.setInput(rootElements);
}
return cdmEntitySession;
}
- @Override
+ @PreDestroy
public void dispose() {
- super.dispose();
if(conversation!=null){
conversation.close();
}
}
}
- @Override
- public void selectionChanged(IWorkbenchPart part, ISelection selection) {
+
+ @Inject
+ @Optional
+ public void selectionChanged(@Optional @Named(IServiceConstants.ACTIVE_SELECTION) ISelection selection,
+ @Named(IServiceConstants.ACTIVE_PART) MPart activePart, MPart thisPart)
+ {
+ if(activePart == thisPart || viewer==null){
+ return;
+ }
if(viewer.getTree().isDisposed()){
return;
}
if(listenToSelectionChange){
- if(part instanceof MultiPageTaxonEditor){
- selectedTaxon = ((MultiPageTaxonEditor) part).getTaxon();
+ selectedTaxon = null;
+ if(activePart instanceof MultiPageTaxonEditor){
+ selectedTaxon = ((MultiPageTaxonEditor) activePart).getTaxon();
}
else if(selection instanceof IStructuredSelection){
Object selectedElement = ((IStructuredSelection) selection).getFirstElement();
}
if(selectedTaxon!=null){
Collection<SpecimenOrObservationBase> fieldUnits = CdmStore.getService(IOccurrenceService.class).listFieldUnitsByAssociatedTaxon(selectedTaxon, null, null);
- Collection<UUID> uuids = new HashSet<UUID>();
+ Collection<UUID> uuids = new HashSet<>();
for (SpecimenOrObservationBase specimenOrObservationBase : fieldUnits) {
uuids.add(specimenOrObservationBase.getUuid());
}
+ checkWarnThreshold(uuids);
updateRootEntities(uuids);
- setPartName("Derivative Editor: " + selectedTaxon.getName());
+
+ thisPart.setLabel(SPECIMEN_EDITOR+": " + selectedTaxon.getName()); //$NON-NLS-1$
+ }
+ else{
+ updateRootEntities((Collection<UUID>)Collections.EMPTY_LIST);
}
}
}
+ private void checkWarnThreshold(Collection<UUID> uuids) {
+ if(uuids!=null && uuids.size()>WARN_THRESHOLD){
+ MessagingUtils.warningDialog(Messages.DerivateView_PERF_WARNING, this.getClass(), String.format(Messages.DerivateView_PERF_WARNING_MESSAGE, uuids.size()));
+ uuids.clear();
+ }
+ }
+
public TreeViewer getViewer() {
return viewer;
}
*/
@Override
public List<SpecimenOrObservationBase<?>> getRootEntities() {
- return new ArrayList<SpecimenOrObservationBase<?>>(rootElements);
+ return new ArrayList<>(rootElements);
}
- public void toggleListenToSelectionChange() {
+ public void toggleListenToSelectionChange(MPart part) {
listenToSelectionChange = !listenToSelectionChange;
derivateSearchCompositeController.setEnabled(!listenToSelectionChange);
if(!listenToSelectionChange){
selectedTaxon = null;
- setPartName("Derivative Editor");
+ part.setLabel(SPECIMEN_EDITOR);
}
else if(selectedTaxon==null){
- setPartName("Derivative Editor [no taxon selected]");
+ part.setLabel(SPECIMEN_EDITOR+Messages.DerivateView_NO_TAXON_SELECTED);
}
}
@Override
public void contextStart(IMemento memento, IProgressMonitor monitor) {
derivateSearchCompositeController.setEnabled(!listenToSelectionChange);
- viewer.getTree().setEnabled(true);
+ if(!viewer.getTree().isDisposed()){
+ viewer.getTree().setEnabled(true);
+ }
refreshTree();
}
public void workbenchShutdown(IMemento memento, IProgressMonitor monitor) {
}
+
+ public boolean isDirty() {
+ return dirty.isDirty();
+ }
+
}