1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.ui.dnd;
12 
13 import java.util.ArrayList;
14 import java.util.Iterator;
15 import java.util.List;
16 
17 import org.eclipse.jface.util.Assert;
18 import org.eclipse.swt.dnd.DragSource;
19 import org.eclipse.swt.dnd.DragSourceEvent;
20 import org.eclipse.swt.dnd.DragSourceListener;
21 import org.eclipse.swt.dnd.Transfer;
22 import org.eclipse.swt.dnd.TransferData;
23 
24 /**
25  * A delegating drag adapter negotiates between a set of
26  * <code>TransferDragSourceListener</code>s On <code>dragStart</code> the
27  * adapter determines the listener to be used for any further <code>drag*</code>
28  * callback.
29  */
30 public class DelegatingDragAdapter implements DragSourceListener {
31 
32 	private TransferDragSourceListener[] fPossibleListeners;
33 
34 	private List fActiveListeners;
35 
36 	private TransferDragSourceListener fFinishListener;
37 
DelegatingDragAdapter(TransferDragSourceListener[] listeners)38 	public DelegatingDragAdapter(TransferDragSourceListener[] listeners) {
39 		setPossibleListeners(listeners);
40 	}
41 
setPossibleListeners(TransferDragSourceListener[] listeners)42 	protected void setPossibleListeners(TransferDragSourceListener[] listeners) {
43 		Assert.isNotNull(listeners);
44 		Assert
45 				.isTrue(fActiveListeners == null,
46 						"Can only set possible listeners before drag operation has started"); //$NON-NLS-1$
47 		fPossibleListeners = listeners;
48 	}
49 
50 	/*
51 	 * non Java-doc
52 	 *
53 	 * @see DragSourceListener
54 	 */
dragStart(DragSourceEvent event)55 	public void dragStart(DragSourceEvent event) {
56 		fFinishListener = null;
57 		boolean saveDoit = event.doit;
58 		Object saveData = event.data;
59 		boolean doIt = false;
60 		List transfers = new ArrayList(fPossibleListeners.length);
61 		fActiveListeners = new ArrayList(fPossibleListeners.length);
62 
63 		for (int i = 0; i < fPossibleListeners.length; i++) {
64 			TransferDragSourceListener listener = fPossibleListeners[i];
65 			event.doit = saveDoit;
66 			listener.dragStart(event);
67 			if (event.doit) {
68 				transfers.add(listener.getTransfer());
69 				fActiveListeners.add(listener);
70 			}
71 			doIt = doIt || event.doit;
72 		}
73 		if (doIt) {
74 			((DragSource) event.widget).setTransfer((Transfer[]) transfers
75 					.toArray(new Transfer[transfers.size()]));
76 		}
77 		event.data = saveData;
78 		event.doit = doIt;
79 	}
80 
81 	/*
82 	 * non Java-doc
83 	 *
84 	 * @see DragSourceListener
85 	 */
dragSetData(DragSourceEvent event)86 	public void dragSetData(DragSourceEvent event) {
87 		fFinishListener = getListener(event.dataType);
88 		if (fFinishListener != null)
89 			fFinishListener.dragSetData(event);
90 	}
91 
92 	/*
93 	 * non Java-doc
94 	 *
95 	 * @see DragSourceListener
96 	 */
dragFinished(DragSourceEvent event)97 	public void dragFinished(DragSourceEvent event) {
98 		try {
99 			if (fFinishListener != null) {
100 				fFinishListener.dragFinished(event);
101 			} else {
102 				// If the user presses Escape then we get a dragFinished without
103 				// getting a dragSetData before.
104 				fFinishListener = getListener(event.dataType);
105 				if (fFinishListener != null)
106 					fFinishListener.dragFinished(event);
107 			}
108 		} finally {
109 			fFinishListener = null;
110 			fActiveListeners = null;
111 		}
112 	}
113 
getListener(TransferData type)114 	private TransferDragSourceListener getListener(TransferData type) {
115 		if (type == null)
116 			return null;
117 
118 		for (Iterator iter = fActiveListeners.iterator(); iter.hasNext();) {
119 			TransferDragSourceListener listener = (TransferDragSourceListener) iter
120 					.next();
121 			if (listener.getTransfer().isSupportedType(type)) {
122 				return listener;
123 			}
124 		}
125 		return null;
126 	}
127 }
128