Package ae.sun.awt.dnd

Source Code of ae.sun.awt.dnd.SunDragSourceContextPeer$EventDispatcher

/*
* Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.  Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/

package ae.sun.awt.dnd;

import ae.java.awt.AWTEvent;
import ae.java.awt.Component;
import ae.java.awt.Cursor;
import ae.java.awt.EventQueue;
import ae.java.awt.Image;
import ae.java.awt.Point;

import ae.java.awt.datatransfer.Transferable;

import ae.java.awt.dnd.DnDConstants;
import ae.java.awt.dnd.DragSourceContext;
import ae.java.awt.dnd.DragSourceEvent;
import ae.java.awt.dnd.DragSourceDropEvent;
import ae.java.awt.dnd.DragSourceDragEvent;
import ae.java.awt.dnd.DragGestureEvent;
import ae.java.awt.dnd.InvalidDnDOperationException;

import ae.java.awt.dnd.peer.DragSourceContextPeer;

import ae.java.awt.event.InputEvent;
import ae.java.awt.event.MouseEvent;

import java.util.Map;
import java.util.SortedMap;

import ae.sun.awt.SunToolkit;
import ae.sun.awt.datatransfer.DataTransferer;


/**
* <p>
* TBC
* </p>
*
* @since JDK1.3.1
*
*/

public abstract class SunDragSourceContextPeer implements DragSourceContextPeer {

    private DragGestureEvent  trigger;
    private Component         component;
    private Cursor            cursor;
    private long              nativeCtxt;
    private DragSourceContext dragSourceContext;
    private int               sourceActions;

    private static boolean    dragDropInProgress = false;
    private static boolean    discardingMouseEvents = false;

    /*
     * dispatch constants
     */

    protected final static int DISPATCH_ENTER   = 1;
    protected final static int DISPATCH_MOTION  = 2;
    protected final static int DISPATCH_CHANGED = 3;
    protected final static int DISPATCH_EXIT    = 4;
    protected final static int DISPATCH_FINISH  = 5;
    protected final static int DISPATCH_MOUSE_MOVED  = 6;

    /**
     * construct a new SunDragSourceContextPeer
     */

    public SunDragSourceContextPeer(DragGestureEvent dge) {
        trigger = dge;
        if (trigger != null) {
            component = trigger.getComponent();
        } else {
            component = null;
        }
    }

    /**
     * Synchro messages in AWT
     */
    public void startSecondaryEventLoop(){}
    public void quitSecondaryEventLoop(){}

    /**
     * initiate a DnD operation ...
     */

    public void startDrag(DragSourceContext dsc, Cursor c, Image di, Point p)
      throws InvalidDnDOperationException {

        /* Fix for 4354044: don't initiate a drag if event sequence provided by
         * DragGestureRecognizer is empty */
        if (getTrigger().getTriggerEvent() == null) {
            throw new InvalidDnDOperationException("DragGestureEvent has a null trigger");
        }

        dragSourceContext = dsc;
        cursor            = c;
        sourceActions     = getDragSourceContext().getSourceActions();

        Transferable transferable  = getDragSourceContext().getTransferable();
        SortedMap formatMap = DataTransferer.getInstance().getFormatsForTransferable
             (transferable, DataTransferer.adaptFlavorMap
                 (getTrigger().getDragSource().getFlavorMap()));
        long[] formats = DataTransferer.getInstance().
            keysToLongArray(formatMap);
        startDrag(transferable, formats, formatMap);

        /*
         * Fix for 4613903.
         * Filter out all mouse events that are currently on the event queue.
         */
        discardingMouseEvents = true;
        EventQueue.invokeLater(new Runnable() {
                public void run() {
                    discardingMouseEvents = false;
                }
            });
    }

    protected abstract void startDrag(Transferable trans,
                                      long[] formats, Map formatMap);

    /**
     * set cursor
     */

    public void setCursor(Cursor c) throws InvalidDnDOperationException {
        synchronized (this) {
            if (cursor == null || !cursor.equals(c)) {
                cursor = c;
                // NOTE: native context can be null at this point.
                // setNativeCursor() should handle it properly.
                setNativeCursor(getNativeContext(), c,
                                c != null ? c.getType() : 0);
            }
        }
    }

    /**
     * return cursor
     */

    public Cursor getCursor() {
        return cursor;
    }

    /**
     * downcall into native code
     */


    protected abstract void setNativeCursor(long nativeCtxt, Cursor c,
                                            int cType);

