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