001: /*
002: * ProfileTreeDragHandler.java
003: *
004: * This file is part of SQL Workbench/J, http://www.sql-workbench.net
005: *
006: * Copyright 2002-2008, Thomas Kellerer
007: * No part of this code maybe reused without the permission of the author
008: *
009: * To contact the author please send an email to: support@sql-workbench.net
010: *
011: */
012: package workbench.gui.profiles;
013:
014: import java.awt.Point;
015: import java.awt.datatransfer.DataFlavor;
016: import java.awt.datatransfer.Transferable;
017: import java.awt.dnd.DnDConstants;
018: import java.awt.dnd.DragGestureEvent;
019: import java.awt.dnd.DragGestureListener;
020: import java.awt.dnd.DragGestureRecognizer;
021: import java.awt.dnd.DragSource;
022: import java.awt.dnd.DragSourceDragEvent;
023: import java.awt.dnd.DragSourceDropEvent;
024: import java.awt.dnd.DragSourceEvent;
025: import java.awt.dnd.DragSourceListener;
026: import java.awt.dnd.DropTarget;
027: import java.awt.dnd.DropTargetContext;
028: import java.awt.dnd.DropTargetDragEvent;
029: import java.awt.dnd.DropTargetDropEvent;
030: import java.awt.dnd.DropTargetEvent;
031: import java.awt.dnd.DropTargetListener;
032: import javax.swing.tree.DefaultMutableTreeNode;
033: import javax.swing.tree.TreeNode;
034: import javax.swing.tree.TreePath;
035: import workbench.log.LogMgr;
036:
037: /**
038: * Handle drag and drop in the profile Tree
039: * @author support@sql-workbench.net
040: */
041: class ProfileTreeDragHandler implements DragSourceListener,
042: DragGestureListener, DropTargetListener {
043: private DropTarget dropTarget;
044: private DragSource dragSource;
045: private DragGestureRecognizer recognizer;
046: private ProfileTree profileTree;
047: private TreePath[] draggedProfiles;
048:
049: public ProfileTreeDragHandler(ProfileTree tree, int actions) {
050: profileTree = tree;
051: dragSource = new DragSource();
052: dropTarget = new DropTarget(profileTree, this );
053: recognizer = dragSource.createDefaultDragGestureRecognizer(
054: profileTree, actions, this );
055: }
056:
057: public void dragGestureRecognized(DragGestureEvent dge) {
058: if (!profileTree.onlyProfilesSelected())
059: return;
060:
061: // For some reason the TreePaths stored in the TransferableProfileNode
062: // are losing their UserObjects, so I'm storing them as a variable
063: // as well (as all Drag&Drop processing is done in this class anyway,
064: // that should not do any harm.
065: draggedProfiles = profileTree.getSelectionPaths();
066: TransferableProfileNode transferable = new TransferableProfileNode(
067: draggedProfiles);
068:
069: dragSource.startDrag(dge, DragSource.DefaultMoveNoDrop,
070: transferable, this );
071: setCurrentDropTargetItem(null);
072: }
073:
074: // ------------ DragSourceListener ---------------------
075:
076: private void handleDragSourceEvent(DragSourceDragEvent dsde) {
077: int action = dsde.getDropAction();
078: if (action == DnDConstants.ACTION_COPY) {
079: dsde.getDragSourceContext().setCursor(
080: DragSource.DefaultCopyDrop);
081: } else {
082: if (action == DnDConstants.ACTION_MOVE) {
083: dsde.getDragSourceContext().setCursor(
084: DragSource.DefaultMoveDrop);
085: } else {
086: dsde.getDragSourceContext().setCursor(
087: DragSource.DefaultMoveNoDrop);
088: }
089: }
090: }
091:
092: public void dragEnter(DragSourceDragEvent dsde) {
093: handleDragSourceEvent(dsde);
094: }
095:
096: public void dragExit(DragSourceEvent dse) {
097: dse.getDragSourceContext().setCursor(
098: DragSource.DefaultMoveNoDrop);
099: }
100:
101: public void dragOver(DragSourceDragEvent dsde) {
102: handleDragSourceEvent(dsde);
103: }
104:
105: public void dropActionChanged(DragSourceDragEvent dsde) {
106: handleDragSourceEvent(dsde);
107: }
108:
109: public void dragDropEnd(DragSourceDropEvent dsde) {
110: setCurrentDropTargetItem(null);
111: }
112:
113: // ----------- DropTargetListener implementation -----------------
114: private void handleDragTargetEvent(DropTargetDragEvent dtde) {
115: Point p = dtde.getLocation();
116: profileTree.autoscroll(p);
117:
118: TreePath path = profileTree.getClosestPathForLocation(p.x, p.y);
119:
120: if (path == null) {
121: dtde.rejectDrag();
122: setCurrentDropTargetItem(null);
123: return;
124: }
125:
126: TreeNode node = (TreeNode) path.getLastPathComponent();
127: if (node.getAllowsChildren()) {
128: dtde.acceptDrag(dtde.getDropAction());
129: setCurrentDropTargetItem(node);
130: } else {
131: dtde.rejectDrag();
132: setCurrentDropTargetItem(null);
133: }
134: }
135:
136: private void setCurrentDropTargetItem(Object item) {
137: ProfileTreeCellRenderer rend = (ProfileTreeCellRenderer) profileTree
138: .getCellRenderer();
139: rend.setDropTargetItem(item);
140: profileTree.repaint();
141: }
142:
143: public void dragEnter(DropTargetDragEvent dtde) {
144: handleDragTargetEvent(dtde);
145: }
146:
147: public void dragOver(DropTargetDragEvent dtde) {
148: handleDragTargetEvent(dtde);
149: }
150:
151: public void dragExit(DropTargetEvent dte) {
152: setCurrentDropTargetItem(null);
153: }
154:
155: public void dropActionChanged(DropTargetDragEvent dtde) {
156: }
157:
158: public void drop(DropTargetDropEvent dtde) {
159: Point pt = dtde.getLocation();
160: DropTargetContext dtc = dtde.getDropTargetContext();
161:
162: TreePath parentpath = profileTree.getClosestPathForLocation(
163: pt.x, pt.y);
164: DefaultMutableTreeNode parent = (DefaultMutableTreeNode) parentpath
165: .getLastPathComponent();
166:
167: if (!parent.getAllowsChildren() || draggedProfiles == null) {
168: dtde.rejectDrop();
169: dtde.dropComplete(false);
170: return;
171: }
172:
173: try {
174: DefaultMutableTreeNode[] nodes = new DefaultMutableTreeNode[draggedProfiles.length];
175: for (int i = 0; i < draggedProfiles.length; i++) {
176: nodes[i] = (DefaultMutableTreeNode) draggedProfiles[i]
177: .getLastPathComponent();
178: }
179: dtde.acceptDrop(dtde.getDropAction());
180: profileTree.handleDroppedNodes(nodes, parent, dtde
181: .getDropAction());
182: dtde.dropComplete(true);
183: } catch (Exception e) {
184: LogMgr.logError("ProfileTreeDragHandler.drop()",
185: "Error when finishing drop", e);
186: dtde.rejectDrop();
187: dtde.dropComplete(false);
188: } finally {
189: draggedProfiles = null;
190: setCurrentDropTargetItem(null);
191: }
192: }
193:
194: }
|