Statistics
| Revision:

gvsig-scripting / org.gvsig.scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.swing / org.gvsig.scripting.swing.impl / src / main / java / org / gvsig / scripting / swing / impl / composer / DefaultJScriptingComposer.java @ 1200

History | View | Annotate | Download (100 KB)

1
package org.gvsig.scripting.swing.impl.composer;
2

    
3
import java.awt.BorderLayout;
4
import java.awt.Color;
5
import java.awt.Cursor;
6
import java.awt.Dialog;
7
import java.awt.Dimension;
8
import java.awt.Font;
9
import java.awt.event.ActionEvent;
10
import java.awt.event.ActionListener;
11
import java.awt.event.KeyEvent;
12
import java.awt.event.MouseAdapter;
13
import java.awt.event.MouseEvent;
14
import java.beans.PropertyChangeEvent;
15
import java.beans.PropertyChangeListener;
16
import java.io.File;
17
import java.util.ArrayList;
18
import java.util.Collection;
19
import java.util.Date;
20
import java.util.HashMap;
21
import java.util.HashSet;
22
import java.util.Iterator;
23
import java.util.LinkedHashMap;
24
import java.util.List;
25
import java.util.Map;
26
import java.util.Set;
27
import javax.swing.AbstractAction;
28
import javax.swing.Action;
29
import static javax.swing.Action.ACCELERATOR_KEY;
30
import static javax.swing.Action.ACTION_COMMAND_KEY;
31
import javax.swing.BorderFactory;
32
import javax.swing.JButton;
33
import javax.swing.JComponent;
34
import javax.swing.JLabel;
35
import javax.swing.JMenuBar;
36
import javax.swing.JMenuItem;
37
import javax.swing.JOptionPane;
38
import javax.swing.JPanel;
39
import javax.swing.JPopupMenu;
40
import javax.swing.JScrollPane;
41
import javax.swing.JSplitPane;
42
import javax.swing.JTabbedPane;
43
import javax.swing.JTable;
44
import javax.swing.JToolBar;
45
import javax.swing.KeyStroke;
46
import javax.swing.ListSelectionModel;
47
import javax.swing.SwingConstants;
48
import javax.swing.SwingUtilities;
49
import javax.swing.UIManager;
50
import javax.swing.event.AncestorEvent;
51
import javax.swing.event.AncestorListener;
52
import javax.swing.event.ChangeEvent;
53
import javax.swing.event.ChangeListener;
54
import javax.swing.event.ListSelectionEvent;
55
import javax.swing.event.ListSelectionListener;
56
import javax.swing.table.DefaultTableModel;
57
import javax.swing.table.TableModel;
58
import javax.swing.text.JTextComponent;
59
import org.apache.commons.io.FileUtils;
60
import org.apache.commons.io.IOCase;
61
import org.apache.commons.io.filefilter.FileFilterUtils;
62
import org.fife.rsta.ui.GoToDialog;
63
import org.fife.rsta.ui.search.FindDialog;
64
import org.fife.rsta.ui.search.ReplaceDialog;
65
import org.fife.rsta.ui.search.SearchEvent;
66
import org.fife.rsta.ui.search.SearchListener;
67
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
68
import org.fife.ui.rtextarea.SearchContext;
69
import org.fife.ui.rtextarea.SearchEngine;
70
import org.fife.ui.rtextarea.SearchResult;
71
import org.gvsig.installer.swing.api.SwingInstallerLocator;
72
import org.gvsig.installer.swing.api.SwingInstallerManager;
73
import org.gvsig.installer.swing.api.packagebuilder.PackageBuildder;
74
import org.gvsig.scripting.CompileErrorException;
75
import org.gvsig.scripting.ExecuteErrorException;
76
import org.gvsig.scripting.ScriptingBaseScript;
77
import org.gvsig.scripting.ScriptingErrorException;
78
import org.gvsig.scripting.ScriptingFolder;
79
import org.gvsig.scripting.ScriptingManager;
80
import org.gvsig.scripting.ScriptingNotification;
81
import org.gvsig.scripting.ScriptingScript;
82
import org.gvsig.scripting.ScriptingUnit;
83
import org.gvsig.scripting.swing.api.JCodeEditor;
84
import org.gvsig.scripting.swing.api.JEditor;
85
import org.gvsig.scripting.swing.api.JScriptingBrowser;
86
import org.gvsig.scripting.swing.api.JScriptingBrowser.BrowserActionEvent;
87
import org.gvsig.scripting.swing.api.JScriptingComposer;
88
import static org.gvsig.scripting.swing.api.JScriptingComposer.DOCKED_PROBLEMS;
89
import org.gvsig.scripting.swing.api.JScriptingComposer.Dock.DockedPanel;
90
import org.gvsig.scripting.swing.api.JScriptingComposer.Problems;
91
import org.gvsig.scripting.swing.api.JScriptingComposer.Problems.Problem;
92
import org.gvsig.scripting.swing.api.JScriptingConsole;
93
import org.gvsig.scripting.swing.api.JScriptingLauncher;
94
import org.gvsig.scripting.swing.api.ScriptingUIManager;
95
import org.gvsig.scripting.swing.api.ScriptingUIManager.MenuEntry;
96
import org.gvsig.scripting.swing.api.SyntaxtHighlightTextComponent.UpdateCaretPositionActionEvent;
97
import org.gvsig.scripting.swing.impl.DefaultJScriptingBrowser;
98
import org.gvsig.scripting.swing.impl.DefaultJScriptingConsole;
99
import org.gvsig.scripting.swing.impl.DefaultScriptingUIManager;
100
import org.gvsig.scripting.swing.impl.JDialogContent;
101
import org.gvsig.scripting.swing.impl.composer.DefaultJScriptingComposer.DefaultProblems.ProblemsTableMode.DefaultProblem;
102
import org.gvsig.scripting.swing.impl.composer.editors.ScriptUnitEditor;
103
import org.gvsig.tools.ToolsLocator;
104
import org.gvsig.tools.i18n.I18nManager;
105
import org.gvsig.tools.observer.Observable;
106
import org.gvsig.tools.observer.Observer;
107
import org.gvsig.tools.packageutils.PackageInfo;
108
import org.gvsig.tools.packageutils.PackageManager;
109
import org.gvsig.tools.packageutils.Version;
110
import org.gvsig.tools.swing.api.ActionListenerSupport;
111
import org.gvsig.tools.swing.api.Component;
112
import org.gvsig.tools.swing.api.ToolsSwingLocator;
113
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
114
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
115
import org.slf4j.Logger;
116
import org.slf4j.LoggerFactory;
117

    
118
@SuppressWarnings("UseSpecificCatch")
119
public class DefaultJScriptingComposer extends JPanel implements JScriptingComposer, Observer, ActionListener {
120

    
121
    /**
122
     *
123
     */
124
    private static final long serialVersionUID = 1L;
125

    
126
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultJScriptingComposer.class);
127

    
128
    public static final int CLOSE_ACTION = 1;
129

    
130
    private final ScriptingUIManager uimanager;
131
    private final ScriptingManager manager;
132
    private final ClassLoader loader;
133

    
134
    private JSplitPane mainPanel;
135
    private Dock dock;
136

    
137
    private Map<String, ToolEntry> menus;
138
    private JMenuBar menuBar;
139

    
140
    private Map<String, ToolEntry> tools;
141
    private JToolBar toolBar;
142

    
143
    private StatusBar statusBar;
144

    
145
    private FindDialog findDialog;
146
    private ReplaceDialog replaceDialog;
147
    private GoToDialog gotoDialog;
148

    
149
    private ActionListener defaultActionlistener = null;
150

    
151
    private Set<ChangeListener> changeEditorListeners = null;
152
    private ScriptingScript mainScript;
153

    
154
    private class GoToLineAction extends AbstractAction {
155

    
156
        private static final long serialVersionUID = -7353913671104893812L;
157

    
158
        @SuppressWarnings("OverridableMethodCallInConstructor")
159
        public GoToLineAction() {
160
            super(uimanager.getTranslation("go_to_line_Xhorizontal_ellipsisX"));
161
            int c = getToolkit().getMenuShortcutKeyMask();
162
            putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_L, c));
163
            putValue(ACTION_COMMAND_KEY, "GotoLine");
164
        }
165

    
166
        @Override
167
        public void actionPerformed(ActionEvent e) {
168
            JEditor editor = getCurrentEditor();
169
            if (!(editor instanceof JCodeEditor)) {
170
                return;
171
            }
172
            JCodeEditor codeEditor = (JCodeEditor) editor;
173
            if (findDialog.isVisible()) {
174
                findDialog.setVisible(false);
175
            }
176
            if (replaceDialog.isVisible()) {
177
                replaceDialog.setVisible(false);
178
            }
179
            gotoDialog.setMaxLineNumberAllowed(codeEditor.getLineCount());
180
            gotoDialog.setVisible(true);
181
            int line = gotoDialog.getLineNumber();
182

    
183
            if (line > 0) {
184
                codeEditor.selectLine(line);
185
            }
186
        }
187

    
188
        @Override
189
        public boolean isEnabled() {
190
            DockedPanel panel = dock.getSelected(Dock.DOCK_CENTER);
191
            return panel != null && panel.getComponent() instanceof JCodeEditor;
192
        }
193
    }
194

    
195
    private class ShowFindDialogAction extends AbstractAction {
196

    
197
        private static final long serialVersionUID = -7840632153011361661L;
198

    
199
        @SuppressWarnings("OverridableMethodCallInConstructor")
200
        public ShowFindDialogAction() {
201
            super(uimanager.getTranslation("find_Xhorizontal_ellipsisX"));
202
            int c = getToolkit().getMenuShortcutKeyMask();
203
            putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F, c));
204
            putValue(ACTION_COMMAND_KEY, "ShowFindDialog");
205
        }
206

    
207
        @Override
208
        public void actionPerformed(ActionEvent e) {
209
            if (replaceDialog.isVisible()) {
210
                replaceDialog.setVisible(false);
211
            }
212
            findDialog.setVisible(true);
213
        }
214

    
215
        @Override
216
        public boolean isEnabled() {
217
            DockedPanel panel = dock.getSelected(Dock.DOCK_CENTER);
218
            return panel != null && panel.getComponent() instanceof JCodeEditor;
219
        }
220
    }
221

    
222
    private class ShowReplaceDialogAction extends AbstractAction {
223

    
224
        private static final long serialVersionUID = 7209167803487996060L;
225

    
226
        @SuppressWarnings("OverridableMethodCallInConstructor")
227
        public ShowReplaceDialogAction() {
228
            super(uimanager.getTranslation("replace_Xhorizontal_ellipsisX"));
229
            int c = getToolkit().getMenuShortcutKeyMask();
230
            putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_H, c));
231
            putValue(ACTION_COMMAND_KEY, "ShowReplaceDialog");
232
        }
233

    
234
        @Override
235
        public void actionPerformed(ActionEvent e) {
236
            if (findDialog.isVisible()) {
237
                findDialog.setVisible(false);
238
            }
239
            replaceDialog.setVisible(true);
240
        }
241

    
242
        @Override
243
        public boolean isEnabled() {
244
            DockedPanel panel = dock.getSelected(Dock.DOCK_CENTER);
245
            return panel != null && panel.getComponent() instanceof JCodeEditor;
246
        }
247
    }
248

    
249
    private class LauncherAction extends AbstractAction {
250

    
251
        private static final long serialVersionUID = 6257776255757689286L;
252

    
253
        @SuppressWarnings("OverridableMethodCallInConstructor")
254
        public LauncherAction() {
255
            super(uimanager.getTranslation("Launcher"));
256
            putValue(ACTION_COMMAND_KEY, "ShowLauncher");
257
        }
258

    
259
        @Override
260
        public void actionPerformed(ActionEvent e) {
261
            getWindowManager().showWindow(
262
                    uimanager.createLauncher().asJComponent(),
263
                    uimanager.getTranslation("Scripting_Launcher"),
264
                    WindowManager.MODE.TOOL
265
            );
266
        }
267

    
268
    }
269

    
270
    private class SelectAllAction extends AbstractAction {
271

    
272
        private static final long serialVersionUID = 2725549699989067383L;
273

    
274
        @SuppressWarnings("OverridableMethodCallInConstructor")
275
        public SelectAllAction() {
276
            super(uimanager.getTranslation("Select_all"));
277
            putValue(Action.SMALL_ICON, uimanager.getIcon("scripting-edit-select-all"));
278
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Select_all"));
279
            putValue(ACTION_COMMAND_KEY, "DocumentSelectAll");
280
        }
281

    
282
        @Override
283
        public void actionPerformed(ActionEvent e) {
284
            currentScriptSelectAll();
285
        }
286

    
287
        @Override
288
        public boolean isEnabled() {
289
            DockedPanel panel = dock.getSelected(Dock.DOCK_CENTER);
290
            return panel != null && panel.getComponent() instanceof JCodeEditor;
291
        }
292

    
293
    }
294

    
295
    private class PackageScriptAction extends AbstractAction {
296

    
297
        private static final long serialVersionUID = 8020393562984016720L;
298

    
299
        @SuppressWarnings("OverridableMethodCallInConstructor")
300
        public PackageScriptAction() {
301
            super(uimanager.getTranslation("_Package_script"));
302
            putValue(Action.SMALL_ICON, uimanager.getIcon("scripting-package"));
303
            putValue(ACTION_COMMAND_KEY, "PackageScript");
304
        }
305

    
306
        @Override
307
        public void actionPerformed(ActionEvent e) {
308
            createScriptPackage();
309
        }
310

    
311
    }
