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 @ 989

History | View | Annotate | Download (88.9 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.Date;
19
import java.util.HashMap;
20
import java.util.HashSet;
21
import java.util.Iterator;
22
import java.util.LinkedHashMap;
23
import java.util.List;
24
import java.util.Map;
25
import java.util.Set;
26
import javax.swing.AbstractAction;
27
import javax.swing.Action;
28
import static javax.swing.Action.ACCELERATOR_KEY;
29
import static javax.swing.Action.ACTION_COMMAND_KEY;
30
import javax.swing.BorderFactory;
31
import javax.swing.JButton;
32
import javax.swing.JComponent;
33
import javax.swing.JLabel;
34
import javax.swing.JMenuBar;
35
import javax.swing.JMenuItem;
36
import javax.swing.JOptionPane;
37
import javax.swing.JPanel;
38
import javax.swing.JScrollPane;
39
import javax.swing.JSplitPane;
40
import javax.swing.JTabbedPane;
41
import javax.swing.JTable;
42
import javax.swing.JToolBar;
43
import javax.swing.KeyStroke;
44
import javax.swing.ListSelectionModel;
45
import javax.swing.SwingConstants;
46
import javax.swing.SwingUtilities;
47
import javax.swing.UIManager;
48
import javax.swing.event.AncestorEvent;
49
import javax.swing.event.AncestorListener;
50
import javax.swing.event.ChangeEvent;
51
import javax.swing.event.ChangeListener;
52
import javax.swing.event.ListSelectionEvent;
53
import javax.swing.event.ListSelectionListener;
54
import javax.swing.table.DefaultTableModel;
55
import javax.swing.table.TableModel;
56
import javax.swing.text.JTextComponent;
57
import org.fife.rsta.ui.GoToDialog;
58
import org.fife.rsta.ui.search.FindDialog;
59
import org.fife.rsta.ui.search.ReplaceDialog;
60
import org.fife.rsta.ui.search.SearchEvent;
61
import org.fife.rsta.ui.search.SearchListener;
62
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
63
import org.fife.ui.rtextarea.SearchContext;
64
import org.fife.ui.rtextarea.SearchEngine;
65
import org.fife.ui.rtextarea.SearchResult;
66
import org.gvsig.installer.swing.api.SwingInstallerLocator;
67
import org.gvsig.installer.swing.api.SwingInstallerManager;
68
import org.gvsig.installer.swing.api.packagebuilder.PackageBuildder;
69
import org.gvsig.scripting.CompileErrorException;
70
import org.gvsig.scripting.ExecuteErrorException;
71
import org.gvsig.scripting.ScriptingBaseScript;
72
import org.gvsig.scripting.ScriptingErrorException;
73
import org.gvsig.scripting.ScriptingFolder;
74
import org.gvsig.scripting.ScriptingManager;
75
import org.gvsig.scripting.ScriptingNotification;
76
import org.gvsig.scripting.ScriptingScript;
77
import org.gvsig.scripting.ScriptingUnit;
78
import org.gvsig.scripting.swing.api.JCodeEditor;
79
import org.gvsig.scripting.swing.api.JEditor;
80
import org.gvsig.scripting.swing.api.JScriptingBrowser;
81
import org.gvsig.scripting.swing.api.JScriptingBrowser.BrowserActionEvent;
82
import org.gvsig.scripting.swing.api.JScriptingComposer;
83
import static org.gvsig.scripting.swing.api.JScriptingComposer.DOCKED_PROBLEMS;
84
import org.gvsig.scripting.swing.api.JScriptingComposer.Dock.DockedPanel;
85
import org.gvsig.scripting.swing.api.JScriptingComposer.Problems;
86
import org.gvsig.scripting.swing.api.JScriptingComposer.Problems.Problem;
87
import org.gvsig.scripting.swing.api.JScriptingConsole;
88
import org.gvsig.scripting.swing.api.JScriptingLauncher;
89
import org.gvsig.scripting.swing.api.ScriptingUIManager;
90
import org.gvsig.scripting.swing.api.ScriptingUIManager.MenuEntry;
91
import org.gvsig.scripting.swing.api.SyntaxtHighlightTextComponent.UpdateCaretPositionActionEvent;
92
import org.gvsig.scripting.swing.impl.DefaultJScriptingConsole;
93
import org.gvsig.scripting.swing.impl.DefaultScriptingUIManager;
94
import org.gvsig.scripting.swing.impl.JDialogContent;
95
import org.gvsig.scripting.swing.impl.composer.DefaultJScriptingComposer.DefaultProblems.ProblemsTableMode.DefaultProblem;
96
import org.gvsig.scripting.swing.impl.composer.editors.ScriptEditor;
97
import org.gvsig.tools.ToolsLocator;
98
import org.gvsig.tools.i18n.I18nManager;
99
import org.gvsig.tools.observer.Observable;
100
import org.gvsig.tools.observer.Observer;
101
import org.gvsig.tools.packageutils.PackageInfo;
102
import org.gvsig.tools.packageutils.PackageManager;
103
import org.gvsig.tools.packageutils.Version;
104
import org.gvsig.tools.swing.api.ActionListenerSupport;
105
import org.gvsig.tools.swing.api.Component;
106
import org.gvsig.tools.swing.api.ToolsSwingLocator;
107
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
108
import org.slf4j.Logger;
109
import org.slf4j.LoggerFactory;
110

    
111
public class DefaultJScriptingComposer extends JPanel implements JScriptingComposer, Observer, ActionListener {
112

    
113
    /**
114
     *
115
     */
116
    private static final long serialVersionUID = 1L;
117

    
118
    private static final Logger logger = LoggerFactory.getLogger(DefaultJScriptingComposer.class);
119

    
120
    public static final int CLOSE_ACTION = 1;
121

    
122
    private final ScriptingUIManager uimanager;
123
    private final ScriptingManager manager;
124
    private final ClassLoader loader;
125

    
126
    private JSplitPane mainPanel;
127
    private Dock dock;
128

    
129
    private Map<String, ToolEntry> menus;
130
    private JMenuBar menuBar;
131

    
132
    private Map<String, ToolEntry> tools;
133
    private JToolBar toolBar;
134

    
135
    private StatusBar statusBar;
136

    
137
    private FindDialog findDialog;
138
    private ReplaceDialog replaceDialog;
139
    private GoToDialog gotoDialog;
140

    
141
    private ActionListener defaultActionlistener = null;
142

    
143
    private Set<ChangeListener> changeEditorListeners = null;
144

    
145
    private class GoToLineAction extends AbstractAction {
146

    
147
        private static final long serialVersionUID = -7353913671104893812L;
148

    
149
        public GoToLineAction() {
150
            super(uimanager.getTranslation("go_to_line_Xhorizontal_ellipsisX"));
151
            int c = getToolkit().getMenuShortcutKeyMask();
152
            putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_L, c));
153
            putValue(ACTION_COMMAND_KEY, "GotoLine");
154
        }
155

    
156
        @Override
157
        public void actionPerformed(ActionEvent e) {
158
            JEditor editor = getCurrentEditor();
159
            if (!(editor instanceof JCodeEditor)) {
160
                return;
161
            }
162
            JCodeEditor codeEditor = (JCodeEditor) editor;
163
            if (findDialog.isVisible()) {
164
                findDialog.setVisible(false);
165
            }
166
            if (replaceDialog.isVisible()) {
167
                replaceDialog.setVisible(false);
168
            }
169
            gotoDialog.setMaxLineNumberAllowed(codeEditor.getLineCount());
170
            gotoDialog.setVisible(true);
171
            int line = gotoDialog.getLineNumber();
172

    
173
            if (line > 0) {
174
                codeEditor.selectLine(line);
175
            }
176
        }
177

    
178
        @Override
179
        public boolean isEnabled() {
180
            DockedPanel panel = dock.getSelected(Dock.DOCK_CENTER);
181
            return panel != null && panel.getComponent() instanceof JCodeEditor;
182
        }
183
    }
184

    
185
    private class ShowFindDialogAction extends AbstractAction {
186

    
187
        private static final long serialVersionUID = -7840632153011361661L;
188

    
189
        public ShowFindDialogAction() {
190
            super(uimanager.getTranslation("find_Xhorizontal_ellipsisX"));
191
            int c = getToolkit().getMenuShortcutKeyMask();
192
            putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F, c));
193
            putValue(ACTION_COMMAND_KEY, "ShowFindDialog");
194
        }
195

    
196
        @Override
197
        public void actionPerformed(ActionEvent e) {
198
            if (replaceDialog.isVisible()) {
199
                replaceDialog.setVisible(false);
200
            }
201
            findDialog.setVisible(true);
202
        }
203

    
204
        @Override
205
        public boolean isEnabled() {
206
            DockedPanel panel = dock.getSelected(Dock.DOCK_CENTER);
207
            return panel != null && panel.getComponent() instanceof JCodeEditor;
208
        }
209
    }
210

    
211
    private class ShowReplaceDialogAction extends AbstractAction {
212

    
213
        private static final long serialVersionUID = 7209167803487996060L;
214

    
215
        public ShowReplaceDialogAction() {
216
            super(uimanager.getTranslation("replace_Xhorizontal_ellipsisX"));
217
            int c = getToolkit().getMenuShortcutKeyMask();
218
            putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_H, c));
219
            putValue(ACTION_COMMAND_KEY, "ShowReplaceDialog");
220
        }
221

    
222
        @Override
223
        public void actionPerformed(ActionEvent e) {
224
            if (findDialog.isVisible()) {
225
                findDialog.setVisible(false);
226
            }
227
            replaceDialog.setVisible(true);
228
        }
229

    
230
        @Override
231
        public boolean isEnabled() {
232
            DockedPanel panel = dock.getSelected(Dock.DOCK_CENTER);
233
            return panel != null && panel.getComponent() instanceof JCodeEditor;
234
        }
235
    }
236

    
237
    private class LauncherAction extends AbstractAction {
238

    
239
        private static final long serialVersionUID = 6257776255757689286L;
240

    
241
        public LauncherAction() {
242
            super(uimanager.getTranslation("Launcher"));
243
            putValue(ACTION_COMMAND_KEY, "ShowLauncher");
244
        }
245

    
246
        @Override
247
        public void actionPerformed(ActionEvent e) {
248
            getWindowManager().showWindow(
249
                    uimanager.createLauncher().asJComponent(),
250
                    uimanager.getTranslation("Scripting_Launcher"),
251
                    WindowManager.MODE.TOOL
252
            );
253
        }
254

    
255
    }
256

    
257
    private class SelectAllAction extends AbstractAction {
258

    
259
        private static final long serialVersionUID = 2725549699989067383L;
260

    
261
        public SelectAllAction() {
262
            super(uimanager.getTranslation("Select_all"));
263
            putValue(Action.SMALL_ICON, uimanager.getIcon("edit-select-all"));
264
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Select_all"));
265
            putValue(ACTION_COMMAND_KEY, "DocumentSelectAll");
266
        }
267

    
268
        @Override
269
        public void actionPerformed(ActionEvent e) {
270
            currentScriptSelectAll();
271
        }
272

    
273
        @Override
274
        public boolean isEnabled() {
275
            DockedPanel panel = dock.getSelected(Dock.DOCK_CENTER);
276
            return panel != null && panel.getComponent() instanceof JCodeEditor;
277
        }
278

    
279
    }
280

    
281
    private class PackageScriptAction extends AbstractAction {
282

    
283
        private static final long serialVersionUID = 8020393562984016720L;
284

    
285
        public PackageScriptAction() {
286
            super(uimanager.getTranslation("_Package_script"));
287
            putValue(Action.SMALL_ICON, uimanager.getIcon("package"));
288
            putValue(ACTION_COMMAND_KEY, "PackageScript");
289
        }
290

    
291
        @Override
292
        public void actionPerformed(ActionEvent e) {
293
            createScriptPackage();
294
        }
295

    
296
    }
