Package org.eclipse.ui.internal

Source Code of org.eclipse.ui.internal.EditorSiteDragAndDropServiceImpl$MergedDropTarget

/*******************************************************************************
* Copyright (c) 2006, 2007 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.ui.internal;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.DropTargetListener;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dnd.IDragAndDropService;
import org.eclipse.ui.services.IDisposable;

/**
* Implementation for the <code>IDragAndDropService</code> to be used from
* <code>EditorSite</code>'s.
* </p><p>
* Adds a drop target to the given control that merges the site's
* drop behaviour with that specified by the <code>addMergedDropTarget</code> call.
* </p><p>
* The current implementation is only defined for EditorSite's and merges the
* given drop handling with the existing EditorSashContainer's behaviour.
* </p><p>
* NOTE: There is no cleanup (i.e. 'dispose') handling necessary for merged
* Drop Targets but the hooks are put into place to maintain the consistency
* of the implementation pattern.
* </p>
* @since 3.3
*
*/
public class EditorSiteDragAndDropServiceImpl implements IDragAndDropService, IDisposable {
  /**
   * Implementation of a DropTarget wrapper that will either delegate to the
   * <code>primaryListener</code> if the event's <code>currentDataType</code>
   * can be handled by it; otherwise the event is forwarded on to the
   * listener specified by <code>secondaryListener</code>.
   * </p><p>
   * NOTE: we should perhaps refactor this out into an external class
   * </p>
   * @since 3.3
   *
   */
  private static class MergedDropTarget {
    private DropTarget realDropTarget;
   
    private Transfer[] secondaryTransfers;
    private DropTargetListener secondaryListener;
   
    private Transfer[] primaryTransfers;
    private DropTargetListener primaryListener;
   
    public MergedDropTarget(Control control,
        int priOps, Transfer[] priTransfers, DropTargetListener priListener,
        int secOps, Transfer[] secTransfers, DropTargetListener secListener) {
      realDropTarget = new DropTarget(control, priOps | secOps);
     
      // Cache the editor's transfers and listener
      primaryTransfers = priTransfers;
      primaryListener = priListener;
     
      // Capture the editor area's current transfers & listener
      WorkbenchWindow ww = (WorkbenchWindow) PlatformUI.getWorkbench().getActiveWorkbenchWindow();
          WorkbenchWindowConfigurer winConfigurer = ww.getWindowConfigurer();
          secondaryTransfers = winConfigurer.getTransfers();
          secondaryListener = winConfigurer.getDropTargetListener();
     
      // Combine the two sets of transfers into one array
      Transfer[] allTransfers = new Transfer[secondaryTransfers.length+primaryTransfers.length];
      int curTransfer = 0;
      for (int i = 0; i < primaryTransfers.length; i++) {
        allTransfers[curTransfer++] = primaryTransfers[i];
      }
      for (int i = 0; i < secondaryTransfers.length; i++) {
        allTransfers[curTransfer++] = secondaryTransfers[i];
      }
      realDropTarget.setTransfer(allTransfers);
     
      // Create a listener that will delegate to the appropriate listener
      // NOTE: the -editor- wins (i.e. it can over-ride WB behaviour if it wants
      realDropTarget.addDropListener(new DropTargetListener() {
        public void dragEnter(DropTargetEvent event) {
          getAppropriateListener(event).dragEnter(event);
        }
        public void dragLeave(DropTargetEvent event) {
          getAppropriateListener(event).dragLeave(event);
        }
        public void dragOperationChanged(DropTargetEvent event) {
          getAppropriateListener(event).dragOperationChanged(event);
        }
        public void dragOver(DropTargetEvent event) {
          getAppropriateListener(event).dragOver(event);
        }
        public void drop(DropTargetEvent event) {
          getAppropriateListener(event).drop(event);
        }
        public void dropAccept(DropTargetEvent event) {
          getAppropriateListener(event).dropAccept(event);
        }
      });
    }

    private DropTargetListener getAppropriateListener(DropTargetEvent event) {
      if (isSupportedType(primaryTransfers, event.currentDataType))
        return primaryListener;
     
      return secondaryListener;
    }
   
    private boolean isSupportedType(Transfer[] transfers, TransferData transferType) {
      for (int i = 0; i < transfers.length; i++) {
        if (transfers[i].isSupportedType(transferType))
          return true;
      }
      return false;
    }

    /**
     * Clean up...
     */
    public void dispose() {
    }
  }
 
  // Cache any listeners for cleanup
  List addedListeners = new ArrayList();

  /* (non-Javadoc)
   * @see org.eclipse.ui.dnd.IEditorDropTargetService#addDropTarget(org.eclipse.swt.widgets.Control, int, org.eclipse.swt.dnd.Transfer[], org.eclipse.swt.dnd.DropTargetListener)
   */
  public void addMergedDropTarget(Control control, int ops, Transfer[] transfers,
      DropTargetListener listener) {
     // First we have to remove any existing drop target from the control
    removeMergedDropTarget(control);
   
    // Capture the editor area's current ops, transfers & listener
    int editorSiteOps = DND.DROP_DEFAULT | DND.DROP_COPY | DND.DROP_LINK;

    WorkbenchWindow ww = (WorkbenchWindow) PlatformUI.getWorkbench().getActiveWorkbenchWindow();
        WorkbenchWindowConfigurer winConfigurer = ww.getWindowConfigurer();
        Transfer[] editorSiteTransfers = winConfigurer.getTransfers();
        DropTargetListener editorSiteListener = winConfigurer.getDropTargetListener();
       
        // Create a new 'merged' drop Listener using combination of the desired
        // transfers and the ones used by the EditorArea
    MergedDropTarget newTarget = new MergedDropTarget(control, ops, transfers, listener,
        editorSiteOps, editorSiteTransfers, editorSiteListener);
    addedListeners.add(newTarget);
  }

  /**
   * This method will return the current drop target for the control
   * (whether or not it was created using this service.
   * <p>
   * <b>WARNING:</b> This code uses an SWT internal string to gain
   * access to the drop target. I've been assured that neither the
   * value of the string nor the fact that the target is stored in
   * a property will change for 3.3 and that post-3.3 we will come
   * up with a more viable DnD SWT story...
   * </p>
   * @param control The control to get the drop target for
   * @return The DropTarget for that control (could be null
   */
  private DropTarget getCurrentDropTarget(Control control) {
    if (control == null)
      return null;
   
    Object curDT = control.getData("DropTarget")//$NON-NLS-1$
    return (DropTarget)curDT;
  }
 
  /* (non-Javadoc)
   * @see org.eclipse.ui.dnd.IDragAndDropService#removeMergedDropTarget(org.eclipse.swt.widgets.Control)
   */
  public void removeMergedDropTarget(Control control) {
    DropTarget targetForControl = getCurrentDropTarget(control);
    if (targetForControl != null) {
      targetForControl.dispose();
      addedListeners.remove(targetForControl);
    }
  }

  /* (non-Javadoc)
   * @see org.eclipse.ui.services.IDisposable#dispose()
   */
  public void dispose() {
    // Clean up the listeners
    for (Iterator iterator = addedListeners.iterator(); iterator.hasNext();) {
      MergedDropTarget target = (MergedDropTarget) iterator.next();
      target.dispose();
    }
    addedListeners.clear();
  }

}
TOP

Related Classes of org.eclipse.ui.internal.EditorSiteDragAndDropServiceImpl$MergedDropTarget

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.