1
|
/*******************************************************************************
|
2
|
* Copyright (c) 2003, 2010 IBM Corporation and others.
|
3
|
* All rights reserved. This program and the accompanying materials
|
4
|
* are made available under the terms of the Eclipse Public License v1.0
|
5
|
* which accompanies this distribution, and is available at
|
6
|
* http://www.eclipse.org/legal/epl-v10.html
|
7
|
*
|
8
|
* Contributors:
|
9
|
* IBM Corporation - initial API and implementation
|
10
|
* ken.ryall@nokia.com - 157506 drop from external sources does not work on Linux/Mac
|
11
|
*******************************************************************************/
|
12
|
package org.eclipse.ui.navigator;
|
13
|
|
14
|
import org.eclipse.core.runtime.IStatus;
|
15
|
import org.eclipse.core.runtime.SafeRunner;
|
16
|
import org.eclipse.jface.util.LocalSelectionTransfer;
|
17
|
import org.eclipse.jface.viewers.StructuredViewer;
|
18
|
import org.eclipse.swt.dnd.DND;
|
19
|
import org.eclipse.swt.dnd.DropTargetEvent;
|
20
|
import org.eclipse.swt.dnd.FileTransfer;
|
21
|
import org.eclipse.swt.dnd.Transfer;
|
22
|
import org.eclipse.swt.dnd.TransferData;
|
23
|
import org.eclipse.swt.graphics.Rectangle;
|
24
|
import org.eclipse.swt.widgets.Item;
|
25
|
import org.eclipse.ui.internal.navigator.NavigatorSafeRunnable;
|
26
|
import org.eclipse.ui.internal.navigator.Policy;
|
27
|
import org.eclipse.ui.internal.navigator.dnd.NavigatorPluginDropAction;
|
28
|
import org.eclipse.ui.part.PluginDropAdapter;
|
29
|
import org.eclipse.ui.part.PluginTransfer;
|
30
|
|
31
|
/**
|
32
|
* Provides an implementation of {@link PluginDropAdapter} which uses the
|
33
|
* extensions provided by the associated {@link INavigatorContentService}.
|
34
|
*
|
35
|
* <p>
|
36
|
* Clients should not need to create an instance of this class unless they are
|
37
|
* creating their own custom viewer. Otherwise, {@link CommonViewer} configures
|
38
|
* its drop adapter automatically.
|
39
|
* </p>
|
40
|
*
|
41
|
*
|
42
|
* @see INavigatorDnDService
|
43
|
* @see CommonDragAdapter
|
44
|
* @see CommonDragAdapterAssistant
|
45
|
* @see CommonDropAdapterAssistant
|
46
|
* @see CommonViewer
|
47
|
* @since 3.2
|
48
|
*/
|
49
|
public final class CommonDropAdapter extends PluginDropAdapter {
|
50
|
|
51
|
private static final Transfer[] SUPPORTED_DROP_TRANSFERS = new Transfer[] {
|
52
|
LocalSelectionTransfer.getTransfer(), FileTransfer.getInstance(),
|
53
|
PluginTransfer.getInstance() };
|
54
|
|
55
|
private final INavigatorContentService contentService;
|
56
|
|
57
|
private final INavigatorDnDService dndService;
|
58
|
|
59
|
/**
|
60
|
* Create a DropAdapter that handles a drop based on the given content
|
61
|
* service and selection provider.
|
62
|
*
|
63
|
* @param aContentService
|
64
|
* The content service this Drop Adapter is associated with
|
65
|
* @param aStructuredViewer
|
66
|
* The viewer this DropAdapter is associated with.
|
67
|
*/
|
68
|
public CommonDropAdapter(INavigatorContentService aContentService,
|
69
|
StructuredViewer aStructuredViewer) {
|
70
|
super(aStructuredViewer);
|
71
|
contentService = aContentService;
|
72
|
dndService = contentService.getDnDService();
|
73
|
setFeedbackEnabled(false);
|
74
|
}
|
75
|
|
76
|
/**
|
77
|
*
|
78
|
* @return An array of Transfers allowed by the CommonDropAdapter. Includes
|
79
|
* {@link LocalSelectionTransfer#getTransfer()},
|
80
|
* {@link FileTransfer#getInstance()},
|
81
|
* {@link PluginTransfer#getInstance()}.
|
82
|
* @see LocalSelectionTransfer
|
83
|
* @see FileTransfer
|
84
|
* @see PluginTransfer
|
85
|
*/
|
86
|
public Transfer[] getSupportedDropTransfers() {
|
87
|
return SUPPORTED_DROP_TRANSFERS;
|
88
|
}
|
89
|
|
90
|
/*
|
91
|
* (non-Javadoc)
|
92
|
*
|
93
|
* @see org.eclipse.jface.viewers.ViewerDropAdapter#dragEnter(org.eclipse.swt.dnd.DropTargetEvent)
|
94
|
*/
|
95
|
public void dragEnter(DropTargetEvent event) {
|
96
|
|
97
|
if (event.detail == DND.DROP_NONE)
|
98
|
return;
|
99
|
|
100
|
if (Policy.DEBUG_DND) {
|
101
|
System.out.println("CommonDropAdapter.dragEnter: " + event); //$NON-NLS-1$
|
102
|
}
|
103
|
for (int i = 0; i < event.dataTypes.length; i++) {
|
104
|
if (LocalSelectionTransfer.getTransfer().isSupportedType(
|
105
|
event.dataTypes[i])) {
|
106
|
event.currentDataType = event.dataTypes[i];
|
107
|
if (Policy.DEBUG_DND) {
|
108
|
System.out.println("CommonDropAdapter.dragEnter: local selection: " + event.currentDataType); //$NON-NLS-1$
|
109
|
}
|
110
|
super.dragEnter(event);
|
111
|
return;
|
112
|
}
|
113
|
}
|
114
|
|
115
|
for (int i = 0; i < event.dataTypes.length; i++) {
|
116
|
if (FileTransfer.getInstance().isSupportedType(event.dataTypes[i])) {
|
117
|
event.currentDataType = event.dataTypes[i];
|
118
|
event.detail = DND.DROP_COPY;
|
119
|
if (Policy.DEBUG_DND) {
|
120
|
System.out.println("CommonDropAdapter.dragEnter: file: " + event.currentDataType); //$NON-NLS-1$
|
121
|
}
|
122
|
super.dragEnter(event);
|
123
|
return;
|
124
|
}
|
125
|
}
|
126
|
|
127
|
for (int i = 0; i < event.dataTypes.length; i++) {
|
128
|
if (PluginTransfer.getInstance()
|
129
|
.isSupportedType(event.dataTypes[i])) {
|
130
|
event.currentDataType = event.dataTypes[i];
|
131
|
if (Policy.DEBUG_DND) {
|
132
|
System.out.println("CommonDropAdapter.dragEnter: plugin: " + event.currentDataType); //$NON-NLS-1$
|
133
|
}
|
134
|
super.dragEnter(event);
|
135
|
return;
|
136
|
}
|
137
|
}
|
138
|
|
139
|
event.detail = DND.DROP_NONE;
|
140
|
|
141
|
}
|
142
|
|
143
|
/*
|
144
|
* (non-Javadoc)
|
145
|
*
|
146
|
* @see org.eclipse.swt.dnd.DropTargetAdapter#dragLeave(org.eclipse.swt.dnd.DropTargetEvent)
|
147
|
*/
|
148
|
public void dragLeave(DropTargetEvent event) {
|
149
|
super.dragLeave(event);
|
150
|
if (LocalSelectionTransfer.getTransfer().isSupportedType(
|
151
|
event.currentDataType)) {
|
152
|
event.data = NavigatorPluginDropAction
|
153
|
.createTransferData(contentService);
|
154
|
}
|
155
|
}
|
156
|
|
157
|
public boolean performDrop(Object data) {
|
158
|
final DropTargetEvent event = getCurrentEvent();
|
159
|
if (Policy.DEBUG_DND) {
|
160
|
System.out.println("CommonDropAdapter.drop (begin): " + event); //$NON-NLS-1$
|
161
|
}
|
162
|
final Object target = getCurrentTarget() != null ?
|
163
|
getCurrentTarget() : getViewer().getInput();
|
164
|
|
165
|
// Must validate the drop here because on some platforms (Linux, Mac) the event
|
166
|
// is not populated with the correct currentDataType until the drop actually
|
167
|
// happens, and validateDrop sets the currentTransfer based on that. The
|
168
|
// call to validateDrop in dragAccept is too early.
|
169
|
validateDrop(target, getCurrentOperation(), event.currentDataType);
|
170
|
if (PluginTransfer.getInstance().isSupportedType(event.currentDataType)) {
|
171
|
super.drop(event);
|
172
|
return true;
|
173
|
}
|
174
|
|
175
|
if (Policy.DEBUG_DND) {
|
176
|
System.out.println("CommonDropAdapter.drop target: " + target + " op: " + getCurrentOperation()); //$NON-NLS-1$ //$NON-NLS-2$
|
177
|
}
|
178
|
final CommonDropAdapterAssistant[] assistants = dndService.findCommonDropAdapterAssistants(target,
|
179
|
getCurrentTransfer());
|
180
|
|
181
|
final boolean[] retValue = new boolean[1];
|
182
|
for (int i = 0; i < assistants.length; i++) {
|
183
|
final CommonDropAdapterAssistant localAssistant = assistants[i];
|
184
|
SafeRunner.run(new NavigatorSafeRunnable() {
|
185
|
public void run() throws Exception {
|
186
|
localAssistant.setCurrentEvent(event);
|
187
|
IStatus valid = localAssistant.validateDrop(target, getCurrentOperation(),
|
188
|
getCurrentTransfer());
|
189
|
if (valid != null && valid.isOK()) {
|
190
|
if (Policy.DEBUG_DND) {
|
191
|
System.out
|
192
|
.println("CommonDropAdapter.drop assistant selected: " + localAssistant + " op: " + event.detail); //$NON-NLS-1$ //$NON-NLS-2$
|
193
|
}
|
194
|
localAssistant.handleDrop(CommonDropAdapter.this, event, target);
|
195
|
retValue[0] = true;
|
196
|
}
|
197
|
}
|
198
|
});
|
199
|
if (retValue[0])
|
200
|
return true;
|
201
|
}
|
202
|
|
203
|
return false;
|
204
|
}
|
205
|
|
206
|
/*
|
207
|
* (non-Javadoc)
|
208
|
*
|
209
|
* @see org.eclipse.jface.viewers.ViewerDropAdapter#validateDrop(java.lang.Object,
|
210
|
* int, org.eclipse.swt.dnd.TransferData)
|
211
|
*/
|
212
|
public boolean validateDrop(final Object aDropTarget, final int theDropOperation,
|
213
|
final TransferData theTransferData) {
|
214
|
|
215
|
if (Policy.DEBUG_DND) {
|
216
|
System.out.println("CommonDropAdapter.validateDrop (begin) operation: " + theDropOperation + " target: " + aDropTarget /*+ " transferType: " + theTransferData.type*/); //$NON-NLS-1$ //$NON-NLS-2$
|
217
|
//new Exception().printStackTrace(System.out);
|
218
|
}
|
219
|
|
220
|
boolean result = false;
|
221
|
final IStatus[] valid = new IStatus[1];
|
222
|
|
223
|
if (super.validateDrop(aDropTarget, theDropOperation, theTransferData)) {
|
224
|
result = true;
|
225
|
if (Policy.DEBUG_DND) {
|
226
|
System.out.println("CommonDropAdapter.validateDrop valid for plugin transfer"); //$NON-NLS-1$
|
227
|
}
|
228
|
} else {
|
229
|
final Object target = aDropTarget != null ? aDropTarget : getViewer().getInput();
|
230
|
if (Policy.DEBUG_DND) {
|
231
|
System.out.println("CommonDropAdapter.validateDrop target: " + target); //$NON-NLS-1$
|
232
|
System.out.println("CommonDropAdapter.validateDrop local selection: " + //$NON-NLS-1$
|
233
|
LocalSelectionTransfer.getTransfer().getSelection());
|
234
|
}
|
235
|
CommonDropAdapterAssistant[] assistants = dndService.findCommonDropAdapterAssistants(
|
236
|
target, theTransferData);
|
237
|
for (int i = 0; i < assistants.length; i++) {
|
238
|
if (Policy.DEBUG_DND) {
|
239
|
System.out
|
240
|
.println("CommonDropAdapter.validateDrop checking assistant: \"" + assistants[i]); //$NON-NLS-1$
|
241
|
}
|
242
|
final CommonDropAdapterAssistant assistantLocal = assistants[i];
|
243
|
|
244
|
SafeRunner.run(new NavigatorSafeRunnable() {
|
245
|
public void run() throws Exception {
|
246
|
assistantLocal.setCurrentEvent(getCurrentEvent());
|
247
|
valid[0] = assistantLocal.validateDrop(target, theDropOperation,
|
248
|
theTransferData);
|
249
|
}
|
250
|
});
|
251
|
if (valid[0] != null && valid[0].isOK()) {
|
252
|
result = true;
|
253
|
if (Policy.DEBUG_DND) {
|
254
|
System.out.println("CommonDropAdapter.validateDrop VALID"); //$NON-NLS-1$
|
255
|
}
|
256
|
break;
|
257
|
}
|
258
|
if (Policy.DEBUG_DND) {
|
259
|
System.out
|
260
|
.println("CommonDropAdapter.validateDrop NOT valid: " + (valid[0] != null ? (valid[0].getSeverity() + ": " + valid[0].getMessage()) : "")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
261
|
}
|
262
|
}
|
263
|
}
|
264
|
|
265
|
if (Policy.DEBUG_DND) {
|
266
|
System.out
|
267
|
.println("CommonDropAdapter.validateDrop (returning " + (valid[0] != null ? valid[0].getSeverity() + ": " + valid[0].getMessage() : "" + result) + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
268
|
}
|
269
|
|
270
|
setScrollExpandEnabled(true);
|
271
|
return result;
|
272
|
|
273
|
}
|
274
|
|
275
|
/*
|
276
|
* The visibility of the following methods is raised for downstream clients
|
277
|
* (assistants).
|
278
|
*/
|
279
|
|
280
|
/*
|
281
|
* (non-Javadoc)
|
282
|
*
|
283
|
* @see org.eclipse.jface.viewers.ViewerDropAdapter#getBounds(org.eclipse.swt.widgets.Item)
|
284
|
*/
|
285
|
public Rectangle getBounds(Item item) {
|
286
|
return super.getBounds(item);
|
287
|
}
|
288
|
|
289
|
/*
|
290
|
* (non-Javadoc)
|
291
|
*
|
292
|
* @see org.eclipse.jface.viewers.ViewerDropAdapter#getCurrentLocation()
|
293
|
*/
|
294
|
public int getCurrentLocation() {
|
295
|
return super.getCurrentLocation();
|
296
|
}
|
297
|
|
298
|
/*
|
299
|
* (non-Javadoc)
|
300
|
*
|
301
|
* @see org.eclipse.jface.viewers.ViewerDropAdapter#getCurrentOperation()
|
302
|
*/
|
303
|
public int getCurrentOperation() {
|
304
|
return super.getCurrentOperation();
|
305
|
}
|
306
|
|
307
|
/**
|
308
|
* @see org.eclipse.jface.viewers.ViewerDropAdapter#overrideOperation(int)
|
309
|
* @since 3.4
|
310
|
*/
|
311
|
public void overrideOperation(int operation) {
|
312
|
if (Policy.DEBUG_DND) {
|
313
|
System.out.println("CommonDropAdapter.overrideOperation: " + operation); //$NON-NLS-1$
|
314
|
}
|
315
|
super.overrideOperation(operation);
|
316
|
}
|
317
|
|
318
|
/*
|
319
|
* (non-Javadoc)
|
320
|
*
|
321
|
* @see org.eclipse.jface.viewers.ViewerDropAdapter#getCurrentTarget()
|
322
|
*/
|
323
|
public Object getCurrentTarget() {
|
324
|
return super.getCurrentTarget();
|
325
|
}
|
326
|
|
327
|
/*
|
328
|
* (non-Javadoc)
|
329
|
*
|
330
|
* @see org.eclipse.ui.part.PluginDropAdapter#getCurrentTransfer()
|
331
|
*/
|
332
|
public TransferData getCurrentTransfer() {
|
333
|
return super.getCurrentTransfer();
|
334
|
}
|
335
|
|
336
|
|
337
|
}
|