297

    
298
    private class AboutAction extends AbstractAction {
299

    
300
        private static final long serialVersionUID = -4928359535828269502L;
301

    
302
        public AboutAction() {
303
            super(uimanager.getTranslation("About_scripts_editor"));
304
            putValue(Action.SMALL_ICON, uimanager.getIcon("about"));
305
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("About_scripts_editor"));
306
            putValue(ACTION_COMMAND_KEY, "About");
307
        }
308

    
309
        @Override
310
        public void actionPerformed(ActionEvent e) {
311
            getWindowManager().showWindow(
312
                    getAboutUsDialog(),
313
                    uimanager.getTranslation("About_scripts_editor"),
314
                    WindowManager.MODE.WINDOW
315
            );
316
        }
317

    
318
    }
319

    
320
    private class CutAction extends AbstractAction {
321

    
322
        private static final long serialVersionUID = -8549655706085425411L;
323

    
324
        public CutAction() {
325
            super(uimanager.getTranslation("Cut"));
326
            putValue(Action.SMALL_ICON, uimanager.getIcon("edit-cut"));
327
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Cut"));
328
            putValue(ACTION_COMMAND_KEY, "DocumentCut");
329
        }
330

    
331
        @Override
332
        public void actionPerformed(ActionEvent e) {
333
            currentScriptCut();
334
        }
335

    
336
        @Override
337
        public boolean isEnabled() {
338
            DockedPanel panel = dock.getSelected(Dock.DOCK_CENTER);
339
            return panel != null && panel.getComponent() instanceof JCodeEditor;
340
        }
341

    
342
    }
343

    
344
    private class CopyAction extends AbstractAction {
345

    
346
        private static final long serialVersionUID = -6870773810752024874L;
347

    
348
        public CopyAction() {
349
            super(uimanager.getTranslation("Copy"));
350
            putValue(Action.SMALL_ICON, uimanager.getIcon("edit-copy"));
351
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Copy"));
352
            putValue(ACTION_COMMAND_KEY, "DocumentCopy");
353
        }
354

    
355
        @Override
356
        public void actionPerformed(ActionEvent e) {
357
            currentScriptCopy();
358
        }
359

    
360
        @Override
361
        public boolean isEnabled() {
362
            DockedPanel panel = dock.getSelected(Dock.DOCK_CENTER);
363
            return panel != null && panel.getComponent() instanceof JCodeEditor;
364
        }
365

    
366
    }
367

    
368
    private class PasteAction extends AbstractAction {
369

    
370
        private static final long serialVersionUID = -5829551248494873061L;
371

    
372
        public PasteAction() {
373
            super(uimanager.getTranslation("Paste"));
374
            putValue(Action.SMALL_ICON, uimanager.getIcon("edit-paste"));
375
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Paste"));
376
            putValue(ACTION_COMMAND_KEY, "DocumentPaste");
377
        }
378

    
379
        @Override
380
        public void actionPerformed(ActionEvent e) {
381
            currentScriptPaste();
382
        }
383

    
384
        @Override
385
        public boolean isEnabled() {
386
            DockedPanel panel = dock.getSelected(Dock.DOCK_CENTER);
387
            return panel != null && panel.getComponent() instanceof JCodeEditor;
388
        }
389

    
390
    }
391

    
392
    private class ExitAction extends AbstractAction {
393

    
394
        private static final long serialVersionUID = 9165363564675325925L;
395

    
396
        public ExitAction() {
397
            super(uimanager.getTranslation("Close"));
398
            putValue(Action.SMALL_ICON, uimanager.getIcon("exit"));
399
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Close"));
400
            putValue(ACTION_COMMAND_KEY, "CloseComposer");
401
        }
402

    
403
        @Override
404
        public void actionPerformed(ActionEvent e) {
405
            closeAllScripts();
406
            closeWindow();
407
            if (defaultActionlistener != null) {
408
                ActionEvent event = new ActionEvent(this, CLOSE_ACTION, "close");
409
                defaultActionlistener.actionPerformed(event);
410
            }
411
        }
412

    
413
    }
414

    
415
    private class SaveAction extends AbstractAction {
416

    
417
        private static final long serialVersionUID = -870379961486387727L;
418

    
419
        public SaveAction() {
420
            super(uimanager.getTranslation("Save"));
421
            int c = getToolkit().getMenuShortcutKeyMask();
422
            putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S, c));
423
            putValue(Action.SMALL_ICON, uimanager.getIcon("doc-save"));
424
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Save"));
425
            putValue(ACTION_COMMAND_KEY, "DocumentSave");
426
        }
427

    
428
        @Override
429
        public void actionPerformed(ActionEvent e) {
430
            currentScriptSave();
431
        }
432

    
433
        @Override
434
        public boolean isEnabled() {
435
            DockedPanel panel = dock.getSelected(Dock.DOCK_CENTER);
436
            return panel != null;
437
        }
438
    }
439

    
440
    private class RunAction extends AbstractAction {
441

    
442
        private static final long serialVersionUID = 4851968883766990149L;
443

    
444
        public RunAction() {
445
            super(uimanager.getTranslation("Run"));
446
            int c = getToolkit().getMenuShortcutKeyMask();
447
//            putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0));
448
            putValue(Action.SMALL_ICON, uimanager.getIcon("run"));
449
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Run"));
450
            putValue(ACTION_COMMAND_KEY, "DocumentRun");
451
        }
452

    
453
        @Override
454
        public void actionPerformed(ActionEvent e) {
455
            currentScriptExecute();
456
        }
457

    
458
        @Override
459
        public boolean isEnabled() {
460
            DockedPanel panel = dock.getSelected(Dock.DOCK_CENTER);
461
            return panel != null;
462
        }
463
    }
464

    
465
    private class SaveAndRunAction extends AbstractAction {
466

    
467
        private static final long serialVersionUID = 4851968883766990149L;
468

    
469
        public SaveAndRunAction() {
470
            super(uimanager.getTranslation("Save and run"));
471
            int c = getToolkit().getMenuShortcutKeyMask();
472
            putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0));
473
            putValue(Action.SMALL_ICON, uimanager.getIcon("save_and_run"));
474
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Save and run"));
475
            putValue(ACTION_COMMAND_KEY, "DocumentSaveAndRun");
476
        }
477

    
478
        @Override
479
        public void actionPerformed(ActionEvent e) {
480
            currentScriptSave();
481
            currentScriptExecute();
482
        }
483

    
484
        @Override
485
        public boolean isEnabled() {
486
            DockedPanel panel = dock.getSelected(Dock.DOCK_CENTER);
487
            return panel != null;
488
        }
489
    }
490

    
491
    private class CloseAllAction extends AbstractAction {
492

    
493
        private static final long serialVersionUID = 3385142920283598457L;
494

    
495
        public CloseAllAction() {
496
            super(uimanager.getTranslation("Close_all_documents"));
497
            putValue(Action.SMALL_ICON, uimanager.getIcon("doc-closeall"));
498
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Close_all_documents"));
499
            putValue(ACTION_COMMAND_KEY, "CloseAll");
500
        }
501

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

    
507
        @Override
508
        public boolean isEnabled() {
509
            DockedPanel panel = dock.getSelected(Dock.DOCK_CENTER);
510
            return panel != null;
511
        }
512

    
513
    }
514

    
515
    private class CloseDocumentAction extends AbstractAction {
516

    
517
        private static final long serialVersionUID = 4152188500446249755L;
518

    
519
        public CloseDocumentAction() {
520
            super(uimanager.getTranslation("Close_document"));
521
            putValue(Action.SMALL_ICON, uimanager.getIcon("doc-close"));
522
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Close_current_tab"));
523
            putValue(ACTION_COMMAND_KEY, "DocumentClose");
524
        }
525

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

    
531
        @Override
532
        public boolean isEnabled() {
533
            DockedPanel panel = dock.getSelected(Dock.DOCK_CENTER);
534
            return panel != null;
535
        }
536

    
537
    }
538

    
539
    private class ShowConsoleAction extends AbstractAction {
540

    
541
        private static final long serialVersionUID = -7545333555439711068L;
542

    
543
        public ShowConsoleAction() {
544
            super(uimanager.getTranslation("Console"));
545
            putValue(Action.SMALL_ICON, uimanager.getIcon("show-console"));
546
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Show_console_panel"));
547
            putValue(ACTION_COMMAND_KEY, "ShowConsole");
548
        }
549

    
550
        @Override
551
        public void actionPerformed(ActionEvent e) {
552
            addConsolePanel();
553
        }
554
    }
555

    
556
    private class ShowProblemsAction extends AbstractAction {
557

    
558
        private static final long serialVersionUID = 5276964996914550830L;
559

    
560
        public ShowProblemsAction() {
561
            super(uimanager.getTranslation("Problems"));
562
            putValue(Action.SMALL_ICON, uimanager.getIcon("show-problems"));
563
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Show_problems_panel"));
564
            putValue(ACTION_COMMAND_KEY, "ShowProblems");
565
        }
566

    
567
        @Override
568
        public void actionPerformed(ActionEvent e) {
569
            addProblemsPanel();
570
        }
571
    }
572

    
573
    private class ShowProjectsAction extends AbstractAction {
574

    
575
        private static final long serialVersionUID = 5873598740133693862L;
576

    
577
        public ShowProjectsAction() {
578
            super(uimanager.getTranslation("Projects"));
579
            putValue(Action.SMALL_ICON, uimanager.getIcon("show-projects"));
580
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Show_projects_panel"));
581
            putValue(ACTION_COMMAND_KEY, "ShowProjects");
582
        }
583

    
584
        @Override
585
        public void actionPerformed(ActionEvent e) {
586
            addProjectsPanel();
587
        }
588
    }
589

    
590
    private class NewDocumentAction extends AbstractAction {
591

    
592
        private static final long serialVersionUID = 7889613706183211620L;
593

    
594
        public NewDocumentAction() {
595
            super(uimanager.getTranslation("New"));
596
            putValue(Action.SMALL_ICON, uimanager.getIcon("doc-add"));
597
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("New"));
598
            putValue(ACTION_COMMAND_KEY, "DocumentNew");
599
        }
600

    
601
        @Override
602
        public void actionPerformed(ActionEvent e) {
603
            try {
604
                scriptNew();
605
            } catch (Exception e1) {
606
                logger.warn("Can't create a new document", e1);
607
            }
608
        }
609

    
610
    }
611
    
612
    private class NewFolderAction extends AbstractAction {
613

    
614
        private static final long serialVersionUID = 7889613706183211620L;
615

    
616
        public NewFolderAction() {
617
            super(uimanager.getTranslation("New folder"));
618
            putValue(Action.SMALL_ICON, uimanager.getIcon("folder-add"));
619
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("New folder"));
620
            putValue(ACTION_COMMAND_KEY, "FolderNew");
621
        }
622

    
623
        @Override
624
        public void actionPerformed(ActionEvent e) {
625
            try {
626
                FolderNew();
627
            } catch (Exception e1) {
628
                logger.warn("Can't create a new folder", e1);
629
            }
630
        }
631

    
632
    }    
633

    
634
    private class ProjectEditAction extends AbstractAction {
635

    
636
        private static final long serialVersionUID = -3393464285985649074L;
637

    
638
        public ProjectEditAction() {
639
            super(uimanager.getTranslation("Edit"));
640
            putValue(Action.SMALL_ICON, uimanager.getIcon("doc-edit"));
641
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Open_edition_mode"));
642
            putValue(ACTION_COMMAND_KEY, "DocumentEdit");
643
        }
644

    
645
        @Override
646
        public void actionPerformed(ActionEvent e) {
647
            try {
648
                ScriptingUnit selectedItem = getLauncherSelectedScript();
649
                if (selectedItem instanceof ScriptingBaseScript) {
650
                    scriptEdit((ScriptingBaseScript) selectedItem);
651
                }
652
            } catch (Exception e1) {
653
                logger.warn("Can't edit document", e1);
654
            }
655
        }
656
    }
