fix #7111: synchronize sync butoon of navigator with attribute linkWithTaxon
[taxeditor.git] / eu.etaxonomy.taxeditor.navigation / src / main / java / eu / etaxonomy / taxeditor / navigation / navigator / TreeNodeDropAdapter.java
1 /**
2 * Copyright (C) 2015 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9
10 package eu.etaxonomy.taxeditor.navigation.navigator;
11
12 import java.util.EnumSet;
13 import java.util.HashSet;
14 import java.util.Iterator;
15 import java.util.Set;
16
17 import org.apache.log4j.Logger;
18 import org.eclipse.jface.dialogs.MessageDialog;
19 import org.eclipse.jface.util.LocalSelectionTransfer;
20 import org.eclipse.jface.viewers.ISelection;
21 import org.eclipse.jface.viewers.TreeSelection;
22 import org.eclipse.jface.viewers.ViewerDropAdapter;
23 import org.eclipse.swt.dnd.DND;
24 import org.eclipse.swt.dnd.DropTargetEvent;
25 import org.eclipse.swt.dnd.TransferData;
26
27 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
28 import eu.etaxonomy.cdm.model.common.CdmBase;
29 import eu.etaxonomy.cdm.model.taxon.Classification;
30 import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
31 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
32 import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
33 import eu.etaxonomy.taxeditor.navigation.l10n.Messages;
34 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
35 import eu.etaxonomy.taxeditor.store.CdmStore;
36
37 /**
38 * <p>TreeNodeDropAdapter class.</p>
39 *
40 * @author k.luther
41 * @date 02.06.2015
42 */
43 public class TreeNodeDropAdapter extends ViewerDropAdapter implements IPostOperationEnabled {
44
45 protected static final String TREE_NODE_DROP_ADAPTER_UNSAVED_PARENT_MESSAGE = Messages.TreeNodeDropAdapter_UNSAVED_PARENT_MESSAGE;
46 protected static final String TREE_NODE_DROP_ADAPTER_UNSAVED_PARENT = Messages.TreeNodeDropAdapter_UNSAVED_PARENT;
47 protected static final String TREE_NODE_DROP_ADAPTER_MOVE_TAXON = Messages.TreeNodeDropAdapter_MOVE_TAXON;
48 protected static final String TREE_NODE_DROP_ADAPTER_CANCEL = Messages.TreeNodeDropAdapter_CANCEL;
49 protected static final String TREE_NODE_DROP_ADAPTER_BEHIND = Messages.TreeNodeDropAdapter_BEHIND;
50 protected static final String TREE_NODE_DROP_ADAPTER_CHILD = Messages.TreeNodeDropAdapter_CHILD;
51 protected static final String DO_YOU_WANT_TO_MOVE_THE_TAXONNODE_AS_CHILD_OR_BEHIND_THE_TARGET_NODE = Messages.TreeNodeDropAdapter_MOVE_BEHIND;
52 protected static final String TARGET_NODE = Messages.TreeNodeDropAdapter_TARGET_NODE;
53
54 private static final Logger logger = Logger.getLogger(TreeNodeDropAdapter.class);
55
56 private final TaxonNavigatorViewer navigatorViewer;
57
58 /**
59 * @param viewer
60 */
61 protected TreeNodeDropAdapter(TaxonNavigatorViewer navigatorViewer) {
62 super(navigatorViewer);
63 this.navigatorViewer = navigatorViewer;
64 }
65
66
67 /** Constant <code>ID="eu.etaxonomy.taxeditor.navigation.navig"{trunked}</code> */
68 public static final String ID = "eu.etaxonomy.taxeditor.navigation.navigator.dropassistant"; //$NON-NLS-1$
69
70 private static final EnumSet<CRUD> UPDATE = EnumSet.of(CRUD.UPDATE);
71
72 public enum MovingType{
73 CHILD, PREVIOUS, BEHIND
74 }
75
76
77 /** {@inheritDoc} */
78 @Override
79 public boolean performDrop(Object target) {
80
81
82 if (target instanceof ITaxonTreeNode) {
83 Set<TaxonNode> taxonNodes = getSelectedTaxa();
84 ITaxonTreeNode targetTreeNode = (ITaxonTreeNode) target;
85 if (targetTreeNode instanceof Classification){
86 targetTreeNode = ((Classification)targetTreeNode).getRootNode();
87 targetTreeNode = HibernateProxyHelper.deproxy(targetTreeNode, TaxonNode.class);
88 }
89 if(taxonNodes != null) {
90 if (taxonNodes.size() == 1){
91 return moveTaxon(taxonNodes, targetTreeNode);
92 } else{
93 if( MessageDialog.openConfirm(null, Messages.TreeNodeDropAdapter_MOVING, Messages.TreeNodeDropAdapter_MOVING_MESSAGE)){
94 return true;
95 }
96 }
97 }
98 }
99
100 return false;
101 }
102
103 private Set<TaxonNode> getSelectedTaxa(){
104 HashSet<TaxonNode> taxonNodes = new HashSet<TaxonNode>();
105
106 ISelection selection = LocalSelectionTransfer.getTransfer().getSelection();
107 if (selection instanceof TreeSelection) {
108
109 Iterator<?> selectionIterator = ((TreeSelection) selection).iterator();
110
111 while (selectionIterator.hasNext()){
112 Object object = selectionIterator.next();
113 if(object instanceof TaxonNode){
114 TaxonNode taxonNode = (TaxonNode) object;
115 taxonNodes.add(taxonNode);
116 }
117 }
118 }
119 return taxonNodes.size() > 0 ? taxonNodes : null;
120 }
121
122 /** {@inheritDoc} */
123 @Override
124 public boolean validateDrop(Object target, int operation,
125 TransferData transferType) {
126
127 if (target instanceof ITaxonTreeNode) {
128
129 // check users permissions with target taxonnode and taxon
130 if (target instanceof TaxonNode) {
131 TaxonNode targetNode = (TaxonNode)target;
132 boolean hasTargetNodePermission = CdmStore.currentAuthentiationHasPermission(targetNode, UPDATE);
133 boolean hasTargetTaxonPermission = targetNode.getTaxon() == null ?
134 true :
135 CdmStore.currentAuthentiationHasPermission(targetNode.getTaxon(), UPDATE);
136
137 if(logger.isDebugEnabled()){
138 logger.debug("target: " + targetNode.getTaxon() == null? "-" : targetNode.getTaxon().getTitleCache()); //$NON-NLS-1$
139 }
140
141 if(!hasTargetNodePermission || ! hasTargetNodePermission){
142 if(logger.isDebugEnabled()){
143 logger.debug("CANCEL_STATUS for target node: " + hasTargetNodePermission + " " + hasTargetTaxonPermission + " "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
144 }
145 return false;
146 }
147 }
148
149 // do not allow to drop onto itself and
150 // check users permissions with all selected taxon nodes and taxa
151 for(TaxonNode taxonNode : getSelectedTaxa()){
152 if (logger.isDebugEnabled()){
153 logger.debug("selectedTaxa: " + taxonNode.getTaxon() == null? "-" : taxonNode.getTaxon().getTitleCache()); //$NON-NLS-1$
154 }
155 boolean isSameTaxonNode = taxonNode.equals(target);
156 boolean hasTaxonNodePermission = CdmStore.currentAuthentiationHasPermission(taxonNode, UPDATE);
157 boolean hasTaxonPermission = taxonNode.getTaxon() == null ?
158 true :
159 CdmStore.currentAuthentiationHasPermission(taxonNode.getTaxon(), UPDATE);CdmStore.currentAuthentiationHasPermission(taxonNode.getTaxon(), UPDATE);
160 if (
161 isSameTaxonNode
162 || !hasTaxonNodePermission
163 || !hasTaxonPermission
164 ) {
165 if(logger.isDebugEnabled()){
166 logger.debug("CANCEL_STATUS for selected " + isSameTaxonNode + Messages.TreeNodeDropAdapter_10 + hasTaxonNodePermission + " " + hasTaxonPermission + " "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
167 }
168 return false;
169 }
170 }
171 logger.debug("OK_STATUS"); //$NON-NLS-1$
172 return true;
173 }
174 logger.debug("CANCEL_STATUS"); //$NON-NLS-1$
175 return false;
176 }
177
178
179 /**
180 * @param childTaxonNode
181 * @param parentTaxon
182 * @return
183 */
184 private boolean moveTaxon(Set<TaxonNode> taxonNodes, ITaxonTreeNode targetITaxonTreeNode) {
185
186 // TaxonNavigator taxonNavigator;
187 // taxonNavigator = (TaxonNavigator) NavigationUtil.showView(TaxonNavigator.ID);
188 //
189 // if(targetITaxonTreeNode instanceof TaxonNode){
190 //
191 // TaxonNode targetTaxonNode = (TaxonNode) targetITaxonTreeNode;
192 // // Make sure parent taxon does not have unsaved changes
193 //// if (NavigationUtil.isDirty(targetTaxonNode)){
194 //// MessageDialog.openWarning(NavigationUtil.getShell(), TREE_NODE_DROP_ADAPTER_UNSAVED_PARENT, TREE_NODE_DROP_ADAPTER_UNSAVED_PARENT_MESSAGE);
195 //// return false;
196 //// }
197 //
198 // }
199 // Iterator<TaxonNode> taxIterator = taxonNodes.iterator();
200 // Set<UUID> uuids = new HashSet<UUID>();
201 // TaxonNode node = null;
202 // while(taxIterator.hasNext()){
203 // node = taxIterator.next();
204 // uuids.add(node.getUuid());
205 // }
206 // if (!PreferencesUtil.getSortNodesNaturally()){
207 // IUndoContext workspaceUndoContext = NavigationUtil.getWorkbenchUndoContext();
208 // if (workspaceUndoContext == null) {
209 // logger.error("Workspace undo context is null. DND operation cancelled"); //$NON-NLS-1$
210 // return false;
211 // }
212 //
213 // AbstractPostOperation<?> operation = new MoveTaxonOperation
214 // (TREE_NODE_DROP_ADAPTER_MOVE_TAXON, workspaceUndoContext, uuids, targetITaxonTreeNode, this, taxonNavigator, MovingType.CHILD);
215 // NavigationUtil.executeOperation(operation);
216 //
217 // logger.info("Moved taxa to new parent " + targetITaxonTreeNode); //$NON-NLS-1$
218 // return true;
219 // }else{
220 // String[] buttonLables = {TREE_NODE_DROP_ADAPTER_CHILD, TREE_NODE_DROP_ADAPTER_BEHIND,TREE_NODE_DROP_ADAPTER_CANCEL};
221 // MessageDialog dialog = new MessageDialog(null, TARGET_NODE, null, DO_YOU_WANT_TO_MOVE_THE_TAXONNODE_AS_CHILD_OR_BEHIND_THE_TARGET_NODE, MessageDialog.QUESTION_WITH_CANCEL, buttonLables, 0);
222 // dialog.open();
223 // int returnCode = dialog.getReturnCode();
224 // if (returnCode == 0){
225 // IUndoContext workspaceUndoContext = NavigationUtil.getWorkbenchUndoContext();
226 // if (workspaceUndoContext == null) {
227 // logger.error("Workspace undo context is null. DND operation cancelled"); //$NON-NLS-1$
228 // return false;
229 // }
230 //
231 // AbstractPostOperation<?> operation = new MoveTaxonOperation
232 // (TREE_NODE_DROP_ADAPTER_MOVE_TAXON, workspaceUndoContext, uuids, targetITaxonTreeNode, this, taxonNavigator, MovingType.CHILD);
233 // NavigationUtil.executeOperation(operation);
234 //
235 // logger.info("Moved taxa to new parent " + targetITaxonTreeNode); //$NON-NLS-1$
236 // return true;
237 // }else if (returnCode == 1){
238 // IUndoContext workspaceUndoContext = NavigationUtil.getWorkbenchUndoContext();
239 // if (workspaceUndoContext == null) {
240 // logger.error("Workspace undo context is null. DND operation cancelled"); //$NON-NLS-1$
241 // return false;
242 // }
243 // TaxonNode targetNode = (TaxonNode) targetITaxonTreeNode;
244 //
245 // AbstractPostOperation<?> operation = new MoveTaxonOperation
246 // (TREE_NODE_DROP_ADAPTER_MOVE_TAXON, workspaceUndoContext, uuids, targetNode, this, taxonNavigator, MovingType.PREVIOUS);
247 // NavigationUtil.executeOperation(operation);
248 //
249 // logger.info("Moved taxa to new parent " + targetITaxonTreeNode); //$NON-NLS-1$
250 // return true;
251 // }
252 //// } else if (returnCode == 2){
253 //// IUndoContext workspaceUndoContext = NavigationUtil.getWorkbenchUndoContext();
254 //// if (workspaceUndoContext == null) {
255 //// logger.error("Workspace undo context is null. DND operation cancelled");
256 //// return false;
257 //// }
258 //// TaxonNode targetNode = (TaxonNode) targetITaxonTreeNode;
259 ////
260 //// AbstractPostOperation operation = new MoveTaxonOperation
261 //// ("Move Taxon", workspaceUndoContext, uuids, targetNode, this, taxonNavigator, MovingType.BEHIND);
262 //// NavigationUtil.executeOperation(operation);
263 ////
264 //// logger.info("Moved taxa to new parent " + targetITaxonTreeNode);
265 //// return true;
266 //// }
267 // else{
268 return false;
269 // }
270 //
271 //
272 // }
273 }
274
275 /** {@inheritDoc} */
276 @Override
277 public boolean postOperation(CdmBase objectAffectedByOperation) {
278 return true;
279 }
280
281 /**
282 * <p>onComplete</p>
283 *
284 * @return a boolean.
285 */
286 @Override
287 public boolean onComplete() {
288 // TODO Auto-generated method stub
289 return false;
290 }
291 @Override
292 public void dragOver(DropTargetEvent event) {
293 super.dragOver(event);
294 event.feedback = DND.FEEDBACK_SELECT | DND.FEEDBACK_INSERT_AFTER;
295
296 }
297
298 }