package eu.etaxonomy.taxeditor.editor.view.derivate;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.util.LocalSelectionTransfer;
+import org.eclipse.jface.viewers.AbstractTreeViewer;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeNode;
import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.Transfer;
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.IWorkbenchPart;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.part.EditorPart;
-import eu.etaxonomy.cdm.model.common.CdmBase;
-import eu.etaxonomy.taxeditor.bulkeditor.BulkEditor;
-import eu.etaxonomy.taxeditor.model.AbstractUtility;
+import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
+import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
+import eu.etaxonomy.cdm.api.service.molecular.ISequenceService;
+import eu.etaxonomy.cdm.model.molecular.Sequence;
+import eu.etaxonomy.cdm.model.molecular.SingleRead;
+import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
+import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
+import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
+import eu.etaxonomy.taxeditor.model.IContextListener;
+import eu.etaxonomy.taxeditor.model.IDirtyMarkableSelectionProvider;
import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
+import eu.etaxonomy.taxeditor.model.IPartContentHasFactualData;
import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
-import eu.etaxonomy.taxeditor.view.AbstractCdmEditorViewPart;
+import eu.etaxonomy.taxeditor.store.CdmStore;
+import eu.etaxonomy.taxeditor.view.derivateSearch.DerivateLabelProvider;
/**
- * Displays the derivate hierarchy of all derivates belonging to a taxon.
+ * Displays the derivate hierarchy of all derivates having one single {@link FieldUnit} as root.
*
*/
-public class DerivateView extends AbstractCdmEditorViewPart implements IPartContentHasDetails, IPartContentHasSupplementalData {
+public class DerivateView extends EditorPart implements IPartContentHasFactualData, IDirtyMarkableSelectionProvider,
+ IConversationEnabled, IPartContentHasDetails, IPartContentHasSupplementalData, IContextListener {
+
+ /**
+ * Key used for storing a single DerivateView in a memento
+ */
+ private static final String DERIVATE_VIEW_MEMENTO_KEY = "derivateView";
+
+ /**
+ * Key to to group mementos for every single DerivateView
+ */
+ private static final String DERIVATE_VIEWS_MEMENTO_KEY = "derivateViews";
+
+ public static final String ID = "eu.etaxonomy.taxeditor.editor.view.derivate.DerivateView";
+
+ private ConversationHolder conversation;
+
+ private TreeViewer viewer;
+
+ private boolean isDirty;
+
+ private final int dndOperations = DND.DROP_MOVE;
+
+ private DerivateLabelProvider labelProvider;
- /** Constant <code>ID="eu.etaxonomy.taxeditor.editor.view.desc"{trunked}</code> */
- public static final String ID = "eu.etaxonomy.taxeditor.editor.view.derivate.SpecimenView";
+ private Set<SingleRead> multiLinkSingleReads;
- protected TreeViewer viewer;
+ /**
+ * Default constructor
+ */
+ public DerivateView() {
+ CdmStore.getContextManager().addContextListener(this);
+ }
- @Override
- public void createViewer(Composite parent) {
- viewer = new TreeViewer(new Tree(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION));
- viewer.setContentProvider(new DerivateContentProvider());
- viewer.setLabelProvider(new DerivateLabelProvider());
- viewer.setAutoExpandLevel(2);
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ public void createPartControl(Composite parent) {
+ viewer = new TreeViewer(new Tree(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION));
+ viewer.setContentProvider(new DerivateContentProvider());
+ labelProvider = new DerivateLabelProvider();
+ labelProvider.setConversation(conversation);
+ viewer.setLabelProvider(labelProvider);
+ viewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS);
// Propagate selection from viewer
getSite().setSelectionProvider(viewer);
- }
-
- @Override
- public void selectionChanged(IWorkbenchPart part, ISelection selection) {
- if(AbstractUtility.getActiveEditor()==null || !(AbstractUtility.getActiveEditor() instanceof BulkEditor)){
- showEmptyPage();
- return;
- }
- else if(part instanceof BulkEditor && selection instanceof IStructuredSelection){
- showViewer(part, (IStructuredSelection)selection);
- return;
- }
- }
-
- @Override
- public boolean onComplete() {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public Viewer getViewer() {
- return viewer;
- }
-
-
- @Override
- public boolean postOperation(CdmBase objectAffectedByOperation) {
- return super.postOperation(objectAffectedByOperation);
- }
+ //create context menu
+ MenuManager menuManager = new MenuManager();
+ getSite().registerContextMenu(menuManager, viewer);
+ Control control = viewer.getControl();
+ Menu menu = menuManager.createContextMenu(control);
+ control.setMenu(menu);
+
+ generateMultiLinkSingleReads();
+ labelProvider.setMultiLinkSingleReads(multiLinkSingleReads);
+ IEditorInput editorInput = getEditorInput();
+ viewer.setInput(editorInput);
+ if(editorInput instanceof DerivateViewEditorInput){
+ SpecimenOrObservationBase<?> specimen = ((DerivateViewEditorInput) editorInput).getDerivate();
+ SpecimenOrObservationBase<?> rootElement = ((DerivateViewEditorInput) editorInput).getRootElement();
+ setPartName(labelProvider.getDerivateText(rootElement));
+ viewer.setSelection(new StructuredSelection(new TreeNode(specimen)));
+ }
+
+ //add drag'n'drop support
+ Transfer[] transfers = new Transfer[] {LocalSelectionTransfer.getTransfer(),};
+ viewer.addDragSupport(dndOperations, transfers, new DerivateDragListener(this));
+ viewer.addDropSupport(dndOperations, transfers, new DerivateDropListener(this));
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public void doSave(IProgressMonitor monitor) {
+ monitor.beginTask("Saving Derivates", 3);
+ if (!conversation.isBound()) {
+ conversation.bind();
+ }
+ monitor.worked(1);
+
+ // commit the conversation and start a new transaction immediately
+ conversation.commit(true);
+ monitor.worked(1);
+
+ this.setDirty(false);
+ monitor.worked(1);
+ monitor.done();
+ firePropertyChange(PROP_DIRTY);
+ refreshTree();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.EditorPart#doSaveAs()
+ */
+ @Override
+ public void doSaveAs() {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.EditorPart#getTitleToolTip()
+ */
+ @Override
+ public String getTitleToolTip() {
+ return "Derivate View";
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.EditorPart#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
+ */
+ @Override
+ public void init(IEditorSite site, IEditorInput input) throws PartInitException {
+ setSite(site);
+ setInput(input);
+ if(input instanceof DerivateViewEditorInput){
+ conversation = ((DerivateViewEditorInput) input).getConversationHolder();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.EditorPart#isDirty()
+ */
+ @Override
+ public boolean isDirty() {
+ return isDirty;
+ }
+
+ /**
+ * @param isDirty the isDirty to set
+ */
+ public void setDirty(boolean isDirty) {
+ this.isDirty = isDirty;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed()
+ */
+ @Override
+ public boolean isSaveAsAllowed() {
+ return false;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
+ */
+ @Override
+ public void setFocus() {
+ viewer.getControl().setFocus();
+ //make sure to bind again if maybe in another view the conversation was unbound
+ if(!conversation.isBound()){
+ conversation.bind();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see eu.etaxonomy.cdm.persistence.hibernate.ICdmPostDataChangeObserver#update(eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap)
+ */
+ @Override
+ public void update(CdmDataChangeMap changeEvents) {
+ }
+
+ /* (non-Javadoc)
+ * @see eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder()
+ */
+ @Override
+ public ConversationHolder getConversationHolder() {
+ return conversation;
+ }
+
+ /**
+ * @return the viewer
+ */
+ public TreeViewer getViewer() {
+ return viewer;
+ }
+
+ /* (non-Javadoc)
+ * @see eu.etaxonomy.taxeditor.model.IDirtyMarkableSelectionProvider#changed(java.lang.Object)
+ */
+ @Override
+ public void changed(Object element) {
+ setDirty(true);
+ firePropertyChange(IEditorPart.PROP_DIRTY);
+ viewer.refresh();
+ }
+
+ /**
+ * Refreshes the derivate hierarchy tree
+ */
+ public void refreshTree(){
+ generateMultiLinkSingleReads();
+ labelProvider.setMultiLinkSingleReads(multiLinkSingleReads);
+ viewer.refresh();
+ }
+
+ private void generateMultiLinkSingleReads() {
+ Set<SingleRead> multiLinkSingleReads = new HashSet<SingleRead>();
+ for(Entry<SingleRead, Collection<Sequence>> entry:CdmStore.getService(ISequenceService.class).getSingleReadSequencesMap().entrySet()){
+ if(entry.getValue().size()>1){
+ multiLinkSingleReads.add(entry.getKey());
+ }
+ }
+ this.multiLinkSingleReads = multiLinkSingleReads;
+ }
+
+ /**
+ * @return a set of {@link SingleRead}s that have multiple parents
+ */
+ public Set<SingleRead> getMultiLinkSingleReads() {
+ return this.multiLinkSingleReads;
+ }
+
+ /* (non-Javadoc)
+ * @see eu.etaxonomy.taxeditor.model.IContextListener#contextAboutToStop(org.eclipse.ui.IMemento, org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public void contextAboutToStop(IMemento memento, IProgressMonitor monitor) {
+ }
+
+ /* (non-Javadoc)
+ * @see eu.etaxonomy.taxeditor.model.IContextListener#contextStop(org.eclipse.ui.IMemento, org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public void contextStop(IMemento memento, IProgressMonitor monitor) {
+ }
+
+ /* (non-Javadoc)
+ * @see eu.etaxonomy.taxeditor.model.IContextListener#contextStart(org.eclipse.ui.IMemento, org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public void contextStart(IMemento memento, IProgressMonitor monitor) {
+// if(memento == null){
+// return;
+// }
+// IMemento editorMementos = memento.getChild(DERIVATE_VIEW_MEMENTO_KEY);
+// DerivateViewEditorInput input = new DerivateViewEditorInput(UUID.fromString(editorInput.getString(DerivateViewEditorInput.UUID_MEMENTO_KEY)));
+// try {
+// EditorUtil.open(input);
+// } catch (PartInitException e) {
+// AbstractUtility.error(getClass(), "Error opening an editor window", e);
+// }
+ }
+
+ /* (non-Javadoc)
+ * @see eu.etaxonomy.taxeditor.model.IContextListener#contextRefresh(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public void contextRefresh(IProgressMonitor monitor) {
+ }
+
+ /* (non-Javadoc)
+ * @see eu.etaxonomy.taxeditor.model.IContextListener#workbenchShutdown(org.eclipse.ui.IMemento, org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public void workbenchShutdown(IMemento memento, IProgressMonitor monitor) {
+// if (!conversation.isBound()) {
+// conversation.bind();
+// }
+// conversation.close();
+// if(memento == null){
+// return;
+// }
+//
+// IEditorInput input = getEditorInput();
+// if(input instanceof IPersistable){
+// memento.createChild(DERIVATE_VIEW_MEMENTO_KEY);
+// ((IPersistable) input).saveState(memento);
+// }
+ }
}