001: /**
002: *
003: */package net.refractions.udig.ui;
004:
005: import java.util.Iterator;
006: import java.util.Set;
007: import java.util.concurrent.CopyOnWriteArrayList;
008:
009: import net.refractions.udig.internal.ui.IDropTargetProvider;
010: import net.refractions.udig.internal.ui.UDIGControlDragListener;
011: import net.refractions.udig.internal.ui.UDIGControlDropListener;
012: import net.refractions.udig.internal.ui.UDIGDNDProcessor;
013: import net.refractions.udig.internal.ui.UDIGTransfer;
014: import net.refractions.udig.internal.ui.UDIGViewerDropAdapter;
015:
016: import org.eclipse.core.runtime.IProgressMonitor;
017: import org.eclipse.jface.viewers.ISelectionChangedListener;
018: import org.eclipse.jface.viewers.ISelectionProvider;
019: import org.eclipse.jface.viewers.IStructuredSelection;
020: import org.eclipse.jface.viewers.SelectionChangedEvent;
021: import org.eclipse.jface.viewers.StructuredViewer;
022: import org.eclipse.swt.dnd.DND;
023: import org.eclipse.swt.dnd.DragSource;
024: import org.eclipse.swt.dnd.DragSourceListener;
025: import org.eclipse.swt.dnd.DropTarget;
026: import org.eclipse.swt.dnd.DropTargetEvent;
027: import org.eclipse.swt.dnd.FileTransfer;
028: import org.eclipse.swt.dnd.HTMLTransfer;
029: import org.eclipse.swt.dnd.RTFTransfer;
030: import org.eclipse.swt.dnd.TextTransfer;
031: import org.eclipse.swt.dnd.Transfer;
032: import org.eclipse.swt.graphics.Image;
033: import org.eclipse.swt.widgets.Composite;
034: import org.eclipse.swt.widgets.Control;
035: import org.eclipse.ui.IEditorInput;
036: import org.eclipse.ui.IEditorPart;
037: import org.eclipse.ui.IEditorSite;
038: import org.eclipse.ui.IPropertyListener;
039: import org.eclipse.ui.IWorkbenchPartSite;
040: import org.eclipse.ui.PartInitException;
041: import org.eclipse.ui.PlatformUI;
042: import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
043:
044: /**
045: * Useful methods for adding drag and drop support to controls or
046: * viewers. It hooks up the control with the udig drag and drop
047: * framework.
048: *
049: * @author jones
050: *
051: */
052: public class UDIGDragDropUtilities {
053:
054: /**
055: * This class listens for selection events and enables and disables the applicable transfer types.
056: *
057: * @author jones
058: * @since 1.0.0
059: */
060: private static class DragController implements
061: ISelectionChangedListener {
062: private static final Transfer[] EMPTY = new Transfer[0];
063: private DragSource dragSource;
064: private Set<Transfer> transfers;
065:
066: public DragController(DragSource dragSourceA,
067: Set<Transfer> transfersA) {
068: this .dragSource = dragSourceA;
069: transfers = transfersA;
070: }
071:
072: public void selectionChanged(SelectionChangedEvent event) {
073: if (event.getSelection() == null) {
074: dragSource.setTransfer(EMPTY);
075: }
076:
077: IStructuredSelection selection = (IStructuredSelection) event
078: .getSelection();
079: setTransfers(selection);
080: }
081:
082: private void setTransfers(IStructuredSelection selection) {
083: CopyOnWriteArrayList<Transfer> toSet = new CopyOnWriteArrayList<Transfer>(
084: transfers);
085:
086: for (Iterator iter = selection.iterator(); iter.hasNext();) {
087: if (toSet.isEmpty())
088: break;
089: Object element = iter.next();
090:
091: for (Transfer transfer : toSet) {
092: if (transfer instanceof UDIGTransfer) {
093: UDIGTransfer t = (UDIGTransfer) transfer;
094: if (!t.validate(element))
095: toSet.remove(t);
096: continue;
097: }
098: if (transfer instanceof TextTransfer) {
099: TextTransfer t = (TextTransfer) transfer;
100: try {
101: t.javaToNative(element, t
102: .getSupportedTypes()[0]);
103: } catch (Exception e) {
104: toSet.remove(t);
105: }
106: }
107: if (transfer instanceof FileTransfer) {
108: FileTransfer t = (FileTransfer) transfer;
109: try {
110: t.javaToNative(element, t
111: .getSupportedTypes()[0]);
112: } catch (Exception e) {
113: toSet.remove(t);
114: }
115: }
116: if (transfer instanceof RTFTransfer) {
117: RTFTransfer t = (RTFTransfer) transfer;
118: try {
119: t.javaToNative(element, t
120: .getSupportedTypes()[0]);
121: } catch (Exception e) {
122: toSet.remove(t);
123: }
124: }
125: if (transfer instanceof HTMLTransfer) {
126: HTMLTransfer t = (HTMLTransfer) transfer;
127: try {
128: t.javaToNative(element, t
129: .getSupportedTypes()[0]);
130: } catch (Exception e) {
131: toSet.remove(t);
132: }
133: }
134: }
135: }
136:
137: if (toSet.isEmpty())
138: dragSource.setTransfer(EMPTY);
139: else
140: dragSource.setTransfer(toSet.toArray(new Transfer[toSet
141: .size()]));
142: }
143:
144: }
145:
146: /**
147: * Adds both drag and drop support to the StructuredViewer.
148: * <p>For this to work the destination object must have a dropAction extension
149: * defined for it.<p>
150: * Feedback is enabled but scroll and expand is not.
151: *
152: * @param viewer the viewer to have drag and drop support added to it.
153: * @param defaultTarget The target to use if the mouse is not over an item in the viewer
154: *
155: */
156: public static void addDragDropSupport(StructuredViewer viewer,
157: IDropTargetProvider defaultTarget) {
158: addDragDropSupport(viewer, defaultTarget, true, false);
159: }
160:
161: /**
162: * Adds both drag and drop support to the StructuredViewer.
163: * <p>For this to work the destination object must have a dropAction extension
164: * defined for it.<p>
165: *
166: * @param viewer the viewer to have drag and drop support added to it.
167: * @param defaultTarget The target to use if the mouse is not over an item in the viewer
168: */
169: public static void addDragDropSupport(StructuredViewer viewer,
170: IDropTargetProvider defaultTarget,
171: boolean showDropFeedback, boolean expandTree) {
172: addDragSupport(viewer.getControl(), viewer);
173: addDropSupport(viewer, defaultTarget, showDropFeedback,
174: expandTree);
175: }
176:
177: /**
178: * Adds drop support to the StructuredViewer.
179: * <p>For this to work the destination object must have a dropAction extension
180: * defined for it.<p>
181: * Feedback is enabled but scroll and expand is not.
182: *
183: * @param viewer the viewer to have drop support added to it.
184: * @param destination The target to use if the mouse is not over an item in the viewer
185: */
186: public static UDIGDropTargetListener addDropSupport(
187: StructuredViewer viewer, IDropTargetProvider defaultTarget) {
188: return addDropSupport(viewer, defaultTarget, true, false);
189: }
190:
191: /**
192: * Adds drop support to the StructuredViewer.
193: * <p>For this to work the destination object must have a dropAction extension
194: * defined for it.<p>
195: *
196: * @param viewer the viewer to have drop support added to it.
197: * @param destination The target to use if the mouse is not over an item in the viewer
198: * @param showDropFeedback if true the feedback bars will be shown in the viewer.
199: * @param scrollExpandEnabled if true trees will be expanded and the viewer will be scrolled.
200: */
201: public static UDIGDropTargetListener addDropSupport(
202: StructuredViewer viewer, IDropTargetProvider defaultTarget,
203: boolean showDropFeedback, boolean scrollExpandEnabled) {
204: int dndOperations = DND.DROP_COPY | DND.DROP_MOVE
205: | DND.DROP_LINK | DND.DROP_DEFAULT;
206: Set<Transfer> transfers = getTransfers();
207:
208: UDIGViewerDropAdapter viewerDropAdapter = new UDIGViewerDropAdapter(
209: viewer, defaultTarget);
210: viewerDropAdapter.setFeedbackEnabled(showDropFeedback);
211: viewerDropAdapter.setScrollExpandEnabled(scrollExpandEnabled);
212: viewer.addDropSupport(dndOperations, transfers
213: .toArray(new Transfer[transfers.size()]),
214: viewerDropAdapter);
215: return viewerDropAdapter;
216: }
217:
218: /**
219: * Adds both drag and drop support to the StructuredViewer.
220: * <p>For this to work the destination object must have a dropAction extension
221: * defined for it.<p>
222: *
223: * @param control the viewer to have drag and drop support added to it.
224: * @param destination the destination that determines what actions will take
225: * place when a drag or drop event occurs.
226: */
227: public static void addDragDropSupport(Control control,
228: IDropTargetProvider destination, ISelectionProvider source) {
229: addDragSupport(control, source);
230: addDropSupport(control, destination);
231: }
232:
233: /**
234: * Adds drag support to the StructuredViewer.
235: * <p>For this to work the destination object must have a dropAction extension
236: * defined for it.<p>
237: *
238: * @param control the viewer to have drag support added to it.
239: * @param destination the destination that determines what actions will take
240: * place when a drag event occurs.
241: * @return
242: */
243: public static DragSourceDescriptor addDragSupport(Control control,
244: ISelectionProvider provider) {
245: int dndOperations = DND.DROP_COPY | DND.DROP_MOVE
246: | DND.DROP_LINK | DND.DROP_DEFAULT;
247: Set<Transfer> transfers = getTransfers();
248: transfers.remove(FileTransfer.getInstance());
249:
250: DragSource dragSource = new DragSource(control, dndOperations);
251: DragController dragController = new DragController(dragSource,
252: transfers);
253: provider.addSelectionChangedListener(dragController);
254: dragController.setTransfers((IStructuredSelection) provider
255: .getSelection());
256: UDIGControlDragListener controlDragListener = new UDIGControlDragListener(
257: provider);
258: dragSource.addDragListener(controlDragListener);
259: return new DragSourceDescriptor(dragSource, controlDragListener);
260: }
261:
262: /**
263: * Adds drop support to the StructuredViewer.
264: * <p>For this to work the destination object must have a dropAction extension
265: * defined for it.<p>
266: *
267: * @param control the viewer to have drop support added to it.
268: * @param destination the destination that determines what actions will take
269: * place when a drop event occurs.
270: * @return
271: */
272: public static DropTargetDescriptor addDropSupport(Control control,
273: IDropTargetProvider destination) {
274: int dndOperations = DND.DROP_COPY | DND.DROP_MOVE
275: | DND.DROP_LINK | DND.DROP_DEFAULT;
276: Set<Transfer> transfers = getTransfers();
277: DropTarget target = new DropTarget(control, dndOperations);
278: target.setTransfer(transfers.toArray(new Transfer[transfers
279: .size()]));
280: UDIGControlDropListener controlDropListener = new UDIGControlDropListener(
281: destination);
282: target.addDropListener(controlDropListener);
283: return new DropTargetDescriptor(target, controlDropListener);
284: }
285:
286: /**
287: * Returns the transfers that are available with the current
288: * udig configuration.
289: *
290: * @return the transfers that are available with the current
291: * udig configuration.
292: */
293: public static Set<Transfer> getTransfers() {
294: return UDIGDNDProcessor.getTransfers();
295: }
296:
297: /**
298: * Registers the DND Support needed by uDig.
299: * Public because it might need to be called by another application using uDig as a plugin.
300: * @param configurer The IWorkbenchWindowConfigurer for the workbench
301: */
302: public static void registerUDigDND(
303: IWorkbenchWindowConfigurer configurer) {
304: Set<Transfer> transfers = getTransfers();
305: for (Transfer transfer : transfers) {
306: configurer.addEditorAreaTransfer(transfer);
307: }
308: configurer
309: .configureEditorAreaDropListener(new UDIGControlDropListener(
310: new EditorPlaceholder()));
311: }
312:
313: /**
314: * Creates a drop listener that will send the drop event to the
315: * currently active editor.
316: *
317: * @return a drop listener that will send the drop event to the
318: * currently active editor.
319: */
320: public static UDIGControlDropListener getEditorDropListener() {
321: return new UDIGControlDropListener(new EditorPlaceholder());
322: }
323:
324: public static class DragSourceDescriptor {
325:
326: public final DragSource source;
327: public final DragSourceListener listener;
328:
329: public DragSourceDescriptor(DragSource sourceA,
330: DragSourceListener listenerA) {
331: source = sourceA;
332: listener = listenerA;
333: }
334: }
335:
336: public static class DropTargetDescriptor {
337: public final DropTarget target;
338: public final UDIGDropTargetListener listener;
339:
340: public DropTargetDescriptor(DropTarget targetA,
341: UDIGDropTargetListener listenerA) {
342: target = targetA;
343: listener = listenerA;
344: }
345: }
346:
347: static private class EditorPlaceholder implements IEditorPart,
348: IDropTargetProvider {
349:
350: IEditorPart getEditorPart() {
351: return PlatformUI.getWorkbench().getActiveWorkbenchWindow()
352: .getActivePage().getActiveEditor();
353: }
354:
355: public IEditorInput getEditorInput() {
356: return getEditorPart() != null ? getEditorPart()
357: .getEditorInput() : null;
358: }
359:
360: public IEditorSite getEditorSite() {
361: return getEditorPart() != null ? getEditorPart()
362: .getEditorSite() : null;
363: }
364:
365: public void init(IEditorSite site, IEditorInput input)
366: throws PartInitException {
367:
368: if (getEditorPart() != null)
369: getEditorPart().init(site, input);
370: }
371:
372: public void addPropertyListener(IPropertyListener listener) {
373: if (getEditorPart() != null)
374: getEditorPart().addPropertyListener(listener);
375: }
376:
377: public void createPartControl(Composite parent) {
378: if (getEditorPart() != null)
379: getEditorPart().createPartControl(parent);
380: }
381:
382: public void dispose() {
383: if (getEditorPart() != null)
384: getEditorPart().dispose();
385: }
386:
387: public IWorkbenchPartSite getSite() {
388: return getEditorPart() != null ? getEditorPart().getSite()
389: : null;
390: }
391:
392: public String getTitle() {
393: return getEditorPart() != null ? getEditorPart().getTitle()
394: : null;
395: }
396:
397: public Image getTitleImage() {
398: return getEditorPart() != null ? getEditorPart()
399: .getTitleImage() : null;
400: }
401:
402: public String getTitleToolTip() {
403: return getEditorPart() != null ? getEditorPart()
404: .getTitleToolTip() : null;
405: }
406:
407: public void removePropertyListener(IPropertyListener listener) {
408: if (getEditorPart() != null)
409: getEditorPart().removePropertyListener(listener);
410: }
411:
412: public void setFocus() {
413: if (getEditorPart() != null)
414: getEditorPart().setFocus();
415: }
416:
417: public Object getAdapter(Class adapter) {
418: return getEditorPart() != null ? getEditorPart()
419: .getAdapter(adapter) : null;
420: }
421:
422: public void doSave(IProgressMonitor monitor) {
423: if (getEditorPart() != null)
424: getEditorPart().doSave(monitor);
425: }
426:
427: public void doSaveAs() {
428: if (getEditorPart() != null)
429: getEditorPart().doSaveAs();
430: }
431:
432: public boolean isDirty() {
433: return getEditorPart() != null ? getEditorPart().isDirty()
434: : false;
435: }
436:
437: public boolean isSaveAsAllowed() {
438: return getEditorPart() != null ? getEditorPart()
439: .isSaveAsAllowed() : false;
440: }
441:
442: public boolean isSaveOnCloseNeeded() {
443: return getEditorPart() != null ? getEditorPart()
444: .isSaveOnCloseNeeded() : false;
445: }
446:
447: public Object getTarget(DropTargetEvent event) {
448: return this;
449: }
450:
451: }
452:
453: }
|