View | Details | Raw Unified | Return to bug 54834
Collapse All | Expand All

(-)xdocs/changes.xml (+1 lines)
Lines 179-184 Link Here
179
<li><bugzilla>54669</bugzilla> - Add flag forcing non-GUI JVM to exit after test</li>
179
<li><bugzilla>54669</bugzilla> - Add flag forcing non-GUI JVM to exit after test</li>
180
<li><bugzilla>42428</bugzilla> - Workbench not saved with Test Plan</li>
180
<li><bugzilla>42428</bugzilla> - Workbench not saved with Test Plan</li>
181
<li><bugzilla>54825</bugzilla> - Add shortcuts to move elements in the tree</li>
181
<li><bugzilla>54825</bugzilla> - Add shortcuts to move elements in the tree</li>
182
<li><bugzilla>54834</bugzilla> - Improve Drag & Drop in the jmeter tree</li>
182
</ul>
183
</ul>
183
184
184
<h2>Non-functional changes</h2>
185
<h2>Non-functional changes</h2>
(-)src/core/org/apache/jmeter/gui/MainFrame.java (-16 / +28 lines)
Lines 49-54 Link Here
49
import javax.swing.BorderFactory;
49
import javax.swing.BorderFactory;
50
import javax.swing.Box;
50
import javax.swing.Box;
51
import javax.swing.BoxLayout;
51
import javax.swing.BoxLayout;
52
import javax.swing.DropMode;
52
import javax.swing.ImageIcon;
53
import javax.swing.ImageIcon;
53
import javax.swing.JButton;
54
import javax.swing.JButton;
54
import javax.swing.JComponent;
55
import javax.swing.JComponent;
Lines 74-79 Link Here
74
import org.apache.jmeter.gui.action.LoadDraggedFile;
75
import org.apache.jmeter.gui.action.LoadDraggedFile;
75
import org.apache.jmeter.gui.tree.JMeterCellRenderer;
76
import org.apache.jmeter.gui.tree.JMeterCellRenderer;
76
import org.apache.jmeter.gui.tree.JMeterTreeListener;
77
import org.apache.jmeter.gui.tree.JMeterTreeListener;
78
import org.apache.jmeter.gui.tree.JMeterTreeTransferHandler;
77
import org.apache.jmeter.gui.util.EscapeDialog;
79
import org.apache.jmeter.gui.util.EscapeDialog;
78
import org.apache.jmeter.gui.util.JMeterMenuBar;
80
import org.apache.jmeter.gui.util.JMeterMenuBar;
79
import org.apache.jmeter.gui.util.JMeterToolBar;
81
import org.apache.jmeter.gui.util.JMeterToolBar;
Lines 619-625 Link Here
619
                return null;
621
                return null;
620
                }
622
                }
621
            };
623
            };
622
           treevar.setToolTipText("");
624
        treevar.setToolTipText("");
623
        treevar.setCellRenderer(getCellRenderer());
625
        treevar.setCellRenderer(getCellRenderer());
624
        treevar.setRootVisible(false);
626
        treevar.setRootVisible(false);
625
        treevar.setShowsRootHandles(true);
627
        treevar.setShowsRootHandles(true);
Lines 627-634 Link Here
627
        treeListener.setJTree(treevar);
629
        treeListener.setJTree(treevar);
628
        treevar.addTreeSelectionListener(treeListener);
630
        treevar.addTreeSelectionListener(treeListener);
629
        treevar.addMouseListener(treeListener);
631
        treevar.addMouseListener(treeListener);
630
        treevar.addMouseMotionListener(treeListener);
631
        treevar.addKeyListener(treeListener);
632
        treevar.addKeyListener(treeListener);
633
        
634
        // enable drag&drop, install a custom transfer handler
635
        treevar.setDragEnabled(true);
636
        treevar.setDropMode(DropMode.ON_OR_INSERT);
637
        treevar.setTransferHandler(new JMeterTreeTransferHandler());
632
638
633
        return treevar;
639
        return treevar;
634
    }
640
    }