312

    
313
    private class AboutAction extends AbstractAction {
314

    
315
        private static final long serialVersionUID = -4928359535828269502L;
316

    
317
        @SuppressWarnings("OverridableMethodCallInConstructor")
318
        public AboutAction() {
319
            super(uimanager.getTranslation("About_scripts_editor"));
320
            putValue(Action.SMALL_ICON, uimanager.getIcon("scripting-about"));
321
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("About_scripts_editor"));
322
            putValue(ACTION_COMMAND_KEY, "About");
323
        }
324

    
325
        @Override
326
        public void actionPerformed(ActionEvent e) {
327
            getWindowManager().showWindow(
328
                    getAboutUsDialog(),
329
                    uimanager.getTranslation("About_scripts_editor"),
330
                    WindowManager.MODE.WINDOW
331
            );
332
        }
333

    
334
    }
335

    
336
    private class CutAction extends AbstractAction {
337

    
338
        private static final long serialVersionUID = -8549655706085425411L;
339

    
340
        @SuppressWarnings("OverridableMethodCallInConstructor")
341
        public CutAction() {
342
            super(uimanager.getTranslation("Cut"));
343
            putValue(Action.SMALL_ICON, uimanager.getIcon("scripting-edit-cut"));
344
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Cut"));
345
            putValue(ACTION_COMMAND_KEY, "DocumentCut");
346
        }
347

    
348
        @Override
349
        public void actionPerformed(ActionEvent e) {
350
            currentScriptCut();
351
        }
352

    
353
        @Override
354
        public boolean isEnabled() {
355
            DockedPanel panel = dock.getSelected(Dock.DOCK_CENTER);
356
            return panel != null && panel.getComponent() instanceof JCodeEditor;
357
        }
358

    
359
    }
360

    
361
    private class CopyAction extends AbstractAction {
362

    
363
        private static final long serialVersionUID = -6870773810752024874L;
364

    
365
        @SuppressWarnings("OverridableMethodCallInConstructor")
366
        public CopyAction() {
367
            super(uimanager.getTranslation("Copy"));
368
            putValue(Action.SMALL_ICON, uimanager.getIcon("scripting-edit-copy"));
369
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Copy"));
370
            putValue(ACTION_COMMAND_KEY, "DocumentCopy");
371
        }
372

    
373
        @Override
374
        public void actionPerformed(ActionEvent e) {
375
            currentScriptCopy();
376
        }
377

    
378
        @Override
379
        public boolean isEnabled() {
380
            DockedPanel panel = dock.getSelected(Dock.DOCK_CENTER);
381
            return panel != null && panel.getComponent() instanceof JCodeEditor;
382
        }
383

    
384
    }
385

    
386
    private class PasteAction extends AbstractAction {
387

    
388
        private static final long serialVersionUID = -5829551248494873061L;
389

    
390
        @SuppressWarnings("OverridableMethodCallInConstructor")
391
        public PasteAction() {
392
            super(uimanager.getTranslation("Paste"));
393
            putValue(Action.SMALL_ICON, uimanager.getIcon("scripting-edit-paste"));
394
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Paste"));
395
            putValue(ACTION_COMMAND_KEY, "DocumentPaste");
396
        }
397

    
398
        @Override
399
        public void actionPerformed(ActionEvent e) {
400
            currentScriptPaste();
401
        }
402

    
403
        @Override
404
        public boolean isEnabled() {
405
            DockedPanel panel = dock.getSelected(Dock.DOCK_CENTER);
406
            return panel != null && panel.getComponent() instanceof JCodeEditor;
407
        }
408

    
409
    }
410

    
411
    private class ExitAction extends AbstractAction {
412

    
413
        private static final long serialVersionUID = 9165363564675325925L;
414

    
415
        @SuppressWarnings("OverridableMethodCallInConstructor")
416
        public ExitAction() {
417
            super(uimanager.getTranslation("Close"));
418
            putValue(Action.SMALL_ICON, uimanager.getIcon("scripting-exit"));
419
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Close"));
420
            putValue(ACTION_COMMAND_KEY, "CloseComposer");
421
        }
422

    
423
        @Override
424
        public void actionPerformed(ActionEvent e) {
425
            closeAllScripts();
426
            closeWindow();
427
            if (defaultActionlistener != null) {
428
                ActionEvent event = new ActionEvent(this, CLOSE_ACTION, "close");
429
                defaultActionlistener.actionPerformed(event);
430
            }
431
        }
432

    
433
    }
434

    
435
    private class SaveAction extends AbstractAction {
436

    
437
        private static final long serialVersionUID = -870379961486387727L;
438

    
439
        @SuppressWarnings("OverridableMethodCallInConstructor")
440
        public SaveAction() {
441
            super(uimanager.getTranslation("Save"));
442
            int c = getToolkit().getMenuShortcutKeyMask();
443
            putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S, c));
444
            putValue(Action.SMALL_ICON, uimanager.getIcon("scripting-doc-save"));
445
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Save"));
446
            putValue(ACTION_COMMAND_KEY, "DocumentSave");
447
        }
448

    
449
        @Override
450
        public void actionPerformed(ActionEvent e) {
451
            currentScriptSave();
452
        }
453

    
454
        @Override
455
        public boolean isEnabled() {
456
            DockedPanel panel = dock.getSelected(Dock.DOCK_CENTER);
457
            return panel != null;
458
        }
459
    }
460

    
461
    private class RunAction extends AbstractAction {
462

    
463
        private static final long serialVersionUID = 4851968883766990149L;
464

    
465
        @SuppressWarnings("OverridableMethodCallInConstructor")
466
        public RunAction() {
467
            super(uimanager.getTranslation("Run"));
468
            int c = getToolkit().getMenuShortcutKeyMask();
469
//            putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0));
470
            putValue(Action.SMALL_ICON, uimanager.getIcon("scripting-run"));
471
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Run"));
472
            putValue(ACTION_COMMAND_KEY, "DocumentRun");
473
        }
474

    
475
        @Override
476
        public void actionPerformed(ActionEvent e) {
477
            currentScriptExecute();
478
        }
479

    
480
        @Override
481
        public boolean isEnabled() {
482
            DockedPanel panel = dock.getSelected(Dock.DOCK_CENTER);
483
            return panel != null;
484
        }
485
    }
486

    
487
    private class RunMainAction extends AbstractAction {
488

    
489
        private static final long serialVersionUID = 4851968883766990149L;
490

    
491
        @SuppressWarnings("OverridableMethodCallInConstructor")
492
        public RunMainAction() {
493
            super(uimanager.getTranslation("_Run_main_script"));
494
            int c = getToolkit().getMenuShortcutKeyMask();
495
//            putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0));
496
            putValue(Action.SMALL_ICON, uimanager.getIcon("scripting-run-main"));
497
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("_Run_main_script"));
498
            putValue(ACTION_COMMAND_KEY, "RunMainScript");
499
        }
500

    
501
        @Override
502
        public void actionPerformed(ActionEvent e) {
503
            mainScriptExecute();
504
        }
505

    
506
        @Override
507
        public boolean isEnabled() {
508
            return true;
509
        }
510
    }
511

    
512
    private class SelectMainScriptAction extends AbstractAction {
513

    
514
        private static final long serialVersionUID = 4851968883766990149L;
515

    
516
        @SuppressWarnings("OverridableMethodCallInConstructor")
517
        public SelectMainScriptAction() {
518
            super(uimanager.getTranslation("_Select_main_script"));
519
            int c = getToolkit().getMenuShortcutKeyMask();
520
//            putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0));
521
            putValue(Action.SMALL_ICON, uimanager.getIcon("scripting-select-main"));
522
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("_Select_main_script"));
523
            putValue(ACTION_COMMAND_KEY, "SelectMainScript");
524
        }
525

    
526
        @Override
527
        public void actionPerformed(ActionEvent e) {
528
            mainScriptSelect();
529
        }
530

    
531
        @Override
532
        public boolean isEnabled() {
533
            return true;
534
        }
535
    }
536

    
537
    private class SaveAndRunAction extends AbstractAction {
538

    
539
        private static final long serialVersionUID = 4851968883766990149L;
540

    
541
        @SuppressWarnings("OverridableMethodCallInConstructor")
542
        public SaveAndRunAction() {
543
            super(uimanager.getTranslation("Save and run"));
544
            int c = getToolkit().getMenuShortcutKeyMask();
545
            putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0));
546
            putValue(Action.SMALL_ICON, uimanager.getIcon("scripting-save-and-run"));
547
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Save and run"));
548
            putValue(ACTION_COMMAND_KEY, "DocumentSaveAndRun");
549
        }
550

    
551
        @Override
552
        public void actionPerformed(ActionEvent e) {
553
            currentScriptSave();
554
            currentScriptExecute();
555
        }
556

    
557
        @Override
558
        public boolean isEnabled() {
559
            DockedPanel panel = dock.getSelected(Dock.DOCK_CENTER);
560
            return panel != null;
561
        }
562
    }
563

    
564
    private class CloseAllAction extends AbstractAction {
565

    
566
        private static final long serialVersionUID = 3385142920283598457L;
567

    
568
        @SuppressWarnings("OverridableMethodCallInConstructor")
569
        public CloseAllAction() {
570
            super(uimanager.getTranslation("Close_all_documents"));
571
            putValue(Action.SMALL_ICON, uimanager.getIcon("scripting-doc-closeall"));
572
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Close_all_documents"));
573
            putValue(ACTION_COMMAND_KEY, "CloseAll");
574
        }
575

    
576
        @Override
577
        public void actionPerformed(ActionEvent e) {
578
            closeAllScripts();
579
        }
580

    
581
        @Override
582
        public boolean isEnabled() {
583
            DockedPanel panel = dock.getSelected(Dock.DOCK_CENTER);
584
            return panel != null;
585
        }
586

    
587
    }
588

    
589
    private class CloseDocumentAction extends AbstractAction {
590

    
591
        private static final long serialVersionUID = 4152188500446249755L;
592

    
593
        @SuppressWarnings("OverridableMethodCallInConstructor")
594
        public CloseDocumentAction() {
595
            super(uimanager.getTranslation("Close_document"));
596
            putValue(Action.SMALL_ICON, uimanager.getIcon("scripting-doc-close"));
597
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Close_current_tab"));
598
            putValue(ACTION_COMMAND_KEY, "DocumentClose");
599
        }
600

    
601
        @Override
602
        public void actionPerformed(ActionEvent e) {
603
            currentScriptClose();
604
        }
605

    
606
        @Override
607
        public boolean isEnabled() {
608
            DockedPanel panel = dock.getSelected(Dock.DOCK_CENTER);
609
            return panel != null;
610
        }
611

    
612
    }
613

    
614
    private class ShowConsoleAction extends AbstractAction {
615

    
616
        private static final long serialVersionUID = -7545333555439711068L;
617

    
618
        @SuppressWarnings("OverridableMethodCallInConstructor")
619
        public ShowConsoleAction() {
620
            super(uimanager.getTranslation("Console"));
621
            putValue(Action.SMALL_ICON, uimanager.getIcon("scripting-show-console"));
622
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Show_console_panel"));
623
            putValue(ACTION_COMMAND_KEY, "ShowConsole");
624
        }
625

    
626
        @Override
627
        public void actionPerformed(ActionEvent e) {
628
            addConsolePanel();
629
        }
630
    }
631

    
632
    private class ShowProblemsAction extends AbstractAction {
633

    
634
        private static final long serialVersionUID = 5276964996914550830L;
635

    
636
        @SuppressWarnings("OverridableMethodCallInConstructor")
637
        public ShowProblemsAction() {
638
            super(uimanager.getTranslation("Problems"));
639
            putValue(Action.SMALL_ICON, uimanager.getIcon("scripting-show-problems"));
640
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Show_problems_panel"));
641
            putValue(ACTION_COMMAND_KEY, "ShowProblems");
642
        }
643

    
644
        @Override
645
        public void actionPerformed(ActionEvent e) {
646
            addProblemsPanel();
647
        }
648
    }
649

    
650
    private class ShowProjectsAction extends AbstractAction {
651

    
652
        private static final long serialVersionUID = 5873598740133693862L;
653

    
654
        @SuppressWarnings("OverridableMethodCallInConstructor")
655
        public ShowProjectsAction() {
656
            super(uimanager.getTranslation("Projects"));
657
            putValue(Action.SMALL_ICON, uimanager.getIcon("scripting-show-projects"));
658
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Show_projects_panel"));
659
            putValue(ACTION_COMMAND_KEY, "ShowProjects");
660
        }
661

    
662
        @Override
663
        public void actionPerformed(ActionEvent e) {
664
            addProjectsPanel();
665
        }
666
    }
667

    
668
    private class NewDocumentAction extends AbstractAction {
669

    
670
        private static final long serialVersionUID = 7889613706183211620L;
671

    
672
        @SuppressWarnings("OverridableMethodCallInConstructor")
673
        public NewDocumentAction() {
674
            super(uimanager.getTranslation("New"));
675
            putValue(Action.SMALL_ICON, uimanager.getIcon("scripting-doc-add"));
676
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("New"));
677
            putValue(ACTION_COMMAND_KEY, "DocumentNew");
678
        }
679

    
680
        @Override
681
        public void actionPerformed(ActionEvent e) {
682
            try {
683
                scriptNew();
684
            } catch (Exception e1) {
685
                LOGGER.warn("Can't create a new document", e1);
686
            }
687
        }
688

    
689
    }
690
    
