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