Lines 710-729 Link Here
710
                if (flavors[i].isFlavorJavaFileListType()) {
716
                if (flavors[i].isFlavorJavaFileListType()) {
711
                    dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
717
                    dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
712
                    try {
718
                    try {
713
                        @SuppressWarnings("unchecked")
719
                        openJmxFilesFromDragAndDrop(tr);
714
                        List<File> files = (List<File>)
715
                                tr.getTransferData(DataFlavor.javaFileListFlavor);
716
                        if(files.isEmpty()) {
717
                            return;
718
                        }
719
                        File file = files.get(0);
720
                        if(!file.getName().endsWith(".jmx")) {
721
                            log.warn("Importing file:" + file.getName()+ "from DnD failed because file extension does not end with .jmx");
722
                            return;
723
                        }
724
725
                        ActionEvent fakeEvent = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, ActionNames.OPEN);
726
                        LoadDraggedFile.loadProject(fakeEvent, file);
727
                    } finally {
720
                    } finally {
728
                        dtde.dropComplete(true);
721
                        dtde.dropComplete(true);
729
                    }
722
                    }
Lines 738-743 Link Here
738
731
739
    }
732
    }
740
733
734
    public boolean openJmxFilesFromDragAndDrop(Transferable tr) throws UnsupportedFlavorException, IOException {
735
        @SuppressWarnings("unchecked")
736
        List<File> files = (List<File>)
737
                tr.getTransferData(DataFlavor.javaFileListFlavor);
738
        if(files.isEmpty()) {
739
            return false;
740
        }
741
        File file = files.get(0);
742
        if(!file.getName().endsWith(".jmx")) {
743
            log.warn("Importing file:" + file.getName()+ "from DnD failed because file extension does not end with .jmx");
744
            return false;
745
        }
746
747
        ActionEvent fakeEvent = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, ActionNames.OPEN);
748
        LoadDraggedFile.loadProject(fakeEvent, file);
749
        
750
        return true;
751
    }
752
741
    @Override
753
    @Override