691
    private class NewFolderAction extends AbstractAction {
692

    
693
        private static final long serialVersionUID = 7889613706183211620L;
694

    
695
        @SuppressWarnings("OverridableMethodCallInConstructor")
696
        public NewFolderAction() {
697
            super(uimanager.getTranslation("New folder"));
698
            putValue(Action.SMALL_ICON, uimanager.getIcon("scripting-folder-add"));
699
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("New folder"));
700
            putValue(ACTION_COMMAND_KEY, "FolderNew");
701
        }
702

    
703
        @Override
704
        public void actionPerformed(ActionEvent e) {
705
            try {
706
                FolderNew();
707
            } catch (Exception e1) {
708
                LOGGER.warn("Can't create a new folder", e1);
709
            }
710
        }
711

    
712
    }    
713

    
714
    private class ProjectEditAction extends AbstractAction {
715

    
716
        private static final long serialVersionUID = -3393464285985649074L;
717

    
718
        @SuppressWarnings("OverridableMethodCallInConstructor")
719
        public ProjectEditAction() {
720
            super(uimanager.getTranslation("Edit"));
721
            putValue(Action.SMALL_ICON, uimanager.getIcon("scripting-doc-edit"));
722
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Open_edition_mode"));
723
            putValue(ACTION_COMMAND_KEY, "DocumentEdit");
724
        }
725

    
726
        @Override
727
        public void actionPerformed(ActionEvent e) {
728
            try {
729
                ScriptingUnit selectedItem = getLauncherSelectedUnit();
730
                if( uimanager.hasEditor(selectedItem) ) {
731
                    scriptEdit(selectedItem);
732
                }
733
            } catch (Exception e1) {
734
                LOGGER.warn("Can't edit document", e1);
735
            }
736
        }
737
    }
738

    
739
    private class ProjectRefreshAction extends AbstractAction {
740

    
741
        private static final long serialVersionUID = 1944121660002532563L;
742

    
743
        @SuppressWarnings("OverridableMethodCallInConstructor")
744
        public ProjectRefreshAction() {
745
            super(uimanager.getTranslation("Refresh"));
746
            putValue(Action.SMALL_ICON, uimanager.getIcon("scripting-refresh"));
747
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Refresh_directories"));
748
            putValue(ACTION_COMMAND_KEY, "ProjectsRefresh");
749
        }
750

    
751
        @Override
752
        public void actionPerformed(ActionEvent e) {
753
            refreshProjects();
754
        }
755

    
756
    }
757

    
758
    private class ProjectRenameAction extends AbstractAction {
759

    
760
        private static final long serialVersionUID = 7469858242486966790L;
761

    
762
        @SuppressWarnings("OverridableMethodCallInConstructor")
763
        public ProjectRenameAction() {
764
            super(uimanager.getTranslation("Rename"));
765
            putValue(Action.SMALL_ICON, uimanager.getIcon("scripting-doc-rename"));
766
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Set_file_properties"));
767
            putValue(ACTION_COMMAND_KEY, "Rename");
768
        }
769

    
770
        @Override
771
        public void actionPerformed(ActionEvent e) {
772
            try {
773
                scriptRename(getLauncherSelectedUnit());
774
            } catch (Exception e1) {
775
                LOGGER.warn("Can't rename document", e1);
776
            }
777
        }
778
    }
779

    
780
    private class ProjectMoveAction extends AbstractAction {
781

    
782
        private static final long serialVersionUID = -8857101021126773295L;
783

    
784
        @SuppressWarnings("OverridableMethodCallInConstructor")
785
        public ProjectMoveAction() {
786
            super(uimanager.getTranslation("Move"));
787
            putValue(Action.SMALL_ICON, uimanager.getIcon("scripting-doc-move"));
788
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Move_files"));
789
            putValue(ACTION_COMMAND_KEY, "Move");
790
        }
791

    
792
        @Override
793
        public void actionPerformed(ActionEvent e) {
794
            try {
795
                scriptMove(getLauncherSelectedUnit());
796
            } catch (Exception e1) {
797
                LOGGER.warn("Can't move document", e1);
798
            }
799
        }
800
    }
801

    
802
    private class ProjectDeleteAction extends AbstractAction {
803

    
804
        private static final long serialVersionUID = 9039455504757742743L;
805

    
806
        @SuppressWarnings("OverridableMethodCallInConstructor")
807
        public ProjectDeleteAction() {
808
            super(uimanager.getTranslation("Delete"));
809
            putValue(Action.SMALL_ICON, uimanager.getIcon("scripting-doc-remove"));
810
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Delete_selected_script"));
811
            putValue(ACTION_COMMAND_KEY, "Delete");
812
        }
813

    
814
        @Override
815
        public void actionPerformed(ActionEvent e) {
816
            try {
817
                scriptDelete(getLauncherSelectedUnit(), false);
818
            } catch (Exception e1) {
819
                LOGGER.warn("Can't delete document", e1);
820
            }
821
        }
822
    }
823

    
824
    /**
825
     * Instanciacion de un JComposer con todos sus elementos y acciones
826
     *
827
     * @param uimanager
828
     */
829
    public DefaultJScriptingComposer(final ScriptingUIManager uimanager) {
830
        loader = this.getClass().getClassLoader();
831
        this.uimanager = uimanager;
832
        this.manager = uimanager.getManager();
833
        synchronized(this.manager) {
834
            initComponents();
835
        }
836
    }
837

    
838
    @Override
839
    public JComponent asJComponent() {
840
        return this;
841
    }
842

    
843
    @Override
844
    public WindowManager getWindowManager() {
845
        return ((DefaultScriptingUIManager) (this.uimanager)).getWindowManager();
846
    }
847

    
848
    @Override
849
    public void setWindowManager(WindowManager windowsManager) {
850
        ((DefaultScriptingUIManager) (this.uimanager)).setWindowManager(windowsManager);
851
    }
852

    
853
    private void initComponents() {
854

    
855
        this.addAncestorListener(new AncestorListener() {
856

    
857
            @Override
858
            public void ancestorAdded(AncestorEvent event) {
859
                ((DefaultScriptingUIManager) uimanager).setActiveComposer(DefaultJScriptingComposer.this);
860
            }
861

    
862
            @Override
863
            public void ancestorRemoved(AncestorEvent event) {
864
                ((DefaultScriptingUIManager) uimanager).setActiveComposer(null);
865
            }
866

    
867
            @Override
868
            public void ancestorMoved(AncestorEvent event) {
869
            }
870
        });
871
        SearchListener findReplaceSearchListener = new FindReplaceSearchListener();
872

    
873
        findDialog = new FindDialog((Dialog) null, findReplaceSearchListener);
874
        replaceDialog = new ReplaceDialog((Dialog) null, findReplaceSearchListener);
875
        gotoDialog = new GoToDialog((Dialog) null);
876

    
877
        SearchContext searchContext = findDialog.getSearchContext();
878
        replaceDialog.setSearchContext(searchContext);
879

    
880
        this.menuBar = new JMenuBar();
881
        this.toolBar = new JToolBar();
882

    
883
        this.menus = new LinkedHashMap<>();
884
        this.tools = new LinkedHashMap<>();
885

    
886
        String _File = this.uimanager.getTranslation("File");
887
        String _Edit = this.uimanager.getTranslation("Edit");
888
        String _Projects = this.uimanager.getTranslation("Projects");
889
        String _Tools = this.uimanager.getTranslation("Tools");
890
        String _Help = this.uimanager.getTranslation("Help");
891
        String _View = this.uimanager.getTranslation("Show");
892

    
893
        this.addMenu(_File, null);
894
        this.addMenu(_File, new NewDocumentAction());
895
        this.addMenu(_File, new NewFolderAction());
896
        this.addMenuSeparator(_File);
897
        this.addMenu(_File, new CloseDocumentAction());
898
        this.addMenu(_File, new CloseAllAction());
899
        this.addMenuSeparator(_File);
900
        this.addMenu(_File, new SelectMainScriptAction());
901
        this.addMenu(_File, new RunMainAction());
902
        this.addMenu(_File, new RunAction());
903
        this.addMenu(_File, new SaveAndRunAction());
904
        this.addMenuSeparator(_File);
905
        this.addMenu(_File, new SaveAction());
906
        this.addMenuSeparator(_File);
907
        this.addMenu(_File, new ExitAction());
908

    
909
        this.addMenu(_Edit, null);
910
        this.addMenu(_Edit, new CutAction());
911
        this.addMenu(_Edit, new CopyAction());
912
        this.addMenu(_Edit, new PasteAction());
913
        this.addMenuSeparator(_Edit);
914
        this.addMenu(_Edit, new SelectAllAction());
915
        this.addMenuSeparator(_Edit);
916
        this.addMenu(_Edit, new ShowFindDialogAction());
917
        this.addMenu(_Edit, new ShowReplaceDialogAction());
918
        this.addMenu(_Edit, new GoToLineAction());
919

    
920
        this.addMenu(_View, null);
921
        this.addMenu(_View, new ShowProjectsAction());
922
        this.addMenu(_View, new ShowProblemsAction());
923
        this.addMenu(_View, new ShowConsoleAction());
924

    
925
        this.addMenu(_Projects, null);
926
        this.addMenu(_Projects, new ProjectEditAction());
927
        this.addMenuSeparator(_Projects);
928
        this.addMenu(_Projects, new ProjectRefreshAction());
929
        this.addMenuSeparator(_Projects);
930
        this.addMenu(_Projects, new ProjectRenameAction());
931
        this.addMenu(_Projects, new ProjectMoveAction());
932
        this.addMenu(_Projects, new ProjectDeleteAction());
933

    
934
        this.addMenu(_Tools, null);
935
        this.addMenu(_Tools, new LauncherAction());
936
        this.addMenuSeparator(_Tools);
937
        this.addMenu(_Tools, new PackageScriptAction());
938

    
939
        this.addMenu(_Help, null);
940
        this.addMenu(_Help, new AboutAction());
941

    
942
        this.addTool(new NewDocumentAction());
943
        this.addTool(new SaveAction());
944
        this.addTool(new CutAction());
945
        this.addTool(new CopyAction());
946
        this.addTool(new PasteAction());
947
        this.addTool(new RunMainAction());
948
        this.addTool(new RunAction());
949
        this.addTool(new SaveAndRunAction());
950

    
951
        JTabbedPaneClosable tabbedPanelLeft = new JTabbedPaneClosable(uimanager);
952
        JTabbedPaneClosable tabbedPanelBottom = new JTabbedPaneClosable(uimanager);
953
        JTabbedPaneClosable tabbedPanelCenter = new JTabbedPaneClosable(uimanager);
954

    
955
        tabbedPanelLeft.setTabPlacement(JTabbedPane.BOTTOM);
956
        tabbedPanelCenter.setPreferredSize(new Dimension(500, 300));
957
        tabbedPanelCenter.addChangeListener(new ChangeListener() {
958

    
959
            @Override
960
            public void stateChanged(ChangeEvent e) {
961
                updateMenusAndTools();
962
                try {
963
                    ((ScriptUnitEditor)((JTabbedPane)e.getSource()).getSelectedComponent()).getJTextComponent().requestFocusInWindow();
964
                } catch(Throwable th) {
965
                    LOGGER.debug("Can't set focus in the editor", th);
966
                }
967
            }
968
        });
969

    
970
        this.dock = new DefaultDock(
971
                tabbedPanelLeft,
972
                tabbedPanelBottom,
973
                tabbedPanelCenter
974
        );
975
        this.dock.addCloseListener(new ActionListener() {
976

    
977
            @Override
978
            public void actionPerformed(ActionEvent e) {
979
                DockedPanel panel = (DockedPanel) e.getSource();
980
                scriptClose(panel);
981
            }
982
        });
983
        //tabbedPanelBottom.setPreferredSize(new Dimension(450, 100));
984

    
985
        this.addProjectsPanel();
986
        this.addConsolePanel();
987
        this.addProblemsPanel();
988

    
989
        this.dock.select(DOCKED_CONSOLE);
990
        this.dock.select(DOCKED_PROJECTS);
991

    
992
        JSplitPane centerPanel = new JSplitPane(
993
                JSplitPane.VERTICAL_SPLIT,
994
                tabbedPanelCenter,
995
                tabbedPanelBottom
996
        );
997
        centerPanel.setResizeWeight(0.8);
998
        centerPanel.setOneTouchExpandable(true);
999

    
1000
        mainPanel = new JSplitPane(
1001
                JSplitPane.HORIZONTAL_SPLIT,
1002
                tabbedPanelLeft,
1003
                centerPanel
1004
        );
1005
        mainPanel.setOneTouchExpandable(true);
1006

    
1007
        statusBar = new DefaultStatusBar(uimanager);
1008

    
1009
        updateMenusAndTools();
1010

    
1011
        JPanel buttons = new JPanel();
1012
        buttons.setLayout(new BorderLayout());
1013
        buttons.add(BorderLayout.NORTH, this.menuBar);
1014
        buttons.add(BorderLayout.SOUTH, this.toolBar);
1015

    
1016
        this.setLayout(new BorderLayout());
1017
        this.add(BorderLayout.NORTH, buttons);
1018
        this.add(BorderLayout.CENTER, mainPanel);
1019
        this.add(BorderLayout.SOUTH, statusBar.asJComponent());
1020
        this.setPreferredSize(new Dimension(800, 600));
1021
    }
1022

    
1023
    public void addMenu(String text, Action action) {
1024
        String name;
1025
        if (action == null) {
1026
            name = String.format("Menu%x", new Date().getTime());
1027
        } else {
1028
            name = (String) action.getValue(Action.ACTION_COMMAND_KEY);
1029
        }
1030
        this.menus.put(name, new ToolEntry(name, action, text));
1031
    }