657

    
658
    private class ProjectRefreshAction extends AbstractAction {
659

    
660
        private static final long serialVersionUID = 1944121660002532563L;
661

    
662
        public ProjectRefreshAction() {
663
            super(uimanager.getTranslation("Refresh"));
664
            putValue(Action.SMALL_ICON, uimanager.getIcon("refresh"));
665
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Refresh_directories"));
666
            putValue(ACTION_COMMAND_KEY, "ProjectsRefresh");
667
        }
668

    
669
        @Override
670
        public void actionPerformed(ActionEvent e) {
671
            refreshProjects();
672
        }
673

    
674
    }
675

    
676
    private class ProjectRenameAction extends AbstractAction {
677

    
678
        private static final long serialVersionUID = 7469858242486966790L;
679

    
680
        public ProjectRenameAction() {
681
            super(uimanager.getTranslation("Rename"));
682
            putValue(Action.SMALL_ICON, uimanager.getIcon("doc-rename"));
683
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Set_file_properties"));
684
            putValue(ACTION_COMMAND_KEY, "Rename");
685
        }
686

    
687
        @Override
688
        public void actionPerformed(ActionEvent e) {
689
            try {
690
                scriptRename(getLauncherSelectedScript());
691
            } catch (Exception e1) {
692
                logger.warn("Can't rename document", e1);
693
            }
694
        }
695
    }
696

    
697
    private class ProjectMoveAction extends AbstractAction {
698

    
699
        private static final long serialVersionUID = -8857101021126773295L;
700

    
701
        public ProjectMoveAction() {
702
            super(uimanager.getTranslation("Move"));
703
            putValue(Action.SMALL_ICON, uimanager.getIcon("doc-move"));
704
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Move_files"));
705
            putValue(ACTION_COMMAND_KEY, "Move");
706
        }
707

    
708
        @Override
709
        public void actionPerformed(ActionEvent e) {
710
            try {
711
                scriptMove(getLauncherSelectedScript());
712
            } catch (Exception e1) {
713
                logger.warn("Can't move document", e1);
714
            }
715
        }
716
    }
717

    
718
    private class ProjectDeleteAction extends AbstractAction {
719

    
720
        private static final long serialVersionUID = 9039455504757742743L;
721

    
722
        public ProjectDeleteAction() {
723
            super(uimanager.getTranslation("Delete"));
724
            putValue(Action.SMALL_ICON, uimanager.getIcon("doc-remove"));
725
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Delete_selected_script"));
726
            putValue(ACTION_COMMAND_KEY, "Delete");
727
        }
728

    
729
        @Override
730
        public void actionPerformed(ActionEvent e) {
731
            try {
732
                scriptDelete(getLauncherSelectedScript(), false);
733
            } catch (Exception e1) {
734
                logger.warn("Can't delete document", e1);
735
            }
736
        }
737
    }
738

    
739
    /**
740
     * Instanciacion de un JComposer con todos sus elementos y acciones
741
     *
742
     * @param uimanager
743
     */
744
    public DefaultJScriptingComposer(final ScriptingUIManager uimanager) {
745
        loader = this.getClass().getClassLoader();
746
        this.uimanager = uimanager;
747
        this.manager = uimanager.getManager();
748
        synchronized(this.manager) {
749
            initComponents();
750
        }
751
    }
752

    
753
    @Override
754
    public JComponent asJComponent() {
755
        return this;
756
    }
757

    
758
    @Override
759
    public WindowManager getWindowManager() {
760
        return ((DefaultScriptingUIManager) (this.uimanager)).getWindowManager();
761
    }
762

    
763
    @Override
764
    public void setWindowManager(WindowManager windowsManager) {
765
        ((DefaultScriptingUIManager) (this.uimanager)).setWindowManager(windowsManager);
766
    }
767

    
768
    private void initComponents() {
769

    
770
        this.addAncestorListener(new AncestorListener() {
771

    
772
            @Override
773
            public void ancestorAdded(AncestorEvent event) {
774
                ((DefaultScriptingUIManager) uimanager).setActiveComposer(DefaultJScriptingComposer.this);
775
            }
776

    
777
            @Override
778
            public void ancestorRemoved(AncestorEvent event) {
779
                ((DefaultScriptingUIManager) uimanager).setActiveComposer(null);
780
            }
781

    
782
            @Override
783
            public void ancestorMoved(AncestorEvent event) {
784
            }
785
        });
786
        SearchListener findReplaceSearchListener = new FindReplaceSearchListener();
787

    
788
        findDialog = new FindDialog((Dialog) null, findReplaceSearchListener);
789
        replaceDialog = new ReplaceDialog((Dialog) null, findReplaceSearchListener);
790
        gotoDialog = new GoToDialog((Dialog) null);
791

    
792
        SearchContext searchContext = findDialog.getSearchContext();
793
        replaceDialog.setSearchContext(searchContext);
794

    
795
        this.menuBar = new JMenuBar();
796
        this.toolBar = new JToolBar();
797

    
798
        this.menus = new LinkedHashMap<>();
799
        this.tools = new LinkedHashMap<>();
800

    
801
        String _File = this.uimanager.getTranslation("File");
802
        String _Edit = this.uimanager.getTranslation("Edit");
803
        String _Projects = this.uimanager.getTranslation("Projects");
804
        String _Tools = this.uimanager.getTranslation("Tools");
805
        String _Help = this.uimanager.getTranslation("Help");
806
        String _View = this.uimanager.getTranslation("Show");
807

    
808
        this.addMenu(_File, null);
809
        this.addMenu(_File, new NewDocumentAction());
810
        this.addMenu(_File, new NewFolderAction());
811
        this.addMenuSeparator(_File);
812
        this.addMenu(_File, new CloseDocumentAction());
813
        this.addMenu(_File, new CloseAllAction());
814
        this.addMenuSeparator(_File);
815
        this.addMenu(_File, new RunAction());
816
        this.addMenu(_File, new SaveAndRunAction());
817
        this.addMenuSeparator(_File);
818
        this.addMenu(_File, new SaveAction());
819
        this.addMenuSeparator(_File);
820
        this.addMenu(_File, new ExitAction());
821

    
822
        this.addMenu(_Edit, null);
823
        this.addMenu(_Edit, new CutAction());
824
        this.addMenu(_Edit, new CopyAction());
825
        this.addMenu(_Edit, new PasteAction());
826
        this.addMenuSeparator(_Edit);
827
        this.addMenu(_Edit, new SelectAllAction());
828
        this.addMenuSeparator(_Edit);
829
        this.addMenu(_Edit, new ShowFindDialogAction());
830
        this.addMenu(_Edit, new ShowReplaceDialogAction());
831
        this.addMenu(_Edit, new GoToLineAction());
832

    
833
        this.addMenu(_View, null);
834
        this.addMenu(_View, new ShowProjectsAction());
835
        this.addMenu(_View, new ShowProblemsAction());
836
        this.addMenu(_View, new ShowConsoleAction());
837

    
838
        this.addMenu(_Projects, null);
839
        this.addMenu(_Projects, new ProjectEditAction());
840
        this.addMenuSeparator(_Projects);
841
        this.addMenu(_Projects, new ProjectRefreshAction());
842
        this.addMenuSeparator(_Projects);
843
        this.addMenu(_Projects, new ProjectRenameAction());
844
        this.addMenu(_Projects, new ProjectMoveAction());
845
        this.addMenu(_Projects, new ProjectDeleteAction());
846

    
847
        this.addMenu(_Tools, null);
848
        this.addMenu(_Tools, new LauncherAction());
849
        this.addMenuSeparator(_Tools);
850
        this.addMenu(_Tools, new PackageScriptAction());
851

    
852
        this.addMenu(_Help, null);
853
        this.addMenu(_Help, new AboutAction());
854

    
855
        this.addTool(new NewDocumentAction());
856
        this.addTool(new SaveAction());
857
        this.addTool(new CutAction());
858
        this.addTool(new CopyAction());
859
        this.addTool(new PasteAction());
860
        this.addTool(new RunAction());
861
        this.addTool(new SaveAndRunAction());
862

    
863
        JTabbedPaneClosable tabbedPanelLeft = new JTabbedPaneClosable(uimanager);
864
        JTabbedPaneClosable tabbedPanelBottom = new JTabbedPaneClosable(uimanager);
865
        JTabbedPaneClosable tabbedPanelCenter = new JTabbedPaneClosable(uimanager);
866

    
867
        tabbedPanelLeft.setTabPlacement(JTabbedPane.BOTTOM);
868
        tabbedPanelCenter.setPreferredSize(new Dimension(500, 300));
869
        tabbedPanelCenter.addChangeListener(new ChangeListener() {
870

    
871
            @Override
872
            public void stateChanged(ChangeEvent e) {
873
                updateMenusAndTools();
874
                try {
875
                    ((ScriptEditor)((JTabbedPane)e.getSource()).getSelectedComponent()).getJTextComponent().requestFocusInWindow();
876
                } catch(Throwable th) {
877
                    logger.debug("Can't set focus in the editor", th);
878
                }
879
            }
880
        });
881

    
882
        this.dock = new DefaultDock(
883
                tabbedPanelLeft,
884
                tabbedPanelBottom,
885
                tabbedPanelCenter
886
        );
887
        this.dock.addCloseListener(new ActionListener() {
888

    
889
            @Override
890
            public void actionPerformed(ActionEvent e) {
891
                DockedPanel panel = (DockedPanel) e.getSource();
892
                scriptClose(panel);
893
            }
894
        });
895
        //tabbedPanelBottom.setPreferredSize(new Dimension(450, 100));
896

    
897
        this.addProjectsPanel();
898
        this.addConsolePanel();
899
        this.addProblemsPanel();
900

    
901
        this.dock.select(DOCKED_CONSOLE);
902
        this.dock.select(DOCKED_PROJECTS);
903

    
904
        JSplitPane centerPanel = new JSplitPane(
905
                JSplitPane.VERTICAL_SPLIT,
906
                tabbedPanelCenter,
907
                tabbedPanelBottom
908
        );
909
        centerPanel.setResizeWeight(0.8);
910
        centerPanel.setOneTouchExpandable(true);
911

    
912
        mainPanel = new JSplitPane(
913
                JSplitPane.HORIZONTAL_SPLIT,
914
                tabbedPanelLeft,
915
                centerPanel
916
        );
917
        mainPanel.setOneTouchExpandable(true);
918

    
919
        statusBar = new DefaultStatusBar(uimanager);
920

    
921
        updateMenusAndTools();
922

    
923
        JPanel buttons = new JPanel();
924
        buttons.setLayout(new BorderLayout());
925
        buttons.add(BorderLayout.NORTH, this.menuBar);
926
        buttons.add(BorderLayout.SOUTH, this.toolBar);
927

    
928
        this.setLayout(new BorderLayout());
929
        this.add(BorderLayout.NORTH, buttons);
930
        this.add(BorderLayout.CENTER, mainPanel);
931
        this.add(BorderLayout.SOUTH, statusBar.asJComponent());
932
        this.setPreferredSize(new Dimension(800, 600));
933
    }
934

    
935
    public void addMenu(String text, Action action) {
936
        String name;
937
        if (action == null) {
938
            name = String.format("Menu%x", new Date().getTime());
939
        } else {
940
            name = (String) action.getValue(Action.ACTION_COMMAND_KEY);
941
        }
942
        this.menus.put(name, new ToolEntry(name, action, text));
943
    }
944

    
945
    public void addMenuSeparator(String text) {
946
        String name = String.format("Sep%x", new Date().getTime());
947
        this.menus.put(name, new ToolEntry(name, null, text + "/-"));
948
    }
949

    
950
    public void addTool(Action action) {
951
        String name = (String) action.getValue(Action.ACTION_COMMAND_KEY);
952
        this.tools.put(name, new ToolEntry(name, action));
953
    }
