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

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

    
109
public class DefaultJScriptingComposer extends JPanel implements JScriptingComposer, Observer, ActionListener {
110

    
111
    /**
112
     *
113
     */
114
    private static final long serialVersionUID = 1L;
115

    
116
    private static final Logger logger = LoggerFactory.getLogger(DefaultJScriptingComposer.class);
117

    
118
    public static final int CLOSE_ACTION = 1;
119

    
120
    private final ScriptingUIManager uimanager;
121
    private final ScriptingManager manager;
122
    private final ClassLoader loader;
123

    
124
    private JSplitPane mainPanel;
125
    private Dock dock;
126

    
127
    private Map<String, ToolEntry> menus;
128
    private JMenuBar menuBar;
129

    
130
    private Map<String, ToolEntry> tools;
131
    private JToolBar toolBar;
132

    
133
    private StatusBar statusBar;
134

    
135
    private FindDialog findDialog;
136
    private ReplaceDialog replaceDialog;
137
    private GoToDialog gotoDialog;
138

    
139
    private ActionListener defaultActionlistener = null;
140

    
141
    private Set<ChangeListener> changeEditorListeners = null;
142

    
143
    private class GoToLineAction extends AbstractAction {
144

    
145
        private static final long serialVersionUID = -7353913671104893812L;
146

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

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

    
171
            if (line > 0) {
172
                codeEditor.selectLine(line);
173
            }
174
        }
175

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

    
183
    private class ShowFindDialogAction extends AbstractAction {
184

    
185
        private static final long serialVersionUID = -7840632153011361661L;
186

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

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

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

    
209
    private class ShowReplaceDialogAction extends AbstractAction {
210

    
211
        private static final long serialVersionUID = 7209167803487996060L;
212

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

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

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

    
235
    private class LauncherAction extends AbstractAction {
236

    
237
        private static final long serialVersionUID = 6257776255757689286L;
238

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

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

    
253
    }
254

    
255
    private class SelectAllAction extends AbstractAction {
256

    
257
        private static final long serialVersionUID = 2725549699989067383L;
258

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

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

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

    
277
    }
278

    
279
    private class PackageScriptAction extends AbstractAction {
280

    
281
        private static final long serialVersionUID = 8020393562984016720L;
282

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

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

    
294
    }
295

    
296
    private class AboutAction extends AbstractAction {
297

    
298
        private static final long serialVersionUID = -4928359535828269502L;
299

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

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

    
316
    }
317

    
318
    private class CutAction extends AbstractAction {
319

    
320
        private static final long serialVersionUID = -8549655706085425411L;
321

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

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

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

    
340
    }
341

    
342
    private class CopyAction extends AbstractAction {
343

    
344
        private static final long serialVersionUID = -6870773810752024874L;
345

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

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

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

    
364
    }
365

    
366
    private class PasteAction extends AbstractAction {
367

    
368
        private static final long serialVersionUID = -5829551248494873061L;
369

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

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

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

    
388
    }
389

    
390
    private class ExitAction extends AbstractAction {
391

    
392
        private static final long serialVersionUID = 9165363564675325925L;
393

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

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

    
411
    }
412

    
413
    private class SaveAction extends AbstractAction {
414

    
415
        private static final long serialVersionUID = -870379961486387727L;
416

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

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

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

    
438
    private class RunAction extends AbstractAction {
439

    
440
        private static final long serialVersionUID = 4851968883766990149L;
441

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

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

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

    
463
    private class SaveAndRunAction extends AbstractAction {
464

    
465
        private static final long serialVersionUID = 4851968883766990149L;
466

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

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

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

    
489
    private class CloseAllAction extends AbstractAction {
490

    
491
        private static final long serialVersionUID = 3385142920283598457L;
492

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

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

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

    
511
    }
512

    
513
    private class CloseDocumentAction extends AbstractAction {
514

    
515
        private static final long serialVersionUID = 4152188500446249755L;
516

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

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

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

    
535
    }
536

    
537
    private class ShowConsoleAction extends AbstractAction {
538

    
539
        private static final long serialVersionUID = -7545333555439711068L;
540

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

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

    
554
    private class ShowProblemsAction extends AbstractAction {
555

    
556
        private static final long serialVersionUID = 5276964996914550830L;
557

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

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

    
571
    private class ShowProjectsAction extends AbstractAction {
572

    
573
        private static final long serialVersionUID = 5873598740133693862L;
574

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

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

    
588
    private class NewDocumentAction extends AbstractAction {
589

    
590
        private static final long serialVersionUID = 7889613706183211620L;
591

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

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

    
608
    }
609

    
610
    private class ProjectEditAction extends AbstractAction {
611

    
612
        private static final long serialVersionUID = -3393464285985649074L;
613

    
614
        public ProjectEditAction() {
615
            super(uimanager.getTranslation("Edit"));
616
            putValue(Action.SMALL_ICON, uimanager.getIcon("doc-edit"));
617
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Open_edition_mode"));
618
            putValue(ACTION_COMMAND_KEY, "DocumentEdit");
619
        }
620

    
621
        @Override
622
        public void actionPerformed(ActionEvent e) {
623
            try {
624
                ScriptingUnit selectedItem = getLauncherSelectedScript();
625
                if (selectedItem instanceof ScriptingBaseScript) {
626
                    scriptEdit((ScriptingBaseScript) selectedItem);
627
                }
628
            } catch (Exception e1) {
629
                logger.warn("Can't edit document", e1);
630
            }
631
        }
632
    }
633

    
634
    private class ProjectRefreshAction extends AbstractAction {
635

    
636
        private static final long serialVersionUID = 1944121660002532563L;
637

    
638
        public ProjectRefreshAction() {
639
            super(uimanager.getTranslation("Refresh"));
640
            putValue(Action.SMALL_ICON, uimanager.getIcon("refresh"));
641
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Refresh_directories"));
642
            putValue(ACTION_COMMAND_KEY, "ProjectsRefresh");
643
        }
644

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

    
650
    }
651

    
652
    private class ProjectRenameAction extends AbstractAction {
653

    
654
        private static final long serialVersionUID = 7469858242486966790L;
655

    
656
        public ProjectRenameAction() {
657
            super(uimanager.getTranslation("Rename"));
658
            putValue(Action.SMALL_ICON, uimanager.getIcon("doc-rename"));
659
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Set_file_properties"));
660
            putValue(ACTION_COMMAND_KEY, "Rename");
661
        }
662

    
663
        @Override
664
        public void actionPerformed(ActionEvent e) {
665
            try {
666
                scriptRename(getLauncherSelectedScript());
667
            } catch (Exception e1) {
668
                logger.warn("Can't rename document", e1);
669
            }
670
        }
671
    }
672

    
673
    private class ProjectMoveAction extends AbstractAction {
674

    
675
        private static final long serialVersionUID = -8857101021126773295L;
676

    
677
        public ProjectMoveAction() {
678
            super(uimanager.getTranslation("Move"));
679
            putValue(Action.SMALL_ICON, uimanager.getIcon("doc-move"));
680
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Move_files"));
681
            putValue(ACTION_COMMAND_KEY, "Move");
682
        }
683

    
684
        @Override
685
        public void actionPerformed(ActionEvent e) {
686
            try {
687
                scriptMove(getLauncherSelectedScript());
688
            } catch (Exception e1) {
689
                logger.warn("Can't move document", e1);
690
            }
691
        }
692
    }
693

    
694
    private class ProjectDeleteAction extends AbstractAction {
695

    
696
        private static final long serialVersionUID = 9039455504757742743L;
697

    
698
        public ProjectDeleteAction() {
699
            super(uimanager.getTranslation("Delete"));
700
            putValue(Action.SMALL_ICON, uimanager.getIcon("doc-remove"));
701
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Delete_selected_script"));
702
            putValue(ACTION_COMMAND_KEY, "Delete");
703
        }
704

    
705
        @Override
706
        public void actionPerformed(ActionEvent e) {
707
            try {
708
                scriptDelete(getLauncherSelectedScript(), false);
709
            } catch (Exception e1) {
710
                logger.warn("Can't delete document", e1);
711
            }
712
        }
713
    }
714

    
715
    /**
716
     * Instanciacion de un JComposer con todos sus elementos y acciones
717
     *
718
     * @param uimanager
719
     */
720
    public DefaultJScriptingComposer(final ScriptingUIManager uimanager) {
721
        loader = this.getClass().getClassLoader();
722
        this.uimanager = uimanager;
723
        this.manager = uimanager.getManager();
724
        initComponents();
725
    }
726

    
727
    @Override
728
    public JComponent asJComponent() {
729
        return this;
730
    }
731

    
732
    @Override
733
    public WindowManager getWindowManager() {
734
        return ((DefaultScriptingUIManager) (this.uimanager)).getWindowManager();
735
    }
736

    
737
    @Override
738
    public void setWindowManager(WindowManager windowsManager) {
739
        ((DefaultScriptingUIManager) (this.uimanager)).setWindowManager(windowsManager);
740
    }
741

    
742
    private void initComponents() {
743

    
744
        this.addAncestorListener(new AncestorListener() {
745

    
746
            @Override
747
            public void ancestorAdded(AncestorEvent event) {
748
                ((DefaultScriptingUIManager) uimanager).setActiveComposer(DefaultJScriptingComposer.this);
749
            }
750

    
751
            @Override
752
            public void ancestorRemoved(AncestorEvent event) {
753
                ((DefaultScriptingUIManager) uimanager).setActiveComposer(null);
754
            }
755

    
756
            @Override
757
            public void ancestorMoved(AncestorEvent event) {
758
            }
759
        });
760
        SearchListener findReplaceSearchListener = new FindReplaceSearchListener();
761

    
762
        findDialog = new FindDialog((Dialog) null, findReplaceSearchListener);
763
        replaceDialog = new ReplaceDialog((Dialog) null, findReplaceSearchListener);
764
        gotoDialog = new GoToDialog((Dialog) null);
765

    
766
        SearchContext searchContext = findDialog.getSearchContext();
767
        replaceDialog.setSearchContext(searchContext);
768

    
769
        this.menuBar = new JMenuBar();
770
        this.toolBar = new JToolBar();
771

    
772
        this.menus = new LinkedHashMap<>();
773
        this.tools = new LinkedHashMap<>();
774

    
775
        String _File = this.uimanager.getTranslation("File");
776
        String _Edit = this.uimanager.getTranslation("Edit");
777
        String _Projects = this.uimanager.getTranslation("Projects");
778
        String _Tools = this.uimanager.getTranslation("Tools");
779
        String _Help = this.uimanager.getTranslation("Help");
780
        String _View = this.uimanager.getTranslation("Show");
781

    
782
        this.addMenu(_File, null);
783
        this.addMenu(_File, new NewDocumentAction());
784
        this.addMenuSeparator(_File);
785
        this.addMenu(_File, new CloseDocumentAction());
786
        this.addMenu(_File, new CloseAllAction());
787
        this.addMenuSeparator(_File);
788
        this.addMenu(_File, new RunAction());
789
        this.addMenu(_File, new SaveAndRunAction());
790
        this.addMenuSeparator(_File);
791
        this.addMenu(_File, new SaveAction());
792
        this.addMenuSeparator(_File);
793
        this.addMenu(_File, new ExitAction());
794

    
795
        this.addMenu(_Edit, null);
796
        this.addMenu(_Edit, new CutAction());
797
        this.addMenu(_Edit, new CopyAction());
798
        this.addMenu(_Edit, new PasteAction());
799
        this.addMenuSeparator(_Edit);
800
        this.addMenu(_Edit, new SelectAllAction());
801
        this.addMenuSeparator(_Edit);
802
        this.addMenu(_Edit, new ShowFindDialogAction());
803
        this.addMenu(_Edit, new ShowReplaceDialogAction());
804
        this.addMenu(_Edit, new GoToLineAction());
805

    
806
        this.addMenu(_View, null);
807
        this.addMenu(_View, new ShowProjectsAction());
808
        this.addMenu(_View, new ShowProblemsAction());
809
        this.addMenu(_View, new ShowConsoleAction());
810

    
811
        this.addMenu(_Projects, null);
812
        this.addMenu(_Projects, new ProjectEditAction());
813
        this.addMenuSeparator(_Projects);
814
        this.addMenu(_Projects, new ProjectRefreshAction());
815
        this.addMenuSeparator(_Projects);
816
        this.addMenu(_Projects, new ProjectRenameAction());
817
        this.addMenu(_Projects, new ProjectMoveAction());
818
        this.addMenu(_Projects, new ProjectDeleteAction());
819

    
820
        this.addMenu(_Tools, null);
821
        this.addMenu(_Tools, new LauncherAction());
822
        this.addMenuSeparator(_Tools);
823
        this.addMenu(_Tools, new PackageScriptAction());
824

    
825
        this.addMenu(_Help, null);
826
        this.addMenu(_Help, new AboutAction());
827

    
828
        this.addTool(new NewDocumentAction());
829
        this.addTool(new SaveAction());
830
        this.addTool(new CutAction());
831
        this.addTool(new CopyAction());
832
        this.addTool(new PasteAction());
833
        this.addTool(new RunAction());
834
        this.addTool(new SaveAndRunAction());
835

    
836
        JTabbedPaneClosable tabbedPanelLeft = new JTabbedPaneClosable(uimanager);
837
        JTabbedPaneClosable tabbedPanelBottom = new JTabbedPaneClosable(uimanager);
838
        JTabbedPaneClosable tabbedPanelCenter = new JTabbedPaneClosable(uimanager);
839

    
840
        tabbedPanelLeft.setTabPlacement(JTabbedPane.BOTTOM);
841
        tabbedPanelCenter.setPreferredSize(new Dimension(500, 300));
842
        tabbedPanelCenter.addChangeListener(new ChangeListener() {
843

    
844
            @Override
845
            public void stateChanged(ChangeEvent e) {
846
                updateMenusAndTools();
847
            }
848
        });
849

    
850
        this.dock = new DefaultDock(
851
                tabbedPanelLeft,
852
                tabbedPanelBottom,
853
                tabbedPanelCenter
854
        );
855
        this.dock.addCloseListener(new ActionListener() {
856

    
857
            @Override
858
            public void actionPerformed(ActionEvent e) {
859
                DockedPanel panel = (DockedPanel) e.getSource();
860
                scriptClose(panel);
861
            }
862
        });
863
        tabbedPanelBottom.setPreferredSize(new Dimension(450, 100));
864

    
865
        this.addProjectsPanel();
866
        this.addConsolePanel();
867
        this.addProblemsPanel();
868

    
869
        this.dock.select(DOCKED_CONSOLE);
870
        this.dock.select(DOCKED_PROJECTS);
871

    
872
        JSplitPane centerPanel = new JSplitPane(
873
                JSplitPane.VERTICAL_SPLIT,
874
                tabbedPanelCenter,
875
                tabbedPanelBottom
876
        );
877
        centerPanel.setOneTouchExpandable(true);
878

    
879
        mainPanel = new JSplitPane(
880
                JSplitPane.HORIZONTAL_SPLIT,
881
                tabbedPanelLeft,
882
                centerPanel
883
        );
884
        mainPanel.setOneTouchExpandable(true);
885

    
886
        statusBar = new DefaultStatusBar(uimanager);
887

    
888
        updateMenusAndTools();
889

    
890
        JPanel buttons = new JPanel();
891
        buttons.setLayout(new BorderLayout());
892
        buttons.add(BorderLayout.NORTH, this.menuBar);
893
        buttons.add(BorderLayout.SOUTH, this.toolBar);
894

    
895
        this.setLayout(new BorderLayout());
896
        this.add(BorderLayout.NORTH, buttons);
897
        this.add(BorderLayout.CENTER, mainPanel);
898
        this.add(BorderLayout.SOUTH, statusBar.asJComponent());
899
        this.setPreferredSize(new Dimension(800, 600));
900
    }
901

    
902
    public void addMenu(String text, Action action) {
903
        String name;
904
        if (action == null) {
905
            name = String.format("Menu%x", new Date().getTime());
906
        } else {
907
            name = (String) action.getValue(Action.ACTION_COMMAND_KEY);
908
        }
909
        this.menus.put(name, new ToolEntry(name, action, text));
910
    }
911

    
912
    public void addMenuSeparator(String text) {
913
        String name = String.format("Sep%x", new Date().getTime());
914
        this.menus.put(name, new ToolEntry(name, null, text + "/-"));
915
    }
916

    
917
    public void addTool(Action action) {
918
        String name = (String) action.getValue(Action.ACTION_COMMAND_KEY);
919
        this.tools.put(name, new ToolEntry(name, action));
920
    }
921

    
922
    public void updateMenusAndTools() {
923

    
924
        this.menuBar.removeAll();
925
        this.toolBar.removeAll();
926
        for (MenuEntry entry : this.uimanager.getComposerMenus()) {
927
            this.addMenu(entry.getText(), entry.getAction());
928
        }
929
        for (Action action : this.uimanager.getComposerTools()) {
930
            this.addTool(action);
931
        }
932

    
933
        MenuBarHelper menuBarHelper = new MenuBarHelper(menuBar);
934
        for (ToolEntry entry : menus.values()) {
935
            try {
936
                JMenuItem menu = menuBarHelper.add(entry.getText(), entry.getAction(), this);
937
                entry.setComponent(menu);
938
            } catch(Throwable th) {
939
                logger.warn("Can't add entry '"+entry.getName()+"' to the toolbar.", th);
940
            }
941
        }
942

    
943
        for (ToolEntry entry : tools.values()) {
944
            try {
945
                JButton button = new ButtonWithContext(entry.getAction());
946
                this.toolBar.add(button);
947
                entry.setComponent(button);
948
            } catch(Throwable th) {
949
                logger.warn("Can't add entry '"+entry.getName()+"' to the toolbar.", th);
950
            }
951
            
952
        }
953
        this.menuBar.repaint();
954
        this.toolBar.repaint();
955
    }
956

    
957
    public void addProblemsPanel() {
958
        DockedPanel panel = this.dock.get(DOCKED_PROBLEMS);
959
        if (panel != null) {
960
            panel.select();
961
            return;
962
        }
963
        final Problems problems = new DefaultProblems(this.uimanager);
964
        problems.addListSelectionListener(new ListSelectionListener() {
965

    
966
            @Override
967
            public void valueChanged(ListSelectionEvent e) {
968
                if (e.getValueIsAdjusting()) {
969
                    return;
970
                }
971
                Problem row = problems.getSelect();
972
                if (row != null) {
973
                    JEditor editor;
974
                    int lineno = row.getLineNumber();
975
                    if( row.getResource() == null ) {
976
                        editor = getCurrentEditor();
977
                    } else {
978
                        String id = row.getResource().getAbsolutePath();
979
                        DockedPanel panel = getDock().get(id);
980
                        if( panel == null ) {
981
                            ScriptingBaseScript script = manager.getScript(row.getResource());
982
                            scriptEdit(script);
983
                            panel = getDock().get(id);
984
                            if( panel == null ) {
985
                                logger.warn("Can't load script '"+id+"'.");
986
                                return;
987
                            }
988
                        } 
989
                        panel.select();
990
                        editor = (JEditor) panel.getComponent();
991
                    }
992
                    if ( editor instanceof JCodeEditor) {
993
                        ((JCodeEditor) editor).gotoline(lineno);
994
                    }
995
                }
996
            }
997
        });
998
        this.dock.add(
999
                DOCKED_PROBLEMS,
1000
                this.uimanager.getTranslation("Problems"),
1001
                problems,
1002
                Dock.DOCK_BOTTOM
1003
        );
1004
        this.dock.select(DOCKED_PROBLEMS);
1005
    }
1006

    
1007
    public void addConsolePanel() {
1008
        DockedPanel panel = this.dock.get(DOCKED_CONSOLE);
1009
        if (panel != null) {
1010
            panel.select();
1011
            return;
1012
        }
1013
        DefaultJScriptingConsole console = new DefaultJScriptingConsole(true);
1014
        this.dock.add(
1015
                DOCKED_CONSOLE,
1016
                this.uimanager.getTranslation("Console"),
1017
                console,
1018
                Dock.DOCK_BOTTOM
1019
        );
1020
        this.dock.select(DOCKED_CONSOLE);
1021
    }
1022

    
1023
    public void addProjectsPanel() {
1024
        DockedPanel panel = this.dock.get(DOCKED_PROJECTS);
1025
        if (panel != null) {
1026
            panel.select();
1027
            return;
1028
        }
1029
        JScriptingLauncher launcher = uimanager.createLauncher();
1030
        launcher.addDefaultActionListener(new ActionListener() {
1031

    
1032
            @Override
1033
            public void actionPerformed(ActionEvent e) {
1034
                BrowserActionEvent e2 = (BrowserActionEvent) e;
1035
                switch (e.getID()) {
1036
                    case JScriptingBrowser.DEFAULT_ACTION:
1037
                        if( uimanager.hasEditor(e2.getUnit()) ) {
1038
                            scriptEdit(e2.getUnit());
1039
                        }
1040
                        break;
1041
                    case JScriptingBrowser.DROPDOWN_ACTION:
1042
                    case JScriptingBrowser.SELECTION_ACTION:
1043
                        break;
1044
                }
1045
            }
1046
        });
1047
        launcher.asJComponent().setPreferredSize(new Dimension(200, 450));
1048

    
1049
        this.dock.add(
1050
                DOCKED_PROJECTS,
1051
                this.uimanager.getTranslation("Projects"),
1052
                launcher,
1053
                Dock.DOCK_LEFT
1054
        );
1055
        this.dock.select(DOCKED_PROJECTS);
1056
    }
1057

    
1058
    @Override
1059
    public Problems getProblems() {
1060
        DockedPanel panel = this.dock.get(DOCKED_PROBLEMS);
1061
        if (panel == null) {
1062
            return null;
1063
        }
1064
        return (Problems) panel.getComponent();
1065
    }
1066

    
1067
    @Override
1068
    public JScriptingLauncher getProjects() {
1069
        DockedPanel panel = this.dock.get(DOCKED_PROJECTS);
1070
        if (panel == null) {
1071
            return null;
1072
        }
1073
        return (JScriptingLauncher) panel.getComponent();
1074
    }
1075

    
1076
    @Override
1077
    public Dock getDock() {
1078
        return dock;
1079
    }
1080

    
1081
    @Override
1082
    public JScriptingConsole getConsole() {
1083
        DockedPanel panel = this.dock.get(DOCKED_CONSOLE);
1084
        if (panel == null) {
1085
            return null;
1086
        }
1087
        return (JScriptingConsole) panel.getComponent();
1088
    }
1089

    
1090
    @Override
1091
    public void addChangeEditorListener(ChangeListener listener) {
1092
        if (this.changeEditorListeners == null) {
1093
            this.changeEditorListeners = new HashSet<>();
1094
        }
1095
        this.changeEditorListeners.add(listener);
1096
    }
1097
    
1098
    public void removeChangeEditorListener(ChangeListener listener) {
1099
        if (this.changeEditorListeners == null) {
1100
            return;
1101
        }
1102
        this.changeEditorListeners.remove(listener);
1103
    }
1104

    
1105
    public void fireChangeEditor(ChangeEvent e) {
1106
        if (this.changeEditorListeners == null) {
1107
            return;
1108
        }
1109
        for (ChangeListener listener : this.changeEditorListeners) {
1110
            try {
1111
                listener.stateChanged(e);
1112
            } catch (Throwable th) {
1113

    
1114
            }
1115
        }
1116
    }
1117

    
1118
    private void createScriptPackage() {
1119
        I18nManager i18nManager = ToolsLocator.getI18nManager();
1120
        SwingInstallerManager installerManager = SwingInstallerLocator.getSwingInstallerManager();
1121
        PackageBuildder packager = installerManager.createPackagerPanel(
1122
                ScriptingManager.INSTALLER_PROVIDER_NAME,
1123
                manager.getRootUserFolder(),
1124
                manager.getPackagesFolder()
1125
        );
1126
        PackageInfo packageInfo = packager.getPackageInfo();
1127
        packageInfo.setArchitecture(PackageManager.ARCH.ALL);
1128
        packageInfo.setJavaVM(PackageManager.JVM.J1_7);
1129
        packageInfo.setOperatingSystem(PackageManager.OS.ALL);
1130
        packageInfo.setOfficial(false);
1131
        packageInfo.setState(PackageManager.STATE.TESTING);
1132
        packageInfo.setType(ScriptingManager.INSTALLER_PROVIDER_NAME);
1133
        Version version = ToolsLocator.getPackageManager().createVersion();
1134
        version.parse("1.0.0");
1135
        packageInfo.setVersion(version);
1136
        this.uimanager.showWindow(
1137
                (JPanel) packager.asJComponent(),
1138
                i18nManager.getTranslation("_Scripting_packager")
1139
        );
1140
    }
1141

    
1142
//    private void setEditorSelection(String name, int line) {
1143
//        for (int i = 0; i < scriptEditors.getTabCount(); i++) {
1144
//
1145
//            if (((JEditor) scriptEditors.getComponent(i)).getScript().getId().equals(name)) {
1146
//                scriptEditors.setSelectedIndex(i);
1147
//
1148
//                JCodeEditor editor = ((JCodeEditor) scriptEditors.getComponent(i));
1149
//                editor.selectLine(line);
1150
//            }
1151
//        }xxxxxxxxxxxxxxxxxxxxxxxx
1152
//    }
1153
    public void addDefaultActionListener(ActionListener actionlistener) {
1154
        this.defaultActionlistener = actionlistener;
1155
    }
1156

    
1157
    /**
1158
     * Funci?n para obtener el elemento seleccionado del Launcher
1159
     *
1160
     * @return Selected ScriptingUnit on the tree
1161
     */
1162
    private ScriptingUnit getLauncherSelectedScript() {
1163
        JScriptingBrowser browser = this.getCurrentBrowser();
1164
        ScriptingUnit unit = browser.getSelectedNode();
1165
        return unit;
1166
    }
1167
    
1168
    private JScriptingBrowser getCurrentBrowser() {
1169
        JScriptingLauncher launcher = this.getProjects();
1170
        JScriptingBrowser browser = launcher.getSelectedBrowser();
1171
        return browser;
1172
    }
1173

    
1174
//    /**
1175
//     * Lanza la ejecuci?n de un ScriptingBaseScript
1176
//     *
1177
//     * @param unit
1178
//     */
1179
//    private void scriptExecute(ScriptingUnit unit) {
1180
//        if (unit instanceof ScriptingBaseScript) {
1181
//            ((ScriptingBaseScript) unit).run();
1182
//        }
1183
//    }
1184

    
1185
    public void scriptEdit(ScriptingUnit unit) {
1186
        String id = unit.getFile().getAbsolutePath();
1187
        DockedPanel x = this.dock.get(id);
1188
        if (x != null) {
1189
            x.select();
1190
            return;
1191
        }
1192
        final JEditor editor = this.uimanager.createEditor(unit);
1193
        if (editor == null) {
1194
            JOptionPane.showMessageDialog(null, this.uimanager.getTranslation("Error_opening_in_edition_mode"), this.uimanager.getTranslation("Error_opening_in_edition_mode_title"), JOptionPane.INFORMATION_MESSAGE);
1195
            return;
1196
        }
1197
        final DockedPanel panel = this.dock.add(id, unit.getName(), editor, Dock.DOCK_CENTER);
1198
        panel.select();
1199
        editor.addChangeListener(new PropertyChangeListener() {
1200

    
1201
            @Override
1202
            public void propertyChange(PropertyChangeEvent evt) {
1203
                panel.setModified(true);
1204
                fireChangeEditor(new ChangeEvent(editor));
1205
            }
1206
        });
1207
        if (editor instanceof JCodeEditor) {
1208
            ((JCodeEditor) editor).addUpdateCaretPositionActionListener(new ActionListener() {
1209

    
1210
                @Override
1211
                public void actionPerformed(ActionEvent e) {
1212
                    UpdateCaretPositionActionEvent event = (UpdateCaretPositionActionEvent) e;
1213
                    getStatusbar().setPosition(
1214
                            event.getLine(),
1215
                            event.getColumn()
1216
                    );
1217
                }
1218
            });
1219
        }
1220
        ScriptingUnit xx = editor.getUnit();
1221
        if (xx instanceof ScriptingScript ) {
1222
            ((ScriptingScript)xx).addObserver(this);
1223
        }
1224
    }
1225

    
1226
    /**
1227
     * Ventana para creaci?n de nuevos ScriptingBaseScripts
1228
     *
1229
     * @throws Exception
1230
     *
1231
     */
1232
    public void scriptNew() throws Exception {
1233
        JNewScriptModel model = new JNewScriptModel(manager);
1234
        model.setSelectionPath(this.getCurrentBrowser().getSelectionPath());
1235
        JDialogContent dialog = new JDialogContent(
1236
                uimanager,
1237
                "document-new",
1238
                this.uimanager.getTranslation("New_Script"),
1239
                this.uimanager.getTranslation("New_Script_Description"),
1240
                new JNewScriptPanel(uimanager, model)
1241
        );
1242
        dialog.showDialog();
1243
        if (model.getAction() == JNewScriptModel.ACTION_ACCEPT) {
1244
            model.validate();
1245
            ScriptingUnit unit = this.manager.createUnit(
1246
                    model.getType(),
1247
                    manager.getFolder(new File(model.getPath())),
1248
                    model.getName(),
1249
                    model.getLanguage()
1250
            );
1251
            if (unit instanceof ScriptingBaseScript) {
1252
                this.scriptEdit((ScriptingBaseScript) unit);
1253
            }
1254

    
1255
            this.refreshProjects();
1256
        }
1257
    }
1258

    
1259
    public void scriptClose(DockedPanel panel) {
1260
        if (!panel.isModified()) {
1261
            panel.remove();
1262
            return;
1263
        }
1264
        panel.select();
1265
        I18nManager i18nManager = ToolsLocator.getI18nManager();
1266
        int respuesta = JOptionPane.showConfirmDialog(
1267
                this,
1268
                i18nManager.getTranslation("_The_script_XscriptnameX_is_modified",
1269
                        new String[]{panel.getTitle()})
1270
                + "\n\n"
1271
                + i18nManager.getTranslation("_Do_you_want_to_save_changes_XquestionX"),
1272
                i18nManager.getTranslation("_Save_changes_XquestionX"),
1273
                JOptionPane.YES_NO_CANCEL_OPTION
1274
        );
1275
        switch (respuesta) {
1276
            case JOptionPane.YES_OPTION:
1277
                currentScriptSave();
1278
                panel.remove();
1279
                break;
1280
            case JOptionPane.NO_OPTION:
1281
                panel.remove();
1282
                break;
1283
            default:
1284
            case JOptionPane.CANCEL_OPTION:
1285
                break;
1286
        }
1287
    }
1288

    
1289
    public void scriptMove(final ScriptingUnit theUnit) throws Exception {
1290
        if (theUnit.getParent() == null) {
1291
            JOptionPane.showMessageDialog(null, "Please, select first the file to move on the tree directory", "Error", JOptionPane.ERROR_MESSAGE);
1292
        } else {
1293
            JMoveScriptModel model = new JMoveScriptModel(manager, theUnit);
1294
            JDialogContent dialog = new JDialogContent(
1295
                    uimanager,
1296
                    "format-indent-more",
1297
                    this.uimanager.getTranslation("Move") + " '" + theUnit.getName() + "' " + this.uimanager.getTranslation("script_filesystem"),
1298
                    this.uimanager.getTranslation("move_desc"),
1299
                    new JMoveScriptPanel(uimanager, model)
1300
            );
1301
            dialog.showDialog();
1302
            if (model.getAction() == JMoveScriptModel.ACTION_ACCEPT) {
1303
                model.validate();
1304
                ScriptingFolder folderDest = manager.getFolder(model.getMoveTo());
1305
                if (model.getUnit().move(folderDest)) {
1306
                    JOptionPane.showMessageDialog(null,
1307
                            this.uimanager.getTranslation("Moving_succesfully"),
1308
                            this.uimanager.getTranslation("Success"), JOptionPane.INFORMATION_MESSAGE);
1309
                    this.refreshProjects();
1310
                } else {
1311
                    JOptionPane.showMessageDialog(null,
1312
                            this.uimanager.getTranslation("Error_moving"),
1313
                            this.uimanager.getTranslation("Error"), JOptionPane.ERROR_MESSAGE);
1314
                }
1315
            }
1316
        }
1317

    
1318
    }
1319

    
1320
    public void scriptRename(ScriptingUnit theUnit) throws Exception {
1321
        if (theUnit.getParent() == null) {
1322
            JOptionPane.showMessageDialog(null,
1323
                    this.uimanager.getTranslation("Select_first"),
1324
                    this.uimanager.getTranslation("Error"), JOptionPane.ERROR_MESSAGE);
1325
        } else {
1326
            JRenameModel model = new JRenameModel(manager, theUnit);
1327
            JDialogContent dialog = new JDialogContent(
1328
                    uimanager,
1329
                    "preferences-system",
1330
                    this.uimanager.getTranslation("Rename") + " '" + theUnit.getName() + "' " + this.uimanager.getTranslation("script_filesystem"),
1331
                    this.uimanager.getTranslation("rename_desc"),
1332
                    new JRenamePanel(uimanager, model)
1333
            );
1334
            dialog.showDialog();
1335
            if (model.getAction() == JRenameModel.ACTION_ACCEPT) {
1336
                model.validate();
1337
                ScriptingUnit unit = model.getUnit();
1338
                if (!model.getNewName().equals(unit.getId())) {
1339
                    if (unit.rename(model.getNewName())) {
1340
                        JOptionPane.showMessageDialog(null,
1341
                                this.uimanager.getTranslation("Rename_succesfully"),
1342
                                this.uimanager.getTranslation("Success"), JOptionPane.INFORMATION_MESSAGE);
1343
                        this.refreshProjects();
1344
                    } else {
1345
                        JOptionPane.showMessageDialog(null,
1346
                                this.uimanager.getTranslation(this.uimanager.getTranslation("Error_renaming")),
1347
                                this.uimanager.getTranslation("Error"), JOptionPane.ERROR_MESSAGE);
1348
                    }
1349
                    if (unit instanceof ScriptingScript) {
1350
                        ((ScriptingScript) unit).save();
1351
                    }
1352
                }
1353
            }
1354
        }
1355
    }
1356

    
1357
    @Override
1358
    public JPanel getAboutUsDialog() {
1359
        return new JDialogContent(uimanager,
1360
                "system-users",
1361
                this.uimanager.getTranslation("About_us"),
1362
                this.uimanager.getTranslation("About_us_title"),
1363
                new JDefaultDialog(uimanager, this, uimanager.getAboutManager().getAboutPanel()));
1364
    }
1365

    
1366
    public void scriptDelete(final ScriptingUnit unit, boolean isRecursive) {
1367
        int n = 0;
1368
        if (!isRecursive) {
1369
            n = JOptionPane.showConfirmDialog(
1370
                    this.getRootPane(),
1371
                    this.uimanager.getTranslation("Delete_all_message"),
1372
                    this.uimanager.getTranslation("Delete_all_title"),
1373
                    JOptionPane.YES_NO_OPTION);
1374
        }
1375
        if (n == 0) {
1376
            //Si es un folder borramos recursivamente sus subdirectorios
1377
            if (unit instanceof ScriptingFolder) {
1378
                List<ScriptingUnit> subunits
1379
                        = ((ScriptingFolder) unit).getUnits();
1380
                Iterator<ScriptingUnit> it = subunits.iterator();
1381
                while (it.hasNext()) {
1382
                    ScriptingUnit subunit = it.next();
1383
                    scriptDelete(subunit, true);
1384
                }
1385
            }
1386
            // Por ?ltimo borramos el nodo seleccionado
1387
            unit.getParent().remove(unit);
1388
            this.refreshProjects();
1389

    
1390
        }
1391
    }
1392

    
1393
    /**
1394
     * Funci?n que cierra la pesta?a de edici?n actual
1395
     *
1396
     */
1397
    public void currentScriptClose() {
1398
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1399
        if (panel == null) {
1400
            return;
1401
        }
1402
        scriptClose(panel);
1403
    }
1404

    
1405
    /**
1406
     * Close all editor tabs of the composer
1407
     */
1408
    public void closeAllScripts() {
1409
        List<DockedPanel> modifiedPanels = new ArrayList<>();
1410

    
1411
        for (DockedPanel panel : this.dock) {
1412
            if (Dock.DOCK_CENTER.equals(panel.getAlign())) {
1413
                if (panel.isModified()) {
1414
                    modifiedPanels.add(panel);
1415
                }
1416
            }
1417
        }
1418
        if (modifiedPanels.isEmpty()) {
1419
            return;
1420
        }
1421
        int action = JOptionPane.showConfirmDialog(
1422
                this,
1423
                this.uimanager.getTranslation("projects_modified"),
1424
                this.uimanager.getTranslation("projects_modified_title"),
1425
                JOptionPane.YES_NO_CANCEL_OPTION
1426
        );
1427
        switch (action) {
1428
            case JOptionPane.CANCEL_OPTION:
1429
                return;
1430
            case JOptionPane.YES_OPTION:
1431
                for (DockedPanel panel : modifiedPanels) {
1432
                    JEditor editor = (JEditor) panel.getComponent();
1433
                    if (editor.getUnit()!= null) {
1434
                        editor.getUnit().setSaved(true);
1435
                    }
1436
                    editor.save();
1437
                    panel.remove();
1438
                }
1439
                break;
1440
            case JOptionPane.NO_OPTION:
1441
                for (DockedPanel panel : modifiedPanels) {
1442
                    JEditor editor = (JEditor) panel.getComponent();
1443
                    if (editor.getUnit() != null) {
1444
                        editor.getUnit().setSaved(true);
1445
                    }
1446
                    panel.remove();
1447
                }
1448
        }
1449

    
1450
    }
1451

    
1452
    /**
1453
     * Funci?n que ejecuta el ScriptingBaseScript de la pesta?a actual
1454
     *
1455
     */
1456
    public void currentScriptExecute() {
1457
        ScriptingScript script = this.getCurrentScript();
1458
        if (script != null) {
1459
            Problems problems = this.getProblems();
1460
            if (problems != null) {
1461
                problems.removeAll();
1462
            }
1463
            JScriptingConsole console = this.getConsole();
1464
            if (console == null) {
1465
                addConsolePanel();
1466
            } else {
1467
                console.clear();
1468
            }
1469
            script.addObserver(this);
1470
            script.addStdoutWriter(this.getConsole().getOutputWriter());
1471
            script.addStderrWriter(this.getConsole().getErrorsWriter());
1472
            try {
1473
                script.compile();
1474
                script.runAsTask(null);
1475
            } catch (Throwable e) {
1476
                logger.info("Can't execute script", e);
1477
            }
1478
        }
1479
    }
1480

    
1481
    /**
1482
     * Funciones de 'cortar', 'copiar', 'pegar' y 'seleccionar todo' para los
1483
     * JEditors
1484
     *
1485
     */
1486
    public void currentScriptCopy() {
1487
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1488
        if (panel.getComponent().asJComponent() instanceof JCodeEditor) {
1489
            JCodeEditor editor = (JCodeEditor) panel.getComponent().asJComponent();
1490
            editor.getJTextComponent().copy();
1491
        }
1492
    }
1493

    
1494
    public void currentScriptCut() {
1495
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1496
        if (panel.getComponent().asJComponent() instanceof JCodeEditor) {
1497
            JCodeEditor editor = (JCodeEditor) panel.getComponent().asJComponent();
1498
            editor.getJTextComponent().cut();
1499
            panel.setModified(true);
1500
        }
1501
    }
1502

    
1503
    public void currentScriptPaste() {
1504
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1505
        if (panel.getComponent().asJComponent() instanceof JCodeEditor) {
1506
            JCodeEditor editor = (JCodeEditor) panel.getComponent().asJComponent();
1507
            editor.getJTextComponent().paste();
1508
            panel.setModified(true);
1509
        }
1510
    }
1511

    
1512
    public void currentScriptSelectAll() {
1513
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1514
        if (panel.getComponent().asJComponent() instanceof JCodeEditor) {
1515
            JCodeEditor editor = (JCodeEditor) panel.getComponent().asJComponent();
1516
            editor.getJTextComponent().selectAll();
1517
        }
1518
    }
1519

    
1520
    /**
1521
     * Funci?n para el guardado del ScriptingBaseScript de la pesta?a actual
1522
     *
1523
     */
1524
    public void currentScriptSave() {
1525
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1526
        if (panel.getComponent().asJComponent() instanceof JEditor) {
1527
            JEditor editor = (JEditor) panel.getComponent().asJComponent();
1528
            editor.save();
1529
            panel.setModified(false);
1530
        }
1531
    }
1532

    
1533
    @Override
1534
    public JEditor getCurrentEditor() {
1535
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1536
        if (panel == null) {
1537
            return null;
1538
        }
1539
        if (panel.getComponent().asJComponent() instanceof JEditor) {
1540
            return (JEditor) panel.getComponent().asJComponent();
1541
        }
1542
        return null;
1543
    }
1544

    
1545
    @Override
1546
    public ScriptingScript getCurrentScript() {
1547
        JEditor editor = this.getCurrentEditor();
1548
        if (editor == null) {
1549
            return null;
1550
        }
1551
        ScriptingUnit unit = editor.getUnit();
1552
        if( unit instanceof ScriptingScript ) {
1553
            return (ScriptingScript) unit;
1554
        }
1555
        return null;
1556
    }
1557

    
1558
    private RSyntaxTextArea getCurrentRSyntaxTextArea() {
1559
        JEditor editor = getCurrentEditor();
1560
        if (editor instanceof JCodeEditor) {
1561
            JTextComponent textComponent = ((JCodeEditor) editor).getJTextComponent();
1562
            if (textComponent instanceof RSyntaxTextArea) {
1563
                return (RSyntaxTextArea) textComponent;
1564
            }
1565
        }
1566
        return null;
1567
    }
1568

    
1569
    @Override
1570
    public void refreshProjects() {
1571
        try {
1572
            this.getProjects().refresh();
1573
        } catch (Exception ex) {
1574
            // Ignore
1575
        }
1576
    }
1577

    
1578
    @Override
1579
    public StatusBar getStatusbar() {
1580
        return this.statusBar;
1581
    }
1582

    
1583
    /**
1584
     *
1585
     * @param e
1586
     */
1587
    @Override
1588
    public void actionPerformed(ActionEvent e) {
1589

    
1590
        if (e instanceof UpdateCaretPositionActionEvent) {
1591
            UpdateCaretPositionActionEvent e2 = (UpdateCaretPositionActionEvent) e;
1592

    
1593
            if (e2.hasLineAndColumn()) {
1594
                this.getStatusbar().setPosition(e2.getLine(), e2.getColumn());
1595
            } else {
1596
                this.getStatusbar().setPosition(0, 0);
1597
            }
1598
        }
1599
    }
1600

    
1601
    @Override
1602
    public void update(final Observable observable, final Object notification) {
1603
        if (!SwingUtilities.isEventDispatchThread()) {
1604
            SwingUtilities.invokeLater(new Runnable() {
1605
                @Override
1606
                public void run() {
1607
                    update(observable, notification);
1608
                }
1609
            });
1610
            return;
1611
        }
1612
        if (notification instanceof ScriptingNotification) {
1613
            ScriptingNotification e = (ScriptingNotification) notification;
1614

    
1615
            if (e.getException() instanceof CompileErrorException) {
1616
                CompileErrorException ce = (CompileErrorException) e.getException();
1617
                Problems problems = this.getProblems();
1618
                if (problems != null) {
1619
                    problems.add("Error", ce);
1620
                    this.dock.select(DOCKED_PROBLEMS);
1621
                }
1622

    
1623
            } else if (e.getException() instanceof ExecuteErrorException) {
1624
                ExecuteErrorException ee = (ExecuteErrorException) e.getException();
1625
                Problems problems = this.getProblems();
1626
                if (problems != null) {
1627
                    problems.add("Error",ee);
1628
                    this.dock.select(DOCKED_PROBLEMS);
1629
                }
1630
                JScriptingConsole console = this.getConsole();
1631
                if (console != null) {
1632
                    console.append(ee.getMessage(), Color.RED.darker());
1633
                    ee.printStackTrace(console.errors());
1634
                }
1635

    
1636
            } else {
1637
                Exception ex = e.getException();
1638
                Problems problems = this.getProblems();
1639
                if (problems != null) {
1640
                    problems.add("Error",ex); 
1641
                    this.dock.select(DOCKED_PROBLEMS);
1642
                }
1643
                JScriptingConsole console = this.getConsole();
1644
                if (console != null) {
1645
                    console.append(ex.getMessage(), Color.RED.darker());
1646
                    ex.printStackTrace(console.errors());
1647
                }
1648
            }
1649
        }
1650
    }
1651

    
1652
    public void closeWindow() {
1653
        this.setVisible(false);
1654
    }
1655

    
1656
    private static class DefaultStatusBar extends JPanel implements StatusBar {
1657

    
1658
        private static final long serialVersionUID = -6135634992327170084L;
1659

    
1660
        private JLabel message;
1661
        private JLabel position;
1662
        private final ScriptingUIManager uimanager;
1663

    
1664
        public DefaultStatusBar(ScriptingUIManager uimanager) {
1665
            this.uimanager = uimanager;
1666
            this.initComponents();
1667
        }
1668

    
1669
        private void initComponents() {
1670
            this.message = new JLabel(this.uimanager.getTranslation("Welcome_message"));
1671
            this.position = new JLabel("Line 0:0");
1672

    
1673
            this.setLayout(new BorderLayout());
1674

    
1675
            this.add(this.message, BorderLayout.WEST);
1676
            this.add(this.position, BorderLayout.EAST);
1677
        }
1678

    
1679
        @Override
1680
        public void clear() {
1681
            this.message.setText("");
1682
        }
1683

    
1684
        @Override
1685
        public void message(String message) {
1686
            this.message.setText(message);
1687
        }
1688

    
1689
        @Override
1690
        public void setPosition(int line) {
1691
            this.setPosition(line, -1);
1692
        }
1693

    
1694
        @Override
1695
        public void setPosition(int line, int column) {
1696
            if (line < 0) {
1697
                this.position.setText("");
1698
                return;
1699
            }
1700
            if (column < 0) {
1701
                this.position.setText(this.uimanager.getTranslation("Line") + " " + line + ":0");
1702
            } else {
1703
                this.position.setText(this.uimanager.getTranslation("Line") + " " + line + ":" + column);
1704
            }
1705
        }
1706

    
1707
        @Override
1708
        public JComponent asJComponent() {
1709
            return this;
1710
        }
1711
    }
1712

    
1713
    public static class JTabbedPaneClosable extends JTabbedPane {
1714

    
1715
        private static final long serialVersionUID = -3995298424891579555L;
1716

    
1717
        private final ActionListenerSupport closeTabListeners;
1718
        private ScriptingUIManager uimanager;
1719

    
1720
        private class TabTitleComponent extends JPanel {
1721

    
1722
            private static final long serialVersionUID = -1061417669527944341L;
1723
            private final JLabel label;
1724
            private final JButton button;
1725
            private boolean changed = false;
1726
            private final Font fontNormal;
1727
            private final Font fontBold;
1728

    
1729
            public TabTitleComponent(String title, final ActionListener onclose) {
1730
                this.setOpaque(true);
1731
                this.label = new JLabel(title + " ");
1732
                this.label.setOpaque(true);
1733
                this.label.setBackground(UIManager.getColor("TabbedPane.tabAreaBackground"));
1734
                this.label.setVerticalTextPosition(SwingConstants.CENTER);
1735
                this.fontNormal = this.label.getFont();
1736
                this.fontBold = new Font(this.fontNormal.getFontName(), Font.BOLD, this.fontNormal.getSize());
1737

    
1738
                this.button = new JButton();
1739
                this.button.setText("");
1740
                this.button.setToolTipText(uimanager.getTranslation("Close_tab"));
1741
                this.button.setBackground(UIManager.getColor("TabbedPane.tabAreaBackground"));
1742
                this.button.setBorder(BorderFactory.createEmptyBorder());
1743
                this.button.setBorderPainted(false);
1744
                this.button.setFocusPainted(false);
1745
                this.button.setContentAreaFilled(false);
1746
                this.button.setCursor(new Cursor(Cursor.HAND_CURSOR));
1747
                this.button.setRolloverEnabled(true);
1748
                this.button.setIcon(uimanager.getIcon("tabclose-inactive"));
1749
                this.button.setRolloverIcon(uimanager.getIcon("tabclose-active"));
1750
                this.button.addActionListener(new ActionListener() {
1751
                    @Override
1752
                    public void actionPerformed(ActionEvent ae) {
1753
                        ae.setSource(TabTitleComponent.this);
1754
                        onclose.actionPerformed(ae);
1755
                    }
1756
                });
1757
                this.setLayout(new BorderLayout());
1758
                this.add(this.label, BorderLayout.CENTER);
1759
                this.add(this.button, BorderLayout.EAST);
1760
            }
1761

    
1762
            public void setTitle(String title) {
1763
                this.label.setText(title);
1764
            }
1765

    
1766
            public String getTitle() {
1767
                return this.label.getText();
1768
            }
1769

    
1770
            public void setChanged(boolean changed) {
1771
                if (changed) {
1772
                    this.label.setFont(this.fontBold);
1773
                } else {
1774
                    this.label.setFont(this.fontNormal);
1775
                }
1776
                this.changed = changed;
1777
            }
1778

    
1779
            public boolean isChanged() {
1780
                return this.changed;
1781
            }
1782
        }
1783

    
1784
        public JTabbedPaneClosable(ScriptingUIManager uimanager) {
1785
            super();
1786
            this.uimanager = uimanager;
1787
            this.closeTabListeners = ToolsSwingLocator.getToolsSwingManager().createActionListenerSupport();
1788
        }
1789

    
1790
        @Override
1791
        public String getTitleAt(int index) {
1792
            TabTitleComponent title = (TabTitleComponent) this.getTabComponentAt(index);
1793
            if (title == null) {
1794
                return null;
1795
            }
1796
            return title.getTitle();
1797
        }
1798

    
1799
        @Override
1800
        public void setTitleAt(int index, String title) {
1801
            TabTitleComponent titleComponent = (TabTitleComponent) this.getTabComponentAt(index);
1802
            titleComponent.setTitle(title);
1803
        }
1804

    
1805
        @Override
1806
        public void addTab(String title, java.awt.Component component) {
1807
            super.addTab(null, component);
1808
            int index = getTabCount() - 1;
1809
            TabTitleComponent tabcomponent = new TabTitleComponent(title, new ActionListener() {
1810

    
1811
                @Override
1812
                public void actionPerformed(ActionEvent ae) {
1813
                    TabTitleComponent tabTitleComponent = (TabTitleComponent) ae.getSource();
1814
                    int index = indexOfTabComponent(tabTitleComponent);
1815
                    setSelectedIndex(index);
1816
                    ae.setSource(JTabbedPaneClosable.this);
1817
                    closeTabListeners.fireActionEvent(ae);
1818
                }
1819
            });
1820
            super.setTabComponentAt(index, tabcomponent);
1821
        }
1822

    
1823
        public void addCloseTabListener(ActionListener remove) {
1824
            this.closeTabListeners.addActionListener(remove);
1825
        }
1826

    
1827
        public void removeCloseTabListener(ActionListener remove) {
1828
            this.closeTabListeners.removeActionListener(remove);
1829
        }
1830

    
1831
        public ActionListener[] getCloseTabListeners() {
1832
            return this.closeTabListeners.getActionListeners();
1833
        }
1834

    
1835
        public boolean isTabModified(int index) {
1836
            TabTitleComponent comp = (TabTitleComponent) this.getTabComponentAt(index);
1837
            if (comp == null) {
1838
                return false;
1839
            }
1840
            return comp.isChanged();
1841
        }
1842

    
1843
        public void setTabModified(int index, boolean changed) {
1844
            TabTitleComponent comp = (TabTitleComponent) this.getTabComponentAt(index);
1845
            if (comp != null) {
1846
                comp.setChanged(changed);
1847
            }
1848
        }
1849
    }
1850

    
1851
    public static class DefaultProblems extends JPanel implements Problems {
1852

    
1853
        private static final long serialVersionUID = 7728033081188167969L;
1854

    
1855
        private static final int COLUMN_TYPE = 0;
1856
        private static final int COLUMN_MESSAGE = 1;
1857
        private static final int COLUMN_RESOURCE = 2;
1858
        private static final int COLUMN_LOCATION = 3;
1859
        private static final int NUM_COLUMNS = 4;
1860

    
1861
        private JTable table;
1862
        private ProblemsTableMode tableModel;
1863
        private final ScriptingUIManager uimanager;
1864
        private Set<ListSelectionListener> selectionListeners; 
1865

    
1866
        public static class ProblemsTableMode extends DefaultTableModel implements TableModel {
1867
            private static final long serialVersionUID = -3294067602561419422L;
1868

    
1869
            public static class DefaultProblem implements Problem {
1870

    
1871
                String[] row;
1872
                private File resource;
1873

    
1874
                public DefaultProblem() {
1875
                    this.row = new String[NUM_COLUMNS];
1876
                }
1877

    
1878
                public DefaultProblem(String[] row) {
1879
                    this.row = row;
1880
                }
1881

    
1882
                public DefaultProblem(String type, String message, String resourceName, String location, File resource) {
1883
                    String[] row = new String[NUM_COLUMNS];
1884
                    row[COLUMN_TYPE] = type;
1885
                    row[COLUMN_MESSAGE] = message;
1886
                    row[COLUMN_RESOURCE] = resourceName;
1887
                    row[COLUMN_LOCATION] = location;
1888
                    this.resource = resource;
1889
                    this.row = row;
1890
                }
1891

    
1892
                public String get(int index) {
1893
                    return row[index];
1894
                }
1895

    
1896
                public String getValue(int index) {
1897
                    return row[index];
1898
                }
1899

    
1900
                public void setValue(int index, String value) {
1901
                    row[index] = value;
1902
                }
1903

    
1904
                @Override
1905
                public String getType() {
1906
                    return this.row[COLUMN_TYPE];
1907
                }
1908

    
1909
                @Override
1910
                public String getMessage() {
1911
                    return this.row[COLUMN_MESSAGE];
1912
                }
1913

    
1914
                @Override
1915
                public String getResourceName() {
1916
                    return this.row[COLUMN_RESOURCE];
1917
                }
1918

    
1919
                @Override
1920
                public File getResource() {
1921
                    return this.resource;
1922
                }
1923

    
1924
                @Override
1925
                public int getLineNumber() {
1926
                    try {
1927
                        String[] lineAndColumn = this.row[COLUMN_LOCATION].split(":");
1928
                        if (lineAndColumn.length > 0) {
1929
                            int lineno = Integer.parseInt(lineAndColumn[0].trim());
1930
                            return lineno;
1931
                        }
1932
                    } catch (Exception e) {
1933
                        // Do nothing
1934
                    }
1935
                    return -1;
1936
                }
1937

    
1938
            }
1939
            private final ScriptingUIManager uimanager;
1940
            private List<DefaultProblem> data;
1941
            private String[] columnNames;
1942

    
1943
            public ProblemsTableMode(ScriptingUIManager uimanager) {
1944
                this.uimanager = uimanager;
1945
                this.columnNames = new String[]{
1946
                    this.uimanager.getTranslation("Category"),
1947
                    this.uimanager.getTranslation("Description"),
1948
                    this.uimanager.getTranslation("Resource"),
1949
                    this.uimanager.getTranslation("Location")
1950
                };
1951

    
1952
            }
1953
            
1954
            private List<DefaultProblem> getData() {
1955
                if( this.data == null ) {
1956
                    this.data = new ArrayList<>();
1957
                }
1958
                return this.data;
1959
            }
1960

    
1961
            public void add(DefaultProblem row) {
1962
                this.getData().add(row);
1963
                this.fireTableDataChanged();
1964
            }
1965

    
1966
            private void add(String type, String message, String resourceName, String location, File resource) {
1967
                DefaultProblem problem = new DefaultProblem(type, message, resourceName, location, resource);
1968
                this.add(problem);
1969
            }
1970

    
1971
            @Override
1972
            public int getRowCount() {
1973
                return this.getData().size();
1974
            }
1975

    
1976
            @Override
1977
            public int getColumnCount() {
1978
                return NUM_COLUMNS;
1979
            }
1980

    
1981
            @Override
1982
            public String getColumnName(int columnIndex) {
1983
                return columnNames[columnIndex];
1984
            }
1985

    
1986
            @Override
1987
            public Class<?> getColumnClass(int columnIndex) {
1988
                return String.class;
1989
            }
1990

    
1991
            @Override
1992
            public boolean isCellEditable(int rowIndex, int columnIndex) {
1993
                return false;
1994
            }
1995

    
1996
            @Override
1997
            public Object getValueAt(int rowIndex, int columnIndex) {
1998
                return this.getData().get(rowIndex).get(columnIndex);
1999
            }
2000
            
2001
            public Problem getProblem(int rowIndex) {
2002
                return this.getData().get(rowIndex);
2003
            }
2004

    
2005
            @Override
2006
            public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
2007
                this.getData().get(rowIndex).setValue(columnIndex, (String) aValue);
2008
            }
2009

    
2010
            public void removeAll() {
2011
                this.getData().clear();
2012
            }
2013
        }
2014

    
2015
        public DefaultProblems(ScriptingUIManager uimanager) {
2016
            this.uimanager = uimanager;
2017
            this.initComponents();
2018
        }
2019

    
2020
        private void initComponents() {
2021
            this.selectionListeners = new HashSet<>();
2022
            tableModel = new ProblemsTableMode(this.uimanager);
2023
            table = new JTable(tableModel);
2024
            table.getColumnModel().getColumn(1).setPreferredWidth(300);
2025

    
2026
            table.setRowSelectionAllowed(true);
2027
            table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
2028

    
2029
            JScrollPane scrollProblems = new JScrollPane(table);
2030
            scrollProblems.setAutoscrolls(true);
2031

    
2032
            this.setLayout(new BorderLayout());
2033
            this.add(scrollProblems, BorderLayout.CENTER);
2034
            
2035
            // Si ya hay seleccionada una linea y vuelvo a clickar sobre ella 
2036
            // para que me lleve a la linea del editor que toque, con el
2037
            // addSelectionListener no me vuelve a lanzar el evento, asi que
2038
            // me apalanco en el mouseClicked tambien.
2039
            table.addMouseListener(new MouseAdapter(){
2040
                @Override
2041
                public void mouseClicked(MouseEvent evnt) {
2042
                    if (evnt.getClickCount() == 1) {
2043
                        fireSelectionListeners();
2044
                     }
2045
                 }
2046
            });
2047
        }
2048

    
2049
        @Override
2050
        public void addListSelectionListener(ListSelectionListener listener) {
2051
            this.table.getSelectionModel().addListSelectionListener(listener);
2052
            this.selectionListeners.add(listener);
2053
        }
2054

    
2055
        private void fireSelectionListeners() {
2056
            int row = this.table.getSelectedRow();
2057
            for( ListSelectionListener listener : this.selectionListeners ) {
2058
                try {
2059
                    listener.valueChanged(new ListSelectionEvent(this, row, row, false));
2060
                } catch(Exception th) {
2061
                    
2062
                }
2063
            }
2064
        }
2065
        
2066
        @Override
2067
        public void removeAll() {
2068
            this.tableModel.removeAll();
2069
            this.table.updateUI();
2070
        }
2071

    
2072
        @Override
2073
        public void add(String type, String message, String resource, String location) {
2074
            this.tableModel.add(type, message, resource, location, null);
2075
        }
2076

    
2077
        @Override
2078
        public void add(String type, String message, String resource, int line, int column) {
2079
            this.add(type, message, resource, line + ":" + column);
2080
        }
2081
        
2082
        public void add(String type, String message, String resourceName, int line, int column, File resource) {
2083
            this.tableModel.add(type, message, resourceName, line + ":" + column, resource);
2084
        }
2085
                
2086
        @Override
2087
        public void add(String type, Exception e) {
2088
            if (e  instanceof ScriptingErrorException) {
2089
                ScriptingErrorException se = (ScriptingErrorException) e;
2090
                    this.add(
2091
                        "Error",
2092
                        se.getMessage(),
2093
                        se.getScriptName(),
2094
                        se.getLineNumber(),
2095
                        se.getColumnNumber(),
2096
                        se.getScriptFile()
2097
                    );
2098

    
2099
            } else {
2100
                    this.add("Error", 
2101
                        "Error",
2102
                        e.getMessage(),
2103
                        null
2104
                    );
2105
            }            
2106
        }
2107

    
2108
        @Override
2109
        public Problem getSelect() {
2110
            int row = this.table.getSelectedRow();
2111
            if (row < 0) {
2112
                return null;
2113
            }
2114
            return this.get(row);
2115
        }
2116

    
2117
        @Override
2118
        public int getCount() {
2119
            return this.tableModel.getRowCount();
2120
        }
2121

    
2122
        @Override
2123
        public Problem get(int row) {
2124
            return this.tableModel.getProblem(row);
2125
        }
2126

    
2127
        @Override
2128
        public JComponent asJComponent() {
2129
            return this;
2130
        }
2131

    
2132
    }
2133

    
2134
    public static class DefaultDock extends JPanel implements Dock {
2135

    
2136
        private static final long serialVersionUID = 4899734277977456625L;
2137

    
2138
        public class DefaultDockedPanel implements DockedPanel {
2139

    
2140
            String id;
2141
            String title;
2142
            Component component;
2143
            private final String align;
2144

    
2145
            public DefaultDockedPanel(String id, String title, Component component, String align) {
2146
                this.id = id;
2147
                this.title = title;
2148
                this.component = component;
2149
                this.align = align;
2150
            }
2151

    
2152
            @Override
2153
            public String getId() {
2154
                return this.id;
2155
            }
2156

    
2157
            @Override
2158
            public String getAlign() {
2159
                return this.align;
2160
            }
2161

    
2162
            @Override
2163
            public Component getComponent() {
2164
                return this.component;
2165
            }
2166

    
2167
            @Override
2168
            public String getTitle() {
2169
                return this.title;
2170
            }
2171

    
2172
            @Override
2173
            public boolean isModified() {
2174
                return getModified(this);
2175
            }
2176

    
2177
            @Override
2178
            public void setModified(boolean modified) {
2179
                DefaultDock.this.setModified(this, modified);
2180
            }
2181

    
2182
            @Override
2183
            public void remove() {
2184
                DefaultDock.this.remove(this.getId());
2185
            }
2186

    
2187
            @Override
2188
            public void select() {
2189
                DefaultDock.this.select(this.getId());
2190
            }
2191
        }
2192

    
2193
        private final Map<String, Dock.DockedPanel> panels;
2194
        private final JTabbedPaneClosable tabbedPanelLeft;
2195
        private final JTabbedPaneClosable tabbedPanelBottom;
2196
        private final JTabbedPaneClosable tabbedPanelCenter;
2197
        private Set<ActionListener> closeListeners;
2198
        private Set<ActionListener> activePanelListeners;
2199

    
2200
        public DefaultDock(JTabbedPaneClosable tabbedPanelLeft, JTabbedPaneClosable tabbedPanelBottom, JTabbedPaneClosable tabbedPanelCenter) {
2201
            this.panels = new HashMap<>();
2202
            this.tabbedPanelBottom = tabbedPanelBottom;
2203
            this.tabbedPanelLeft = tabbedPanelLeft;
2204
            this.tabbedPanelCenter = tabbedPanelCenter;
2205

    
2206
            ActionListener onCloseTab = new ActionListener() {
2207

    
2208
                @Override
2209
                public void actionPerformed(ActionEvent e) {
2210
                    JTabbedPaneClosable tabbedPanel = (JTabbedPaneClosable) e.getSource();
2211
                    java.awt.Component component = tabbedPanel.getSelectedComponent();
2212
                    if (component != null) {
2213
                        DockedPanel panel = getDockedPanel(component);
2214
                        if (panel != null) {
2215
                            fireCloseListener(new ActionEvent(panel, 0, ACTION_CLOSE_PANEL));
2216
                        }
2217
//                        panels.remove(panel.getId());
2218
//                        tabbedPanel.remove(panel.getComponent().asJComponent());
2219
                    }
2220
                }
2221
            };
2222
            ChangeListener onChangeTab = new ChangeListener() {
2223

    
2224
                @Override
2225
                public void stateChanged(ChangeEvent e) {
2226
                    
2227
                    fireChangeListener(new ActionEvent(DefaultDock.this, 0, ACTION_ACTIVATE_PANEL));
2228
                }
2229
            };
2230
            this.tabbedPanelCenter.addChangeListener(onChangeTab);
2231
            this.tabbedPanelBottom.addChangeListener(onChangeTab);
2232
            this.tabbedPanelLeft.addChangeListener(onChangeTab);
2233
            
2234
            this.tabbedPanelBottom.addCloseTabListener(onCloseTab);
2235
            this.tabbedPanelLeft.addCloseTabListener(onCloseTab);
2236
            this.tabbedPanelCenter.addCloseTabListener(onCloseTab);
2237

    
2238
        }
2239

    
2240
        /**
2241
         *
2242
         * @param listener
2243
         */
2244
        @Override
2245
        public void addCloseListener(ActionListener listener) {
2246
            if (this.closeListeners == null) {
2247
                this.closeListeners = new HashSet<>();
2248
            }
2249
            this.closeListeners.add(listener);
2250
        }
2251
        
2252
        @Override
2253
        public void removeCloseListener(ActionListener listener) {
2254
            if (this.closeListeners == null) {
2255
                return;
2256
            }
2257
            this.closeListeners.remove(listener);
2258
        }
2259

    
2260
        @Override
2261
        public void addActivateListener(ActionListener listener) {
2262
            if (this.activePanelListeners == null) {
2263
                this.activePanelListeners = new HashSet<>();
2264
            }
2265
            this.activePanelListeners.add(listener);
2266
        }
2267
        
2268
        @Override
2269
        public void removeActivateListener(ActionListener listener) {
2270
            if (this.activePanelListeners == null) {
2271
                return;
2272
            }
2273
            this.activePanelListeners.remove(listener);
2274
        }
2275
                
2276

    
2277
        public void fireCloseListener(ActionEvent e) {
2278
            if (this.closeListeners == null) {
2279
                return;
2280
            }
2281
            for (ActionListener listener : this.closeListeners) {
2282
                try {
2283
                    listener.actionPerformed(e);
2284
                } catch (Exception ex) {
2285

    
2286
                }
2287
            }
2288
        }
2289

    
2290
        public void fireChangeListener(ActionEvent e) {
2291
            if (this.activePanelListeners == null) {
2292
                return;
2293
            }
2294
            for (ActionListener listener : this.activePanelListeners) {
2295
                try {
2296
                    listener.actionPerformed(e);
2297
                } catch (Exception ex) {
2298

    
2299
                }
2300
            }
2301
        }
2302

    
2303
        private JTabbedPaneClosable getTabbedPanel(String align) {
2304
            switch (align) {
2305
                case Dock.DOCK_LEFT:
2306
                    return this.tabbedPanelLeft;
2307
                case Dock.DOCK_CENTER:
2308
                    return this.tabbedPanelCenter;
2309
                default:
2310
                case Dock.DOCK_BOTTOM:
2311
                    return this.tabbedPanelBottom;
2312
            }
2313
        }
2314

    
2315
        private DockedPanel getDockedPanel(java.awt.Component component) {
2316
            for (DockedPanel panel : this.panels.values()) {
2317
                if (panel.getComponent().asJComponent() == component) {
2318
                    return panel;
2319
                }
2320
            }
2321
            return null;
2322
        }
2323

    
2324
        private int getIndex(DockedPanel panel) {
2325
            final JTabbedPaneClosable tabbedPanel = getTabbedPanel(panel.getAlign());
2326
            for (int i = 0; i < tabbedPanel.getTabCount(); i++) {
2327
                java.awt.Component component = tabbedPanel.getComponentAt(i);
2328
                if (component == panel.getComponent().asJComponent()) {
2329
                    return i;
2330
                }
2331
            }
2332
            return -1;
2333
        }
2334

    
2335
        @Override
2336
        public void setModified(DockedPanel panel, boolean modified) {
2337
            final int index = this.getIndex(panel);
2338
            if (index < 0) {
2339
                return;
2340
            }
2341
            final JTabbedPaneClosable tabbedPanel = getTabbedPanel(panel.getAlign());
2342
            tabbedPanel.setTabModified(index, modified);
2343
        }
2344

    
2345
        @Override
2346
        public boolean getModified(DockedPanel panel) {
2347
            final int index = this.getIndex(panel);
2348
            if (index < 0) {
2349
                return false;
2350
            }
2351
            final JTabbedPaneClosable tabbedPanel = getTabbedPanel(panel.getAlign());
2352
            return tabbedPanel.isTabModified(index);
2353
        }
2354

    
2355
        @Override
2356
        public DockedPanel getSelected(String align) {
2357
            final JTabbedPaneClosable tabbedPanel = getTabbedPanel(align);
2358
            java.awt.Component selected = tabbedPanel.getSelectedComponent();
2359
            return this.getDockedPanel(selected);
2360
        }
2361

    
2362
        @Override
2363
        public DockedPanel add(String id, String title, final Component component, String align) {
2364
            final JTabbedPaneClosable tabbedPanel = getTabbedPanel(align);
2365
            DockedPanel panel = this.panels.get(id);
2366
            if (panel != null) {
2367
                tabbedPanel.remove(panel.getComponent().asJComponent());
2368
            }
2369
            panel = new DefaultDockedPanel(id, title, component, align);
2370
            this.panels.put(id, panel);
2371
            tabbedPanel.add(panel.getTitle(), panel.getComponent().asJComponent());
2372
            return panel;
2373
        }
2374

    
2375
        @Override
2376
        public void remove(String id) {
2377
            DockedPanel panel = this.panels.get(id);
2378
            if (panel != null) {
2379
                final JTabbedPaneClosable tabbedPanel = getTabbedPanel(panel.getAlign());
2380
                tabbedPanel.remove(panel.getComponent().asJComponent());
2381
                this.panels.remove(id);
2382
            }
2383
        }
2384

    
2385
        @Override
2386
        public DockedPanel get(String id) {
2387
            DockedPanel panel = this.panels.get(id);
2388
            return panel;
2389
        }
2390

    
2391
        @Override
2392
        public void select(String id) {
2393
            DockedPanel panel = this.panels.get(id);
2394
            if (panel != null) {
2395
                final JTabbedPaneClosable tabbedPanel = getTabbedPanel(panel.getAlign());
2396
                tabbedPanel.setSelectedComponent(panel.getComponent().asJComponent());
2397
            }
2398
        }
2399

    
2400
        @Override
2401
        public Iterator<DockedPanel> iterator() {
2402
            return this.panels.values().iterator();
2403
        }
2404

    
2405
    }
2406

    
2407
    private static class ToolEntry {
2408

    
2409
        private String name;
2410
        private String text;
2411
        private Action action;
2412
        private JComponent component;
2413

    
2414
        public ToolEntry(String name, Action action, String text) {
2415
            this.name = name;
2416
            this.action = action;
2417
            this.text = text;
2418
        }
2419

    
2420
        public ToolEntry(String name, Action action) {
2421
            this(name, action, null);
2422
        }
2423

    
2424
        public String getName() {
2425
            return this.name;
2426
        }
2427

    
2428
        public String getText() {
2429
            return this.text;
2430
        }
2431

    
2432
        public Action getAction() {
2433
            return this.action;
2434
        }
2435

    
2436
        public JComponent getComponent() {
2437
            return this.component;
2438
        }
2439

    
2440
        public void setComponent(JComponent component) {
2441
            this.component = component;
2442
        }
2443
    }
2444

    
2445
    public class ButtonWithContext extends JButton {
2446

    
2447
        private static final long serialVersionUID = -7434255417630073101L;
2448

    
2449
        public ButtonWithContext(Action action) {
2450
            super(action);
2451
            this.setBorderPainted(false);
2452
            this.setText("");
2453
        }
2454

    
2455
        public Object getContext() {
2456
            return DefaultJScriptingComposer.this;
2457
        }
2458
    }
2459

    
2460
    private class FindReplaceSearchListener implements SearchListener {
2461

    
2462
        @Override
2463
        public void searchEvent(SearchEvent e) {
2464

    
2465
            RSyntaxTextArea textArea = getCurrentRSyntaxTextArea();
2466
            if (textArea == null) {
2467
                return;
2468
            }
2469

    
2470
            SearchEvent.Type type = e.getType();
2471
            SearchContext context = e.getSearchContext();
2472
            SearchResult result;
2473

    
2474
            switch (type) {
2475
                default: // Prevent FindBugs warning later
2476
                case MARK_ALL:
2477
                    result = SearchEngine.markAll(textArea, context);
2478
                    break;
2479
                case FIND:
2480
                    result = SearchEngine.find(textArea, context);
2481
                    if (!result.wasFound()) {
2482
                        UIManager.getLookAndFeel().provideErrorFeedback(textArea);
2483
                    }
2484
                    break;
2485
                case REPLACE:
2486
                    result = SearchEngine.replace(textArea, context);
2487
                    if (!result.wasFound()) {
2488
                        UIManager.getLookAndFeel().provideErrorFeedback(textArea);
2489
                    }
2490
                    break;
2491
                case REPLACE_ALL:
2492
                    result = SearchEngine.replaceAll(textArea, context);
2493
                    JOptionPane.showMessageDialog(null, result.getCount()
2494
                            + " occurrences replaced.");
2495
                    break;
2496
            }
2497
            String text;
2498
            if (result.wasFound()) {
2499
                text = "Text found; occurrences marked: " + result.getMarkedCount();
2500
            } else if (type == SearchEvent.Type.MARK_ALL) {
2501
                if (result.getMarkedCount() > 0) {
2502
                    text = "Occurrences marked: " + result.getMarkedCount();
2503
                } else {
2504
                    text = "";
2505
                }
2506
            } else {
2507
                text = "Text not found";
2508
            }
2509
            getStatusbar().message(text);
2510
        }
2511

    
2512
        @Override
2513
        public String getSelectedText() {
2514
            RSyntaxTextArea textArea = getCurrentRSyntaxTextArea();
2515
            if (textArea == null) {
2516
                return "";
2517
            }
2518
            return textArea.getSelectedText();
2519
        }
2520

    
2521
    }
2522
}