Project

General

Profile

Download (10.9 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.e4;
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.taxon.Classification;
31
import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
32
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
33
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
34
import eu.etaxonomy.taxeditor.model.AbstractUtility;
35
import eu.etaxonomy.taxeditor.navigation.l10n.Messages;
36
import eu.etaxonomy.taxeditor.navigation.navigator.operation.MoveTaxonOperation;
37
import eu.etaxonomy.taxeditor.operation.AbstractPostOperation;
38
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
39
import eu.etaxonomy.taxeditor.store.CdmStore;
40

    
41
/**
42
 * @author k.luther
43
 * @date 02.06.2015
44
 */
45
public class TreeNodeDropAdapterE4 extends ViewerDropAdapter {
46

    
47
    protected static final String TREE_NODE_DROP_ADAPTER_UNSAVED_PARENT_MESSAGE = Messages.TreeNodeDropAdapter_UNSAVED_PARENT_MESSAGE;
48
    protected static final String TREE_NODE_DROP_ADAPTER_UNSAVED_PARENT = Messages.TreeNodeDropAdapter_UNSAVED_PARENT;
49
    protected static final String TREE_NODE_DROP_ADAPTER_MOVE_TAXON = Messages.TreeNodeDropAdapter_MOVE_TAXON;
50
    protected static final String TREE_NODE_DROP_ADAPTER_CANCEL = Messages.TreeNodeDropAdapter_CANCEL;
51
    protected static final String TREE_NODE_DROP_ADAPTER_BEHIND = Messages.TreeNodeDropAdapter_BEHIND;
52
    protected static final String TREE_NODE_DROP_ADAPTER_CHILD = Messages.TreeNodeDropAdapter_CHILD;
53
    protected static final String DO_YOU_WANT_TO_MOVE_THE_TAXONNODE_AS_CHILD_OR_BEHIND_THE_TARGET_NODE = Messages.TreeNodeDropAdapter_MOVE_BEHIND;
54
    protected static final String TARGET_NODE = Messages.TreeNodeDropAdapter_TARGET_NODE;
55

    
56
    private static final Logger logger = Logger.getLogger(TreeNodeDropAdapterE4.class);
57

    
58
    private TaxonNavigatorE4 taxonNavigator;
59

    
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
	public enum MovingType{
65
	    CHILD, PREVIOUS, BEHIND
66
	}
67

    
68
	protected TreeNodeDropAdapterE4(TaxonNavigatorE4 navigator) {
69
	    super(navigator.getViewer());
70
	    this.taxonNavigator = navigator;
71
	}
72

    
73
	/** {@inheritDoc} */
74
	@Override
75
	public boolean performDrop(Object data) {
76
        Object target = getCurrentTarget();
77
		if (getCurrentTarget() instanceof ITaxonTreeNode) {
78
			Set<TaxonNode> taxonNodes = getSelectedTaxa();
79
			ITaxonTreeNode targetTreeNode = (ITaxonTreeNode) target;
80
			if (targetTreeNode instanceof Classification){
81
				targetTreeNode = ((Classification)targetTreeNode).getRootNode();
82
				targetTreeNode = HibernateProxyHelper.deproxy(targetTreeNode, TaxonNode.class);
83
			}
84
			if(taxonNodes != null) {
85
				if (taxonNodes.size() == 1){
86
					return moveTaxon(taxonNodes, targetTreeNode);
87
				} else{
88
					if( MessageDialog.openConfirm(null, Messages.TreeNodeDropAdapter_MOVING, Messages.TreeNodeDropAdapter_MOVING_MESSAGE)){
89
						return true;
90
					}
91
				}
92
            }
93
		}
94
		return false;
95
	}
96

    
97
	private Set<TaxonNode> getSelectedTaxa(){
98
		HashSet<TaxonNode> taxonNodes = new HashSet<TaxonNode>();
99

    
100
		ISelection selection = LocalSelectionTransfer.getTransfer().getSelection();
101
		if (selection instanceof TreeSelection) {
102

    
103
			Iterator<?> selectionIterator = ((TreeSelection) selection).iterator();
104

    
105
			while (selectionIterator.hasNext()){
106
				Object object = selectionIterator.next();
107
				if(object instanceof TaxonNode){
108
					TaxonNode taxonNode = (TaxonNode) object;
109
					taxonNodes.add(taxonNode);
110
				}
111
			}
112
		}
113
		return taxonNodes;
114
	}
115

    
116
	/** {@inheritDoc} */
117
	@Override
118
	public boolean validateDrop(Object target, int operation,
119
			TransferData transferType) {
120

    
121
		if (target instanceof ITaxonTreeNode) {
122

    
123
		    // check users permissions with target taxonnode and taxon
124
		    if (target instanceof TaxonNode) {
125
		        TaxonNode targetNode = (TaxonNode)target;
126
		        boolean hasTargetNodePermission = CdmStore.currentAuthentiationHasPermission(targetNode, UPDATE);
127
		        boolean hasTargetTaxonPermission = targetNode.getTaxon() == null ?
128
		        			true :
129
		        			CdmStore.currentAuthentiationHasPermission(targetNode.getTaxon(), UPDATE);
130

    
131
                if(logger.isDebugEnabled()){
132
                    logger.debug("target: " + targetNode.getTaxon() == null? "-" : targetNode.getTaxon().getTitleCache()); //$NON-NLS-1$
133
                }
134

    
135
		        if(!hasTargetNodePermission || ! hasTargetNodePermission){
136
		            if(logger.isDebugEnabled()){
137
		                logger.debug("CANCEL_STATUS for target node: " + hasTargetNodePermission + " " + hasTargetTaxonPermission + " "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
138
		            }
139
		            return false;
140
		        }
141
		    }
142

    
143
		    // do not allow to drop onto itself and
144
		    // check users permissions with all selected taxon nodes and taxa
145
		    for(TaxonNode taxonNode : getSelectedTaxa()){
146
			    if (logger.isDebugEnabled()){
147
			    	logger.debug("selectedTaxa: " + taxonNode.getTaxon() == null? "-" : taxonNode.getTaxon().getTitleCache()); //$NON-NLS-1$
148
			    }
149
			    boolean isClassification = !taxonNode.hasTaxon();
150
			    if (isClassification) {
151
	                    if(logger.isDebugEnabled()){
152
	                        logger.debug("CANCEL_STATUS for selected taxonNode " + taxonNode.getId()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
153
	                    }
154
	                    return false;
155
	                }
156
			    boolean isSameTaxonNode = taxonNode.equals(target);
157
				boolean hasTaxonNodePermission = CdmStore.currentAuthentiationHasPermission(taxonNode, UPDATE);
158

    
159
				boolean hasTaxonPermission =
160
	        			CdmStore.currentAuthentiationHasPermission(taxonNode.getTaxon(), UPDATE);CdmStore.currentAuthentiationHasPermission(taxonNode.getTaxon(), UPDATE);
161
                if (
162
			        isSameTaxonNode
163
			        || !hasTaxonNodePermission
164
    	            || !hasTaxonPermission
165
    	            ) {
166
                    if(logger.isDebugEnabled()){
167
                        logger.debug("CANCEL_STATUS for selected  " + isSameTaxonNode + Messages.TreeNodeDropAdapter_10 + hasTaxonNodePermission + " " + hasTaxonPermission + " "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
168
                    }
169
					return false;
170
				}
171
			}
172
			logger.debug("OK_STATUS"); //$NON-NLS-1$
173
			return true;
174
		}
175
		logger.debug("CANCEL_STATUS"); //$NON-NLS-1$
176
		return false;
177
	}
178

    
179

    
180
	private boolean moveTaxon(Set<TaxonNode> taxonNodes, ITaxonTreeNode targetITaxonTreeNode) {
181

    
182

    
183
		if(targetITaxonTreeNode instanceof TaxonNode){
184

    
185
		// Make sure parent taxon does not have unsaved changes
186
//			if (NavigationUtil.isDirty(targetTaxonNode)){
187
//				MessageDialog.openWarning(NavigationUtil.getShell(), TREE_NODE_DROP_ADAPTER_UNSAVED_PARENT, TREE_NODE_DROP_ADAPTER_UNSAVED_PARENT_MESSAGE);
188
//				return false;
189
//			}
190

    
191
		}
192
		Iterator<TaxonNode> taxIterator = taxonNodes.iterator();
193
        Set<UUID> uuids = new HashSet<UUID>();
194
        TaxonNode node = null;
195
        while(taxIterator.hasNext()){
196
            node = taxIterator.next();
197
            uuids.add(node.getUuid());
198
        }
199
        IUndoContext workspaceUndoContext = taxonNavigator.getUndoContext();
200
		if (!PreferencesUtil.getSortNodesNaturally()){
201
			if (workspaceUndoContext == null) {
202
				logger.error("Workspace undo context is null. DND operation cancelled"); //$NON-NLS-1$
203
				return false;
204
			}
205

    
206
			AbstractPostOperation<?> operation = new MoveTaxonOperation
207
			        (TREE_NODE_DROP_ADAPTER_MOVE_TAXON, workspaceUndoContext, uuids, targetITaxonTreeNode, taxonNavigator, taxonNavigator, MovingType.CHILD);
208
			AbstractUtility.executeOperation(operation, taxonNavigator.getSync());
209

    
210
			logger.info("Moved taxa to new parent " + targetITaxonTreeNode); //$NON-NLS-1$
211
			return true;
212
		}else{
213
			String[] buttonLables = {TREE_NODE_DROP_ADAPTER_CHILD, TREE_NODE_DROP_ADAPTER_BEHIND,TREE_NODE_DROP_ADAPTER_CANCEL};
214
			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);
215
			dialog.open();
216
			int returnCode = dialog.getReturnCode();
217
			if (returnCode == 0){
218
				if (workspaceUndoContext == null) {
219
					logger.error("Workspace undo context is null. DND operation cancelled"); //$NON-NLS-1$
220
					return false;
221
				}
222

    
223
				AbstractPostOperation<?> operation = new MoveTaxonOperation
224
						(TREE_NODE_DROP_ADAPTER_MOVE_TAXON, workspaceUndoContext, uuids, targetITaxonTreeNode, taxonNavigator, taxonNavigator, MovingType.CHILD);
225
				AbstractUtility.executeOperation(operation, taxonNavigator.getSync());
226

    
227
				logger.info("Moved taxa to new parent " + targetITaxonTreeNode); //$NON-NLS-1$
228
				return true;
229
			}else if (returnCode == 1){
230
				if (workspaceUndoContext == null) {
231
					logger.error("Workspace undo context is null. DND operation cancelled"); //$NON-NLS-1$
232
					return false;
233
				}
234
				TaxonNode targetNode = (TaxonNode) targetITaxonTreeNode;
235

    
236
				AbstractPostOperation<?> operation = new MoveTaxonOperation
237
						(TREE_NODE_DROP_ADAPTER_MOVE_TAXON, workspaceUndoContext, uuids, targetNode, taxonNavigator, taxonNavigator, MovingType.PREVIOUS);
238
				AbstractUtility.executeOperation(operation, taxonNavigator.getSync());
239

    
240
				logger.info("Moved taxa to new parent " + targetITaxonTreeNode); //$NON-NLS-1$
241
				return true;
242
			}
243
//			} else if (returnCode == 2){
244
//                IUndoContext workspaceUndoContext = NavigationUtil.getWorkbenchUndoContext();
245
//                if (workspaceUndoContext == null) {
246
//                    logger.error("Workspace undo context is null. DND operation cancelled");
247
//                    return false;
248
//                }
249
//                TaxonNode targetNode = (TaxonNode) targetITaxonTreeNode;
250
//
251
//                AbstractPostOperation operation = new MoveTaxonOperation
252
//                        ("Move Taxon", workspaceUndoContext, uuids, targetNode, this, taxonNavigator, MovingType.BEHIND);
253
//                NavigationUtil.executeOperation(operation);
254
//
255
//                logger.info("Moved taxa to new parent " + targetITaxonTreeNode);
256
//                return true;
257
//            }
258
				else{
259
				return false;
260
			}
261

    
262

    
263
		}
264
	}
265

    
266
	@Override
267
	public void dragOver(DropTargetEvent event) {
268
		super.dragOver(event);
269
		event.feedback = DND.FEEDBACK_SELECT | DND.FEEDBACK_INSERT_AFTER;
270
	}
271

    
272
}
(6-6/6)