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

(-)src/core/org/apache/jmeter/gui/GuiPackage.java (-9 / +78 lines)
Lines 44-49 Link Here
44
import org.apache.jmeter.testbeans.gui.TestBeanGUI;
44
import org.apache.jmeter.testbeans.gui.TestBeanGUI;
45
import org.apache.jmeter.testelement.TestElement;
45
import org.apache.jmeter.testelement.TestElement;
46
import org.apache.jmeter.testelement.TestPlan;
46
import org.apache.jmeter.testelement.TestPlan;
47
import org.apache.jmeter.testelement.property.JMeterProperty;
48
import org.apache.jmeter.testelement.property.PropertyIterator;
49
import org.apache.jmeter.testelement.property.TestElementProperty;
47
import org.apache.jmeter.util.JMeterUtils;
50
import org.apache.jmeter.util.JMeterUtils;
48
import org.apache.jmeter.util.LocaleChangeEvent;
51
import org.apache.jmeter.util.LocaleChangeEvent;
49
import org.apache.jmeter.util.LocaleChangeListener;
52
import org.apache.jmeter.util.LocaleChangeListener;
Lines 104-110 Link Here
104
107
105
    /** The main JMeter frame. */
108
    /** The main JMeter frame. */
106
    private MainFrame mainFrame;
109
    private MainFrame mainFrame;
107
    
110
108
    /** The main JMeter toolbar. */
111
    /** The main JMeter toolbar. */
109
    private JToolBar toolbar;
112
    private JToolBar toolbar;
110
113
Lines 121-133 Link Here
121
     */
124
     */
122
    private LoggerPanel loggerPanel;
125
    private LoggerPanel loggerPanel;
123
126
124
    
125
    /**
127
    /**
128
     * History for tree states
129
     */
130
    private UndoHistory undoHistory = new UndoHistory();
131
132
    /**
126
     * Private constructor to permit instantiation only from within this class.
133
     * Private constructor to permit instantiation only from within this class.
127
     * Use {@link #getInstance()} to retrieve a singleton instance.
134
     * Use {@link #getInstance()} to retrieve a singleton instance.
128
     */
135
     */
129
    private GuiPackage(JMeterTreeModel treeModel, JMeterTreeListener treeListener) {
136
    private GuiPackage(JMeterTreeModel treeModel, JMeterTreeListener treeListener) {
130
        this.treeModel = treeModel;
137
        this.treeModel = treeModel;
138
        this.treeModel.addTreeModelListener(undoHistory);
131
        this.treeListener = treeListener;
139
        this.treeListener = treeListener;
132
        JMeterUtils.addLocaleChangeListener(this);
140
        JMeterUtils.addLocaleChangeListener(this);
133
    }
141
    }
Lines 155-160 Link Here
155
    public static GuiPackage getInstance(JMeterTreeListener listener, JMeterTreeModel treeModel) {
163
    public static GuiPackage getInstance(JMeterTreeListener listener, JMeterTreeModel treeModel) {
156
        if (guiPack == null) {
164
        if (guiPack == null) {
157
            guiPack = new GuiPackage(treeModel, listener);
165
            guiPack = new GuiPackage(treeModel, listener);
166
            guiPack.undoHistory.add(treeModel, "Created");
158
        }
167
        }
159
        return guiPack;
168
        return guiPack;
160
    }
169
    }
Lines 408-415 Link Here
408
                log.debug("Updating current node " + currentNode.getName());
417
                log.debug("Updating current node " + currentNode.getName());
409
                JMeterGUIComponent comp = getGui(currentNode.getTestElement());
418
                JMeterGUIComponent comp = getGui(currentNode.getTestElement());
410
                TestElement el = currentNode.getTestElement();
419
                TestElement el = currentNode.getTestElement();
420
                int before = getTestElementCheckSum(el);
411
                comp.modifyTestElement(el);
421
                comp.modifyTestElement(el);
412
                currentNode.nameChanged(); // Bug 50221 - ensure label is updated
422
                int after = getTestElementCheckSum(el);
423
                if (before != after) {
424
                    currentNode.nameChanged(); // Bug 50221 - ensure label is updated
425
                }
413
            }
426
            }
414
            // The current node is now updated
427
            // The current node is now updated
415
            currentNodeUpdated = true;
428
            currentNodeUpdated = true;
Lines 464-470 Link Here
464
     *             if a subtree cannot be added to the currently selected node
477
     *             if a subtree cannot be added to the currently selected node
465
     */
478
     */
466
    public HashTree addSubTree(HashTree subTree) throws IllegalUserActionException {
479
    public HashTree addSubTree(HashTree subTree) throws IllegalUserActionException {
467
        return treeModel.addSubTree(subTree, treeListener.getCurrentNode());
480
        HashTree hashTree = treeModel.addSubTree(subTree, treeListener.getCurrentNode());
481
        undoHistory.clear();
482
        undoHistory.add(this.treeModel, "Loaded tree");
483
        return hashTree;
468
    }
484
    }