1032

    
1033
    public void addMenuSeparator(String text) {
1034
        String name = String.format("Sep%x", new Date().getTime());
1035
        this.menus.put(name, new ToolEntry(name, null, text + "/-"));
1036
    }
1037

    
1038
    public void addTool(Action action) {
1039
        String name = (String) action.getValue(Action.ACTION_COMMAND_KEY);
1040
        this.tools.put(name, new ToolEntry(name, action));
1041
    }
1042

    
1043
    public void updateMenusAndTools() {
1044

    
1045
        this.menuBar.removeAll();
1046
        this.toolBar.removeAll();
1047
        for (MenuEntry entry : this.uimanager.getComposerMenus()) {
1048
            this.addMenu(entry.getText(), entry.getAction());
1049
        }
1050
        for (Action action : this.uimanager.getComposerTools()) {
1051
            this.addTool(action);
1052
        }
1053

    
1054
        MenuBarHelper menuBarHelper = new MenuBarHelper(menuBar);
1055
        for (ToolEntry entry : menus.values()) {
1056
            try {
1057
                JMenuItem menu = menuBarHelper.add(entry.getText(), entry.getAction(), this);
1058
                entry.setComponent(menu);
1059
            } catch(Throwable th) {
1060
                LOGGER.warn("Can't add entry '"+entry.getName()+"' to the toolbar.", th);
1061
            }
1062
        }
1063

    
1064
        for (ToolEntry entry : tools.values()) {
1065
            try {
1066
                JButton button = new ButtonWithContext(entry.getAction());
1067
                this.toolBar.add(button);
1068
                entry.setComponent(button);
1069
            } catch(Throwable th) {
1070
                LOGGER.warn("Can't add entry '"+entry.getName()+"' to the toolbar.", th);
1071
            }
1072
            
1073
        }
1074
        this.menuBar.repaint();
1075
        this.toolBar.repaint();
1076
    }
1077

    
1078
    public void addProblemsPanel() {
1079
        DockedPanel panel = this.dock.get(DOCKED_PROBLEMS);
1080
        if (panel != null) {
1081
            panel.select();
1082
            return;
1083
        }
1084
        final Problems problems = new DefaultProblems(this.uimanager);
1085
        problems.addListSelectionListener(new ListSelectionListener() {
1086

    
1087
            @Override
1088
            public void valueChanged(ListSelectionEvent e) {
1089
                if (e.getValueIsAdjusting()) {
1090
                    return;
1091
                }
1092
                Problem row = problems.getSelect();
1093
                if (row != null) {
1094
                    JEditor editor;
1095
                    int lineno = row.getLineNumber();
1096
                    if( row.getResource() == null ) {
1097
                        editor = getCurrentEditor();
1098
                    } else {
1099
                        String id = row.getResource().getAbsolutePath();
1100
                        DockedPanel panel = getDock().get(id);
1101
                        if( panel == null ) {
1102
                            ScriptingBaseScript script = manager.getScript(row.getResource());
1103
                            scriptEdit(script);
1104
                            panel = getDock().get(id);
1105
                            if( panel == null ) {
1106
                                LOGGER.warn("Can't load script '"+id+"'.");
1107
                                return;
1108
                            }
1109
                        } 
1110
                        panel.select();
1111
                        editor = (JEditor) panel.getComponent();
1112
                    }
1113
                    if ( editor instanceof JCodeEditor) {
1114
                        ((JCodeEditor) editor).gotoline(lineno);
1115
                    }
1116
                }
1117
            }
1118
        });
1119
        this.dock.add(
1120
                DOCKED_PROBLEMS,
1121
                this.uimanager.getTranslation("Problems"),
1122
                problems,
1123
                Dock.DOCK_BOTTOM
1124
        );
1125
        this.dock.select(DOCKED_PROBLEMS);
1126
    }
1127

    
1128
    public void addConsolePanel() {
1129
        DockedPanel panel = this.dock.get(DOCKED_CONSOLE);
1130
        if (panel != null) {
1131
            panel.select();
1132
            return;
1133
        }
1134
        DefaultJScriptingConsole console = new DefaultJScriptingConsole(true);
1135
        this.dock.add(
1136
                DOCKED_CONSOLE,
1137
                this.uimanager.getTranslation("Console"),
1138
                console,
1139
                Dock.DOCK_BOTTOM
1140
        );
1141
        this.dock.select(DOCKED_CONSOLE);
1142
    }
1143

    
1144
    public void addProjectsPanel() {
1145
        DockedPanel panel = this.dock.get(DOCKED_PROJECTS);
1146
        if (panel != null) {
1147
            panel.select();
1148
            return;
1149
        }
1150
        JScriptingLauncher launcher = uimanager.createLauncher();
1151
        launcher.addDefaultActionListener(new ActionListener() {
1152

    
1153
            @Override
1154
            public void actionPerformed(ActionEvent e) {
1155
                BrowserActionEvent e2 = (BrowserActionEvent) e;
1156
                switch (e.getID()) {
1157
                    case JScriptingBrowser.DEFAULT_ACTION:
1158
                        ScriptingUnit unit = e2.getUnit();
1159
                        if( unit instanceof ScriptingFolder ) {
1160
                            return;
1161
                        }
1162
                        if( uimanager.hasEditor(unit) ) {
1163
                            scriptEdit(unit);
1164
                        }
1165
                        break;
1166
                    case JScriptingBrowser.DROPDOWN_ACTION:
1167
                    case JScriptingBrowser.SELECTION_ACTION:
1168
                        break;
1169
                }
1170
            }
1171
        });
1172
        launcher.asJComponent().setPreferredSize(new Dimension(200, 450));
1173

    
1174
        this.dock.add(
1175
                DOCKED_PROJECTS,
1176
                this.uimanager.getTranslation("Projects"),
1177
                launcher,
1178
                Dock.DOCK_LEFT
1179
        );
1180
        this.dock.select(DOCKED_PROJECTS);
1181
    }
1182

    
1183
    @Override
1184
    public Problems getProblems() {
1185
        DockedPanel panel = this.dock.get(DOCKED_PROBLEMS);
1186
        if (panel == null) {
1187
            return null;
1188
        }
1189
        return (Problems) panel.getComponent();
1190
    }
1191

    
1192
    @Override
1193
    public JScriptingLauncher getProjects() {
1194
        DockedPanel panel = this.dock.get(DOCKED_PROJECTS);
1195
        if (panel == null) {
1196
            return null;
1197
        }
1198
        return (JScriptingLauncher) panel.getComponent();
1199
    }
1200

    
1201
    @Override
1202
    public Dock getDock() {
1203
        return dock;
1204
    }
1205

    
1206
    @Override
1207
    public JScriptingConsole getConsole() {
1208
        DockedPanel panel = this.dock.get(DOCKED_CONSOLE);
1209
        if (panel == null) {
1210
            return null;
1211
        }
1212
        return (JScriptingConsole) panel.getComponent();
1213
    }
1214

    
1215
    @Override
1216
    public void addChangeEditorListener(ChangeListener listener) {
1217
        if (this.changeEditorListeners == null) {
1218
            this.changeEditorListeners = new HashSet<>();
1219
        }
1220
        this.changeEditorListeners.add(listener);
1221
    }
1222
    
1223
    @Override
1224
    public void removeChangeEditorListener(ChangeListener listener) {
1225
        if (this.changeEditorListeners == null) {
1226
            return;
1227
        }
1228
        this.changeEditorListeners.remove(listener);
1229
    }
1230

    
1231
    public void fireChangeEditor(ChangeEvent e) {
1232
        if (this.changeEditorListeners == null) {
1233
            return;
1234
        }
1235
        for (ChangeListener listener : this.changeEditorListeners) {
1236
            try {
1237
                listener.stateChanged(e);
1238
            } catch (Throwable th) {
1239

    
1240
            }
1241
        }
1242
    }
1243

    
1244
    private void createScriptPackage() {
1245
        I18nManager i18nManager = ToolsLocator.getI18nManager();
1246
        SwingInstallerManager installerManager = SwingInstallerLocator.getSwingInstallerManager();
1247
        PackageBuildder packager = installerManager.createPackagerPanel(
1248
                ScriptingManager.INSTALLER_PROVIDER_NAME,
1249
                manager.getRootUserFolder(),
1250
                manager.getPackagesFolder()
1251
        );
1252
        packager.addBeforePackingListener(new PackageBuildder.BeforePackingListener() {
1253
            @Override
1254
            public void perfrom(PackageBuildder builder) {
1255
                // Clean $py.class files before packing
1256
                Collection<File> files = FileUtils.listFiles(
1257
                        builder.getFolderToPackaging(),
1258
                        FileFilterUtils.suffixFileFilter("$py.class", IOCase.INSENSITIVE), 
1259
                        FileFilterUtils.trueFileFilter()
1260
                );
1261
                if( files!=null ) {
1262
                    for (File file : files) {
1263
                        FileUtils.deleteQuietly(file);
1264
                    }
1265
                }
1266
            }
1267
        }); 
1268
                
1269
        PackageInfo packageInfo = packager.getPackageInfo();
1270
        packageInfo.setArchitecture(PackageManager.ARCH.ALL);
1271
        packageInfo.setJavaVM(PackageManager.JVM.J1_7);
1272
        packageInfo.setOperatingSystem(PackageManager.OS.ALL);
1273
        packageInfo.setOfficial(false);
1274
        packageInfo.setState(PackageManager.STATE.TESTING);
1275
        packageInfo.setType(ScriptingManager.INSTALLER_PROVIDER_NAME);
1276
        Version version = ToolsLocator.getPackageManager().createVersion();
1277
        version.parse("1.0.0");
1278
        packageInfo.setVersion(version);
1279
        this.uimanager.showWindow(
1280
                (JPanel) packager.asJComponent(),
1281
                i18nManager.getTranslation("_Scripting_packager")
1282
        );
1283
    }
1284

    
1285
//    private void setEditorSelection(String name, int line) {
1286
//        for (int i = 0; i < scriptEditors.getTabCount(); i++) {
1287
//
1288
//            if (((JEditor) scriptEditors.getComponent(i)).getScript().getId().equals(name)) {
1289
//                scriptEditors.setSelectedIndex(i);
1290
//
1291
//                JCodeEditor editor = ((JCodeEditor) scriptEditors.getComponent(i));
1292
//                editor.selectLine(line);
1293
//            }
1294
//        }xxxxxxxxxxxxxxxxxxxxxxxx
1295
//    }
1296
    public void addDefaultActionListener(ActionListener actionlistener) {
1297
        this.defaultActionlistener = actionlistener;
1298
    }
1299

    
1300
    /**
1301
     * Funci?n para obtener el elemento seleccionado del Launcher
1302
     *
1303
     * @return Selected ScriptingUnit on the tree
1304
     */
1305
    public ScriptingUnit getLauncherSelectedUnit() {
1306
        JScriptingBrowser browser = this.getCurrentBrowser();
1307
        ScriptingUnit unit = browser.getSelectedNode();
1308
        return unit;
1309
    }
1310
    
1311
    public void msgbox(String title, String msg) {
1312
      msgbox(title, msg, JOptionPane.INFORMATION_MESSAGE);
1313
    }
1314
    
1315
    public void msgbox(final String title, final String msg, final int type) {
1316
      if( SwingUtilities.isEventDispatchThread() ) {
1317
        try {
1318
          SwingUtilities.invokeAndWait(() -> {
1319
            msgbox(title, msg, type);
1320
          });
1321
        } catch (Exception ex) {
1322
        }
1323
        return;
1324
      }
1325
      JOptionPane.showMessageDialog(this, msg, title, type);
1326
    }
1327
    
1328
    private JScriptingBrowser getCurrentBrowser() {
1329
        JScriptingLauncher launcher = this.getProjects();
1330
        JScriptingBrowser browser = launcher.getSelectedBrowser();
1331
        return browser;
1332
    }
1333

    
1334
//    /**
1335
//     * Lanza la ejecuci?n de un ScriptingBaseScript
1336
//     *
1337
//     * @param unit
1338
//     */
1339
//    private void scriptExecute(ScriptingUnit unit) {
1340
//        if (unit instanceof ScriptingBaseScript) {
1341
//            ((ScriptingBaseScript) unit).run();
1342
//        }
1343
//    }
1344

    
1345
    public void scriptEdit(ScriptingUnit unit) {
1346
        String id = unit.getFile().getAbsolutePath();
1347
        DockedPanel x = this.dock.get(id);
1348
        if (x != null) {
1349
            x.select();
1350
            return;
1351
        }
1352
        final JEditor editor = this.uimanager.createEditor(unit);
1353
        if (editor == null) {
1354
            JOptionPane.showMessageDialog(null, this.uimanager.getTranslation("Error_opening_in_edition_mode"), this.uimanager.getTranslation("Error_opening_in_edition_mode_title"), JOptionPane.INFORMATION_MESSAGE);
1355
            return;
1356
        }
1357
        final DockedPanel panel = this.dock.add(id, unit.getName(), editor, Dock.DOCK_CENTER);
1358
        panel.select();
1359
        editor.addChangeListener(new PropertyChangeListener() {
1360

    
1361
            @Override
1362
            public void propertyChange(PropertyChangeEvent evt) {
1363
                panel.setModified(true);
1364
                fireChangeEditor(new ChangeEvent(editor));
1365
            }
1366
        });
1367
        if (editor instanceof JCodeEditor) {
1368
            ((JCodeEditor) editor).addUpdateCaretPositionActionListener(new ActionListener() {
1369

    
1370
                @Override
1371
                public void actionPerformed(ActionEvent e) {
1372
                    UpdateCaretPositionActionEvent event = (UpdateCaretPositionActionEvent) e;
1373
                    getStatusbar().setPosition(
1374
                            event.getLine(),
1375
                            event.getColumn()
1376
                    );
1377
                }
1378
            });
1379
        }
1380
        ScriptingUnit xx = editor.getUnit();
1381
        if (xx instanceof ScriptingScript ) {
1382
            ((ScriptingScript)xx).addObserver(this);
1383
        }
1384
    }