    protected synchronized void setTrigger(DragGestureEvent dge) {
        trigger = dge;
        if (trigger != null) {
            component = trigger.getComponent();
        } else {
            component = null;
        }
    }

    protected DragGestureEvent getTrigger() {
        return trigger;
    }

    protected Component getComponent() {
        return component;
    }

    protected synchronized void setNativeContext(long ctxt) {
        nativeCtxt = ctxt;
    }

    protected synchronized long getNativeContext() {
        return nativeCtxt;
    }

    protected DragSourceContext getDragSourceContext() {
        return dragSourceContext;
    }

    /**
     * Notify the peer that the transferables' DataFlavors have changed.
     *
     * No longer useful as the transferables are determined at the time
     * of the drag.
     */

    public void transferablesFlavorsChanged() {
    }





    protected final void postDragSourceDragEvent(final int targetAction,
                                                 final int modifiers,
                                                 final int x, final int y,
                                                 final int dispatchType) {

        final int dropAction =
            SunDragSourceContextPeer.convertModifiersToDropAction(modifiers,
                                                                  sourceActions);

        DragSourceDragEvent event =
            new DragSourceDragEvent(getDragSourceContext(),
                                    dropAction,
                                    targetAction & sourceActions,
                                    modifiers, x, y);
        EventDispatcher dispatcher = new EventDispatcher(dispatchType, event);

        SunToolkit.invokeLaterOnAppContext(
            SunToolkit.targetToAppContext(getComponent()), dispatcher);

        startSecondaryEventLoop();
    }

    /**
     * upcall from native code
     */

    private void dragEnter(final int targetActions,
                           final int modifiers,
                           final int x, final int y) {
        postDragSourceDragEvent(targetActions, modifiers, x, y, DISPATCH_ENTER);
    }

    /**
     * upcall from native code
     */

    private void dragMotion(final int targetActions,
                            final int modifiers,
                            final int x, final int y) {
        postDragSourceDragEvent(targetActions, modifiers, x, y, DISPATCH_MOTION);
    }

    /**
     * upcall from native code
     */

    private void operationChanged(final int targetActions,
                                  final int modifiers,
                                  final int x, final int y) {
        postDragSourceDragEvent(targetActions, modifiers, x, y, DISPATCH_CHANGED);
    }

    /**
     * upcall from native code
     */

    protected final void dragExit(final int x, final int y) {
        DragSourceEvent event =
            new DragSourceEvent(getDragSourceContext(), x, y);
        EventDispatcher dispatcher =
            new EventDispatcher(DISPATCH_EXIT, event);

        SunToolkit.invokeLaterOnAppContext(
            SunToolkit.targetToAppContext(getComponent()), dispatcher);

        startSecondaryEventLoop();
    }

    /**
     * upcall from native code
     */

    private void dragMouseMoved(final int targetActions,
                                final int modifiers,
                                final int x, final int y) {
        postDragSourceDragEvent(targetActions, modifiers, x, y,
                                DISPATCH_MOUSE_MOVED);
    }

    /**
     * upcall from native code via implemented class (do)
     */

    protected final void dragDropFinished(final boolean success,
                                          final int operations,
                                          final int x, final int y) {
        DragSourceEvent event =
            new DragSourceDropEvent(getDragSourceContext(),
                                    operations & sourceActions,
                                    success, x, y);
        EventDispatcher dispatcher =
            new EventDispatcher(DISPATCH_FINISH, event);

        SunToolkit.invokeLaterOnAppContext(
            SunToolkit.targetToAppContext(getComponent()), dispatcher);

        startSecondaryEventLoop();
        setNativeContext(0);
    }

    public static void setDragDropInProgress(boolean b)
      throws InvalidDnDOperationException {
        if (dragDropInProgress == b) {
            throw new InvalidDnDOperationException(getExceptionMessage(b));
        }

        synchronized (SunDragSourceContextPeer.class) {
            if (dragDropInProgress == b) {
                throw new InvalidDnDOperationException(getExceptionMessage(b));
            }
            dragDropInProgress = b;
        }
    }

    /**
     * Filters out all mouse events that were on the java event queue when
     * startDrag was called.
     */
    public static boolean checkEvent(AWTEvent event) {
        if (discardingMouseEvents && event instanceof MouseEvent) {
            MouseEvent mouseEvent = (MouseEvent)event;
            if (!(mouseEvent instanceof SunDropTargetEvent)) {
                return false;
            }
        }
        return true;
    }