954

    
955
    public void updateMenusAndTools() {
956

    
957
        this.menuBar.removeAll();
958
        this.toolBar.removeAll();
959
        for (MenuEntry entry : this.uimanager.getComposerMenus()) {
960
            this.addMenu(entry.getText(), entry.getAction());
961
        }
962
        for (Action action : this.uimanager.getComposerTools()) {
963
            this.addTool(action);
964
        }
965

    
966
        MenuBarHelper menuBarHelper = new MenuBarHelper(menuBar);
967
        for (ToolEntry entry : menus.values()) {
968
            try {
969
                JMenuItem menu = menuBarHelper.add(entry.getText(), entry.getAction(), this);
970
                entry.setComponent(menu);
971
            } catch(Throwable th) {
972
                logger.warn("Can't add entry '"+entry.getName()+"' to the toolbar.", th);
973
            }
974
        }
975

    
976
        for (ToolEntry entry : tools.values()) {
977
            try {
978
                JButton button = new ButtonWithContext(entry.getAction());
979
                this.toolBar.add(button);
980
                entry.setComponent(button);
981
            } catch(Throwable th) {
982
                logger.warn("Can't add entry '"+entry.getName()+"' to the toolbar.", th);
983
            }
984
            
985
        }
986
        this.menuBar.repaint();
987
        this.toolBar.repaint();
988
    }
989

    
990
    public void addProblemsPanel() {
991
        DockedPanel panel = this.dock.get(DOCKED_PROBLEMS);
992
        if (panel != null) {
993
            panel.select();
994
            return;
995
        }
996
        final Problems problems = new DefaultProblems(this.uimanager);
997
        problems.addListSelectionListener(new ListSelectionListener() {
998

    
999
            @Override
1000
            public void valueChanged(ListSelectionEvent e) {
1001
                if (e.getValueIsAdjusting()) {
1002
                    return;
1003
                }
1004
                Problem row = problems.getSelect();
1005
                if (row != null) {
1006
                    JEditor editor;
1007
                    int lineno = row.getLineNumber();
1008
                    if( row.getResource() == null ) {
1009
                        editor = getCurrentEditor();
1010
                    } else {
1011
                        String id = row.getResource().getAbsolutePath();
1012
                        DockedPanel panel = getDock().get(id);
1013
                        if( panel == null ) {
1014
                            ScriptingBaseScript script = manager.getScript(row.getResource());
1015
                            scriptEdit(script);
1016
                            panel = getDock().get(id);
1017
                            if( panel == null ) {
1018
                                logger.warn("Can't load script '"+id+"'.");
1019
                                return;
1020
                            }
1021
                        } 
1022
                        panel.select();
1023
                        editor = (JEditor) panel.getComponent();
1024
                    }
1025
                    if ( editor instanceof JCodeEditor) {
1026
                        ((JCodeEditor) editor).gotoline(lineno);
1027
                    }
1028
                }
1029
            }
1030
        });
1031
        this.dock.add(
1032
                DOCKED_PROBLEMS,
1033
                this.uimanager.getTranslation("Problems"),
1034
                problems,
1035
                Dock.DOCK_BOTTOM
1036
        );
1037
        this.dock.select(DOCKED_PROBLEMS);
1038
    }
1039

    
1040
    public void addConsolePanel() {
1041
        DockedPanel panel = this.dock.get(DOCKED_CONSOLE);
1042
        if (panel != null) {
1043
            panel.select();
1044
            return;
1045
        }
1046
        DefaultJScriptingConsole console = new DefaultJScriptingConsole(true);
1047
        this.dock.add(
1048
                DOCKED_CONSOLE,
1049
                this.uimanager.getTranslation("Console"),
1050
                console,
1051
                Dock.DOCK_BOTTOM
1052
        );
1053
        this.dock.select(DOCKED_CONSOLE);
1054
    }
1055

    
1056
    public void addProjectsPanel() {
1057
        DockedPanel panel = this.dock.get(DOCKED_PROJECTS);
1058
        if (panel != null) {
1059
            panel.select();
1060
            return;
1061
        }
1062
        JScriptingLauncher launcher = uimanager.createLauncher();
1063
        launcher.addDefaultActionListener(new ActionListener() {
1064

    
1065
            @Override
1066
            public void actionPerformed(ActionEvent e) {
1067
                BrowserActionEvent e2 = (BrowserActionEvent) e;
1068
                switch (e.getID()) {
1069
                    case JScriptingBrowser.DEFAULT_ACTION:
1070
                        if( uimanager.hasEditor(e2.getUnit()) ) {
1071
                            scriptEdit(e2.getUnit());
1072
                        }
1073
                        break;
1074
                    case JScriptingBrowser.DROPDOWN_ACTION:
1075
                    case JScriptingBrowser.SELECTION_ACTION:
1076
                        break;
1077
                }
1078
            }
1079
        });
1080
        launcher.asJComponent().setPreferredSize(new Dimension(200, 450));
1081

    
1082
        this.dock.add(
1083
                DOCKED_PROJECTS,
1084
                this.uimanager.getTranslation("Projects"),
1085
                launcher,
1086
                Dock.DOCK_LEFT
1087
        );
1088
        this.dock.select(DOCKED_PROJECTS);
1089
    }
1090

    
1091
    @Override
1092
    public Problems getProblems() {
1093
        DockedPanel panel = this.dock.get(DOCKED_PROBLEMS);
1094
        if (panel == null) {
1095
            return null;
1096
        }
1097
        return (Problems) panel.getComponent();
1098
    }
1099

    
1100
    @Override
1101
    public JScriptingLauncher getProjects() {
1102
        DockedPanel panel = this.dock.get(DOCKED_PROJECTS);
1103
        if (panel == null) {
1104
            return null;
1105
        }
1106
        return (JScriptingLauncher) panel.getComponent();
1107
    }
1108

    
1109
    @Override
1110
    public Dock getDock() {
1111
        return dock;
1112
    }
1113

    
1114
    @Override
1115
    public JScriptingConsole getConsole() {
1116
        DockedPanel panel = this.dock.get(DOCKED_CONSOLE);
1117
        if (panel == null) {
1118
            return null;
1119
        }
1120
        return (JScriptingConsole) panel.getComponent();
1121
    }
1122

    
1123
    @Override
1124
    public void addChangeEditorListener(ChangeListener listener) {
1125
        if (this.changeEditorListeners == null) {
1126
            this.changeEditorListeners = new HashSet<>();
1127
        }
1128
        this.changeEditorListeners.add(listener);
1129
    }
1130
    
1131
    public void removeChangeEditorListener(ChangeListener listener) {
1132
        if (this.changeEditorListeners == null) {
1133
            return;
1134
        }
1135
        this.changeEditorListeners.remove(listener);
1136
    }
1137

    
1138
    public void fireChangeEditor(ChangeEvent e) {
1139
        if (this.changeEditorListeners == null) {
1140
            return;
1141
        }
1142
        for (ChangeListener listener : this.changeEditorListeners) {
1143
            try {
1144
                listener.stateChanged(e);
1145
            } catch (Throwable th) {
1146

    
1147
            }
1148
        }
1149
    }
1150

    
1151
    private void createScriptPackage() {
1152
        I18nManager i18nManager = ToolsLocator.getI18nManager();
1153
        SwingInstallerManager installerManager = SwingInstallerLocator.getSwingInstallerManager();
1154
        PackageBuildder packager = installerManager.createPackagerPanel(
1155
                ScriptingManager.INSTALLER_PROVIDER_NAME,
1156
                manager.getRootUserFolder(),
1157
                manager.getPackagesFolder()
1158
        );
1159
        PackageInfo packageInfo = packager.getPackageInfo();
1160
        packageInfo.setArchitecture(PackageManager.ARCH.ALL);
1161
        packageInfo.setJavaVM(PackageManager.JVM.J1_7);
1162
        packageInfo.setOperatingSystem(PackageManager.OS.ALL);
1163
        packageInfo.setOfficial(false);
1164
        packageInfo.setState(PackageManager.STATE.TESTING);
1165
        packageInfo.setType(ScriptingManager.INSTALLER_PROVIDER_NAME);
1166
        Version version = ToolsLocator.getPackageManager().createVersion();
1167
        version.parse("1.0.0");
1168
        packageInfo.setVersion(version);
1169
        this.uimanager.showWindow(
1170
                (JPanel) packager.asJComponent(),
1171
                i18nManager.getTranslation("_Scripting_packager")
1172
        );
1173
    }
1174

    
1175
//    private void setEditorSelection(String name, int line) {
1176
//        for (int i = 0; i < scriptEditors.getTabCount(); i++) {
1177
//
1178
//            if (((JEditor) scriptEditors.getComponent(i)).getScript().getId().equals(name)) {
1179
//                scriptEditors.setSelectedIndex(i);
1180
//
1181
//                JCodeEditor editor = ((JCodeEditor) scriptEditors.getComponent(i));
1182
//                editor.selectLine(line);
1183
//            }
1184
//        }xxxxxxxxxxxxxxxxxxxxxxxx
1185
//    }
1186
    public void addDefaultActionListener(ActionListener actionlistener) {
1187
        this.defaultActionlistener = actionlistener;
1188
    }
1189

    
1190
    /**
1191
     * Funci?n para obtener el elemento seleccionado del Launcher
1192
     *
1193
     * @return Selected ScriptingUnit on the tree
1194
     */
1195
    private ScriptingUnit getLauncherSelectedScript() {
1196
        JScriptingBrowser browser = this.getCurrentBrowser();
1197
        ScriptingUnit unit = browser.getSelectedNode();
1198
        return unit;
1199
    }
1200
    
1201
    private JScriptingBrowser getCurrentBrowser() {
1202
        JScriptingLauncher launcher = this.getProjects();
1203
        JScriptingBrowser browser = launcher.getSelectedBrowser();
1204
        return browser;
1205
    }
1206

    
1207
//    /**
1208
//     * Lanza la ejecuci?n de un ScriptingBaseScript
1209
//     *
1210
//     * @param unit
1211
//     */
1212
//    private void scriptExecute(ScriptingUnit unit) {
1213
//        if (unit instanceof ScriptingBaseScript) {
1214
//            ((ScriptingBaseScript) unit).run();
1215
//        }
1216
//    }
1217

    
1218
    public void scriptEdit(ScriptingUnit unit) {
1219
        String id = unit.getFile().getAbsolutePath();
1220
        DockedPanel x = this.dock.get(id);
1221
        if (x != null) {
1222
            x.select();
1223
            return;
1224
        }
1225
        final JEditor editor = this.uimanager.createEditor(unit);
1226
        if (editor == null) {
1227
            JOptionPane.showMessageDialog(null, this.uimanager.getTranslation("Error_opening_in_edition_mode"), this.uimanager.getTranslation("Error_opening_in_edition_mode_title"), JOptionPane.INFORMATION_MESSAGE);
1228
            return;
1229
        }
1230
        final DockedPanel panel = this.dock.add(id, unit.getName(), editor, Dock.DOCK_CENTER);
1231
        panel.select();
1232
        editor.addChangeListener(new PropertyChangeListener() {
1233

    
1234
            @Override
1235
            public void propertyChange(PropertyChangeEvent evt) {
1236
                panel.setModified(true);
1237
                fireChangeEditor(new ChangeEvent(editor));
1238
            }
1239
        });
1240
        if (editor instanceof JCodeEditor) {
1241
            ((JCodeEditor) editor).addUpdateCaretPositionActionListener(new ActionListener() {
1242

    
1243
                @Override
1244
                public void actionPerformed(ActionEvent e) {
1245
                    UpdateCaretPositionActionEvent event = (UpdateCaretPositionActionEvent) e;
1246
                    getStatusbar().setPosition(
1247
                            event.getLine(),
1248
                            event.getColumn()
1249
                    );
1250
                }
1251
            });
1252
        }
1253
        ScriptingUnit xx = editor.getUnit();
1254
        if (xx instanceof ScriptingScript ) {
1255
            ((ScriptingScript)xx).addObserver(this);
1256
        }
1257
    }
