///*******************************************************************************
// * Copyright (c) 2000, 2006 IBM Corporation and others.
// * All rights reserved. This program and the accompanying materials
// * are made available under the terms of the Eclipse Public License v1.0
// * which accompanies this distribution, and is available at
// * http://www.eclipse.org/legal/epl-v10.html
// *
// * Contributors:
// * IBM Corporation - initial API and implementation
// *******************************************************************************/
//package org.eclipse.jface.util;
//
//import java.util.ArrayList;
//import java.util.Iterator;
//import java.util.List;
//
//import org.eclipse.swt.dnd.DragSource;
//import org.eclipse.swt.dnd.DragSourceEvent;
//import org.eclipse.swt.dnd.DragSourceListener;
//import org.eclipse.swt.dnd.Transfer;
//import org.eclipse.swt.dnd.TransferData;
//
///**
// * A <code>DelegatingDragAdapter</code> is a <code>DragSourceListener</code> that
// * maintains and delegates to a set of {@link TransferDragSourceListener}s. Each
// * TransferDragSourceListener can then be implemented as if it were the
// * <code>DragSource's</code> only DragSourceListener.
// * <p>
// * When a drag is started, a subset of all <code>TransferDragSourceListeners</code>
// * is generated and stored in a list of <i>active</i> listeners. This subset is
// * calculated by forwarding {@link DragSourceListener#dragStart(DragSourceEvent)} to
// * every listener, and checking if the {@link DragSourceEvent#doit doit} field is left
// * set to <code>true</code>.
// * </p>
// * The <code>DragSource</code>'s set of supported Transfer types ({@link
// * DragSource#setTransfer(Transfer[])}) is updated to reflect the Transfer types
// * corresponding to the active listener subset.
// * <p>
// * If and when {@link #dragSetData(DragSourceEvent)} is called, a single
// * <code>TransferDragSourceListener</code> is chosen, and only it is allowed to set the
// * drag data. The chosen listener is the first listener in the subset of active listeners
// * whose Transfer supports ({@link Transfer#isSupportedType(TransferData)}) the
// * <code>dataType</code> in the <code>DragSourceEvent</code>.
// * </p>
// * <p>
// * The following example snippet shows a <code>DelegatingDragAdapter</code> with two
// * <code>TransferDragSourceListeners</code>. One implements drag of text strings,
// * the other supports file transfer and demonstrates how a listener can be disabled using
// * the dragStart method.
// * </p>
// * <code><pre>
// * final TreeViewer viewer = new TreeViewer(shell, SWT.NONE);
// *
// * DelegatingDragAdapter dragAdapter = new DelegatingDragAdapter();
// * dragAdapter.addDragSourceListener(new TransferDragSourceListener() {
// * public Transfer getTransfer() {
// * return TextTransfer.getInstance();
// * }
// * public void dragStart(DragSourceEvent event) {
// * // always enabled, can control enablement based on selection etc.
// * }
// * public void dragSetData(DragSourceEvent event) {
// * event.data = "Transfer data";
// * }
// * public void dragFinished(DragSourceEvent event) {
// * // no clean-up required
// * }
// * });
// * dragAdapter.addDragSourceListener(new TransferDragSourceListener() {
// * public Transfer getTransfer() {
// * return FileTransfer.getInstance();
// * }
// * public void dragStart(DragSourceEvent event) {
// * // enable drag listener if there is a viewer selection
// * event.doit = !viewer.getSelection().isEmpty();
// * }
// * public void dragSetData(DragSourceEvent event) {
// * File file1 = new File("C:/temp/file1");
// * File file2 = new File("C:/temp/file2");
// * event.data = new String[] {file1.getAbsolutePath(), file2.getAbsolutePath()};
// * }
// * public void dragFinished(DragSourceEvent event) {
// * // no clean-up required
// * }
// * });
// * viewer.addDragSupport(DND.DROP_COPY | DND.DROP_MOVE, dragAdapter.getTransfers(), dragAdapter);
// * </pre></code>
// * @since 1.0
// */
//public class DelegatingDragAdapter implements DragSourceListener {
// private List listeners = new ArrayList();
//
// private List activeListeners = new ArrayList();
//
// private TransferDragSourceListener currentListener;
//
// /**
// * Adds the given <code>TransferDragSourceListener</code>.
// *
// * @param listener the new listener
// */
// public void addDragSourceListener(TransferDragSourceListener listener) {
// listeners.add(listener);
// }
//
// /**
// * The drop has successfully completed. This event is forwarded to the current
// * drag listener.
// * Doesn't update the current listener, since the current listener is already the one
// * that completed the drag operation.
// *
// * @param event the drag source event
// * @see DragSourceListener#dragFinished(DragSourceEvent)
// */
// public void dragFinished(final DragSourceEvent event) {
// // if (Policy.DEBUG_DRAG_DROP)
// // System.out.println("Drag Finished: " + toString()); //$NON-NLS-1$
// SafeRunnable.run(new SafeRunnable() {
// public void run() throws Exception {
// if (currentListener != null) {
// // there is a listener that can handle the drop, delegate the event
// currentListener.dragFinished(event);
// } else {
// // The drag was canceled and currentListener was never set, so send the
// // dragFinished event to all the active listeners.
// Iterator iterator = activeListeners.iterator();
// while (iterator.hasNext()) {
// ((TransferDragSourceListener) iterator.next())
// .dragFinished(event);
// }
// }
// }
// });
// currentListener = null;
// activeListeners.clear();
// }
//
// /**
// * The drop data is requested.
// * Updates the current listener and then forwards the event to it.
// *
// * @param event the drag source event
// * @see DragSourceListener#dragSetData(DragSourceEvent)
// */
// public void dragSetData(final DragSourceEvent event) {
// // if (Policy.DEBUG_DRAG_DROP)
// // System.out.println("Drag Set Data: " + toString()); //$NON-NLS-1$
//
// updateCurrentListener(event); // find a listener that can provide the given data type
// if (currentListener != null) {
// SafeRunnable.run(new SafeRunnable() {
// public void run() throws Exception {
// currentListener.dragSetData(event);
// }
// });
// }
// }
//
// /**
// * A drag operation has started.
// * Forwards this event to each listener. A listener must set <code>event.doit</code>
// * to <code>false</code> if it cannot handle the drag operation. If a listener can
// * handle the drag, it is added to the list of active listeners.
// * The drag is aborted if there are no listeners that can handle it.
// *
// * @param event the drag source event
// * @see DragSourceListener#dragStart(DragSourceEvent)
// */
// public void dragStart(final DragSourceEvent event) {
// // if (Policy.DEBUG_DRAG_DROP)
// // System.out.println("Drag Start: " + toString()); //$NON-NLS-1$
// boolean doit = false; // true if any one of the listeners can handle the drag
// List transfers = new ArrayList(listeners.size());
//
// activeListeners.clear();
// for (int i = 0; i < listeners.size(); i++) {
// final TransferDragSourceListener listener = (TransferDragSourceListener) listeners
// .get(i);
// event.doit = true; // restore event.doit
// SafeRunnable.run(new SafeRunnable() {
// public void run() throws Exception {
// listener.dragStart(event);
// }
// });
// if (event.doit) { // the listener can handle this drag
// transfers.add(listener.getTransfer());
// activeListeners.add(listener);
// }
// doit |= event.doit;
// }
//
// if (doit) {
// ((DragSource) event.widget).setTransfer((Transfer[]) transfers
// .toArray(new Transfer[transfers.size()]));
// }
//
// event.doit = doit;
// }
//
// /**
// * Returns the <code>Transfer<code>s from every <code>TransferDragSourceListener</code>.
// *
// * @return the combined <code>Transfer</code>s
// */
// public Transfer[] getTransfers() {
// Transfer[] types = new Transfer[listeners.size()];
// for (int i = 0; i < listeners.size(); i++) {
// TransferDragSourceListener listener = (TransferDragSourceListener) listeners
// .get(i);
// types[i] = listener.getTransfer();
// }
// return types;
// }
//
// /**
// * Returns <code>true</code> if there are no listeners to delegate drag events to.
// *
// * @return <code>true</code> if there are no <code>TransferDragSourceListeners</code>
// * <code>false</code> otherwise.
// */
// public boolean isEmpty() {
// return listeners.isEmpty();
// }
//
// /**
// * Removes the given <code>TransferDragSourceListener</code>.
// * Listeners should not be removed while a drag and drop operation is in progress.
// *
// * @param listener the <code>TransferDragSourceListener</code> to remove
// */
// public void removeDragSourceListener(TransferDragSourceListener listener) {
// listeners.remove(listener);
// if (currentListener == listener) {
// currentListener = null;
// }
// if (activeListeners.contains(listener)) {
// activeListeners.remove(listener);
// }
// }
//
// /**
// * Updates the current listener to one that can handle the drag. There can
// * be many listeners and each listener may be able to handle many <code>TransferData</code>
// * types. The first listener found that supports one of the <code>TransferData</ode>
// * types specified in the <code>DragSourceEvent</code> will be selected.
// *
// * @param event the drag source event
// */
// private void updateCurrentListener(DragSourceEvent event) {
// currentListener = null;
// if (event.dataType == null) {
// return;
// }
// Iterator iterator = activeListeners.iterator();
// while (iterator.hasNext()) {
// TransferDragSourceListener listener = (TransferDragSourceListener) iterator
// .next();
//
// if (listener.getTransfer().isSupportedType(event.dataType)) {
// // if (Policy.DEBUG_DRAG_DROP)
// // System.out.println("Current drag listener: " + listener); //$NON-NLS-1$
// currentListener = listener;
// return;
// }
// }
// }
//
//}