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

History | View | Annotate | Download (87.5 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
        List<DockedPanel> toRemove = new ArrayList<>();
1411

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

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

    
1489
    /**
1490
     * Funciones de 'cortar', 'copiar', 'pegar' y 'seleccionar todo' para los
1491
     * JEditors
1492
     *
1493
     */
1494
    public void currentScriptCopy() {
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().copy();
1499
        }
1500
    }
1501

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

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

    
1520
    public void currentScriptSelectAll() {
1521
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1522
        if (panel.getComponent().asJComponent() instanceof JCodeEditor) {
1523
            JCodeEditor editor = (JCodeEditor) panel.getComponent().asJComponent();
1524
            editor.getJTextComponent().selectAll();
1525
        }
1526
    }
1527

    
1528
    /**
1529
     * Funci?n para el guardado del ScriptingBaseScript de la pesta?a actual
1530
     *
1531
     */
1532
    public void currentScriptSave() {
1533
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1534
        if (panel.getComponent().asJComponent() instanceof JEditor) {
1535
            JEditor editor = (JEditor) panel.getComponent().asJComponent();
1536
            editor.save();
1537
            panel.setModified(false);
1538
        }
1539
    }
1540

    
1541
    @Override
1542
    public JEditor getCurrentEditor() {
1543
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1544
        if (panel == null) {
1545
            return null;
1546
        }
1547
        if (panel.getComponent().asJComponent() instanceof JEditor) {
1548
            return (JEditor) panel.getComponent().asJComponent();
1549
        }
1550
        return null;
1551
    }
1552

    
1553
    @Override
1554
    public ScriptingScript getCurrentScript() {
1555
        JEditor editor = this.getCurrentEditor();
1556
        if (editor == null) {
1557
            return null;
1558
        }
1559
        ScriptingUnit unit = editor.getUnit();
1560
        if( unit instanceof ScriptingScript ) {
1561
            return (ScriptingScript) unit;
1562
        }
1563
        return null;
1564
    }
1565

    
1566
    private RSyntaxTextArea getCurrentRSyntaxTextArea() {
1567
        JEditor editor = getCurrentEditor();
1568
        if (editor instanceof JCodeEditor) {
1569
            JTextComponent textComponent = ((JCodeEditor) editor).getJTextComponent();
1570
            if (textComponent instanceof RSyntaxTextArea) {
1571
                return (RSyntaxTextArea) textComponent;
1572
            }
1573
        }
1574
        return null;
1575
    }
1576

    
1577
    @Override
1578
    public void refreshProjects() {
1579
        try {
1580
            this.getProjects().refresh();
1581
        } catch (Exception ex) {
1582
            // Ignore
1583
        }
1584
    }
1585

    
1586
    @Override
1587
    public StatusBar getStatusbar() {
1588
        return this.statusBar;
1589
    }
1590

    
1591
    /**
1592
     *
1593
     * @param e
1594
     */
1595
    @Override
1596
    public void actionPerformed(ActionEvent e) {
1597

    
1598
        if (e instanceof UpdateCaretPositionActionEvent) {
1599
            UpdateCaretPositionActionEvent e2 = (UpdateCaretPositionActionEvent) e;
1600

    
1601
            if (e2.hasLineAndColumn()) {
1602
                this.getStatusbar().setPosition(e2.getLine(), e2.getColumn());
1603
            } else {
1604
                this.getStatusbar().setPosition(0, 0);
1605
            }
1606
        }
1607
    }
1608

    
1609
    @Override