1258

    
1259
    /**
1260
     * Ventana para creaci?n de nuevos ScriptingBaseScripts
1261
     *
1262
     * @throws Exception
1263
     *
1264
     */
1265
    public void scriptNew() throws Exception {
1266
        this.unitNew(false);
1267
    }
1268

    
1269
    public void FolderNew() throws Exception {
1270
        this.unitNew(true);
1271
    }
1272

    
1273
    public void unitNew(boolean folder) throws Exception {
1274
        JNewScriptModel model = new JNewScriptModel(manager);
1275
        model.setSelectionPath(this.getCurrentBrowser().getSelectionPath());
1276
        JDialogContent dialog = new JDialogContent(
1277
                uimanager,
1278
                "document-new",
1279
                this.uimanager.getTranslation("New_Script"),
1280
                this.uimanager.getTranslation("New_Script_Description"),
1281
                new JNewScriptPanel(uimanager, model,folder)
1282
        );
1283
        dialog.showDialog();
1284
        if (model.getAction() == JNewScriptModel.ACTION_ACCEPT) {
1285
            model.validate();
1286
            ScriptingUnit unit = this.manager.createUnit(
1287
                    model.getType(),
1288
                    manager.getFolder(model.getPath()),
1289
                    model.getName(),
1290
                    model.getLanguage()
1291
            );
1292
            if (unit instanceof ScriptingBaseScript) {
1293
                this.scriptEdit((ScriptingBaseScript) unit);
1294
            }
1295

    
1296
            this.refreshProjects();
1297
        }
1298
    }
1299

    
1300

    
1301
    public void scriptClose(DockedPanel panel) {
1302
        if (!panel.isModified()) {
1303
            panel.remove();
1304
            return;
1305
        }
1306
        panel.select();
1307
        I18nManager i18nManager = ToolsLocator.getI18nManager();
1308
        int respuesta = JOptionPane.showConfirmDialog(
1309
                this,
1310
                i18nManager.getTranslation("_The_script_XscriptnameX_is_modified",
1311
                        new String[]{panel.getTitle()})
1312
                + "\n\n"
1313
                + i18nManager.getTranslation("_Do_you_want_to_save_changes_XquestionX"),
1314
                i18nManager.getTranslation("_Save_changes_XquestionX"),
1315
                JOptionPane.YES_NO_CANCEL_OPTION
1316
        );
1317
        switch (respuesta) {
1318
            case JOptionPane.YES_OPTION:
1319
                currentScriptSave();
1320
                panel.remove();
1321
                break;
1322
            case JOptionPane.NO_OPTION:
1323
                panel.remove();
1324
                break;
1325
            default:
1326
            case JOptionPane.CANCEL_OPTION:
1327
                break;
1328
        }
1329
    }
1330

    
1331
    public void scriptMove(final ScriptingUnit theUnit) throws Exception {
1332
        if (theUnit.getParent() == null) {
1333
            JOptionPane.showMessageDialog(null, "Please, select first the file to move on the tree directory", "Error", JOptionPane.ERROR_MESSAGE);
1334
        } else {
1335
            JMoveScriptModel model = new JMoveScriptModel(manager, theUnit);
1336
            JDialogContent dialog = new JDialogContent(
1337
                    uimanager,
1338
                    "format-indent-more",
1339
                    this.uimanager.getTranslation("Move") + " '" + theUnit.getName() + "' " + this.uimanager.getTranslation("script_filesystem"),
1340
                    this.uimanager.getTranslation("move_desc"),
1341
                    new JMoveScriptPanel(uimanager, model)
1342
            );
1343
            dialog.showDialog();
1344
            if (model.getAction() == JMoveScriptModel.ACTION_ACCEPT) {
1345
                model.validate();
1346
                ScriptingFolder folderDest = manager.getFolder(model.getMoveTo());
1347
                if (model.getUnit().move(folderDest)) {
1348
                    JOptionPane.showMessageDialog(null,
1349
                            this.uimanager.getTranslation("Moving_succesfully"),
1350
                            this.uimanager.getTranslation("Success"), JOptionPane.INFORMATION_MESSAGE);
1351
                    this.refreshProjects();
1352
                } else {
1353
                    JOptionPane.showMessageDialog(null,
1354
                            this.uimanager.getTranslation("Error_moving"),
1355
                            this.uimanager.getTranslation("Error"), JOptionPane.ERROR_MESSAGE);
1356
                }
1357
            }
1358
        }
1359

    
1360
    }
1361

    
1362
    public void scriptRename(ScriptingUnit theUnit) throws Exception {
1363
        if (theUnit.getParent() == null) {
1364
            JOptionPane.showMessageDialog(null,
1365
                    this.uimanager.getTranslation("Select_first"),
1366
                    this.uimanager.getTranslation("Error"), JOptionPane.ERROR_MESSAGE);
1367
        } else {
1368
            JRenameModel model = new JRenameModel(manager, theUnit);
1369
            JDialogContent dialog = new JDialogContent(
1370
                    uimanager,
1371
                    "preferences-system",
1372
                    this.uimanager.getTranslation("Rename") + " '" + theUnit.getName() + "' " + this.uimanager.getTranslation("script_filesystem"),
1373
                    this.uimanager.getTranslation("rename_desc"),
1374
                    new JRenamePanel(uimanager, model)
1375
            );
1376
            dialog.showDialog();
1377
            if (model.getAction() == JRenameModel.ACTION_ACCEPT) {
1378
                model.validate();
1379
                ScriptingUnit unit = model.getUnit();
1380
                if (!model.getNewName().equals(unit.getId())) {
1381
                    if (unit.rename(model.getNewName())) {
1382
                        JOptionPane.showMessageDialog(null,
1383
                                this.uimanager.getTranslation("Rename_succesfully"),
1384
                                this.uimanager.getTranslation("Success"), JOptionPane.INFORMATION_MESSAGE);
1385
                        this.refreshProjects();
1386
                    } else {
1387
                        JOptionPane.showMessageDialog(null,
1388
                                this.uimanager.getTranslation(this.uimanager.getTranslation("Error_renaming")),
1389
                                this.uimanager.getTranslation("Error"), JOptionPane.ERROR_MESSAGE);
1390
                    }
1391
                    if (unit instanceof ScriptingScript) {
1392
                        ((ScriptingScript) unit).save();
1393
                    }
1394
                }
1395
            }
1396
        }
1397
    }
1398

    
1399
    @Override
1400
    public JPanel getAboutUsDialog() {
1401
        return new JDialogContent(uimanager,
1402
                "system-users",
1403
                this.uimanager.getTranslation("About_us"),
1404
                this.uimanager.getTranslation("About_us_title"),
1405
                new JDefaultDialog(uimanager, this, uimanager.getAboutManager().getAboutPanel()));
1406
    }
1407

    
1408
    public void scriptDelete(final ScriptingUnit unit, boolean isRecursive) {
1409
        int n = 0;
1410
        if (!isRecursive) {
1411
            n = JOptionPane.showConfirmDialog(
1412
                    this.getRootPane(),
1413
                    this.uimanager.getTranslation("Delete_all_message"),
1414
                    this.uimanager.getTranslation("Delete_all_title"),
1415
                    JOptionPane.YES_NO_OPTION);
1416
        }
1417
        if (n == 0) {
1418
            //Si es un folder borramos recursivamente sus subdirectorios
1419
            if (unit instanceof ScriptingFolder) {
1420
                List<ScriptingUnit> subunits
1421
                        = ((ScriptingFolder) unit).getUnits();
1422
                Iterator<ScriptingUnit> it = subunits.iterator();
1423
                while (it.hasNext()) {
1424
                    ScriptingUnit subunit = it.next();
1425
                    scriptDelete(subunit, true);
1426
                }
1427
            }
1428
            // Por ?ltimo borramos el nodo seleccionado
1429
            unit.getParent().remove(unit);
1430
            this.refreshProjects();
1431

    
1432
        }
1433
    }
1434

    
1435
    /**
1436
     * Funci?n que cierra la pesta?a de edici?n actual
1437
     *
1438
     */
1439
    public void currentScriptClose() {
1440
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1441
        if (panel == null) {
1442
            return;
1443
        }
1444
        scriptClose(panel);
1445
    }
1446

    
1447
    /**
1448
     * Close all editor tabs of the composer
1449
     */
1450
    public void closeAllScripts() {
1451
        List<DockedPanel> modifiedPanels = new ArrayList<>();
1452
        List<DockedPanel> toRemove = new ArrayList<>();
1453

    
1454
        for (DockedPanel panel : this.dock) {
1455
            if (Dock.DOCK_CENTER.equals(panel.getAlign())) {
1456
                if (panel.isModified()) {
1457
                    modifiedPanels.add(panel);
1458
                } else {
1459
                    toRemove.add(panel);
1460
                }
1461
            }
1462
        }
1463
        if (modifiedPanels.isEmpty() && toRemove.isEmpty()) {
1464
            return;
1465
        }
1466
        int action = JOptionPane.showConfirmDialog(
1467
                this,
1468
                this.uimanager.getTranslation("projects_modified"),
1469
                this.uimanager.getTranslation("projects_modified_title"),
1470
                JOptionPane.YES_NO_CANCEL_OPTION
1471
        );
1472
        switch (action) {
1473
            case JOptionPane.CANCEL_OPTION:
1474
                return;
1475
            case JOptionPane.YES_OPTION:
1476
                for (DockedPanel panel : modifiedPanels) {
1477
                    JEditor editor = (JEditor) panel.getComponent();
1478
                    if (editor.getUnit()!= null) {
1479
                        editor.getUnit().setSaved(true);
1480
                    }
1481
                    editor.save();
1482
                    toRemove.add(panel);
1483
                }
1484
                break;
1485
            case JOptionPane.NO_OPTION:
1486
                for (DockedPanel panel : modifiedPanels) {
1487
                    JEditor editor = (JEditor) panel.getComponent();
1488
                    if (editor.getUnit() != null) {
1489
                        editor.getUnit().setSaved(true);
1490
                    }
1491
                    toRemove.add(panel);
1492
                }
1493
        }
1494
        if( toRemove.isEmpty() ) {
1495
            return;
1496
        }
1497
        for (DockedPanel panel : toRemove) {
1498
            panel.remove();
1499
        }
1500
    }
1501

    
1502
    /**
1503
     * Funci?n que ejecuta el ScriptingBaseScript de la pesta?a actual
1504
     *
1505
     */
1506
    public void currentScriptExecute() {
1507
        ScriptingScript script = this.getCurrentScript();
1508
        if (script != null) {
1509
            Problems problems = this.getProblems();
1510
            if (problems != null) {
1511
                problems.removeAll();
1512
            }
1513
            JScriptingConsole console = this.getConsole();
1514
            if (console == null) {
1515
                addConsolePanel();
1516
            } else {
1517
                console.clear();
1518
            }
1519
            script.addObserver(this);
1520
            script.addStdoutWriter(this.getConsole().getOutputWriter());
1521
            script.addStderrWriter(this.getConsole().getErrorsWriter());
1522
            try {
1523
                script.compile();
1524
                script.runAsTask(null);
1525
            } catch (Throwable e) {
1526
                logger.info("Can't execute script", e);
1527
            }
1528
        }
1529
    }
1530

    
1531
    /**
1532
     * Funciones de 'cortar', 'copiar', 'pegar' y 'seleccionar todo' para los
1533
     * JEditors
1534
     *
1535
     */
1536
    public void currentScriptCopy() {
1537
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1538
        if (panel.getComponent().asJComponent() instanceof JCodeEditor) {
1539
            JCodeEditor editor = (JCodeEditor) panel.getComponent().asJComponent();
1540
            editor.getJTextComponent().copy();
1541
        }
1542
    }
