From 274217d7c8fafbce1681396f660ff76f49b28493 Mon Sep 17 00:00:00 2001 From: dragonmacher <48328597+dragonmacher@users.noreply.github.com> Date: Tue, 21 May 2024 13:09:04 -0400 Subject: [PATCH] GP-4574 - Minor refactor of drag and drop interfaces --- .../core/codebrowser/CodeViewerProvider.java | 27 +- .../compositeeditor/CompositeEditorPanel.java | 122 +---- .../datapreview/DataTypePreviewPlugin.java | 14 +- .../core/programtree/DragNDropTree.java | 190 +++----- .../core/programtree/ProgramDnDTree.java | 69 +-- .../core/programtree/ReorderManager.java | 438 +++++++++--------- .../references/EditReferencesProvider.java | 35 -- .../core/references/InstructionPanel.java | 59 +-- .../VTDualListingDragNDropHandler.java | 64 +-- .../java/docking/dnd/DragGestureAdapter.java | 112 ++--- .../main/java/docking/dnd/DragSrcAdapter.java | 204 ++++---- .../src/main/java/docking/dnd/Draggable.java | 65 +-- .../src/main/java/docking/dnd/Droppable.java | 28 +- .../filechooser/GhidraFileChooserPanel.java | 48 +- .../ghidra/app/util/FileOpenDropHandler.java | 10 - .../ghidra/framework/main/FrontEndPlugin.java | 12 - .../ghidra/framework/main/ToolButton.java | 64 +-- .../main/ToolButtonTransferable.java | 142 +++--- .../main/datatree/VersionHistoryPanel.java | 10 - 19 files changed, 605 insertions(+), 1108 deletions(-) diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeViewerProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeViewerProvider.java index d7af298e11..4732ac66ad 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeViewerProvider.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeViewerProvider.java @@ -340,11 +340,6 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter return null; } - @Override - public void dragCanceled(DragSourceDropEvent event) { - // nothing to do - } - @Override public int getDragAction() { return dragAction; @@ -370,11 +365,6 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter return listingPanel.isStartDragOk(); } - @Override - public void move() { - // nothing to do - } - @Override public void add(Object obj, DropTargetDropEvent event, DataFlavor f) { Point p = event.getLocation(); @@ -385,11 +375,6 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter } } - @Override - public void dragUnderFeedback(boolean ok, DropTargetDragEvent e) { - // nothing to do - } - @Override public boolean isDropOk(DropTargetDragEvent e) { curDropProvider = null; @@ -431,11 +416,6 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter } } - @Override - public void undoDragUnderFeedback() { - // nothing to do - } - protected void doSetProgram(Program newProgram) { currentLocation = null; @@ -1112,11 +1092,10 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter public Highlight[] createHighlights(String text, ListingField field, int cursorTextOffset) { List list = new ArrayList<>(); - ListingHighlightProvider currentExternalHighligter = - programHighlighterMap.get(program); + ListingHighlightProvider currentExternalHighligter = programHighlighterMap.get(program); if (currentExternalHighligter != null) { - Highlight[] highlights = currentExternalHighligter.createHighlights(text, field, - cursorTextOffset); + Highlight[] highlights = + currentExternalHighligter.createHighlights(text, field, cursorTextOffset); for (Highlight highlight : highlights) { list.add(highlight); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/CompositeEditorPanel.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/CompositeEditorPanel.java index 58c81ee818..5f3610b61b 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/CompositeEditorPanel.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/CompositeEditorPanel.java @@ -17,7 +17,6 @@ package ghidra.app.plugin.core.compositeeditor; import java.awt.*; import java.awt.datatransfer.DataFlavor; -import java.awt.datatransfer.Transferable; import java.awt.dnd.*; import java.awt.event.*; import java.math.BigInteger; @@ -34,7 +33,8 @@ import javax.swing.text.JTextComponent; import docking.DockingWindowManager; import docking.actions.KeyBindingUtils; -import docking.dnd.*; +import docking.dnd.DropTgtAdapter; +import docking.dnd.Droppable; import docking.widgets.DropDownSelectionTextField; import docking.widgets.OptionDialog; import docking.widgets.fieldpanel.support.FieldRange; @@ -68,10 +68,7 @@ import help.HelpService; * composite data type. To add your own info panel override the createInfoPanel() method. */ public abstract class CompositeEditorPanel extends JPanel - implements CompositeEditorModelListener, ComponentCellEditorListener, Draggable, Droppable { - - // Normal color for selecting components in the table. - //protected static final Insets TEXTFIELD_INSETS = new JTextField().getInsets(); + implements CompositeEditorModelListener, ComponentCellEditorListener, Droppable { protected static final Border BEVELED_BORDER = BorderFactory.createLoweredBevelBorder(); @@ -90,10 +87,6 @@ public abstract class CompositeEditorPanel extends JPanel /** The table cell renderer for drag-n-drop. */ protected DndTableCellRenderer dndTableCellRenderer; protected DndTableCellRenderer dndDtiCellRenderer; - private DragSource dragSource; - private DragGestureAdapter dragGestureAdapter; - private DragSrcAdapter dragSourceAdapter; - private int dragAction = DnDConstants.ACTION_MOVE; private DropTarget dropTarget; private DropTgtAdapter dropTargetAdapter; private DataFlavor[] acceptableFlavors; // data flavors that are valid. @@ -151,8 +144,7 @@ public abstract class CompositeEditorPanel extends JPanel } private boolean launchBitFieldEditor(int modelRow, int modelColumn) { - if (model.viewComposite instanceof Structure && - !model.viewComposite.isPackingEnabled() && + if (model.viewComposite instanceof Structure && !model.viewComposite.isPackingEnabled() && model.getDataTypeColumn() == modelColumn && modelRow < model.getNumComponents()) { // check if we are attempting to edit a bitfield DataTypeComponent dtComponent = model.getComponent(modelRow); @@ -788,99 +780,6 @@ public abstract class CompositeEditorPanel extends JPanel dropTarget = new DropTarget(table, DnDConstants.ACTION_COPY_OR_MOVE, dropTargetAdapter, true); dropTarget.setActive(true); - - // set up the component area as a drag site that provides Data Types. - dragSource = DragSource.getDefaultDragSource(); - dragGestureAdapter = new DragGestureAdapter(this); - dragSourceAdapter = new DragSrcAdapter(this); - dragSource.createDefaultDragGestureRecognizer(table, dragAction, dragGestureAdapter); - } - - /** - * Return true if the object at the location in the DragGesture - * event is draggable. - * - * @param e event passed to a DragGestureListener via its - * dragGestureRecognized() method when a particular DragGestureRecognizer - * detects a platform dependent Drag and Drop action initiating - * gesture has occurred on the Component it is tracking. - * @see docking.dnd.DragGestureAdapter - */ - @Override - public boolean isStartDragOk(DragGestureEvent e) { - return false; -// boolean dragOk = false; -// // Need to check that the location is on a component. -// Point point = e.getDragOrigin(); -// int index = table.rowAtPoint(point); -// // If we are on a component then drag is allowed. -// if ((index >= 0) && (index < model.getNumComponents())) { -// dragOk = true; -// } -// return dragOk; - } - - /** - * Called by the DragGestureAdapter to start the drag. - */ - @Override - public DragSourceListener getDragSourceListener() { - return dragSourceAdapter; - } - - /** - * Do the move operation; called when the drag and drop operation - * completes. - * @see docking.dnd.DragSrcAdapter#dragDropEnd - */ - @Override - public void move() { - // no-op - } - - /** - * Method called when the drag operation exits the drop target - * without dropping. - */ - @Override - public void dragCanceled(DragSourceDropEvent event) { - // no-op - } - - /** - * Get the drag actions supported by this drag source: - * - * - * @return the drag actions - */ - @Override - public int getDragAction() { - return dragAction; - } - - /** - * Get the object to transfer. - * - * @param p location of object to transfer - * @return object to transfer - */ - @Override - public Transferable getTransferable(Point p) { - int index = table.rowAtPoint(p); - int numRows = model.getRowCount(); - if (index >= numRows) { - index = numRows; - } - DataType dt = DefaultDataType.dataType; - // If we are on a component then get the data type. - if ((index >= 0)) { - dt = model.getComponent(index).getDataType(); - } - return new DataTypeTransferable(dt); } @Override @@ -888,15 +787,6 @@ public abstract class CompositeEditorPanel extends JPanel return true; } - /** - * Add the object to the droppable component. The DragSrcAdapter calls this method from its - * drop() method. - * - * @param obj Transferable object that is to be dropped. - * @param e has current state of drop operation - * @param f represents the opaque concept of a data format as - * would appear on a clipboard, during drag and drop. - */ @Override public void add(Object obj, DropTargetDropEvent e, DataFlavor f) { if (!(obj instanceof DataType)) { @@ -1491,8 +1381,8 @@ public abstract class CompositeEditorPanel extends JPanel String status = columnName + " field is not editable"; boolean isValidRow = row >= 0 && row < model.getNumComponents(); - boolean isStringColumn = modelColumn == model.getNameColumn() || - modelColumn == model.getCommentColumn(); + boolean isStringColumn = + modelColumn == model.getNameColumn() || modelColumn == model.getCommentColumn(); if (isValidRow && isStringColumn) { DataType dt = model.getComponent(row).getDataType(); if (dt == DataType.DEFAULT) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datapreview/DataTypePreviewPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datapreview/DataTypePreviewPlugin.java index 050887110a..ceab354645 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datapreview/DataTypePreviewPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datapreview/DataTypePreviewPlugin.java @@ -422,16 +422,6 @@ public class DataTypePreviewPlugin extends ProgramPlugin { return true; } - @Override - public void dragUnderFeedback(boolean ok, DropTargetDragEvent e) { - // don't care - } - - @Override - public void undoDragUnderFeedback() { - // don't care - } - @Override public void add(Object obj, DropTargetDropEvent e, DataFlavor f) { if (obj instanceof DataType) { @@ -608,9 +598,7 @@ public class DataTypePreviewPlugin extends ProgramPlugin { } private boolean contains(DataType dt) { - Iterator iter = data.iterator(); - while (iter.hasNext()) { - Preview p = iter.next(); + for (Preview p : data) { if (p.getDataType().equals(dt) || p.getDataType().isEquivalent(dt)) { return true; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/programtree/DragNDropTree.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/programtree/DragNDropTree.java index 02f0a8f347..b9f01e2cbe 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/programtree/DragNDropTree.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/programtree/DragNDropTree.java @@ -43,7 +43,7 @@ public abstract class DragNDropTree extends JTree implements Draggable, Droppabl private AutoscrollAdapter autoscroller; - protected DefaultTreeModel treeModel; + protected DefaultTreeModel model; protected DragSource dragSource; protected DragGestureAdapter dragGestureAdapter; protected TreeDragSrcAdapter dragSourceAdapter; @@ -52,7 +52,6 @@ public abstract class DragNDropTree extends JTree implements Draggable, Droppabl protected DropTarget dropTarget; protected DropTgtAdapter dropTargetAdapter; protected ProgramNode root; - protected ProgramTreeCellEditor cellEditor; protected Color plafSelectionColor; protected DnDTreeCellRenderer dndCellRenderer; protected boolean drawFeedback; @@ -60,23 +59,23 @@ public abstract class DragNDropTree extends JTree implements Draggable, Droppabl protected ProgramNode destinationNode; // target for drop site // data flavors that this tree can support - protected DataFlavor[] acceptableFlavors; // filled in by the - // getAcceptableDataFlavors() method + protected DataFlavor[] acceptableFlavors; protected TreeTransferable transferable; protected Color nonSelectionDragColor; - protected int relativeMousePos; // mouse position within the node: + protected int relativeMousePos; // mouse position within the node public DragNDropTree(DefaultTreeModel model) { super(model); setBackground(new GColor("color.bg.tree")); - treeModel = model; + this.model = model; this.root = (ProgramNode) model.getRoot(); - //setEditable(true); // edit interferes with drag gesture listener + + // setEditable(true); // edit interferes with drag gesture listener setShowsRootHandles(true); // need this to "drill down" - cellEditor = new ProgramTreeCellEditor(); - setCellEditor(cellEditor); + ProgramTreeCellEditor treeCellEditor = new ProgramTreeCellEditor(); + setCellEditor(treeCellEditor); dndCellRenderer = new DnDTreeCellRenderer(); setCellRenderer(dndCellRenderer); plafSelectionColor = dndCellRenderer.getBackgroundSelectionColor(); @@ -87,10 +86,10 @@ public abstract class DragNDropTree extends JTree implements Draggable, Droppabl disableJTreeTransferActions(); } - //// Draggable interface methods - /** - * Return true if the location in the event is draggable. - */ +//================================================================================================= +// Draggable Methods +//================================================================================================= + @Override public boolean isStartDragOk(DragGestureEvent e) { synchronized (root) { @@ -106,27 +105,16 @@ public abstract class DragNDropTree extends JTree implements Draggable, Droppabl } } - /** - * Called by the DragGestureAdapter to start the drag. - */ @Override public DragSourceListener getDragSourceListener() { return dragSourceAdapter; } - /** - * Called by the DragGestureAdapter and the DragSourceAdapter to - * know what actions this component allows. - */ @Override public int getDragAction() { return DnDConstants.ACTION_COPY_OR_MOVE; } - /** - * Called by the DragGestureAdapter when the drag is about to - * start. - */ @Override public Transferable getTransferable(Point p) { synchronized (root) { @@ -146,31 +134,16 @@ public abstract class DragNDropTree extends JTree implements Draggable, Droppabl } } - /** - * Do the move operation. Called from the DragSourceAdapter - * when the drop completes and the user action was a - * DnDConstants.MOVE. - */ @Override - public abstract void move(); - - /** - * Called from the DragSourceAdapter when the drag operation exits the - * drop target without dropping. - */ - @Override - public void dragCanceled(DragSourceDropEvent event) { + public void dragFinished(boolean wasCancelled) { draggedNodes = null; dndCellRenderer.setBackgroundSelectionColor(plafSelectionColor); - dndCellRenderer - .setBackgroundNonSelectionColor(dndCellRenderer.getBackgroundNonSelectionColor()); } - ////////////////////////////////////////////////////////////////////// - // Droppable interface methods - /** - * Return true if OK to drop at the location specified in the event. - */ +//================================================================================================= +// Droppable Methods +//================================================================================================= + @Override public boolean isDropOk(DropTargetDragEvent e) { synchronized (root) { @@ -228,11 +201,6 @@ public abstract class DragNDropTree extends JTree implements Draggable, Droppabl return false; } - /** - * Called from the DropTgtAdapter when the drag operation is going over a drop site; indicate - * when the drop is OK by providing appropriate feedback. - * @param ok true means OK to drop - */ @Override public void dragUnderFeedback(boolean ok, DropTargetDragEvent e) { synchronized (root) { @@ -271,10 +239,6 @@ public abstract class DragNDropTree extends JTree implements Draggable, Droppabl } } - /** - * Called from the DropTgtAdapter to revert any feedback - * changes back to normal. - */ @Override public void undoDragUnderFeedback() { synchronized (root) { @@ -283,52 +247,29 @@ public abstract class DragNDropTree extends JTree implements Draggable, Droppabl repaint(); } - /** - * Add the data to the tree. Called from the DropTgtAdapter - * when the drop completes and the user action was a - * DnDConstants.COPY. - */ - @Override - public abstract void add(Object data, DropTargetDropEvent e, DataFlavor chosen); +//================================================================================================= +// Autoscroll Methods +//================================================================================================= - /////////////////////////////////////////////////////////// - // Autoscroll Interface methods - /////////////////////////////////////////////////////////// - /** - * This method returns the Insets describing - * the autoscrolling region or border relative - * to the geometry of the implementing Component; called - * repeatedly while dragging. - * @return the Insets - */ @Override public Insets getAutoscrollInsets() { return autoscroller.getAutoscrollInsets(); } - /** - * Notify the Component to autoscroll; called repeatedly - * while dragging. - *

- * @param p A Point indicating the - * location of the cursor that triggered this operation. - */ - @Override public void autoscroll(Point p) { autoscroller.autoscroll(p); } - /////////////////////////////////////////////////////////////// - // protected methods - /////////////////////////////////////////////////////////////// - /** - * Get the data flavors that this tree supports. - */ +//================================================================================================= +// Protected Methods +//================================================================================================= + protected abstract DataFlavor[] getAcceptableDataFlavors(); /** * Return true if the node can accept the drop as indicated by the event. + * @param node the node being dragged * @param e event that has current state of drag and drop operation * @return true if drop is OK */ @@ -336,11 +277,14 @@ public abstract class DragNDropTree extends JTree implements Draggable, Droppabl /** * Get the string to use as the tool tip for the specified node. + * @param node the node + * @return the text */ protected abstract String getToolTipText(ProgramNode node); /** * Get the node at the given point. + * @param p the point * @return null if there is no node a the point p. */ protected ProgramNode getTreeNode(Point p) { @@ -351,16 +295,41 @@ public abstract class DragNDropTree extends JTree implements Draggable, Droppabl return null; } - /** - * Return the drawFeedback state. - */ boolean getDrawFeedbackState() { return drawFeedback; } - ////////////////////////////////////////////////////////////////////// - // *** private methods - ////////////////////////////////////////////////////////////////////// + /** + * Determine where the mouse pointer is within the node. + * @param p the point + * @param node the node + * @return -1 if the mouse pointer is in the upper quarter of the node, 1 if the mouse pointer + * is in the lower quarter of the node, or 0 if the mouse pointer is in the center of the node. + */ + protected int comparePointerLocation(Point p, ProgramNode node) { + + int localRowHeight = getRowHeight(); + int row = this.getRowForPath(node.getTreePath()); + Rectangle rect = getRowBounds(row); + if (p.y == rect.y) { + return 1; + } + if ((p.y - rect.y) <= localRowHeight) { + int delta = localRowHeight - (p.y - rect.y); + int sliceSize = localRowHeight / 4; + if (delta < sliceSize) { + return 1; // in the lower part of the node + } + if (delta > (sliceSize * 3)) { + return -1; // in the upper part of the node + } + } + return 0; + } + +//================================================================================================= +// Private Methods +//================================================================================================= /** * Set up the drag and drop stuff. @@ -392,49 +361,16 @@ public abstract class DragNDropTree extends JTree implements Draggable, Droppabl KeyStroke.getKeyStroke(KeyEvent.VK_X, DockingUtils.CONTROL_KEY_MODIFIER_MASK)); } - /** - * Determine where the mouse pointer is within the node. - * @return -1 if the mouse pointer is in the upper quarter of the node, 1 if the mouse pointer - * is in the lower quarter of the node, or 0 if the mouse pointer is in the center of the node. - */ - int comparePointerLocation(Point p, ProgramNode node) { +//================================================================================================= +// Inner Classes +//================================================================================================= - int localRowHeight = getRowHeight(); - int row = this.getRowForPath(node.getTreePath()); - Rectangle rect = getRowBounds(row); - if (p.y == rect.y) { - return 1; - } - if ((p.y - rect.y) <= localRowHeight) { - int delta = localRowHeight - (p.y - rect.y); - int sliceSize = localRowHeight / 4; - if (delta < sliceSize) { - return 1; // in the lower part of the node - } - if (delta > (sliceSize * 3)) { - return -1; // in the upper part of the node - } - } - return 0; - } + private class ProgramTreeCellEditor extends DefaultTreeCellEditor { - ////////////////////////////////////////////////////////////////////// - /** - * TreeCellEditor for the program tree. - */ - protected class ProgramTreeCellEditor extends DefaultTreeCellEditor { - - /** - * Construct a new ProgramTreeCellEditor. - */ public ProgramTreeCellEditor() { super(DragNDropTree.this, null); } - /** - * Override this method in order to select the contents of - * the editing component which is a JTextField. - */ @Override public boolean shouldSelectCell(EventObject anEvent) { ((JTextField) editingComponent).selectAll(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/programtree/ProgramDnDTree.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/programtree/ProgramDnDTree.java index b092f3727a..568b556aaf 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/programtree/ProgramDnDTree.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/programtree/ProgramDnDTree.java @@ -161,10 +161,12 @@ public class ProgramDnDTree extends DragNDropTree { if (!super.isDropOk(e)) { return false; } + if (draggedNodes == null) { - return true; // drag initiated from somewhere else, so - // if the superclass said it was OK, then it's OK... + // drag initiated from elsewhere, if the superclass said it was OK, then it's OK + return true; } + Point p = e.getLocation(); ProgramNode destNode = getTreeNode(p); relativeMousePos = comparePointerLocation(p, destNode); @@ -173,14 +175,13 @@ public class ProgramDnDTree extends DragNDropTree { } } - /** - * Droppable interface method called from the DropTargetAdapter's - * drop() method. - */ @Override public void add(Object data, DropTargetDropEvent e, DataFlavor chosen) { synchronized (root) { + + draggedNodes = null; + if (destinationNode == null) { return; } @@ -189,20 +190,16 @@ public class ProgramDnDTree extends DragNDropTree { if (e != null) { dropAction = e.getDropAction(); } - // note: must use destinationNode because the when the user - // releases the mouse, the point could have moved, so - // the node obtained at the point is not necessarily the + + // Note: must use destinationNode because when the user releases the mouse, the + // point could have moved, so the node obtained at the point is not necessarily the // expected destinationNode. processDropRequest(destinationNode, data, chosen, dropAction); - if (dropAction == DnDConstants.ACTION_COPY) { - draggedNodes = null; - } } catch (Exception ex) { if (!(ex instanceof UsrException)) { Msg.error(this, "Unexpected Exception: " + ex.getMessage(), ex); } - draggedNodes = null; //let the drop() method handle the error reporting String msg = ex.getMessage(); @@ -219,20 +216,6 @@ public class ProgramDnDTree extends DragNDropTree { } } - /** - * Method called from the dragDropEnd() method in the - * DragSourceAdapter when the drop has completed. - * The "copy" part is done in the add() method. - * @see #add(Object, DropTargetDropEvent, DataFlavor) - */ - @Override - public void move() { - draggedNodes = null; - } - - /** - * Set the program for this tree. - */ void setProgram(Program p) { if (p == program) { return; @@ -423,13 +406,6 @@ public class ProgramDnDTree extends DragNDropTree { treeListener = null; } - /** - * Clear the variable that has the dragged data. - */ - void clearDragData() { - draggedNodes = null; - } - /** * Get the view list. * @@ -506,8 +482,7 @@ public class ProgramDnDTree extends DragNDropTree { TreePath path = node.getTreePath(); - for (int i = 0; i < viewList.size(); i++) { - TreePath viewPath = viewList.get(i); + for (TreePath viewPath : viewList) { if (viewPath.isDescendant(path) && !viewPath.equals(path)) { return true; } @@ -834,7 +809,7 @@ public class ProgramDnDTree extends DragNDropTree { if (parentModuleName.equals(parent.getName())) { TreePath childPath = child.getTreePath(); - treeModel.removeNodeFromParent(child); + model.removeNodeFromParent(child); child.removeAllChildren(); child.removeFromParent(); if (updateViewList) { @@ -902,7 +877,7 @@ public class ProgramDnDTree extends DragNDropTree { } ProgramNode child = new ProgramNode(program, group); - treeModel.insertNodeInto(child, parent, index); + model.insertNodeInto(child, parent, index); child.setParentModule(parent.getModule()); // do the lazy population which means don't @@ -1013,11 +988,10 @@ public class ProgramDnDTree extends DragNDropTree { } parent.insert(node, tempIndex); - treeModel.reload(parent); + model.reload(parent); } - for (int i = 0; i < list.size(); i++) { - TreePath p = list.get(i); + for (TreePath p : list) { expandPath(p); } } @@ -1181,7 +1155,7 @@ public class ProgramDnDTree extends DragNDropTree { List list = getExpandedPaths(node); TreePath[] paths = getSelectionPaths(); - treeModel.reload(node); + model.reload(node); expandPaths(list); @@ -1331,8 +1305,7 @@ public class ProgramDnDTree extends DragNDropTree { * @param list list of TreePaths. */ public void expandPaths(List list) { - for (int i = 0; i < list.size(); i++) { - TreePath path = list.get(i); + for (TreePath path : list) { expandPath(path); } } @@ -1402,8 +1375,7 @@ public class ProgramDnDTree extends DragNDropTree { */ private TreePath findTreePath(GroupPath groupPath) { - for (int i = 0; i < nodeList.size(); i++) { - ProgramNode node = nodeList.get(i); + for (ProgramNode node : nodeList) { GroupPath p = node.getGroupPath(); if (p.equals(groupPath)) { return node.getTreePath(); @@ -1753,8 +1725,7 @@ public class ProgramDnDTree extends DragNDropTree { * garbage collected. */ private void disposeOfNodes() { - for (int i = 0; i < nodeList.size(); i++) { - ProgramNode node = nodeList.get(i); + for (ProgramNode node : nodeList) { node.dispose(); } } @@ -1837,7 +1808,7 @@ public class ProgramDnDTree extends DragNDropTree { versionTag = rm.getVersionTag(); } - treeModel.setRoot(root); + model.setRoot(root); root.setTree(this); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/programtree/ReorderManager.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/programtree/ReorderManager.java index d16f235338..35320048fd 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/programtree/ReorderManager.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/programtree/ReorderManager.java @@ -15,134 +15,126 @@ */ package ghidra.app.plugin.core.programtree; -import ghidra.app.cmd.module.ReorderModuleCmd; -import ghidra.program.model.listing.CircularDependencyException; -import ghidra.program.model.listing.DuplicateGroupException; -import ghidra.program.model.listing.ProgramFragment; -import ghidra.program.model.listing.Group; -import ghidra.program.model.listing.ProgramModule; -import ghidra.util.Msg; -import ghidra.util.exception.NotFoundException; - import java.awt.dnd.DnDConstants; import javax.swing.SwingUtilities; import javax.swing.tree.TreePath; +import ghidra.app.cmd.module.ReorderModuleCmd; +import ghidra.program.model.listing.*; +import ghidra.util.Msg; +import ghidra.util.exception.NotFoundException; + /** * Manage the drop operation for reordering modules and fragments. */ class ReorderManager { - private ProgramDnDTree tree; + private ProgramDnDTree tree; - ReorderManager(ProgramDnDTree tree) { - this.tree = tree; - } + ReorderManager(ProgramDnDTree tree) { + this.tree = tree; + } - /** - * Return true if the destNode can accept the dropNode. - */ - boolean isDropSiteOk(ProgramNode destNode, ProgramNode dropNode, - int dropAction, int relativeMousePos) { + /** + * Return true if the destNode can accept the dropNode. + */ + boolean isDropSiteOk(ProgramNode destNode, ProgramNode dropNode, int dropAction, + int relativeMousePos) { - ProgramModule mParent = destNode.getParentModule(); - Group dragGroup = dropNode.getGroup(); + ProgramModule mParent = destNode.getParentModule(); + Group dragGroup = dropNode.getGroup(); - if (dragGroup.equals(destNode.getGroup())) { - return false; // can't drop a group onto itself - } + if (dragGroup.equals(destNode.getGroup())) { + return false; // can't drop a group onto itself + } if (mParent == null && relativeMousePos != 0) { return false;// can't reorder above or below root } - // if the target node is the same as the parent of the - // fromObject (node to be dropped), then the action - // must be a move, because this is just a reorder of the - // children. - if (destNode.equals(dropNode.getParent())) { - if (dropAction != DnDConstants.ACTION_MOVE) { - return false; - } - return true; - } - if (dropNode.getParent().equals(destNode.getParent()) && - dropAction != DnDConstants.ACTION_MOVE) { - return false; - } - if (!dropNode.getParent().equals(destNode.getParent())) { - // if parent nodes are different, check to make sure this - // fragment does not already exist as a child of the - // parent of the fromObject - if (dropNode.isFragment() ) { + // if the target node is the same as the parent of the + // fromObject (node to be dropped), then the action + // must be a move, because this is just a reorder of the + // children. + if (destNode.equals(dropNode.getParent())) { + if (dropAction != DnDConstants.ACTION_MOVE) { + return false; + } + return true; + } + if (dropNode.getParent().equals(destNode.getParent()) && + dropAction != DnDConstants.ACTION_MOVE) { + return false; + } + if (!dropNode.getParent().equals(destNode.getParent())) { + // if parent nodes are different, check to make sure this + // fragment does not already exist as a child of the + // parent of the fromObject + if (dropNode.isFragment()) { - ProgramFragment frag = dropNode.getFragment(); + ProgramFragment frag = dropNode.getFragment(); - if (mParent != null && - mParent.contains(frag)) { - return false; - } - // this is the root; make sure fragment does not - // already exist as a child of root... - if (mParent == null && - destNode.getModule().contains(frag)) { - return false; - } + if (mParent != null && mParent.contains(frag)) { + return false; + } + // this is the root; make sure fragment does not + // already exist as a child of root... + if (mParent == null && destNode.getModule().contains(frag)) { + return false; + } - if (destNode.isModule()) { - ProgramModule dm = destNode.getModule(); - if (dm.contains(frag)) { - return false; - } - } - return true; - } + if (destNode.isModule()) { + ProgramModule dm = destNode.getModule(); + if (dm.contains(frag)) { + return false; + } + } + return true; + } - // fromObject must be a module... - ProgramModule m = dropNode.getModule(); + // fromObject must be a module... + ProgramModule m = dropNode.getModule(); - if (mParent != null && (!m.equals(mParent) && - mParent.contains(m)) || m.equals(mParent) ) { - return false; - } - // this is the root; make sure module does not - // already exist as a child of root... - if (mParent == null && - destNode.getModule().contains(m) ) { - return false; - } - } - //else parent nodes are the same, so this a reorder + if (mParent != null && (!m.equals(mParent) && mParent.contains(m)) || + m.equals(mParent)) { + return false; + } + // this is the root; make sure module does not + // already exist as a child of root... + if (mParent == null && destNode.getModule().contains(m)) { + return false; + } + } + //else parent nodes are the same, so this a reorder - if (destNode.isModule() && dropAction == DnDConstants.ACTION_COPY) { - ProgramModule dm = destNode.getModule(); - if (dropNode.isModule()) { - if (dm.contains(dropNode.getModule())) { - return false; - } - } - else { - if (dm.contains(dropNode.getFragment())) { - return false; - } - } - } - return true; - } + if (destNode.isModule() && dropAction == DnDConstants.ACTION_COPY) { + ProgramModule dm = destNode.getModule(); + if (dropNode.isModule()) { + if (dm.contains(dropNode.getModule())) { + return false; + } + } + else { + if (dm.contains(dropNode.getFragment())) { + return false; + } + } + } + return true; + } - /** - * Add the given data to the destination node. - * @param destNode destination node for the data. - * @param dropNode data to add - */ - void add(ProgramNode destNode, ProgramNode[] dropNodes, int dropAction, int relativeMousePos) - throws NotFoundException, CircularDependencyException, DuplicateGroupException { + /** + * Add the given data to the destination node. + * @param destNode destination node for the data. + * @param dropNode data to add + */ + void add(ProgramNode destNode, ProgramNode[] dropNodes, int dropAction, int relativeMousePos) + throws NotFoundException, CircularDependencyException, DuplicateGroupException { - ProgramModule targetModule = destNode.getModule(); - ProgramFragment targetFrag = destNode.getFragment(); - if (targetModule == null && targetFrag == null) { - tree.clearDragData(); - return; // ignore the drop - } + ProgramModule targetModule = destNode.getModule(); + ProgramFragment targetFrag = destNode.getFragment(); + if (targetModule == null && targetFrag == null) { + return; // ignore the drop + } int transactionID = tree.startTransaction("Reorder"); if (transactionID < 0) { @@ -150,71 +142,72 @@ class ReorderManager { } try { - for ( int i = 0; i < dropNodes.length; i++ ) { - ProgramNode parentNode = (ProgramNode)destNode.getParent(); - reorderNode( destNode, dropAction, relativeMousePos, parentNode, dropNodes[i] ); - } - } finally { + for (ProgramNode dropNode : dropNodes) { + ProgramNode parentNode = (ProgramNode) destNode.getParent(); + reorderNode(destNode, dropAction, relativeMousePos, parentNode, dropNode); + } + } + finally { tree.endTransaction(transactionID, true); - } - } + } + } - private void reorderNode( ProgramNode destNode, int dropAction, - int relativeMousePos, ProgramNode parentNode, ProgramNode dropNode ) - throws NotFoundException, CircularDependencyException, DuplicateGroupException { - - if (!reorderChildren(destNode, dropNode, relativeMousePos)) { - int index; - - // this is the case where destNode and dropNode have different parents... - if (relativeMousePos < 0) { - if (parentNode == null) { - return; - } - index = parentNode.getIndex(destNode); - } - else { - // if destNode is a module and if it is expanded, - // then dropNode will go inside the module - if (destNode.isModule() && tree.isExpanded(destNode.getTreePath())) { - index = 0; - destNode = (ProgramNode)destNode.getChildAt(0); - } - else { - // destNode is a module or a fragment, but place - // destNode after it - index = parentNode.getIndex(destNode); - ++index; - } - - } - addGroup(destNode, dropNode, index, dropAction); - ProgramNode child = (ProgramNode)parentNode.getChildAt(index); - selectNode(dropNode, child); - } - } + private void reorderNode(ProgramNode destNode, int dropAction, int relativeMousePos, + ProgramNode parentNode, ProgramNode dropNode) + throws NotFoundException, CircularDependencyException, DuplicateGroupException { + + if (!reorderChildren(destNode, dropNode, relativeMousePos)) { + int index; + + // this is the case where destNode and dropNode have different parents... + if (relativeMousePos < 0) { + if (parentNode == null) { + return; + } + index = parentNode.getIndex(destNode); + } + else { + // if destNode is a module and if it is expanded, + // then dropNode will go inside the module + if (destNode.isModule() && tree.isExpanded(destNode.getTreePath())) { + index = 0; + destNode = (ProgramNode) destNode.getChildAt(0); + } + else { + // destNode is a module or a fragment, but place + // destNode after it + index = parentNode.getIndex(destNode); + ++index; + } + + } + addGroup(destNode, dropNode, index, dropAction); + ProgramNode child = (ProgramNode) parentNode.getChildAt(index); + selectNode(dropNode, child); + } + } /** * Reorder children with the same module. * @return true if reordering was done; false if no changes * were made */ - private boolean reorderChildren(ProgramNode destNode, ProgramNode dropNode, - int relativeMousePos) { + private boolean reorderChildren(ProgramNode destNode, ProgramNode dropNode, + int relativeMousePos) { boolean didReorder = false; - + int index = 0; - ProgramNode parentNode = (ProgramNode)destNode.getParent(); + ProgramNode parentNode = (ProgramNode) destNode.getParent(); ProgramModule dropParentModule = dropNode.getParentModule(); ProgramModule targetModule = destNode.getModule(); - + if (parentNode.equals(dropNode.getParent())) { didReorder = true; - targetModule = parentNode.getModule(); + targetModule = parentNode.getModule(); int myIndex = parentNode.getIndex(dropNode); - index = parentNode.getIndex(destNode); + index = parentNode.getIndex(destNode); if (relativeMousePos < 0 && myIndex < index) { --index; } @@ -222,39 +215,38 @@ class ReorderManager { ++index; } Group group = dropNode.getGroup(); - ReorderModuleCmd cmd = new ReorderModuleCmd(tree.getTreeName(), - targetModule.getName(), - group.getName(), index); + ReorderModuleCmd cmd = new ReorderModuleCmd(tree.getTreeName(), targetModule.getName(), + group.getName(), index); if (tree.getTool().execute(cmd, tree.getProgram())) { - tree.reorder(group, dropParentModule, index); - ProgramNode child = (ProgramNode)parentNode.getChildAt(index); + tree.reorder(group, dropParentModule, index); + ProgramNode child = (ProgramNode) parentNode.getChildAt(index); addToSelection(child); - } + } else { Msg.showError(this, tree, "Error Moving Child", cmd.getStatusMsg()); } } return didReorder; } - //////////////////////////////////////////////////////////////////// - - /** - * Match the expansion state for the dropNode and the nodeToSelect - * (which is the new node that just got added). Select the new - * node. - */ - private void selectNode(ProgramNode dropNode, ProgramNode nodeToSelect) { - - // apply expansion state of the dropped node to the new node. - tree.matchExpansionState(dropNode, nodeToSelect); + //////////////////////////////////////////////////////////////////// - // add the target node to the selection later so - // that the selection shows as being selected; - // without the invokeLater(), the path is not - // rendered as being selected. + /** + * Match the expansion state for the dropNode and the nodeToSelect + * (which is the new node that just got added). Select the new + * node. + */ + private void selectNode(ProgramNode dropNode, ProgramNode nodeToSelect) { + + // apply expansion state of the dropped node to the new node. + tree.matchExpansionState(dropNode, nodeToSelect); + + // add the target node to the selection later so + // that the selection shows as being selected; + // without the invokeLater(), the path is not + // rendered as being selected. addToSelection(nodeToSelect); - } + } /** * Add the path for the given node to the selection. @@ -263,61 +255,57 @@ class ReorderManager { final TreePath p = node.getTreePath(); tree.addSelectionPath(p); Runnable r = new Runnable() { - public void run() { - tree.addSelectionPath(p); - } + @Override + public void run() { + tree.addSelectionPath(p); + } }; SwingUtilities.invokeLater(r); } - - /** - * Add a new group to the destNode or re-parent the drop Node to - * the destNode's parent (or to root if destNode's parent is null). - * @param destNode drop site for dropped node - * @param dropNode node to drop at destNode - * @param targetIndex new index for node that is added - * @param dropAction DnDConstants.ACTION_COPY or ACTION_MOVE - */ - private void addGroup(ProgramNode destNode, ProgramNode dropNode, - int targetIndex, int dropAction) - throws NotFoundException, CircularDependencyException, - DuplicateGroupException{ - Group group = null; - ProgramNode targetParent = (ProgramNode)destNode.getParent(); - - // first add drop fragment or module - // to target's parent - ProgramModule targetParentModule = - (targetParent != null) ? targetParent.getModule() : - destNode.getModule(); - ProgramFragment dropFragment = dropNode.getFragment(); - ProgramModule dropModule = dropNode.getModule(); + /** + * Add a new group to the destNode or re-parent the drop Node to + * the destNode's parent (or to root if destNode's parent is null). + * @param destNode drop site for dropped node + * @param dropNode node to drop at destNode + * @param targetIndex new index for node that is added + * @param dropAction DnDConstants.ACTION_COPY or ACTION_MOVE + */ + private void addGroup(ProgramNode destNode, ProgramNode dropNode, int targetIndex, + int dropAction) + throws NotFoundException, CircularDependencyException, DuplicateGroupException { + Group group = null; + ProgramNode targetParent = (ProgramNode) destNode.getParent(); - if (dropAction == DnDConstants.ACTION_COPY) { - if (dropFragment!= null) { - targetParentModule.add(dropFragment); - group = dropFragment; - } - else { - targetParentModule.add(dropModule); - group = dropModule; - } - } - else { - targetParentModule.reparent(dropNode.getName(), - dropNode.getParentModule()); - if (dropFragment != null) { - group = dropFragment; - } - else { - group = dropModule; - } - } - tree.groupAdded(group); - targetParentModule.moveChild(group.getName(), - targetIndex); - tree.reorder(dropNode.getGroup(), targetParentModule, - targetIndex); - } + // first add drop fragment or module + // to target's parent + ProgramModule targetParentModule = + (targetParent != null) ? targetParent.getModule() : destNode.getModule(); + + ProgramFragment dropFragment = dropNode.getFragment(); + ProgramModule dropModule = dropNode.getModule(); + + if (dropAction == DnDConstants.ACTION_COPY) { + if (dropFragment != null) { + targetParentModule.add(dropFragment); + group = dropFragment; + } + else { + targetParentModule.add(dropModule); + group = dropModule; + } + } + else { + targetParentModule.reparent(dropNode.getName(), dropNode.getParentModule()); + if (dropFragment != null) { + group = dropFragment; + } + else { + group = dropModule; + } + } + tree.groupAdded(group); + targetParentModule.moveChild(group.getName(), targetIndex); + tree.reorder(dropNode.getGroup(), targetParentModule, targetIndex); + } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/EditReferencesProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/EditReferencesProvider.java index 1ec62a6d0e..c3b8a6b241 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/EditReferencesProvider.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/EditReferencesProvider.java @@ -112,23 +112,6 @@ public class EditReferencesProvider extends ComponentProviderAdapter private DropTgtAdapter dropTargetAdapter; private Droppable dropHandler = new Droppable() { - /** - * Set drag feedback according to the ok parameter. - * - * @param ok true means the drop action is OK - * @param e event that has current state of drag and drop operation - */ - @Override - public void dragUnderFeedback(boolean ok, DropTargetDragEvent e) { - // don't care - } - - /** - * Return true if is OK to drop the transferable at the location - * specified the event. - * - * @param e event that has current state of drag and drop operation - */ @Override public boolean isDropOk(DropTargetDragEvent e) { if (currentCodeUnit != null) { @@ -151,24 +134,6 @@ public class EditReferencesProvider extends ComponentProviderAdapter return false; } - /** - * Revert back to normal if any drag feedback was set. - */ - @Override - public void undoDragUnderFeedback() { - // don't care - } - - /** - * Add the object to the droppable component. The DropTargetAdapter - * calls this method from its drop() method. - * - * @param obj Transferable object that is to be dropped; in this case, - * it is an AddressSetView - * @param e has current state of drop operation - * @param f represents the opaque concept of a data format as would - * appear on a clipboard, during drag and drop. - */ @Override public void add(Object obj, DropTargetDropEvent e, DataFlavor f) { AddressSetView view = ((SelectionTransferData) obj).getAddressSet(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/InstructionPanel.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/InstructionPanel.java index 774f91575e..e9c56d680a 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/InstructionPanel.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/InstructionPanel.java @@ -434,61 +434,34 @@ class InstructionPanel extends JPanel implements ChangeListener { } private class InstructionPanelDroppable implements Droppable { - /** - * Set drag feedback according to the ok parameter. - * @param ok true means the drop action is OK - * @param e event that has current state of drag and drop operation - */ - @Override - public void dragUnderFeedback(boolean ok, DropTargetDragEvent e) { - // stub - } - /** - * Return true if is OK to drop the transferable at the location - * specified the event. - * @param e event that has current state of drag and drop operation - */ @Override public boolean isDropOk(DropTargetDragEvent e) { Component targetComp = e.getDropTargetContext().getComponent(); - if (targetComp instanceof JLabel) { + if (!(targetComp instanceof JLabel)) { + return false; + } - updateActiveIndex(getLabelIndex((JLabel) targetComp), -1); + updateActiveIndex(getLabelIndex((JLabel) targetComp), -1); - try { - Object data = e.getTransferable() - .getTransferData(SelectionTransferable.localProgramSelectionFlavor); - AddressSetView view = ((SelectionTransferData) data).getAddressSet(); - if (memory.contains(view)) { - return true; - } - } - catch (UnsupportedFlavorException e1) { - // return false - } - catch (IOException e1) { - // return false + try { + Object data = e.getTransferable() + .getTransferData(SelectionTransferable.localProgramSelectionFlavor); + AddressSetView view = ((SelectionTransferData) data).getAddressSet(); + if (memory.contains(view)) { + return true; } } + catch (UnsupportedFlavorException e1) { + // return false + } + catch (IOException e1) { + // return false + } return false; } - @Override - public void undoDragUnderFeedback() { - // stub - } - - /** - * Add the object to the droppable component. The DropTargetAdapter - * calls this method from its drop() method. - * @param obj Transferable object that is to be dropped; in this - * case, it is an AddressSetView - * @param e has current state of drop operation - * @param f represents the opaque concept of a data format as - * would appear on a clipboard, during drag and drop. - */ @Override public void add(Object obj, DropTargetDropEvent e, DataFlavor f) { AddressSetView view = ((SelectionTransferData) obj).getAddressSet(); diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/duallisting/VTDualListingDragNDropHandler.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/duallisting/VTDualListingDragNDropHandler.java index d7f4d652ba..c4b2d0b838 100644 --- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/duallisting/VTDualListingDragNDropHandler.java +++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/duallisting/VTDualListingDragNDropHandler.java @@ -15,6 +15,13 @@ */ package ghidra.feature.vt.gui.duallisting; +import java.awt.Point; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.*; +import java.util.ArrayList; + +import docking.dnd.*; import ghidra.app.util.viewer.listingpanel.ListingCodeComparisonPanel; import ghidra.app.util.viewer.listingpanel.ListingPanel; import ghidra.feature.vt.api.main.*; @@ -26,14 +33,6 @@ import ghidra.program.util.ProgramLocation; import ghidra.util.Msg; import ghidra.util.SystemUtilities; -import java.awt.Point; -import java.awt.datatransfer.DataFlavor; -import java.awt.datatransfer.Transferable; -import java.awt.dnd.*; -import java.util.ArrayList; - -import docking.dnd.*; - public class VTDualListingDragNDropHandler implements Draggable, Droppable { private final int SOURCE = 0; // left side @@ -52,7 +51,8 @@ public class VTDualListingDragNDropHandler implements Draggable, Droppable { private DropTgtAdapter dropTargetAdapter; private DataFlavor[] acceptableFlavors; // data flavors that are valid. - public VTDualListingDragNDropHandler(VTController controller, ListingCodeComparisonPanel dualListingPanel) { + public VTDualListingDragNDropHandler(VTController controller, + ListingCodeComparisonPanel dualListingPanel) { this.controller = controller; this.dualListingPanel = dualListingPanel; listingPanels[SOURCE] = dualListingPanel.getLeftPanel(); @@ -79,9 +79,8 @@ public class VTDualListingDragNDropHandler implements Draggable, Droppable { // set up the destination fieldPanel as a drop target that accepts mark-up items. dropTargetAdapter = new DropTgtAdapter(this, DnDConstants.ACTION_COPY_OR_MOVE, acceptableFlavors); - dropTarget = - new DropTarget(listingPanels[DESTINATION].getFieldPanel(), - DnDConstants.ACTION_COPY_OR_MOVE, dropTargetAdapter, true); + dropTarget = new DropTarget(listingPanels[DESTINATION].getFieldPanel(), + DnDConstants.ACTION_COPY_OR_MOVE, dropTargetAdapter, true); dropTarget.setActive(true); } @@ -106,9 +105,8 @@ public class VTDualListingDragNDropHandler implements Draggable, Droppable { } Point p = e.getDragOrigin(); ProgramLocation programLocation = listingPanels[SOURCE].getProgramLocation(p); - VTMarkupItem markupItem = - controller.getCurrentMarkupForLocation(programLocation, - dualListingPanel.getLeftProgram()); + VTMarkupItem markupItem = controller.getCurrentMarkupForLocation(programLocation, + dualListingPanel.getLeftProgram()); if (markupItem == null) { return false; } @@ -122,11 +120,6 @@ public class VTDualListingDragNDropHandler implements Draggable, Droppable { return status == VTMarkupItemDestinationAddressEditStatus.EDITABLE; } - @Override - public void dragCanceled(DragSourceDropEvent event) { - // nothing to do - } - @Override public Transferable getTransferable(Point p) { if (!listingPanels[SOURCE].contains(p)) { @@ -134,25 +127,14 @@ public class VTDualListingDragNDropHandler implements Draggable, Droppable { } ProgramLocation programLocation = listingPanels[SOURCE].getProgramLocation(p); - VTMarkupItem markupItem = - controller.getCurrentMarkupForLocation(programLocation, - dualListingPanel.getLeftProgram()); + VTMarkupItem markupItem = controller.getCurrentMarkupForLocation(programLocation, + dualListingPanel.getLeftProgram()); if (markupItem == null) { return null; } return new VTMarkupItemTransferable(markupItem); } - @Override - public void dragUnderFeedback(boolean ok, DropTargetDragEvent e) { - // nothing to do - } - - @Override - public void undoDragUnderFeedback() { - // nothing to do - } - @Override public boolean isDropOk(DropTargetDragEvent e) { return true; @@ -175,9 +157,9 @@ public class VTDualListingDragNDropHandler implements Draggable, Droppable { if ((markupItem.getStatus() == VTMarkupItemStatus.SAME) && (SystemUtilities.isEqual(markupItem.getDestinationAddress(), newDestinationAddress))) { // Dropped at expected address and already the same there. - Msg.showInfo(getClass(), dualListingPanel, "Already The Same", - markupType.getDisplayName() + - " was dropped at its expected\ndestination where the value is already the same."); + Msg.showInfo(getClass(), dualListingPanel, "Already The Same", markupType + .getDisplayName() + + " was dropped at its expected\ndestination where the value is already the same."); return; } @@ -190,15 +172,9 @@ public class VTDualListingDragNDropHandler implements Draggable, Droppable { // newDestinationAddress); // Use the following if you want to set the address and apply the markup item using the default action. - ApplyMarkupAtDestinationAddressTask task = - new ApplyMarkupAtDestinationAddressTask(controller.getSession(), arrayList, - newDestinationAddress, controller.getOptions()); + ApplyMarkupAtDestinationAddressTask task = new ApplyMarkupAtDestinationAddressTask( + controller.getSession(), arrayList, newDestinationAddress, controller.getOptions()); controller.runVTTask(task); } - - @Override - public void move() { - // nothing to do - } } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/dnd/DragGestureAdapter.java b/Ghidra/Framework/Docking/src/main/java/docking/dnd/DragGestureAdapter.java index c43f5ca7cd..fac524b03f 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/dnd/DragGestureAdapter.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/dnd/DragGestureAdapter.java @@ -15,87 +15,65 @@ */ package docking.dnd; -import ghidra.util.Msg; - import java.awt.datatransfer.Transferable; import java.awt.dnd.*; import java.awt.event.InputEvent; +import ghidra.util.Msg; + /** - * This class receives notification when the user intitiates a - * drag and drop operation; it is responsible for getting the - * Transferable and telling the DragSource to + * This class receives notification when the user initiates a drag and drop operation; it is + * responsible for getting the Transferable and telling the DragSource to * start the drag. */ public class DragGestureAdapter implements DragGestureListener { - - private Draggable dragComponent; -// private Cursor cursor = DragSource.DefaultCopyNoDrop; -// private static Transferable transferable; + + private Draggable dragComponent; /** * Construct a new DragGestureAdapter * * @param dragComponent Component that can support drag operations */ - public DragGestureAdapter(Draggable dragComponent) { - this.dragComponent = dragComponent; - } - - /** - * A DragGestureRecognizer has detected a - * platform-dependent Drag and Drop action initiating gesture - * and is notifying this Listener in order for it to initiate - * the action for the user. - *

The DragGestureRecognizer hides the platform-specific - * events that initate a drag and drop operation. - * - * @param e event describing the gesture that has just occurred - */ - public void dragGestureRecognized(DragGestureEvent e) { + public DragGestureAdapter(Draggable dragComponent) { + this.dragComponent = dragComponent; + } - // check input event: if any button other than MB1 is pressed, - // don't attempt to process the drag and drop event. - InputEvent ie = e.getTriggerEvent(); - int modifiers = ie.getModifiers(); - if ((modifiers & InputEvent.BUTTON2_MASK) != 0 || - (modifiers & InputEvent.BUTTON3_MASK) != 0) { - return; - } - int dragAction = dragComponent.getDragAction(); - - if ( ((e.getDragAction() & dragAction) == 0) || - !dragComponent.isStartDragOk(e)) { - return; - } - - Transferable t = dragComponent.getTransferable(e.getDragOrigin()); - - DragSourceListener l = dragComponent.getDragSourceListener(); - if (t == null || l == null) { - return; - } -// transferable = t; - try { - e.startDrag(DragSource.DefaultCopyNoDrop, t, l); - } catch (InvalidDnDOperationException exc) { - // the Drag and Drop system is unable to initiate a drag operation - Msg.error(this, "Exception occurred during drag initiation: " + exc, exc); + @Override + public void dragGestureRecognized(DragGestureEvent e) { + + // check input event: if any button other than MB1 is pressed, + // don't attempt to process the drag and drop event. + InputEvent ie = e.getTriggerEvent(); + int modifiers = ie.getModifiersEx(); + if ((modifiers & InputEvent.BUTTON2_DOWN_MASK) != 0 || + (modifiers & InputEvent.BUTTON3_DOWN_MASK) != 0) { + return; + } + + int dragAction = dragComponent.getDragAction(); + + if (((e.getDragAction() & dragAction) == 0) || !dragComponent.isStartDragOk(e)) { + return; + } + + DragSourceListener l = dragComponent.getDragSourceListener(); + if (l == null) { + return; + } + + Transferable t = dragComponent.getTransferable(e.getDragOrigin()); + if (t == null) { + return; + } + + try { + e.startDrag(DragSource.DefaultCopyNoDrop, t, l); + } + catch (InvalidDnDOperationException exc) { + // the Drag and Drop system is unable to initiate a drag operation + Msg.error(this, "Exception occurred during drag initiation: " + exc, exc); + } + } - // transferable = null; - } - } - -// /** -// * Get the transferable that is being dragged. -// */ -// static Transferable getTransferable() { -// return transferable; -// } -// /** -// * Clear the transferable object that is being dragged. -// */ -// static void clearTransferable() { -// transferable = null; -// } } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/dnd/DragSrcAdapter.java b/Ghidra/Framework/Docking/src/main/java/docking/dnd/DragSrcAdapter.java index adad655e23..c741fab892 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/dnd/DragSrcAdapter.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/dnd/DragSrcAdapter.java @@ -19,137 +19,109 @@ import java.awt.Cursor; import java.awt.dnd.*; /** - * Adapter class that receives notifications in order to - * provide drag over effects. - *

When the operation ends, this class receives a - * dragDropEnd message, and is responsible for - * checking the success of the operation. If the operation was - * successful, and if it was a Move, then - * this class will remove the source data. + * Adapter class that receives notifications in order to provide drag over effects. + * + *

When the operation ends, this class receives a dragDropEnd message, and is + * responsible for checking the success of the operation. If the operation was successful, and if it + * was a Move, then this class will remove the source data. */ public class DragSrcAdapter implements DragSourceListener { - protected Draggable dragComponent; - private Cursor currentCursor; - private Cursor copyDropCursor=DragSource.DefaultCopyDrop; - private Cursor copyNoDropCursor=DragSource.DefaultCopyNoDrop; - private Cursor moveDropCursor =DragSource.DefaultMoveDrop; - private Cursor moveNoDropCursor=DragSource.DefaultMoveNoDrop; - private Cursor linkDropCursor =DragSource.DefaultLinkDrop; - private Cursor linkNoDropCursor = DragSource.DefaultLinkNoDrop; + private static final Cursor COPY_DROP_CURSOR = DragSource.DefaultCopyDrop; + private static final Cursor COPY_NO_DROP_CURSOR = DragSource.DefaultCopyNoDrop; + private static final Cursor MOVE_DROP_CURSOR = DragSource.DefaultMoveDrop; + private static final Cursor MOVE_NO_DROP_CURSOR = DragSource.DefaultMoveNoDrop; + private static final Cursor LINK_DROP_CURSOR = DragSource.DefaultLinkDrop; + private static final Cursor LINK_NO_DROP_CURSOR = DragSource.DefaultLinkNoDrop; - /** - * Constructor - * @param dragComponent component that can be dragged. - */ - public DragSrcAdapter(Draggable dragComponent) { - this.dragComponent = dragComponent; - } - /** - * Called when the drag-drop operation completes. - * Calls the drag component's move() method if the action is a - * move operation. - */ - public void dragDropEnd(DragSourceDropEvent e) { + private Cursor currentCursor; + protected Draggable dragComponent; - if (!e.getDropSuccess()) { - dragComponent.dragCanceled(e); -// DragGestureAdapter.clearTransferable(); - return; - } - int dropOp = e.getDropAction(); - int dragAction = dragComponent.getDragAction(); + /** + * Constructor + * @param dragComponent component that can be dragged. + */ + public DragSrcAdapter(Draggable dragComponent) { + this.dragComponent = dragComponent; + } - if ((dropOp & DnDConstants.ACTION_MOVE) == DnDConstants.ACTION_MOVE && - (dragAction & DnDConstants.ACTION_MOVE) != 0) { - dragComponent.move(); -// DragGestureAdapter.clearTransferable(); - } - } - /** - * Called as the hotspot enters a platform dependent drop site. - */ - public void dragEnter(DragSourceDragEvent e) { + @Override + public void dragDropEnd(DragSourceDropEvent e) { + dragComponent.dragFinished(!e.getDropSuccess()); + } - setDragOverFeedback(e); - } - /** - * Called as the hotspot moves over a platform dependent drop site. - */ - public void dragOver(DragSourceDragEvent e) { + @Override + public void dragEnter(DragSourceDragEvent e) { + setDragOverFeedback(e); + } - setDragOverFeedback(e); - } + @Override + public void dragOver(DragSourceDragEvent e) { + setDragOverFeedback(e); + } - /** - * Called as the hotspot exits a platform dependent drop site. - */ - public void dragExit(DragSourceEvent e) { + @Override + public void dragExit(DragSourceEvent e) { - DragSourceContext context = e.getDragSourceContext(); - context.setCursor(null); // bug workaround - currentCursor = copyNoDropCursor; - context.setCursor(currentCursor); - } - /** - * Drop action changed, i.e., ctrl key pressed during drag to - * change to a copy operation. - */ - public void dropActionChanged(DragSourceDragEvent e) { - setDragOverFeedback(e); - } + DragSourceContext context = e.getDragSourceContext(); + context.setCursor(null); // bug workaround + currentCursor = COPY_NO_DROP_CURSOR; + context.setCursor(currentCursor); + } - ////////////////////////////////////////////////////////////////////// - // *** private methods *** - ////////////////////////////////////////////////////////////////////// + @Override + public void dropActionChanged(DragSourceDragEvent e) { + setDragOverFeedback(e); + } - /** - * Sets the cursor according to the actions that are legal. - */ - protected void setDragOverFeedback(DragSourceDragEvent e) { - DragSourceContext context = e.getDragSourceContext(); - int dropOp = e.getDropAction(); - int targetAction = e.getTargetActions(); - int action = dropOp & targetAction; - Cursor c = null; + /** + * Sets the cursor according to the actions that are legal. + * @param e the event + */ + protected void setDragOverFeedback(DragSourceDragEvent e) { + DragSourceContext context = e.getDragSourceContext(); + int dropOp = e.getDropAction(); + int targetAction = e.getTargetActions(); + int action = dropOp & targetAction; + Cursor c = null; - if (action == DnDConstants.ACTION_NONE) { - // drop not possible - if ((dropOp & DnDConstants.ACTION_LINK) == DnDConstants.ACTION_LINK) { - c = linkNoDropCursor; - } - else if ((dropOp & DnDConstants.ACTION_MOVE) == DnDConstants.ACTION_MOVE) { - c = moveNoDropCursor; - } - else { - c = copyNoDropCursor; - } - } - else { - // drop is possible - c = getDropOkCursor(action); - } - context.setCursor(null); // bug workaround... - currentCursor = c; - context.setCursor(c); - } - - /** - * Get the cursor for an "OK" drop. - * @param action action for the drag operation (copy, move, link) - * @return cursor that is appropriate for the give action - */ - protected Cursor getDropOkCursor(int action) { - Cursor c; - if ((action & DnDConstants.ACTION_LINK) == DnDConstants.ACTION_LINK) { - c = linkDropCursor; - } - else if ((action & DnDConstants.ACTION_MOVE) == DnDConstants.ACTION_MOVE) { - c = moveDropCursor; + if (action == DnDConstants.ACTION_NONE) { + // drop not possible + if ((dropOp & DnDConstants.ACTION_LINK) == DnDConstants.ACTION_LINK) { + c = LINK_NO_DROP_CURSOR; + } + else if ((dropOp & DnDConstants.ACTION_MOVE) == DnDConstants.ACTION_MOVE) { + c = MOVE_NO_DROP_CURSOR; + } + else { + c = COPY_NO_DROP_CURSOR; + } } else { - c = copyDropCursor; + // drop is possible + c = getDropOkCursor(action); + } + + context.setCursor(null); // bug workaround... + currentCursor = c; + context.setCursor(c); + } + + /** + * Get the cursor for an "OK" drop. + * @param action action for the drag operation (copy, move, link) + * @return cursor that is appropriate for the give action + */ + protected Cursor getDropOkCursor(int action) { + + if ((action & DnDConstants.ACTION_LINK) == DnDConstants.ACTION_LINK) { + return LINK_DROP_CURSOR; + } + else if ((action & DnDConstants.ACTION_MOVE) == DnDConstants.ACTION_MOVE) { + return MOVE_DROP_CURSOR; + } + else { + return COPY_DROP_CURSOR; } - return c; } } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/dnd/Draggable.java b/Ghidra/Framework/Docking/src/main/java/docking/dnd/Draggable.java index 8195bcf7f4..f41c83bb3d 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/dnd/Draggable.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/dnd/Draggable.java @@ -15,7 +15,7 @@ */ package docking.dnd; -import java.awt.Point; +import java.awt.*; import java.awt.datatransfer.Transferable; import java.awt.dnd.*; @@ -23,37 +23,30 @@ import java.awt.dnd.*; * Interface to define a drag source. */ public interface Draggable { - - /** - * Return true if the object at the location in the DragGesture - * event is draggable. + + /** + * Return true if the object at the location in the DragGesture event is draggable. * * @param e event passed to a DragGestureListener via its * dragGestureRecognized() method when a particular DragGestureRecognizer * detects a platform dependent Drag and Drop action initiating * gesture has occurred on the Component it is tracking. + * @return true if a drag can be starts * @see docking.dnd.DragGestureAdapter - */ - public boolean isStartDragOk(DragGestureEvent e); - - /** - * Called by the DragGestureAdapter to start the drag. - */ - public DragSourceListener getDragSourceListener(); - - /** - * Do the move operation; called when the drag and drop operation - * completes. - * @see docking.dnd.DragSrcAdapter#dragDropEnd - */ - public void move(); - - /** - * Method called when the drag operation exits the drop target - * without dropping. - * @param event TODO - */ - public void dragCanceled(DragSourceDropEvent event); + */ + public boolean isStartDragOk(DragGestureEvent e); + + /** + * Called when the drag and drop operation completes. + * + *

Clients can use this callback to reset visual state. + * @param cancelled true if the drag operation was cancelled + * + * @see docking.dnd.DragSrcAdapter#dragDropEnd(DragSourceDropEvent) + */ + public default void dragFinished(boolean cancelled) { + // stub + } /** * Get the drag actions supported by this drag source: @@ -65,12 +58,20 @@ public interface Draggable { * * @return the drag actions */ - public int getDragAction(); - - /** - * Get the object to transfer. + public int getDragAction(); + + /** + * Get the object to transfer. * @param p location of object to transfer * @return object to transfer - */ - public Transferable getTransferable(Point p); + */ + public Transferable getTransferable(Point p); + + /** + * Called by the DragGestureAdapter when the drag is started. + * @return the listener + * @see DragGestureEvent#startDrag(Cursor, Image, Point, Transferable, DragSourceListener) + */ + public DragSourceListener getDragSourceListener(); + } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/dnd/Droppable.java b/Ghidra/Framework/Docking/src/main/java/docking/dnd/Droppable.java index fc6e5d819e..4e30e9b538 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/dnd/Droppable.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/dnd/Droppable.java @@ -31,18 +31,6 @@ public interface Droppable { */ public boolean isDropOk(DropTargetDragEvent e); - /** - * Set drag feedback according to the ok parameter - * @param ok true means the drop action is OK - * @param e event that has current state of drag and drop operation - */ - public void dragUnderFeedback(boolean ok, DropTargetDragEvent e); - - /** - * Revert back to normal if any drag feedback was set - */ - public void undoDragUnderFeedback(); - /** * Add the object to the droppable component. The DropTargetAdapter * calls this method from its drop() method. @@ -54,4 +42,20 @@ public interface Droppable { */ public void add(Object obj, DropTargetDropEvent e, DataFlavor f); + /** + * Set drag feedback according to the ok parameter + * @param ok true means the drop action is OK + * @param e event that has current state of drag and drop operation + */ + public default void dragUnderFeedback(boolean ok, DropTargetDragEvent e) { + // stub + } + + /** + * Revert back to normal if any drag feedback was set + */ + public default void undoDragUnderFeedback() { + // stub + } + } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/filechooser/GhidraFileChooserPanel.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/filechooser/GhidraFileChooserPanel.java index 4e14d8647d..964fa0567f 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/filechooser/GhidraFileChooserPanel.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/filechooser/GhidraFileChooserPanel.java @@ -259,6 +259,20 @@ public class GhidraFileChooserPanel extends JPanel implements Droppable { return file; } + /** + * Sets the GhidraFileChooser to allow the user to just + * select files, just select + * directories, or select both files and directories. The default is + * GhidraFileChooserMode.FILES_ONLY. + * + * @param mode the type of files to be displayed + * @exception IllegalArgumentException if mode is an + * illegal Dialog mode + */ + public void setFileSelectionMode(GhidraFileChooserMode mode) { + this.selectionMode = mode; + } + private void setupDragAndDrop() { acceptableFlavors = new DataFlavor[] { DataFlavor.javaFileListFlavor, }; @@ -287,42 +301,8 @@ public class GhidraFileChooserPanel extends JPanel implements Droppable { } } - /** - * Sets the GhidraFileChooser to allow the user to just - * select files, just select - * directories, or select both files and directories. The default is - * GhidraFileChooserMode.FILES_ONLY. - * - * @param mode the type of files to be displayed - * @exception IllegalArgumentException if mode is an - * illegal Dialog mode - */ - public void setFileSelectionMode(GhidraFileChooserMode mode) { - this.selectionMode = mode; - } - - /** - * @see docking.dnd.Droppable#dragUnderFeedback(boolean, java.awt.dnd.DropTargetDragEvent) - */ - @Override - public void dragUnderFeedback(boolean ok, DropTargetDragEvent e) { - // don't care - } - - /** - * @see docking.dnd.Droppable#isDropOk(java.awt.dnd.DropTargetDragEvent) - */ @Override public boolean isDropOk(DropTargetDragEvent e) { return true; } - - /** - * @see docking.dnd.Droppable#undoDragUnderFeedback() - */ - @Override - public void undoDragUnderFeedback() { - // don't care - } - } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/app/util/FileOpenDropHandler.java b/Ghidra/Framework/Project/src/main/java/ghidra/app/util/FileOpenDropHandler.java index 58a98f3c16..e95cde904b 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/app/util/FileOpenDropHandler.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/app/util/FileOpenDropHandler.java @@ -97,16 +97,6 @@ public class FileOpenDropHandler implements DropTargetHandler, Droppable, Contai } } - @Override - public void dragUnderFeedback(boolean ok, DropTargetDragEvent e) { - // nothing to display or do - } - - @Override - public void undoDragUnderFeedback() { - // nothing to display or do - } - private void initializeComponents(Component comp) { if (comp instanceof CellRendererPane) { return; diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FrontEndPlugin.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FrontEndPlugin.java index 4618dccd6f..be780e9eb1 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FrontEndPlugin.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FrontEndPlugin.java @@ -85,7 +85,6 @@ public class FrontEndPlugin extends Plugin private ProjectToolBar toolBar; private ProjectDataTreePanel dataTreePanel; private ProjectDataTablePanel dataTablePanel; - private ToolButtonTransferable toolButtonTransferable; private WorkspacePanel workspacePanel; private Project activeProject; private ProjectManager projectManager; @@ -613,17 +612,6 @@ public class FrontEndPlugin extends Plugin return actionContext; } - ToolButtonTransferable getToolButtonTransferable() { - return toolButtonTransferable; - } - - void setToolButtonTransferable(ToolButtonTransferable t) { - if (t == null && toolButtonTransferable != null) { - toolButtonTransferable.clearTransferData(); - } - toolButtonTransferable = t; - } - void updateToolConnectionDialog() { toolActionManager.updateConnectionDialog(); } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ToolButton.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ToolButton.java index f9836554c4..554198aa82 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ToolButton.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ToolButton.java @@ -151,11 +151,6 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable { // Droppable interface //================================================================================================== - @Override - public void dragUnderFeedback(boolean ok, DropTargetDragEvent e) { - // nothing to do - } - @Override public boolean isDropOk(DropTargetDragEvent e) { DataFlavor[] flavors = e.getCurrentDataFlavors(); @@ -219,11 +214,6 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable { return fileList.size() > 0; } - @Override - public void undoDragUnderFeedback() { - // nothing to do - } - @Override public void add(Object obj, DropTargetDropEvent event, DataFlavor f) { @@ -255,8 +245,8 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable { } } } + // else assume ToolButtonTransferable else { - plugin.setToolButtonTransferable(null); ToolButton toolButton = (ToolButton) obj; resetButtonAfterDrag(toolButton); addFromToolButton(toolButton); @@ -264,7 +254,6 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable { } private void addFromToolButton(ToolButton toolButton) { - plugin.setToolButtonTransferable(null); PluginTool tool = null; if (associatedRunningTool != null && toolButton.associatedRunningTool != null) { final PluginTool t2 = toolButton.associatedRunningTool; @@ -353,51 +342,13 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable { clearBorder(); } - /** - * Method called when the drag operation exits the drop target - * without dropping. - */ @Override - public void dragCanceled(DragSourceDropEvent event) { - plugin.setToolButtonTransferable(null); + public void dragFinished(boolean wasCancelled) { resetButtonAfterDrag(this); - - // Unusual Code Alert! - // When dragging, we do not get mouseReleased() events, which we use to launch tools. - // In this case, the drag was cancelled; if we are over ourselves, then simulate - // the Java-eaten mouseReleased() call - Container parent = getParent(); - if (parent == null) { - return; - } - - Point point = event.getLocation(); - if (point == null) { - return; - } - SwingUtilities.convertPointFromScreen(point, parent); - Component componentUnderMouse = - SwingUtilities.getDeepestComponentAt(parent, point.x, point.y); - - if (componentUnderMouse == this) { - handleMouseReleased(); - } - } - /** - * Return true if the object at the location in the DragGesture - * event is draggable. - * - * @param e event passed to a DragGestureListener via its - * dragGestureRecognized() method when a particular DragGestureRecognizer - * detects a platform dependent Drag and Drop action initiating - * gesture has occurred on the Component it is tracking. - * @see docking.dnd.DragGestureAdapter - */ @Override public boolean isStartDragOk(DragGestureEvent e) { - plugin.setToolButtonTransferable(new ToolButtonTransferable(this)); return true; } @@ -408,12 +359,7 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable { @Override public Transferable getTransferable(Point p) { - return plugin.getToolButtonTransferable(); - } - - @Override - public void move() { - resetButtonAfterDrag(this); + return new ToolButtonTransferable(this); } @Override @@ -610,10 +556,6 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable { help.registerHelp(this, new HelpLocation(ToolConstants.TOOL_HELP_TOPIC, anchorTag)); } - private void handleMouseReleased() { - activateTool(); - } - //================================================================================================== // Inner Classes //================================================================================================== diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ToolButtonTransferable.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ToolButtonTransferable.java index 8833917078..70e4646a82 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ToolButtonTransferable.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ToolButtonTransferable.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,92 +15,79 @@ */ package ghidra.framework.main; -import ghidra.util.Msg; - import java.awt.datatransfer.*; import java.io.IOException; -import java.util.Arrays; -import java.util.List; import docking.dnd.GenericDataFlavor; +import ghidra.util.Msg; /** * Defines data that is available for drag/drop and clipboard transfers. * The data is a ToolButton object. */ public class ToolButtonTransferable implements Transferable, ClipboardOwner { - - public static DataFlavor localToolButtonFlavor = createLocalToolButtonFlavor(); - - // create a data flavor that is a tool button - private static DataFlavor createLocalToolButtonFlavor() { - try { - return new GenericDataFlavor( - DataFlavor.javaJVMLocalObjectMimeType+ - "; class=ghidra.framework.main.ToolButton", - "Local tool button object"); - }catch (Exception e) { - Msg.showError(ToolButtonTransferable.class, null, null, null, e); - } - return null; - } - private static DataFlavor []flavors= - {localToolButtonFlavor}; - - private static List flavorList = Arrays.asList(flavors); - private ToolButton button; - - /** - * Constructor - */ - ToolButtonTransferable(ToolButton button) { - this.button = button; - } - - /** - * Return all data flavors that this class supports. - */ - public synchronized DataFlavor []getTransferDataFlavors() { - return flavors; - } - - /** - * Return whether the specifed data flavor is supported. - */ - public boolean isDataFlavorSupported(DataFlavor f) { - return flavorList.contains(f); - } - - /** - * Return the transfer data with the given data flavor. - */ - public synchronized Object getTransferData(DataFlavor f) - throws UnsupportedFlavorException, IOException { - - if (f.equals(localToolButtonFlavor)) { - return button; - } - throw new UnsupportedFlavorException(f); - - } - /** - * Get the string representation for this transferable. - */ - @Override - public String toString() { - return "ToolButtonTransferable"; - } - - /** - * ClipboardOwner interface method. - */ - public void lostOwnership(Clipboard clipboard, Transferable contents) { - } - /** - * Clear the tool button that is being transferred. - */ - void clearTransferData() { - button = null; - } + public static DataFlavor localToolButtonFlavor = createLocalToolButtonFlavor(); + + // create a data flavor that is a tool button + private static DataFlavor createLocalToolButtonFlavor() { + try { + return new GenericDataFlavor( + DataFlavor.javaJVMLocalObjectMimeType + "; class=ghidra.framework.main.ToolButton", + "Local tool button object"); + } + catch (Exception e) { + Msg.showError(ToolButtonTransferable.class, null, null, null, e); + } + return null; + } + + private static DataFlavor[] flavors = { localToolButtonFlavor }; + private ToolButton button; + + /** + * Constructor + * @param button the button + */ + ToolButtonTransferable(ToolButton button) { + this.button = button; + } + + @Override + public synchronized DataFlavor[] getTransferDataFlavors() { + return flavors; + } + + @Override + public boolean isDataFlavorSupported(DataFlavor f) { + return localToolButtonFlavor.equals(f); + } + + @Override + public synchronized Object getTransferData(DataFlavor f) + throws UnsupportedFlavorException, IOException { + + if (f.equals(localToolButtonFlavor)) { + return button; + } + throw new UnsupportedFlavorException(f); + + } + + @Override + public String toString() { + return "ToolButtonTransferable"; + } + + @Override + public void lostOwnership(Clipboard clipboard, Transferable contents) { + // stub + } + + /** + * Clear the tool button that is being transferred. + */ + void clearTransferData() { + button = null; + } } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/VersionHistoryPanel.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/VersionHistoryPanel.java index bf247ded2a..67c38e809c 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/VersionHistoryPanel.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/VersionHistoryPanel.java @@ -175,11 +175,6 @@ public class VersionHistoryPanel extends JPanel implements Draggable { return DomainFile.DEFAULT_VERSION; } - @Override - public void dragCanceled(DragSourceDropEvent event) { - // no-op - } - @Override public int getDragAction() { return dragAction; @@ -209,11 +204,6 @@ public class VersionHistoryPanel extends JPanel implements Draggable { return false; } - @Override - public void move() { - // no-op - } - // For Junit tests VersionHistoryTableModel getVersionHistoryTableModel() { return tableModel;