Close name editor for moved taxon nodes
[taxeditor.git] / eu.etaxonomy.taxeditor.navigation / src / main / java / eu / etaxonomy / taxeditor / navigation / navigator / e4 / TreeNodeDropAdapterE4.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.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 javax.inject.Inject;
19
20 import org.apache.log4j.Logger;
21 import org.eclipse.core.commands.operations.IUndoContext;
22 import org.eclipse.e4.ui.workbench.modeling.EPartService;
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.jface.viewers.ViewerDropAdapter;
28 import org.eclipse.swt.dnd.DND;
29 import org.eclipse.swt.dnd.DropTargetEvent;
30 import org.eclipse.swt.dnd.TransferData;
31 import org.eclipse.swt.widgets.Display;
32
33 import eu.etaxonomy.cdm.api.application.CdmApplicationState;
34 import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
35 import eu.etaxonomy.cdm.api.service.UpdateResult;
36 import eu.etaxonomy.cdm.common.monitor.IRemotingProgressMonitor;
37 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
38 import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
39 import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
40 import eu.etaxonomy.taxeditor.editor.EditorUtil;
41 import eu.etaxonomy.taxeditor.event.EventUtility;
42 import eu.etaxonomy.taxeditor.event.WorkbenchEventConstants;
43 import eu.etaxonomy.taxeditor.model.AbstractUtility;
44 import eu.etaxonomy.taxeditor.navigation.l10n.Messages;
45 import eu.etaxonomy.taxeditor.operation.IPostMoniteredOperationEnabled;
46 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
47 import eu.etaxonomy.taxeditor.store.CdmStore;
48
49 /**
50 * @author k.luther
51 * @date 02.06.2015
52 */
53 public class TreeNodeDropAdapterE4 extends ViewerDropAdapter implements IPostMoniteredOperationEnabled{
54
55 protected static final String TREE_NODE_DROP_ADAPTER_UNSAVED_PARENT_MESSAGE = Messages.TreeNodeDropAdapter_UNSAVED_PARENT_MESSAGE;
56 protected static final String TREE_NODE_DROP_ADAPTER_UNSAVED_PARENT = Messages.TreeNodeDropAdapter_UNSAVED_PARENT;
57 protected static final String TREE_NODE_DROP_ADAPTER_MOVE_TAXON = Messages.TreeNodeDropAdapter_MOVE_TAXON;
58 protected static final String TREE_NODE_DROP_ADAPTER_CANCEL = Messages.TreeNodeDropAdapter_CANCEL;
59 protected static final String TREE_NODE_DROP_ADAPTER_BEHIND = Messages.TreeNodeDropAdapter_BEHIND;
60 protected static final String TREE_NODE_DROP_ADAPTER_CHILD = Messages.TreeNodeDropAdapter_CHILD;
61 protected static final String DO_YOU_WANT_TO_MOVE_THE_TAXONNODE_AS_CHILD_OR_BEHIND_THE_TARGET_NODE = Messages.TreeNodeDropAdapter_MOVE_BEHIND;
62 protected static final String TARGET_NODE = Messages.TreeNodeDropAdapter_TARGET_NODE;
63
64 private static final Logger logger = Logger.getLogger(TreeNodeDropAdapterE4.class);
65
66 private TaxonNavigatorE4 taxonNavigator;
67 UpdateResult result;
68
69 public static final String ID = "eu.etaxonomy.taxeditor.navigation.navigator.dropassistant"; //$NON-NLS-1$
70
71 private static final EnumSet<CRUD> UPDATE = EnumSet.of(CRUD.UPDATE);
72
73 @Inject
74 private EPartService partService;
75
76 public enum MovingType{
77 CHILD, PREVIOUS, BEHIND
78 }
79
80 protected TreeNodeDropAdapterE4(TaxonNavigatorE4 navigator) {
81 super(navigator.getViewer());
82 this.taxonNavigator = navigator;
83 }
84
85 /** {@inheritDoc} */
86 @Override
87 public boolean performDrop(Object data) {
88 Object target = getCurrentTarget();
89 if (getCurrentTarget() instanceof TaxonNodeDto) {
90 Set<TaxonNodeDto> taxonNodes = getSelectedTaxa();
91 TaxonNodeDto targetTreeNode = (TaxonNodeDto) target;
92 // if (targetTreeNode.getType() != null && targetTreeNode.getType().equals(Classification.class)){
93 // targetTreeNode = ((Classification)targetTreeNode).getRootNode();
94 // targetTreeNode = HibernateProxyHelper.deproxy(targetTreeNode, TaxonNode.class);
95 // }
96 if(taxonNodes != null) {
97 // if (taxonNodes.size() == 1){
98 boolean success = moveTaxon(taxonNodes, targetTreeNode);
99 // if (success){
100 // taxonNavigator.refresh();
101 // }
102 return success;
103 // } else{
104 // if( MessageDialog.openConfirm(null, Messages.TreeNodeDropAdapter_MOVING, Messages.TreeNodeDropAdapter_MOVING_MESSAGE)){
105 // return true;
106 // }
107 // }
108 }
109 }
110 return false;
111 }
112
113 private Set<TaxonNodeDto> getSelectedTaxa(){
114 HashSet<TaxonNodeDto> taxonNodes = new HashSet();
115
116 ISelection selection = LocalSelectionTransfer.getTransfer().getSelection();
117 if (selection instanceof TreeSelection) {
118
119 Iterator<?> selectionIterator = ((TreeSelection) selection).iterator();
120
121 while (selectionIterator.hasNext()){
122 Object object = selectionIterator.next();
123 if(object instanceof TaxonNodeDto){
124 TaxonNodeDto taxonNode = (TaxonNodeDto) object;
125 taxonNodes.add(taxonNode);
126 }
127 }
128 }
129 return taxonNodes;
130 }
131
132 /** {@inheritDoc} */
133 @Override
134 public boolean validateDrop(Object target, int operation,
135 TransferData transferType) {
136
137 if (target instanceof TaxonNodeDto) {
138
139 // check users permissions with target taxonnode and taxon
140 if (target instanceof TaxonNodeDto) {
141 TaxonNodeDto targetNode = (TaxonNodeDto)target;
142 TaxonNode node = CdmStore.getService(ITaxonNodeService.class).load(targetNode.getUuid());
143 boolean hasTargetNodePermission = CdmStore.currentAuthentiationHasPermission(node, UPDATE);
144 boolean hasTargetTaxonPermission = node.getTaxon() == null ?
145 true :
146 CdmStore.currentAuthentiationHasPermission(node.getTaxon(), UPDATE);
147
148 if(!hasTargetNodePermission || ! hasTargetNodePermission){
149 if(logger.isDebugEnabled()){
150 logger.debug("CANCEL_STATUS for target node: " + hasTargetNodePermission + " " + hasTargetTaxonPermission + " "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
151 }
152 return false;
153 }
154 }
155
156 // do not allow to drop onto itself and
157 // check users permissions with all selected taxon nodes and taxa
158 for(TaxonNodeDto taxonNode : getSelectedTaxa()){
159 if (logger.isDebugEnabled()){
160 logger.debug("selectedTaxa: " + taxonNode.getTaxonUuid() == null? "-" : taxonNode.getTitleCache()); //$NON-NLS-1$
161 }
162 boolean isClassification = taxonNode.getTaxonUuid()== null;
163 if (isClassification) {
164 if(logger.isDebugEnabled()){
165 logger.debug("CANCEL_STATUS for selected classification " + taxonNode.getClassificationUUID()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
166 }
167 return false;
168 }
169 boolean isSameTaxonNode = taxonNode.equals(target);
170 TaxonNode node = CdmStore.getService(ITaxonNodeService.class).load(taxonNode.getUuid());
171 boolean hasTaxonNodePermission = CdmStore.currentAuthentiationHasPermission(node, UPDATE);
172
173 boolean hasTaxonPermission =
174 CdmStore.currentAuthentiationHasPermission(node.getTaxon(), UPDATE);CdmStore.currentAuthentiationHasPermission(node.getTaxon(), UPDATE);
175 if (
176 isSameTaxonNode
177 || !hasTaxonNodePermission
178 || !hasTaxonPermission
179 ) {
180 if(logger.isDebugEnabled()){
181 logger.debug("CANCEL_STATUS for selected " + isSameTaxonNode + Messages.TreeNodeDropAdapter_10 + hasTaxonNodePermission + " " + hasTaxonPermission + " "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
182 }
183 return false;
184 }
185 }
186 logger.debug("OK_STATUS"); //$NON-NLS-1$
187 return true;
188 }
189 logger.debug("CANCEL_STATUS"); //$NON-NLS-1$
190 return false;
191 }
192
193
194 private boolean moveTaxon(Set<TaxonNodeDto> taxonNodes, TaxonNodeDto targetITaxonTreeNode) {
195 Iterator<TaxonNodeDto> taxIterator = taxonNodes.iterator();
196 Set<UUID> uuids = new HashSet<UUID>();
197 TaxonNodeDto node = null;
198 while(taxIterator.hasNext()){
199 node = taxIterator.next();
200 uuids.add(node.getUuid());
201 }
202 IUndoContext workspaceUndoContext = taxonNavigator.getUndoContext();
203 int movingTypeInt = 0;
204 if (!PreferencesUtil.getSortNodesNaturally()){
205 // if (workspaceUndoContext == null) {
206 // logger.error("Workspace undo context is null. DND operation cancelled"); //$NON-NLS-1$
207 // return false;
208 // }
209 // result =CdmStore.getService(ITaxonNodeService.class).moveTaxonNodes(uuids,targetITaxonTreeNode.getUuid(), 0);
210 //
211 // logger.info("Moved taxa to new parent " + targetITaxonTreeNode); //$NON-NLS-1$
212 // return true;
213 }else{
214 String[] buttonLables = {TREE_NODE_DROP_ADAPTER_CHILD, TREE_NODE_DROP_ADAPTER_BEHIND,TREE_NODE_DROP_ADAPTER_CANCEL};
215 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);
216 dialog.open();
217 int returnCode = dialog.getReturnCode();
218
219 if (returnCode == 0){
220 if (workspaceUndoContext == null) {
221 logger.error("Workspace undo context is null. DND operation cancelled"); //$NON-NLS-1$
222 return false;
223 }
224
225 // result = CdmStore.getService(ITaxonNodeService.class).moveTaxonNodes(uuids,targetITaxonTreeNode.getUuid(), 0);
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
235 movingTypeInt = 2;
236 // CdmStore.getService(ITaxonNodeService.class).moveTaxonNodes(uuids,targetITaxonTreeNode.getUuid(), 2);
237 // logger.info("Moved taxa to new parent " + targetITaxonTreeNode); //$NON-NLS-1$
238 // return true;
239 }
240 // } else if (returnCode == 2){
241 // IUndoContext workspaceUndoContext = NavigationUtil.getWorkbenchUndoContext();
242 // if (workspaceUndoContext == null) {
243 // logger.error("Workspace undo context is null. DND operation cancelled");
244 // return false;
245 // }
246 // TaxonNode targetNode = (TaxonNode) targetITaxonTreeNode;
247 //
248 // AbstractPostOperation operation = new MoveTaxonOperation
249 // ("Move Taxon", workspaceUndoContext, uuids, targetNode, this, taxonNavigator, MovingType.BEHIND);
250 // NavigationUtil.executeOperation(operation);
251 //
252 // logger.info("Moved taxa to new parent " + targetITaxonTreeNode);
253 // return true;
254 // }
255 else{
256 return false;
257 }
258
259
260 }
261 //close possible open name editors for the moved taxon nodes
262 taxonNodes.forEach(nodeDto->EditorUtil.closeObsoleteEditor(nodeDto, partService));
263 moveNodes(uuids, targetITaxonTreeNode.getUuid(), movingTypeInt);
264 return true;
265 }
266
267 private void moveNodes(Set<UUID> taxonNodesToMoveUuid, UUID newParentTreeNodeUuid, int movingTypeInt){
268 UUID uuid = CdmApplicationState.getLongRunningTasksService().monitLongRunningTask(taxonNodesToMoveUuid,
269 newParentTreeNodeUuid, movingTypeInt);
270
271 Display.getDefault().asyncExec(new Runnable() {
272 @Override
273 public void run() {
274 AbstractUtility.executeMoniteredOperation("Move Taxon to new parent: ",
275 uuid,
276 1000,
277 false,
278 TreeNodeDropAdapterE4.this,
279 null);
280 }
281 });
282 }
283
284
285 @Override
286 public void dragOver(DropTargetEvent event) {
287 super.dragOver(event);
288 event.feedback = DND.FEEDBACK_SELECT | DND.FEEDBACK_INSERT_AFTER;
289 }
290
291 /**
292 * {@inheritDoc}
293 */
294 @Override
295 public void postOperation(IRemotingProgressMonitor monitor) {
296 EventUtility.postEvent(WorkbenchEventConstants.REFRESH_NAVIGATOR, true);
297 }
298
299 }