1543

    
1544
    public void currentScriptCut() {
1545
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1546
        if (panel.getComponent().asJComponent() instanceof JCodeEditor) {
1547
            JCodeEditor editor = (JCodeEditor) panel.getComponent().asJComponent();
1548
            editor.getJTextComponent().cut();
1549
            panel.setModified(true);
1550
        }
1551
    }
1552

    
1553
    public void currentScriptPaste() {
1554
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1555
        if (panel.getComponent().asJComponent() instanceof JCodeEditor) {
1556
            JCodeEditor editor = (JCodeEditor) panel.getComponent().asJComponent();
1557
            editor.getJTextComponent().paste();
1558
            panel.setModified(true);
1559
        }
1560
    }
1561

    
1562
    public void currentScriptSelectAll() {
1563
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1564
        if (panel.getComponent().asJComponent() instanceof JCodeEditor) {
1565
            JCodeEditor editor = (JCodeEditor) panel.getComponent().asJComponent();
1566
            editor.getJTextComponent().selectAll();
1567
        }
1568
    }
1569

    
1570
    /**
1571
     * Funci?n para el guardado del ScriptingBaseScript de la pesta?a actual
1572
     *
1573
     */
1574
    public void currentScriptSave() {
1575
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1576
        if (panel.getComponent().asJComponent() instanceof JEditor) {
1577
            JEditor editor = (JEditor) panel.getComponent().asJComponent();
1578
            editor.save();
1579
            panel.setModified(false);
1580
        }
1581
    }
1582

    
1583
    @Override
1584
    public JEditor getCurrentEditor() {
1585
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1586
        if (panel == null) {
1587
            return null;
1588
        }
1589
        if (panel.getComponent().asJComponent() instanceof JEditor) {
1590
            return (JEditor) panel.getComponent().asJComponent();
1591
        }
1592
        return null;
1593
    }
1594

    
1595
    @Override
1596
    public ScriptingScript getCurrentScript() {
1597
        JEditor editor = this.getCurrentEditor();
1598
        if (editor == null) {
1599
            return null;
1600
        }
1601
        ScriptingUnit unit = editor.getUnit();
1602
        if( unit instanceof ScriptingScript ) {
1603
            return (ScriptingScript) unit;
1604
        }
1605
        return null;
1606
    }
1607

    
1608
    private RSyntaxTextArea getCurrentRSyntaxTextArea() {
1609
        JEditor editor = getCurrentEditor();
1610
        if (editor instanceof JCodeEditor) {
1611
            JTextComponent textComponent = ((JCodeEditor) editor).getJTextComponent();
1612
            if (textComponent instanceof RSyntaxTextArea) {
1613
                return (RSyntaxTextArea) textComponent;
1614
            }
1615
        }
1616
        return null;
1617
    }
1618

    
1619
    @Override
1620
    public void refreshProjects() {
1621
        try {
1622
            this.getProjects().refresh();
1623
        } catch (Exception ex) {
1624
            // Ignore
1625
        }
1626
    }
1627

    
1628
    @Override
1629
    public StatusBar getStatusbar() {
1630
        return this.statusBar;
1631
    }
1632

    
1633
    /**
1634
     *
1635
     * @param e
1636
     */
1637
    @Override
1638
    public void actionPerformed(ActionEvent e) {
1639

    
1640
        if (e instanceof UpdateCaretPositionActionEvent) {
1641
            UpdateCaretPositionActionEvent e2 = (UpdateCaretPositionActionEvent) e;
1642

    
1643
            if (e2.hasLineAndColumn()) {
1644
                this.getStatusbar().setPosition(e2.getLine(), e2.getColumn());
1645
            } else {
1646
                this.getStatusbar().setPosition(0, 0);
1647
            }
1648
        }
1649
    }
1650

    
1651
    @Override
1652
    public void update(final Observable observable, final Object notification) {
1653
        if (!SwingUtilities.isEventDispatchThread()) {
1654
            SwingUtilities.invokeLater(new Runnable() {
1655
                @Override
1656
                public void run() {
1657
                    update(observable, notification);
1658
                }
1659
            });
1660
            return;
1661
        }
1662
        if (notification instanceof ScriptingNotification) {
1663
            ScriptingNotification e = (ScriptingNotification) notification;
1664

    
1665
            if (e.getException() instanceof CompileErrorException) {
1666
                CompileErrorException ce = (CompileErrorException) e.getException();
1667
                Problems problems = this.getProblems();
1668
                if (problems != null) {
1669
                    problems.add("Error", ce);
1670
                    this.dock.select(DOCKED_PROBLEMS);
1671
                }
1672

    
1673
            } else if (e.getException() instanceof ExecuteErrorException) {
1674
                ExecuteErrorException ee = (ExecuteErrorException) e.getException();
1675
                Problems problems = this.getProblems();
1676
                if (problems != null) {
1677
                    problems.add("Error",ee);
1678
                    this.dock.select(DOCKED_PROBLEMS);
1679
                }
1680
                JScriptingConsole console = this.getConsole();
1681
                if (console != null) {
1682
                    console.append(ee.getMessage(), Color.RED.darker());
1683
                    ee.printStackTrace(console.errors());
1684
                }
1685

    
1686
            } else {
1687
                Exception ex = e.getException();
1688
                Problems problems = this.getProblems();
1689
                if (problems != null) {
1690
                    problems.add("Error",ex); 
1691
                    this.dock.select(DOCKED_PROBLEMS);
1692
                }
1693
                JScriptingConsole console = this.getConsole();
1694
                if (console != null) {
1695
                    console.append(ex.getMessage(), Color.RED.darker());
1696
                    ex.printStackTrace(console.errors());
1697
                }
1698
            }
1699
        }
1700
    }
1701

    
1702
    public void closeWindow() {
1703
        this.setVisible(false);
1704
    }
1705

    
1706
    private static class DefaultStatusBar extends JPanel implements StatusBar {
1707

    
1708
        private static final long serialVersionUID = -6135634992327170084L;
1709

    
1710
        private JLabel message;
1711
        private JLabel position;
1712
        private final ScriptingUIManager uimanager;
1713

    
1714
        public DefaultStatusBar(ScriptingUIManager uimanager) {
1715
            this.uimanager = uimanager;
1716
            this.initComponents();
1717
        }
1718

    
1719
        private void initComponents() {
1720
            this.message = new JLabel(this.uimanager.getTranslation("Welcome_message"));
1721
            this.position = new JLabel("Line 0:0");
1722

    
1723
            this.setLayout(new BorderLayout());
1724

    
1725
            this.add(this.message, BorderLayout.WEST);
1726
            this.add(this.position, BorderLayout.EAST);
1727
        }
1728

    
1729
        @Override
1730
        public void clear() {
1731
            this.message.setText("");
1732
        }
1733

    
1734
        @Override
1735
        public void message(String message) {
1736
            this.message.setText(message);
1737
        }
1738

    
1739
        @Override
1740
        public void setPosition(int line) {
1741
            this.setPosition(line, -1);
1742
        }
1743

    
1744
        @Override
1745
        public void setPosition(int line, int column) {
1746
            if (line < 0) {
1747
                this.position.setText("");
1748
                return;
1749
            }
1750
            if (column < 0) {
1751
                this.position.setText(this.uimanager.getTranslation("Line") + " " + line + ":0");
1752
            } else {
1753
                this.position.setText(this.uimanager.getTranslation("Line") + " " + line + ":" + column);
1754
            }
1755
        }
1756

    
1757
        @Override
1758
        public JComponent asJComponent() {
1759
            return this;
1760
        }
1761
    }
1762

    
1763
    public static class JTabbedPaneClosable extends JTabbedPane {
1764

    
1765
        private static final long serialVersionUID = -3995298424891579555L;
1766

    
1767
        private final ActionListenerSupport closeTabListeners;
1768
        private ScriptingUIManager uimanager;
1769

    
1770
        private class TabTitleComponent extends JPanel {
1771

    
1772
            private static final long serialVersionUID = -1061417669527944341L;
1773
            private final JLabel label;
1774
            private final JButton button;
1775
            private boolean changed = false;
1776
            private final Font fontNormal;
1777
            private final Font fontBold;
1778

    
1779
            public TabTitleComponent(String title, final ActionListener onclose) {
1780
                this.setOpaque(true);
1781
                this.label = new JLabel(title + " ");
1782
                this.label.setOpaque(true);
1783
                this.label.setBackground(UIManager.getColor("TabbedPane.tabAreaBackground"));
1784
                this.label.setVerticalTextPosition(SwingConstants.CENTER);
1785
                this.fontNormal = this.label.getFont();
1786
                this.fontBold = new Font(this.fontNormal.getFontName(), Font.BOLD, this.fontNormal.getSize());
1787

    
1788
                this.button = new JButton();
1789
                this.button.setText("");
1790
                this.button.setToolTipText(uimanager.getTranslation("Close_tab"));
1791
                this.button.setBackground(UIManager.getColor("TabbedPane.tabAreaBackground"));
1792
                this.button.setBorder(BorderFactory.createEmptyBorder());
1793
                this.button.setBorderPainted(false);
1794
                this.button.setFocusPainted(false);
1795
                this.button.setContentAreaFilled(false);
1796
                this.button.setCursor(new Cursor(Cursor.HAND_CURSOR));
1797
                this.button.setRolloverEnabled(true);
1798
                this.button.setIcon(uimanager.getIcon("tabclose-inactive"));
1799
                this.button.setRolloverIcon(uimanager.getIcon("tabclose-active"));
1800
                this.button.addActionListener(new ActionListener() {
1801
                    @Override
1802
                    public void actionPerformed(ActionEvent ae) {
1803
                        ae.setSource(TabTitleComponent.this);
1804
                        onclose.actionPerformed(ae);
1805
                    }
1806
                });
1807
                this.setLayout(new BorderLayout());
1808
                this.add(this.label, BorderLayout.CENTER);
1809
                this.add(this.button, BorderLayout.EAST);
1810
            }
1811

    
1812
            public void setTitle(String title) {
1813
                this.label.setText(title);
1814
            }
1815

    
1816
            public String getTitle() {
1817
                return this.label.getText();
1818
            }
1819

    
1820
            public void setChanged(boolean changed) {
1821
                if (changed) {
1822
                    this.label.setFont(this.fontBold);
1823
                } else {
1824
                    this.label.setFont(this.fontNormal);
1825
                }
1826
                this.changed = changed;
1827
            }
1828

    
1829
            public boolean isChanged() {
1830
                return this.changed;
1831
            }
1832
        }
1833

    
1834
        public JTabbedPaneClosable(ScriptingUIManager uimanager) {
1835
            super();
1836
            this.uimanager = uimanager;
1837
            this.closeTabListeners = ToolsSwingLocator.getToolsSwingManager().createActionListenerSupport();
1838
        }
1839

    
1840
        @Override
1841
        public String getTitleAt(int index) {
1842
            TabTitleComponent title = (TabTitleComponent) this.getTabComponentAt(index);
1843
            if (title == null) {
1844
                return null;
1845
            }
1846
            return title.getTitle();
1847
        }
1848

    
1849
        @Override
1850
        public void setTitleAt(int index, String title) {
1851
            TabTitleComponent titleComponent = (TabTitleComponent) this.getTabComponentAt(index);
1852
            titleComponent.setTitle(title);
1853
        }
1854

    
1855
        @Override
1856
        public void addTab(String title, java.awt.Component component) {
1857
            super.addTab(null, component);
1858
            int index = getTabCount() - 1;
1859
            TabTitleComponent tabcomponent = new TabTitleComponent(title, new ActionListener() {
1860

    
1861
                @Override
1862
                public void actionPerformed(ActionEvent ae) {
1863
                    TabTitleComponent tabTitleComponent = (TabTitleComponent) ae.getSource();
1864
                    int index = indexOfTabComponent(tabTitleComponent);
1865
                    setSelectedIndex(index);
1866
                    ae.setSource(JTabbedPaneClosable.this);
1867
                    closeTabListeners.fireActionEvent(ae);
1868
                }
1869
            });
1870
            super.setTabComponentAt(index, tabcomponent);
1871
        }
1872

    
1873
        public void addCloseTabListener(ActionListener remove) {
1874
            this.closeTabListeners.addActionListener(remove);
1875
        }
1876

    
1877
        public void removeCloseTabListener(ActionListener remove) {
1878
            this.closeTabListeners.removeActionListener(remove);
1879
        }
1880

    
1881
        public ActionListener[] getCloseTabListeners() {
1882
            return this.closeTabListeners.getActionListeners();
1883
        }
1884

    
1885
        public boolean isTabModified(int index) {
1886
            TabTitleComponent comp = (TabTitleComponent) this.getTabComponentAt(index);
1887
            if (comp == null) {
1888
                return false;
1889
            }
1890
            return comp.isChanged();
1891
        }
1892

    
1893
        public void setTabModified(int index, boolean changed) {
1894
            TabTitleComponent comp = (TabTitleComponent) this.getTabComponentAt(index);
1895
            if (comp != null) {
1896
                comp.setChanged(changed);
1897
            }
1898
        }
1899
    }