742
    public void dropActionChanged(DropTargetDragEvent dtde) {
754
    public void dropActionChanged(DropTargetDragEvent dtde) {
743
        // NOOP
755
        // NOOP
(-)src/core/org/apache/jmeter/gui/tree/JMeterTreeTransferHandler.java (+239 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *   http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 */
18
19
package org.apache.jmeter.gui.tree;
20
21
import java.awt.datatransfer.DataFlavor;
22
import java.awt.datatransfer.Transferable;
23
import java.awt.datatransfer.UnsupportedFlavorException;
24
25
import javax.swing.JComponent;
26
import javax.swing.JTree;
27
import javax.swing.TransferHandler;
28
import javax.swing.tree.TreePath;
29
30
import org.apache.jmeter.gui.GuiPackage;
31
import org.apache.jmeter.gui.util.MenuFactory;
32
import org.apache.jorphan.logging.LoggingManager;
33
import org.apache.log.Logger;
34
35
public class JMeterTreeTransferHandler extends TransferHandler {
36
    
37
    private static final long serialVersionUID = 8560957372186260765L;
38
39
    private static final Logger LOG = LoggingManager.getLoggerForClass();
40
  
41
    private DataFlavor nodeFlavor;
42
    private DataFlavor[] jMeterTreeNodeDataFlavors = new DataFlavor[1];
43
44
    public JMeterTreeTransferHandler() {
45
        try {
46
            String mimeType = DataFlavor.javaJVMLocalObjectMimeType + ";class=\"" + JMeterTreeNode[].class.getName() + "\"";
47
            nodeFlavor = new DataFlavor(mimeType);
48
            jMeterTreeNodeDataFlavors[0] = nodeFlavor;
49
        }
50
        catch (ClassNotFoundException e) {
51
            LOG.error("Class Not Found", e);
52
        }
53
    }
54
55
    
56
    @Override
57
    public int getSourceActions(JComponent c) {
58
        return MOVE;
59
    }
60
    
61
62
    @Override
63
    protected Transferable createTransferable(JComponent c) {
64
        JTree tree = (JTree) c;
65
        TreePath[] paths = tree.getSelectionPaths();
66
        if (paths != null) {
67
           
68
            //TODO : deal with all the selected nodes
69
            JMeterTreeNode node = (JMeterTreeNode) paths[0].getLastPathComponent();
70
            
71
            return new NodesTransferable(new JMeterTreeNode[] {node});
72
        }
73
        
74
        return null;
75
    }
76
   
77
    @Override
78
    protected void exportDone(JComponent source, Transferable data, int action) {
79
    }
80
81
    @Override
82
    public boolean canImport(TransferHandler.TransferSupport support) {
83
        if (!support.isDrop()) {
84
            return false;
85
        }
86
        
87
        // the tree accepts a jmx file 
88
        DataFlavor[] flavors = support.getDataFlavors();
89
        for (int i = 0; i < flavors.length; i++) {
90
            // Check for file lists specifically
91
            if (flavors[i].isFlavorJavaFileListType()) {
92
                return true;
93
            }
94
        }
95
96
        // or a treenode from the same tree
97
        if (!support.isDataFlavorSupported(nodeFlavor)) {
98
            return false;
99
        }
100
        
101
        // the copy is disabled
102
        int action = support.getDropAction();
103
        if(action != MOVE) {
104
            return false;
105
        }
106
        
107
        support.setShowDropLocation(true);
108
109
        // Do not allow a drop on the drag source selections.
110
        JTree.DropLocation dl = (JTree.DropLocation) support.getDropLocation();
111
        JTree tree = (JTree) support.getComponent();
112
        int dropRow = tree.getRowForPath(dl.getPath());
113
        int[] selRows = tree.getSelectionRows();
114
        for (int i = 0; i < selRows.length; i++) {
115
            if (selRows[i] == dropRow) {
116
                return false;
117
            }
118
        }
119
        
120
        TreePath dest = dl.getPath();
121
        JMeterTreeNode target = (JMeterTreeNode) dest.getLastPathComponent();
122
        
123
        // TestPlan and WorkBench are the only children of the root
124
        if(target.isRoot()) {
125
            return false;
126
        }
127
        
128
        TreePath path = tree.getPathForRow(selRows[0]);
129
        JMeterTreeNode draggedNode = (JMeterTreeNode) path.getLastPathComponent();
130
        
131
        // Do not allow a non-leaf node to be moved into one of its children
132
        if (draggedNode.getChildCount() > 0
133
                && target.isNodeAncestor(draggedNode)) {
134
            return false;
135
        }
136
        
137
        // re-use node association logic
138
        return MenuFactory.canAddTo(target, new JMeterTreeNode[] { draggedNode });
139
    }
140
141
142
    @Override
143
    public boolean importData(TransferHandler.TransferSupport support) {
144
        if (!canImport(support)) {
145
            return false;
146
        }
147
        
148
        // deal with the jmx files
149
        GuiPackage guiInstance = GuiPackage.getInstance();
150
        DataFlavor[] flavors = support.getDataFlavors();
151
        Transferable t = support.getTransferable();
152
        for (int i = 0; i < flavors.length; i++) {
153
            // Check for file lists specifically
154
            if (flavors[i].isFlavorJavaFileListType()) {
155
                try {
156
                    return guiInstance.getMainFrame().openJmxFilesFromDragAndDrop(t);
157
                }
158
                catch (Exception e) {
159
                    LOG.error("Drop file failed", e);
160
                }
161
                return false;
162
            }
163
        }
164
        
165
        // Extract transfer data.
166
        JMeterTreeNode[] nodes = null;
167
        try {
168
            nodes = (JMeterTreeNode[]) t.getTransferData(nodeFlavor);
169
        }
170
        catch (Exception e) {
171
            LOG.error("Unsupported Flavor in Transferable", e);
172
        }
173
174
        if(nodes == null || nodes.length == 0) {
175
            return false;
176
        }
177
        
178
        // Get drop location and mode
179
        JTree.DropLocation dl = (JTree.DropLocation) support.getDropLocation();
180
        TreePath dest = dl.getPath();
181
        JMeterTreeNode parent = (JMeterTreeNode) dest.getLastPathComponent();
182
       
183
        //TODO : deal with all the selected nodes
184
        JMeterTreeNode draggedNode = nodes[0];
185
        
186
        
187
        int index = dl.getChildIndex();
188
        if (index == -1) { // drop mode is ON
189
            // can not drop in the current parent
190
            if(draggedNode.getParent() == parent) {
191
                return false;
192
            }
193
            index = parent.getChildCount();
194
        }
195
        else if(draggedNode.getParent() == parent) { // insert mode
196
            if(guiInstance.getTreeModel().getIndexOfChild(parent, draggedNode) < index) {
197
                index--;
198
            }
199
        }
200
        
201
        // remove - add the nodes
202
        for (int i = 0; i < nodes.length; i++) {
203
            guiInstance.getTreeModel().removeNodeFromParent(nodes[i]);
204
            guiInstance.getTreeModel().insertNodeInto(nodes[i], parent, index);
205
        }
206
        
207
        // expand the destination node
208
        JTree tree = (JTree) support.getComponent();
209
        tree.expandPath(new TreePath(parent.getPath()));
210
        
211
        return true;
212
    }
213
214
    private class NodesTransferable implements Transferable {
215
        JMeterTreeNode[] nodes;
216
217
        public NodesTransferable(JMeterTreeNode[] nodes) {
218
            this.nodes = nodes;
219
        }
220
221
        @Override
222
        public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
223
            if (!isDataFlavorSupported(flavor)) {
224
                throw new UnsupportedFlavorException(flavor);
225
            }
226
            return nodes;
227
        }
228
229
        @Override
230
        public DataFlavor[] getTransferDataFlavors() {
231
            return jMeterTreeNodeDataFlavors;
232
        }
233
234
        @Override
235
        public boolean isDataFlavorSupported(DataFlavor flavor) {
236
            return nodeFlavor.equals(flavor);
237
        }
238
    }
239
}
(-)src/core/org/apache/jmeter/gui/tree/JMeterTreeListener.java (-112 / +2 lines)
Lines 26-55 Link Here
26
import java.awt.event.KeyListener;
26
import java.awt.event.KeyListener;
27
import java.awt.event.MouseEvent;
27
import java.awt.event.MouseEvent;
28
import java.awt.event.MouseListener;
28
import java.awt.event.MouseListener;
29
import java.awt.event.MouseMotionListener;
30
29
31
import javax.swing.JLabel;
32
import javax.swing.JMenuItem;
33
import javax.swing.JPopupMenu;
30
import javax.swing.JPopupMenu;
34
import javax.swing.JTree;
31
import javax.swing.JTree;
35
import javax.swing.event.TreeSelectionEvent;
32
import javax.swing.event.TreeSelectionEvent;
36
import javax.swing.event.TreeSelectionListener;
33
import javax.swing.event.TreeSelectionListener;
37
import javax.swing.tree.TreeNode;
38
import javax.swing.tree.TreePath;
34
import javax.swing.tree.TreePath;
39
35
40
import org.apache.jmeter.control.gui.TestPlanGui;
41
import org.apache.jmeter.control.gui.WorkBenchGui;
42
import org.apache.jmeter.gui.GuiPackage;
36
import org.apache.jmeter.gui.GuiPackage;
43
import org.apache.jmeter.gui.MainFrame;
37
import org.apache.jmeter.gui.MainFrame;
44
import org.apache.jmeter.gui.action.ActionNames;
38
import org.apache.jmeter.gui.action.ActionNames;
45
import org.apache.jmeter.gui.action.ActionRouter;
39
import org.apache.jmeter.gui.action.ActionRouter;
46
import org.apache.jmeter.gui.action.KeyStrokes;
40
import org.apache.jmeter.gui.action.KeyStrokes;
47
import org.apache.jmeter.gui.util.MenuFactory;
48
import org.apache.jmeter.util.JMeterUtils;
49
import org.apache.jorphan.logging.LoggingManager;
41
import org.apache.jorphan.logging.LoggingManager;
50
import org.apache.log.Logger;
42
import org.apache.log.Logger;
51
43
52
public class JMeterTreeListener implements TreeSelectionListener, MouseListener, KeyListener, MouseMotionListener {
44
public class JMeterTreeListener implements TreeSelectionListener, MouseListener, KeyListener {
53
    private static final Logger log = LoggingManager.getLoggerForClass();
45
    private static final Logger log = LoggingManager.getLoggerForClass();
54
46
55
    // Container endWindow;
47
    // Container endWindow;
Lines 62-85 Link Here
62
54
63
    private JTree tree;
55
    private JTree tree;
64
56
65
    private boolean dragging = false;
66
67
    private JMeterTreeNode[] draggedNodes;
68
69
    private final JLabel dragIcon = new JLabel(JMeterUtils.getImage("leafnode.gif")); // $NON-NLS-1$
70
71
    /**
57
    /**
72
     * Constructor for the JMeterTreeListener object.
58
     * Constructor for the JMeterTreeListener object.
73
     */
59
     */
74
    public JMeterTreeListener(JMeterTreeModel model) {
60
    public JMeterTreeListener(JMeterTreeModel model) {
75
        this.model = model;
61
        this.model = model;
76
        dragIcon.validate();
77
        dragIcon.setVisible(true);
78
    }
62
    }
79
63
80
    public JMeterTreeListener() {
64
    public JMeterTreeListener() {
81
        dragIcon.validate();
82
        dragIcon.setVisible(true);
83
    }
65
    }
84
66
85
    public void setModel(JMeterTreeModel m) {
67
    public void setModel(JMeterTreeModel m) {
Lines 171-247 Link Here
171
153
172
    @Override
154
    @Override
173
    public void mouseReleased(MouseEvent e) {
155
    public void mouseReleased(MouseEvent e) {
174
        if (dragging && isValidDragAction(draggedNodes, getCurrentNode())) {
156
        GuiPackage.getInstance().getMainFrame().repaint();
175
            dragging = false;
176
            JPopupMenu dragNdrop = new JPopupMenu();
177
            JMenuItem item = new JMenuItem(JMeterUtils.getResString("insert_before")); // $NON-NLS-1$
178
            item.addActionListener(actionHandler);
179
            item.setActionCommand(ActionNames.INSERT_BEFORE);
180
            dragNdrop.add(item);
181
            item = new JMenuItem(JMeterUtils.getResString("insert_after")); // $NON-NLS-1$
182
            item.addActionListener(actionHandler);
183
            item.setActionCommand(ActionNames.INSERT_AFTER);
184
            dragNdrop.add(item);
185
            if (MenuFactory.canAddTo(getCurrentNode(), draggedNodes)){
186
                item = new JMenuItem(JMeterUtils.getResString("add_as_child")); // $NON-NLS-1$
187
                item.addActionListener(actionHandler);
188
                item.setActionCommand(ActionNames.DRAG_ADD);
189
                dragNdrop.add(item);
190
            }
191
            dragNdrop.addSeparator();
192
            item = new JMenuItem(JMeterUtils.getResString("cancel")); // $NON-NLS-1$
193
            dragNdrop.add(item);
194
            displayPopUp(e, dragNdrop);
195
        } else {
196
            GuiPackage.getInstance().getMainFrame().repaint();
197
        }
198
        dragging = false;
199
    }
200
201
    public JMeterTreeNode[] getDraggedNodes() {
202
        return draggedNodes;
203
    }
204
205
    /**
206
     * Tests if the node is being dragged into one of it's own sub-nodes, or
207
     * into itself.
208
     */
209
    private boolean isValidDragAction(JMeterTreeNode[] source, JMeterTreeNode dest) {
210
        boolean isValid = true;
211
        TreeNode[] path = dest.getPath();
212
        for (int i = 0; i < path.length; i++) {
213
            if (contains(source, path[i])) {
214
                isValid = false;
215
            }
216
        }
217
        return isValid;
218
    }
157
    }
219
158
220
    @Override
159
    @Override
221
    public void mouseEntered(MouseEvent e) {
160
    public void mouseEntered(MouseEvent e) {
222
    }
161
    }
223
162
224
    private void changeSelectionIfDragging(MouseEvent e) {
225
        if (dragging) {
226
            GuiPackage.getInstance().getMainFrame().drawDraggedComponent(dragIcon, e.getX(), e.getY());
227
            if (tree.getPathForLocation(e.getX(), e.getY()) != null) {
228
                currentPath = tree.getPathForLocation(e.getX(), e.getY());
229
                if (!contains(draggedNodes, getCurrentNode())) {
230
                    tree.setSelectionPath(currentPath);
231
                }
232
            }
233
        }
234
    }
235
236
    private boolean contains(Object[] container, Object item) {
237
        for (int i = 0; i < container.length; i++) {
238
            if (container[i] == item) {
239
                return true;
240
            }
241
        }
242
        return false;
243
    }
244
245
    @Override
163
    @Override
246
    public void mousePressed(MouseEvent e) {
164
    public void mousePressed(MouseEvent e) {
247
        // Get the Main Frame.
165
        // Get the Main Frame.
Lines 266-288 Link Here
266
        }
184
        }
267
    }
185
    }
268
186
269
    @Override
270
    public void mouseDragged(MouseEvent e) {
271
        if (!dragging) {
272
            dragging = true;
273
            draggedNodes = getSelectedNodes();
274
            if (draggedNodes[0].getUserObject() instanceof TestPlanGui
275
                    || draggedNodes[0].getUserObject() instanceof WorkBenchGui) {
276
                dragging = false;
277
            }
278
279
        }
280
        changeSelectionIfDragging(e);
281
    }
282
283
    @Override
284
    public void mouseMoved(MouseEvent e) {
285
    }
286
187
287
    @Override
188
    @Override
288
    public void mouseExited(MouseEvent ev) {
189
    public void mouseExited(MouseEvent ev) {
Lines 341-355 Link Here
341
        JPopupMenu pop = getCurrentNode().createPopupMenu();
242
        JPopupMenu pop = getCurrentNode().createPopupMenu();
342
        GuiPackage.getInstance().displayPopUp(e, pop);
243
        GuiPackage.getInstance().displayPopUp(e, pop);
343
    }
244
    }
344
345
    private void displayPopUp(MouseEvent e, JPopupMenu popup) {
346
        // See Bug 46108 - this log message is unnecessary and misleading
347
        // log.warn("Shouldn't be here");
348
        if (popup != null) {
349
            popup.pack();
350
            popup.show(tree, e.getX(), e.getY());
351
            popup.setVisible(true);
352
            popup.requestFocus();
353
        }
354
    }
355
}
245
}
(-)src/core/org/apache/jmeter/gui/action/ActionNames.java (-3 lines)
Lines 48-54 Link Here
48
    public static final String DEBUG_ON         = "debug_on"; // $NON-NLS-1$
48
    public static final String DEBUG_ON         = "debug_on"; // $NON-NLS-1$
49
    public static final String DEBUG_OFF        = "debug_off"; // $NON-NLS-1$
49
    public static final String DEBUG_OFF        = "debug_off"; // $NON-NLS-1$
50
    public static final String DISABLE          = "disable"; // $NON-NLS-1$
50
    public static final String DISABLE          = "disable"; // $NON-NLS-1$
51
    public static final String DRAG_ADD         = "drag_n_drop.add";//$NON-NLS-1$
52
    /** Copy, then paste afterwards */
51
    /** Copy, then paste afterwards */
53
    public static final String DUPLICATE        = "duplicate"; // $NON-NLS-1$
52
    public static final String DUPLICATE        = "duplicate"; // $NON-NLS-1$
54
    public static final String EDIT             = "edit"; // $NON-NLS-1$
53
    public static final String EDIT             = "edit"; // $NON-NLS-1$
Lines 58-65 Link Here
58
    public static final String FUNCTIONS        = "functions"; // $NON-NLS-1$
57
    public static final String FUNCTIONS        = "functions"; // $NON-NLS-1$
59
    public static final String HELP             = "help"; // $NON-NLS-1$
58
    public static final String HELP             = "help"; // $NON-NLS-1$
60
    public static final String HEAP_DUMP        = "heap_dump"; // $NON-NLS-1$
59
    public static final String HEAP_DUMP        = "heap_dump"; // $NON-NLS-1$
61
    public static final String INSERT_AFTER     = "drag_n_drop.insert_after";//$NON-NLS-1$
62
    public static final String INSERT_BEFORE    = "drag_n_drop.insert_before";//$NON-NLS-1$
63
    public static final String LAF_PREFIX       = "laf:"; // Look and Feel prefix
60
    public static final String LAF_PREFIX       = "laf:"; // Look and Feel prefix
64
    public static final String LOGGER_PANEL_ENABLE_DISABLE     = "logger_panel_enable_disable"; // $NON-NLS-1$
61
    public static final String LOGGER_PANEL_ENABLE_DISABLE     = "logger_panel_enable_disable"; // $NON-NLS-1$
65
    public static final String MERGE            = "merge"; // $NON-NLS-1$
62
    public static final String MERGE            = "merge"; // $NON-NLS-1$
(-)src/core/org/apache/jmeter/gui/action/DragNDrop.java (-104 lines)
Lines 1-104 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *   http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 */
18
19
package org.apache.jmeter.gui.action;
20
21
import java.awt.Toolkit;
22
import java.awt.event.ActionEvent;
23
import java.util.HashSet;
24
import java.util.Set;
25
26
import org.apache.jmeter.gui.GuiPackage;
27
import org.apache.jmeter.gui.tree.JMeterTreeListener;
28
import org.apache.jmeter.gui.tree.JMeterTreeNode;
29
import org.apache.jmeter.gui.util.MenuFactory;
30
import org.apache.jmeter.testelement.TestElement;
31
import org.apache.jmeter.testelement.TestPlan;
32
import org.apache.jmeter.testelement.WorkBench;
33
34
public class DragNDrop extends AbstractAction {
35
    private static final Set<String> commands = new HashSet<String>();
36
37
    static {
38
        commands.add(ActionNames.DRAG_ADD);
39
        commands.add(ActionNames.INSERT_BEFORE);
40
        commands.add(ActionNames.INSERT_AFTER);
41
    }
42
43
    /**
44
     * @see Command#doAction(ActionEvent)
45
     */
46
    @Override
47
    public void doAction(ActionEvent e) {
48
        String action = e.getActionCommand();
49
        GuiPackage guiPackage = GuiPackage.getInstance();
50
        JMeterTreeNode[] draggedNodes = guiPackage.getTreeListener().getDraggedNodes();
51
        JMeterTreeListener treeListener = guiPackage.getTreeListener();
52
        JMeterTreeNode currentNode = treeListener.getCurrentNode();
53
        JMeterTreeNode parentNode = (JMeterTreeNode) currentNode.getParent();
54
        TestElement te = currentNode.getTestElement();
55
        if (te instanceof TestPlan || te instanceof WorkBench) {
56
            parentNode = null; // So elements can only be added as children
57
        }
58
59
        if (ActionNames.DRAG_ADD.equals(action) && canAddTo(currentNode,draggedNodes)) {
60
            removeNodesFromParents(draggedNodes);
61
            for (int i = 0; i < draggedNodes.length; i++) {
62
                GuiPackage.getInstance().getTreeModel().insertNodeInto(draggedNodes[i], currentNode,
63
                        currentNode.getChildCount());
64
            }
65
        } else if (parentNode != null) {
66
            if (ActionNames.INSERT_BEFORE.equals(action) && canAddTo(parentNode,draggedNodes)) {
67
                removeNodesFromParents(draggedNodes);
68
                for (int i = 0; i < draggedNodes.length; i++) {
69
                    int index = parentNode.getIndex(currentNode);
70
                    GuiPackage.getInstance().getTreeModel().insertNodeInto(draggedNodes[i], parentNode, index);
71
                }
72
            } else if (ActionNames.INSERT_AFTER.equals(action) && canAddTo(parentNode,draggedNodes)) {
73
                removeNodesFromParents(draggedNodes);
74
                for (int i = 0; i < draggedNodes.length; i++) {
75
                    int index = parentNode.getIndex(currentNode) + 1;
76
                    GuiPackage.getInstance().getTreeModel().insertNodeInto(draggedNodes[i], parentNode, index);
77
                }
78
            }
79
        }
80
        GuiPackage.getInstance().getMainFrame().repaint();
81
    }
82
83
    private static boolean canAddTo(JMeterTreeNode parentNode, JMeterTreeNode[] draggedNodes) {
84
        boolean ok = MenuFactory.canAddTo(parentNode, draggedNodes);
85
        if (!ok){
86
            Toolkit.getDefaultToolkit().beep();
87
        }
88
        return ok;
89
    }
90
91
    private void removeNodesFromParents(JMeterTreeNode[] nodes) {
92
        for (int i = 0; i < nodes.length; i++) {
93
            GuiPackage.getInstance().getTreeModel().removeNodeFromParent(nodes[i]);
94
        }
95
    }
96
97
    /**
98
     * @see Command#getActionNames()
99
     */
100
    @Override
101
    public Set<String> getActionNames() {
102
        return commands;
103
    }
104
}

Return to bug 54834