1385

    
1386
    /**
1387
     * Ventana para creaci?n de nuevos ScriptingBaseScripts
1388
     *
1389
     * @throws Exception
1390
     *
1391
     */
1392
    public void scriptNew() throws Exception {
1393
        this.unitNew(false);
1394
    }
1395

    
1396
    public void FolderNew() throws Exception {
1397
        this.unitNew(true);
1398
    }
1399

    
1400
    public void unitNew(boolean folder) throws Exception {
1401
        JNewScriptModel model = new JNewScriptModel(manager);
1402
        model.setSelectionPath(this.getCurrentBrowser().getSelectionPath());
1403
        JDialogContent dialog = new JDialogContent(
1404
                uimanager,
1405
                "document-new",
1406
                this.uimanager.getTranslation("New_Script"),
1407
                this.uimanager.getTranslation("New_Script_Description"),
1408
                new JNewScriptPanel(uimanager, model,folder)
1409
        );
1410
        dialog.showDialog();
1411
        if (model.getAction() == JNewScriptModel.ACTION_ACCEPT) {
1412
            model.validate();
1413
            ScriptingUnit unit = this.manager.createUnit(
1414
                    model.getType(),
1415
                    manager.getFolder(model.getPath()),
1416
                    model.getName(),
1417
                    model.getLanguage()
1418
            );
1419
            if (unit instanceof ScriptingBaseScript) {
1420
                this.scriptEdit((ScriptingBaseScript) unit);
1421
            }
1422

    
1423
            this.refreshProjects();
1424
        }
1425
    }
1426

    
1427

    
1428
    public void scriptClose(DockedPanel panel) {
1429
        if (!panel.isModified()) {
1430
            panel.remove();
1431
            return;
1432
        }
1433
        panel.select();
1434
        I18nManager i18nManager = ToolsLocator.getI18nManager();
1435
        int respuesta = JOptionPane.showConfirmDialog(
1436
                this,
1437
                i18nManager.getTranslation("_The_script_XscriptnameX_is_modified",
1438
                        new String[]{panel.getTitle()})
1439
                + "\n\n"
1440
                + i18nManager.getTranslation("_Do_you_want_to_save_changes_XquestionX"),
1441
                i18nManager.getTranslation("_Save_changes_XquestionX"),
1442
                JOptionPane.YES_NO_CANCEL_OPTION
1443
        );
1444
        switch (respuesta) {
1445
            case JOptionPane.YES_OPTION:
1446
                currentScriptSave();
1447
                panel.remove();
1448
                break;
1449
            case JOptionPane.NO_OPTION:
1450
                panel.remove();
1451
                break;
1452
            default:
1453
            case JOptionPane.CANCEL_OPTION:
1454
                break;
1455
        }
1456
    }
1457

    
1458
    public void scriptMove(final ScriptingUnit theUnit) throws Exception {
1459
        if (theUnit.getParent() == null) {
1460
            JOptionPane.showMessageDialog(null, "Please, select first the file to move on the tree directory", "Error", JOptionPane.ERROR_MESSAGE);
1461
        } else {
1462
            JMoveScriptModel model = new JMoveScriptModel(manager, theUnit);
1463
            JDialogContent dialog = new JDialogContent(
1464
                    uimanager,
1465
                    "format-indent-more",
1466
                    this.uimanager.getTranslation("Move") + " '" + theUnit.getName() + "' " + this.uimanager.getTranslation("script_filesystem"),
1467
                    this.uimanager.getTranslation("move_desc"),
1468
                    new JMoveScriptPanel(uimanager, model)
1469
            );
1470
            dialog.showDialog();
1471
            if (model.getAction() == JMoveScriptModel.ACTION_ACCEPT) {
1472
                model.validate();
1473
                ScriptingFolder folderDest = manager.getFolder(model.getMoveTo());
1474
                if (model.getUnit().move(folderDest)) {
1475
                    JOptionPane.showMessageDialog(null,
1476
                            this.uimanager.getTranslation("Moving_succesfully"),
1477
                            this.uimanager.getTranslation("Success"), JOptionPane.INFORMATION_MESSAGE);
1478
                    this.refreshProjects();
1479
                } else {
1480
                    JOptionPane.showMessageDialog(null,
1481
                            this.uimanager.getTranslation("Error_moving"),
1482
                            this.uimanager.getTranslation("Error"), JOptionPane.ERROR_MESSAGE);
1483
                }
1484
            }
1485
        }
1486

    
1487
    }
1488

    
1489
    public void scriptRename(ScriptingUnit theUnit) throws Exception {
1490
        if (theUnit.getParent() == null) {
1491
            JOptionPane.showMessageDialog(null,
1492
                    this.uimanager.getTranslation("Select_first"),
1493
                    this.uimanager.getTranslation("Error"), JOptionPane.ERROR_MESSAGE);
1494
        } else {
1495
            JRenameModel model = new JRenameModel(manager, theUnit);
1496
            JDialogContent dialog = new JDialogContent(
1497
                    uimanager,
1498
                    "preferences-system",
1499
                    this.uimanager.getTranslation("Rename") + " '" + theUnit.getName() + "' " + this.uimanager.getTranslation("script_filesystem"),
1500
                    this.uimanager.getTranslation("rename_desc"),
1501
                    new JRenamePanel(uimanager, model)
1502
            );
1503
            dialog.showDialog();
1504
            if (model.getAction() == JRenameModel.ACTION_ACCEPT) {
1505
                model.validate();
1506
                ScriptingUnit unit = model.getUnit();
1507
                if (!model.getNewName().equals(unit.getId())) {
1508
                    if (unit.rename(model.getNewName())) {
1509
                        JOptionPane.showMessageDialog(null,
1510
                                this.uimanager.getTranslation("Rename_succesfully"),
1511
                                this.uimanager.getTranslation("Success"), JOptionPane.INFORMATION_MESSAGE);
1512
                        this.refreshProjects();
1513
                    } else {
1514
                        JOptionPane.showMessageDialog(null,
1515
                                this.uimanager.getTranslation(this.uimanager.getTranslation("Error_renaming")),
1516
                                this.uimanager.getTranslation("Error"), JOptionPane.ERROR_MESSAGE);
1517
                    }
1518
                    if (unit instanceof ScriptingScript) {
1519
                        ((ScriptingScript) unit).save();
1520
                    }
1521
                }
1522
            }
1523
        }
1524
    }
1525

    
1526
    @Override
1527
    public JPanel getAboutUsDialog() {
1528
        return new JDialogContent(uimanager,
1529
                "system-users",
1530
                this.uimanager.getTranslation("About_us"),
1531
                this.uimanager.getTranslation("About_us_title"),
1532
                new JDefaultDialog(uimanager, this, uimanager.getAboutManager().getAboutPanel()));
1533
    }
1534

    
1535
    public void scriptDelete(final ScriptingUnit unit, boolean isRecursive) {
1536
        int n = 0;
1537
        if (!isRecursive) {
1538
            n = JOptionPane.showConfirmDialog(
1539
                    this.getRootPane(),
1540
                    this.uimanager.getTranslation("Delete_all_message"),
1541
                    this.uimanager.getTranslation("Delete_all_title"),
1542
                    JOptionPane.YES_NO_OPTION);
1543
        }
1544
        if (n == 0) {
1545
            //Si es un folder borramos recursivamente sus subdirectorios
1546
            if (unit instanceof ScriptingFolder) {
1547
                List<ScriptingUnit> subunits
1548
                        = ((ScriptingFolder) unit).getUnits();
1549
                Iterator<ScriptingUnit> it = subunits.iterator();
1550
                while (it.hasNext()) {
1551
                    ScriptingUnit subunit = it.next();
1552
                    scriptDelete(subunit, true);
1553
                }
1554
            }
1555
            // Por ?ltimo borramos el nodo seleccionado
1556
            unit.getParent().remove(unit);
1557
            this.refreshProjects();
1558

    
1559
        }
1560
    }
1561

    
1562
    /**
1563
     * Funci?n que cierra la pesta?a de edici?n actual
1564
     *
1565
     */
1566
    public void currentScriptClose() {
1567
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1568
        if (panel == null) {
1569
            return;
1570
        }
1571
        scriptClose(panel);
1572
    }
1573

    
1574
    /**
1575
     * Close all editor tabs of the composer
1576
     */
1577
    public void closeAllScripts() {
1578
        List<DockedPanel> modifiedPanels = new ArrayList<>();
1579
        List<DockedPanel> toRemove = new ArrayList<>();
1580

    
1581
        for (DockedPanel panel : this.dock) {
1582
            if (Dock.DOCK_CENTER.equals(panel.getAlign())) {
1583
                if (panel.isModified()) {
1584
                    modifiedPanels.add(panel);
1585
                } else {
1586
                    toRemove.add(panel);
1587
                }
1588
            }
1589
        }
1590
        if (modifiedPanels.isEmpty() && toRemove.isEmpty()) {
1591
            return;
1592
        }
1593
        int action = JOptionPane.showConfirmDialog(
1594
                this,
1595
                this.uimanager.getTranslation("projects_modified"),
1596
                this.uimanager.getTranslation("projects_modified_title"),
1597
                JOptionPane.YES_NO_CANCEL_OPTION
1598
        );
1599
        switch (action) {
1600
            case JOptionPane.CANCEL_OPTION:
1601
                return;
1602
            case JOptionPane.YES_OPTION:
1603
                for (DockedPanel panel : modifiedPanels) {
1604
                    JEditor editor = (JEditor) panel.getComponent();
1605
                    if (editor.getUnit()!= null) {
1606
                        editor.getUnit().setSaved(true);
1607
                    }
1608
                    editor.save();
1609
                    toRemove.add(panel);
1610
                }
1611
                break;
1612
            case JOptionPane.NO_OPTION:
1613
                for (DockedPanel panel : modifiedPanels) {
1614
                    JEditor editor = (JEditor) panel.getComponent();
1615
                    if (editor.getUnit() != null) {
1616
                        editor.getUnit().setSaved(true);
1617
                    }
1618
                    toRemove.add(panel);
1619
                }
1620
        }
1621
        if( toRemove.isEmpty() ) {
1622
            return;
1623
        }
1624
        for (DockedPanel panel : toRemove) {
1625
            panel.remove();
1626
        }
1627
    }
1628

    
1629
    /**
1630
     * Funci?n que ejecuta el ScriptingBaseScript de la pesta?a actual
1631
     *
1632
     */
1633
    @SuppressWarnings("UseSpecificCatch")
1634
    public void currentScriptExecute() {
1635
        ScriptingScript script = this.getCurrentScript();
1636
        if (script != null) {
1637
            Problems problems = this.getProblems();
1638
            if (problems != null) {
1639
                problems.removeAll();
1640
            }
1641
            JScriptingConsole console = this.getConsole();
1642
            if (console == null) {
1643
                addConsolePanel();
1644
            } else {
1645
                console.clear();
1646
            }
1647
            script.addObserver(this);
1648
            script.addStdoutWriter(this.getConsole().getOutputWriter());
1649
            script.addStderrWriter(this.getConsole().getErrorsWriter());
1650
            try {
1651
                script.compile();
1652
                script.runAsTask(null);
1653
            } catch (Throwable e) {
1654
                LOGGER.info("Can't execute script", e);
1655
            }
1656
        }
1657
    }
1658

    
1659
    /**
1660
     * Funciones de 'cortar', 'copiar', 'pegar' y 'seleccionar todo' para los
1661
     * JEditors
1662
     *
1663
     */
1664
    public void currentScriptCopy() {
1665
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1666
        if (panel.getComponent().asJComponent() instanceof JCodeEditor) {
1667
            JCodeEditor editor = (JCodeEditor) panel.getComponent().asJComponent();
1668
            editor.getJTextComponent().copy();
1669
        }
1670
    }
1671

    
1672
    public void currentScriptCut() {
1673
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1674
        if (panel.getComponent().asJComponent() instanceof JCodeEditor) {
1675
            JCodeEditor editor = (JCodeEditor) panel.getComponent().asJComponent();
1676
            editor.getJTextComponent().cut();
1677
            panel.setModified(true);
1678
        }
1679
    }
1680

    
1681
    public void currentScriptPaste() {
1682
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1683
        if (panel.getComponent().asJComponent() instanceof JCodeEditor) {
1684
            JCodeEditor editor = (JCodeEditor) panel.getComponent().asJComponent();
1685
            editor.getJTextComponent().paste();
1686
            panel.setModified(true);
1687
        }
1688
    }
1689

    
1690
    public void currentScriptSelectAll() {
1691
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1692
        if (panel.getComponent().asJComponent() instanceof JCodeEditor) {
1693
            JCodeEditor editor = (JCodeEditor) panel.getComponent().asJComponent();
1694
            editor.getJTextComponent().selectAll();
1695
        }
1696
    }
1697

    
1698
    /**
1699
     * Funci?n para el guardado del ScriptingBaseScript de la pesta?a actual
1700
     *
1701
     */
1702
    public void currentScriptSave() {
1703
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1704
        if (panel.getComponent().asJComponent() instanceof JEditor) {
1705
            JEditor editor = (JEditor) panel.getComponent().asJComponent();
1706
            editor.save();
1707
            panel.setModified(false);
1708
        }
1709
    }
