| /****************************************************************************** |
| * Copyright (c) 2003, 2005 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.gmf.runtime.common.ui.services.dnd.drop; |
| |
| import org.eclipse.swt.dnd.DropTargetEvent; |
| import org.eclipse.swt.dnd.Transfer; |
| import org.eclipse.swt.dnd.TransferData; |
| |
| import org.eclipse.gmf.runtime.common.core.util.Log; |
| import org.eclipse.gmf.runtime.common.core.util.Trace; |
| import org.eclipse.gmf.runtime.common.ui.services.dnd.core.DragDropListenerService; |
| import org.eclipse.gmf.runtime.common.ui.services.dnd.core.ITransferAgent; |
| import org.eclipse.gmf.runtime.common.ui.services.dnd.internal.CommonUIServicesDNDDebugOptions; |
| import org.eclipse.gmf.runtime.common.ui.services.dnd.internal.CommonUIServicesDNDPlugin; |
| import org.eclipse.gmf.runtime.common.ui.services.dnd.internal.CommonUIServicesDNDStatusCodes; |
| import org.eclipse.gmf.runtime.common.ui.services.dnd.internal.core.DropListenerContext; |
| |
| /** |
| * Parent of all the transfer drop target adapters. Every transfer type drop |
| * target adapter should override the methods in the |
| * <code>DropTargetListener</code> interface. |
| * |
| * @author Vishy Ramaswamy |
| */ |
| public class TransferDropTargetAdapter |
| implements ITransferDropTargetListener { |
| |
| /** |
| * Attribute for the drop target listener. |
| */ |
| private IDropTargetListener listener; |
| |
| /** |
| * Attribute for the transfer agent. |
| */ |
| private final ITransferAgent transferAgent; |
| |
| /** |
| * Attribute for the drop target context. |
| */ |
| private IDropTargetContext context; |
| |
| /** |
| * Attribute for the current event |
| */ |
| private final org.eclipse.gmf.runtime.common.ui.services.dnd.drop.DropTargetEvent currentEvent; |
| |
| /** |
| * Constructor for TransferDropTargetAdapter. |
| * |
| * @param aTransferAgent |
| * The transfer agent |
| */ |
| public TransferDropTargetAdapter(ITransferAgent aTransferAgent) { |
| super(); |
| |
| assert null != aTransferAgent : "aTransferAgent cannot be null"; //$NON-NLS-1$ |
| |
| this.listener = null; |
| this.transferAgent = aTransferAgent; |
| this.context = null; |
| this.currentEvent = new org.eclipse.gmf.runtime.common.ui.services.dnd.drop.DropTargetEvent(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.swt.dnd.DropTargetListener#dragEnter(org.eclipse.swt.dnd.DropTargetEvent) |
| */ |
| public void dragEnter(DropTargetEvent event) { |
| if (listener != null) { |
| /* Send the event to the selected listener */ |
| listener.setFeedback(event); |
| |
| /* Send the event to the selected listener */ |
| listener.dragEnter(event); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.swt.dnd.DropTargetListener#dragLeave(org.eclipse.swt.dnd.DropTargetEvent) |
| */ |
| public void dragLeave(DropTargetEvent event) { |
| /* Send the event to the selected listener */ |
| if (listener != null) { |
| listener.dragLeave(event); |
| } |
| listener = null; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.swt.dnd.DropTargetListener#dragOperationChanged(org.eclipse.swt.dnd.DropTargetEvent) |
| */ |
| public void dragOperationChanged(DropTargetEvent event) { |
| /* Send the event to the selected listener */ |
| if (listener != null) { |
| listener.dragOperationChanged(event); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.swt.dnd.DropTargetListener#dragOver(org.eclipse.swt.dnd.DropTargetEvent) |
| */ |
| public void dragOver(DropTargetEvent event) { |
| /* Send the event to the selected listener */ |
| if (listener != null) { |
| /* Send the event to the selected listener */ |
| listener.setFeedback(event); |
| |
| /* Send the event to the selected listener */ |
| listener.dragOver(event); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.swt.dnd.DropTargetListener#drop(org.eclipse.swt.dnd.DropTargetEvent) |
| */ |
| public final void drop(DropTargetEvent event) { |
| /* Send the event to the selected listener */ |
| if (listener != null) { |
| /* Send the event to the selected listener */ |
| listener.drop(event); |
| } |
| listener = null; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.swt.dnd.DropTargetListener#dropAccept(org.eclipse.swt.dnd.DropTargetEvent) |
| */ |
| public void dropAccept(DropTargetEvent event) { |
| /* Set the event to the selected listener */ |
| if (listener != null) { |
| listener.dropAccept(event); |
| } |
| } |
| |
| /** |
| * Returns the listener. |
| * |
| * @return IDropTargetListener |
| */ |
| protected final IDropTargetListener getListener() { |
| return listener; |
| } |
| |
| /** |
| * Returns the context. |
| * |
| * @return IDropTargetContext |
| */ |
| protected final IDropTargetContext getContext() { |
| return context; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.gmf.runtime.common.ui.services.dnd.drop.ITransferDropTargetListener#init(org.eclipse.gmf.runtime.common.ui.services.dnd.drop.IDropTargetContext) |
| */ |
| public final void init(IDropTargetContext initialContext) { |
| assert null != initialContext : "initialContext cannot be null"; //$NON-NLS-1$ |
| |
| this.context = initialContext; |
| } |
| |
| /** |
| * Returns the transfer agent. |
| * |
| * @return ITransferAgent |
| */ |
| public final ITransferAgent getTransferAgent() { |
| return transferAgent; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.gmf.runtime.common.ui.services.dnd.drop.ITransferDropTargetListener#canSupport(org.eclipse.swt.dnd.DropTargetEvent) |
| */ |
| public boolean canSupport(DropTargetEvent event) { |
| if (Trace.shouldTrace(CommonUIServicesDNDPlugin.getDefault(), |
| CommonUIServicesDNDDebugOptions.DND)) { |
| Trace.trace(CommonUIServicesDNDPlugin.getDefault(), |
| CommonUIServicesDNDDebugOptions.DND, |
| "canSupport::Adapter is " + getClass().getName()); //$NON-NLS-1$ |
| } |
| |
| /* |
| * Check if one of the transfer data can be supported by this transfer |
| * and if a supporting listener is available |
| */ |
| return canSupportTransferData(event) && isSupportingListenerAvailable(); |
| } |
| |
| /** |
| * Check if a supporting listener is available.It also updates the current |
| * listener cache. |
| * |
| * @return boolean true or false |
| */ |
| protected final boolean isSupportingListenerAvailable() { |
| /* Get the listeners if any for the adapter's transfer type */ |
| IDropTargetListener[] listeners = getListeners(false); |
| |
| /* Get a compatible one if no listener is found for a direct match */ |
| if (listeners == null || listeners.length == 0) { |
| listeners = getListeners(true); |
| } |
| |
| /* Choose the current listener */ |
| if (listeners != null) { |
| CommonUIServicesDNDPlugin plugin = CommonUIServicesDNDPlugin |
| .getDefault(); |
| boolean shouldTrace = Trace.shouldTrace(plugin, |
| CommonUIServicesDNDDebugOptions.DND); |
| |
| for (int i = 0; i < listeners.length; ++i) { |
| try { |
| /* Update the listener */ |
| listener = listeners[i]; |
| if (listener.canSupport(context, currentEvent, |
| transferAgent)) { |
| if (shouldTrace) { |
| Trace |
| .trace( |
| plugin, |
| CommonUIServicesDNDDebugOptions.DND, |
| "isSupportingListenerAvailable::Chosen listener is " + listener.getClass().getName()); //$NON-NLS-1$ |
| } |
| |
| return true; |
| } |
| } catch (RuntimeException e) { |
| if (shouldTrace) { |
| Trace.catching(plugin, |
| CommonUIServicesDNDDebugOptions.DND, getClass(), |
| "isSupportingListenerAvailable", e); //$NON-NLS-1$ |
| } |
| Log |
| .warning( |
| plugin, |
| CommonUIServicesDNDStatusCodes.IGNORED_EXCEPTION_WARNING, |
| "Drop Listener " + listeners[i].getClass().getName(), e); //$NON-NLS-1$ |
| } |
| } |
| } |
| |
| /* Set the listener back to null */ |
| listener = null; |
| |
| return false; |
| } |
| |
| /** |
| * Checks if the transfer agent can support one of the transfer datas passed |
| * into the event. It also updates the internal current event cache and sets |
| * the current data type on the current event. |
| * |
| * @param event |
| * the drop target event |
| * @return boolean true or false |
| */ |
| protected final boolean canSupportTransferData(DropTargetEvent event) { |
| /* Update the current event */ |
| currentEvent.setEvent(event); |
| |
| Transfer transfer = transferAgent.getTransfer(); |
| |
| for (int i = 0; i < event.dataTypes.length; ++i) { |
| TransferData dataType = event.dataTypes[i]; |
| |
| if (transfer.isSupportedType(dataType)) { |
| /* Set the current data type */ |
| event.currentDataType = dataType; |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| /** |
| * Returns the drop target listeners for the current context. |
| * |
| * @param isCompatible |
| * should compatible listeners be considered |
| * @return IDropTargetListener[] the drop target listeners |
| */ |
| private final IDropTargetListener[] getListeners(boolean isCompatible) { |
| /* Get the drop target listeners */ |
| IDropTargetListener[] listeners = DragDropListenerService.getInstance() |
| .getDropTargetListeners( |
| new DropListenerContext(context.getActivePart(), context |
| .getCurrentTarget().getClass(), transferAgent |
| .getTransferId(), isCompatible)); |
| |
| return listeners; |
| } |
| } |