    public static void checkDragDropInProgress()
      throws InvalidDnDOperationException {
        if (dragDropInProgress) {
            throw new InvalidDnDOperationException(getExceptionMessage(true));
        }
    }

    private static String getExceptionMessage(boolean b) {
        return b ? "Drag and drop in progress" : "No drag in progress";
    }

    public static int convertModifiersToDropAction(final int modifiers,
                                                   final int supportedActions) {
        int dropAction = DnDConstants.ACTION_NONE;

        /*
         * Fix for 4285634.
         * Calculate the drop action to match Motif DnD behavior.
         * If the user selects an operation (by pressing a modifier key),
         * return the selected operation or ACTION_NONE if the selected
         * operation is not supported by the drag source.
         * If the user doesn't select an operation search the set of operations
         * supported by the drag source for ACTION_MOVE, then for
         * ACTION_COPY, then for ACTION_LINK and return the first operation
         * found.
         */
        switch (modifiers & (InputEvent.SHIFT_DOWN_MASK |
                             InputEvent.CTRL_DOWN_MASK)) {
        case InputEvent.SHIFT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK:
            dropAction = DnDConstants.ACTION_LINK; break;
        case InputEvent.CTRL_DOWN_MASK:
            dropAction = DnDConstants.ACTION_COPY; break;
        case InputEvent.SHIFT_DOWN_MASK:
            dropAction = DnDConstants.ACTION_MOVE; break;
        default:
            if ((supportedActions & DnDConstants.ACTION_MOVE) != 0) {
                dropAction = DnDConstants.ACTION_MOVE;
            } else if ((supportedActions & DnDConstants.ACTION_COPY) != 0) {
                dropAction = DnDConstants.ACTION_COPY;
            } else if ((supportedActions & DnDConstants.ACTION_LINK) != 0) {
                dropAction = DnDConstants.ACTION_LINK;
            }
        }

        return dropAction & supportedActions;
    }

    private void cleanup() {
        trigger = null;
        component = null;
        cursor = null;
        dragSourceContext = null;
        SunDropTargetContextPeer.setCurrentJVMLocalSourceTransferable(null);
        SunDragSourceContextPeer.setDragDropInProgress(false);
    }

    private class EventDispatcher implements Runnable {

        private final int dispatchType;

        private final DragSourceEvent event;

        EventDispatcher(int dispatchType, DragSourceEvent event) {
            switch (dispatchType) {
            case DISPATCH_ENTER:
            case DISPATCH_MOTION:
            case DISPATCH_CHANGED:
            case DISPATCH_MOUSE_MOVED:
                if (!(event instanceof DragSourceDragEvent)) {
                    throw new IllegalArgumentException("Event: " + event);
                }
                break;
            case DISPATCH_EXIT:
                break;
            case DISPATCH_FINISH:
                if (!(event instanceof DragSourceDropEvent)) {
                    throw new IllegalArgumentException("Event: " + event);
                }
                break;
            default:
                throw new IllegalArgumentException("Dispatch type: " +
                                                   dispatchType);
            }

            this.dispatchType  = dispatchType;
            this.event         = event;
        }

        public void run() {
            DragSourceContext dragSourceContext =
                SunDragSourceContextPeer.this.getDragSourceContext();
            try {
                switch (dispatchType) {
                case DISPATCH_ENTER:
                    dragSourceContext.dragEnter((DragSourceDragEvent)event);
                    break;
                case DISPATCH_MOTION:
                    dragSourceContext.dragOver((DragSourceDragEvent)event);
                    break;
                case DISPATCH_CHANGED:
                    dragSourceContext.dropActionChanged((DragSourceDragEvent)event);
                    break;
                case DISPATCH_EXIT:
                    dragSourceContext.dragExit(event);
                    break;
                case DISPATCH_MOUSE_MOVED:
                    dragSourceContext.dragMouseMoved((DragSourceDragEvent)event);
                    break;
                case DISPATCH_FINISH:
                    try {
                        dragSourceContext.dragDropEnd((DragSourceDropEvent)event);
                    } finally {
                        SunDragSourceContextPeer.this.cleanup();
                    }
                    break;
                default:
                    throw new IllegalStateException("Dispatch type: " +
                                                    dispatchType);
                }
            } finally {
                 SunDragSourceContextPeer.this.quitSecondaryEventLoop();
            }
        }
    }
}
TOP

Related Classes of ae.sun.awt.dnd.SunDragSourceContextPeer$EventDispatcher

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.