1610
    public void update(final Observable observable, final Object notification) {
1611
        if (!SwingUtilities.isEventDispatchThread()) {
1612
            SwingUtilities.invokeLater(new Runnable() {
1613
                @Override
1614
                public void run() {
1615
                    update(observable, notification);
1616
                }
1617
            });
1618
            return;
1619
        }
1620
        if (notification instanceof ScriptingNotification) {
1621
            ScriptingNotification e = (ScriptingNotification) notification;
1622

    
1623
            if (e.getException() instanceof CompileErrorException) {
1624
                CompileErrorException ce = (CompileErrorException) e.getException();
1625
                Problems problems = this.getProblems();
1626
                if (problems != null) {
1627
                    problems.add("Error", ce);
1628
                    this.dock.select(DOCKED_PROBLEMS);
1629
                }
1630

    
1631
            } else if (e.getException() instanceof ExecuteErrorException) {
1632
                ExecuteErrorException ee = (ExecuteErrorException) e.getException();
1633
                Problems problems = this.getProblems();
1634
                if (problems != null) {
1635
                    problems.add("Error",ee);
1636
                    this.dock.select(DOCKED_PROBLEMS);
1637
                }
1638
                JScriptingConsole console = this.getConsole();
1639
                if (console != null) {
1640
                    console.append(ee.getMessage(), Color.RED.darker());
1641
                    ee.printStackTrace(console.errors());
1642
                }
1643

    
1644
            } else {
1645
                Exception ex = e.getException();
1646
                Problems problems = this.getProblems();
1647
                if (problems != null) {
1648
                    problems.add("Error",ex); 
1649
                    this.dock.select(DOCKED_PROBLEMS);
1650
                }
1651
                JScriptingConsole console = this.getConsole();
1652
                if (console != null) {
1653
                    console.append(ex.getMessage(), Color.RED.darker());
1654
                    ex.printStackTrace(console.errors());
1655
                }
1656
            }
1657
        }
1658
    }
1659

    
1660
    public void closeWindow() {
1661
        this.setVisible(false);
1662
    }
1663

    
1664
    private static class DefaultStatusBar extends JPanel implements StatusBar {
1665

    
1666
        private static final long serialVersionUID = -6135634992327170084L;
1667

    
1668
        private JLabel message;
1669
        private JLabel position;
1670
        private final ScriptingUIManager uimanager;
1671

    
1672
        public DefaultStatusBar(ScriptingUIManager uimanager) {
1673
            this.uimanager = uimanager;
1674
            this.initComponents();
1675
        }
1676

    
1677
        private void initComponents() {
1678
            this.message = new JLabel(this.uimanager.getTranslation("Welcome_message"));
1679
            this.position = new JLabel("Line 0:0");
1680

    
1681
            this.setLayout(new BorderLayout());
1682

    
1683
            this.add(this.message, BorderLayout.WEST);
1684
            this.add(this.position, BorderLayout.EAST);
1685
        }
1686

    
1687
        @Override
1688
        public void clear() {
1689
            this.message.setText("");
1690
        }
1691

    
1692
        @Override
1693
        public void message(String message) {
1694
            this.message.setText(message);
1695
        }
1696

    
1697
        @Override
1698
        public void setPosition(int line) {
1699
            this.setPosition(line, -1);
1700
        }
1701

    
1702
        @Override
1703
        public void setPosition(int line, int column) {
1704
            if (line < 0) {
1705
                this.position.setText("");
1706
                return;
1707
            }
1708
            if (column < 0) {
1709
                this.position.setText(this.uimanager.getTranslation("Line") + " " + line + ":0");
1710
            } else {
1711
                this.position.setText(this.uimanager.getTranslation("Line") + " " + line + ":" + column);
1712
            }
1713
        }
1714

    
1715
        @Override
1716
        public JComponent asJComponent() {
1717
            return this;
1718
        }
1719
    }