1900

    
1901
    public static class DefaultProblems extends JPanel implements Problems {
1902

    
1903
        private static final long serialVersionUID = 7728033081188167969L;
1904

    
1905
        private static final int COLUMN_TYPE = 0;
1906
        private static final int COLUMN_MESSAGE = 1;
1907
        private static final int COLUMN_RESOURCE = 2;
1908
        private static final int COLUMN_LOCATION = 3;
1909
        private static final int NUM_COLUMNS = 4;
1910

    
1911
        private JTable table;
1912
        private ProblemsTableMode tableModel;
1913
        private final ScriptingUIManager uimanager;
1914
        private Set<ListSelectionListener> selectionListeners; 
1915

    
1916
        public static class ProblemsTableMode extends DefaultTableModel implements TableModel {
1917
            private static final long serialVersionUID = -3294067602561419422L;
1918

    
1919
            public static class DefaultProblem implements Problem {
1920

    
1921
                String[] row;
1922
                private File resource;
1923

    
1924
                public DefaultProblem() {
1925
                    this.row = new String[NUM_COLUMNS];
1926
                }
1927

    
1928
                public DefaultProblem(String[] row) {
1929
                    this.row = row;
1930
                }
1931

    
1932
                public DefaultProblem(String type, String message, String resourceName, String location, File resource) {
1933
                    String[] row = new String[NUM_COLUMNS];
1934
                    row[COLUMN_TYPE] = type;
1935
                    row[COLUMN_MESSAGE] = message;
1936
                    row[COLUMN_RESOURCE] = resourceName;
1937
                    row[COLUMN_LOCATION] = location;
1938
                    this.resource = resource;
1939
                    this.row = row;
1940
                }
1941

    
1942
                public String get(int index) {
1943
                    return row[index];
1944
                }
1945

    
1946
                public String getValue(int index) {
1947
                    return row[index];
1948
                }
1949

    
1950
                public void setValue(int index, String value) {
1951
                    row[index] = value;
1952
                }
1953

    
1954
                @Override
1955
                public String getType() {
1956
                    return this.row[COLUMN_TYPE];
1957
                }
1958

    
1959
                @Override
1960
                public String getMessage() {
1961
                    return this.row[COLUMN_MESSAGE];
1962
                }
1963

    
1964
                @Override
1965
                public String getResourceName() {
1966
                    return this.row[COLUMN_RESOURCE];
1967
                }
1968

    
1969
                @Override
1970
                public File getResource() {
1971
                    return this.resource;
1972
                }
1973

    
1974
                @Override
1975
                public int getLineNumber() {
1976
                    try {
1977
                        String[] lineAndColumn = this.row[COLUMN_LOCATION].split(":");
1978
                        if (lineAndColumn.length > 0) {
1979
                            int lineno = Integer.parseInt(lineAndColumn[0].trim());
1980
                            return lineno;
1981
                        }
1982
                    } catch (Exception e) {
1983
                        // Do nothing
1984
                    }
1985
                    return -1;
1986
                }
1987

    
1988
            }
1989
            private final ScriptingUIManager uimanager;
1990
            private List<DefaultProblem> data;
1991
            private String[] columnNames;
1992

    
1993
            public ProblemsTableMode(ScriptingUIManager uimanager) {
1994
                this.uimanager = uimanager;
1995
                this.columnNames = new String[]{
1996
                    this.uimanager.getTranslation("Category"),
1997
                    this.uimanager.getTranslation("Description"),
1998
                    this.uimanager.getTranslation("Resource"),
1999
                    this.uimanager.getTranslation("Location")
2000
                };
2001

    
2002
            }
2003
            
2004
            private List<DefaultProblem> getData() {
2005
                if( this.data == null ) {
2006
                    this.data = new ArrayList<>();
2007
                }
2008
                return this.data;
2009
            }
2010

    
2011
            public void add(DefaultProblem row) {
2012
                this.getData().add(row);
2013
                this.fireTableDataChanged();
2014
            }
2015

    
2016
            private void add(String type, String message, String resourceName, String location, File resource) {
2017
                DefaultProblem problem = new DefaultProblem(type, message, resourceName, location, resource);
2018
                this.add(problem);
2019
            }
2020

    
2021
            @Override
2022
            public int getRowCount() {
2023
                return this.getData().size();
2024
            }
2025

    
2026
            @Override
2027
            public int getColumnCount() {
2028
                return NUM_COLUMNS;
2029
            }
2030

    
2031
            @Override
2032
            public String getColumnName(int columnIndex) {
2033
                return columnNames[columnIndex];
2034
            }
2035

    
2036
            @Override
2037
            public Class<?> getColumnClass(int columnIndex) {
2038
                return String.class;
2039
            }
2040

    
2041
            @Override
2042
            public boolean isCellEditable(int rowIndex, int columnIndex) {
2043
                return false;
2044
            }
2045

    
2046
            @Override
2047
            public Object getValueAt(int rowIndex, int columnIndex) {
2048
                return this.getData().get(rowIndex).get(columnIndex);
2049
            }
2050
            
2051
            public Problem getProblem(int rowIndex) {
2052
                return this.getData().get(rowIndex);
2053
            }
2054

    
2055
            @Override
2056
            public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
2057
                this.getData().get(rowIndex).setValue(columnIndex, (String) aValue);
2058
            }
2059

    
2060
            public void removeAll() {
2061
                this.getData().clear();
2062
            }
2063
        }
2064

    
2065
        public DefaultProblems(ScriptingUIManager uimanager) {
2066
            this.uimanager = uimanager;
2067
            this.initComponents();
2068
        }
2069

    
2070
        private void initComponents() {
2071
            this.selectionListeners = new HashSet<>();
2072
            tableModel = new ProblemsTableMode(this.uimanager);
2073
            table = new JTable(tableModel);
2074
            table.getColumnModel().getColumn(1).setPreferredWidth(300);
2075

    
2076
            table.setRowSelectionAllowed(true);
2077
            table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
2078

    
2079
            JScrollPane scrollProblems = new JScrollPane(table);
2080
            scrollProblems.setAutoscrolls(true);
2081

    
2082
            this.setLayout(new BorderLayout());
2083
            this.add(scrollProblems, BorderLayout.CENTER);
2084
            
2085
            // Si ya hay seleccionada una linea y vuelvo a clickar sobre ella 
2086
            // para que me lleve a la linea del editor que toque, con el
2087
            // addSelectionListener no me vuelve a lanzar el evento, asi que
2088
            // me apalanco en el mouseClicked tambien.
2089
            table.addMouseListener(new MouseAdapter(){
2090
                @Override
2091
                public void mouseClicked(MouseEvent evnt) {
2092
                    if (evnt.getClickCount() == 1) {
2093
                        fireSelectionListeners();
2094
                     }
2095
                 }
2096
            });
2097
        }
2098

    
2099
        @Override
2100
        public void addListSelectionListener(ListSelectionListener listener) {
2101
            this.table.getSelectionModel().addListSelectionListener(listener);
2102
            this.selectionListeners.add(listener);
2103
        }
2104

    
2105
        private void fireSelectionListeners() {
2106
            int row = this.table.getSelectedRow();
2107
            for( ListSelectionListener listener : this.selectionListeners ) {
2108
                try {
2109
                    listener.valueChanged(new ListSelectionEvent(this, row, row, false));
2110
                } catch(Exception th) {
2111
                    
2112
                }
2113
            }
2114
        }
2115
        
2116
        @Override
2117
        public void removeAll() {
2118
            this.tableModel.removeAll();
2119
            this.table.updateUI();
2120
        }
2121

    
2122
        @Override
2123
        public void add(String type, String message, String resource, String location) {
2124
            this.tableModel.add(type, message, resource, location, null);
2125
        }
2126

    
2127
        @Override
2128
        public void add(String type, String message, String resource, int line, int column) {
2129
            this.add(type, message, resource, line + ":" + column);
2130
        }
2131
        
2132
        public void add(String type, String message, String resourceName, int line, int column, File resource) {
2133
            this.tableModel.add(type, message, resourceName, line + ":" + column, resource);
2134
        }
2135
                
2136
        @Override
2137
        public void add(String type, Exception e) {
2138
            if (e  instanceof ScriptingErrorException) {
2139
                ScriptingErrorException se = (ScriptingErrorException) e;
2140
                    this.add(
2141
                        "Error",
2142
                        se.getMessage(),
2143
                        se.getScriptName(),
2144
                        se.getLineNumber(),
2145
                        se.getColumnNumber(),
2146
                        se.getScriptFile()
2147
                    );
2148

    
2149
            } else {
2150
                    this.add("Error", 
2151
                        "Error",
2152
                        e.getMessage(),
2153
                        null
2154
                    );
2155
            }            
2156
        }
2157

    
2158
        @Override
2159
        public Problem getSelect() {
2160
            int row = this.table.getSelectedRow();
2161
            if (row < 0) {
2162
                return null;
2163
            }
2164
            return this.get(row);
2165
        }
2166

    
2167
        @Override
2168
        public int getCount() {
2169
            return this.tableModel.getRowCount();
2170
        }
2171

    
2172
        @Override
2173
        public Problem get(int row) {
2174
            return this.tableModel.getProblem(row);
2175
        }
2176

    
2177
        @Override
2178
        public JComponent asJComponent() {
2179
            return this;
2180
        }
2181

    
2182
    }
