From 95ee1b51f476e72636aa96a830f85b9e41861c59 Mon Sep 17 00:00:00 2001 From: "U-BGBM\\k.luther" Date: Wed, 2 Sep 2015 11:33:31 +0200 Subject: [PATCH 1/1] moving more than one taxon node, merge of team and person, reusing name for new taxon --- .../bulkeditor/input/AgentEditorInput.java | 2 +- .../editor/name/container/RulerWithIcon.java | 660 ++++++++++++++++++ .../navigator/TreeNodeDropAdapter.java | 69 +- .../TreeNodeDropAdapterAssistant.java | 50 +- .../navigator/handler/MoveTaxonHandler.java | 69 +- .../operation/MoveTaxonOperation.java | 26 +- .../TaxonNodeDetailElement.java | 1 + 7 files changed, 764 insertions(+), 113 deletions(-) create mode 100644 eu.etaxonomy.taxeditor.editor.src/main/java/eu/etaxonomy/taxeditor/editor/name/container/RulerWithIcon.java diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/input/AgentEditorInput.java b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/input/AgentEditorInput.java index 36a7cc9bc..4c2dccc55 100644 --- a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/input/AgentEditorInput.java +++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/input/AgentEditorInput.java @@ -82,7 +82,7 @@ public class AgentEditorInput extends AbstractBulkEditorInput public boolean merge(TeamOrPersonBase entity, TeamOrPersonBase mergeTarget) { if (entity instanceof IMergable) { try { - if(entity instanceof Person) { + if(entity instanceof Person && mergeTarget instanceof Person) { IMergeStrategy strategy = DefaultMergeStrategy.NewInstance(Person.class); strategy.setMergeMode("institutionalMemberships", MergeMode.FIRST); CdmStore.getCommonService().merge(mergeTarget.getId(), entity.getId(), Person.class); diff --git a/eu.etaxonomy.taxeditor.editor.src/main/java/eu/etaxonomy/taxeditor/editor/name/container/RulerWithIcon.java b/eu.etaxonomy.taxeditor.editor.src/main/java/eu/etaxonomy/taxeditor/editor/name/container/RulerWithIcon.java new file mode 100644 index 000000000..db4416160 --- /dev/null +++ b/eu.etaxonomy.taxeditor.editor.src/main/java/eu/etaxonomy/taxeditor/editor/name/container/RulerWithIcon.java @@ -0,0 +1,660 @@ +/** +* Copyright (C) 2007 EDIT +* European Distributed Institute of Taxonomy +* http://www.e-taxonomy.eu +* +* The contents of this file are subject to the Mozilla Public License Version 1.1 +* See LICENSE.TXT at the top of this package for the full license terms. +*/ + +package eu.etaxonomy.taxeditor.editor.name.container; + +import java.util.Iterator; + +import org.apache.log4j.Logger; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextListener; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.ITextViewerExtension5; +import org.eclipse.jface.text.IViewportListener; +import org.eclipse.jface.text.JFaceTextUtil; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.TextEvent; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.IAnnotationAccess; +import org.eclipse.jface.text.source.IAnnotationAccessExtension; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.IAnnotationModelListener; +import org.eclipse.jface.text.source.IAnnotationPresentation; +import org.eclipse.jface.text.source.IVerticalRuler; +import org.eclipse.jface.text.source.IVerticalRulerExtension; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.forms.widgets.TableWrapData; + +/** + * 99% of the code in this class was copied from org.eclipse.jface.text.source.VerticalRuler, + * which allows neither access to its paint methods nor subclassing to do same. + *

+ * Changes made in method doubleBufferPaint(doubleBufferPaint(GC dest)). + * + * @see org.eclipse.jface.text.source.VerticalRuler + * @author p.ciardelli + * @created 27.01.2009 + * @version 1.0 + */ +public class RulerWithIcon implements IVerticalRuler, IVerticalRulerExtension { + private static final Logger logger = Logger.getLogger(RulerWithIcon.class); + + /** + * Internal listener class. + */ + class InternalListener implements IViewportListener, IAnnotationModelListener, ITextListener { + + /* + * @see IViewportListener#viewportChanged(int) + */ + public void viewportChanged(int verticalPosition) { + if (verticalPosition != fScrollPos) + redraw(); + } + + /* + * @see IAnnotationModelListener#modelChanged(IAnnotationModel) + */ + public void modelChanged(IAnnotationModel model) { + update(); + } + + /* + * @see ITextListener#textChanged(TextEvent) + */ + public void textChanged(TextEvent e) { + if (fTextViewer != null && e.getViewerRedrawState()) + redraw(); + } + } + + /** The vertical ruler's text viewer */ + private ITextViewer fTextViewer; + /** The ruler's canvas */ + private Canvas fCanvas; + /** The vertical ruler's model */ + private IAnnotationModel fModel; + /** Cache for the actual scroll position in pixels */ + private int fScrollPos; + /** The buffer for double buffering */ + private Image fBuffer; + /** The line of the last mouse button activity */ + private int fLastMouseButtonActivityLine= -1; + /** The internal listener */ + private InternalListener fInternalListener= new InternalListener(); + /** The width of this vertical ruler */ + private int fWidth; + /** + * The annotation access of this vertical ruler + * @since 3.0 + */ + private IAnnotationAccess fAnnotationAccess; + private Image icon; + + /** + * Constructs a vertical ruler with the given width. + * + * @param width the width of the vertical ruler + */ + public RulerWithIcon(int width) { + this(width, null); + } + + /** + * Constructs a vertical ruler with the given width and the given annotation + * access. + * + * @param width the width of the vertical ruler + * @param annotationAcccess the annotation access + * @since 3.0 + */ + public RulerWithIcon(int width, IAnnotationAccess annotationAcccess) { + fWidth= width; + fAnnotationAccess= annotationAcccess; + } + + /* + * @see IVerticalRuler#getControl() + */ + /** + *

getControl

+ * + * @return a {@link org.eclipse.swt.widgets.Control} object. + */ + public Control getControl() { + return fCanvas; + } + + /* + * @see IVerticalRuler#createControl(Composite, ITextViewer) + */ + /** {@inheritDoc} */ + public Control createControl(Composite parent, ITextViewer textViewer) { + + fTextViewer= textViewer; + + fCanvas= new Canvas(parent, SWT.NO_BACKGROUND); + + TableWrapData layout = new TableWrapData(TableWrapData.LEFT); + layout.heightHint = 20; + layout.maxWidth = fWidth; + fCanvas.setLayoutData(layout); + + fCanvas.addPaintListener(new PaintListener() { + public void paintControl(PaintEvent event) { + if (fTextViewer != null) + doubleBufferPaint(event.gc); + } + }); + + fCanvas.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + handleDispose(); + fTextViewer= null; + } + }); + + fCanvas.addMouseListener(new MouseListener() { + public void mouseUp(MouseEvent event) { + } + + public void mouseDown(MouseEvent event) { + fLastMouseButtonActivityLine= toDocumentLineNumber(event.y); + } + + public void mouseDoubleClick(MouseEvent event) { + fLastMouseButtonActivityLine= toDocumentLineNumber(event.y); + } + }); + + if (fTextViewer != null) { + fTextViewer.addViewportListener(fInternalListener); + fTextViewer.addTextListener(fInternalListener); + } + + return fCanvas; + } + + /** + * Disposes the ruler's resources. + */ + private void handleDispose() { + + if (fTextViewer != null) { + fTextViewer.removeViewportListener(fInternalListener); + fTextViewer.removeTextListener(fInternalListener); + fTextViewer= null; + } + + if (fModel != null) + fModel.removeAnnotationModelListener(fInternalListener); + + if (fBuffer != null) { + fBuffer.dispose(); + fBuffer= null; + } + } + + + /** + * Double buffer drawing. + * + * @param dest the GC to draw into + */ + private void doubleBufferPaint(GC dest) { + + Point size= fCanvas.getSize(); + + if (size.x <= 0 || size.y <= 0) + return; + + if (fBuffer != null) { + Rectangle r= fBuffer.getBounds(); + if (r.width != size.x || r.height != size.y) { + fBuffer.dispose(); + fBuffer= null; + } + } + if (fBuffer == null) + fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y); + + GC gc= new GC(fBuffer); + gc.setFont(fTextViewer.getTextWidget().getFont()); + try { + gc.setBackground(fCanvas.getBackground()); + gc.fillRectangle(0, 0, size.x, size.y); + + // Code added to VerticalRuler starts here + if (icon != null) { + + Rectangle r = icon.getBounds(); + + if (r.width > size.x || r.height > size.y) { + logger.warn(r.width + "x" + r.height + " icon too big for " + size.x + "x" + size.y + " Canvas."); + } else { + + // Set destination coordinates to center icon + int x = (size.x - r.width) / 2; + int y = (size.y - r.height) / 2; + + gc.drawImage(icon, 0, 0, r.width, r.height, x, y, r.width, r.height); + } + } + // Code added to VerticalRuler ends here + + if (fTextViewer instanceof ITextViewerExtension5) + doPaint1(gc); + else + doPaint(gc); + + } finally { + gc.dispose(); + } + + dest.drawImage(fBuffer, 0, 0); + } + + /** + * Returns the document offset of the upper left corner of the + * widgets view port, possibly including partially visible lines. + * + * @return the document offset of the upper left corner including partially visible lines + * @since 2.0 + */ + private int getInclusiveTopIndexStartOffset() { + + StyledText textWidget= fTextViewer.getTextWidget(); + if (textWidget != null && !textWidget.isDisposed()) { + int top= JFaceTextUtil.getPartialTopIndex(fTextViewer); + try { + IDocument document= fTextViewer.getDocument(); + return document.getLineOffset(top); + } catch (BadLocationException x) { + } + } + + return -1; + } + + + + /** + * Draws the vertical ruler w/o drawing the Canvas background. + * + * @param gc the GC to draw into + */ + protected void doPaint(GC gc) { + + if (fModel == null || fTextViewer == null) + return; + + IAnnotationAccessExtension annotationAccessExtension= null; + if (fAnnotationAccess instanceof IAnnotationAccessExtension) + annotationAccessExtension= (IAnnotationAccessExtension) fAnnotationAccess; + + StyledText styledText= fTextViewer.getTextWidget(); + IDocument doc= fTextViewer.getDocument(); + + int topLeft= getInclusiveTopIndexStartOffset(); + int bottomRight= fTextViewer.getBottomIndexEndOffset(); + int viewPort= bottomRight - topLeft; + + Point d= fCanvas.getSize(); + fScrollPos= styledText.getTopPixel(); + + int topLine= -1, bottomLine= -1; + try { + IRegion region= fTextViewer.getVisibleRegion(); + topLine= doc.getLineOfOffset(region.getOffset()); + bottomLine= doc.getLineOfOffset(region.getOffset() + region.getLength()); + } catch (BadLocationException x) { + return; + } + + // draw Annotations + Rectangle r= new Rectangle(0, 0, 0, 0); + int maxLayer= 1; // loop at least once though layers. + + for (int layer= 0; layer < maxLayer; layer++) { + Iterator iter= fModel.getAnnotationIterator(); + while (iter.hasNext()) { + IAnnotationPresentation annotationPresentation= null; + Annotation annotation= (Annotation) iter.next(); + + int lay= IAnnotationAccessExtension.DEFAULT_LAYER; + if (annotationAccessExtension != null) + lay= annotationAccessExtension.getLayer(annotation); + else if (annotation instanceof IAnnotationPresentation) { + annotationPresentation= (IAnnotationPresentation)annotation; + lay= annotationPresentation.getLayer(); + } + maxLayer= Math.max(maxLayer, lay+1); // dynamically update layer maximum + if (lay != layer) // wrong layer: skip annotation + continue; + + Position position= fModel.getPosition(annotation); + if (position == null) + continue; + + if (!position.overlapsWith(topLeft, viewPort)) + continue; + + try { + + int offset= position.getOffset(); + int length= position.getLength(); + + int startLine= doc.getLineOfOffset(offset); + if (startLine < topLine) + startLine= topLine; + + int endLine= startLine; + if (length > 0) + endLine= doc.getLineOfOffset(offset + length - 1); + if (endLine > bottomLine) + endLine= bottomLine; + + startLine -= topLine; + endLine -= topLine; + + r.x= 0; + r.y= JFaceTextUtil.computeLineHeight(styledText, 0, startLine, startLine) - fScrollPos; + + r.width= d.x; + int lines= endLine - startLine; + + r.height= JFaceTextUtil.computeLineHeight(styledText, startLine, endLine + 1, (lines+1)); + + if (r.y < d.y && annotationAccessExtension != null) // annotation within visible area + annotationAccessExtension.paint(annotation, gc, fCanvas, r); + else if (annotationPresentation != null) + annotationPresentation.paint(gc, fCanvas, r); + + } catch (BadLocationException e) { + } + } + } + } + + /** + * Draws the vertical ruler w/o drawing the Canvas background. Uses + * ITextViewerExtension5 for its implementation. Will replace + * doPaint(GC). + * + * @param gc the GC to draw into + */ + protected void doPaint1(GC gc) { + + if (fModel == null || fTextViewer == null) + return; + + IAnnotationAccessExtension annotationAccessExtension= null; + if (fAnnotationAccess instanceof IAnnotationAccessExtension) + annotationAccessExtension= (IAnnotationAccessExtension) fAnnotationAccess; + + ITextViewerExtension5 extension= (ITextViewerExtension5) fTextViewer; + StyledText textWidget= fTextViewer.getTextWidget(); + + fScrollPos= textWidget.getTopPixel(); + Point dimension= fCanvas.getSize(); + + // draw Annotations + Rectangle r= new Rectangle(0, 0, 0, 0); + int maxLayer= 1; // loop at least once through layers. + + for (int layer= 0; layer < maxLayer; layer++) { + Iterator iter= fModel.getAnnotationIterator(); + while (iter.hasNext()) { + IAnnotationPresentation annotationPresentation= null; + Annotation annotation= (Annotation) iter.next(); + + int lay= IAnnotationAccessExtension.DEFAULT_LAYER; + if (annotationAccessExtension != null) + lay= annotationAccessExtension.getLayer(annotation); + else if (annotation instanceof IAnnotationPresentation) { + annotationPresentation= (IAnnotationPresentation)annotation; + lay= annotationPresentation.getLayer(); + } + maxLayer= Math.max(maxLayer, lay+1); // dynamically update layer maximum + if (lay != layer) // wrong layer: skip annotation + continue; + + Position position= fModel.getPosition(annotation); + if (position == null) + continue; + + IRegion widgetRegion= extension.modelRange2WidgetRange(new Region(position.getOffset(), position.getLength())); + if (widgetRegion == null) + continue; + + int startLine= extension.widgetLineOfWidgetOffset(widgetRegion.getOffset()); + if (startLine == -1) + continue; + + int endLine= extension.widgetLineOfWidgetOffset(widgetRegion.getOffset() + Math.max(widgetRegion.getLength() -1, 0)); + if (endLine == -1) + continue; + + r.x= 0; + r.y= JFaceTextUtil.computeLineHeight(textWidget, 0, startLine, startLine) - fScrollPos; + + r.width= dimension.x; + int lines= endLine - startLine; + + r.height= JFaceTextUtil.computeLineHeight(textWidget, startLine, endLine + 1, lines+1); + + if (r.y < dimension.y && annotationAccessExtension != null) // annotation within visible area + annotationAccessExtension.paint(annotation, gc, fCanvas, r); + else if (annotationPresentation != null) + annotationPresentation.paint(gc, fCanvas, r); + } + } + } + + /** + * Thread-safe implementation. + * Can be called from any thread. + */ + /* + * @see IVerticalRuler#update() + */ + public void update() { + if (fCanvas != null && !fCanvas.isDisposed()) { + Display d= fCanvas.getDisplay(); + if (d != null) { + d.asyncExec(new Runnable() { + public void run() { + redraw(); + } + }); + } + } + } + + /** + * Redraws the vertical ruler. + */ + private void redraw() { + if (fCanvas != null && !fCanvas.isDisposed()) { + GC gc= new GC(fCanvas); + doubleBufferPaint(gc); + gc.dispose(); + } + } + + /* + * @see IVerticalRuler#setModel(IAnnotationModel) + */ + /** {@inheritDoc} */ + public void setModel(IAnnotationModel model) { + if (model != fModel) { + + if (fModel != null) + fModel.removeAnnotationModelListener(fInternalListener); + + fModel= model; + + if (fModel != null) + fModel.addAnnotationModelListener(fInternalListener); + + update(); + } + } + + /* + * @see IVerticalRuler#getModel() + */ + /** + *

getModel

+ * + * @return a {@link org.eclipse.jface.text.source.IAnnotationModel} object. + */ + public IAnnotationModel getModel() { + return fModel; + } + + /* + * @see IVerticalRulerInfo#getWidth() + */ + /** + *

getWidth

+ * + * @return a int. + */ + public int getWidth() { + return fWidth; + } + + /* + * @see IVerticalRulerInfo#getLineOfLastMouseButtonActivity() + */ + /** + *

getLineOfLastMouseButtonActivity

+ * + * @return a int. + */ + public int getLineOfLastMouseButtonActivity() { + return fLastMouseButtonActivityLine; + } + + /* + * @see IVerticalRulerInfo#toDocumentLineNumber(int) + */ + /** {@inheritDoc} */ + public int toDocumentLineNumber(int y_coordinate) { + if (fTextViewer == null || y_coordinate == -1) + return -1; + + StyledText text= fTextViewer.getTextWidget(); + int line= text.getLineIndex(y_coordinate); + + if (line == text.getLineCount() - 1) { + // check whether y_coordinate exceeds last line + if (y_coordinate > text.getLinePixel(line + 1)) + return -1; + } + + return widgetLine2ModelLine(fTextViewer, line); + } + + /** + * Returns the line of the viewer's document that corresponds to the given widget line. + * + * @param viewer the viewer + * @param widgetLine the widget line + * @return the corresponding line of the viewer's document + * @since 2.1 + */ + protected final static int widgetLine2ModelLine(ITextViewer viewer, int widgetLine) { + + if (viewer instanceof ITextViewerExtension5) { + ITextViewerExtension5 extension= (ITextViewerExtension5) viewer; + return extension.widgetLine2ModelLine(widgetLine); + } + + try { + IRegion r= viewer.getVisibleRegion(); + IDocument d= viewer.getDocument(); + return widgetLine += d.getLineOfOffset(r.getOffset()); + } catch (BadLocationException x) { + } + return widgetLine; + } + + /* + * @see IVerticalRulerExtension#setFont(Font) + * @since 2.0 + */ + /** {@inheritDoc} */ + public void setFont(Font font) { + } + + /* + * @see IVerticalRulerExtension#setLocationOfLastMouseButtonActivity(int, int) + * @since 2.0 + */ + /** {@inheritDoc} */ + public void setLocationOfLastMouseButtonActivity(int x, int y) { + fLastMouseButtonActivityLine= toDocumentLineNumber(y); + } + + /** + * Adds the given mouse listener. + * + * @param listener the listener to be added + * @deprecated will be removed + * @since 2.0 + */ + public void addMouseListener(MouseListener listener) { + if (fCanvas != null && !fCanvas.isDisposed()) + fCanvas.addMouseListener(listener); + } + + /** + * Removes the given mouse listener. + * + * @param listener the listener to be removed + * @deprecated will be removed + * @since 2.0 + */ + public void removeMouseListener(MouseListener listener) { + if (fCanvas != null && !fCanvas.isDisposed()) + fCanvas.removeMouseListener(listener); + } + + /** + *

Setter for the field icon.

+ * + * @param icon a {@link org.eclipse.swt.graphics.Image} object. + */ + public void setIcon(Image icon) { + this.icon = icon; + redraw(); + } +} + diff --git a/eu.etaxonomy.taxeditor.navigation/src/main/java/eu/etaxonomy/taxeditor/navigation/navigator/TreeNodeDropAdapter.java b/eu.etaxonomy.taxeditor.navigation/src/main/java/eu/etaxonomy/taxeditor/navigation/navigator/TreeNodeDropAdapter.java index 448da0521..2dd550d23 100644 --- a/eu.etaxonomy.taxeditor.navigation/src/main/java/eu/etaxonomy/taxeditor/navigation/navigator/TreeNodeDropAdapter.java +++ b/eu.etaxonomy.taxeditor.navigation/src/main/java/eu/etaxonomy/taxeditor/navigation/navigator/TreeNodeDropAdapter.java @@ -14,37 +14,25 @@ import java.util.EnumSet; import java.util.HashSet; import java.util.Iterator; import java.util.Set; +import java.util.UUID; import org.apache.log4j.Logger; import org.eclipse.core.commands.operations.IUndoContext; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.dialogs.IconAndMessageDialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.util.LocalSelectionTransfer; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.TreeSelection; -import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerDropAdapter; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.DropTargetEvent; import org.eclipse.swt.dnd.TransferData; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.handlers.HandlerUtil; -import org.eclipse.ui.navigator.CommonDropAdapter; -import org.eclipse.ui.navigator.CommonDropAdapterAssistant; -import org.eclipse.ui.navigator.CommonViewer; import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper; import eu.etaxonomy.cdm.model.common.CdmBase; -import eu.etaxonomy.cdm.model.common.OrderedTermBase; -import eu.etaxonomy.cdm.model.common.TermBase; import eu.etaxonomy.cdm.model.taxon.Classification; import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode; import eu.etaxonomy.cdm.model.taxon.TaxonNode; import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD; -import eu.etaxonomy.taxeditor.editor.definedterm.DefinedTermEditor; import eu.etaxonomy.taxeditor.navigation.NavigationUtil; import eu.etaxonomy.taxeditor.navigation.navigator.operation.MoveTaxonOperation; import eu.etaxonomy.taxeditor.operation.AbstractPostOperation; @@ -67,9 +55,9 @@ public class TreeNodeDropAdapter extends ViewerDropAdapter implements IPostOpera protected TreeNodeDropAdapter(TaxonNavigatorViewer navigatorViewer) { super(navigatorViewer); this.navigatorViewer = navigatorViewer; - + } - + private final TaxonNavigatorViewer navigatorViewer; private static final Logger logger = Logger.getLogger(TreeNodeDropAdapter.class); @@ -77,9 +65,9 @@ public class TreeNodeDropAdapter extends ViewerDropAdapter implements IPostOpera public static final String ID = "eu.etaxonomy.taxeditor.navigation.navigator.dropassistant"; //$NON-NLS-1$ private static final EnumSet UPDATE = EnumSet.of(CRUD.UPDATE); - - - + + + /* (non-Javadoc) * @see org.eclipse.ui.navigator.CommonDropAdapterAssistant#handleDrop(org.eclipse.ui.navigator.CommonDropAdapter, org.eclipse.swt.dnd.DropTargetEvent, java.lang.Object) */ @@ -87,7 +75,7 @@ public class TreeNodeDropAdapter extends ViewerDropAdapter implements IPostOpera @Override public boolean performDrop(Object target) { - + if (target instanceof ITaxonTreeNode) { Set taxonNodes = getSelectedTaxa(); ITaxonTreeNode targetTreeNode = (ITaxonTreeNode) target; @@ -97,7 +85,7 @@ public class TreeNodeDropAdapter extends ViewerDropAdapter implements IPostOpera } if(taxonNodes != null) { if (taxonNodes.size() == 1){ - return moveTaxon(taxonNodes.iterator().next(), targetTreeNode); + return moveTaxon(taxonNodes, targetTreeNode); } else{ if( MessageDialog.openConfirm(null, "Moving taxon", "The operation move accepted taxon to other parent is available only for a single taxon.")){ return true; @@ -105,7 +93,7 @@ public class TreeNodeDropAdapter extends ViewerDropAdapter implements IPostOpera } } } - + return false; } @@ -135,9 +123,9 @@ public class TreeNodeDropAdapter extends ViewerDropAdapter implements IPostOpera @Override public boolean validateDrop(Object target, int operation, TransferData transferType) { - + if (target instanceof ITaxonTreeNode) { - + // check users permissions with target taxonnode and taxon if (target instanceof TaxonNode) { TaxonNode targetNode = (TaxonNode)target; @@ -187,7 +175,7 @@ public class TreeNodeDropAdapter extends ViewerDropAdapter implements IPostOpera * @param parentTaxon * @return */ - private boolean moveTaxon(TaxonNode taxonNode, ITaxonTreeNode targetITaxonTreeNode) { + private boolean moveTaxon(Set taxonNodes, ITaxonTreeNode targetITaxonTreeNode) { TaxonNavigator taxonNavigator; taxonNavigator = (TaxonNavigator) NavigationUtil.showView(TaxonNavigator.ID); @@ -203,17 +191,24 @@ public class TreeNodeDropAdapter extends ViewerDropAdapter implements IPostOpera } } + Iterator taxIterator = taxonNodes.iterator(); + Set uuids = new HashSet(); + TaxonNode node = null; + while(taxIterator.hasNext()){ + node = taxIterator.next(); + uuids.add(node.getUuid()); + } if (!PreferencesUtil.getSortNodesNaturally()){ IUndoContext workspaceUndoContext = NavigationUtil.getWorkbenchUndoContext(); if (workspaceUndoContext == null) { logger.error("Workspace undo context is null. DND operation cancelled"); return false; } - + AbstractPostOperation operation = new MoveTaxonOperation - ("Move Taxon", workspaceUndoContext, taxonNode, targetITaxonTreeNode, this, taxonNavigator, true); + ("Move Taxon", workspaceUndoContext, uuids, targetITaxonTreeNode, this, taxonNavigator, true); NavigationUtil.executeOperation(operation); - + logger.info("Moved taxa to new parent " + targetITaxonTreeNode); return true; }else{ @@ -227,11 +222,11 @@ public class TreeNodeDropAdapter extends ViewerDropAdapter implements IPostOpera logger.error("Workspace undo context is null. DND operation cancelled"); return false; } - + AbstractPostOperation operation = new MoveTaxonOperation - ("Move Taxon", workspaceUndoContext, taxonNode, targetITaxonTreeNode, this, taxonNavigator, true); + ("Move Taxon", workspaceUndoContext, uuids, targetITaxonTreeNode, this, taxonNavigator, true); NavigationUtil.executeOperation(operation); - + logger.info("Moved taxa to new parent " + targetITaxonTreeNode); return true; }else if (returnCode == 1){ @@ -240,18 +235,18 @@ public class TreeNodeDropAdapter extends ViewerDropAdapter implements IPostOpera logger.error("Workspace undo context is null. DND operation cancelled"); return false; } - + AbstractPostOperation operation = new MoveTaxonOperation - ("Move Taxon", workspaceUndoContext, taxonNode, targetITaxonTreeNode, this, taxonNavigator, false); + ("Move Taxon", workspaceUndoContext, uuids, targetITaxonTreeNode, this, taxonNavigator, false); NavigationUtil.executeOperation(operation); - + logger.info("Moved taxa to new parent " + targetITaxonTreeNode); return true; } else{ return false; } - - + + } } @@ -278,7 +273,7 @@ public class TreeNodeDropAdapter extends ViewerDropAdapter implements IPostOpera public void dragOver(DropTargetEvent event) { super.dragOver(event); event.feedback = DND.FEEDBACK_SELECT | DND.FEEDBACK_INSERT_AFTER; - + } - + } diff --git a/eu.etaxonomy.taxeditor.navigation/src/main/java/eu/etaxonomy/taxeditor/navigation/navigator/TreeNodeDropAdapterAssistant.java b/eu.etaxonomy.taxeditor.navigation/src/main/java/eu/etaxonomy/taxeditor/navigation/navigator/TreeNodeDropAdapterAssistant.java index 86eb9506f..cca66d57c 100644 --- a/eu.etaxonomy.taxeditor.navigation/src/main/java/eu/etaxonomy/taxeditor/navigation/navigator/TreeNodeDropAdapterAssistant.java +++ b/eu.etaxonomy.taxeditor.navigation/src/main/java/eu/etaxonomy/taxeditor/navigation/navigator/TreeNodeDropAdapterAssistant.java @@ -14,21 +14,18 @@ import java.util.EnumSet; import java.util.HashSet; import java.util.Iterator; import java.util.Set; +import java.util.UUID; import org.apache.log4j.Logger; import org.eclipse.core.commands.operations.IUndoContext; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; -import org.eclipse.jface.dialogs.IconAndMessageDialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.util.LocalSelectionTransfer; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.TreeSelection; import org.eclipse.swt.dnd.DropTargetEvent; import org.eclipse.swt.dnd.TransferData; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.handlers.HandlerUtil; import org.eclipse.ui.navigator.CommonDropAdapter; import org.eclipse.ui.navigator.CommonDropAdapterAssistant; @@ -69,7 +66,7 @@ public class TreeNodeDropAdapterAssistant extends CommonDropAdapterAssistant imp public IStatus handleDrop(CommonDropAdapter dropAdapter, DropTargetEvent dropTargetEvent, Object target) { - + if (target instanceof ITaxonTreeNode) { Set taxonNodes = getSelectedTaxa(); ITaxonTreeNode targetTreeNode = (ITaxonTreeNode) target; @@ -77,17 +74,17 @@ public class TreeNodeDropAdapterAssistant extends CommonDropAdapterAssistant imp targetTreeNode = ((Classification)targetTreeNode).getRootNode(); targetTreeNode = HibernateProxyHelper.deproxy(targetTreeNode, TaxonNode.class); } - if(taxonNodes != null) { - if (taxonNodes.size() == 1){ - return moveTaxon(taxonNodes.iterator().next(), targetTreeNode); - } else{ + //if(taxonNodes != null) { + if (taxonNodes.size() >= 1){ + return moveTaxon(taxonNodes, targetTreeNode); + /*} else{ if( MessageDialog.openConfirm(null, "Moving taxon", "The operation move accepted taxon to other parent is available only for a single taxon.")){ return null; } - } + }*/ } } - + return Status.CANCEL_STATUS; } @@ -168,7 +165,7 @@ public class TreeNodeDropAdapterAssistant extends CommonDropAdapterAssistant imp * @param parentTaxon * @return */ - private IStatus moveTaxon(TaxonNode taxonNode, ITaxonTreeNode targetITaxonTreeNode) { + private IStatus moveTaxon(Set taxonNodes, ITaxonTreeNode targetITaxonTreeNode) { TaxonNavigator taxonNavigator; taxonNavigator = (TaxonNavigator) NavigationUtil.showView(TaxonNavigator.ID); @@ -184,17 +181,24 @@ public class TreeNodeDropAdapterAssistant extends CommonDropAdapterAssistant imp } } + Iterator taxIterator = taxonNodes.iterator(); + Set uuids = new HashSet(); + TaxonNode node = null; + while(taxIterator.hasNext()){ + node = taxIterator.next(); + uuids.add(node.getUuid()); + } if (!PreferencesUtil.getSortNodesNaturally()){ IUndoContext workspaceUndoContext = NavigationUtil.getWorkbenchUndoContext(); if (workspaceUndoContext == null) { logger.error("Workspace undo context is null. DND operation cancelled"); return Status.CANCEL_STATUS; } - + AbstractPostOperation operation = new MoveTaxonOperation - ("Move Taxon", workspaceUndoContext, taxonNode, targetITaxonTreeNode, this, taxonNavigator, true); + ("Move Taxon", workspaceUndoContext, uuids, targetITaxonTreeNode, this, taxonNavigator, true); NavigationUtil.executeOperation(operation); - + logger.info("Moved taxa to new parent " + targetITaxonTreeNode); return Status.OK_STATUS; }else{ @@ -208,11 +212,11 @@ public class TreeNodeDropAdapterAssistant extends CommonDropAdapterAssistant imp logger.error("Workspace undo context is null. DND operation cancelled"); return Status.CANCEL_STATUS; } - + AbstractPostOperation operation = new MoveTaxonOperation - ("Move Taxon", workspaceUndoContext, taxonNode, targetITaxonTreeNode, this, taxonNavigator, true); + ("Move Taxon", workspaceUndoContext, uuids, targetITaxonTreeNode, this, taxonNavigator, true); NavigationUtil.executeOperation(operation); - + logger.info("Moved taxa to new parent " + targetITaxonTreeNode); return Status.OK_STATUS; }else if (returnCode == 1){ @@ -221,18 +225,18 @@ public class TreeNodeDropAdapterAssistant extends CommonDropAdapterAssistant imp logger.error("Workspace undo context is null. DND operation cancelled"); return Status.CANCEL_STATUS; } - + AbstractPostOperation operation = new MoveTaxonOperation - ("Move Taxon", workspaceUndoContext, taxonNode, targetITaxonTreeNode, this, taxonNavigator, false); + ("Move Taxon", workspaceUndoContext, uuids, targetITaxonTreeNode, this, taxonNavigator, false); NavigationUtil.executeOperation(operation); - + logger.info("Moved taxa to new parent " + targetITaxonTreeNode); return Status.OK_STATUS; } else{ return Status.CANCEL_STATUS; } - - + + } } diff --git a/eu.etaxonomy.taxeditor.navigation/src/main/java/eu/etaxonomy/taxeditor/navigation/navigator/handler/MoveTaxonHandler.java b/eu.etaxonomy.taxeditor.navigation/src/main/java/eu/etaxonomy/taxeditor/navigation/navigator/handler/MoveTaxonHandler.java index 4c84b0197..a761433ad 100644 --- a/eu.etaxonomy.taxeditor.navigation/src/main/java/eu/etaxonomy/taxeditor/navigation/navigator/handler/MoveTaxonHandler.java +++ b/eu.etaxonomy.taxeditor.navigation/src/main/java/eu/etaxonomy/taxeditor/navigation/navigator/handler/MoveTaxonHandler.java @@ -1,8 +1,8 @@ /** * Copyright (C) 2007 EDIT -* European Distributed Institute of Taxonomy +* European Distributed Institute of Taxonomy * http://www.e-taxonomy.eu -* +* * The contents of this file are subject to the Mozilla Public License Version 1.1 * See LICENSE.TXT at the top of this package for the full license terms. */ @@ -19,32 +19,21 @@ import java.util.UUID; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.expressions.EvaluationContext; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.TreeSelection; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorReference; import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.PartInitException; import org.eclipse.ui.handlers.HandlerUtil; -import eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration; -import eu.etaxonomy.cdm.api.service.ITaxonNodeService; import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper; import eu.etaxonomy.cdm.model.common.CdmBase; -import eu.etaxonomy.cdm.model.common.ITreeNode; -import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode; import eu.etaxonomy.cdm.model.taxon.TaxonNode; -import eu.etaxonomy.taxeditor.editor.TaxonEditorInput; import eu.etaxonomy.taxeditor.navigation.NavigationUtil; import eu.etaxonomy.taxeditor.navigation.navigator.TaxonNavigator; import eu.etaxonomy.taxeditor.navigation.navigator.operation.MoveTaxonOperation; import eu.etaxonomy.taxeditor.operation.AbstractPostOperation; import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled; import eu.etaxonomy.taxeditor.preference.PreferencesUtil; -import eu.etaxonomy.taxeditor.store.CdmStore; import eu.etaxonomy.taxeditor.ui.dialog.selection.TaxonNodeSelectionDialog; -import eu.etaxonomy.taxeditor.ui.dialog.selection.TaxonNodeSelectionNaturalOrderDialog; /** *

MoveTaxonHandler class.

@@ -61,35 +50,41 @@ public class MoveTaxonHandler extends AbstractHandler implements IPostOperationE * @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent) */ /** {@inheritDoc} */ - public Object execute(ExecutionEvent event) throws ExecutionException { + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { activePage = HandlerUtil.getActiveWorkbenchWindow(event).getActivePage(); TaxonNavigator taxonNavigator = (TaxonNavigator)NavigationUtil.showView(TaxonNavigator.ID); - + TreeSelection selection = (TreeSelection) HandlerUtil.getCurrentSelection(event); - + Iterator selectionIterator = selection.iterator(); - TaxonNode taxonNode = null; - UUID taxonNodeUUID = null; + Set taxonNodes = new HashSet(); + TaxonNode taxonNode= null; + Set taxonNodeUUIDs = new HashSet(); // do not show the current selection List excludeTaxa = new ArrayList(); - - if (selection.size() == 1){ + + //if (selection.size() == 1){ + + while (selectionIterator.hasNext()){ Object object = selectionIterator.next(); if(object instanceof TaxonNode){ - taxonNode = HibernateProxyHelper.deproxy(object,TaxonNode.class); - taxonNodeUUID = taxonNode.getUuid(); + taxonNode = HibernateProxyHelper.deproxy(object,TaxonNode.class); + taxonNodes.add(taxonNode); + taxonNodeUUIDs.add(taxonNode.getUuid()); excludeTaxa.add(taxonNode.getTaxon().getUuid()); } - } else{ + } + /*} else{ if( MessageDialog.openConfirm(HandlerUtil.getActiveShell(event), "Moving taxon", "The operation move accepted taxon to other parent is available only for a single taxon.")){ return null; } - } - - + }*/ + + // TaxonNode taxonNode = (TaxonNode) selection.getFirstElement(); - if (taxonNode != null){ - boolean moveToNewParent = true; + if (taxonNodes.size() >= 1){ + boolean moveToNewParent = true; if (PreferencesUtil.getSortNodesNaturally()){ if(!MessageDialog.openQuestion(null, "Target node", "The choosen target node should be the parent?")){ moveToNewParent = false; @@ -104,13 +99,13 @@ public class MoveTaxonHandler extends AbstractHandler implements IPostOperationE "changes in the parent taxon. Please save first."); return null; } - + AbstractPostOperation operation = new MoveTaxonOperation ("Move taxon to new parent", NavigationUtil.getUndoContext(), - taxonNode, parentTaxonNode, taxonNavigator, taxonNavigator, moveToNewParent); //$NON-NLS-1$ + taxonNodeUUIDs, parentTaxonNode, taxonNavigator, taxonNavigator, moveToNewParent); //$NON-NLS-1$ NavigationUtil.executeOperation(operation); taxonNavigator.refresh(); - + } } return null; @@ -120,7 +115,8 @@ public class MoveTaxonHandler extends AbstractHandler implements IPostOperationE * @see eu.etaxonomy.taxeditor.operations.IPostOperationEnabled#postOperation(eu.etaxonomy.cdm.model.common.CdmBase) */ /** {@inheritDoc} */ - public boolean postOperation(CdmBase objectAffectedByOperation) { + @Override + public boolean postOperation(CdmBase objectAffectedByOperation) { return true; } @@ -129,10 +125,11 @@ public class MoveTaxonHandler extends AbstractHandler implements IPostOperationE * * @return a boolean. */ - public boolean onComplete() { + @Override + public boolean onComplete() { return false; } - - - + + + } diff --git a/eu.etaxonomy.taxeditor.navigation/src/main/java/eu/etaxonomy/taxeditor/navigation/navigator/operation/MoveTaxonOperation.java b/eu.etaxonomy.taxeditor.navigation/src/main/java/eu/etaxonomy/taxeditor/navigation/navigator/operation/MoveTaxonOperation.java index bd2b57db5..830d572a4 100644 --- a/eu.etaxonomy.taxeditor.navigation/src/main/java/eu/etaxonomy/taxeditor/navigation/navigator/operation/MoveTaxonOperation.java +++ b/eu.etaxonomy.taxeditor.navigation/src/main/java/eu/etaxonomy/taxeditor/navigation/navigator/operation/MoveTaxonOperation.java @@ -9,9 +9,6 @@ package eu.etaxonomy.taxeditor.navigation.navigator.operation; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; import java.util.Set; import java.util.UUID; @@ -22,13 +19,10 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; -import eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration; import eu.etaxonomy.cdm.api.conversation.IConversationEnabled; import eu.etaxonomy.cdm.api.service.ITaxonNodeService; import eu.etaxonomy.cdm.api.service.UpdateResult; import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode; -import eu.etaxonomy.cdm.model.taxon.IllegalAncestryException; -import eu.etaxonomy.cdm.model.taxon.TaxonNode; import eu.etaxonomy.taxeditor.model.MessagingUtils; import eu.etaxonomy.taxeditor.operation.AbstractPersistentPostOperation; import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled; @@ -46,14 +40,14 @@ public class MoveTaxonOperation extends AbstractPersistentPostOperation { /** * A reference to the new taxonomical parent. */ - private ITaxonTreeNode newParentTreeNode; + private final ITaxonTreeNode newParentTreeNode; /** * A reference to the former taxonomical parents */ //private Map oldParentTreeNodes; - private TaxonNode taxonNode; - private boolean moveToParentNode; + private final Set taxonNodesUuid; + private final boolean moveToParentNode; /** *

Constructor for MoveTaxonOperation.

* @@ -65,18 +59,18 @@ public class MoveTaxonOperation extends AbstractPersistentPostOperation { * @param conversationEnabled a {@link eu.etaxonomy.cdm.api.conversation.IConversationEnabled} object. */ public MoveTaxonOperation(String label, IUndoContext undoContext, - TaxonNode taxonNodeToMove, ITaxonTreeNode newParentTreeNode, IPostOperationEnabled postOperationEnabled, IConversationEnabled conversationEnabled, boolean moveToParentNode) { + Set taxonNodesUUIDToMove, ITaxonTreeNode newParentTreeNode, IPostOperationEnabled postOperationEnabled, IConversationEnabled conversationEnabled, boolean moveToParentNode) { super(label, undoContext, postOperationEnabled, conversationEnabled); - - this.taxonNode = taxonNodeToMove; + + this.taxonNodesUuid = taxonNodesUUIDToMove; /*for (TaxonNode node:taxonNodes){ this.taxonNodes.add(service.load(node.getUuid())); }*/ - + this.newParentTreeNode = newParentTreeNode; this.moveToParentNode = moveToParentNode; // Save old parent ITaxonTreeNodes for undo - + //this.parentNode = taxonNode.getParent(); } @@ -90,13 +84,13 @@ public class MoveTaxonOperation extends AbstractPersistentPostOperation { bind(); monitor.worked(20); - UpdateResult result = CdmStore.getService(ITaxonNodeService.class).moveTaxonNode(this.taxonNode.getUuid(),newParentTreeNode.getUuid(), moveToParentNode); + UpdateResult result = CdmStore.getService(ITaxonNodeService.class).moveTaxonNodes(this.taxonNodesUuid,newParentTreeNode.getUuid()); // try { // for (TaxonNode taxonNode : taxonNodes){ // TaxonNode newTaxonNode = newParentTreeNode.addChildNode(taxonNode, // newParentTreeNode.getReference(), newParentTreeNode.getMicroReference()); // //taxonNodes.add(newTaxonNode); -// +// // monitor.worked(2); // } // } catch(IllegalAncestryException e) { diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/section/classification/TaxonNodeDetailElement.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/section/classification/TaxonNodeDetailElement.java index 2f148a8bc..bd12ab644 100644 --- a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/section/classification/TaxonNodeDetailElement.java +++ b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/section/classification/TaxonNodeDetailElement.java @@ -174,6 +174,7 @@ public class TaxonNodeDetailElement extends AbstractCdmDetailElement