1720

    
1721
    public static class JTabbedPaneClosable extends JTabbedPane {
1722

    
1723
        private static final long serialVersionUID = -3995298424891579555L;
1724

    
1725
        private final ActionListenerSupport closeTabListeners;
1726
        private ScriptingUIManager uimanager;
1727

    
1728
        private class TabTitleComponent extends JPanel {
1729

    
1730
            private static final long serialVersionUID = -1061417669527944341L;
1731
            private final JLabel label;
1732
            private final JButton button;
1733
            private boolean changed = false;
1734
            private final Font fontNormal;
1735
            private final Font fontBold;
1736

    
1737
            public TabTitleComponent(String title, final ActionListener onclose) {
1738
                this.setOpaque(true);
1739
                this.label = new JLabel(title + " ");
1740
                this.label.setOpaque(true);
1741
                this.label.setBackground(UIManager.getColor("TabbedPane.tabAreaBackground"));
1742
                this.label.setVerticalTextPosition(SwingConstants.CENTER);
1743
                this.fontNormal = this.label.getFont();
1744
                this.fontBold = new Font(this.fontNormal.getFontName(), Font.BOLD, this.fontNormal.getSize());
1745

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

    
1770
            public void setTitle(String title) {
1771
                this.label.setText(title);
1772
            }
1773

    
1774
            public String getTitle() {
1775
                return this.label.getText();
1776
            }
1777

    
1778
            public void setChanged(boolean changed) {
1779
                if (changed) {
1780
                    this.label.setFont(this.fontBold);
1781
                } else {
1782
                    this.label.setFont(this.fontNormal);
1783
                }
1784
                this.changed = changed;
1785
            }
1786

    
1787
            public boolean isChanged() {
1788
                return this.changed;
1789
            }
1790
        }
1791

    
1792
        public JTabbedPaneClosable(ScriptingUIManager uimanager) {
1793
            super();
1794
            this.uimanager = uimanager;
1795
            this.closeTabListeners = ToolsSwingLocator.getToolsSwingManager().createActionListenerSupport();
1796
        }
1797

    
1798
        @Override
1799
        public String getTitleAt(int index) {
1800
            TabTitleComponent title = (TabTitleComponent) this.getTabComponentAt(index);
1801
            if (title == null) {
1802
                return null;
1803
            }
1804
            return title.getTitle();
1805
        }
1806

    
1807
        @Override
1808
        public void setTitleAt(int index, String title) {
1809
            TabTitleComponent titleComponent = (TabTitleComponent) this.getTabComponentAt(index);
1810
            titleComponent.setTitle(title);
1811
        }
1812

    
1813
        @Override
1814
        public void addTab(String title, java.awt.Component component) {
1815
            super.addTab(null, component);
1816
            int index = getTabCount() - 1;
1817
            TabTitleComponent tabcomponent = new TabTitleComponent(title, new ActionListener() {
1818

    
1819
                @Override
1820
                public void actionPerformed(ActionEvent ae) {
1821
                    TabTitleComponent tabTitleComponent = (TabTitleComponent) ae.getSource();
1822
                    int index = indexOfTabComponent(tabTitleComponent);
1823
                    setSelectedIndex(index);
1824
                    ae.setSource(JTabbedPaneClosable.this);
1825
                    closeTabListeners.fireActionEvent(ae);
1826
                }
1827
            });
1828
            super.setTabComponentAt(index, tabcomponent);
1829
        }
1830

    
1831
        public void addCloseTabListener(ActionListener remove) {
1832
            this.closeTabListeners.addActionListener(remove);
1833
        }
1834

    
1835
        public void removeCloseTabListener(ActionListener remove) {
1836
            this.closeTabListeners.removeActionListener(remove);
1837
        }
1838

    
1839
        public ActionListener[] getCloseTabListeners() {
1840
            return this.closeTabListeners.getActionListeners();
1841
        }
1842

    
1843
        public boolean isTabModified(int index) {
1844
            TabTitleComponent comp = (TabTitleComponent) this.getTabComponentAt(index);
1845
            if (comp == null) {
1846
                return false;
1847
            }
1848
            return comp.isChanged();
1849
        }
1850

    
1851
        public void setTabModified(int index, boolean changed) {
1852
            TabTitleComponent comp = (TabTitleComponent) this.getTabComponentAt(index);
1853
            if (comp != null) {
1854
                comp.setChanged(changed);
1855
            }
1856
        }
1857
    }
1858

    
1859
    public static class DefaultProblems extends JPanel implements Problems {
1860

    
1861
        private static final long serialVersionUID = 7728033081188167969L;
1862

    
1863
        private static final int COLUMN_TYPE = 0;
1864
        private static final int COLUMN_MESSAGE = 1;
1865
        private static final int COLUMN_RESOURCE = 2;
1866
        private static final int COLUMN_LOCATION = 3;
1867
        private static final int NUM_COLUMNS = 4;
1868

    
1869
        private JTable table;
1870
        private ProblemsTableMode tableModel;
1871
        private final ScriptingUIManager uimanager;
1872
        private Set<ListSelectionListener> selectionListeners; 
1873

    
1874
        public static class ProblemsTableMode extends DefaultTableModel implements TableModel {
1875
            private static final long serialVersionUID = -3294067602561419422L;
1876

    
1877
            public static class DefaultProblem implements Problem {
1878

    
1879
                String[] row;
1880
                private File resource;
1881

    
1882
                public DefaultProblem() {
1883
                    this.row = new String[NUM_COLUMNS];
1884
                }
1885

    
1886
                public DefaultProblem(String[] row) {
1887
                    this.row = row;
1888
                }
1889

    
1890
                public DefaultProblem(String type, String message, String resourceName, String location, File resource) {
1891
                    String[] row = new String[NUM_COLUMNS];
1892
                    row[COLUMN_TYPE] = type;
1893
                    row[COLUMN_MESSAGE] = message;
1894
                    row[COLUMN_RESOURCE] = resourceName;
1895
                    row[COLUMN_LOCATION] = location;
1896
                    this.resource = resource;
1897
                    this.row = row;
1898
                }
1899

    
1900
                public String get(int index) {
1901
                    return row[index];
1902
                }
1903

    
1904
                public String getValue(int index) {
1905
                    return row[index];
1906
                }
1907

    
1908
                public void setValue(int index, String value) {
1909
                    row[index] = value;
1910
                }
1911

    
1912
                @Override
1913
                public String getType() {
1914
                    return this.row[COLUMN_TYPE];
1915
                }
1916

    
1917
                @Override
1918
                public String getMessage() {
1919
                    return this.row[COLUMN_MESSAGE];
1920
                }
1921

    
1922
                @Override
1923
                public String getResourceName() {
1924
                    return this.row[COLUMN_RESOURCE];
1925
                }
1926

    
1927
                @Override
1928
                public File getResource() {
1929
                    return this.resource;
1930
                }
1931

    
1932
                @Override
1933
                public int getLineNumber() {
1934
                    try {
1935
                        String[] lineAndColumn = this.row[COLUMN_LOCATION].split(":");
1936
                        if (lineAndColumn.length > 0) {
1937
                            int lineno = Integer.parseInt(lineAndColumn[0].trim());
1938
                            return lineno;
1939
                        }
1940
                    } catch (Exception e) {
1941
                        // Do nothing
1942
                    }
1943
                    return -1;
1944
                }
1945

    
1946
            }
1947
            private final ScriptingUIManager uimanager;
1948
            private List<DefaultProblem> data;
1949
            private String[] columnNames;
1950

    
1951
            public ProblemsTableMode(ScriptingUIManager uimanager) {
1952
                this.uimanager = uimanager;
1953
                this.columnNames = new String[]{
1954
                    this.uimanager.getTranslation("Category"),
1955
                    this.uimanager.getTranslation("Description"),
1956
                    this.uimanager.getTranslation("Resource"),
1957
                    this.uimanager.getTranslation("Location")
1958
                };
1959

    
1960
            }
1961
            
1962
            private List<DefaultProblem> getData() {
1963
                if( this.data == null ) {
1964
                    this.data = new ArrayList<>();
1965
                }
1966
                return this.data;
1967
            }
1968

    
1969
            public void add(DefaultProblem row) {
1970
                this.getData().add(row);
1971
                this.fireTableDataChanged();
1972
            }
1973

    
1974
            private void add(String type, String message, String resourceName, String location, File resource) {
1975
                DefaultProblem problem = new DefaultProblem(type, message, resourceName, location, resource);
1976
                this.add(problem);
1977
            }
1978

    
1979
            @Override
1980
            public int getRowCount() {
1981
                return this.getData().size();
1982
            }
1983

    
1984
            @Override
1985
            public int getColumnCount() {
1986
                return NUM_COLUMNS;
1987
            }
1988

    
1989
            @Override
1990
            public String getColumnName(int columnIndex) {
1991
                return columnNames[columnIndex];
1992
            }
1993

    
1994
            @Override
1995
            public Class<?> getColumnClass(int columnIndex) {
1996
                return String.class;
1997
            }
1998

    
1999
            @Override
2000
            public boolean isCellEditable(int rowIndex, int columnIndex) {
2001
                return false;
2002
            }
2003

    
2004
            @Override
2005
            public Object getValueAt(int rowIndex, int columnIndex) {
2006
                return this.getData().get(rowIndex).get(columnIndex);
2007
            }
2008
            
2009
            public Problem getProblem(int rowIndex) {
2010
                return this.getData().get(rowIndex);
2011
            }
2012

    
2013
            @Override
2014
            public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
2015
                this.getData().get(rowIndex).setValue(columnIndex, (String) aValue);
2016
            }
2017

    
2018
            public void removeAll() {
2019
                this.getData().clear();
2020
            }
2021
        }
2022

    
2023
        public DefaultProblems(ScriptingUIManager uimanager) {
2024
            this.uimanager = uimanager;
2025
            this.initComponents();
2026
        }
2027

    
2028
        private void initComponents() {
2029
            this.selectionListeners = new HashSet<>();
2030
            tableModel = new ProblemsTableMode(this.uimanager);
2031
            table = new JTable(tableModel);
2032
            table.getColumnModel().getColumn(1).setPreferredWidth(300);
2033

    
2034
            table.setRowSelectionAllowed(true);
2035
            table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
2036

    
2037
            JScrollPane scrollProblems = new JScrollPane(table);
2038
            scrollProblems.setAutoscrolls(true);
2039

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

    
2057
        @Override
2058
        public void addListSelectionListener(ListSelectionListener listener) {
2059
            this.table.getSelectionModel().addListSelectionListener(listener);
2060
            this.selectionListeners.add(listener);
2061
        }
2062

    
2063
        private void fireSelectionListeners() {
2064
            int row = this.table.getSelectedRow();
2065
            for( ListSelectionListener listener : this.selectionListeners ) {
2066
                try {
2067
                    listener.valueChanged(new ListSelectionEvent(this, row, row, false));
2068
                } catch(Exception th) {
2069
                    
2070
                }
2071
            }
2072
        }
2073
        
2074
        @Override
2075
        public void removeAll() {
2076
            this.tableModel.removeAll();
2077
            this.table.updateUI();
2078
        }
2079

    
2080
        @Override
2081
        public void add(String type, String message, String resource, String location) {
2082
            this.tableModel.add(type, message, resource, location, null);
2083
        }
2084

    
2085
        @Override
2086
        public void add(String type, String message, String resource, int line, int column) {
2087
            this.add(type, message, resource, line + ":" + column);
2088
        }
2089
        
2090
        public void add(String type, String message, String resourceName, int line, int column, File resource) {
2091
            this.tableModel.add(type, message, resourceName, line + ":" + column, resource);
2092
        }
2093
                
2094
        @Override
2095
        public void add(String type, Exception e) {
2096
            if (e  instanceof ScriptingErrorException) {
2097
                ScriptingErrorException se = (ScriptingErrorException) e;
2098
                    this.add(
2099
                        "Error",
2100
                        se.getMessage(),
2101
                        se.getScriptName(),
2102
                        se.getLineNumber(),
2103
                        se.getColumnNumber(),
2104
                        se.getScriptFile()
2105
                    );
2106

    
2107
            } else {
2108
                    this.add("Error", 
2109
                        "Error",
2110
                        e.getMessage(),
2111
                        null
2112
                    );
2113
            }            
2114
        }
2115

    
2116
        @Override
2117
        public Problem getSelect() {
2118
            int row = this.table.getSelectedRow();
2119
            if (row < 0) {
2120
                return null;
2121
            }
2122
            return this.get(row);
2123
        }
2124

    
2125
        @Override
2126
        public int getCount() {
2127
            return this.tableModel.getRowCount();
2128
        }
2129

    
2130
        @Override
2131
        public Problem get(int row) {
2132
            return this.tableModel.getProblem(row);
2133
        }
2134

    
2135
        @Override
2136
        public JComponent asJComponent() {
2137
            return this;
2138
        }
2139

    
2140
    }
2141

    
2142
    public static class DefaultDock extends JPanel implements Dock {
2143

    
2144
        private static final long serialVersionUID = 4899734277977456625L;
2145

    
2146
        public class DefaultDockedPanel implements DockedPanel {
2147

    
2148
            String id;
2149
            String title;
2150
            Component component;
2151
            private final String align;
2152

    
2153
            public DefaultDockedPanel(String id, String title, Component component, String align) {
2154
                this.id = id;
2155
                this.title = title;
2156
                this.component = component;
2157
                this.align = align;
2158
            }
2159

    
2160
            @Override
2161
            public String getId() {
2162
                return this.id;
2163
            }
2164

    
2165
            @Override
2166
            public String getAlign() {
2167
                return this.align;
2168
            }
2169

    
2170
            @Override
2171
            public Component getComponent() {
2172
                return this.component;
2173
            }
2174

    
2175
            @Override
2176
            public String getTitle() {
2177
                return this.title;
2178
            }
2179

    
2180
            @Override
2181
            public boolean isModified() {
2182
                return getModified(this);
2183
            }
2184

    
2185
            @Override
2186
            public void setModified(boolean modified) {
2187
                DefaultDock.this.setModified(this, modified);
2188
            }
2189

    
2190
            @Override
2191
            public void remove() {
2192
                DefaultDock.this.remove(this.getId());
2193
            }
2194

    
2195
            @Override
2196
            public void select() {
2197
                DefaultDock.this.select(this.getId());
2198
            }
2199
        }
2200

    
2201
        private final Map<String, Dock.DockedPanel> panels;
2202
        private final JTabbedPaneClosable tabbedPanelLeft;
2203
        private final JTabbedPaneClosable tabbedPanelBottom;
2204
        private final JTabbedPaneClosable tabbedPanelCenter;
2205
        private Set<ActionListener> closeListeners;
2206
        private Set<ActionListener> activePanelListeners;
2207

    
2208
        public DefaultDock(JTabbedPaneClosable tabbedPanelLeft, JTabbedPaneClosable tabbedPanelBottom, JTabbedPaneClosable tabbedPanelCenter) {
2209
            this.panels = new HashMap<>();
2210
            this.tabbedPanelBottom = tabbedPanelBottom;
2211
            this.tabbedPanelLeft = tabbedPanelLeft;
2212
            this.tabbedPanelCenter = tabbedPanelCenter;
2213

    
2214
            ActionListener onCloseTab = new ActionListener() {
2215

    
2216
                @Override
2217
                public void actionPerformed(ActionEvent e) {
2218
                    JTabbedPaneClosable tabbedPanel = (JTabbedPaneClosable) e.getSource();
2219
                    java.awt.Component component = tabbedPanel.getSelectedComponent();
2220
                    if (component != null) {
2221
                        DockedPanel panel = getDockedPanel(component);
2222
                        if (panel != null) {
2223
                            fireCloseListener(new ActionEvent(panel, 0, ACTION_CLOSE_PANEL));
2224
                        }
2225
//                        panels.remove(panel.getId());
2226
//                        tabbedPanel.remove(panel.getComponent().asJComponent());
2227
                    }
2228
                }
2229
            };
2230
            ChangeListener onChangeTab = new ChangeListener() {
2231

    
2232
                @Override
2233
                public void stateChanged(ChangeEvent e) {
2234
                    
2235
                    fireChangeListener(new ActionEvent(DefaultDock.this, 0, ACTION_ACTIVATE_PANEL));
2236
                }
2237
            };
2238
            this.tabbedPanelCenter.addChangeListener(onChangeTab);
2239
            this.tabbedPanelBottom.addChangeListener(onChangeTab);
2240
            this.tabbedPanelLeft.addChangeListener(onChangeTab);
2241
            
2242
            this.tabbedPanelBottom.addCloseTabListener(onCloseTab);
2243
            this.tabbedPanelLeft.addCloseTabListener(onCloseTab);
2244
            this.tabbedPanelCenter.addCloseTabListener(onCloseTab);
2245

    
2246
        }
2247

    
2248
        /**
2249
         *
2250
         * @param listener
2251
         */
2252
        @Override
2253
        public void addCloseListener(ActionListener listener) {
2254
            if (this.closeListeners == null) {
2255
                this.closeListeners = new HashSet<>();
2256
            }
2257
            this.closeListeners.add(listener);
2258
        }
2259
        
2260
        @Override
2261
        public void removeCloseListener(ActionListener listener) {
2262
            if (this.closeListeners == null) {
2263
                return;
2264
            }
2265
            this.closeListeners.remove(listener);
2266
        }
2267

    
2268
        @Override
2269
        public void addActivateListener(ActionListener listener) {
2270
            if (this.activePanelListeners == null) {
2271
                this.activePanelListeners = new HashSet<>();
2272
            }
2273
            this.activePanelListeners.add(listener);
2274
        }
2275
        
2276
        @Override
2277
        public void removeActivateListener(ActionListener listener) {
2278
            if (this.activePanelListeners == null) {
2279
                return;
2280
            }
2281
            this.activePanelListeners.remove(listener);
2282
        }
2283
                
2284

    
2285
        public void fireCloseListener(ActionEvent e) {
2286
            if (this.closeListeners == null) {
2287
                return;
2288
            }
2289
            for (ActionListener listener : this.closeListeners) {
2290
                try {
2291
                    listener.actionPerformed(e);
2292
                } catch (Exception ex) {
2293

    
2294
                }
2295
            }
2296
        }
2297

    
2298
        public void fireChangeListener(ActionEvent e) {
2299
            if (this.activePanelListeners == null) {
2300
                return;
2301
            }
2302
            for (ActionListener listener : this.activePanelListeners) {
2303
                try {
2304
                    listener.actionPerformed(e);
2305
                } catch (Exception ex) {
2306

    
2307
                }
2308
            }
2309
        }
2310

    
2311
        private JTabbedPaneClosable getTabbedPanel(String align) {
2312
            switch (align) {
2313
                case Dock.DOCK_LEFT:
2314
                    return this.tabbedPanelLeft;
2315
                case Dock.DOCK_CENTER:
2316
                    return this.tabbedPanelCenter;
2317
                default:
2318
                case Dock.DOCK_BOTTOM:
2319
                    return this.tabbedPanelBottom;
2320
            }
2321
        }
2322

    
2323
        private DockedPanel getDockedPanel(java.awt.Component component) {
2324
            for (DockedPanel panel : this.panels.values()) {
2325
                if (panel.getComponent().asJComponent() == component) {
2326
                    return panel;
2327
                }
2328
            }
2329
            return null;
2330
        }
2331

    
2332
        private int getIndex(DockedPanel panel) {
2333
            final JTabbedPaneClosable tabbedPanel = getTabbedPanel(panel.getAlign());
2334
            for (int i = 0; i < tabbedPanel.getTabCount(); i++) {
2335
                java.awt.Component component = tabbedPanel.getComponentAt(i);
2336
                if (component == panel.getComponent().asJComponent()) {
2337
                    return i;
2338
                }
2339
            }
2340
            return -1;
2341
        }
2342

    
2343
        @Override
2344
        public void setModified(DockedPanel panel, boolean modified) {
2345
            final int index = this.getIndex(panel);
2346
            if (index < 0) {
2347
                return;
2348
            }
2349
            final JTabbedPaneClosable tabbedPanel = getTabbedPanel(panel.getAlign());
2350
            tabbedPanel.setTabModified(index, modified);
2351
        }
2352

    
2353
        @Override
2354
        public boolean getModified(DockedPanel panel) {
2355
            final int index = this.getIndex(panel);
2356
            if (index < 0) {
2357
                return false;
2358
            }
2359
            final JTabbedPaneClosable tabbedPanel = getTabbedPanel(panel.getAlign());
2360
            return tabbedPanel.isTabModified(index);
2361
        }
2362

    
2363
        @Override
2364
        public DockedPanel getSelected(String align) {
2365
            final JTabbedPaneClosable tabbedPanel = getTabbedPanel(align);
2366
            java.awt.Component selected = tabbedPanel.getSelectedComponent();
2367
            return this.getDockedPanel(selected);
2368
        }
2369

    
2370
        @Override
2371
        public DockedPanel add(String id, String title, final Component component, String align) {
2372
            final JTabbedPaneClosable tabbedPanel = getTabbedPanel(align);
2373
            DockedPanel panel = this.panels.get(id);
2374
            if (panel != null) {
2375
                tabbedPanel.remove(panel.getComponent().asJComponent());
2376
            }
2377
            panel = new DefaultDockedPanel(id, title, component, align);
2378
            this.panels.put(id, panel);
2379
            tabbedPanel.add(panel.getTitle(), panel.getComponent().asJComponent());
2380
            return panel;
2381
        }
2382

    
2383
        @Override
2384
        public void remove(String id) {
2385
            DockedPanel panel = this.panels.get(id);
2386
            if (panel != null) {
2387
                final JTabbedPaneClosable tabbedPanel = getTabbedPanel(panel.getAlign());
2388
                tabbedPanel.remove(panel.getComponent().asJComponent());
2389
                this.panels.remove(id);
2390
            }
2391
        }
2392

    
2393
        @Override
2394
        public DockedPanel get(String id) {
2395
            DockedPanel panel = this.panels.get(id);
2396
            return panel;
2397
        }
2398

    
2399
        @Override
2400
        public void select(String id) {
2401
            DockedPanel panel = this.panels.get(id);
2402
            if (panel != null) {
2403
                final JTabbedPaneClosable tabbedPanel = getTabbedPanel(panel.getAlign());
2404
                tabbedPanel.setSelectedComponent(panel.getComponent().asJComponent());
2405
            }
2406
        }
2407

    
2408
        @Override
2409
        public Iterator<DockedPanel> iterator() {
2410
            return this.panels.values().iterator();
2411
        }
2412

    
2413
    }
2414

    
2415
    private static class ToolEntry {
2416

    
2417
        private String name;
2418
        private String text;
2419
        private Action action;
2420
        private JComponent component;
2421

    
2422
        public ToolEntry(String name, Action action, String text) {
2423
            this.name = name;
2424
            this.action = action;
2425
            this.text = text;
2426
        }
2427

    
2428
        public ToolEntry(String name, Action action) {
2429
            this(name, action, null);
2430
        }
2431

    
2432
        public String getName() {
2433
            return this.name;
2434
        }
2435

    
2436
        public String getText() {
2437
            return this.text;
2438
        }
2439

    
2440
        public Action getAction() {
2441
            return this.action;
2442
        }
2443

    
2444
        public JComponent getComponent() {
2445
            return this.component;
2446
        }
2447

    
2448
        public void setComponent(JComponent component) {
2449
            this.component = component;
2450
        }
2451
    }
2452

    
2453
    public class ButtonWithContext extends JButton {
2454

    
2455
        private static final long serialVersionUID = -7434255417630073101L;
2456

    
2457
        public ButtonWithContext(Action action) {
2458
            super(action);
2459
            this.setBorderPainted(false);
2460
            this.setText("");
2461
        }
2462

    
2463
        public Object getContext() {
2464
            return DefaultJScriptingComposer.this;
2465
        }
2466
    }
2467

    
2468
    private class FindReplaceSearchListener implements SearchListener {
2469

    
2470
        @Override
2471
        public void searchEvent(SearchEvent e) {
2472

    
2473
            RSyntaxTextArea textArea = getCurrentRSyntaxTextArea();
2474
            if (textArea == null) {
2475
                return;
2476
            }
2477

    
2478
            SearchEvent.Type type = e.getType();
2479
            SearchContext context = e.getSearchContext();
2480
            SearchResult result;
2481

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

    
2520
        @Override
2521
        public String getSelectedText() {
2522
            RSyntaxTextArea textArea = getCurrentRSyntaxTextArea();
2523
            if (textArea == null) {
2524
                return "";
2525
            }
2526
            return textArea.getSelectedText();
2527
        }
2528

    
2529
    }
2530
}