001package com.ganteater.ae.desktop.editor;
002
003import java.awt.BorderLayout;
004import java.awt.CardLayout;
005import java.awt.Color;
006import java.awt.Component;
007import java.awt.Desktop;
008import java.awt.Dimension;
009import java.awt.FileDialog;
010import java.awt.Font;
011import java.awt.Point;
012import java.awt.Toolkit;
013import java.awt.event.ActionEvent;
014import java.awt.event.ActionListener;
015import java.awt.event.ComponentAdapter;
016import java.awt.event.ComponentEvent;
017import java.awt.event.KeyAdapter;
018import java.awt.event.KeyEvent;
019import java.awt.event.MouseAdapter;
020import java.awt.event.MouseEvent;
021import java.io.File;
022import java.io.FileOutputStream;
023import java.io.IOException;
024import java.lang.reflect.Constructor;
025import java.lang.reflect.InvocationTargetException;
026import java.util.ArrayList;
027import java.util.HashMap;
028import java.util.Map;
029import java.util.Properties;
030import java.util.Set;
031import java.util.Vector;
032
033import javax.swing.BorderFactory;
034import javax.swing.JButton;
035import javax.swing.JCheckBox;
036import javax.swing.JComponent;
037import javax.swing.JLabel;
038import javax.swing.JMenu;
039import javax.swing.JMenuBar;
040import javax.swing.JMenuItem;
041import javax.swing.JOptionPane;
042import javax.swing.JPanel;
043import javax.swing.JScrollPane;
044import javax.swing.JSeparator;
045import javax.swing.JSlider;
046import javax.swing.JSplitPane;
047import javax.swing.JTabbedPane;
048import javax.swing.JToolBar;
049import javax.swing.JTree;
050import javax.swing.JTree.DynamicUtilTreeNode;
051import javax.swing.KeyStroke;
052import javax.swing.SwingConstants;
053import javax.swing.SwingUtilities;
054import javax.swing.plaf.basic.BasicTabbedPaneUI;
055import javax.swing.table.AbstractTableModel;
056import javax.swing.text.BadLocationException;
057import javax.swing.tree.DefaultMutableTreeNode;
058import javax.swing.tree.DefaultTreeModel;
059import javax.swing.tree.TreePath;
060import javax.swing.tree.TreeSelectionModel;
061
062import org.apache.commons.io.FilenameUtils;
063import org.apache.commons.lang.StringUtils;
064import org.apache.commons.lang.SystemUtils;
065import org.apache.commons.lang.exception.ExceptionUtils;
066
067import com.ganteater.ae.AEWorkspace;
068import com.ganteater.ae.CommandException;
069import com.ganteater.ae.ConfigurationException;
070import com.ganteater.ae.ILogger;
071import com.ganteater.ae.desktop.WorkPlace;
072import com.ganteater.ae.desktop.ui.AEFrame;
073import com.ganteater.ae.desktop.ui.Button;
074import com.ganteater.ae.desktop.ui.DialogPopupMenu;
075import com.ganteater.ae.desktop.ui.TaskPanel;
076import com.ganteater.ae.desktop.view.AbstractView;
077import com.ganteater.ae.desktop.view.ListLogView;
078import com.ganteater.ae.desktop.view.LogView;
079import com.ganteater.ae.processor.BaseProcessor;
080import com.ganteater.ae.processor.Processor;
081import com.ganteater.ae.util.xml.easyparser.EasyParser;
082import com.ganteater.ae.util.xml.easyparser.EasyUtils;
083import com.ganteater.ae.util.xml.easyparser.Node;
084import com.ganteater.ae.util.xml.easyparser.Node.TreeVector;
085
086/**
087 * @author victort
088 * @version 1.0, 29-Jul-2005
089 */
090public class TaskEditor extends WorkPlace {
091
092        public static final Font font = new Font("Monospaced", Font.PLAIN, 12);
093
094        public static final String EDITOR_STD_PACKAGE = "com.ganteater.ae.desktop.editor.";
095        private static final String ABOUT = "About";
096        private static final Color ACTIVE_COLOR = Color.GREEN.darker();
097
098        private static final String TASK_EDITOR = "Editor";
099        private static final String TASK_TREE = "Process";
100
101        private String fTaskFile;
102        private Vector<?> fTreeVector;
103        private Map<String, Object> fPresentationPanels = new HashMap<String, Object>();
104
105        private AEFrame frame;
106        private JTree taskTree;
107        private TextEditor fTaskText;
108        private TaskPanel taskPanel;
109
110        private JMenuItem fRunMenuItem = new JMenuItem("Run");
111        private JMenuItem fContinueMenuItem = new JMenuItem("Continue");
112        private JMenuItem fStopMenuItem = new JMenuItem("Stop");
113        private JMenuItem fPauseMenuItem = new JMenuItem("Pause");
114        private JButton fRunButton = new JButton("Run");
115        private JCheckBox notifyMeCheckBox = new JCheckBox();
116        private JMenuItem saveMenuItem;
117        private JSplitPane fOutputSplitPanel;
118        private JSlider speed = new JSlider(0, 100, 100);
119        private JLabel changedLabel = new JLabel("");
120
121        private JTabbedPane createEditorPanel;
122
123        private JLabel lblTitle = new JLabel();
124        private JTabbedPane tabbedPanel;
125
126        private JTabbedPane fOutputTabbedPane;
127
128        private boolean openIn;
129        private boolean editable = true;
130
131        private ArrayList<LogView> fLoggers = new ArrayList<LogView>();
132        private boolean isRunning;
133
134        private boolean restoreDividerRequired;
135
136        private static String directory;
137
138        public TaskEditor(AEFrame frame, Node aConfigNode, Map<String, Object> aSystemVariables) throws CommandException {
139                super(frame, aConfigNode, aSystemVariables);
140                this.frame = frame;
141
142                this.taskPanel = new TaskPanel(this);
143                taskPanel.addComponentListener(new ComponentAdapter() {
144                        @Override
145                        public void componentResized(ComponentEvent e) {
146                                if (taskPanel.getSize().width > AEFrame.MINIMUM_WIN_WIDTH) {
147                                        createEditorPanel.setVisible(true);
148                                        restoreDivider();
149                                } else {
150                                        createEditorPanel.setVisible(false);
151                                }
152                        }
153                });
154
155                fOutputTabbedPane = new JTabbedPane();
156                fOutputTabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
157                fOutputTabbedPane.setUI(new BasicTabbedPaneUI() {
158                        @Override
159                        protected int calculateTabAreaHeight(int tab_placement, int run_count, int max_tab_height) {
160                                int calculateTabAreaHeight = 0;
161                                if (fOutputTabbedPane.getTabCount() > 1) {
162                                        calculateTabAreaHeight = super.calculateTabAreaHeight(tab_placement, run_count, max_tab_height);
163                                }
164                                return calculateTabAreaHeight;
165                        }
166                });
167
168                fOutputTabbedPane.setPreferredSize(new Dimension(200, 800));
169                fOutputTabbedPane.addKeyListener(new KeyAdapter() {
170                        @Override
171                        public void keyReleased(KeyEvent e) {
172                                if (e.getKeyCode() == KeyEvent.VK_F4 && e.isControlDown()) {
173                                        removeActivePresentationPanel();
174                                }
175                        }
176                });
177
178                fOutputTabbedPane.addMouseListener(new MouseAdapter() {
179                        @Override
180                        public void mouseClicked(MouseEvent e) {
181                                JTabbedPane outputTabbedPane = (JTabbedPane) e.getSource();
182                                if (e.getButton() == MouseEvent.BUTTON2) {
183                                        if (outputTabbedPane.indexAtLocation(e.getX(), e.getY()) != -1) {
184                                                Component selectedComponent = outputTabbedPane.getSelectedComponent();
185                                                String id = ((AbstractView) selectedComponent).getName();
186                                                removeActivePresentationPanel();
187                                                fPresentationPanels.remove(id);
188                                        }
189                                }
190                                if (e.getButton() == MouseEvent.BUTTON3) {
191                                        if (outputTabbedPane.findComponentAt(e.getX(), e.getY()) == outputTabbedPane
192                                                        && outputTabbedPane.indexAtLocation(e.getX(), e.getY()) != -1) {
193
194                                                AbstractView selectedComponent = (AbstractView) outputTabbedPane.getSelectedComponent();
195
196                                                if (selectedComponent instanceof LogView && !((LogView) selectedComponent).isEmpty()) {
197                                                        if (fLoggers.contains(selectedComponent)) {
198                                                                String id = selectedComponent.getName();
199                                                                LogView findLogger = findLogger(id);
200                                                                LogView bakPresenter = findLogger.copyAndClean();
201                                                                outputTabbedPane.addTab(id, AEFrame.getIcon("copied.png"), bakPresenter);
202                                                        }
203                                                }
204                                        }
205                                }
206                        }
207                });
208
209                createEditorPanel = createEditorPanel();
210
211                fOutputSplitPanel = new JSplitPane(JSplitPane.VERTICAL_SPLIT, createEditorPanel, fOutputTabbedPane);
212                fOutputSplitPanel.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, e -> {
213                        if (taskPanel.getSize().width > AEFrame.MINIMUM_WIN_WIDTH && !restoreDividerRequired) {
214                                int dividerLocation = fOutputSplitPanel.getDividerLocation();
215                                String divider = Integer.toString(dividerLocation);
216                                int selectedIndex = createEditorPanel.getSelectedIndex();
217                                AEWorkspace.getInstance().setDefaultUserConfiguration("splitPanel.divider." + selectedIndex, divider);
218                        }
219                });
220
221                setSplitPanel();
222
223                taskPanel.addEditor(fOutputSplitPanel);
224                JMenuBar menuBar = new JMenuBar();
225
226                createFileMenu(menuBar);
227                createProcessMenu(menuBar);
228
229                Node taskNode = getTaskNode();
230                if (taskNode != null && taskNode.findNode(ABOUT, null, null) != null) {
231                        showAbout();
232                }
233
234                JToolBar panel2 = new JToolBar();
235                panel2.setBorderPainted(false);
236                panel2.setFloatable(false);
237
238                fRunButton.setBorder(BorderFactory.createEmptyBorder());
239                panel2.add(fRunButton);
240
241                notifyMeCheckBox.setBorder(BorderFactory.createEmptyBorder());
242                notifyMeCheckBox.setIcon(AEFrame.getIcon("shout-off.png"));
243                notifyMeCheckBox.setSelectedIcon(AEFrame.getIcon("shout.png"));
244                panel2.add(notifyMeCheckBox);
245
246                notifyMeCheckBox.addActionListener(e -> {
247                        if (getTaskName() != null) {
248                                String aName = getTaskName() + ".notifyMe";
249                                String value = Boolean.toString(notifyMeCheckBox.isSelected());
250                                AEWorkspace.getInstance().setDefaultUserConfiguration(aName, value);
251                                AEWorkspace.getInstance().setDefaultUserConfiguration("notifyMe", value);
252                        }
253                });
254
255                speed.setPreferredSize(new Dimension(30, 18));
256                speed.setToolTipText("Action speed");
257
258                speed.addChangeListener(e -> {
259                        String text;
260                        long traceDelay = getTraceDelay();
261                        if (traceDelay < 1000) {
262                                text = traceDelay + "ms.";
263                        } else {
264                                text = String.format("%.2f", traceDelay / 1000.0) + "s";
265                        }
266
267                        speed.setToolTipText("Delay: " + text);
268                        setMessage("Slow motion time: " + text);
269                });
270
271                JButton closeBtn = new Button("close.png");
272                closeBtn.setBorder(BorderFactory.createEtchedBorder());
273
274                closeBtn.addActionListener(e -> {
275                        stopTest();
276                        closeTab();
277                });
278
279                taskPanel.setCloseBtn(closeBtn);
280                taskPanel.setMenu(menuBar);
281
282                JPanel aboutPanel = new JPanel(new BorderLayout(0, 0));
283                aboutButtonPanel.setBorderPainted(false);
284                aboutButtonPanel.setFloatable(false);
285                aboutPanel.add(panel2, BorderLayout.WEST);
286
287                JPanel titlePanel = new JPanel(new BorderLayout(0, 0));
288                titlePanel.add(aboutButtonPanel, BorderLayout.WEST);
289                titlePanel.add(fTitleTest, BorderLayout.CENTER);
290                aboutPanel.add(titlePanel, BorderLayout.CENTER);
291
292                taskPanel.addAboutPanel(aboutPanel);
293        }
294
295        public void setSplitPanel() {
296                fOutputSplitPanel.setOneTouchExpandable(true);
297        }
298
299        private String getTaskName() {
300                String name = null;
301                if (getTaskNode() != null) {
302                        name = getTaskNode().getAttribute("name");
303                }
304                return name;
305        }
306
307        public TaskEditor(AEFrame aeFrame) throws CommandException {
308                this(aeFrame, aeFrame.getWorkspace().getConfigNode(), aeFrame.getWorkspace().getSystemVariables());
309                setRunButtonAction(true);
310        }
311
312        private void createFileMenu(JMenuBar menuBar) {
313                JMenu menu = new JMenu("File");
314
315                JMenuItem menuItem;
316                menuItem = new JMenuItem("Save");
317                try {
318                        menuItem.setAccelerator(KeyStroke.getKeyStroke('S', Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
319                } catch (Exception e) {
320                }
321
322                this.saveMenuItem = menuItem;
323                menuItem.addActionListener(new ActionListener() {
324                        public void actionPerformed(ActionEvent arg0) {
325
326                                SwingUtilities.invokeLater(() -> {
327                                        try {
328                                                save();
329                                        } catch (IOException e) {
330                                                JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
331                                                                "Error: Unable to Save File: " + fTaskFile);
332                                        }
333                                });
334                        }
335                });
336                menu.add(menuItem);
337
338                menuItem = new JMenuItem("Reload");
339                final JMenuItem reloadmenuItem = menuItem;
340                try {
341                        menuItem.setAccelerator(KeyStroke.getKeyStroke('R', Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
342                } catch (Exception e) {
343                }
344                menuItem.addActionListener(arg0 -> {
345                        reload();
346                });
347                menu.add(menuItem);
348
349                menuItem = new JMenuItem("Format");
350                try {
351                        menuItem.setAccelerator(KeyStroke.getKeyStroke('F', Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
352                } catch (Exception e) {
353                }
354                menuItem.addActionListener(arg0 -> {
355                        format();
356                });
357                menu.add(menuItem);
358
359                menuItem = new JMenuItem("Open In");
360                try {
361                        menuItem.setAccelerator(KeyStroke.getKeyStroke('E', Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
362                } catch (Exception e) {
363                }
364                menuItem.addActionListener(arg0 -> {
365                        File file;
366                        if (fTaskFile.startsWith("jar:file:")) {
367                                String pathname = fTaskFile.replaceFirst("jar:file:", "");
368                                pathname = StringUtils.substringBeforeLast(pathname, "!");
369                                file = new File(pathname);
370                        } else {
371                                file = new File(fTaskFile);
372                        }
373                        if (file.exists() || fTaskFile.startsWith("jar:file:")) {
374                                try {
375                                        Desktop.getDesktop().open(file);
376                                        openIn = true;
377                                        reloadmenuItem.setText("Reload [Before Run]");
378
379                                } catch (IOException e) {
380                                        getLogger().error(e.getMessage(), e);
381                                }
382                        }
383                });
384                menu.add(menuItem);
385
386                menu.add(new JSeparator());
387                menuItem = new JMenuItem("Close");
388                try {
389                        menuItem.setAccelerator(KeyStroke.getKeyStroke('X', Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
390                } catch (Exception e) {
391                }
392                menuItem.addActionListener(e -> {
393                        closeTab();
394                });
395                menu.add(menuItem);
396                menuBar.add(menu);
397        }
398
399        public void reload() {
400                openTaskFile(fTaskFile);
401        }
402
403        public void save() throws IOException {
404                changedLabel.setText("");
405                format();
406                saveTask();
407        }
408
409        public void format() {
410                try {
411                        compileTask();
412                        refreshTaskTree();
413
414                        Node taskNode = getTaskNode();
415                        applyText(taskNode);
416
417                        if (taskNode != null && taskNode.findNode(ABOUT, null, null) != null) {
418                                showAbout();
419                        }
420
421                } catch (Exception e) {
422                        getLogger().error("Save action failed.", e);
423                }
424        }
425
426        private void createProcessMenu(JMenuBar menuBar) {
427                JMenu menu = new JMenu("Process");
428
429                JMenuItem compileMenuItem = new JMenuItem("Compile");
430                menu.add(compileMenuItem);
431                compileMenuItem.addActionListener(arg0 -> {
432                        try {
433                                compileTask();
434                        } catch (Exception e) {
435                                getLogger().error("Compilation failed.", e);
436                        }
437                });
438
439                menu.add(fRunMenuItem);
440
441                try {
442                        fRunMenuItem.setAccelerator(
443                                        KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
444                } catch (Exception e) {
445                }
446
447                fRunMenuItem.addActionListener(e -> {
448                        runTask();
449                });
450                menu.add(speed);
451
452                fRunButton.addActionListener(e -> {
453                        boolean isCurrentRunAction = "Run".equals(e.getActionCommand());
454
455                        if (isCurrentRunAction) {
456                                runTask();
457                        } else {
458                                stopTest();
459                                if (getProcessor().isStoppedTest()) {
460                                        setRunButtonAction(true);
461                                }
462                        }
463                });
464
465                menu.add(fPauseMenuItem);
466
467                try {
468                        fPauseMenuItem
469                                        .setAccelerator(KeyStroke.getKeyStroke('P', Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
470                } catch (Exception e) {
471                }
472
473                fPauseMenuItem.addActionListener(e -> {
474                        getProcessor().pause();
475                });
476
477                menu.add(fContinueMenuItem);
478
479                try {
480                        fContinueMenuItem
481                                        .setAccelerator(KeyStroke.getKeyStroke('P', Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
482                } catch (Exception e) {
483                }
484
485                fContinueMenuItem.addActionListener(arg0 -> getProcessor().resume());
486
487                try {
488                        fStopMenuItem.setAccelerator(
489                                        KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
490                } catch (Exception e) {
491                }
492
493                fStopMenuItem.addActionListener(arg0 -> stopTask());
494                menu.add(fStopMenuItem);
495                menuBar.add(menu);
496        }
497
498        @Override
499        public void setProgress(String message, long aMaxTags, long aCurrTags, boolean aErrorState) {
500                manager.progressValue((int) (((double) aCurrTags / aMaxTags) * 100), 100, true);
501                setMessage(message);
502        }
503
504        private void setMessage(String message) {
505                fTitleTest.setText(message);
506                int width = fTitleTest.getSize().width;
507                int textWidth = message.length() * 8;
508                if (width < textWidth) {
509                        fTitleTest.setToolTipText(message);
510                } else {
511                        fTitleTest.setToolTipText(null);
512                }
513        }
514
515        public void stopTask() {
516                super.stopTest();
517        }
518
519        private JTabbedPane createEditorPanel() throws CommandException {
520                JTabbedPane editorPanel = new JTabbedPane();
521                editorPanel.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
522
523                editorPanel.setTabPlacement(SwingConstants.TOP);
524
525                JScrollPane theScroll = new JScrollPane();
526                theScroll.getViewport().removeAll();
527                taskTree = new JTree();
528                taskTree.setRootVisible(false);
529                taskTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
530
531                taskTree.addMouseListener(new MouseAdapter() {
532                        @Override
533                        public void mousePressed(MouseEvent e) {
534                                if (e.getClickCount() == 2) {
535                                        DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) taskTree
536                                                        .getLastSelectedPathComponent();
537                                        TreeVector userObject = (TreeVector) selectedNode.getUserObject();
538                                        Node node = userObject.getNode();
539
540                                        String tagName = node.getTag();
541                                        if ("Task".equals(tagName)) {
542                                                String name = node.getAttribute("name");
543                                                TaskEditor editTask;
544                                                try {
545                                                        editTask = getAeFrame().editTask(name);
546                                                        editTask.setRunButtonAction(true);
547                                                } catch (CommandException e1) {
548                                                        // TODO Auto-generated catch block
549                                                        e1.printStackTrace();
550                                                }
551                                        }
552                                }
553                        }
554                });
555
556                theScroll.getViewport().add(taskTree);
557
558                editorPanel.addTab(TASK_TREE, theScroll);
559
560                return editorPanel;
561        }
562
563        private void restoreDivider() {
564                if (!restoreDividerRequired) {
565                        this.restoreDividerRequired = true;
566                        new Thread(() -> {
567                                try {
568                                        Thread.sleep(50);
569                                } catch (InterruptedException e) {
570                                        // do nothing.
571                                }
572
573                                if (restoreDividerRequired) {
574                                        int selectedIndex = createEditorPanel.getSelectedIndex();
575                                        String divider = AEWorkspace.getInstance()
576                                                        .getDefaultUserConfiguration("splitPanel.divider." + selectedIndex, null);
577                                        if (divider != null) {
578                                                fOutputSplitPanel.setDividerLocation(Integer.parseInt(divider));
579                                        }
580
581                                        Component selectedComponent = createEditorPanel.getSelectedComponent();
582                                        if (selectedComponent instanceof VariableViewPanel) {
583                                                VariableViewPanel panel = (VariableViewPanel) selectedComponent;
584                                                panel.refreshData();
585                                        }
586                                        restoreDividerRequired = false;
587                                }
588                        }).start();
589                }
590        }
591
592        public void compileTask() {
593                try {
594                        String text = fTaskText.getText();
595                        Node object = new EasyParser().getObject(text);
596                        setTaskNode(object);
597
598                } catch (Exception e1) {
599                        JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "Incorrect code!\nError: " + e1.getMessage());
600                        throw e1;
601                }
602        }
603
604        public void showPanel(JTabbedPane panel, String name) {
605                if (name == null) {
606                        name = getPanelName();
607                }
608                tabbedPanel = panel;
609                String tabNameId = Integer.toString(taskPanel.hashCode());
610                panel.addTab(tabNameId, taskPanel);
611                panel.setSelectedComponent(taskPanel);
612
613                JPanel pnlTab = new JPanel(new BorderLayout());
614                pnlTab.setOpaque(false);
615                pnlTab.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 0));
616
617                setTitle(name);
618                lblTitle.addMouseListener(new MouseAdapter() {
619                        @Override
620                        public void mouseClicked(MouseEvent var1) {
621                                int index = tabbedPanel.indexOfTab(tabNameId);
622                                int button = var1.getButton();
623                                if (button == MouseEvent.BUTTON2) {
624                                        TaskEditor.this.frame.removeTab(TaskEditor.this);
625                                } else {
626                                        tabbedPanel.setSelectedIndex(index);
627                                }
628                        }
629                });
630
631                pnlTab.add(lblTitle, BorderLayout.CENTER);
632                pnlTab.add(changedLabel, BorderLayout.EAST);
633
634                int index = tabbedPanel.indexOfTab(tabNameId);
635                tabbedPanel.setTabComponentAt(index, pnlTab);
636        }
637
638        private void setTitle(String name) {
639                lblTitle.setText(StringUtils.abbreviate(name, 12));
640                lblTitle.setToolTipText(name);
641        }
642
643        public TaskPanel getMainPanel() {
644                return taskPanel;
645        }
646
647        @Override
648        public void endTask(boolean aErrorState) {
649                super.endTask(aErrorState);
650                fRunMenuItem.setEnabled(true);
651                setRunButtonAction(true);
652        }
653
654        private void openTaskFile(String filePath) {
655                fTaskFile = filePath;
656                if (new File(fTaskFile).exists() && !openIn) {
657                        setEditable(true);
658                }
659
660                try {
661                        Node node = new EasyParser().load(filePath);
662                        applyText(node);
663                        changedLabel.setText("");
664                } catch (Exception e1) {
665                        throw new ConfigurationException("Invalid recipe file.", e1);
666                }
667
668        }
669
670        private void applyText(Node node) {
671                setTaskNode(node);
672
673                int caretPosition = fTaskText.getCaretPosition();
674                EasyUtils.removeTagId(node);
675
676                fTaskText.setOriginalText(node.getXMLText());
677                if (caretPosition < fTaskText.getDocument().getLength()) {
678                        fTaskText.setCaretPosition(caretPosition);
679                }
680                refreshTaskTree();
681        }
682
683        private void createEditors(Node[] editors) {
684                for (Node editorNode : editors) {
685                        String className = editorNode.getAttribute("class");
686                        if (className == null) {
687                                className = TextEditor.class.getName();
688                        }
689                        Class<?> filterClass;
690                        try {
691                                if (!className.startsWith(EDITOR_STD_PACKAGE)) {
692                                        className = EDITOR_STD_PACKAGE + className;
693                                }
694
695                                filterClass = Class.forName(className);
696                                Constructor<?> constructor = filterClass.getConstructor();
697
698                                String name = editorNode.getAttribute("name");
699                                String tabName = StringUtils.defaultIfEmpty(name, StringUtils.substringAfterLast(className, "."));
700
701                                JComponent editor = (JComponent) constructor.newInstance();
702                                if (editor instanceof TextEditor) {
703                                        if (fTaskText == null) {
704                                                setEditor(editorNode, (TextEditor) editor);
705                                        }
706                                } else if (editor instanceof Editor) {
707                                        ((Editor) editor).setEditorNode(editorNode);
708                                        ((Editor) editor).init(this);
709                                        createEditorPanel.addTab(tabName, editor);
710                                }
711
712                        } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException
713                                        | IllegalAccessException | IllegalArgumentException | InvocationTargetException
714                                        | CommandException e) {
715                                e.printStackTrace();
716                                JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
717                                                "The creation of the extended panel failed.\nError: " + ExceptionUtils.getRootCauseMessage(e));
718                        }
719                }
720
721                createEditorPanel.addChangeListener(e -> {
722                        restoreDivider();
723                });
724        }
725
726        private void setEditor(Node editorNode, TextEditor editor) {
727                ((TextEditor) editor).setEditorNode(editorNode);
728                JScrollPane scrollPane = new JScrollPane();
729                scrollPane.getViewport().add(editor);
730                editor.setEditable(editable);
731                createEditorPanel.insertTab(TASK_EDITOR, null, scrollPane, null, 1);
732                fTaskText = editor;
733        }
734
735        private void setEditable(boolean editable) {
736                this.editable = editable;
737                saveMenuItem.setEnabled(editable);
738                if (fTaskText != null) {
739                        fTaskText.setEditable(editable);
740                }
741        }
742
743        protected void refreshTaskTree() {
744                if (getTaskNode() != null) {
745                        fTreeVector = getTaskNode().getVector(true);
746
747                        DefaultMutableTreeNode root = new DefaultMutableTreeNode("root");
748                        DynamicUtilTreeNode.createChildren(root, fTreeVector);
749                        DefaultTreeModel model = new DefaultTreeModel(root, false);
750                        taskTree.setModel(model);
751
752                        taskTree.setEditable(false);
753                        taskTree.setEnabled(true);
754
755                        taskTree.setFont(font);
756                        taskTree.setForeground(ACTIVE_COLOR);
757                        for (int i = 0; i < taskTree.getRowCount(); i++) {
758                                taskTree.expandRow(i);
759                        }
760                }
761        }
762
763        @Override
764        public void changeVariable(String aAttribut, Object aValue) {
765        }
766
767        static class JBorderedPanel extends JPanel {
768                private static final long serialVersionUID = 1L;
769
770                public JBorderedPanel(Component aNorth, Component aWest, Component aCenter, Component aEast, Component aSouth) {
771                        setLayout(new BorderLayout());
772                        if (aNorth != null) {
773                                add(aNorth, BorderLayout.NORTH);
774                        }
775                        if (aWest != null) {
776                                add(aWest, BorderLayout.WEST);
777                        }
778                        if (aCenter != null) {
779                                add(aCenter, BorderLayout.CENTER);
780                        }
781                        if (aEast != null) {
782                                add(aEast, BorderLayout.EAST);
783                        }
784                        if (aSouth != null) {
785                                add(aSouth, BorderLayout.SOUTH);
786                        }
787                }
788        }
789
790        @Override
791        public void startCommand(int aNumberCommand) {
792                setRunButtonAction(false);
793                try {
794                        if (taskTree != null) {
795                                taskTree.setSelectionRow(aNumberCommand);
796                                long delay = getTraceDelay();
797                                if (delay > 0) {
798                                        try {
799                                                Thread.sleep(delay);
800                                        } catch (Exception e) {
801                                                Thread.currentThread().interrupt();
802                                        }
803                                }
804                        }
805                } catch (Exception e) {
806                        //
807                }
808        }
809
810        private long getTraceDelay() {
811                return (int) ((Math.pow(1.5, (double) (100 - speed.getValue()) / 4)) - 1);
812        }
813
814        @Override
815        public void aboutTest(String theTaskName, Node aCurrentAction) {
816                try {
817                        setAbout(theTaskName, aCurrentAction);
818                        aboutButtonPanel.setVisible(true);
819                } catch (Exception e) {
820                        getLogger().error("Error", e);
821                }
822        }
823
824        @Override
825        public void runCommandView(Properties params) {
826                String id = params.getProperty("name");
827                String title = params.getProperty("title");
828
829                String reuse = params.getProperty("reuse");
830                if ("true".equals(reuse)) {
831                        AbstractView thePPanel = (AbstractView) fPresentationPanels.get(id);
832                        if (thePPanel != null && thePPanel.isValid()) {
833                                return;
834                        }
835                }
836
837                createView(id, params, title);
838        }
839
840        private AbstractView createView(String name, Properties linkedMap, String title) {
841
842                if (title == null) {
843                        title = name;
844                }
845
846                String className = linkedMap.getProperty("type", "Text");
847
848                if (className.indexOf('.') < 0) {
849                        className = "com.ganteater.ae.desktop.view." + className;
850                }
851
852                Class<?> ppClass;
853                try {
854                        ppClass = Class.forName(className);
855                        Constructor<?> constructor = ppClass.getConstructor();
856                        AbstractView pPanel = (AbstractView) constructor.newInstance();
857                        pPanel.init(linkedMap, manager);
858
859                        fPresentationPanels.put(name, pPanel);
860                        fOutputTabbedPane.add(title, pPanel);
861
862                        fOutputTabbedPane.setSelectedComponent(pPanel);
863                        return pPanel;
864
865                } catch (Exception e) {
866                        throw new IllegalArgumentException(e);
867                }
868        }
869
870        @Override
871        public void outToView(Processor processor, Properties properties, Object value) {
872                String id = processor.replaceProperties((String) properties.get("view"));
873                if (id != null) {
874                        AbstractView panel = (AbstractView) fPresentationPanels.get(id);
875                        if (panel != null) {
876                                Properties params = panel.getParams();
877
878                                if (fOutputTabbedPane.getComponentZOrder(panel) < 0) {
879                                        fPresentationPanels.remove(id);
880                                        panel = null;
881                                }
882
883                                if (panel == null) {
884                                        createView(id, params, null);
885                                } else {
886                                        panel.out(value, properties);
887                                }
888                        }
889                }
890        }
891
892        public void removeActivePresentationPanel() {
893                int selectedIndex = fOutputTabbedPane.getSelectedIndex();
894
895                Component theComp = fOutputTabbedPane.getComponent(selectedIndex);
896                if (theComp instanceof AbstractView) {
897                        AbstractView thePPanel = (AbstractView) theComp;
898                        fPresentationPanels.remove(thePPanel.getName());
899                }
900
901                fOutputTabbedPane.remove(selectedIndex);
902                fLoggers.remove(findLogger(theComp));
903        }
904
905        int fNumberLog = 1;
906
907        private File baseDir;
908
909        public ILogger createLog(String aLogName, boolean mainLog) {
910
911                LogView loggPanel = findLogger(aLogName);
912
913                if (loggPanel == null) {
914                        if (aLogName == null || aLogName.length() == 0)
915                                aLogName = "Log #" + String.valueOf(fNumberLog++);
916                        loggPanel = new ListLogView(this, aLogName, mainLog);
917                        outputPaneAdd(loggPanel);
918                }
919
920                setLog(loggPanel);
921                return loggPanel;
922        }
923
924        public void setLog(ILogger log) {
925                super.setLog(log);
926        }
927
928        private LogView findLogger(String aLogName) {
929                if (aLogName == null && fLoggers.size() > 0) {
930                        return fLoggers.get(0);
931                }
932
933                int tabCount = fLoggers.size();
934                for (int i = 0; i < tabCount; i++) {
935                        LogView logger = (LogView) fLoggers.get(i);
936                        String name = logger.getName();
937                        if (name.equals(aLogName)) {
938                                return logger;
939                        }
940                }
941
942                return null;
943        }
944
945        private LogView findLogger(Component comp) {
946                int tabCount = fLoggers.size();
947                for (int i = 0; i < tabCount; i++) {
948                        LogView logger = (LogView) fLoggers.get(i);
949                        if (logger == comp) {
950                                return logger;
951                        }
952                }
953                return null;
954        }
955
956        @Override
957        public void errorInformation(Processor processor, Throwable exception, Node command) throws CommandException {
958                try {
959                        frame.errorInformation(processor, exception, command, notifyMeCheckBox.isSelected());
960                } catch (CommandException e) {
961                        throw e;
962                } catch (Throwable e) {
963                        throw new CommandException(e, processor, command);
964                }
965        }
966
967        class VarTableModel extends AbstractTableModel {
968                private static final long serialVersionUID = 1L;
969                private String[][] fRows;
970
971                public VarTableModel() throws Exception {
972                        Set<String> enumeration = getSystemVariables().keySet();
973                        fRows = new String[getSystemVariables().size()][2];
974                        int i = 0;
975                        for (String theName : enumeration) {
976                                String theValue = (String) getSystemVariables().get(theName);
977                                fRows[i][0] = theName;
978                                fRows[i][1] = theValue;
979                                i++;
980                        }
981                }
982
983                public int getColumnCount() {
984                        return 2;
985                }
986
987                public int getRowCount() {
988                        return getSystemVariables().size();
989                }
990
991                public Class<String> getColumnClass(int columnIndex) {
992                        return String.class;
993                }
994
995                public Object getValueAt(int row, int col) {
996                        return fRows[row][col];
997                }
998
999                public boolean isCellEditable(int rowIndex, int columnIndex) {
1000                        return columnIndex > 0;
1001                }
1002
1003                public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
1004                        if (columnIndex == 1) {
1005                                getSystemVariables().put(fRows[rowIndex][0], aValue);
1006                                fRows[rowIndex][1] = (String) aValue;
1007                        }
1008                }
1009
1010                public String getColumnName(int column) {
1011                        if (column == 0) {
1012                                return "Name";
1013                        } else {
1014                                return "Value";
1015                        }
1016                }
1017
1018        }
1019
1020        public void outputPaneAdd(LogView logPanel) {
1021                fLoggers.add(logPanel);
1022                LogView panel = logPanel;
1023                fOutputTabbedPane.add(logPanel.getName(), panel);
1024                fPresentationPanels.put(logPanel.getName(), logPanel);
1025                fOutputTabbedPane.setSelectedComponent(panel);
1026        }
1027
1028        @Override
1029        public void setActiveTest(String theActiveTest) throws CommandException {
1030                Node taskNode = getConfigNode();
1031                if (taskNode != null) {
1032                        Node[] editors = taskNode.getNodes(TASK_EDITOR);
1033                        createEditors(editors);
1034                }
1035                if (fTaskText == null) {
1036                        setEditor(null, new TextEditor());
1037                }
1038
1039                String fileName = manager.getTestPath(theActiveTest);
1040                if (fileName == null) {
1041                        throw new IllegalArgumentException("Task file is not found. Recipe: " + theActiveTest);
1042                }
1043
1044                setActiveTestFile(fileName);
1045                fTaskText.init(this);
1046
1047                taskNode = getTaskNode();
1048                if (taskNode != null) {
1049                        Node[] editors = taskNode.getNodes(TASK_EDITOR);
1050                        createEditors(editors);
1051                }
1052
1053        }
1054
1055        private void setActiveTestFile(String fileName) {
1056                openTaskFile(fileName);
1057                recipeFilePath = fileName;
1058
1059                boolean editable = new File(fTaskFile).exists();
1060
1061                setEditable(editable);
1062
1063                Node taskNode = getTaskNode();
1064                boolean c = taskNode != null && taskNode.findNode(ABOUT, null, null) != null;
1065                if (c) {
1066                        showAbout();
1067                }
1068
1069                restoreDivider();
1070        }
1071
1072        public void runTaskNode() {
1073                setRunButtonAction(false);
1074
1075                Thread thread = new Thread() {
1076                        public void run() {
1077                                try {
1078                                        runCode(false);
1079
1080                                } catch (Exception e) {
1081                                        e.printStackTrace();
1082                                } finally {
1083                                        setRunButtonAction(true);
1084                                }
1085                        }
1086                };
1087
1088                thread.start();
1089        }
1090
1091        public void runCode(boolean runSelectedCode) throws BadLocationException, CommandException {
1092
1093                File parentFile = SystemUtils.getUserDir();
1094                if (fTaskFile != null) {
1095                        parentFile = new File(fTaskFile).getParentFile();
1096                }
1097
1098                Processor processor;
1099                Node taskNode;
1100                Map<String, Object> hashtable;
1101
1102                if (!runSelectedCode) {
1103                        compileTask();
1104                        taskNode = getTaskNode();
1105                        processor = createProcessor();
1106                        hashtable = processor.startVariables;
1107
1108                } else {
1109                        String selectedText = fTaskText.getSelectedText();
1110                        if (StringUtils.isNotBlank(selectedText)) {
1111                                Node selectedNode = new EasyParser().getObject(selectedText);
1112                                boolean isValide = !"$Text".equals(selectedNode.getTag());
1113
1114                                if (!isValide) {
1115                                        JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "The selected code is invalid to run.");
1116                                        return;
1117                                }
1118                        }
1119
1120                        String code = fTaskText.getText(0, fTaskText.getSelectionStart());
1121                        code = StringUtils.substringAfterLast(code, "<Extern ");
1122                        if (!StringUtils.isEmpty(code)) {
1123                                code = "<Extern " + code;
1124                                selectedText = StringUtils.substringBefore(code, ">") + ">" + selectedText + "</Extern>";
1125                        }
1126
1127                        code = "<Task>" + selectedText + "</Task>";
1128                        taskNode = new EasyParser().getObject(code);
1129
1130                        processor = getProcessor();
1131                        hashtable = processor.getVariables();
1132                }
1133                taskNode.getVector(true);
1134
1135                if (taskNode.size() > 0 && StringUtils.isNotBlank(taskNode.get(0).toString())) {
1136                        processor.processTesting(taskNode, hashtable, parentFile);
1137                } else {
1138                        fTaskText.select(fTaskText.getCaretPosition(), fTaskText.getCaretPosition());
1139                }
1140                processor.getListener().endTask(false);
1141                endTask(false);
1142                setRunButtonAction(true);
1143        }
1144
1145        private void runProcessTreeLine() {
1146                TreePath[] selectedPaths = taskTree.getSelectionPaths();
1147                if (createEditorPanel.getSelectedIndex() == 0 && selectedPaths != null) {
1148                        Processor processor = getProcessor();
1149                        Node taskNode = new Node("Task");
1150                        setRunButtonAction(false);
1151                        for (TreePath path : selectedPaths) {
1152                                DefaultMutableTreeNode lastPathComponent = (DefaultMutableTreeNode) path.getLastPathComponent();
1153                                TreeVector userObject = (TreeVector) lastPathComponent.getUserObject();
1154                                Node node = userObject.getNode();
1155                                if ("Recipe".equals(node.getTag())) {
1156                                        taskNode = node;
1157                                        processor = createProcessor();
1158                                        Map<String, Object> hashtable = processor.startVariables;
1159                                } else {
1160                                        taskNode.add(node);
1161                                        processor = getProcessor();
1162                                }
1163                        }
1164                }
1165        }
1166
1167        private Processor createProcessor() {
1168                String attribute = getTaskNode().getAttribute("name");
1169                if (attribute == null || attribute.isEmpty())
1170                        attribute = getTaskNode().getAttribute("description");
1171
1172                ILogger createLog = createLog(attribute, true);
1173                setProcessor(null);
1174                File baseDir = this.baseDir != null ? this.baseDir : getManager().getStartDir();
1175                Processor processor = new BaseProcessor(getManager(), createLog, baseDir);
1176                processor.init(fConfigNode, getSystemVariables(), this, baseDir, createLog);
1177                processor.setTestListener(this);
1178
1179                setProcessor(processor);
1180                return processor;
1181        }
1182
1183        public void start(String name) throws CommandException {
1184                if (StringUtils.isNotBlank(name)) {
1185                        setActiveTest(name);
1186                        runTaskNode();
1187                }
1188                fRunMenuItem.setEnabled(false);
1189        }
1190
1191        public void setRunButtonAction(boolean runAction) {
1192                this.isRunning = !runAction;
1193                if (runAction) {
1194                        try {
1195                                fRunButton.setText("Run");
1196                                fRunButton.setToolTipText("Run");
1197                                fContinueMenuItem.setEnabled(false);
1198                                fRunMenuItem.setEnabled(true);
1199                                fStopMenuItem.setEnabled(false);
1200                                fPauseMenuItem.setEnabled(false);
1201                                lblTitle.setBorder(BorderFactory.createEmptyBorder());
1202                        } catch (Exception e) {
1203                                e.printStackTrace();
1204                        }
1205
1206                } else {
1207                        try {
1208                                fRunButton.setText("Stop");
1209                                fRunButton.setToolTipText("Stop");
1210                                fContinueMenuItem.setEnabled(false);
1211                                fRunMenuItem.setEnabled(false);
1212                                fStopMenuItem.setEnabled(true);
1213                                fPauseMenuItem.setEnabled(true);
1214                                lblTitle.setBorder(BorderFactory.createMatteBorder(0, 0, 2, 0, ACTIVE_COLOR));
1215                        } catch (Exception e) {
1216                                e.printStackTrace();
1217                        }
1218                }
1219        }
1220
1221        public void edit(String name) {
1222                ListLogView log = new ListLogView(this, name);
1223                setLog(log);
1224                outputPaneAdd(log);
1225                fRunMenuItem.setEnabled(true);
1226        }
1227
1228        public void create(String name) throws CommandException {
1229                ListLogView log = new ListLogView(this, name);
1230                setLog(log);
1231
1232                fRunMenuItem.setEnabled(true);
1233                Node node = new EasyParser().getObject("<Recipe name=\"" + name + "\">\n<!-- your recipe code -->\n</Recipe>");
1234
1235                Node confNode = getConfigNode();
1236                if (confNode != null) {
1237                        Node[] editors = confNode.getNodes(TASK_EDITOR);
1238                        createEditors(editors);
1239                }
1240
1241                if (fTaskText == null) {
1242                        setEditor(null, new TextEditor());
1243                }
1244
1245                applyText(node);
1246
1247                runTest(new Node[] { node });
1248                fContinueMenuItem.setEnabled(false);
1249                fTaskText.init(this);
1250        }
1251
1252        public String getPanelName() {
1253                Processor processor = getProcessor();
1254                return processor.getTestName();
1255        }
1256
1257        public void saveTask() throws IOException {
1258                String recipeName = getTaskNode().getAttribute("name");
1259                if (fTaskFile == null || !fTaskFile.startsWith("jar:")) {
1260
1261                        if (fTaskFile == null) {
1262                                FileDialog theFileDialog = new FileDialog(JOptionPane.getRootFrame(), "Save Recipe File",
1263                                                FileDialog.SAVE);
1264
1265                                if (directory == null) {
1266                                        theFileDialog.setDirectory(getFrame().getWorkspace().getWorkingDir().getAbsolutePath());
1267                                }
1268
1269                                if (getTaskNode() != null) {
1270                                        theFileDialog.setFile(recipeName + ".recipe");
1271                                }
1272                                theFileDialog.setVisible(true);
1273                                if (theFileDialog.getFile() == null)
1274                                        return;
1275
1276                                baseDir = new File(theFileDialog.getDirectory());
1277                                directory = theFileDialog.getDirectory();
1278                                fTaskFile = new File(theFileDialog.getDirectory() + theFileDialog.getFile()).getAbsolutePath();
1279                        }
1280
1281                        if (getTaskNode() != null) {
1282                                File file = new File(fTaskFile);
1283                                String name = FilenameUtils.getBaseName(file.getName());
1284                                String oldName = getTaskNode().getAttribute("name");
1285                                if (!StringUtils.equals(name, oldName)) {
1286                                        File newfile = new File(file.getParent(), oldName + ".recipe");
1287                                        if (file.renameTo(newfile)) {
1288                                                file = newfile;
1289                                                fTaskFile = file.getAbsolutePath();
1290                                        }
1291                                }
1292
1293                                Node theNode = (Node) getTaskNode().clone();
1294                                String newName = theNode.getAttribute("name");
1295
1296                                AEWorkspace workspace = frame.getWorkspace();
1297                                workspace.removeTestPath(oldName);
1298                                workspace.setTestPath(newName, fTaskFile);
1299
1300                                EasyUtils.removeTagId(theNode);
1301
1302                                byte[] bytes = getTaskNode().getXMLText().getBytes("UTF-8");
1303
1304                                try (FileOutputStream theFileOutputStream = new FileOutputStream(fTaskFile)) {
1305                                        theFileOutputStream.write(bytes);
1306                                }
1307
1308                                setTitle(recipeName);
1309                        }
1310                }
1311        }
1312
1313        public void runTask() {
1314                try {
1315                        final String selectedText = fTaskText.getSelectedText();
1316
1317                        if (openIn && StringUtils.isBlank(selectedText)) {
1318                                reload();
1319                        }
1320
1321                        getManager().startTaskNotify(this);
1322                        runTaskNode();
1323
1324                } catch (Exception e) {
1325                        getLogger().error("Running failed.", e);
1326                }
1327        }
1328
1329        @Override
1330        public void criticalError(final CommandException exception, final Processor processor) {
1331                frame.criticalError(TaskEditor.this);
1332                lblTitle.setBorder(BorderFactory.createMatteBorder(0, 0, 2, 0, Color.RED));
1333
1334                if (isNotifyMe()) {
1335                        getFrame().fireBuzzAction(() -> super.criticalError(exception, processor));
1336                } else {
1337                        super.criticalError(exception, processor);
1338                }
1339        }
1340
1341        @Override
1342        public void checkFailure(final CommandException exception, final Processor processor) {
1343                frame.checkFailure(TaskEditor.this);
1344
1345                if (isNotifyMe()) {
1346                        getFrame().fireBuzzAction(() -> super.checkFailure(exception, processor));
1347                } else {
1348                        super.checkFailure(exception, processor);
1349                }
1350        }
1351
1352        public void closeTab() {
1353                frame.removeTab(TaskEditor.this);
1354        }
1355
1356        public void showAbout() {
1357                Node taskNode = getTaskNode();
1358                aboutTest(taskNode.getAttribute("name"), taskNode.findNode(ABOUT, null, null));
1359        }
1360
1361        public void showTaskTreePane() {
1362                CardLayout cl = (CardLayout) (createEditorPanel.getLayout());
1363                cl.show(createEditorPanel, TASK_TREE);
1364        }
1365
1366        public int getCaretPosition() {
1367                return fTaskText.getCaretPosition();
1368        }
1369
1370        public Point getMagicCaretPosition() {
1371                return fTaskText.getCaret().getMagicCaretPosition();
1372        }
1373
1374        public String getText() {
1375                return fTaskText.getText();
1376        }
1377
1378        public void replaceRange(String text, int i, int caretPosition2) {
1379                fTaskText.replaceRange(text, i, caretPosition2);
1380        }
1381
1382        public DialogPopupMenu contextHelp(DialogPopupMenu menu) {
1383                return menu;
1384        }
1385
1386        @Override
1387        public void runTest(Node testNode[]) {
1388                Node object = testNode[0];
1389                object.getVector(true);
1390                setTaskNode(object);
1391                refreshTaskTree();
1392                runTaskNode();
1393        }
1394
1395        public AEFrame getFrame() {
1396                return frame;
1397        }
1398
1399        public void pause() {
1400                fRunMenuItem.setEnabled(false);
1401                fContinueMenuItem.setEnabled(true);
1402                fPauseMenuItem.setEnabled(false);
1403
1404                setMessage(" Suspended execution ...");
1405                fTitleTest.setForeground(Color.YELLOW.darker());
1406                lblTitle.setBorder(BorderFactory.createMatteBorder(0, 0, 2, 0, Color.YELLOW));
1407        }
1408
1409        @Override
1410        public void resume() {
1411                fRunMenuItem.setEnabled(false);
1412                fContinueMenuItem.setEnabled(false);
1413                fPauseMenuItem.setEnabled(true);
1414
1415                setMessage("");
1416                fTitleTest.setForeground(Color.GRAY.darker());
1417                lblTitle.setBorder(BorderFactory.createMatteBorder(0, 0, 2, 0, ACTIVE_COLOR));
1418        }
1419
1420        public boolean isRunning() {
1421                return isRunning;
1422        }
1423
1424        public TextEditor getEditor() {
1425                return fTaskText;
1426        }
1427
1428        public void select() {
1429                getFrame().setSelectedComponent(getMainPanel());
1430        }
1431
1432        @Override
1433        public void setTaskNode(Node taskNode) {
1434                super.setTaskNode(taskNode);
1435                String aName = getTaskName() + ".notifyMe";
1436                String defaultNotify = AEWorkspace.getInstance().getDefaultUserConfiguration("notifyMe", "true");
1437                boolean notify = Boolean
1438                                .parseBoolean(AEWorkspace.getInstance().getDefaultUserConfiguration(aName, defaultNotify));
1439                notifyMeCheckBox.setSelected(notify);
1440        }
1441
1442        public boolean isNotifyMe() {
1443                return notifyMeCheckBox.isSelected();
1444        }
1445
1446}