Bug 366174 - PresentationUtil is not in Juno 4.2

Add back a DND util class
diff --git a/bundles/org.eclipse.ui.workbench/.settings/.api_filters b/bundles/org.eclipse.ui.workbench/.settings/.api_filters
index 870901b..4b417e9 100644
--- a/bundles/org.eclipse.ui.workbench/.settings/.api_filters
+++ b/bundles/org.eclipse.ui.workbench/.settings/.api_filters
@@ -94,6 +94,15 @@
             </message_arguments>
         </filter>
     </resource>
+    <resource path="Eclipse UI/org/eclipse/ui/presentations/PresentationUtil.java" type="org.eclipse.ui.presentations.PresentationUtil">
+        <filter id="1108344834">
+            <message_arguments>
+                <message_argument value="3.0"/>
+                <message_argument value="3.103"/>
+                <message_argument value="org.eclipse.ui.presentations.PresentationUtil"/>
+            </message_arguments>
+        </filter>
+    </resource>
     <resource path="Eclipse UI/org/eclipse/ui/progress/IProgressConstants.java" type="org.eclipse.ui.progress.IProgressConstants">
         <filter id="403767336">
             <message_arguments>
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/presentations/PresentationUtil.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/presentations/PresentationUtil.java
new file mode 100644
index 0000000..b3f3948
--- /dev/null
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/presentations/PresentationUtil.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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.ui.presentations;
+
+import org.eclipse.jface.util.Geometry;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.ui.internal.dnd.DragUtil;
+
+/**
+ * Contains various utility methods for Presentation authors
+ * 
+ * @since 3.0
+ */
+public class PresentationUtil {
+    private static Point anchor;
+
+    private final static int HYSTERESIS = 16;
+    
+    private static int initialMouseButton = 0;
+
+    private final static String LISTENER_ID = PresentationUtil.class.getName()
+            + ".dragListener"; //$NON-NLS-1$
+
+    private static Event dragEvent;
+
+    private static Listener currentListener = null;
+
+    private static Control dragSource;
+
+    private static Listener dragListener = new Listener() {
+        public void handleEvent(Event event) {
+            dragEvent = event;
+            if (dragSource != event.widget) {
+                dragSource = null;
+                currentListener = null;
+            }
+        }
+    };
+
+    /**
+     * Returns whether the mouse has moved enough to warrant
+     * opening a tracker.
+     */
+    private static boolean hasMovedEnough(Event event) {
+        return Geometry.distanceSquared(DragUtil.getEventLoc(event), anchor) >= HYSTERESIS
+                * HYSTERESIS;
+    }
+
+    private static Listener moveListener = new Listener() {
+        public void handleEvent(Event event) {
+            handleMouseMove(event);
+        }
+    };
+
+    private static Listener clickListener = new Listener() {
+        public void handleEvent(Event e) {
+            handleMouseClick(e);
+        }
+    };
+
+    private static Listener mouseDownListener = new Listener() {
+        public void handleEvent(Event event) {
+            if (event.widget instanceof Control) {
+            	// Remember the button that started the drag so we
+            	// can forward it on the call to the 'externalDragListener'
+            	initialMouseButton = event.button;
+            	
+                dragSource = (Control) event.widget;
+                currentListener = (Listener) dragSource.getData(LISTENER_ID);
+                anchor = DragUtil.getEventLoc(event);
+
+                if (dragEvent != null && (dragEvent.widget != dragSource)) {
+                    dragEvent = null;
+                }
+            }
+        }
+    };
+
+    private static void handleMouseClick(Event event) {
+        cancelDrag();
+    }
+
+    private static void handleMouseMove(Event e) {
+        if (currentListener != null && dragEvent != null && hasMovedEnough(e)) {
+            if (dragSource != null && !dragSource.isDisposed()
+                    && dragSource == e.widget) {
+                Event de = dragEvent;
+                
+                // cache the current value so we can restore it later
+                int originalMouseButton = de.button;
+                
+                // Update the button field so that the drag listener
+                // can detect whether or not it's a 'right button' drag
+                de.button = initialMouseButton;
+                
+                Listener l = currentListener;
+                cancelDrag();
+                l.handleEvent(de);
+                
+                // Restore the event's state so that other listeners see 
+                // the original values
+                de.button = originalMouseButton;
+            } else {
+                cancelDrag();
+            }
+        }
+    }
+
+    private static void cancelDrag() {
+        currentListener = null;
+        dragEvent = null;
+        dragSource = null;
+
+        initialMouseButton = 0;
+    }
+
+    /**
+     * Adds a drag listener to the given control. The behavior is very similar
+     * to control.addListener(SWT.DragDetect, dragListener), however the listener
+     * attached by this method is less sensitive. The drag event is only fired
+     * once the user moves the cursor more than HYSTERESIS pixels. 
+     * <p>
+     * This is useful for registering a listener that will trigger an editor or
+     * view drag, since an overly sensitive drag listener can cause users to accidentally
+     * drag views when trying to select a tab.</p>
+     * <p>
+     * Currently, only one such drag listener can be registered at a time. </p> 
+     * 
+     * @param control the control containing the drag listener
+     * @param externalDragListener the drag listener to attach
+     */
+    public static void addDragListener(Control control,
+            Listener externalDragListener) {
+        control.addListener(SWT.DragDetect, dragListener);
+        control.addListener(SWT.MouseUp, clickListener);
+        control.addListener(SWT.MouseDoubleClick, clickListener);
+        control.addListener(SWT.MouseDown, mouseDownListener);
+        control.addListener(SWT.MouseMove, moveListener);
+        control.setData(LISTENER_ID, externalDragListener);
+    }
+
+    /**
+     * Removes a drag listener that was previously attached using addDragListener
+     * 
+     * @param control the control containing the drag listener
+     * @param externalDragListener the drag listener to remove
+     */
+    public static void removeDragListener(Control control,
+            Listener externalDragListener) {
+        control.removeListener(SWT.DragDetect, dragListener);
+        control.removeListener(SWT.MouseUp, clickListener);
+        control.removeListener(SWT.MouseDoubleClick, clickListener);
+        control.removeListener(SWT.MouseDown, mouseDownListener);
+        control.removeListener(SWT.MouseMove, moveListener);
+        control.setData(LISTENER_ID, null);
+        if (externalDragListener == currentListener) {
+            cancelDrag();
+        }
+    }
+
+}