001: /*******************************************************************************
002: * Copyright (c) 2003, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.navigator;
011:
012: import org.eclipse.core.runtime.IStatus;
013: import org.eclipse.jface.util.LocalSelectionTransfer;
014: import org.eclipse.jface.viewers.StructuredViewer;
015: import org.eclipse.swt.dnd.DND;
016: import org.eclipse.swt.dnd.DropTargetEvent;
017: import org.eclipse.swt.dnd.FileTransfer;
018: import org.eclipse.swt.dnd.Transfer;
019: import org.eclipse.swt.dnd.TransferData;
020: import org.eclipse.swt.graphics.Point;
021: import org.eclipse.swt.graphics.Rectangle;
022: import org.eclipse.swt.widgets.Item;
023: import org.eclipse.ui.internal.navigator.NavigatorPlugin;
024: import org.eclipse.ui.internal.navigator.dnd.NavigatorDnDService;
025: import org.eclipse.ui.internal.navigator.dnd.NavigatorPluginDropAction;
026: import org.eclipse.ui.part.PluginDropAdapter;
027: import org.eclipse.ui.part.PluginTransfer;
028:
029: /**
030: * Provides an implementation of {@link PluginDropAdapter} which uses the
031: * extensions provided by the associated {@link INavigatorContentService}.
032: *
033: * <p>
034: * Clients should not need to create an instance of this class unless they are
035: * creating their own custom viewer. Otherwise, {@link CommonViewer} configures
036: * its drop adapter automatically.
037: * </p>
038: *
039: *
040: * @see INavigatorDnDService
041: * @see CommonDragAdapter
042: * @see CommonDragAdapterAssistant
043: * @see CommonDropAdapterAssistant
044: * @see CommonViewer
045: * @since 3.2
046: */
047: public final class CommonDropAdapter extends PluginDropAdapter {
048:
049: private static final Transfer[] SUPPORTED_DROP_TRANSFERS = new Transfer[] {
050: LocalSelectionTransfer.getTransfer(),
051: FileTransfer.getInstance(), PluginTransfer.getInstance() };
052:
053: private static final boolean DEBUG = false;
054:
055: private final INavigatorContentService contentService;
056:
057: private final NavigatorDnDService dndService;
058:
059: /**
060: * Create a DropAdapter that handles a drop based on the given content
061: * service and selection provider.
062: *
063: * @param aContentService
064: * The content service this Drop Adapter is associated with
065: * @param aStructuredViewer
066: * The viewer this DropAdapter is associated with.
067: */
068: public CommonDropAdapter(INavigatorContentService aContentService,
069: StructuredViewer aStructuredViewer) {
070: super (aStructuredViewer);
071: contentService = aContentService;
072: dndService = (NavigatorDnDService) contentService
073: .getDnDService();
074: }
075:
076: /**
077: *
078: * @return An array of Transfers allowed by the CommonDropAdapter. Includes
079: * {@link LocalSelectionTransfer#getTransfer()},
080: * {@link FileTransfer#getInstance()},
081: * {@link PluginTransfer#getInstance()}.
082: * @see LocalSelectionTransfer
083: * @see FileTransfer
084: * @see PluginTransfer
085: */
086: public Transfer[] getSupportedDropTransfers() {
087: return SUPPORTED_DROP_TRANSFERS;
088: }
089:
090: /*
091: * (non-Javadoc)
092: *
093: * @see org.eclipse.jface.viewers.ViewerDropAdapter#dragEnter(org.eclipse.swt.dnd.DropTargetEvent)
094: */
095: public void dragEnter(DropTargetEvent event) {
096: super .dragEnter(event);
097:
098: for (int i = 0; i < event.dataTypes.length; i++) {
099: if (LocalSelectionTransfer.getTransfer().isSupportedType(
100: event.dataTypes[i])) {
101: event.currentDataType = event.dataTypes[i];
102: return;
103: }
104: }
105:
106: for (int i = 0; i < event.dataTypes.length; i++) {
107: if (FileTransfer.getInstance().isSupportedType(
108: event.dataTypes[i])) {
109: event.currentDataType = event.dataTypes[i];
110: event.detail = DND.DROP_COPY;
111: return;
112: }
113: }
114:
115: for (int i = 0; i < event.dataTypes.length; i++) {
116: if (PluginTransfer.getInstance().isSupportedType(
117: event.dataTypes[i])) {
118: event.currentDataType = event.dataTypes[i];
119: return;
120: }
121: }
122:
123: event.detail = DND.DROP_NONE;
124:
125: }
126:
127: /*
128: * (non-Javadoc)
129: *
130: * @see org.eclipse.swt.dnd.DropTargetAdapter#dragLeave(org.eclipse.swt.dnd.DropTargetEvent)
131: */
132: public void dragLeave(DropTargetEvent event) {
133: super .dragLeave(event);
134: if (LocalSelectionTransfer.getTransfer().isSupportedType(
135: event.currentDataType)) {
136: event.data = NavigatorPluginDropAction
137: .createTransferData(contentService);
138: }
139: }
140:
141: /*
142: * (non-Javadoc)
143: *
144: * @see org.eclipse.ui.part.PluginDropAdapter#drop(org.eclipse.swt.dnd.DropTargetEvent)
145: */
146: public void drop(DropTargetEvent event) {
147: if (PluginTransfer.getInstance().isSupportedType(
148: event.currentDataType)) {
149: super .drop(event);
150: } else {
151:
152: Object target = getCurrentTarget() != null ? getCurrentTarget()
153: : getViewer().getInput();
154:
155: CommonDropAdapterAssistant[] assistants = dndService
156: .findCommonDropAdapterAssistants(target,
157: getCurrentTransfer());
158:
159: IStatus valid = null;
160: for (int i = 0; i < assistants.length; i++) {
161: try {
162:
163: valid = assistants[i].validateDrop(
164: getCurrentTarget(), getCurrentOperation(),
165: getCurrentTransfer());
166: if (valid != null && valid.isOK()) {
167: assistants[i].handleDrop(this , event,
168: getCurrentTarget());
169: return;
170: }
171: } catch (Throwable t) {
172: NavigatorPlugin.logError(0, t.getMessage(), t);
173: }
174: }
175: }
176: }
177:
178: /*
179: * (non-Javadoc)
180: *
181: * @see org.eclipse.jface.viewers.ViewerDropAdapter#validateDrop(java.lang.Object,
182: * int, org.eclipse.swt.dnd.TransferData)
183: */
184: public boolean validateDrop(Object aDropTarget,
185: int theDropOperation, TransferData theTransferData) {
186:
187: if (DEBUG) {
188: System.out
189: .println("CommonDropAdapter.validateDrop (begin)"); //$NON-NLS-1$
190: }
191:
192: boolean result = false;
193:
194: IStatus valid = null;
195:
196: if (super .validateDrop(aDropTarget, theDropOperation,
197: theTransferData)) {
198: result = true;
199: } else {
200:
201: Object target = aDropTarget != null ? aDropTarget
202: : getViewer().getInput();
203: CommonDropAdapterAssistant[] assistants = dndService
204: .findCommonDropAdapterAssistants(target,
205: theTransferData);
206: if (DEBUG) {
207: System.out
208: .println("CommonDropAdapter.validateDrop found " + assistants.length + " drop assistants"); //$NON-NLS-1$//$NON-NLS-2$
209: for (int i = 0; i < assistants.length; i++)
210: System.out
211: .println("CommonDropAdapter.validateDrop :" + assistants[i].getClass().getName()); //$NON-NLS-1$
212:
213: }
214: for (int i = 0; i < assistants.length; i++) {
215: try {
216: valid = assistants[i].validateDrop(target,
217: theDropOperation, theTransferData);
218: } catch (Throwable t) {
219: NavigatorPlugin.logError(0, t.getMessage(), t);
220: }
221: if (valid != null && valid.isOK()) {
222: result = true;
223: if (DEBUG) {
224: System.out
225: .println("CommonDropAdapter.validateDrop found \"" + assistants[i].getClass().getName() + "\" would handle drop."); //$NON-NLS-1$ //$NON-NLS-2$
226: }
227: break;
228: }
229: }
230: }
231:
232: if (DEBUG) {
233: System.out
234: .println("CommonDropAdapter.validateDrop (returning " + (valid != null ? valid.getSeverity() + ": " + valid.getMessage() : "" + result) + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
235: }
236:
237: setScrollExpandEnabled(result);
238: return result;
239:
240: }
241:
242: /*
243: * The visibility of the following methods is raised for downstream clients
244: * (assistants).
245: */
246:
247: /*
248: * (non-Javadoc)
249: *
250: * @see org.eclipse.jface.viewers.ViewerDropAdapter#getBounds(org.eclipse.swt.widgets.Item)
251: */
252: public Rectangle getBounds(Item item) {
253: return super .getBounds(item);
254: }
255:
256: /*
257: * (non-Javadoc)
258: *
259: * @see org.eclipse.jface.viewers.ViewerDropAdapter#getCurrentLocation()
260: */
261: public int getCurrentLocation() {
262: return super .getCurrentLocation();
263: }
264:
265: /*
266: * (non-Javadoc)
267: *
268: * @see org.eclipse.jface.viewers.ViewerDropAdapter#getCurrentOperation()
269: */
270: public int getCurrentOperation() {
271: return super .getCurrentOperation();
272: }
273:
274: /*
275: * (non-Javadoc)
276: *
277: * @see org.eclipse.jface.viewers.ViewerDropAdapter#getCurrentTarget()
278: */
279: public Object getCurrentTarget() {
280: return super .getCurrentTarget();
281: }
282:
283: /*
284: * (non-Javadoc)
285: *
286: * @see org.eclipse.ui.part.PluginDropAdapter#getCurrentTransfer()
287: */
288: public TransferData getCurrentTransfer() {
289: return super .getCurrentTransfer();
290: }
291:
292: /**
293: * Returns the position of the given event's coordinates relative to its target.
294: * The position is determined to be before, after, or on the item, based on
295: * some threshold value.
296: *
297: * @param event the event
298: * @return one of the <code>LOCATION_* </code>constants defined in this class
299: */
300: protected int determineLocation(DropTargetEvent event) {
301: if (!(event.item instanceof Item)) {
302: return LOCATION_NONE;
303: }
304: // Item item = (Item) event.item;
305: Point coordinates = new Point(event.x, event.y);
306: coordinates = getViewer().getControl().toControl(coordinates);
307: // if (item != null) {
308: // Rectangle bounds = getBounds(item);
309: // if (bounds == null) {
310: // return LOCATION_NONE;
311: // }
312: // if ((coordinates.y - bounds.y) < 5) {
313: // return LOCATION_BEFORE;
314: // }
315: // if ((bounds.y + bounds.height - coordinates.y) < 5) {
316: // return LOCATION_AFTER;
317: // }
318: // }
319: return LOCATION_ON;
320: }
321:
322: }
|