Project

General

Profile

Download (11.5 KB) Statistics
| Branch: | Tag: | Revision:
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
import java.util.UUID;
17

    
18
import org.apache.log4j.Logger;
19
import org.eclipse.core.commands.operations.IUndoContext;
20
import org.eclipse.jface.dialogs.MessageDialog;
21
import org.eclipse.jface.util.LocalSelectionTransfer;
22
import org.eclipse.jface.viewers.ISelection;
23
import org.eclipse.jface.viewers.TreeSelection;
24
import org.eclipse.jface.viewers.ViewerDropAdapter;
25
import org.eclipse.swt.dnd.DND;
26
import org.eclipse.swt.dnd.DropTargetEvent;
27
import org.eclipse.swt.dnd.TransferData;
28

    
29
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
30
import eu.etaxonomy.cdm.model.common.CdmBase;
31
import eu.etaxonomy.cdm.model.taxon.Classification;
32
import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
33
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
34
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
35
import eu.etaxonomy.taxeditor.navigation.NavigationUtil;
36
import eu.etaxonomy.taxeditor.navigation.l10n.Messages;
37
import eu.etaxonomy.taxeditor.navigation.navigator.operation.MoveTaxonOperation;
38
import eu.etaxonomy.taxeditor.operation.AbstractPostOperation;
39
import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
40
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
41
import eu.etaxonomy.taxeditor.store.CdmStore;
42

    
43
/**
44
 * <p>TreeNodeDropAdapter class.</p>
45
 *
46
 * @author k.luther
47
 * @date 02.06.2015
48
 */