469
485
470
    /**
486
    /**
Lines 527-533 Link Here
527
    public JMeterTreeListener getTreeListener() {
543
    public JMeterTreeListener getTreeListener() {
528
        return treeListener;
544
        return treeListener;
529
    }
545
    }
530
    
546
531
    /**
547
    /**
532
     * Set the main JMeter toolbar.
548
     * Set the main JMeter toolbar.
533
     *
549
     *
Lines 546-552 Link Here
546
    public JToolBar getMainToolbar() {
562
    public JToolBar getMainToolbar() {
547
        return toolbar;
563
        return toolbar;
548
    }
564
    }
549
    
565
550
    /**
566
    /**
551
     * Set the menu item toolbar.
567
     * Set the menu item toolbar.
552
     *
568
     *
Lines 670-675 Link Here
670
        getTreeModel().clearTestPlan();
686
        getTreeModel().clearTestPlan();
671
        nodesToGui.clear();
687
        nodesToGui.clear();
672
        setTestPlanFile(null);
688
        setTestPlanFile(null);
689
        undoHistory.clear();
690
        undoHistory.add(this.treeModel, "Initial Tree");
673
    }
691
    }
674
692
675
    /**
693
    /**
Lines 680-685 Link Here
680
    public void clearTestPlan(TestElement element) {
698
    public void clearTestPlan(TestElement element) {
681
        getTreeModel().clearTestPlan(element);
699
        getTreeModel().clearTestPlan(element);
682
        removeNode(element);
700
        removeNode(element);
701
        undoHistory.clear();
702
        undoHistory.add(this.treeModel, "Initial Tree");
683
    }
703
    }
684
704
685
    public static void showErrorMessage(final String message, final String title){
705
    public static void showErrorMessage(final String message, final String title){
Lines 720-726 Link Here
720
            }
740
            }
721
        }
741
        }
722
    }
742
    }
723
    
743
724
    /**
744
    /**
725
     * Register process to stop on reload
745
     * Register process to stop on reload
726
     * @param stoppable
746
     * @param stoppable
Lines 730-736 Link Here
730
    }
750
    }
731
751
732
    /**
752
    /**
733
     * 
753
     *
734
     * @return List<IStoppable> Copy of IStoppable
754
     * @return List<IStoppable> Copy of IStoppable
735
     */
755
     */
736
    public List<Stoppable> getStoppables() {
756
    public List<Stoppable> getStoppables() {
Lines 746-752 Link Here
746
    public void setMenuItemLoggerPanel(JCheckBoxMenuItem menuItemLoggerPanel) {
766
    public void setMenuItemLoggerPanel(JCheckBoxMenuItem menuItemLoggerPanel) {
747
        this.menuItemLoggerPanel = menuItemLoggerPanel;
767
        this.menuItemLoggerPanel = menuItemLoggerPanel;
748
    }
768
    }
749
    
769
750
    /**
770
    /**
751
     * Get the menu item LoggerPanel.
771
     * Get the menu item LoggerPanel.
752
     *
772
     *
Lines 769-772 Link Here
769
    public LoggerPanel getLoggerPanel() {
789
    public LoggerPanel getLoggerPanel() {
770
        return loggerPanel;
790
        return loggerPanel;
771
    }
791
    }
792
793
    /**
794
     * Navigate up and down in history
795
     *
796
     * @param offset int
797
     */
798
    public void goInHistory(int offset) {
799
        undoHistory.getRelativeState(offset, this.treeModel);
800
    }
801
802
    /**
803
     * @return true if history contains redo item
804
     */
805
    public boolean canRedo() {
806
        return undoHistory.canRedo();
807
    }
808
809
    /**
810
     * @return true if history contains undo item
811
     */
812
    public boolean canUndo() {
813
        return undoHistory.canUndo();
814
    }
815
816
    /**
817
     * Compute checksum of TestElement to detect changes
818
     * the method calculates properties checksum to detect testelement
819
     * modifications
820
     * TODO would be better to override hashCode for TestElement, but I decided to touch it
821
     *
822
     * @param el {@link TestElement}
823
     * @return int checksum
824
     */
825
    private int getTestElementCheckSum(TestElement el) {
826
        int ret = el.getClass().hashCode();
827
        PropertyIterator it = el.propertyIterator();
828
        while (it.hasNext()) {
829
            JMeterProperty obj = it.next();
830
            if (obj instanceof TestElementProperty) {
831
                ret ^= getTestElementCheckSum(((TestElementProperty) obj)
832
                        .getElement());
833
            } else {
834
                ret ^= obj.getName().hashCode();
835
                ret ^= obj.getStringValue().hashCode();
836
            }
837
        }
838
        return ret;
839
    }
840
772
}
841
}
(-)src/core/org/apache/jmeter/gui/action/ActionNames.java (+2 lines)
Lines 95-100 Link Here
95
    public static final String MOVE_DOWN        = "move_down"; // $NON-NLS-1$