1710

    
1711
    public ScriptingScript getMainScript() {
1712
        return this.mainScript;
1713
    }
1714
    
1715
    public void mainScriptSelect(ScriptingScript script) {
1716
        this.mainScript = script;
1717
    }
1718
    
1719
    public void mainScriptSelect() {
1720
        JScriptingBrowser browser = new DefaultJScriptingBrowser(uimanager, this.manager.getUserFolder());
1721
        browser.asJComponent().setPreferredSize(new Dimension(400, 450));
1722
        WindowManager_v2 winmgr = (WindowManager_v2) uimanager.getWindowManager();
1723
        org.gvsig.tools.swing.api.windowmanager.Dialog dialog = winmgr.createDialog(
1724
                browser.asJComponent(),
1725
                "Select main script",
1726
                null, 
1727
                WindowManager_v2.BUTTONS_OK_CANCEL
1728
        );
1729
        dialog.addActionListener(new ActionListener() {
1730
            @Override
1731
            public void actionPerformed(ActionEvent e) {
1732
                if( dialog.getAction()==WindowManager_v2.BUTTON_OK ) {
1733
                    ScriptingUnit script = browser.getSelectedNode();
1734
                    if( script instanceof ScriptingScript ) {
1735
                        mainScriptSelect((ScriptingScript)script);
1736
                    } else {
1737
                        JOptionPane.showMessageDialog(
1738
                                DefaultJScriptingComposer.this, 
1739
                                uimanager.getTranslation("_The_selected_script_is_invalid"), 
1740
                                uimanager.getTranslation("_Warning"), 
1741
                                JOptionPane.INFORMATION_MESSAGE
1742
                        );
1743
                    }
1744
                }
1745
            }
1746
        });
1747
        dialog.show(WindowManager.MODE.DIALOG);
1748
    }
1749

    
1750
    public void mainScriptExecute() {
1751
        ScriptingScript script = this.getMainScript();
1752
        if (script == null) {
1753
            int r = JOptionPane.showConfirmDialog(
1754
                    DefaultJScriptingComposer.this, 
1755
                    uimanager.getTranslation("_Main_script_is_not_selected")+"\n"+
1756
                            uimanager.getTranslation("_Do_you_want_to_select_one_and_execute_it"), 
1757
                    uimanager.getTranslation("_Warning"), 
1758
                    JOptionPane.YES_NO_OPTION
1759
            );
1760
            if( r != JOptionPane.YES_OPTION ) {
1761
                return;
1762
            }
1763
            mainScriptSelect();
1764
            script = this.getMainScript();
1765
            if( script == null ) {
1766
                return;
1767
            }
1768
        }
1769
        Problems problems = this.getProblems();
1770
        if (problems != null) {
1771
            problems.removeAll();
1772
        }
1773
        JScriptingConsole console = this.getConsole();
1774
        if (console == null) {
1775
            addConsolePanel();
1776
        } else {
1777
            console.clear();
1778
        }
1779
        script.addObserver(this);
1780
        script.addStdoutWriter(this.getConsole().getOutputWriter());
1781
        script.addStderrWriter(this.getConsole().getErrorsWriter());
1782
        try {
1783
            script.setCode(null);
1784
            script.compile();
1785
            script.runAsTask(null);
1786
        } catch (Throwable e) {
1787
            LOGGER.info("Can't execute script", e);
1788
        }
1789
    }
1790
    
1791
    @Override
1792
    public JEditor getCurrentEditor() {
1793
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1794
        if (panel == null) {
1795
            return null;
1796
        }
1797
        if (panel.getComponent().asJComponent() instanceof JEditor) {
1798
            return (JEditor) panel.getComponent().asJComponent();
1799
        }
1800
        return null;
1801
    }
1802

    
1803
    @Override
1804
    public ScriptingScript getCurrentScript() {
1805
        JEditor editor = this.getCurrentEditor();
1806
        if (editor == null) {
1807
            return null;
1808
        }
1809
        ScriptingUnit unit = editor.getUnit();
1810
        if( unit instanceof ScriptingScript ) {
1811
            return (ScriptingScript) unit;
1812
        }
1813
        return null;
1814
    }
1815

    
1816
    private RSyntaxTextArea getCurrentRSyntaxTextArea() {
1817
        JEditor editor = getCurrentEditor();
1818
        if (editor instanceof JCodeEditor) {
1819
            JTextComponent textComponent = ((JCodeEditor) editor).getJTextComponent();
1820
            if (textComponent instanceof RSyntaxTextArea) {
1821
                return (RSyntaxTextArea) textComponent;
1822
            }
1823
        }
1824
        return null;
1825
    }
1826

    
1827
    @Override
1828
    public void refreshProjects() {
1829
        try {
1830
            this.getProjects().refresh();
1831
        } catch (Exception ex) {
1832
            // Ignore
1833
        }
1834
    }
1835

    
1836
    @Override
1837
    public StatusBar getStatusbar() {
1838
        return this.statusBar;
1839
    }
1840

    
1841
    /**
1842
     *
1843
     * @param e
1844
     */
1845
    @Override
1846
    public void actionPerformed(ActionEvent e) {
1847

    
1848
        if (e instanceof UpdateCaretPositionActionEvent) {
1849
            UpdateCaretPositionActionEvent e2 = (UpdateCaretPositionActionEvent) e;
1850

    
1851
            if (e2.hasLineAndColumn()) {
1852
                this.getStatusbar().setPosition(e2.getLine(), e2.getColumn());
1853
            } else {
1854
                this.getStatusbar().setPosition(0, 0);
1855
            }
1856
        }
1857
    }
1858

    
1859
    @Override
1860
    public void update(final Observable observable, final Object notification) {
1861
        if (!SwingUtilities.isEventDispatchThread()) {
1862
            SwingUtilities.invokeLater(new Runnable() {
1863
                @Override
1864
                public void run() {
1865
                    update(observable, notification);
1866
                }
1867
            });
1868
            return;
1869
        }
1870
        if (notification instanceof ScriptingNotification) {
1871
            ScriptingNotification e = (ScriptingNotification) notification;
1872

    
1873
            if (e.getException() instanceof CompileErrorException) {
1874
                CompileErrorException ce = (CompileErrorException) e.getException();
1875
                Problems problems = this.getProblems();
1876
                if (problems != null) {
1877
                    problems.add("Error", ce);
1878
                    this.dock.select(DOCKED_PROBLEMS);
1879
                }
1880

    
1881
            } else if (e.getException() instanceof ExecuteErrorException) {
1882
                ExecuteErrorException ee = (ExecuteErrorException) e.getException();
1883
                Problems problems = this.getProblems();
1884
                if (problems != null) {
1885
                    problems.add("Error",ee);
1886
                    this.dock.select(DOCKED_PROBLEMS);
1887
                }
1888
                JScriptingConsole console = this.getConsole();
1889
                if (console != null) {
1890
                    console.append(ee.getMessage(), Color.RED.darker());
1891
                    ee.printStackTrace(console.errors());
1892
                }
1893

    
1894
            } else {
1895
                Exception ex = e.getException();
1896
                Problems problems = this.getProblems();
1897
                if (problems != null) {
1898
                    problems.add("Error",ex); 
1899
                    this.dock.select(DOCKED_PROBLEMS);
1900
                }
1901
                JScriptingConsole console = this.getConsole();
1902
                if (console != null) {
1903
                    console.append(ex.getMessage(), Color.RED.darker());
1904
                    ex.printStackTrace(console.errors());
1905
                }
1906
            }
1907
        }
1908
    }
1909

    
1910
    public void closeWindow() {
1911
        this.setVisible(false);
1912
    }
1913

    
1914
    private static class DefaultStatusBar extends JPanel implements StatusBar {
1915

    
1916
        private static final long serialVersionUID = -6135634992327170084L;
1917

    
1918
        private JLabel message;
1919
        private JLabel position;
1920
        private final ScriptingUIManager uimanager;
1921

    
1922
        public DefaultStatusBar(ScriptingUIManager uimanager) {
1923
            this.uimanager = uimanager;
1924
            this.initComponents();
1925
        }
1926

    
1927
        private void initComponents() {
1928
            this.message = new JLabel(this.uimanager.getTranslation("Welcome_message"));
1929
            this.position = new JLabel("Line 0:0");
1930

    
1931
            this.setLayout(new BorderLayout());
1932

    
1933
            this.add(this.message, BorderLayout.WEST);
1934
            this.add(this.position, BorderLayout.EAST);
1935
        }
1936

    
1937
        @Override
1938
        public void clear() {
1939
            this.message.setText("");
1940
        }
1941

    
1942
        @Override
1943
        public void message(String message) {
1944
            this.message.setText(message);
1945
        }
1946

    
1947
        @Override
1948
        public void setPosition(int line) {
1949
            this.setPosition(line, -1);
1950
        }
1951

    
1952
        @Override
1953
        public void setPosition(int line, int column) {
1954
            if (line < 0) {
1955
                this.position.setText("");
1956
                return;
1957
            }
1958
            if (column < 0) {
1959
                this.position.setText(this.uimanager.getTranslation("Line") + " " + line + ":0");
1960
            } else {
1961
                this.position.setText(this.uimanager.getTranslation("Line") + " " + line + ":" + column);
1962
            }
1963
        }
1964

    
1965
        @Override
1966
        public JComponent asJComponent() {
1967
            return this;
1968
        }
1969
    }
1970

    
1971
    public static class JTabbedPaneClosable extends JTabbedPane {
1972

    
1973
        private static final long serialVersionUID = -3995298424891579555L;
1974

    
1975
        private final ActionListenerSupport closeTabListeners;
1976
        private ScriptingUIManager uimanager;
1977

    
1978
        private class TabTitleComponent extends JPanel {
1979

    
1980
            private static final long serialVersionUID = -1061417669527944341L;
1981
            private final JLabel label;
1982
            private final JButton button;
1983
            private boolean changed = false;
1984
            private final Font fontNormal;
1985
            private final Font fontBold;
1986
            private JPopupMenu popup;
1987

    
1988
            @SuppressWarnings("OverridableMethodCallInConstructor")
1989
            public TabTitleComponent(String title, final ActionListener onclose) {
1990
                this.setOpaque(true);
1991
                this.label = new JLabel(title + " ");
1992
                this.label.setOpaque(true);
1993
                this.label.setBackground(UIManager.getColor("TabbedPane.tabAreaBackground"));
1994
                this.label.setVerticalTextPosition(SwingConstants.CENTER);
1995
                this.fontNormal = this.label.getFont();
1996
                this.fontBold = new Font(this.fontNormal.getFontName(), Font.BOLD, this.fontNormal.getSize());
1997

    
1998
                this.button = new JButton();
1999
                this.button.setText("");
2000
                this.button.setToolTipText(uimanager.getTranslation("Close_tab"));
2001
                this.button.setBackground(UIManager.getColor("TabbedPane.tabAreaBackground"));
2002
                this.button.setBorder(BorderFactory.createEmptyBorder());
2003
                this.button.setBorderPainted(false);
2004
                this.button.setFocusPainted(false);
2005
                this.button.setContentAreaFilled(false);
2006
                this.button.setCursor(new Cursor(Cursor.HAND_CURSOR));
2007
                this.button.setRolloverEnabled(true);
2008
                this.button.setIcon(uimanager.getIcon("scripting-tabclose-inactive"));
2009
                this.button.setRolloverIcon(uimanager.getIcon("scripting-tabclose-active"));
2010
                this.button.addActionListener(new ActionListener() {
2011
                    @Override
2012
                    public void actionPerformed(ActionEvent ae) {
2013
                        ae.setSource(TabTitleComponent.this);
2014
                        onclose.actionPerformed(ae);
2015
                    }
2016
                });
2017
                this.setLayout(new BorderLayout());
2018
                this.add(this.label, BorderLayout.CENTER);
2019
                this.add(this.button, BorderLayout.EAST);
2020
                
2021
                this.popup = null;
2022
                this.label.addMouseListener(new MouseAdapter() {
2023
                  @Override
2024
                  public void mouseClicked(MouseEvent e) {
2025
                    if( e.isPopupTrigger() || e.getButton()==MouseEvent.BUTTON3) {
2026
                      if( popup!=null ) {
2027
                        popup.show(e.getComponent(), e.getX(), e.getY());
2028
                      }
2029
                    } else {
2030
                      int index = indexOfTabComponent(TabTitleComponent.this);
2031
                      setSelectedIndex(index);
2032
                    }
2033
                  }
2034
                });
2035
            }
2036

    
2037
            public void setTitle(String title) {
2038
                this.label.setText(title);
2039
            }
2040

    
2041
            public String getTitle() {
2042
                return this.label.getText();
2043
            }
2044

    
2045
            public void setChanged(boolean changed) {
2046
                if (changed) {
2047
                    this.label.setFont(this.fontBold);
2048
                } else {
2049
                    this.label.setFont(this.fontNormal);
2050
                }
2051
                this.changed = changed;
2052
            }
2053

    
2054
            public boolean isChanged() {
2055
                return this.changed;
2056
            }
2057
            
2058
            @Override
2059
            public void setComponentPopupMenu(final JPopupMenu popup) {
2060
              // Asignarle un popup menu consume los eventos y no cambia de pesta?a.
2061
              // this.label.setComponentPopupMenu(popup);
2062
              this.popup = popup;
2063
            }
2064
        }
2065

    
2066
        public JTabbedPaneClosable(ScriptingUIManager uimanager) {
2067
            super();
2068
            this.uimanager = uimanager;
2069
            this.closeTabListeners = ToolsSwingLocator.getToolsSwingManager().createActionListenerSupport();
2070
        }
2071

    
2072
        @Override
2073
        public String getTitleAt(int index) {
2074
            TabTitleComponent title = (TabTitleComponent) this.getTabComponentAt(index);
2075
            if (title == null) {
2076
                return null;
2077
            } 
2078
            return title.getTitle();
2079
        }
2080

    
2081
        @Override
2082
        public void setTitleAt(int index, String title) {
2083
            TabTitleComponent titleComponent = (TabTitleComponent) this.getTabComponentAt(index);
2084
            titleComponent.setTitle(title);
2085
        }
2086

    
2087
        @Override
2088
        public void addTab(String title, java.awt.Component component) {
2089
            super.addTab(null, component);
2090
            final int index = getTabCount() - 1;
2091
            TabTitleComponent tabcomponent = new TabTitleComponent(title, new ActionListener() {
2092

    
2093
                @Override
2094
                public void actionPerformed(ActionEvent ae) {
2095
                    TabTitleComponent tabTitleComponent = (TabTitleComponent) ae.getSource();
2096
                    int index = indexOfTabComponent(tabTitleComponent);
2097
                    setSelectedIndex(index);
2098
                    ae.setSource(JTabbedPaneClosable.this);
2099
                    closeTabListeners.fireActionEvent(ae);
2100
                }
2101
            });
2102
            super.setTabComponentAt(index, tabcomponent);
2103
        }
2104

    
2105
        public void addCloseTabListener(ActionListener remove) {
2106
            this.closeTabListeners.addActionListener(remove);
2107
        }
2108

    
2109
        public void removeCloseTabListener(ActionListener remove) {
2110
            this.closeTabListeners.removeActionListener(remove);
2111
        }
2112

    
2113
        public ActionListener[] getCloseTabListeners() {
2114
            return this.closeTabListeners.getActionListeners();
2115
        }
2116

    
2117
        public boolean isTabModified(int index) {
2118
            TabTitleComponent comp = (TabTitleComponent) this.getTabComponentAt(index);
2119
            if (comp == null) {
2120
                return false;
2121
            }
2122
            return comp.isChanged();
2123
        }
2124

    
2125
        public void setTabModified(int index, boolean changed) {
2126
            TabTitleComponent comp = (TabTitleComponent) this.getTabComponentAt(index);
2127
            if (comp != null) {
2128
                comp.setChanged(changed);
2129
            }
2130
        }
2131
    }
