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