95
    public static final String MOVE_DOWN        = "move_down"; // $NON-NLS-1$
96
    public static final String MOVE_LEFT        = "move_left"; // $NON-NLS-1$
96
    public static final String MOVE_LEFT        = "move_left"; // $NON-NLS-1$
97
    public static final String MOVE_RIGHT       = "move_right"; // $NON-NLS-1$
97
    public static final String MOVE_RIGHT       = "move_right"; // $NON-NLS-1$
98
    public static final String UNDO             = "undo"; // $NON-NLS-1$
99
    public static final String REDO             = "redo"; // $NON-NLS-1$
98
100
99
    // Prevent instantiation
101
    // Prevent instantiation
100
    private ActionNames(){
102
    private ActionNames(){
(-)src/core/org/apache/jmeter/gui/util/MenuFactory.java (+25 lines)
Lines 206-211 Link Here
206
     * @param addSaveTestFragmentMenu Add Save as Test Fragment menu if true 
206
     * @param addSaveTestFragmentMenu Add Save as Test Fragment menu if true 
207
     */
207
     */
208
    public static void addFileMenu(JPopupMenu menu, boolean addSaveTestFragmentMenu) {
208
    public static void addFileMenu(JPopupMenu menu, boolean addSaveTestFragmentMenu) {
209
        // the undo/redo as a standard goes first in Edit menus
210
        // maybe there's better place for them in JMeter?
211
        addUndoItems(menu);
212
209
        addSeparator(menu);
213
        addSeparator(menu);
210
        menu.add(makeMenuItemRes("open", ActionNames.OPEN));// $NON-NLS-1$
214
        menu.add(makeMenuItemRes("open", ActionNames.OPEN));// $NON-NLS-1$
211
        menu.add(makeMenuItemRes("menu_merge", ActionNames.MERGE));// $NON-NLS-1$
215
        menu.add(makeMenuItemRes("menu_merge", ActionNames.MERGE));// $NON-NLS-1$
Lines 247-252 Link Here
247
        menu.add(makeMenuItemRes("help", ActionNames.HELP));// $NON-NLS-1$
251
        menu.add(makeMenuItemRes("help", ActionNames.HELP));// $NON-NLS-1$
248
    }
252
    }
249
253
254
    /**
255
     * Add undo / redo
256
     * @param menu JPopupMenu
257
     */
258
    private static void addUndoItems(JPopupMenu menu) {
259
        addSeparator(menu);
260
261
        JMenuItem undo = makeMenuItemRes("undo", ActionNames.UNDO); //$NON-NLS-1$
262
        //undo.setAccelerator(KeyStrokes.UNDO);
263
        undo.setEnabled(GuiPackage.getInstance().canUndo());
264
        menu.add(undo);
265
266
        JMenuItem redo = makeMenuItemRes("redo", ActionNames.REDO); //$NON-NLS-1$
267
        //redo.setAccelerator(KeyStrokes.REDO);
268
        // TODO: we could even show some hints on action being undone here if this will be required (by passing those hints into history  records)
269
        redo.setEnabled(GuiPackage.getInstance().canRedo());
270
        menu.add(redo);
271
        // TODO: find a way to enable/disable toolbar items depending on action states
272
    }
273
274
250
    public static JMenu makeMenus(String[] categories, String label, String actionCommand) {
275
    public static JMenu makeMenus(String[] categories, String label, String actionCommand) {
251
        JMenu addMenu = new JMenu(label);
276
        JMenu addMenu = new JMenu(label);
252
        for (int i = 0; i < categories.length; i++) {
277
        for (int i = 0; i < categories.length; i++) {
(-)src/core/org/apache/jmeter/images/toolbar/icons-toolbar.properties (-2 / +4 lines)
Lines 14-20 Link Here
14
#   limitations under the License.
14
#   limitations under the License.
15
15
16
# Icons order. Keys separate by comma. Use a pipe | to have a space between two icons.
16
# Icons order. Keys separate by comma. Use a pipe | to have a space between two icons.
17
toolbar=new,templates,open,close,save,save_as_testplan,|,cut,copy,paste,|,expand,collapse,toggle,|,test_start,test_start_notimers,test_stop,test_shutdown,|,test_start_remote_all,test_stop_remote_all,test_shutdown_remote_all,|,test_clear,test_clear_all,|,search,search_reset,|,function_helper,help
17
toolbar=new,templates,open,close,save,save_as_testplan,|,undo,redo,cut,copy,paste,|,expand,collapse,toggle,|,test_start,test_start_notimers,test_stop,test_shutdown,|,test_start_remote_all,test_stop_remote_all,test_shutdown_remote_all,|,test_clear,test_clear_all,|,search,search_reset,|,function_helper,help
18
18
19
# Icon / action definition file.
19
# Icon / action definition file.
20
# Key:      button names
20
# Key:      button names
Lines 43-46 Link Here
43
search=menu_search,SEARCH_TREE,org/apache/jmeter/images/toolbar/search.png
43
search=menu_search,SEARCH_TREE,org/apache/jmeter/images/toolbar/search.png
44
search_reset=menu_search_reset,SEARCH_RESET,org/apache/jmeter/images/toolbar/searchreset.png
44
search_reset=menu_search_reset,SEARCH_RESET,org/apache/jmeter/images/toolbar/searchreset.png
45
function_helper=function_dialog_menu_item,FUNCTIONS,org/apache/jmeter/images/toolbar/function.png
45
function_helper=function_dialog_menu_item,FUNCTIONS,org/apache/jmeter/images/toolbar/function.png
46
help=help,HELP,org/apache/jmeter/images/toolbar/help.png
46
help=help,HELP,org/apache/jmeter/images/toolbar/help.png
47
undo=undo,UNDO,org/apache/jmeter/images/toolbar/undo.png
48
redo=redo,REDO,org/apache/jmeter/images/toolbar/redo.png
(-)src/core/org/apache/jmeter/resources/messages.properties (+2 lines)
Lines 769-774 Link Here
769
read_soap_response=Read SOAP Response
769
read_soap_response=Read SOAP Response
770
realm=Realm
770
realm=Realm
771
record_controller_title=Recording Controller
771
record_controller_title=Recording Controller
772
redo=Redo
772
ref_name_field=Reference Name\:
773
ref_name_field=Reference Name\:
773
regex_extractor_title=Regular Expression Extractor
774
regex_extractor_title=Regular Expression Extractor
774
regex_field=Regular Expression\:
775
regex_field=Regular Expression\:
Lines 1131-1136 Link Here
1131
transaction_controller_parent=Generate parent sample
1132
transaction_controller_parent=Generate parent sample
1132
transaction_controller_title=Transaction Controller
1133
transaction_controller_title=Transaction Controller
1133
unbind=Thread Unbind
1134
unbind=Thread Unbind
1135
undo=Undo
1134
unescape_html_string=String to unescape
1136
unescape_html_string=String to unescape
1135
unescape_string=String containing Java escapes
1137
unescape_string=String containing Java escapes
1136
uniform_timer_delay=Constant Delay Offset (in milliseconds)\:
1138
uniform_timer_delay=Constant Delay Offset (in milliseconds)\:
(-)src/core/org/apache/jmeter/resources/messages_fr.properties (+2 lines)
Lines 762-767 Link Here
762
read_soap_response=Lire la r\u00E9ponse SOAP
762
read_soap_response=Lire la r\u00E9ponse SOAP
763
realm=Univers (realm)
763
realm=Univers (realm)
764
record_controller_title=Contr\u00F4leur Enregistreur
764
record_controller_title=Contr\u00F4leur Enregistreur
765
redo=R\u00E9tablir
765
ref_name_field=Nom de r\u00E9f\u00E9rence \:
766
ref_name_field=Nom de r\u00E9f\u00E9rence \:
766
regex_extractor_title=Extracteur Expression r\u00E9guli\u00E8re
767
regex_extractor_title=Extracteur Expression r\u00E9guli\u00E8re
767
regex_field=Expression r\u00E9guli\u00E8re \:
768
regex_field=Expression r\u00E9guli\u00E8re \:
Lines 1124-1129 Link Here
1124
transaction_controller_parent=G\u00E9n\u00E9rer en \u00E9chantillon parent
1125
transaction_controller_parent=G\u00E9n\u00E9rer en \u00E9chantillon parent
1125
transaction_controller_title=Contr\u00F4leur Transaction
1126
transaction_controller_title=Contr\u00F4leur Transaction
1126
unbind=D\u00E9connexion de l'unit\u00E9
1127
unbind=D\u00E9connexion de l'unit\u00E9
1128
undo=Annuler
1127
unescape_html_string=Cha\u00EEne \u00E0 \u00E9chapper
1129
unescape_html_string=Cha\u00EEne \u00E0 \u00E9chapper
1128
unescape_string=Cha\u00EEne de caract\u00E8res contenant des\u00E9chappements Java
1130
unescape_string=Cha\u00EEne de caract\u00E8res contenant des\u00E9chappements Java
1129
uniform_timer_delay=D\u00E9lai de d\u00E9calage constant (en millisecondes) \:
1131
uniform_timer_delay=D\u00E9lai de d\u00E9calage constant (en millisecondes) \:

Return to bug 42248