2132

    
2133
    public static class DefaultProblems extends JPanel implements Problems {
2134

    
2135
        private static final long serialVersionUID = 7728033081188167969L;
2136

    
2137
        private static final int COLUMN_TYPE = 0;
2138
        private static final int COLUMN_MESSAGE = 1;
2139
        private static final int COLUMN_RESOURCE = 2;
2140
        private static final int COLUMN_LOCATION = 3;
2141
        private static final int NUM_COLUMNS = 4;
2142

    
2143
        private JTable table;
2144
        private ProblemsTableMode tableModel;
2145
        private final ScriptingUIManager uimanager;
2146
        private Set<ListSelectionListener> selectionListeners; 
2147

    
2148
        public static class ProblemsTableMode extends DefaultTableModel implements TableModel {
2149
            private static final long serialVersionUID = -3294067602561419422L;
2150

    
2151
            public static class DefaultProblem implements Problem {
2152

    
2153
                String[] row;
2154
                private File resource;
2155

    
2156
                public DefaultProblem() {
2157
                    this.row = new String[NUM_COLUMNS];
2158
                }
2159

    
2160
                public DefaultProblem(String[] row) {
2161
                    this.row = row;
2162
                }
2163

    
2164
                public DefaultProblem(String type, String message, String resourceName, String location, File resource) {
2165
                    String[] theRow = new String[NUM_COLUMNS];
2166
                    theRow[COLUMN_TYPE] = type;
2167
                    theRow[COLUMN_MESSAGE] = message;
2168
                    theRow[COLUMN_RESOURCE] = resourceName;
2169
                    theRow[COLUMN_LOCATION] = location;
2170
                    this.resource = resource;
2171
                    this.row = theRow;
2172
                }
2173

    
2174
                public String get(int index) {
2175
                    return row[index];
2176
                }
2177

    
2178
                public String getValue(int index) {
2179
                    return row[index];
2180
                }
2181

    
2182
                public void setValue(int index, String value) {
2183
                    row[index] = value;
2184
                }
2185

    
2186
                @Override
2187
                public String getType() {
2188
                    return this.row[COLUMN_TYPE];
2189
                }
2190

    
2191
                @Override
2192
                public String getMessage() {
2193
                    return this.row[COLUMN_MESSAGE];
2194
                }
2195

    
2196
                @Override
2197
                public String getResourceName() {
2198
                    return this.row[COLUMN_RESOURCE];
2199
                }
2200

    
2201
                @Override
2202
                public File getResource() {
2203
                    return this.resource;
2204
                }
2205

    
2206
                @Override
2207
                @SuppressWarnings("UseSpecificCatch")
2208
                public int getLineNumber() {
2209
                    try {
2210
                        String[] lineAndColumn = this.row[COLUMN_LOCATION].split(":");
2211
                        if (lineAndColumn.length > 0) {
2212
                            int lineno = Integer.parseInt(lineAndColumn[0].trim());
2213
                            return lineno;
2214
                        }
2215
                    } catch (Exception e) {
2216
                        // Do nothing
2217
                    }
2218
                    return -1;
2219
                }
2220

    
2221
            }
2222
            private final ScriptingUIManager uimanager;
2223
            private List<DefaultProblem> data;
2224
            private String[] columnNames;
2225

    
2226
            public ProblemsTableMode(ScriptingUIManager uimanager) {
2227
                this.uimanager = uimanager;
2228
                this.columnNames = new String[]{
2229
                    this.uimanager.getTranslation("Category"),
2230
                    this.uimanager.getTranslation("Description"),
2231
                    this.uimanager.getTranslation("Resource"),
2232
                    this.uimanager.getTranslation("Location")
2233
                };
2234

    
2235
            }
2236
            
2237
            private List<DefaultProblem> getData() {
2238
                if( this.data == null ) {
2239
                    this.data = new ArrayList<>();
2240
                }
2241
                return this.data;
2242
            }
2243

    
2244
            public void add(DefaultProblem row) {
2245
                this.getData().add(row);
2246
                this.fireTableDataChanged();
2247
            }
2248

    
2249
            private void add(String type, String message, String resourceName, String location, File resource) {
2250
                DefaultProblem problem = new DefaultProblem(type, message, resourceName, location, resource);
2251
                this.add(problem);
2252
            }
2253

    
2254
            @Override
2255
            public int getRowCount() {
2256
                return this.getData().size();
2257
            }
2258

    
2259
            @Override
2260
            public int getColumnCount() {
2261
                return NUM_COLUMNS;
2262
            }
2263

    
2264
            @Override
2265
            public String getColumnName(int columnIndex) {
2266
                return columnNames[columnIndex];
2267
            }
2268

    
2269
            @Override
2270
            public Class<?> getColumnClass(int columnIndex) {
2271
                return String.class;
2272
            }
2273

    
2274
            @Override
2275
            public boolean isCellEditable(int rowIndex, int columnIndex) {
2276
                return false;
2277
            }
2278

    
2279
            @Override
2280
            public Object getValueAt(int rowIndex, int columnIndex) {
2281
                return this.getData().get(rowIndex).get(columnIndex);
2282
            }
2283
            
2284
            public Problem getProblem(int rowIndex) {
2285
                return this.getData().get(rowIndex);
2286
            }
2287

    
2288
            @Override
2289
            public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
2290
                this.getData().get(rowIndex).setValue(columnIndex, (String) aValue);
2291
            }
2292

    
2293
            public void removeAll() {
2294
                this.getData().clear();
2295
            }
2296
        }
2297

    
2298
        public DefaultProblems(ScriptingUIManager uimanager) {
2299
            this.uimanager = uimanager;
2300
            this.initComponents();
2301
        }
2302

    
2303
        private void initComponents() {
2304
            this.selectionListeners = new HashSet<>();
2305
            tableModel = new ProblemsTableMode(this.uimanager);
2306
            table = new JTable(tableModel);
2307
            table.getColumnModel().getColumn(1).setPreferredWidth(300);
2308

    
2309
            table.setRowSelectionAllowed(true);
2310
            table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
2311

    
2312
            JScrollPane scrollProblems = new JScrollPane(table);
2313
            scrollProblems.setAutoscrolls(true);
2314

    
2315
            this.setLayout(new BorderLayout());
2316
            this.add(scrollProblems, BorderLayout.CENTER);
2317
            
2318
            // Si ya hay seleccionada una linea y vuelvo a clickar sobre ella 
2319
            // para que me lleve a la linea del editor que toque, con el
2320
            // addSelectionListener no me vuelve a lanzar el evento, asi que
2321
            // me apalanco en el mouseClicked tambien.
2322
            table.addMouseListener(new MouseAdapter(){
2323
                @Override
2324
                public void mouseClicked(MouseEvent evnt) {
2325
                    if (evnt.getClickCount() == 1) {
2326
                        fireSelectionListeners();
2327
                     }
2328
                 }
2329
            });
2330
        }
2331

    
2332
        @Override
2333
        public void addListSelectionListener(ListSelectionListener listener) {
2334
            this.table.getSelectionModel().addListSelectionListener(listener);
2335
            this.selectionListeners.add(listener);
2336
        }
2337

    
2338
        private void fireSelectionListeners() {
2339
            int row = this.table.getSelectedRow();
2340
            for( ListSelectionListener listener : this.selectionListeners ) {
2341
                try {
2342
                    listener.valueChanged(new ListSelectionEvent(this, row, row, false));
2343
                } catch(Exception th) {
2344
                    
2345
                }
2346
            }
2347
        }
2348
        
2349
        @Override
2350
        public void removeAll() {
2351
            this.tableModel.removeAll();
2352
            this.table.updateUI();
2353
        }
2354

    
2355
        @Override
2356
        public void add(String type, String message, String resource, String location) {
2357
            this.tableModel.add(type, message, resource, location, null);
2358
        }
2359

    
2360
        @Override
2361
        public void add(String type, String message, String resource, int line, int column) {
2362
            this.add(type, message, resource, line + ":" + column);
2363
        }
2364
        
2365
        public void add(String type, String message, String resourceName, int line, int column, File resource) {
2366
            this.tableModel.add(type, message, resourceName, line + ":" + column, resource);
2367
        }
2368
                
2369
        @Override
2370
        public void add(String type, Exception e) {
2371
            if (e  instanceof ScriptingErrorException) {
2372
                ScriptingErrorException se = (ScriptingErrorException) e;
2373
                    this.add(
2374
                        "Error",
2375
                        se.getMessage(),
2376
                        se.getScriptName(),
2377
                        se.getLineNumber(),
2378
                        se.getColumnNumber(),
2379
                        se.getScriptFile()
2380
                    );
2381

    
2382
            } else {
2383
                    this.add("Error", 
2384
                        "Error",
2385
                        e.getMessage(),
2386
                        null
2387
                    );
2388
            }            
2389
        }
2390

    
2391
        @Override
2392
        public Problem getSelect() {
2393
            int row = this.table.getSelectedRow();
2394
            if (row < 0) {
2395
                return null;
2396
            }
2397
            return this.get(row);
2398
        }
2399

    
2400
        @Override
2401
        public int getCount() {
2402
            return this.tableModel.getRowCount();
2403
        }
2404

    
2405
        @Override
2406
        public Problem get(int row) {
2407
            return this.tableModel.getProblem(row);
2408
        }
2409

    
2410
        @Override
2411
        public JComponent asJComponent() {
2412
            return this;
2413
        }
2414

    
2415
    }