49
public class TreeNodeDropAdapter extends ViewerDropAdapter implements IPostOperationEnabled {
50

    
51
    protected static final String TREE_NODE_DROP_ADAPTER_UNSAVED_PARENT_MESSAGE = Messages.TreeNodeDropAdapter_UNSAVED_PARENT_MESSAGE;
52
    protected static final String TREE_NODE_DROP_ADAPTER_UNSAVED_PARENT = Messages.TreeNodeDropAdapter_UNSAVED_PARENT;
53
    protected static final String TREE_NODE_DROP_ADAPTER_MOVE_TAXON = Messages.TreeNodeDropAdapter_MOVE_TAXON;
54
    protected static final String TREE_NODE_DROP_ADAPTER_CANCEL = Messages.TreeNodeDropAdapter_CANCEL;
55
    protected static final String TREE_NODE_DROP_ADAPTER_BEHIND = Messages.TreeNodeDropAdapter_BEHIND;
56
    protected static final String TREE_NODE_DROP_ADAPTER_CHILD = Messages.TreeNodeDropAdapter_CHILD;
57
    protected static final String DO_YOU_WANT_TO_MOVE_THE_TAXONNODE_AS_CHILD_OR_BEHIND_THE_TARGET_NODE = Messages.TreeNodeDropAdapter_MOVE_BEHIND;
58
    protected static final String TARGET_NODE = Messages.TreeNodeDropAdapter_TARGET_NODE;
59

    
60
    private static final Logger logger = Logger.getLogger(TreeNodeDropAdapter.class);
61

    
62
	private final TaxonNavigatorViewer navigatorViewer;
63

    
64
	/**
65
	 * @param viewer
66
	 */
67
	protected TreeNodeDropAdapter(TaxonNavigatorViewer navigatorViewer) {
68
		super(navigatorViewer);
69
		this.navigatorViewer = navigatorViewer;
70
	}
71

    
72

    
73
	/** Constant <code>ID="eu.etaxonomy.taxeditor.navigation.navig"{trunked}</code> */
74
	public static final String ID = "eu.etaxonomy.taxeditor.navigation.navigator.dropassistant"; //$NON-NLS-1$
75

    
76
	private static final EnumSet<CRUD> UPDATE = EnumSet.of(CRUD.UPDATE);
77

    
78
	public enum MovingType{
79
	    CHILD, PREVIOUS, BEHIND
80
	}
81

    
82

    
83
	/** {@inheritDoc} */
84
	@Override
85
	public boolean performDrop(Object target) {
86

    
87

    
88
		if (target instanceof ITaxonTreeNode) {
89
			Set<TaxonNode> taxonNodes = getSelectedTaxa();
90
			ITaxonTreeNode targetTreeNode = (ITaxonTreeNode) target;
91
			if (targetTreeNode instanceof Classification){
92
				targetTreeNode = ((Classification)targetTreeNode).getRootNode();
93
				targetTreeNode = HibernateProxyHelper.deproxy(targetTreeNode, TaxonNode.class);
94
			}
95
			if(taxonNodes != null) {
96
				if (taxonNodes.size() == 1){
97
					return moveTaxon(taxonNodes, targetTreeNode);
98
				} else{
99
					if( MessageDialog.openConfirm(null, Messages.TreeNodeDropAdapter_MOVING, Messages.TreeNodeDropAdapter_MOVING_MESSAGE)){
100
						return true;
101
					}
102
				}
103
            }
104
		}
105

    
106
		return false;
107
	}
108

    
109
	private Set<TaxonNode> getSelectedTaxa(){
110
		HashSet<TaxonNode> taxonNodes = new HashSet<TaxonNode>();
111

    
112
		ISelection selection = LocalSelectionTransfer.getTransfer().getSelection();
113
		if (selection instanceof TreeSelection) {
114

    
115
			Iterator<?> selectionIterator = ((TreeSelection) selection).iterator();
116

    
117
			while (selectionIterator.hasNext()){
118
				Object object = selectionIterator.next();
119
				if(object instanceof TaxonNode){
120
					TaxonNode taxonNode = (TaxonNode) object;
121
					taxonNodes.add(taxonNode);
122
				}
123
			}
124
		}
125
		return taxonNodes.size() > 0 ? taxonNodes : null;
126
	}
127

    
128
	/** {@inheritDoc} */
129
	@Override
130
	public boolean validateDrop(Object target, int operation,
131
			TransferData transferType) {
132

    
133
		if (target instanceof ITaxonTreeNode) {
134

    
135
		    // check users permissions with target taxonnode and taxon
136
		    if (target instanceof TaxonNode) {
137
		        TaxonNode targetNode = (TaxonNode)target;
138
		        boolean hasTargetNodePermission = CdmStore.currentAuthentiationHasPermission(targetNode, UPDATE);
139
		        boolean hasTargetTaxonPermission = targetNode.getTaxon() == null ?
140
		        			true :
141
		        			CdmStore.currentAuthentiationHasPermission(targetNode.getTaxon(), UPDATE);
142

    
143
                if(logger.isDebugEnabled()){
144
                    logger.debug("target: " + targetNode.getTaxon() == null? "-" : targetNode.getTaxon().getTitleCache()); //$NON-NLS-1$
145
                }
146

    
147
		        if(!hasTargetNodePermission || ! hasTargetNodePermission){
148
		            if(logger.isDebugEnabled()){
149
		                logger.debug("CANCEL_STATUS for target node: " + hasTargetNodePermission + " " + hasTargetTaxonPermission + " "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
150
		            }
151
		            return false;
152
		        }
153
		    }
154

    
155
		    // do not allow to drop onto itself and
156
		    // check users permissions with all selected taxon nodes and taxa
157
		    for(TaxonNode taxonNode : getSelectedTaxa()){
158
			    if (logger.isDebugEnabled()){
159
			    	logger.debug("selectedTaxa: " + taxonNode.getTaxon() == null? "-" : taxonNode.getTaxon().getTitleCache()); //$NON-NLS-1$
160
			    }
161
			    boolean isSameTaxonNode = taxonNode.equals(target);
162
				boolean hasTaxonNodePermission = CdmStore.currentAuthentiationHasPermission(taxonNode, UPDATE);
163
				boolean hasTaxonPermission = taxonNode.getTaxon() == null ?
164
	        			true :
165
	        			CdmStore.currentAuthentiationHasPermission(taxonNode.getTaxon(), UPDATE);CdmStore.currentAuthentiationHasPermission(taxonNode.getTaxon(), UPDATE);
166
                if (
167
			        isSameTaxonNode
168
			        || !hasTaxonNodePermission
169
    	            || !hasTaxonPermission
170
	                ) {
171
                    if(logger.isDebugEnabled()){
172
                        logger.debug("CANCEL_STATUS for selected  " + isSameTaxonNode + Messages.TreeNodeDropAdapter_10 + hasTaxonNodePermission + " " + hasTaxonPermission + " "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
173
                    }
174
					return false;
175
				}
176
			}
177
			logger.debug("OK_STATUS"); //$NON-NLS-1$
178
			return true;
179
		}
180
		logger.debug("CANCEL_STATUS"); //$NON-NLS-1$
181
		return false;
182
	}
183

    
184

    
185
	/**
186
	 * @param childTaxonNode
187
	 * @param parentTaxon
188
	 * @return
189
	 */
190
	private boolean moveTaxon(Set<TaxonNode> taxonNodes, ITaxonTreeNode targetITaxonTreeNode) {
191

    
192
		TaxonNavigator taxonNavigator;
193
		taxonNavigator = (TaxonNavigator) NavigationUtil.showView(TaxonNavigator.ID);
194

    
195
		if(targetITaxonTreeNode instanceof TaxonNode){
196

    
197
			TaxonNode targetTaxonNode = (TaxonNode) targetITaxonTreeNode;
198
		// Make sure parent taxon does not have unsaved changes
199
			if (NavigationUtil.isDirty(targetTaxonNode)){
200
				MessageDialog.openWarning(NavigationUtil.getShell(), TREE_NODE_DROP_ADAPTER_UNSAVED_PARENT, TREE_NODE_DROP_ADAPTER_UNSAVED_PARENT_MESSAGE);
201
				return false;
202
			}
203

    
204
		}
205
		Iterator<TaxonNode> taxIterator = taxonNodes.iterator();
206
        Set<UUID> uuids = new HashSet<UUID>();
207
        TaxonNode node = null;
208
        while(taxIterator.hasNext()){
209
            node = taxIterator.next();
210
            uuids.add(node.getUuid());
211
        }
212
		if (!PreferencesUtil.getSortNodesNaturally()){
213
			IUndoContext workspaceUndoContext = NavigationUtil.getWorkbenchUndoContext();
214
			if (workspaceUndoContext == null) {
215
				logger.error("Workspace undo context is null. DND operation cancelled"); //$NON-NLS-1$
216
				return false;
217
			}
218

    
219
			AbstractPostOperation<?> operation = new MoveTaxonOperation
220
					(TREE_NODE_DROP_ADAPTER_MOVE_TAXON, workspaceUndoContext, uuids, targetITaxonTreeNode, this, taxonNavigator, MovingType.CHILD);
221
			NavigationUtil.executeOperation(operation);
222

    
223
			logger.info("Moved taxa to new parent " + targetITaxonTreeNode); //$NON-NLS-1$
224
			return true;
225
		}else{
226
			String[] buttonLables = {TREE_NODE_DROP_ADAPTER_CHILD, TREE_NODE_DROP_ADAPTER_BEHIND,TREE_NODE_DROP_ADAPTER_CANCEL};
227
			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);
228
			dialog.open();
229
			int returnCode = dialog.getReturnCode();
230
			if (returnCode == 0){
231
				IUndoContext workspaceUndoContext = NavigationUtil.getWorkbenchUndoContext();
232
				if (workspaceUndoContext == null) {
233
					logger.error("Workspace undo context is null. DND operation cancelled"); //$NON-NLS-1$
234
					return false;
235
				}
236

    
237
				AbstractPostOperation<?> operation = new MoveTaxonOperation
238
						(TREE_NODE_DROP_ADAPTER_MOVE_TAXON, workspaceUndoContext, uuids, targetITaxonTreeNode, this, taxonNavigator, MovingType.CHILD);
239
				NavigationUtil.executeOperation(operation);
240

    
241
				logger.info("Moved taxa to new parent " + targetITaxonTreeNode); //$NON-NLS-1$
242
				return true;
243
			}else if (returnCode == 1){
244
				IUndoContext workspaceUndoContext = NavigationUtil.getWorkbenchUndoContext();
245
				if (workspaceUndoContext == null) {
246
					logger.error("Workspace undo context is null. DND operation cancelled"); //$NON-NLS-1$
247
					return false;
248
				}
249
				TaxonNode targetNode = (TaxonNode) targetITaxonTreeNode;
250

    
251
				AbstractPostOperation<?> operation = new MoveTaxonOperation
252
						(TREE_NODE_DROP_ADAPTER_MOVE_TAXON, workspaceUndoContext, uuids, targetNode, this, taxonNavigator, MovingType.PREVIOUS);
253
				NavigationUtil.executeOperation(operation);
254

    
255
				logger.info("Moved taxa to new parent " + targetITaxonTreeNode); //$NON-NLS-1$
256
				return true;
257
			}
258
//			} else if (returnCode == 2){
259
//                IUndoContext workspaceUndoContext = NavigationUtil.getWorkbenchUndoContext();
260
//                if (workspaceUndoContext == null) {
261
//                    logger.error("Workspace undo context is null. DND operation cancelled");
262
//                    return false;
263
//                }
264
//                TaxonNode targetNode = (TaxonNode) targetITaxonTreeNode;
265
//
266
//                AbstractPostOperation operation = new MoveTaxonOperation
267
//                        ("Move Taxon", workspaceUndoContext, uuids, targetNode, this, taxonNavigator, MovingType.BEHIND);
268
//                NavigationUtil.executeOperation(operation);
269
//
270
//                logger.info("Moved taxa to new parent " + targetITaxonTreeNode);
271
//                return true;
272
//            }
273
				else{
274
				return false;
275
			}
276

    
277

    
278
		}
279
	}
280

    
281
	/** {@inheritDoc} */
282
	@Override
283
    public boolean postOperation(CdmBase objectAffectedByOperation) {
284
		return true;
285
	}
286

    
287
	/**
288
	 * <p>onComplete</p>
289
	 *
290
	 * @return a boolean.
291
	 */
292
	@Override
293
    public boolean onComplete() {
294
		// TODO Auto-generated method stub
295
		return false;
296
	}
297
	@Override
298
	public void dragOver(DropTargetEvent event) {
299
		super.dragOver(event);
300
		event.feedback = DND.FEEDBACK_SELECT | DND.FEEDBACK_INSERT_AFTER;
301

    
302
	}
303

    
304
}
(20-20/21)