2183

    
2184
    public static class DefaultDock extends JPanel implements Dock {
2185

    
2186
        private static final long serialVersionUID = 4899734277977456625L;
2187

    
2188
        public class DefaultDockedPanel implements DockedPanel {
2189

    
2190
            String id;
2191
            String title;
2192
            Component component;
2193
            private final String align;
2194

    
2195
            public DefaultDockedPanel(String id, String title, Component component, String align) {
2196
                this.id = id;
2197
                this.title = title;
2198
                this.component = component;
2199
                this.align = align;
2200
            }
2201

    
2202
            @Override
2203
            public String getId() {
2204
                return this.id;
2205
            }
2206

    
2207
            @Override
2208
            public String getAlign() {
2209
                return this.align;
2210
            }
2211

    
2212
            @Override
2213
            public Component getComponent() {
2214
                return this.component;
2215
            }
2216

    
2217
            @Override
2218
            public String getTitle() {
2219
                return this.title;
2220
            }
2221

    
2222
            @Override
2223
            public boolean isModified() {
2224
                return getModified(this);
2225
            }
2226

    
2227
            @Override
2228
            public void setModified(boolean modified) {
2229
                DefaultDock.this.setModified(this, modified);
2230
            }
2231

    
2232
            @Override
2233
            public void remove() {
2234
                DefaultDock.this.remove(this.getId());
2235
            }
2236

    
2237
            @Override
2238
            public void select() {
2239
                DefaultDock.this.select(this.getId());
2240
            }
2241
        }
2242

    
2243
        private final Map<String, Dock.DockedPanel> panels;
2244
        private final JTabbedPaneClosable tabbedPanelLeft;
2245
        private final JTabbedPaneClosable tabbedPanelBottom;
2246
        private final JTabbedPaneClosable tabbedPanelCenter;
2247
        private Set<ActionListener> closeListeners;
2248
        private Set<ActionListener> activePanelListeners;
2249

    
2250
        public DefaultDock(JTabbedPaneClosable tabbedPanelLeft, JTabbedPaneClosable tabbedPanelBottom, JTabbedPaneClosable tabbedPanelCenter) {
2251
            this.panels = new HashMap<>();
2252
            this.tabbedPanelBottom = tabbedPanelBottom;
2253
            this.tabbedPanelLeft = tabbedPanelLeft;
2254
            this.tabbedPanelCenter = tabbedPanelCenter;
2255

    
2256
            ActionListener onCloseTab = new ActionListener() {
2257

    
2258
                @Override
2259
                public void actionPerformed(ActionEvent e) {
2260
                    JTabbedPaneClosable tabbedPanel = (JTabbedPaneClosable) e.getSource();
2261
                    java.awt.Component component = tabbedPanel.getSelectedComponent();
2262
                    if (component != null) {
2263
                        DockedPanel panel = getDockedPanel(component);
2264
                        if (panel != null) {
2265
                            fireCloseListener(new ActionEvent(panel, 0, ACTION_CLOSE_PANEL));
2266
                        }
2267
//                        panels.remove(panel.getId());
2268
//                        tabbedPanel.remove(panel.getComponent().asJComponent());
2269
                    }
2270
                }
2271
            };
2272
            ChangeListener onChangeTab = new ChangeListener() {
2273

    
2274
                @Override
2275
                public void stateChanged(ChangeEvent e) {
2276
                    
2277
                    fireChangeListener(new ActionEvent(DefaultDock.this, 0, ACTION_ACTIVATE_PANEL));
2278
                }
2279
            };
2280
            this.tabbedPanelCenter.addChangeListener(onChangeTab);
2281
            this.tabbedPanelBottom.addChangeListener(onChangeTab);
2282
            this.tabbedPanelLeft.addChangeListener(onChangeTab);
2283
            
2284
            this.tabbedPanelBottom.addCloseTabListener(onCloseTab);
2285
            this.tabbedPanelLeft.addCloseTabListener(onCloseTab);
2286
            this.tabbedPanelCenter.addCloseTabListener(onCloseTab);
2287

    
2288
        }
2289

    
2290
        /**
2291
         *
2292
         * @param listener
2293
         */
2294
        @Override
2295
        public void addCloseListener(ActionListener listener) {
2296
            if (this.closeListeners == null) {
2297
                this.closeListeners = new HashSet<>();
2298
            }
2299
            this.closeListeners.add(listener);
2300
        }
2301
        
2302
        @Override
2303
        public void removeCloseListener(ActionListener listener) {
2304
            if (this.closeListeners == null) {
2305
                return;
2306
            }
2307
            this.closeListeners.remove(listener);
2308
        }
2309

    
2310
        @Override
2311
        public void addActivateListener(ActionListener listener) {
2312
            if (this.activePanelListeners == null) {
2313
                this.activePanelListeners = new HashSet<>();
2314
            }
2315
            this.activePanelListeners.add(listener);
2316
        }
2317
        
2318
        @Override
2319
        public void removeActivateListener(ActionListener listener) {
2320
            if (this.activePanelListeners == null) {
2321
                return;
2322
            }
2323
            this.activePanelListeners.remove(listener);
2324
        }
2325
                
2326

    
2327
        public void fireCloseListener(ActionEvent e) {
2328
            if (this.closeListeners == null) {
2329
                return;
2330
            }
2331
            for (ActionListener listener : this.closeListeners) {
2332
                try {
2333
                    listener.actionPerformed(e);
2334
                } catch (Exception ex) {
2335

    
2336
                }
2337
            }
2338
        }
2339

    
2340
        public void fireChangeListener(ActionEvent e) {
2341
            if (this.activePanelListeners == null) {
2342
                return;
2343
            }
2344
            for (ActionListener listener : this.activePanelListeners) {
2345
                try {
2346
                    listener.actionPerformed(e);
2347
                } catch (Exception ex) {
2348

    
2349
                }
2350
            }
2351
        }
2352

    
2353
        private JTabbedPaneClosable getTabbedPanel(String align) {
2354
            switch (align) {
2355
                case Dock.DOCK_LEFT:
2356
                    return this.tabbedPanelLeft;
2357
                case Dock.DOCK_CENTER:
2358
                    return this.tabbedPanelCenter;
2359
                default:
2360
                case Dock.DOCK_BOTTOM:
2361
                    return this.tabbedPanelBottom;
2362
            }
2363
        }
2364

    
2365
        private DockedPanel getDockedPanel(java.awt.Component component) {
2366
            for (DockedPanel panel : this.panels.values()) {
2367
                if (panel.getComponent().asJComponent() == component) {
2368
                    return panel;
2369
                }
2370
            }
2371
            return null;
2372
        }
2373

    
2374
        private int getIndex(DockedPanel panel) {
2375
            final JTabbedPaneClosable tabbedPanel = getTabbedPanel(panel.getAlign());
2376
            for (int i = 0; i < tabbedPanel.getTabCount(); i++) {
2377
                java.awt.Component component = tabbedPanel.getComponentAt(i);
2378
                if (component == panel.getComponent().asJComponent()) {
2379
                    return i;
2380
                }
2381
            }
2382
            return -1;
2383
        }
2384

    
2385
        @Override
2386
        public void setModified(DockedPanel panel, boolean modified) {
2387
            final int index = this.getIndex(panel);
2388
            if (index < 0) {
2389
                return;
2390
            }
2391
            final JTabbedPaneClosable tabbedPanel = getTabbedPanel(panel.getAlign());
2392
            tabbedPanel.setTabModified(index, modified);
2393
        }
2394

    
2395
        @Override
2396
        public boolean getModified(DockedPanel panel) {
2397
            final int index = this.getIndex(panel);
2398
            if (index < 0) {
2399
                return false;
2400
            }
2401
            final JTabbedPaneClosable tabbedPanel = getTabbedPanel(panel.getAlign());
2402
            return tabbedPanel.isTabModified(index);
2403
        }
2404

    
2405
        @Override
2406
        public DockedPanel getSelected(String align) {
2407
            final JTabbedPaneClosable tabbedPanel = getTabbedPanel(align);
2408
            java.awt.Component selected = tabbedPanel.getSelectedComponent();
2409
            return this.getDockedPanel(selected);
2410
        }
2411

    
2412
        @Override
2413
        public DockedPanel add(String id, String title, final Component component, String align) {
2414
            final JTabbedPaneClosable tabbedPanel = getTabbedPanel(align);
2415
            DockedPanel panel = this.panels.get(id);
2416
            if (panel != null) {
2417
                tabbedPanel.remove(panel.getComponent().asJComponent());
2418
            }
2419
            panel = new DefaultDockedPanel(id, title, component, align);
2420
            this.panels.put(id, panel);
2421
            tabbedPanel.add(panel.getTitle(), panel.getComponent().asJComponent());
2422
            return panel;
2423
        }
2424

    
2425
        @Override
2426
        public void remove(String id) {
2427
            DockedPanel panel = this.panels.get(id);
2428
            if (panel != null) {
2429
                final JTabbedPaneClosable tabbedPanel = getTabbedPanel(panel.getAlign());
2430
                tabbedPanel.remove(panel.getComponent().asJComponent());
2431
                this.panels.remove(id);
2432
            }
2433
        }
2434

    
2435
        @Override
2436
        public DockedPanel get(String id) {
2437
            DockedPanel panel = this.panels.get(id);
2438
            return panel;
2439
        }
2440

    
2441
        @Override
2442
        public void select(String id) {
2443
            DockedPanel panel = this.panels.get(id);
2444
            if (panel != null) {
2445
                final JTabbedPaneClosable tabbedPanel = getTabbedPanel(panel.getAlign());
2446
                tabbedPanel.setSelectedComponent(panel.getComponent().asJComponent());
2447
            }
2448
        }
2449

    
2450
        @Override
2451
        public Iterator<DockedPanel> iterator() {
2452
            return this.panels.values().iterator();
2453
        }
2454

    
2455
    }
2456

    
2457
    private static class ToolEntry {
2458

    
2459
        private String name;
2460
        private String text;
2461
        private Action action;
2462
        private JComponent component;
2463

    
2464
        public ToolEntry(String name, Action action, String text) {
2465
            this.name = name;
2466
            this.action = action;
2467
            this.text = text;
2468
        }
2469

    
2470
        public ToolEntry(String name, Action action) {
2471
            this(name, action, null);
2472
        }
2473

    
2474
        public String getName() {
2475
            return this.name;
2476
        }
2477

    
2478
        public String getText() {
2479
            return this.text;
2480
        }
2481

    
2482
        public Action getAction() {
2483
            return this.action;
2484
        }
2485

    
2486
        public JComponent getComponent() {
2487
            return this.component;
2488
        }
2489

    
2490
        public void setComponent(JComponent component) {
2491
            this.component = component;
2492
        }
2493
    }
2494

    
2495
    public class ButtonWithContext extends JButton {
2496

    
2497
        private static final long serialVersionUID = -7434255417630073101L;
2498

    
2499
        public ButtonWithContext(Action action) {
2500
            super(action);
2501
            this.setBorderPainted(false);
2502
            this.setText("");
2503
        }
2504

    
2505
        public Object getContext() {
2506
            return DefaultJScriptingComposer.this;
2507
        }
2508
    }
2509

    
2510
    private class FindReplaceSearchListener implements SearchListener {
2511

    
2512
        @Override
2513
        public void searchEvent(SearchEvent e) {
2514

    
2515
            RSyntaxTextArea textArea = getCurrentRSyntaxTextArea();
2516
            if (textArea == null) {
2517
                return;
2518
            }
2519

    
2520
            SearchEvent.Type type = e.getType();
2521
            SearchContext context = e.getSearchContext();
2522
            SearchResult result;
2523

    
2524
            switch (type) {
2525
                default: // Prevent FindBugs warning later
2526
                case MARK_ALL:
2527
                    result = SearchEngine.markAll(textArea, context);
2528
                    break;
2529
                case FIND:
2530
                    result = SearchEngine.find(textArea, context);
2531
                    if (!result.wasFound()) {
2532
                        UIManager.getLookAndFeel().provideErrorFeedback(textArea);
2533
                    }
2534
                    break;
2535
                case REPLACE:
2536
                    result = SearchEngine.replace(textArea, context);
2537
                    if (!result.wasFound()) {
2538
                        UIManager.getLookAndFeel().provideErrorFeedback(textArea);
2539
                    }
2540
                    break;
2541
                case REPLACE_ALL:
2542
                    result = SearchEngine.replaceAll(textArea, context);
2543
                    JOptionPane.showMessageDialog(null, result.getCount()
2544
                            + " occurrences replaced.");
2545
                    break;
2546
            }
2547
            String text;
2548
            if (result.wasFound()) {
2549
                text = "Text found; occurrences marked: " + result.getMarkedCount();
2550
            } else if (type == SearchEvent.Type.MARK_ALL) {
2551
                if (result.getMarkedCount() > 0) {
2552
                    text = "Occurrences marked: " + result.getMarkedCount();
2553
                } else {
2554
                    text = "";
2555
                }
2556
            } else {
2557
                text = "Text not found";
2558
            }
2559
            getStatusbar().message(text);
2560
        }
2561

    
2562
        @Override
2563
        public String getSelectedText() {
2564
            RSyntaxTextArea textArea = getCurrentRSyntaxTextArea();
2565
            if (textArea == null) {
2566
                return "";
2567
            }
2568
            return textArea.getSelectedText();
2569
        }
2570

    
2571
    }
2572
}