Add space to message
[taxeditor.git] / eu.etaxonomy.taxeditor.navigation / src / main / java / eu / etaxonomy / taxeditor / navigation / navigator / TreeNodeDropAdapter.java
1 // $Id$
2 /**
3 * Copyright (C) 2015 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10
11 package eu.etaxonomy.taxeditor.navigation.navigator;
12
13 import java.util.EnumSet;
14 import java.util.HashSet;
15 import java.util.Iterator;
16 import java.util.Set;
17
18 import org.apache.log4j.Logger;
19 import org.eclipse.core.commands.operations.IUndoContext;
20 import org.eclipse.core.runtime.IStatus;
21 import org.eclipse.core.runtime.Status;
22 import org.eclipse.jface.dialogs.IconAndMessageDialog;
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.Viewer;
28 import org.eclipse.jface.viewers.ViewerDropAdapter;
29 import org.eclipse.swt.dnd.DND;
30 import org.eclipse.swt.dnd.DropTargetEvent;
31 import org.eclipse.swt.dnd.TransferData;
32 import org.eclipse.swt.graphics.Image;
33 import org.eclipse.swt.widgets.Shell;
34 import org.eclipse.ui.handlers.HandlerUtil;
35 import org.eclipse.ui.navigator.CommonDropAdapter;
36 import org.eclipse.ui.navigator.CommonDropAdapterAssistant;
37 import org.eclipse.ui.navigator.CommonViewer;
38
39 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
40 import eu.etaxonomy.cdm.model.common.CdmBase;
41 import eu.etaxonomy.cdm.model.common.OrderedTermBase;
42 import eu.etaxonomy.cdm.model.common.TermBase;
43 import eu.etaxonomy.cdm.model.taxon.Classification;
44 import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
45 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
46 import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
47 import eu.etaxonomy.taxeditor.editor.definedterm.DefinedTermEditor;
48 import eu.etaxonomy.taxeditor.navigation.NavigationUtil;
49 import eu.etaxonomy.taxeditor.navigation.navigator.operation.MoveTaxonOperation;
50 import eu.etaxonomy.taxeditor.operation.AbstractPostOperation;
51 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
52 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
53 import eu.etaxonomy.taxeditor.store.CdmStore;
54
55 /**
56 * <p>TreeNodeDropAdapter class.</p>
57 *
58 * @author k.luther
59 * @date 02.06.2015
60 * @version 1.0
61 */
62 public class TreeNodeDropAdapter extends ViewerDropAdapter implements IPostOperationEnabled {
63
64 /**
65 * @param viewer
66 */
67 protected TreeNodeDropAdapter(TaxonNavigatorViewer navigatorViewer) {
68 super(navigatorViewer);
69 this.navigatorViewer = navigatorViewer;
70
71 }
72
73 private final TaxonNavigatorViewer navigatorViewer;
74 private static final Logger logger = Logger.getLogger(TreeNodeDropAdapter.class);
75
76 /** Constant <code>ID="eu.etaxonomy.taxeditor.navigation.navig"{trunked}</code> */
77 public static final String ID = "eu.etaxonomy.taxeditor.navigation.navigator.dropassistant"; //$NON-NLS-1$
78
79 private static final EnumSet<CRUD> UPDATE = EnumSet.of(CRUD.UPDATE);
80
81
82
83 /* (non-Javadoc)
84 * @see org.eclipse.ui.navigator.CommonDropAdapterAssistant#handleDrop(org.eclipse.ui.navigator.CommonDropAdapter, org.eclipse.swt.dnd.DropTargetEvent, java.lang.Object)
85 */
86 /** {@inheritDoc} */
87 @Override
88 public boolean performDrop(Object target) {
89
90
91 if (target instanceof ITaxonTreeNode) {
92 Set<TaxonNode> taxonNodes = getSelectedTaxa();
93 ITaxonTreeNode targetTreeNode = (ITaxonTreeNode) target;
94 if (targetTreeNode instanceof Classification){
95 targetTreeNode = ((Classification)targetTreeNode).getRootNode();
96 targetTreeNode = HibernateProxyHelper.deproxy(targetTreeNode, TaxonNode.class);
97 }
98 if(taxonNodes != null) {
99 if (taxonNodes.size() == 1){
100 return moveTaxon(taxonNodes.iterator().next(), targetTreeNode);
101 } else{
102 if( MessageDialog.openConfirm(null, "Moving taxon", "The operation move accepted taxon to other parent is available only for a single taxon.")){
103 return true;
104 }
105 }
106 }
107 }
108
109 return false;
110 }
111
112 private Set<TaxonNode> getSelectedTaxa(){
113 HashSet<TaxonNode> taxonNodes = new HashSet<TaxonNode>();
114
115 ISelection selection = LocalSelectionTransfer.getTransfer().getSelection();
116 if (selection instanceof TreeSelection) {
117
118 Iterator selectionIterator = ((TreeSelection) selection).iterator();
119
120 while (selectionIterator.hasNext()){
121 Object object = selectionIterator.next();
122 if(object instanceof TaxonNode){
123 TaxonNode taxonNode = (TaxonNode) object;
124 taxonNodes.add(taxonNode);
125 }
126 }
127 }
128 return taxonNodes.size() > 0 ? taxonNodes : null;
129 }
130
131 /* (non-Javadoc)
132 * @see org.eclipse.ui.navigator.CommonDropAdapter#validateDrop(java.lang.Object, int, org.eclipse.swt.dnd.TransferData)
133 */
134 /** {@inheritDoc} */
135 @Override
136 public boolean validateDrop(Object target, int operation,
137 TransferData transferType) {
138
139 if (target instanceof ITaxonTreeNode) {
140
141 // check users permissions with target taxonnode and taxon
142 if (target instanceof TaxonNode) {
143 TaxonNode targetNode = (TaxonNode)target;
144 Boolean hasTargetNodePermission = CdmStore.currentAuthentiationHasPermission(targetNode, UPDATE);
145 Boolean hasTargetTaxonPermission = CdmStore.currentAuthentiationHasPermission(targetNode.getTaxon(), UPDATE);
146
147 if(logger.isDebugEnabled()){
148 logger.debug("target: " + targetNode.getTaxon().getTitleCache());
149 }
150
151 if(!hasTargetNodePermission || ! hasTargetNodePermission){
152 if(logger.isDebugEnabled()){
153 logger.debug("CANCEL_STATUS for target node: " + hasTargetNodePermission.toString() + " " + hasTargetTaxonPermission.toString() + " ");
154 }
155 return false;
156 }
157 }
158
159 // do not allow to drop onto itself and
160 // check users permissions with all selected taxon nodes and taxa
161 for(TaxonNode taxonNode : getSelectedTaxa()){
162 logger.debug("selectedTaxa: " + taxonNode.getTaxon().getTitleCache());
163 Boolean isSameTaxonNode = taxonNode.equals(target);
164 Boolean hasTaxonNodePermission = CdmStore.currentAuthentiationHasPermission(taxonNode, UPDATE);
165 Boolean hasTaxonPermission = 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.toString() + " " + hasTaxonNodePermission.toString() + " " + hasTaxonPermission.toString() + " ");
173 }
174 return false;
175 }
176 }
177 logger.debug("OK_STATUS");
178 return true;
179 }
180 logger.debug("CANCEL_STATUS");
181 return false;
182 }
183
184
185 /**
186 * @param childTaxonNode
187 * @param parentTaxon
188 * @return
189 */
190 private boolean moveTaxon(TaxonNode taxonNode, 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(), "Unsaved Parent Taxon", "There are unsaved " +
201 "changes in the parent taxon. Pleas save first.");
202 return false;
203 }
204
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");
210 return false;
211 }
212
213 AbstractPostOperation operation = new MoveTaxonOperation
214 ("Move Taxon", workspaceUndoContext, taxonNode, targetITaxonTreeNode, this, taxonNavigator, true);
215 NavigationUtil.executeOperation(operation);
216
217 logger.info("Moved taxa to new parent " + targetITaxonTreeNode);
218 return true;
219 }else{
220 String[] buttonLables = {"Parent", "Predecessor", "Cancel"};
221 MessageDialog dialog = new MessageDialog(null, "Target node", null, "Do you want to use the target node as parent or do you want to move the taxon below the target.", 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");
228 return false;
229 }
230
231 AbstractPostOperation operation = new MoveTaxonOperation
232 ("Move Taxon", workspaceUndoContext, taxonNode, targetITaxonTreeNode, this, taxonNavigator, true);
233 NavigationUtil.executeOperation(operation);
234
235 logger.info("Moved taxa to new parent " + targetITaxonTreeNode);
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");
241 return false;
242 }
243
244 AbstractPostOperation operation = new MoveTaxonOperation
245 ("Move Taxon", workspaceUndoContext, taxonNode, targetITaxonTreeNode, this, taxonNavigator, false);
246 NavigationUtil.executeOperation(operation);
247
248 logger.info("Moved taxa to new parent " + targetITaxonTreeNode);
249 return true;
250 } else{
251 return false;
252 }
253
254
255 }
256 }
257
258 /* (non-Javadoc)
259 * @see eu.etaxonomy.taxeditor.operations.IPostOperationEnabled#postOperation(eu.etaxonomy.cdm.model.common.CdmBase)
260 */
261 /** {@inheritDoc} */
262 @Override
263 public boolean postOperation(CdmBase objectAffectedByOperation) {
264 return true;
265 }
266
267 /**
268 * <p>onComplete</p>
269 *
270 * @return a boolean.
271 */
272 @Override
273 public boolean onComplete() {
274 // TODO Auto-generated method stub
275 return false;
276 }
277 @Override
278 public void dragOver(DropTargetEvent event) {
279 super.dragOver(event);
280 event.feedback = DND.FEEDBACK_SELECT | DND.FEEDBACK_INSERT_AFTER;
281
282 }
283
284 }