Merge branch 'develop' of https://dev.e-taxonomy.eu/git/taxeditor into actualBranch
[taxeditor.git] / eu.etaxonomy.taxeditor.navigation / src / main / java / eu / etaxonomy / taxeditor / navigation / navigator / TreeNodeDropAdapterAssistant.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10
11 package eu.etaxonomy.taxeditor.navigation.navigator;
12
13 import java.util.EnumSet;
14 import java.util.HashSet;
15 import java.util.Iterator;
16 import java.util.Set;
17
18 import org.apache.log4j.Logger;
19 import org.eclipse.core.commands.operations.IUndoContext;
20 import org.eclipse.core.runtime.IStatus;
21 import org.eclipse.core.runtime.Status;
22 import org.eclipse.jface.dialogs.IconAndMessageDialog;
23 import org.eclipse.jface.dialogs.MessageDialog;
24 import org.eclipse.jface.util.LocalSelectionTransfer;
25 import org.eclipse.jface.viewers.ISelection;
26 import org.eclipse.jface.viewers.TreeSelection;
27 import org.eclipse.swt.dnd.DropTargetEvent;
28 import org.eclipse.swt.dnd.TransferData;
29 import org.eclipse.swt.graphics.Image;
30 import org.eclipse.swt.widgets.Shell;
31 import org.eclipse.ui.handlers.HandlerUtil;
32 import org.eclipse.ui.navigator.CommonDropAdapter;
33 import org.eclipse.ui.navigator.CommonDropAdapterAssistant;
34
35 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
36 import eu.etaxonomy.cdm.model.common.CdmBase;
37 import eu.etaxonomy.cdm.model.taxon.Classification;
38 import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
39 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
40 import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
41 import eu.etaxonomy.taxeditor.navigation.NavigationUtil;
42 import eu.etaxonomy.taxeditor.navigation.navigator.operation.MoveTaxonOperation;
43 import eu.etaxonomy.taxeditor.operation.AbstractPostOperation;
44 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
45 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
46 import eu.etaxonomy.taxeditor.store.CdmStore;
47
48 /**
49 * <p>TaxonNodeDropAdapterAssistant class.</p>
50 *
51 * @author p.ciardelli
52 * @created 03.06.2009
53 * @version 1.0
54 */
55 public class TreeNodeDropAdapterAssistant extends CommonDropAdapterAssistant implements IPostOperationEnabled {
56
57 private static final Logger logger = Logger.getLogger(TreeNodeDropAdapterAssistant.class);
58
59 /** Constant <code>ID="eu.etaxonomy.taxeditor.navigation.navig"{trunked}</code> */
60 public static final String ID = "eu.etaxonomy.taxeditor.navigation.navigator.dropassistant"; //$NON-NLS-1$
61
62 private static final EnumSet<CRUD> UPDATE = EnumSet.of(CRUD.UPDATE);
63
64 /* (non-Javadoc)
65 * @see org.eclipse.ui.navigator.CommonDropAdapterAssistant#handleDrop(org.eclipse.ui.navigator.CommonDropAdapter, org.eclipse.swt.dnd.DropTargetEvent, java.lang.Object)
66 */
67 /** {@inheritDoc} */
68 @Override
69 public IStatus handleDrop(CommonDropAdapter dropAdapter,
70 DropTargetEvent dropTargetEvent, Object target) {
71
72
73 if (target instanceof ITaxonTreeNode) {
74 Set<TaxonNode> taxonNodes = getSelectedTaxa();
75 ITaxonTreeNode targetTreeNode = (ITaxonTreeNode) target;
76 if (targetTreeNode instanceof Classification){
77 targetTreeNode = ((Classification)targetTreeNode).getRootNode();
78 targetTreeNode = HibernateProxyHelper.deproxy(targetTreeNode, TaxonNode.class);
79 }
80 if(taxonNodes != null) {
81 if (taxonNodes.size() == 1){
82 return moveTaxon(taxonNodes.iterator().next(), targetTreeNode);
83 } else{
84 if( MessageDialog.openConfirm(null, "Moving taxon", "The operation move accepted taxon to other parent is available only for a single taxon.")){
85 return null;
86 }
87 }
88 }
89 }
90
91 return Status.CANCEL_STATUS;
92 }
93
94 private Set<TaxonNode> getSelectedTaxa(){
95 HashSet<TaxonNode> taxonNodes = new HashSet<TaxonNode>();
96
97 ISelection selection = LocalSelectionTransfer.getTransfer().getSelection();
98 if (selection instanceof TreeSelection) {
99
100 Iterator selectionIterator = ((TreeSelection) selection).iterator();
101
102 while (selectionIterator.hasNext()){
103 Object object = selectionIterator.next();
104 if(object instanceof TaxonNode){
105 TaxonNode taxonNode = (TaxonNode) object;
106 taxonNodes.add(taxonNode);
107 }
108 }
109 }
110 return taxonNodes.size() > 0 ? taxonNodes : null;
111 }
112
113 /* (non-Javadoc)
114 * @see org.eclipse.ui.navigator.CommonDropAdapterAssistant#validateDrop(java.lang.Object, int, org.eclipse.swt.dnd.TransferData)
115 */
116 /** {@inheritDoc} */
117 @Override
118 public IStatus validateDrop(Object target, int operation,
119 TransferData transferType) {
120 if (target instanceof ITaxonTreeNode) {
121
122 // check users permissions with target taxonnode and taxon
123 if (target instanceof TaxonNode) {
124 TaxonNode targetNode = (TaxonNode)target;
125 Boolean hasTargetNodePermission = CdmStore.currentAuthentiationHasPermission(targetNode, UPDATE);
126 Boolean hasTargetTaxonPermission = CdmStore.currentAuthentiationHasPermission(targetNode.getTaxon(), UPDATE);
127
128 if(logger.isDebugEnabled()){
129 logger.debug("target: " + targetNode.getTaxon().getTitleCache());
130 }
131
132 if(!hasTargetNodePermission || ! hasTargetNodePermission){
133 if(logger.isDebugEnabled()){
134 logger.debug("CANCEL_STATUS for target node: " + hasTargetNodePermission.toString() + " " + hasTargetTaxonPermission.toString() + " ");
135 }
136 return Status.CANCEL_STATUS;
137 }
138 }
139
140 // do not allow to drop onto itself and
141 // check users permissions with all selected taxon nodes and taxa
142 for(TaxonNode taxonNode : getSelectedTaxa()){
143 logger.debug("selectedTaxa: " + taxonNode.getTaxon().getTitleCache());
144 Boolean isSameTaxonNode = taxonNode.equals(target);
145 Boolean hasTaxonNodePermission = CdmStore.currentAuthentiationHasPermission(taxonNode, UPDATE);
146 Boolean hasTaxonPermission = CdmStore.currentAuthentiationHasPermission(taxonNode.getTaxon(), UPDATE);
147 if (
148 isSameTaxonNode
149 || !hasTaxonNodePermission
150 || !hasTaxonPermission
151 ) {
152 if(logger.isDebugEnabled()){
153 logger.debug("CANCEL_STATUS for selected " + isSameTaxonNode.toString() + " " + hasTaxonNodePermission.toString() + " " + hasTaxonPermission.toString() + " ");
154 }
155 return Status.CANCEL_STATUS;
156 }
157 }
158 logger.debug("OK_STATUS");
159 return Status.OK_STATUS;
160 }
161 logger.debug("CANCEL_STATUS");
162 return Status.CANCEL_STATUS;
163 }
164
165
166 /**
167 * @param childTaxonNode
168 * @param parentTaxon
169 * @return
170 */
171 private IStatus moveTaxon(TaxonNode taxonNode, ITaxonTreeNode targetITaxonTreeNode) {
172
173 TaxonNavigator taxonNavigator;
174 taxonNavigator = (TaxonNavigator) NavigationUtil.showView(TaxonNavigator.ID);
175
176 if(targetITaxonTreeNode instanceof TaxonNode){
177
178 TaxonNode targetTaxonNode = (TaxonNode) targetITaxonTreeNode;
179 // Make sure parent taxon does not have unsaved changes
180 if (NavigationUtil.isDirty(targetTaxonNode)){
181 MessageDialog.openWarning(NavigationUtil.getShell(), "Unsaved Parent Taxon", "There are unsaved " +
182 "changes in the parent taxon. Pleas save first.");
183 return Status.CANCEL_STATUS;
184 }
185
186 }
187 if (!PreferencesUtil.getSortNodesNaturally()){
188 IUndoContext workspaceUndoContext = NavigationUtil.getWorkbenchUndoContext();
189 if (workspaceUndoContext == null) {
190 logger.error("Workspace undo context is null. DND operation cancelled");
191 return Status.CANCEL_STATUS;
192 }
193
194 AbstractPostOperation operation = new MoveTaxonOperation
195 ("Move Taxon", workspaceUndoContext, taxonNode, targetITaxonTreeNode, this, taxonNavigator, true);
196 NavigationUtil.executeOperation(operation);
197
198 logger.info("Moved taxa to new parent " + targetITaxonTreeNode);
199 return Status.OK_STATUS;
200 }else{
201 String[] buttonLables = {"Parent", "Predecessor", "Cancel"};
202 MessageDialog dialog = new MessageDialog(null, "Target node", null, "Do you want to use the target node as parent or do you want to move the taxon below the target.", MessageDialog.QUESTION_WITH_CANCEL, buttonLables, 0);
203 dialog.open();
204 int returnCode = dialog.getReturnCode();
205 if (returnCode == 0){
206 IUndoContext workspaceUndoContext = NavigationUtil.getWorkbenchUndoContext();
207 if (workspaceUndoContext == null) {
208 logger.error("Workspace undo context is null. DND operation cancelled");
209 return Status.CANCEL_STATUS;
210 }
211
212 AbstractPostOperation operation = new MoveTaxonOperation
213 ("Move Taxon", workspaceUndoContext, taxonNode, targetITaxonTreeNode, this, taxonNavigator, true);
214 NavigationUtil.executeOperation(operation);
215
216 logger.info("Moved taxa to new parent " + targetITaxonTreeNode);
217 return Status.OK_STATUS;
218 }else if (returnCode == 1){
219 IUndoContext workspaceUndoContext = NavigationUtil.getWorkbenchUndoContext();
220 if (workspaceUndoContext == null) {
221 logger.error("Workspace undo context is null. DND operation cancelled");
222 return Status.CANCEL_STATUS;
223 }
224
225 AbstractPostOperation operation = new MoveTaxonOperation
226 ("Move Taxon", workspaceUndoContext, taxonNode, targetITaxonTreeNode, this, taxonNavigator, false);
227 NavigationUtil.executeOperation(operation);
228
229 logger.info("Moved taxa to new parent " + targetITaxonTreeNode);
230 return Status.OK_STATUS;
231 } else{
232 return Status.CANCEL_STATUS;
233 }
234
235
236 }
237 }
238
239 /* (non-Javadoc)
240 * @see eu.etaxonomy.taxeditor.operations.IPostOperationEnabled#postOperation(eu.etaxonomy.cdm.model.common.CdmBase)
241 */
242 /** {@inheritDoc} */
243 @Override
244 public boolean postOperation(CdmBase objectAffectedByOperation) {
245 return true;
246 }
247
248 /**
249 * <p>onComplete</p>
250 *
251 * @return a boolean.
252 */
253 @Override
254 public boolean onComplete() {
255 // TODO Auto-generated method stub
256 return false;
257 }
258
259 }