2416

    
2417
    public static class DefaultDock extends JPanel implements Dock {
2418

    
2419
        private static final long serialVersionUID = 4899734277977456625L;
2420

    
2421
        public class DefaultDockedPanel implements DockedPanel {
2422

    
2423
            String id;
2424
            String title;
2425
            Component component;
2426
            private final String align;
2427

    
2428
            public DefaultDockedPanel(String id, String title, Component component, String align) {
2429
                this.id = id;
2430
                this.title = title;
2431
                this.component = component;
2432
                this.align = align;
2433
            }
2434

    
2435
            @Override
2436
            public String getId() {
2437
                return this.id;
2438
            }
2439

    
2440
            @Override
2441
            public String getAlign() {
2442
                return this.align;
2443
            }
2444

    
2445
            @Override
2446
            public Component getComponent() {
2447
                return this.component;
2448
            }
2449

    
2450
            @Override
2451
            public String getTitle() {
2452
                return this.title;
2453
            }
2454

    
2455
            @Override
2456
            public boolean isModified() {
2457
                return getModified(this);
2458
            }
2459

    
2460
            @Override
2461
            public void setModified(boolean modified) {
2462
                DefaultDock.this.setModified(this, modified);
2463
            }
2464

    
2465
            @Override
2466
            public void remove() {
2467
                DefaultDock.this.remove(this.getId());
2468
            }
2469

    
2470
            @Override
2471
            public void select() {
2472
                DefaultDock.this.select(this.getId());
2473
            }
2474

    
2475
            @Override
2476
            public void moveto(String position) {
2477
              switch(position) {
2478
                case Dock.DOCK_LEFT:
2479
                  add(this.getId(), this.getTitle(), this.getComponent(), Dock.DOCK_LEFT);
2480
                  break;
2481
                case Dock.DOCK_CENTER:
2482
                  add(this.getId(), this.getTitle(), this.getComponent(), Dock.DOCK_CENTER);
2483
                  break;
2484
                case Dock.DOCK_BOTTOM:
2485
                default:
2486
                  add(this.getId(), this.getTitle(), this.getComponent(), Dock.DOCK_BOTTOM);
2487
                  break;
2488
              }
2489
            }
2490
        }
2491

    
2492
        private final Map<String, Dock.DockedPanel> panels;
2493
        private final JTabbedPaneClosable tabbedPanelLeft;
2494
        private final JTabbedPaneClosable tabbedPanelBottom;
2495
        private final JTabbedPaneClosable tabbedPanelCenter;
2496
        private Set<ActionListener> closeListeners;
2497
        private Set<ActionListener> activePanelListeners;
2498

    
2499
        public DefaultDock(JTabbedPaneClosable tabbedPanelLeft, JTabbedPaneClosable tabbedPanelBottom, JTabbedPaneClosable tabbedPanelCenter) {
2500
            this.panels = new HashMap<>();
2501
            this.tabbedPanelBottom = tabbedPanelBottom;
2502
            this.tabbedPanelLeft = tabbedPanelLeft;
2503
            this.tabbedPanelCenter = tabbedPanelCenter;
2504

    
2505
            ActionListener onCloseTab = new ActionListener() {
2506

    
2507
                @Override
2508
                public void actionPerformed(ActionEvent e) {
2509
                    JTabbedPaneClosable tabbedPanel = (JTabbedPaneClosable) e.getSource();
2510
                    java.awt.Component component = tabbedPanel.getSelectedComponent();
2511
                    if (component != null) {
2512
                        DockedPanel panel = getDockedPanel(component);
2513
                        if (panel != null) {
2514
                            fireCloseListener(new ActionEvent(panel, 0, ACTION_CLOSE_PANEL));
2515
                        }
2516
//                        panels.remove(panel.getId());
2517
//                        tabbedPanel.remove(panel.getComponent().asJComponent());
2518
                    }
2519
                }
2520
            };
2521
            ChangeListener onChangeTab = new ChangeListener() {
2522

    
2523
                @Override
2524
                public void stateChanged(ChangeEvent e) {
2525
                    
2526
                    fireChangeListener(new ActionEvent(DefaultDock.this, 0, ACTION_ACTIVATE_PANEL));
2527
                }
2528
            };
2529
            this.tabbedPanelCenter.addChangeListener(onChangeTab);
2530
            this.tabbedPanelBottom.addChangeListener(onChangeTab);
2531
            this.tabbedPanelLeft.addChangeListener(onChangeTab);
2532
            
2533
            this.tabbedPanelBottom.addCloseTabListener(onCloseTab);
2534
            this.tabbedPanelLeft.addCloseTabListener(onCloseTab);
2535
            this.tabbedPanelCenter.addCloseTabListener(onCloseTab);
2536

    
2537
        }
2538

    
2539
        /**
2540
         *
2541
         * @param listener
2542
         */
2543
        @Override
2544
        public void addCloseListener(ActionListener listener) {
2545
            if (this.closeListeners == null) {
2546
                this.closeListeners = new HashSet<>();
2547
            }
2548
            this.closeListeners.add(listener);
2549
        }
2550
        
2551
        @Override
2552
        public void removeCloseListener(ActionListener listener) {
2553
            if (this.closeListeners == null) {
2554
                return;
2555
            }
2556
            this.closeListeners.remove(listener);
2557
        }
2558

    
2559
        @Override
2560
        public void addActivateListener(ActionListener listener) {
2561
            if (this.activePanelListeners == null) {
2562
                this.activePanelListeners = new HashSet<>();
2563
            }
2564
            this.activePanelListeners.add(listener);
2565
        }
2566
        
2567
        @Override
2568
        public void removeActivateListener(ActionListener listener) {
2569
            if (this.activePanelListeners == null) {
2570
                return;
2571
            }
2572
            this.activePanelListeners.remove(listener);
2573
        }
2574
                
2575

    
2576
        public void fireCloseListener(ActionEvent e) {
2577
            if (this.closeListeners == null) {
2578
                return;
2579
            }
2580
            for (ActionListener listener : this.closeListeners) {
2581
                try {
2582
                    listener.actionPerformed(e);
2583
                } catch (Exception ex) {
2584

    
2585
                }
2586
            }
2587
        }
2588

    
2589
        public void fireChangeListener(ActionEvent e) {
2590
            if (this.activePanelListeners == null) {
2591
                return;
2592
            }
2593
            for (ActionListener listener : this.activePanelListeners) {
2594
                try {
2595
                    listener.actionPerformed(e);
2596
                } catch (Exception ex) {
2597

    
2598
                }
2599
            }
2600
        }
2601

    
2602
        private JTabbedPaneClosable getTabbedPanel(String align) {
2603
            switch (align) {
2604
                case Dock.DOCK_LEFT:
2605
                    return this.tabbedPanelLeft;
2606
                case Dock.DOCK_CENTER:
2607
                    return this.tabbedPanelCenter;
2608
                default:
2609
                case Dock.DOCK_BOTTOM:
2610
                    return this.tabbedPanelBottom;
2611
            }
2612
        }
2613

    
2614
        private DockedPanel getDockedPanel(java.awt.Component component) {
2615
            for (DockedPanel panel : this.panels.values()) {
2616
                if (panel.getComponent().asJComponent() == component) {
2617
                    return panel;
2618
                }
2619
            }
2620
            return null;
2621
        }
2622

    
2623
        private int getIndex(DockedPanel panel) {
2624
            final JTabbedPaneClosable tabbedPanel = getTabbedPanel(panel.getAlign());
2625
            for (int i = 0; i < tabbedPanel.getTabCount(); i++) {
2626
                java.awt.Component component = tabbedPanel.getComponentAt(i);
2627
                if (component == panel.getComponent().asJComponent()) {
2628
                    return i;
2629
                }
2630
            }
2631
            return -1;
2632
        }
2633

    
2634
        @Override
2635
        public void setModified(DockedPanel panel, boolean modified) {
2636
            final int index = this.getIndex(panel);
2637
            if (index < 0) {
2638
                return;
2639
            }
2640
            final JTabbedPaneClosable tabbedPanel = getTabbedPanel(panel.getAlign());
2641
            tabbedPanel.setTabModified(index, modified);
2642
        }
2643

    
2644
        @Override
2645
        public boolean getModified(DockedPanel panel) {
2646
            final int index = this.getIndex(panel);
2647
            if (index < 0) {
2648
                return false;
2649
            }
2650
            final JTabbedPaneClosable tabbedPanel = getTabbedPanel(panel.getAlign());
2651
            return tabbedPanel.isTabModified(index);
2652
        }
2653

    
2654
        @Override
2655
        public DockedPanel getSelected(String align) {
2656
            final JTabbedPaneClosable tabbedPanel = getTabbedPanel(align);
2657
            java.awt.Component selected = tabbedPanel.getSelectedComponent();
2658
            return this.getDockedPanel(selected);
2659
        }
2660

    
2661
        @Override
2662
        public DockedPanel add(String id, String title, final Component component, String align) {
2663
            final JTabbedPaneClosable tabbedPanel = getTabbedPanel(align);
2664
            DockedPanel panel = this.panels.get(id);
2665
            if (panel != null) {
2666
                tabbedPanel.remove(panel.getComponent().asJComponent());
2667
            }
2668
            panel = new DefaultDockedPanel(id, title, component, align);
2669
            this.panels.put(id, panel);
2670
            tabbedPanel.add(panel.getTitle(), panel.getComponent().asJComponent());
2671
            JComponent tabComponent = (JComponent) tabbedPanel.getTabComponentAt(tabbedPanel.getTabCount()-1);
2672
            tabComponent.setComponentPopupMenu(this.createDefaultComponentPopupMenu(panel));
2673
            return panel;
2674
        }
2675
        
2676
        private JPopupMenu createDefaultComponentPopupMenu(DockedPanel panel) {
2677
          JPopupMenu menu = new JPopupMenu();
2678
          menu.add(createMenuItem("Move to left", (ActionEvent e) -> {
2679
            panel.moveto(Dock.DOCK_LEFT);
2680
          }));
2681
          menu.add(createMenuItem("Move to bottom", (ActionEvent e) -> {
2682
            panel.moveto(Dock.DOCK_BOTTOM);
2683
          }));
2684
          menu.add(createMenuItem("Move to center", (ActionEvent e) -> {
2685
            panel.moveto(Dock.DOCK_CENTER);
2686
          }));
2687
          return menu;
2688
        }
2689
        
2690
        private JMenuItem createMenuItem(String text, ActionListener listener) {
2691
          JMenuItem item = new JMenuItem(text);
2692
          item.addActionListener(listener);
2693
          return item;
2694
        }
2695

    
2696
        @Override
2697
        public void remove(String id) {
2698
            DockedPanel panel = this.panels.get(id);
2699
            if (panel != null) {
2700
                final JTabbedPaneClosable tabbedPanel = getTabbedPanel(panel.getAlign());
2701
                tabbedPanel.remove(panel.getComponent().asJComponent());
2702
                this.panels.remove(id);
2703
            }
2704
        }
2705

    
2706
        @Override
2707
        public DockedPanel get(String id) {
2708
            DockedPanel panel = this.panels.get(id);
2709
            return panel;
2710
        }
2711

    
2712
        @Override
2713
        public void select(String id) {
2714
            DockedPanel panel = this.panels.get(id);
2715
            if (panel != null) {
2716
                final JTabbedPaneClosable tabbedPanel = getTabbedPanel(panel.getAlign());
2717
                tabbedPanel.setSelectedComponent(panel.getComponent().asJComponent());
2718
            }
2719
        }
2720

    
2721
        @Override
2722
        public Iterator<DockedPanel> iterator() {
2723
            return this.panels.values().iterator();
2724
        }
2725

    
2726
    }
2727

    
2728
    private static class ToolEntry {
2729

    
2730
        private String name;
2731
        private String text;
2732
        private Action action;
2733
        private JComponent component;
2734

    
2735
        public ToolEntry(String name, Action action, String text) {
2736
            this.name = name;
2737
            this.action = action;
2738
            this.text = text;
2739
        }
2740

    
2741
        public ToolEntry(String name, Action action) {
2742
            this(name, action, null);
2743
        }
2744

    
2745
        public String getName() {
2746
            return this.name;
2747
        }
2748

    
2749
        public String getText() {
2750
            return this.text;
2751
        }
2752

    
2753
        public Action getAction() {
2754
            return this.action;
2755
        }
2756

    
2757
        public JComponent getComponent() {
2758
            return this.component;
2759
        }
2760

    
2761
        public void setComponent(JComponent component) {
2762
            this.component = component;
2763
        }
2764
    }
2765

    
2766
    public class ButtonWithContext extends JButton {
2767

    
2768
        private static final long serialVersionUID = -7434255417630073101L;
2769

    
2770
        @SuppressWarnings("OverridableMethodCallInConstructor")
2771
        public ButtonWithContext(Action action) {
2772
            super(action);
2773
            this.setBorderPainted(false);
2774
            this.setText("");
2775
        }
2776

    
2777
        public Object getContext() {
2778
            return DefaultJScriptingComposer.this;
2779
        }
2780
    }
2781

    
2782
    private class FindReplaceSearchListener implements SearchListener {
2783

    
2784
        @Override
2785
        public void searchEvent(SearchEvent e) {
2786

    
2787
            RSyntaxTextArea textArea = getCurrentRSyntaxTextArea();
2788
            if (textArea == null) {
2789
                return;
2790
            }
2791

    
2792
            SearchEvent.Type type = e.getType();
2793
            SearchContext context = e.getSearchContext();
2794
            SearchResult result;
2795

    
2796
            switch (type) {
2797
                default: // Prevent FindBugs warning later
2798
                case MARK_ALL:
2799
                    result = SearchEngine.markAll(textArea, context);
2800
                    break;
2801
                case FIND:
2802
                    result = SearchEngine.find(textArea, context);
2803
                    if (!result.wasFound()) {
2804
                        UIManager.getLookAndFeel().provideErrorFeedback(textArea);
2805
                    }
2806
                    break;
2807
                case REPLACE:
2808
                    result = SearchEngine.replace(textArea, context);
2809
                    if (!result.wasFound()) {
2810
                        UIManager.getLookAndFeel().provideErrorFeedback(textArea);
2811
                    }
2812
                    break;
2813
                case REPLACE_ALL:
2814
                    result = SearchEngine.replaceAll(textArea, context);
2815
                    JOptionPane.showMessageDialog(null, result.getCount()
2816
                            + " occurrences replaced.");
2817
                    break;
2818
            }
2819
            String text;
2820
            if (result.wasFound()) {
2821
                text = "Text found; occurrences marked: " + result.getMarkedCount();
2822
            } else if (type == SearchEvent.Type.MARK_ALL) {
2823
                if (result.getMarkedCount() > 0) {
2824
                    text = "Occurrences marked: " + result.getMarkedCount();
2825
                } else {
2826
                    text = "";
2827
                }
2828
            } else {
2829
                text = "Text not found";
2830
            }
2831
            getStatusbar().message(text);
2832
        }
2833

    
2834
        @Override
2835
        public String getSelectedText() {
2836
            RSyntaxTextArea textArea = getCurrentRSyntaxTextArea();
2837
            if (textArea == null) {
2838
                return "";
2839
            }
2840
            return textArea.getSelectedText();
2841
        }
2842

    
2843
    }
2844
}