1 /******************************************************************************* 2 * Copyright (c) 2003, 2015 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.ui.navigator; 15 16 import org.eclipse.core.runtime.IStatus; 17 import org.eclipse.core.runtime.Status; 18 import org.eclipse.jface.util.LocalSelectionTransfer; 19 import org.eclipse.jface.viewers.IStructuredSelection; 20 import org.eclipse.swt.dnd.DragSourceListener; 21 import org.eclipse.swt.dnd.DropTargetEvent; 22 import org.eclipse.swt.dnd.DropTargetListener; 23 import org.eclipse.swt.dnd.TransferData; 24 import org.eclipse.swt.widgets.Shell; 25 import org.eclipse.ui.internal.navigator.NavigatorContentService; 26 27 /** 28 * <p> 29 * Used by the 30 * <b>org.eclipse.ui.navigator.navigatorContent/navigatorContent/commonDropAdapter</b> 31 * extension point to carry out pluggable drop operations. 32 * </p> 33 * <p> 34 * Each {@link CommonDropAdapterAssistant} is contained by single content 35 * extension. The opportunity for each assistant to handle the drop operation is 36 * determined by the <b>possibleChildren</b> expression of the 37 * <b>org.eclipse.ui.navigator.navigatorContent/navigatorContent</b> extension; 38 * whenever every element in the drag set matches the <b>possibleChildren</b> 39 * expression of an extension, it is eligible to handle the drop operation. This 40 * initial set is further culled using the <b>possibleDropTargets</b> expression 41 * of the <b>commonDropAdapter</b> using the current drop target. 42 * </p> 43 * <p> 44 * If drag operations originate outside of Eclipse, then the set of eligible 45 * drop adapters is determined based on the drop target (using the 46 * <b>possibleDropTargets</b> expression). Each assistant can then indicate 47 * whether {@link #isSupportedType(TransferData) the incoming type is 48 * supported}. 49 * <p> 50 * Whenever a match is found, the assistant will be given an opportunity to 51 * first {@link #validateDrop(Object, int, TransferData)}, and then if the 52 * assistant returns true, the assist must 53 * {@link #handleDrop(CommonDropAdapter, DropTargetEvent, Object)}. If multiple 54 * assistants match the drop target, then the potential assistants are ordered 55 * based on priority and their override relationships and given an opportunity 56 * to validate the drop operation in turn. The first one to validate will have 57 * the opportunty to carry out the drop. 58 * </p> 59 * 60 * <p> 61 * Clients may handle DND operations that begin and end in the current viewer by 62 * overriding the following methods: 63 * </p> 64 * <ul> 65 * <li>{@link #validateDrop(Object, int, TransferData)}: Indicate whether this 66 * assistant can handle a drop onto the current viewer.</li> 67 * <li>{@link #handleDrop(CommonDropAdapter, DropTargetEvent, Object)}: Handle 68 * the drop operation onto the current viewer.</li> 69 * </ul> 70 * <p> 71 * If a user originates a drag operation to another viewer that cannot handle 72 * one of the available drag transfer types, drop assistants may handle the drop 73 * operation for the target viewer. Clients must override : 74 * </p> 75 * <ul> 76 * <li>{@link #validatePluginTransferDrop(IStructuredSelection, Object)}: 77 * Indicate whether this assistant can handle the drop onto another viewer. 78 * <li>{@link #handlePluginTransferDrop(IStructuredSelection, Object)}: Handle 79 * the drop operation onto the other viewer.</li> 80 * </ul> 81 * <p> 82 * Clients may subclass this. 83 * </p> 84 * 85 * @see INavigatorDnDService 86 * @see INavigatorDnDService#findCommonDropAdapterAssistants(Object, 87 * TransferData) 88 * @since 3.2 89 * 90 */ 91 public abstract class CommonDropAdapterAssistant { 92 93 private INavigatorContentService contentService; 94 95 private DropTargetEvent _currentEvent; 96 97 private CommonDropAdapter _dropAdapter; 98 99 /** 100 * Perform any necessary initialization using the 101 * {@link INavigatorContentService}. 102 * 103 * 104 * @param aContentService 105 * The instance of {@link INavigatorContentService} that the 106 * current CommonDropAdapterAssistant will be associated with 107 */ init(INavigatorContentService aContentService)108 public final void init(INavigatorContentService aContentService) { 109 contentService = aContentService; 110 doInit(); 111 } 112 113 114 /** 115 * Override to perform any one-time initialization. 116 */ doInit()117 protected void doInit() { 118 119 } 120 121 /** 122 * Validates dropping on the given object. This method is called whenever 123 * some aspect of the drop operation changes. 124 * <p> 125 * Subclasses must implement this method to define which drops make sense. 126 * If clients return true, then they will be allowed to handle the drop in 127 * {@link #handleDrop(CommonDropAdapter, DropTargetEvent, Object) }. 128 * </p> 129 * 130 * @param target 131 * the object that the mouse is currently hovering over, or 132 * <code>null</code> if the mouse is hovering over empty space 133 * @param operation 134 * the current drag operation (copy, move, etc.) 135 * @param transferType 136 * the current transfer type 137 * @return A status indicating whether the drop is valid. 138 */ validateDrop(Object target, int operation, TransferData transferType)139 public abstract IStatus validateDrop(Object target, int operation, 140 TransferData transferType); 141 142 /** 143 * Carry out the DND operation. 144 * 145 * <p> 146 * Note: Contrary to the SWT {@link DropTargetListener} specification, you 147 * <i>must</i> make sure that the aDropTargetEvent.detail is not set to 148 * DND.DROP_MOVE unless actual work is required in the 149 * {@link DragSourceListener#dragFinished(org.eclipse.swt.dnd.DragSourceEvent)} 150 * to complete the operation (for example removing the moved file). In 151 * particular for the LocalSelectionTransfer case, DND.DROP_MOVE cannot be 152 * used as it will cause incorrect behavior in some existing drag handlers. 153 * 154 * In case of move operations where no action is required on the source side 155 * (e.g. LocalSelectionTransfer) you must set aDropTargetEvent.detail to 156 * DND.DROP_NONE to signal this to the drag source. Even though the SWT 157 * specification says this is canceling the drop, it is not really doing so, 158 * it is only preventing the DND.DROP_MOVE from being passed through to the 159 * dragFinished() method. 160 * 161 * @param aDropAdapter 162 * The Drop Adapter contains information that has already been 163 * parsed from the drop event. 164 * @param aDropTargetEvent 165 * The drop target event. 166 * @param aTarget 167 * The object being dragged onto 168 * @return A status indicating whether the drop completed OK. 169 */ handleDrop(CommonDropAdapter aDropAdapter, DropTargetEvent aDropTargetEvent, Object aTarget)170 public abstract IStatus handleDrop(CommonDropAdapter aDropAdapter, 171 DropTargetEvent aDropTargetEvent, Object aTarget); 172 173 /** 174 * Clients may extend the supported transfer types beyond the default 175 * {@link LocalSelectionTransfer#getTransfer()} and 176 * {@link org.eclipse.ui.part.PluginTransfer#getInstance()} transfer types. When a transfer type 177 * other than one of these is encountered, the DND Service will query the 178 * <b>visible</b> and <b>active</b> descriptors that are <b>enabled</b> 179 * for the drop target of the current operation. 180 * 181 * @param aTransferType 182 * The transfer data from the drop operation 183 * @return True if the given TransferData can be understood by this 184 * assistant. 185 */ isSupportedType(TransferData aTransferType)186 public boolean isSupportedType(TransferData aTransferType) { 187 return LocalSelectionTransfer.getTransfer().isSupportedType( 188 aTransferType); 189 } 190 191 /** 192 * 193 * Return true if the client can handle the drop onto the target viewer of 194 * the drop operation. 195 * <p> 196 * The default behavior of this method is to return <b>Status.CANCEL_STATUS</b>. 197 * </p> 198 * 199 * @param aDragSelection 200 * The selection dragged from the viewer. 201 * @param aDropTarget 202 * The target of the drop operation. 203 * 204 * @return OK if the plugin transfer can be handled by this assistant. 205 */ validatePluginTransferDrop( IStructuredSelection aDragSelection, Object aDropTarget)206 public IStatus validatePluginTransferDrop( 207 IStructuredSelection aDragSelection, Object aDropTarget) { 208 return Status.CANCEL_STATUS; 209 } 210 211 /** 212 * Handle the drop operation for the target viewer. 213 * <p> 214 * The default behavior of this method is to return <b>Status.CANCEL_STATUS</b>. 215 * </p> 216 * 217 * @param aDragSelection 218 * The selection dragged from the viewer. 219 * @param aDropTarget 220 * The target of the drop operation. 221 * 222 * @return OK if the drop operation succeeded. 223 */ handlePluginTransferDrop( IStructuredSelection aDragSelection, Object aDropTarget)224 public IStatus handlePluginTransferDrop( 225 IStructuredSelection aDragSelection, Object aDropTarget) { 226 return Status.CANCEL_STATUS; 227 } 228 229 /** 230 * 231 * @return The associated content service. 232 */ getContentService()233 protected INavigatorContentService getContentService() { 234 return contentService; 235 } 236 237 /** 238 * 239 * @return A shell for the viewer currently used by the 240 * {@link INavigatorContentService}. 241 */ getShell()242 protected final Shell getShell() { 243 return ((NavigatorContentService) contentService).getShell(); 244 } 245 246 /** 247 * Sets the current {@link DropTargetEvent}. 248 * 249 * This is used to make the event available to the client methods of this class. 250 * 251 * @param event 252 * the new event. 253 * 254 * @since 3.4 255 */ setCurrentEvent(DropTargetEvent event)256 void setCurrentEvent(DropTargetEvent event) { 257 _currentEvent = event; 258 } 259 260 /** 261 * Returns the current {@link DropTargetEvent}. 262 * 263 * @return event the current DropTargetEvent. 264 * 265 * @since 3.4 266 */ getCurrentEvent()267 public DropTargetEvent getCurrentEvent() { 268 return _currentEvent; 269 } 270 271 /** 272 * Sets the {@link CommonDropAdapter}. 273 * 274 * @param dropAdapter the drop adapter 275 * 276 * @noreference This method is not intended to be referenced by clients. 277 * @nooverride This method is not intended to be re-implemented or extended by 278 * clients. 279 */ setCommonDropAdapter(CommonDropAdapter dropAdapter)280 public void setCommonDropAdapter(CommonDropAdapter dropAdapter) { 281 _dropAdapter = dropAdapter; 282 } 283 284 /** 285 * Returns the {@link CommonDropAdapter}. 286 * 287 * @return the CommonDropAdapter. 288 * 289 * @since 3.4 290 * 291 */ getCommonDropAdapter()292 protected CommonDropAdapter getCommonDropAdapter() { 293 return _dropAdapter; 294 } 295 296 } 297