Project

General

Profile

Download (11.4 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 = CdmStore.currentAuthentiationHasPermission(targetNode.getTaxon(), UPDATE);
140

    
141
                if(logger.isDebugEnabled()){
142
                    logger.debug("target: " + targetNode.getTaxon().getTitleCache()); //$NON-NLS-1$
143
                }
144

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

    
153
		    // do not allow to drop onto itself and
154
		    // check users permissions with all selected taxon nodes and taxa
155
		    for(TaxonNode taxonNode : getSelectedTaxa()){
156
			    logger.debug("selectedTaxa: " + taxonNode.getTaxon().getTitleCache()); //$NON-NLS-1$
157
				Boolean isSameTaxonNode = taxonNode.equals(target);
158
				Boolean hasTaxonNodePermission = CdmStore.currentAuthentiationHasPermission(taxonNode, UPDATE);
159
				Boolean hasTaxonPermission = 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.toString() + Messages.TreeNodeDropAdapter_10 + hasTaxonNodePermission.toString() + " " + hasTaxonPermission.toString() + " "); //$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
	/* (non-Javadoc)
276
	 * @see eu.etaxonomy.taxeditor.operations.IPostOperationEnabled#postOperation(eu.etaxonomy.cdm.model.common.CdmBase)
277
	 */
278
	/** {@inheritDoc} */
279
	@Override
280
    public boolean postOperation(CdmBase objectAffectedByOperation) {
281
		return true;
282
	}
283

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

    
299
	}
300

    
301
}
(20-20/21)