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

History | View | Annotate | Download (84.7 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 CloseAllAction extends AbstractAction {
464

    
465
        private static final long serialVersionUID = 3385142920283598457L;
466

    
467
        public CloseAllAction() {
468
            super(uimanager.getTranslation("Close_all_documents"));
469
            putValue(Action.SMALL_ICON, uimanager.getIcon("doc-closeall"));
470
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Close_all_documents"));
471
            putValue(ACTION_COMMAND_KEY, "CloseAll");
472
        }
473

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

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

    
485
    }
486

    
487
    private class CloseDocumentAction extends AbstractAction {
488

    
489
        private static final long serialVersionUID = 4152188500446249755L;
490

    
491
        public CloseDocumentAction() {
492
            super(uimanager.getTranslation("Close_document"));
493
            putValue(Action.SMALL_ICON, uimanager.getIcon("doc-close"));
494
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Close_current_tab"));
495
            putValue(ACTION_COMMAND_KEY, "DocumentClose");
496
        }
497

    
498
        @Override
499
        public void actionPerformed(ActionEvent e) {
500
            currentScriptClose();
501
        }
502

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

    
509
    }
510

    
511
    private class ShowConsoleAction extends AbstractAction {
512

    
513
        private static final long serialVersionUID = -7545333555439711068L;
514

    
515
        public ShowConsoleAction() {
516
            super(uimanager.getTranslation("Console"));
517
            putValue(Action.SMALL_ICON, uimanager.getIcon("show-console"));
518
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Show_console_panel"));
519
            putValue(ACTION_COMMAND_KEY, "ShowConsole");
520
        }
521

    
522
        @Override
523
        public void actionPerformed(ActionEvent e) {
524
            addConsolePanel();
525
        }
526
    }
527

    
528
    private class ShowProblemsAction extends AbstractAction {
529

    
530
        private static final long serialVersionUID = 5276964996914550830L;
531

    
532
        public ShowProblemsAction() {
533
            super(uimanager.getTranslation("Problems"));
534
            putValue(Action.SMALL_ICON, uimanager.getIcon("show-problems"));
535
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Show_problems_panel"));
536
            putValue(ACTION_COMMAND_KEY, "ShowProblems");
537
        }
538

    
539
        @Override
540
        public void actionPerformed(ActionEvent e) {
541
            addProblemsPanel();
542
        }
543
    }
544

    
545
    private class ShowProjectsAction extends AbstractAction {
546

    
547
        private static final long serialVersionUID = 5873598740133693862L;
548

    
549
        public ShowProjectsAction() {
550
            super(uimanager.getTranslation("Projects"));
551
            putValue(Action.SMALL_ICON, uimanager.getIcon("show-projects"));
552
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Show_projects_panel"));
553
            putValue(ACTION_COMMAND_KEY, "ShowProjects");
554
        }
555

    
556
        @Override
557
        public void actionPerformed(ActionEvent e) {
558
            addProjectsPanel();
559
        }
560
    }
561

    
562
    private class NewDocumentAction extends AbstractAction {
563

    
564
        private static final long serialVersionUID = 7889613706183211620L;
565

    
566
        public NewDocumentAction() {
567
            super(uimanager.getTranslation("New"));
568
            putValue(Action.SMALL_ICON, uimanager.getIcon("doc-add"));
569
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("New"));
570
            putValue(ACTION_COMMAND_KEY, "DocumentNew");
571
        }
572

    
573
        @Override
574
        public void actionPerformed(ActionEvent e) {
575
            try {
576
                scriptNew();
577
            } catch (Exception e1) {
578
                logger.warn("Can't create a new document", e1);
579
            }
580
        }
581

    
582
    }
583

    
584
    private class ProjectEditAction extends AbstractAction {
585

    
586
        private static final long serialVersionUID = -3393464285985649074L;
587

    
588
        public ProjectEditAction() {
589
            super(uimanager.getTranslation("Edit"));
590
            putValue(Action.SMALL_ICON, uimanager.getIcon("doc-edit"));
591
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Open_edition_mode"));
592
            putValue(ACTION_COMMAND_KEY, "DocumentEdit");
593
        }
594

    
595
        @Override
596
        public void actionPerformed(ActionEvent e) {
597
            try {
598
                ScriptingUnit selectedItem = getLauncherSelectedScript();
599
                if (selectedItem instanceof ScriptingBaseScript) {
600
                    scriptEdit((ScriptingBaseScript) selectedItem);
601
                }
602
            } catch (Exception e1) {
603
                logger.warn("Can't edit document", e1);
604
            }
605
        }
606
    }
607

    
608
    private class ProjectRefreshAction extends AbstractAction {
609

    
610
        private static final long serialVersionUID = 1944121660002532563L;
611

    
612
        public ProjectRefreshAction() {
613
            super(uimanager.getTranslation("Refresh"));
614
            putValue(Action.SMALL_ICON, uimanager.getIcon("refresh"));
615
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Refresh_directories"));
616
            putValue(ACTION_COMMAND_KEY, "ProjectsRefresh");
617
        }
618

    
619
        @Override
620
        public void actionPerformed(ActionEvent e) {
621
            refreshProjects();
622
        }
623

    
624
    }
625

    
626
    private class ProjectRenameAction extends AbstractAction {
627

    
628
        private static final long serialVersionUID = 7469858242486966790L;
629

    
630
        public ProjectRenameAction() {
631
            super(uimanager.getTranslation("Rename"));
632
            putValue(Action.SMALL_ICON, uimanager.getIcon("doc-rename"));
633
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Set_file_properties"));
634
            putValue(ACTION_COMMAND_KEY, "Rename");
635
        }
636

    
637
        @Override
638
        public void actionPerformed(ActionEvent e) {
639
            try {
640
                scriptRename(getLauncherSelectedScript());
641
            } catch (Exception e1) {
642
                logger.warn("Can't rename document", e1);
643
            }
644
        }
645
    }
646

    
647
    private class ProjectMoveAction extends AbstractAction {
648

    
649
        private static final long serialVersionUID = -8857101021126773295L;
650

    
651
        public ProjectMoveAction() {
652
            super(uimanager.getTranslation("Move"));
653
            putValue(Action.SMALL_ICON, uimanager.getIcon("doc-move"));
654
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Move_files"));
655
            putValue(ACTION_COMMAND_KEY, "Move");
656
        }
657

    
658
        @Override
659
        public void actionPerformed(ActionEvent e) {
660
            try {
661
                scriptMove(getLauncherSelectedScript());
662
            } catch (Exception e1) {
663
                logger.warn("Can't move document", e1);
664
            }
665
        }
666
    }
667

    
668
    private class ProjectDeleteAction extends AbstractAction {
669

    
670
        private static final long serialVersionUID = 9039455504757742743L;
671

    
672
        public ProjectDeleteAction() {
673
            super(uimanager.getTranslation("Delete"));
674
            putValue(Action.SMALL_ICON, uimanager.getIcon("doc-remove"));
675
            putValue(Action.SHORT_DESCRIPTION, uimanager.getTranslation("Delete_selected_script"));
676
            putValue(ACTION_COMMAND_KEY, "Delete");
677
        }
678

    
679
        @Override
680
        public void actionPerformed(ActionEvent e) {
681
            try {
682
                scriptDelete(getLauncherSelectedScript(), false);
683
            } catch (Exception e1) {
684
                logger.warn("Can't delete document", e1);
685
            }
686
        }
687
    }
688

    
689
    /**
690
     * Instanciacion de un JComposer con todos sus elementos y acciones
691
     *
692
     * @param uimanager
693
     */
694
    public DefaultJScriptingComposer(final ScriptingUIManager uimanager) {
695
        loader = this.getClass().getClassLoader();
696
        this.uimanager = uimanager;
697
        this.manager = uimanager.getManager();
698
        initComponents();
699
    }
700

    
701
    @Override
702
    public JComponent asJComponent() {
703
        return this;
704
    }
705

    
706
    @Override
707
    public WindowManager getWindowManager() {
708
        return ((DefaultScriptingUIManager) (this.uimanager)).getWindowManager();
709
    }
710

    
711
    @Override
712
    public void setWindowManager(WindowManager windowsManager) {
713
        ((DefaultScriptingUIManager) (this.uimanager)).setWindowManager(windowsManager);
714
    }
715

    
716
    private void initComponents() {
717

    
718
        this.addAncestorListener(new AncestorListener() {
719

    
720
            @Override
721
            public void ancestorAdded(AncestorEvent event) {
722
                ((DefaultScriptingUIManager) uimanager).setActiveComposer(DefaultJScriptingComposer.this);
723
            }
724

    
725
            @Override
726
            public void ancestorRemoved(AncestorEvent event) {
727
                ((DefaultScriptingUIManager) uimanager).setActiveComposer(null);
728
            }
729

    
730
            @Override
731
            public void ancestorMoved(AncestorEvent event) {
732
            }
733
        });
734
        SearchListener findReplaceSearchListener = new FindReplaceSearchListener();
735

    
736
        findDialog = new FindDialog((Dialog) null, findReplaceSearchListener);
737
        replaceDialog = new ReplaceDialog((Dialog) null, findReplaceSearchListener);
738
        gotoDialog = new GoToDialog((Dialog) null);
739

    
740
        SearchContext searchContext = findDialog.getSearchContext();
741
        replaceDialog.setSearchContext(searchContext);
742

    
743
        this.menuBar = new JMenuBar();
744
        this.toolBar = new JToolBar();
745

    
746
        this.menus = new LinkedHashMap<>();
747
        this.tools = new LinkedHashMap<>();
748

    
749
        String _File = this.uimanager.getTranslation("File");
750
        String _Edit = this.uimanager.getTranslation("Edit");
751
        String _Projects = this.uimanager.getTranslation("Projects");
752
        String _Tools = this.uimanager.getTranslation("Tools");
753
        String _Help = this.uimanager.getTranslation("Help");
754
        String _View = this.uimanager.getTranslation("Show");
755

    
756
        this.addMenu(_File, null);
757
        this.addMenu(_File, new NewDocumentAction());
758
        this.addMenuSeparator(_File);
759
        this.addMenu(_File, new CloseDocumentAction());
760
        this.addMenu(_File, new CloseAllAction());
761
        this.addMenuSeparator(_File);
762
        this.addMenu(_File, new RunAction());
763
        this.addMenuSeparator(_File);
764
        this.addMenu(_File, new SaveAction());
765
        this.addMenuSeparator(_File);
766
        this.addMenu(_File, new ExitAction());
767

    
768
        this.addMenu(_Edit, null);
769
        this.addMenu(_Edit, new CutAction());
770
        this.addMenu(_Edit, new CopyAction());
771
        this.addMenu(_Edit, new PasteAction());
772
        this.addMenuSeparator(_Edit);
773
        this.addMenu(_Edit, new SelectAllAction());
774
        this.addMenuSeparator(_Edit);
775
        this.addMenu(_Edit, new ShowFindDialogAction());
776
        this.addMenu(_Edit, new ShowReplaceDialogAction());
777
        this.addMenu(_Edit, new GoToLineAction());
778

    
779
        this.addMenu(_View, null);
780
        this.addMenu(_View, new ShowProjectsAction());
781
        this.addMenu(_View, new ShowProblemsAction());
782
        this.addMenu(_View, new ShowConsoleAction());
783

    
784
        this.addMenu(_Projects, null);
785
        this.addMenu(_Projects, new ProjectEditAction());
786
        this.addMenuSeparator(_Projects);
787
        this.addMenu(_Projects, new ProjectRefreshAction());
788
        this.addMenuSeparator(_Projects);
789
        this.addMenu(_Projects, new ProjectRenameAction());
790
        this.addMenu(_Projects, new ProjectMoveAction());
791

    
792
        this.addMenu(_Tools, null);
793
        this.addMenu(_Tools, new LauncherAction());
794
        this.addMenuSeparator(_Tools);
795
        this.addMenu(_Tools, new PackageScriptAction());
796

    
797
        this.addMenu(_Help, null);
798
        this.addMenu(_Help, new AboutAction());
799

    
800
        this.addTool(new NewDocumentAction());
801
        this.addTool(new SaveAction());
802
        this.addTool(new CutAction());
803
        this.addTool(new CopyAction());
804
        this.addTool(new PasteAction());
805
        this.addTool(new RunAction());
806

    
807
        JTabbedPaneClosable tabbedPanelLeft = new JTabbedPaneClosable(uimanager);
808
        JTabbedPaneClosable tabbedPanelBottom = new JTabbedPaneClosable(uimanager);
809
        JTabbedPaneClosable tabbedPanelCenter = new JTabbedPaneClosable(uimanager);
810

    
811
        tabbedPanelLeft.setTabPlacement(JTabbedPane.BOTTOM);
812
        tabbedPanelCenter.setPreferredSize(new Dimension(500, 300));
813
        tabbedPanelCenter.addChangeListener(new ChangeListener() {
814

    
815
            @Override
816
            public void stateChanged(ChangeEvent e) {
817
                updateMenusAndTools();
818
            }
819
        });
820

    
821
        this.dock = new DefaultDock(
822
                tabbedPanelLeft,
823
                tabbedPanelBottom,
824
                tabbedPanelCenter
825
        );
826
        this.dock.addCloseListener(new ActionListener() {
827

    
828
            @Override
829
            public void actionPerformed(ActionEvent e) {
830
                DockedPanel panel = (DockedPanel) e.getSource();
831
                scriptClose(panel);
832
            }
833
        });
834
        tabbedPanelBottom.setPreferredSize(new Dimension(450, 100));
835

    
836
        this.addProjectsPanel();
837
        this.addConsolePanel();
838
        this.addProblemsPanel();
839

    
840
        this.dock.select(DOCKED_CONSOLE);
841
        this.dock.select(DOCKED_PROJECTS);
842

    
843
        JSplitPane centerPanel = new JSplitPane(
844
                JSplitPane.VERTICAL_SPLIT,
845
                tabbedPanelCenter,
846
                tabbedPanelBottom
847
        );
848
        centerPanel.setOneTouchExpandable(true);
849

    
850
        mainPanel = new JSplitPane(
851
                JSplitPane.HORIZONTAL_SPLIT,
852
                tabbedPanelLeft,
853
                centerPanel
854
        );
855
        mainPanel.setOneTouchExpandable(true);
856

    
857
        statusBar = new DefaultStatusBar(uimanager);
858

    
859
        updateMenusAndTools();
860

    
861
        JPanel buttons = new JPanel();
862
        buttons.setLayout(new BorderLayout());
863
        buttons.add(BorderLayout.NORTH, this.menuBar);
864
        buttons.add(BorderLayout.SOUTH, this.toolBar);
865

    
866
        this.setLayout(new BorderLayout());
867
        this.add(BorderLayout.NORTH, buttons);
868
        this.add(BorderLayout.CENTER, mainPanel);
869
        this.add(BorderLayout.SOUTH, statusBar.asJComponent());
870
        this.setPreferredSize(new Dimension(800, 600));
871
    }
872

    
873
    public void addMenu(String text, Action action) {
874
        String name;
875
        if (action == null) {
876
            name = String.format("Menu%x", new Date().getTime());
877
        } else {
878
            name = (String) action.getValue(Action.ACTION_COMMAND_KEY);
879
        }
880
        this.menus.put(name, new ToolEntry(name, action, text));
881
    }
882

    
883
    public void addMenuSeparator(String text) {
884
        String name = String.format("Sep%x", new Date().getTime());
885
        this.menus.put(name, new ToolEntry(name, null, text + "/-"));
886
    }
887

    
888
    public void addTool(Action action) {
889
        String name = (String) action.getValue(Action.ACTION_COMMAND_KEY);
890
        this.tools.put(name, new ToolEntry(name, action));
891
    }
892

    
893
    public void updateMenusAndTools() {
894

    
895
        this.menuBar.removeAll();
896
        this.toolBar.removeAll();
897
        for (MenuEntry entry : this.uimanager.getComposerMenus()) {
898
            this.addMenu(entry.getText(), entry.getAction());
899
        }
900
        for (Action action : this.uimanager.getComposerTools()) {
901
            this.addTool(action);
902
        }
903

    
904
        MenuBarHelper menuBarHelper = new MenuBarHelper(menuBar);
905
        for (ToolEntry entry : menus.values()) {
906
            try {
907
                JMenuItem menu = menuBarHelper.add(entry.getText(), entry.getAction(), this);
908
                entry.setComponent(menu);
909
            } catch(Throwable th) {
910
                logger.warn("Can't add entry '"+entry.getName()+"' to the toolbar.", th);
911
            }
912
        }
913

    
914
        for (ToolEntry entry : tools.values()) {
915
            try {
916
                JButton button = new ButtonWithContext(entry.getAction());
917
                this.toolBar.add(button);
918
                entry.setComponent(button);
919
            } catch(Throwable th) {
920
                logger.warn("Can't add entry '"+entry.getName()+"' to the toolbar.", th);
921
            }
922
            
923
        }
924
        this.menuBar.repaint();
925
        this.toolBar.repaint();
926
    }
927

    
928
    public void addProblemsPanel() {
929
        DockedPanel panel = this.dock.get(DOCKED_PROBLEMS);
930
        if (panel != null) {
931
            panel.select();
932
            return;
933
        }
934
        final Problems problems = new DefaultProblems(this.uimanager);
935
        problems.addListSelectionListener(new ListSelectionListener() {
936

    
937
            @Override
938
            public void valueChanged(ListSelectionEvent e) {
939
                if (e.getValueIsAdjusting()) {
940
                    return;
941
                }
942
                Problem row = problems.getSelect();
943
                if (row != null) {
944
                    JEditor editor;
945
                    int lineno = row.getLineNumber();
946
                    if( row.getResource() == null ) {
947
                        editor = getCurrentEditor();
948
                    } else {
949
                        String id = row.getResource().getAbsolutePath();
950
                        DockedPanel panel = getDock().get(id);
951
                        if( panel == null ) {
952
                            ScriptingBaseScript script = manager.getScript(row.getResource());
953
                            scriptEdit(script);
954
                            panel = getDock().get(id);
955
                            if( panel == null ) {
956
                                logger.warn("Can't load script '"+id+"'.");
957
                                return;
958
                            }
959
                        } 
960
                        panel.select();
961
                        editor = (JEditor) panel.getComponent();
962
                    }
963
                    if ( editor instanceof JCodeEditor) {
964
                        ((JCodeEditor) editor).gotoline(lineno);
965
                    }
966
                }
967
            }
968
        });
969
        this.dock.add(
970
                DOCKED_PROBLEMS,
971
                this.uimanager.getTranslation("Problems"),
972
                problems,
973
                Dock.DOCK_BOTTOM
974
        );
975
        this.dock.select(DOCKED_PROBLEMS);
976
    }
977

    
978
    public void addConsolePanel() {
979
        DockedPanel panel = this.dock.get(DOCKED_CONSOLE);
980
        if (panel != null) {
981
            panel.select();
982
            return;
983
        }
984
        DefaultJScriptingConsole console = new DefaultJScriptingConsole(true);
985
        this.dock.add(
986
                DOCKED_CONSOLE,
987
                this.uimanager.getTranslation("Console"),
988
                console,
989
                Dock.DOCK_BOTTOM
990
        );
991
        this.dock.select(DOCKED_CONSOLE);
992
    }
993

    
994
    public void addProjectsPanel() {
995
        DockedPanel panel = this.dock.get(DOCKED_PROJECTS);
996
        if (panel != null) {
997
            panel.select();
998
            return;
999
        }
1000
        JScriptingLauncher launcher = uimanager.createLauncher();
1001
        launcher.addDefaultActionListener(new ActionListener() {
1002

    
1003
            @Override
1004
            public void actionPerformed(ActionEvent e) {
1005
                BrowserActionEvent e2 = (BrowserActionEvent) e;
1006
                switch (e.getID()) {
1007
                    case JScriptingBrowser.DEFAULT_ACTION:
1008
                        scriptEdit(e2.getScript());
1009
                        break;
1010
                    case JScriptingBrowser.DROPDOWN_ACTION:
1011
                    case JScriptingBrowser.SELECTION_ACTION:
1012
                        break;
1013
                }
1014
            }
1015
        });
1016
        launcher.asJComponent().setPreferredSize(new Dimension(200, 450));
1017

    
1018
        this.dock.add(
1019
                DOCKED_PROJECTS,
1020
                this.uimanager.getTranslation("Projects"),
1021
                launcher,
1022
                Dock.DOCK_LEFT
1023
        );
1024
        this.dock.select(DOCKED_PROJECTS);
1025
    }
1026

    
1027
    @Override
1028
    public Problems getProblems() {
1029
        DockedPanel panel = this.dock.get(DOCKED_PROBLEMS);
1030
        if (panel == null) {
1031
            return null;
1032
        }
1033
        return (Problems) panel.getComponent();
1034
    }
1035

    
1036
    @Override
1037
    public JScriptingLauncher getProjects() {
1038
        DockedPanel panel = this.dock.get(DOCKED_PROJECTS);
1039
        if (panel == null) {
1040
            return null;
1041
        }
1042
        return (JScriptingLauncher) panel.getComponent();
1043
    }
1044

    
1045
    @Override
1046
    public Dock getDock() {
1047
        return dock;
1048
    }
1049

    
1050
    @Override
1051
    public JScriptingConsole getConsole() {
1052
        DockedPanel panel = this.dock.get(DOCKED_CONSOLE);
1053
        if (panel == null) {
1054
            return null;
1055
        }
1056
        return (JScriptingConsole) panel.getComponent();
1057
    }
1058

    
1059
    @Override
1060
    public void addChangeEditorListener(ChangeListener listener) {
1061
        if (this.changeEditorListeners == null) {
1062
            this.changeEditorListeners = new HashSet<>();
1063
        }
1064
        this.changeEditorListeners.add(listener);
1065
    }
1066

    
1067
    public void fireChangeEditor(ChangeEvent e) {
1068
        if (this.changeEditorListeners == null) {
1069
            return;
1070
        }
1071
        for (ChangeListener listener : this.changeEditorListeners) {
1072
            try {
1073
                listener.stateChanged(e);
1074
            } catch (Throwable th) {
1075

    
1076
            }
1077
        }
1078
    }
1079

    
1080
    private void createScriptPackage() {
1081
        I18nManager i18nManager = ToolsLocator.getI18nManager();
1082
        SwingInstallerManager installerManager = SwingInstallerLocator.getSwingInstallerManager();
1083
        PackageBuildder packager = installerManager.createPackagerPanel(
1084
                ScriptingManager.INSTALLER_PROVIDER_NAME,
1085
                manager.getRootUserFolder(),
1086
                manager.getPackagesFolder()
1087
        );
1088
        PackageInfo packageInfo = packager.getPackageInfo();
1089
        packageInfo.setArchitecture(PackageManager.ARCH.ALL);
1090
        packageInfo.setJavaVM(PackageManager.JVM.J1_7);
1091
        packageInfo.setOperatingSystem(PackageManager.OS.ALL);
1092
        packageInfo.setOfficial(false);
1093
        packageInfo.setState(PackageManager.STATE.TESTING);
1094
        packageInfo.setType(ScriptingManager.INSTALLER_PROVIDER_NAME);
1095
        Version version = ToolsLocator.getPackageManager().createVersion();
1096
        version.parse("1.0.0");
1097
        packageInfo.setVersion(version);
1098
        this.uimanager.showWindow(
1099
                (JPanel) packager.asJComponent(),
1100
                i18nManager.getTranslation("_Scripting_packager")
1101
        );
1102
    }
1103

    
1104
//    private void setEditorSelection(String name, int line) {
1105
//        for (int i = 0; i < scriptEditors.getTabCount(); i++) {
1106
//
1107
//            if (((JEditor) scriptEditors.getComponent(i)).getScript().getId().equals(name)) {
1108
//                scriptEditors.setSelectedIndex(i);
1109
//
1110
//                JCodeEditor editor = ((JCodeEditor) scriptEditors.getComponent(i));
1111
//                editor.selectLine(line);
1112
//            }
1113
//        }xxxxxxxxxxxxxxxxxxxxxxxx
1114
//    }
1115
    public void addDefaultActionListener(ActionListener actionlistener) {
1116
        this.defaultActionlistener = actionlistener;
1117
    }
1118

    
1119
    /**
1120
     * Funci?n para obtener el elemento seleccionado del Launcher
1121
     *
1122
     * @return Selected ScriptingUnit on the tree
1123
     */
1124
    private ScriptingUnit getLauncherSelectedScript() {
1125
        JScriptingLauncher launcher = this.getProjects();
1126
        JScriptingBrowser browser = launcher.getSelectedBrowser();
1127
        ScriptingUnit unit = browser.getSelectedNode();
1128
        return unit;
1129
    }
1130

    
1131
    /**
1132
     * Lanza la ejecuci?n de un ScriptingBaseScript
1133
     *
1134
     * @param unit
1135
     */
1136
    private void scriptExecute(ScriptingUnit unit) {
1137
        if (unit instanceof ScriptingBaseScript) {
1138
            ((ScriptingBaseScript) unit).run();
1139
        }
1140
    }
1141

    
1142
    public void scriptEdit(ScriptingBaseScript unit) {
1143
        String id = unit.getScriptFile().getAbsolutePath();
1144
        DockedPanel x = this.dock.get(id);
1145
        if (x != null) {
1146
            x.select();
1147
            return;
1148
        }
1149
        final JEditor editor = this.uimanager.createEditor(unit);
1150
        if (editor == null) {
1151
            JOptionPane.showMessageDialog(null, this.uimanager.getTranslation("Error_opening_in_edition_mode"), this.uimanager.getTranslation("Error_opening_in_edition_mode_title"), JOptionPane.INFORMATION_MESSAGE);
1152
            return;
1153
        }
1154
        final DockedPanel panel = this.dock.add(id, unit.getName(), editor, Dock.DOCK_CENTER);
1155
        panel.select();
1156
        editor.addChangeListener(new PropertyChangeListener() {
1157

    
1158
            @Override
1159
            public void propertyChange(PropertyChangeEvent evt) {
1160
                panel.setModified(true);
1161
                fireChangeEditor(new ChangeEvent(editor));
1162
            }
1163
        });
1164
        if (editor instanceof JCodeEditor) {
1165
            ((JCodeEditor) editor).addUpdateCaretPositionActionListener(new ActionListener() {
1166

    
1167
                @Override
1168
                public void actionPerformed(ActionEvent e) {
1169
                    UpdateCaretPositionActionEvent event = (UpdateCaretPositionActionEvent) e;
1170
                    getStatusbar().setPosition(
1171
                            event.getLine(),
1172
                            event.getColumn()
1173
                    );
1174
                }
1175
            });
1176
        }
1177
        ScriptingScript script = editor.getScript();
1178
        if (script != null) {
1179
            script.addObserver(this);
1180
        }
1181
    }
1182

    
1183
    /**
1184
     * Ventana para creaci?n de nuevos ScriptingBaseScripts
1185
     *
1186
     * @throws Exception
1187
     *
1188
     */
1189
    public void scriptNew() throws Exception {
1190
        JNewScriptModel model = new JNewScriptModel(manager);
1191
        JDialogContent dialog = new JDialogContent(
1192
                uimanager,
1193
                "document-new",
1194
                this.uimanager.getTranslation("New_Script"),
1195
                this.uimanager.getTranslation("New_Script_Description"),
1196
                new JNewScriptPanel(uimanager, model)
1197
        );
1198
        dialog.showDialog();
1199
        if (model.getAction() == JNewScriptModel.ACTION_ACCEPT) {
1200
            model.validate();
1201
            ScriptingUnit unit = this.manager.createUnit(
1202
                    model.getType(),
1203
                    manager.getFolder(new File(model.getPath())),
1204
                    model.getName(),
1205
                    model.getLanguage()
1206
            );
1207
            if (unit instanceof ScriptingBaseScript) {
1208
                this.scriptEdit((ScriptingBaseScript) unit);
1209
            }
1210

    
1211
            this.refreshProjects();
1212
        }
1213
    }
1214

    
1215
    public void scriptClose(DockedPanel panel) {
1216
        if (!panel.isModified()) {
1217
            panel.remove();
1218
            return;
1219
        }
1220
        panel.select();
1221
        I18nManager i18nManager = ToolsLocator.getI18nManager();
1222
        int respuesta = JOptionPane.showConfirmDialog(
1223
                this,
1224
                i18nManager.getTranslation("_The_script_XscriptnameX_is_modified",
1225
                        new String[]{panel.getTitle()})
1226
                + "\n\n"
1227
                + i18nManager.getTranslation("_Do_you_want_to_save_changes_XquestionX"),
1228
                i18nManager.getTranslation("_Save_changes_XquestionX"),
1229
                JOptionPane.YES_NO_CANCEL_OPTION
1230
        );
1231
        switch (respuesta) {
1232
            case JOptionPane.YES_OPTION:
1233
                currentScriptSave();
1234
                panel.remove();
1235
                break;
1236
            case JOptionPane.NO_OPTION:
1237
                panel.remove();
1238
                break;
1239
            default:
1240
            case JOptionPane.CANCEL_OPTION:
1241
                break;
1242
        }
1243
    }
1244

    
1245
    public void scriptMove(final ScriptingUnit theUnit) throws Exception {
1246
        if (theUnit.getParent() == null) {
1247
            JOptionPane.showMessageDialog(null, "Please, select first the file to move on the tree directory", "Error", JOptionPane.ERROR_MESSAGE);
1248
        } else {
1249
            JMoveScriptModel model = new JMoveScriptModel(manager, theUnit);
1250
            JDialogContent dialog = new JDialogContent(
1251
                    uimanager,
1252
                    "format-indent-more",
1253
                    this.uimanager.getTranslation("Move") + " '" + theUnit.getName() + "' " + this.uimanager.getTranslation("script_filesystem"),
1254
                    this.uimanager.getTranslation("move_desc"),
1255
                    new JMoveScriptPanel(uimanager, model)
1256
            );
1257
            dialog.showDialog();
1258
            if (model.getAction() == JMoveScriptModel.ACTION_ACCEPT) {
1259
                model.validate();
1260
                ScriptingFolder folderDest = manager.getFolder(model.getMoveTo());
1261
                if (model.getUnit().move(folderDest)) {
1262
                    JOptionPane.showMessageDialog(null,
1263
                            this.uimanager.getTranslation("Moving_succesfully"),
1264
                            this.uimanager.getTranslation("Success"), JOptionPane.INFORMATION_MESSAGE);
1265
                    this.refreshProjects();
1266
                } else {
1267
                    JOptionPane.showMessageDialog(null,
1268
                            this.uimanager.getTranslation("Error_moving"),
1269
                            this.uimanager.getTranslation("Error"), JOptionPane.ERROR_MESSAGE);
1270
                }
1271
            }
1272
        }
1273

    
1274
    }
1275

    
1276
    public void scriptRename(ScriptingUnit theUnit) throws Exception {
1277
        if (theUnit.getParent() == null) {
1278
            JOptionPane.showMessageDialog(null,
1279
                    this.uimanager.getTranslation("Select_first"),
1280
                    this.uimanager.getTranslation("Error"), JOptionPane.ERROR_MESSAGE);
1281
        } else {
1282
            JRenameModel model = new JRenameModel(manager, theUnit);
1283
            JDialogContent dialog = new JDialogContent(
1284
                    uimanager,
1285
                    "preferences-system",
1286
                    this.uimanager.getTranslation("Rename") + " '" + theUnit.getName() + "' " + this.uimanager.getTranslation("script_filesystem"),
1287
                    this.uimanager.getTranslation("rename_desc"),
1288
                    new JRenamePanel(uimanager, model)
1289
            );
1290
            dialog.showDialog();
1291
            if (model.getAction() == JRenameModel.ACTION_ACCEPT) {
1292
                model.validate();
1293
                ScriptingUnit unit = model.getUnit();
1294
                if (!model.getNewName().equals(unit.getId())) {
1295
                    if (unit.rename(model.getNewName())) {
1296
                        JOptionPane.showMessageDialog(null,
1297
                                this.uimanager.getTranslation("Rename_succesfully"),
1298
                                this.uimanager.getTranslation("Success"), JOptionPane.INFORMATION_MESSAGE);
1299
                        this.refreshProjects();
1300
                    } else {
1301
                        JOptionPane.showMessageDialog(null,
1302
                                this.uimanager.getTranslation(this.uimanager.getTranslation("Error_renaming")),
1303
                                this.uimanager.getTranslation("Error"), JOptionPane.ERROR_MESSAGE);
1304
                    }
1305
                    if (unit instanceof ScriptingScript) {
1306
                        ((ScriptingScript) unit).save();
1307
                    }
1308
                }
1309
            }
1310
        }
1311
    }
1312

    
1313
    @Override
1314
    public JPanel getAboutUsDialog() {
1315
        return new JDialogContent(uimanager,
1316
                "system-users",
1317
                this.uimanager.getTranslation("About_us"),
1318
                this.uimanager.getTranslation("About_us_title"),
1319
                new JDefaultDialog(uimanager, this, uimanager.getAboutManager().getAboutPanel()));
1320
    }
1321

    
1322
    public void scriptDelete(final ScriptingUnit unit, boolean isRecursive) {
1323
        int n = 0;
1324
        if (!isRecursive) {
1325
            n = JOptionPane.showConfirmDialog(
1326
                    this.getRootPane(),
1327
                    this.uimanager.getTranslation("Delete_all_message"),
1328
                    this.uimanager.getTranslation("Delete_all_title"),
1329
                    JOptionPane.YES_NO_OPTION);
1330
        }
1331
        if (n == 0) {
1332
            //Si es un folder borramos recursivamente sus subdirectorios
1333
            if (unit instanceof ScriptingFolder) {
1334
                List<ScriptingUnit> subunits
1335
                        = ((ScriptingFolder) unit).getUnits();
1336
                Iterator<ScriptingUnit> it = subunits.iterator();
1337
                while (it.hasNext()) {
1338
                    ScriptingUnit subunit = it.next();
1339
                    scriptDelete(subunit, true);
1340
                }
1341
            }
1342
            // Por ?ltimo borramos el nodo seleccionado
1343
            unit.getParent().remove(unit);
1344
            this.refreshProjects();
1345

    
1346
        }
1347
    }
1348

    
1349
    /**
1350
     * Funci?n que cierra la pesta?a de edici?n actual
1351
     *
1352
     */
1353
    public void currentScriptClose() {
1354
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1355
        if (panel == null) {
1356
            return;
1357
        }
1358
        scriptClose(panel);
1359
    }
1360

    
1361
    /**
1362
     * Close all editor tabs of the composer
1363
     */
1364
    public void closeAllScripts() {
1365
        List<DockedPanel> modifiedPanels = new ArrayList<>();
1366

    
1367
        for (DockedPanel panel : this.dock) {
1368
            if (Dock.DOCK_CENTER.equals(panel.getAlign())) {
1369
                if (panel.isModified()) {
1370
                    modifiedPanels.add(panel);
1371
                }
1372
            }
1373
        }
1374
        if (modifiedPanels.isEmpty()) {
1375
            return;
1376
        }
1377
        int action = JOptionPane.showConfirmDialog(
1378
                this,
1379
                this.uimanager.getTranslation("projects_modified"),
1380
                this.uimanager.getTranslation("projects_modified_title"),
1381
                JOptionPane.YES_NO_CANCEL_OPTION
1382
        );
1383
        switch (action) {
1384
            case JOptionPane.CANCEL_OPTION:
1385
                return;
1386
            case JOptionPane.YES_OPTION:
1387
                for (DockedPanel panel : modifiedPanels) {
1388
                    JEditor editor = (JEditor) panel.getComponent();
1389
                    if (editor.getScript() != null) {
1390
                        editor.getScript().setSaved(true);
1391
                    }
1392
                    editor.save();
1393
                    panel.remove();
1394
                }
1395
                break;
1396
            case JOptionPane.NO_OPTION:
1397
                for (DockedPanel panel : modifiedPanels) {
1398
                    JEditor editor = (JEditor) panel.getComponent();
1399
                    if (editor.getScript() != null) {
1400
                        editor.getScript().setSaved(true);
1401
                    }
1402
                    panel.remove();
1403
                }
1404
        }
1405

    
1406
    }
1407

    
1408
    /**
1409
     * Funci?n que ejecuta el ScriptingBaseScript de la pesta?a actual
1410
     *
1411
     */
1412
    public void currentScriptExecute() {
1413
        ScriptingScript script = this.getCurrentScript();
1414
        if (script != null) {
1415
            Problems problems = this.getProblems();
1416
            if (problems != null) {
1417
                problems.removeAll();
1418
            }
1419
            JScriptingConsole console = this.getConsole();
1420
            if (console != null) {
1421
                console.clear();
1422
            }
1423
            script.addObserver(this);
1424
            try {
1425
                script.compile();
1426
                script.runAsTask(null);
1427
            } catch (Throwable e) {
1428
                logger.info("Can't execute script", e);
1429
            }
1430
        }
1431
    }
1432

    
1433
    /**
1434
     * Funciones de 'cortar', 'copiar', 'pegar' y 'seleccionar todo' para los
1435
     * JEditors
1436
     *
1437
     */
1438
    public void currentScriptCopy() {
1439
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1440
        if (panel.getComponent().asJComponent() instanceof JCodeEditor) {
1441
            JCodeEditor editor = (JCodeEditor) panel.getComponent().asJComponent();
1442
            editor.getJTextComponent().copy();
1443
        }
1444
    }
1445

    
1446
    public void currentScriptCut() {
1447
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1448
        if (panel.getComponent().asJComponent() instanceof JCodeEditor) {
1449
            JCodeEditor editor = (JCodeEditor) panel.getComponent().asJComponent();
1450
            editor.getJTextComponent().cut();
1451
            panel.setModified(true);
1452
        }
1453
    }
1454

    
1455
    public void currentScriptPaste() {
1456
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1457
        if (panel.getComponent().asJComponent() instanceof JCodeEditor) {
1458
            JCodeEditor editor = (JCodeEditor) panel.getComponent().asJComponent();
1459
            editor.getJTextComponent().paste();
1460
            panel.setModified(true);
1461
        }
1462
    }
1463

    
1464
    public void currentScriptSelectAll() {
1465
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1466
        if (panel.getComponent().asJComponent() instanceof JCodeEditor) {
1467
            JCodeEditor editor = (JCodeEditor) panel.getComponent().asJComponent();
1468
            editor.getJTextComponent().selectAll();
1469
        }
1470
    }
1471

    
1472
    /**
1473
     * Funci?n para el guardado del ScriptingBaseScript de la pesta?a actual
1474
     *
1475
     */
1476
    public void currentScriptSave() {
1477
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1478
        if (panel.getComponent().asJComponent() instanceof JEditor) {
1479
            JEditor editor = (JEditor) panel.getComponent().asJComponent();
1480
            editor.save();
1481
            panel.setModified(false);
1482
        }
1483
    }
1484

    
1485
    @Override
1486
    public JEditor getCurrentEditor() {
1487
        DockedPanel panel = this.dock.getSelected(Dock.DOCK_CENTER);
1488
        if (panel == null) {
1489
            return null;
1490
        }
1491
        if (panel.getComponent().asJComponent() instanceof JEditor) {
1492
            return (JEditor) panel.getComponent().asJComponent();
1493
        }
1494
        return null;
1495
    }
1496

    
1497
    @Override
1498
    public ScriptingScript getCurrentScript() {
1499
        JEditor editor = this.getCurrentEditor();
1500
        if (editor == null) {
1501
            return null;
1502
        }
1503
        return editor.getScript();
1504
    }
1505

    
1506
    private RSyntaxTextArea getCurrentRSyntaxTextArea() {
1507
        JEditor editor = getCurrentEditor();
1508
        if (editor instanceof JCodeEditor) {
1509
            JTextComponent textComponent = ((JCodeEditor) editor).getJTextComponent();
1510
            if (textComponent instanceof RSyntaxTextArea) {
1511
                return (RSyntaxTextArea) textComponent;
1512
            }
1513
        }
1514
        return null;
1515
    }
1516

    
1517
    @Override
1518
    public void refreshProjects() {
1519
        try {
1520
            this.getProjects().refresh();
1521
        } catch (Exception ex) {
1522
            // Ignore
1523
        }
1524
    }
1525

    
1526
    @Override
1527
    public StatusBar getStatusbar() {
1528
        return this.statusBar;
1529
    }
1530

    
1531
    /**
1532
     *
1533
     * @param e
1534
     */
1535
    @Override
1536
    public void actionPerformed(ActionEvent e) {
1537

    
1538
        if (e instanceof UpdateCaretPositionActionEvent) {
1539
            UpdateCaretPositionActionEvent e2 = (UpdateCaretPositionActionEvent) e;
1540

    
1541
            if (e2.hasLineAndColumn()) {
1542
                this.getStatusbar().setPosition(e2.getLine(), e2.getColumn());
1543
            } else {
1544
                this.getStatusbar().setPosition(0, 0);
1545
            }
1546
        }
1547
    }
1548

    
1549
    @Override
1550
    public void update(final Observable observable, final Object notification) {
1551
        if (!SwingUtilities.isEventDispatchThread()) {
1552
            SwingUtilities.invokeLater(new Runnable() {
1553
                @Override
1554
                public void run() {
1555
                    update(observable, notification);
1556
                }
1557
            });
1558
            return;
1559
        }
1560
        if (notification instanceof ScriptingNotification) {
1561
            ScriptingNotification e = (ScriptingNotification) notification;
1562

    
1563
            if (e.getException() instanceof CompileErrorException) {
1564
                CompileErrorException ce = (CompileErrorException) e.getException();
1565
                Problems problems = this.getProblems();
1566
                if (problems != null) {
1567
                    problems.add("Error", ce);
1568
                    this.dock.select(DOCKED_PROBLEMS);
1569
                }
1570

    
1571
            } else if (e.getException() instanceof ExecuteErrorException) {
1572
                ExecuteErrorException ee = (ExecuteErrorException) e.getException();
1573
                Problems problems = this.getProblems();
1574
                if (problems != null) {
1575
                    problems.add("Error",ee);
1576
                    this.dock.select(DOCKED_PROBLEMS);
1577
                }
1578
                JScriptingConsole console = this.getConsole();
1579
                if (console != null) {
1580
                    console.append(ee.getMessage(), Color.RED.darker());
1581
                    ee.printStackTrace(console.getStderr());
1582
                }
1583

    
1584
            } else {
1585
                Exception ex = e.getException();
1586
                Problems problems = this.getProblems();
1587
                if (problems != null) {
1588
                    problems.add("Error",ex); 
1589
                    this.dock.select(DOCKED_PROBLEMS);
1590
                }
1591
                JScriptingConsole console = this.getConsole();
1592
                if (console != null) {
1593
                    console.append(ex.getMessage(), Color.RED.darker());
1594
                    ex.printStackTrace(console.getStderr());
1595
                }
1596
            }
1597
        }
1598
    }
1599

    
1600
    public void closeWindow() {
1601
        this.setVisible(false);
1602
    }
1603

    
1604
    private static class DefaultStatusBar extends JPanel implements StatusBar {
1605

    
1606
        private static final long serialVersionUID = -6135634992327170084L;
1607

    
1608
        private JLabel message;
1609
        private JLabel position;
1610
        private final ScriptingUIManager uimanager;
1611

    
1612
        public DefaultStatusBar(ScriptingUIManager uimanager) {
1613
            this.uimanager = uimanager;
1614
            this.initComponents();
1615
        }
1616

    
1617
        private void initComponents() {
1618
            this.message = new JLabel(this.uimanager.getTranslation("Welcome_message"));
1619
            this.position = new JLabel("Line 0:0");
1620

    
1621
            this.setLayout(new BorderLayout());
1622

    
1623
            this.add(this.message, BorderLayout.WEST);
1624
            this.add(this.position, BorderLayout.EAST);
1625
        }
1626

    
1627
        @Override
1628
        public void clear() {
1629
            this.message.setText("");
1630
        }
1631

    
1632
        @Override
1633
        public void message(String message) {
1634
            this.message.setText(message);
1635
        }
1636

    
1637
        @Override
1638
        public void setPosition(int line) {
1639
            this.setPosition(line, -1);
1640
        }
1641

    
1642
        @Override
1643
        public void setPosition(int line, int column) {
1644
            if (line < 0) {
1645
                this.position.setText("");
1646
                return;
1647
            }
1648
            if (column < 0) {
1649
                this.position.setText(this.uimanager.getTranslation("Line") + " " + line + ":0");
1650
            } else {
1651
                this.position.setText(this.uimanager.getTranslation("Line") + " " + line + ":" + column);
1652
            }
1653
        }
1654

    
1655
        @Override
1656
        public JComponent asJComponent() {
1657
            return this;
1658
        }
1659
    }
1660

    
1661
    public static class JTabbedPaneClosable extends JTabbedPane {
1662

    
1663
        private static final long serialVersionUID = -3995298424891579555L;
1664

    
1665
        private final ActionListenerSupport closeTabListeners;
1666
        private ScriptingUIManager uimanager;
1667

    
1668
        private class TabTitleComponent extends JPanel {
1669

    
1670
            private static final long serialVersionUID = -1061417669527944341L;
1671
            private final JLabel label;
1672
            private final JButton button;
1673
            private boolean changed = false;
1674
            private final Font fontNormal;
1675
            private final Font fontBold;
1676

    
1677
            public TabTitleComponent(String title, final ActionListener onclose) {
1678
                this.setOpaque(true);
1679
                this.label = new JLabel(title + " ");
1680
                this.label.setOpaque(true);
1681
                this.label.setBackground(UIManager.getColor("TabbedPane.tabAreaBackground"));
1682
                this.label.setVerticalTextPosition(SwingConstants.CENTER);
1683
                this.fontNormal = this.label.getFont();
1684
                this.fontBold = new Font(this.fontNormal.getFontName(), Font.BOLD, this.fontNormal.getSize());
1685

    
1686
                this.button = new JButton();
1687
                this.button.setText("");
1688
                this.button.setToolTipText(uimanager.getTranslation("Close_tab"));
1689
                this.button.setBackground(UIManager.getColor("TabbedPane.tabAreaBackground"));
1690
                this.button.setBorder(BorderFactory.createEmptyBorder());
1691
                this.button.setBorderPainted(false);
1692
                this.button.setFocusPainted(false);
1693
                this.button.setContentAreaFilled(false);
1694
                this.button.setCursor(new Cursor(Cursor.HAND_CURSOR));
1695
                this.button.setRolloverEnabled(true);
1696
                this.button.setIcon(uimanager.getIcon("tabclose-inactive"));
1697
                this.button.setRolloverIcon(uimanager.getIcon("tabclose-active"));
1698
                this.button.addActionListener(new ActionListener() {
1699
                    @Override
1700
                    public void actionPerformed(ActionEvent ae) {
1701
                        ae.setSource(TabTitleComponent.this);
1702
                        onclose.actionPerformed(ae);
1703
                    }
1704
                });
1705
                this.setLayout(new BorderLayout());
1706
                this.add(this.label, BorderLayout.CENTER);
1707
                this.add(this.button, BorderLayout.EAST);
1708
            }
1709

    
1710
            public void setTitle(String title) {
1711
                this.label.setText(title);
1712
            }
1713

    
1714
            public String getTitle() {
1715
                return this.label.getText();
1716
            }
1717

    
1718
            public void setChanged(boolean changed) {
1719
                if (changed) {
1720
                    this.label.setFont(this.fontBold);
1721
                } else {
1722
                    this.label.setFont(this.fontNormal);
1723
                }
1724
                this.changed = changed;
1725
            }
1726

    
1727
            public boolean isChanged() {
1728
                return this.changed;
1729
            }
1730
        }
1731

    
1732
        public JTabbedPaneClosable(ScriptingUIManager uimanager) {
1733
            super();
1734
            this.uimanager = uimanager;
1735
            this.closeTabListeners = ToolsSwingLocator.getToolsSwingManager().createActionListenerSupport();
1736
        }
1737

    
1738
        @Override
1739
        public String getTitleAt(int index) {
1740
            TabTitleComponent title = (TabTitleComponent) this.getTabComponentAt(index);
1741
            if (title == null) {
1742
                return null;
1743
            }
1744
            return title.getTitle();
1745
        }
1746

    
1747
        @Override
1748
        public void setTitleAt(int index, String title) {
1749
            TabTitleComponent titleComponent = (TabTitleComponent) this.getTabComponentAt(index);
1750
            titleComponent.setTitle(title);
1751
        }
1752

    
1753
        @Override
1754
        public void addTab(String title, java.awt.Component component) {
1755
            super.addTab(null, component);
1756
            int index = getTabCount() - 1;
1757
            TabTitleComponent tabcomponent = new TabTitleComponent(title, new ActionListener() {
1758

    
1759
                @Override
1760
                public void actionPerformed(ActionEvent ae) {
1761
                    TabTitleComponent tabTitleComponent = (TabTitleComponent) ae.getSource();
1762
                    int index = indexOfTabComponent(tabTitleComponent);
1763
                    setSelectedIndex(index);
1764
                    ae.setSource(JTabbedPaneClosable.this);
1765
                    closeTabListeners.fireActionEvent(ae);
1766
                }
1767
            });
1768
            super.setTabComponentAt(index, tabcomponent);
1769
        }
1770

    
1771
        public void addCloseTabListener(ActionListener remove) {
1772
            this.closeTabListeners.addActionListener(remove);
1773
        }
1774

    
1775
        public void removeCloseTabListener(ActionListener remove) {
1776
            this.closeTabListeners.removeActionListener(remove);
1777
        }
1778

    
1779
        public ActionListener[] getCloseTabListeners() {
1780
            return this.closeTabListeners.getActionListeners();
1781
        }
1782

    
1783
        public boolean isTabModified(int index) {
1784
            TabTitleComponent comp = (TabTitleComponent) this.getTabComponentAt(index);
1785
            if (comp == null) {
1786
                return false;
1787
            }
1788
            return comp.isChanged();
1789
        }
1790

    
1791
        public void setTabModified(int index, boolean changed) {
1792
            TabTitleComponent comp = (TabTitleComponent) this.getTabComponentAt(index);
1793
            if (comp != null) {
1794
                comp.setChanged(changed);
1795
            }
1796
        }
1797
    }
1798

    
1799
    public static class DefaultProblems extends JPanel implements Problems {
1800

    
1801
        private static final long serialVersionUID = 7728033081188167969L;
1802

    
1803
        private static final int COLUMN_TYPE = 0;
1804
        private static final int COLUMN_MESSAGE = 1;
1805
        private static final int COLUMN_RESOURCE = 2;
1806
        private static final int COLUMN_LOCATION = 3;
1807
        private static final int NUM_COLUMNS = 4;
1808

    
1809
        private JTable table;
1810
        private ProblemsTableMode tableModel;
1811
        private final ScriptingUIManager uimanager;
1812
        private Set<ListSelectionListener> selectionListeners; 
1813

    
1814
        public static class ProblemsTableMode extends DefaultTableModel implements TableModel {
1815
            private static final long serialVersionUID = -3294067602561419422L;
1816

    
1817
            public static class DefaultProblem implements Problem {
1818

    
1819
                String[] row;
1820
                private File resource;
1821

    
1822
                public DefaultProblem() {
1823
                    this.row = new String[NUM_COLUMNS];
1824
                }
1825

    
1826
                public DefaultProblem(String[] row) {
1827
                    this.row = row;
1828
                }
1829

    
1830
                public DefaultProblem(String type, String message, String resourceName, String location, File resource) {
1831
                    String[] row = new String[NUM_COLUMNS];
1832
                    row[COLUMN_TYPE] = type;
1833
                    row[COLUMN_MESSAGE] = message;
1834
                    row[COLUMN_RESOURCE] = resourceName;
1835
                    row[COLUMN_LOCATION] = location;
1836
                    this.resource = resource;
1837
                    this.row = row;
1838
                }
1839

    
1840
                public String get(int index) {
1841
                    return row[index];
1842
                }
1843

    
1844
                public String getValue(int index) {
1845
                    return row[index];
1846
                }
1847

    
1848
                public void setValue(int index, String value) {
1849
                    row[index] = value;
1850
                }
1851

    
1852
                @Override
1853
                public String getType() {
1854
                    return this.row[COLUMN_TYPE];
1855
                }
1856

    
1857
                @Override
1858
                public String getMessage() {
1859
                    return this.row[COLUMN_MESSAGE];
1860
                }
1861

    
1862
                @Override
1863
                public String getResourceName() {
1864
                    return this.row[COLUMN_RESOURCE];
1865
                }
1866

    
1867
                @Override
1868
                public File getResource() {
1869
                    return this.resource;
1870
                }
1871

    
1872
                @Override
1873
                public int getLineNumber() {
1874
                    try {
1875
                        String[] lineAndColumn = this.row[COLUMN_LOCATION].split(":");
1876
                        if (lineAndColumn.length > 0) {
1877
                            int lineno = Integer.parseInt(lineAndColumn[0].trim());
1878
                            return lineno;
1879
                        }
1880
                    } catch (Exception e) {
1881
                        // Do nothing
1882
                    }
1883
                    return -1;
1884
                }
1885

    
1886
            }
1887
            private final ScriptingUIManager uimanager;
1888
            private List<DefaultProblem> data;
1889
            private String[] columnNames;
1890

    
1891
            public ProblemsTableMode(ScriptingUIManager uimanager) {
1892
                this.uimanager = uimanager;
1893
                this.columnNames = new String[]{
1894
                    this.uimanager.getTranslation("Category"),
1895
                    this.uimanager.getTranslation("Description"),
1896
                    this.uimanager.getTranslation("Resource"),
1897
                    this.uimanager.getTranslation("Location")
1898
                };
1899

    
1900
            }
1901
            
1902
            private List<DefaultProblem> getData() {
1903
                if( this.data == null ) {
1904
                    this.data = new ArrayList<>();
1905
                }
1906
                return this.data;
1907
            }
1908

    
1909
            public void add(DefaultProblem row) {
1910
                this.getData().add(row);
1911
                this.fireTableDataChanged();
1912
            }
1913

    
1914
            private void add(String type, String message, String resourceName, String location, File resource) {
1915
                DefaultProblem problem = new DefaultProblem(type, message, resourceName, location, resource);
1916
                this.add(problem);
1917
            }
1918

    
1919
            @Override
1920
            public int getRowCount() {
1921
                return this.getData().size();
1922
            }
1923

    
1924
            @Override
1925
            public int getColumnCount() {
1926
                return NUM_COLUMNS;
1927
            }
1928

    
1929
            @Override
1930
            public String getColumnName(int columnIndex) {
1931
                return columnNames[columnIndex];
1932
            }
1933

    
1934
            @Override
1935
            public Class<?> getColumnClass(int columnIndex) {
1936
                return String.class;
1937
            }
1938

    
1939
            @Override
1940
            public boolean isCellEditable(int rowIndex, int columnIndex) {
1941
                return false;
1942
            }
1943

    
1944
            @Override
1945
            public Object getValueAt(int rowIndex, int columnIndex) {
1946
                return this.getData().get(rowIndex).get(columnIndex);
1947
            }
1948
            
1949
            public Problem getProblem(int rowIndex) {
1950
                return this.getData().get(rowIndex);
1951
            }
1952

    
1953
            @Override
1954
            public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
1955
                this.getData().get(rowIndex).setValue(columnIndex, (String) aValue);
1956
            }
1957

    
1958
            public void removeAll() {
1959
                this.getData().clear();
1960
            }
1961
        }
1962

    
1963
        public DefaultProblems(ScriptingUIManager uimanager) {
1964
            this.uimanager = uimanager;
1965
            this.initComponents();
1966
        }
1967

    
1968
        private void initComponents() {
1969
            this.selectionListeners = new HashSet<>();
1970
            tableModel = new ProblemsTableMode(this.uimanager);
1971
            table = new JTable(tableModel);
1972
            table.getColumnModel().getColumn(1).setPreferredWidth(300);
1973

    
1974
            table.setRowSelectionAllowed(true);
1975
            table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
1976

    
1977
            JScrollPane scrollProblems = new JScrollPane(table);
1978
            scrollProblems.setAutoscrolls(true);
1979

    
1980
            this.setLayout(new BorderLayout());
1981
            this.add(scrollProblems, BorderLayout.CENTER);
1982
            
1983
            // Si ya hay seleccionada una linea y vuelvo a clickar sobre ella 
1984
            // para que me lleve a la linea del editor que toque, con el
1985
            // addSelectionListener no me vuelve a lanzar el evento, asi que
1986
            // me apalanco en el mouseClicked tambien.
1987
            table.addMouseListener(new MouseAdapter(){
1988
                @Override
1989
                public void mouseClicked(MouseEvent evnt) {
1990
                    if (evnt.getClickCount() == 1) {
1991
                        fireSelectionListeners();
1992
                     }
1993
                 }
1994
            });
1995
        }
1996

    
1997
        @Override
1998
        public void addListSelectionListener(ListSelectionListener listener) {
1999
            this.table.getSelectionModel().addListSelectionListener(listener);
2000
            this.selectionListeners.add(listener);
2001
        }
2002

    
2003
        private void fireSelectionListeners() {
2004
            int row = this.table.getSelectedRow();
2005
            for( ListSelectionListener listener : this.selectionListeners ) {
2006
                try {
2007
                    listener.valueChanged(new ListSelectionEvent(this, row, row, false));
2008
                } catch(Exception th) {
2009
                    
2010
                }
2011
            }
2012
        }
2013
        
2014
        @Override
2015
        public void removeAll() {
2016
            this.tableModel.removeAll();
2017
            this.table.updateUI();
2018
        }
2019

    
2020
        @Override
2021
        public void add(String type, String message, String resource, String location) {
2022
            this.tableModel.add(type, message, resource, location, null);
2023
        }
2024

    
2025
        @Override
2026
        public void add(String type, String message, String resource, int line, int column) {
2027
            this.add(type, message, resource, line + ":" + column);
2028
        }
2029
        
2030
        public void add(String type, String message, String resourceName, int line, int column, File resource) {
2031
            this.tableModel.add(type, message, resourceName, line + ":" + column, resource);
2032
        }
2033
                
2034
        @Override
2035
        public void add(String type, Exception e) {
2036
            if (e  instanceof ScriptingErrorException) {
2037
                ScriptingErrorException se = (ScriptingErrorException) e;
2038
                    this.add(
2039
                        "Error",
2040
                        se.getMessage(),
2041
                        se.getScriptName(),
2042
                        se.getLineNumber(),
2043
                        se.getColumnNumber(),
2044
                        se.getScriptFile()
2045
                    );
2046

    
2047
            } else {
2048
                    this.add("Error", 
2049
                        "Error",
2050
                        e.getMessage(),
2051
                        null
2052
                    );
2053
            }            
2054
        }
2055

    
2056
        @Override
2057
        public Problem getSelect() {
2058
            int row = this.table.getSelectedRow();
2059
            if (row < 0) {
2060
                return null;
2061
            }
2062
            return this.get(row);
2063
        }
2064

    
2065
        @Override
2066
        public int getCount() {
2067
            return this.tableModel.getRowCount();
2068
        }
2069

    
2070
        @Override
2071
        public Problem get(int row) {
2072
            return this.tableModel.getProblem(row);
2073
        }
2074

    
2075
        @Override
2076
        public JComponent asJComponent() {
2077
            return this;
2078
        }
2079

    
2080
    }
2081

    
2082
    public static class DefaultDock extends JPanel implements Dock {
2083

    
2084
        private static final long serialVersionUID = 4899734277977456625L;
2085

    
2086
        public class DefaultDockedPanel implements DockedPanel {
2087

    
2088
            String id;
2089
            String title;
2090
            Component component;
2091
            private final String align;
2092

    
2093
            public DefaultDockedPanel(String id, String title, Component component, String align) {
2094
                this.id = id;
2095
                this.title = title;
2096
                this.component = component;
2097
                this.align = align;
2098
            }
2099

    
2100
            @Override
2101
            public String getId() {
2102
                return this.id;
2103
            }
2104

    
2105
            @Override
2106
            public String getAlign() {
2107
                return this.align;
2108
            }
2109

    
2110
            @Override
2111
            public Component getComponent() {
2112
                return this.component;
2113
            }
2114

    
2115
            @Override
2116
            public String getTitle() {
2117
                return this.title;
2118
            }
2119

    
2120
            @Override
2121
            public boolean isModified() {
2122
                return getModified(this);
2123
            }
2124

    
2125
            @Override
2126
            public void setModified(boolean modified) {
2127
                DefaultDock.this.setModified(this, modified);
2128
            }
2129

    
2130
            @Override
2131
            public void remove() {
2132
                DefaultDock.this.remove(this.getId());
2133
            }
2134

    
2135
            @Override
2136
            public void select() {
2137
                DefaultDock.this.select(this.getId());
2138
            }
2139
        }
2140

    
2141
        private final Map<String, Dock.DockedPanel> panels;
2142
        private final JTabbedPaneClosable tabbedPanelLeft;
2143
        private final JTabbedPaneClosable tabbedPanelBottom;
2144
        private final JTabbedPaneClosable tabbedPanelCenter;
2145
        private Set<ActionListener> closeListeners;
2146
        private Set<ActionListener> activePanelListeners;
2147

    
2148
        public DefaultDock(JTabbedPaneClosable tabbedPanelLeft, JTabbedPaneClosable tabbedPanelBottom, JTabbedPaneClosable tabbedPanelCenter) {
2149
            this.panels = new HashMap<>();
2150
            this.tabbedPanelBottom = tabbedPanelBottom;
2151
            this.tabbedPanelLeft = tabbedPanelLeft;
2152
            this.tabbedPanelCenter = tabbedPanelCenter;
2153

    
2154
            ActionListener onCloseTab = new ActionListener() {
2155

    
2156
                @Override
2157
                public void actionPerformed(ActionEvent e) {
2158
                    JTabbedPaneClosable tabbedPanel = (JTabbedPaneClosable) e.getSource();
2159
                    java.awt.Component component = tabbedPanel.getSelectedComponent();
2160
                    if (component != null) {
2161
                        DockedPanel panel = getDockedPanel(component);
2162
                        if (panel != null) {
2163
                            fireCloseListener(new ActionEvent(panel, 0, ACTION_CLOSE_PANEL));
2164
                        }
2165
//                        panels.remove(panel.getId());
2166
//                        tabbedPanel.remove(panel.getComponent().asJComponent());
2167
                    }
2168
                }
2169
            };
2170
            ChangeListener onChangeTab = new ChangeListener() {
2171

    
2172
                @Override
2173
                public void stateChanged(ChangeEvent e) {
2174
                    
2175
                    fireChangeListener(new ActionEvent(DefaultDock.this, 0, ACTION_ACTIVATE_PANEL));
2176
                }
2177
            };
2178
            this.tabbedPanelCenter.addChangeListener(onChangeTab);
2179
            this.tabbedPanelBottom.addChangeListener(onChangeTab);
2180
            this.tabbedPanelLeft.addChangeListener(onChangeTab);
2181
            
2182
            this.tabbedPanelBottom.addCloseTabListener(onCloseTab);
2183
            this.tabbedPanelLeft.addCloseTabListener(onCloseTab);
2184
            this.tabbedPanelCenter.addCloseTabListener(onCloseTab);
2185

    
2186
        }
2187

    
2188
        /**
2189
         *
2190
         * @param listener
2191
         */
2192
        @Override
2193
        public void addCloseListener(ActionListener listener) {
2194
            if (this.closeListeners == null) {
2195
                this.closeListeners = new HashSet<>();
2196
            }
2197
            this.closeListeners.add(listener);
2198
        }
2199

    
2200
        @Override
2201
        public void addActivateListener(ActionListener listener) {
2202
            if (this.activePanelListeners == null) {
2203
                this.activePanelListeners = new HashSet<>();
2204
            }
2205
            this.activePanelListeners.add(listener);
2206
        }
2207

    
2208
        public void fireCloseListener(ActionEvent e) {
2209
            if (this.closeListeners == null) {
2210
                return;
2211
            }
2212
            for (ActionListener listener : this.closeListeners) {
2213
                try {
2214
                    listener.actionPerformed(e);
2215
                } catch (Exception ex) {
2216

    
2217
                }
2218
            }
2219
        }
2220

    
2221
        public void fireChangeListener(ActionEvent e) {
2222
            if (this.activePanelListeners == null) {
2223
                return;
2224
            }
2225
            for (ActionListener listener : this.activePanelListeners) {
2226
                try {
2227
                    listener.actionPerformed(e);
2228
                } catch (Exception ex) {
2229

    
2230
                }
2231
            }
2232
        }
2233

    
2234
        private JTabbedPaneClosable getTabbedPanel(String align) {
2235
            switch (align) {
2236
                case Dock.DOCK_LEFT:
2237
                    return this.tabbedPanelLeft;
2238
                case Dock.DOCK_CENTER:
2239
                    return this.tabbedPanelCenter;
2240
                default:
2241
                case Dock.DOCK_BOTTOM:
2242
                    return this.tabbedPanelBottom;
2243
            }
2244
        }
2245

    
2246
        private DockedPanel getDockedPanel(java.awt.Component component) {
2247
            for (DockedPanel panel : this.panels.values()) {
2248
                if (panel.getComponent().asJComponent() == component) {
2249
                    return panel;
2250
                }
2251
            }
2252
            return null;
2253
        }
2254

    
2255
        private int getIndex(DockedPanel panel) {
2256
            final JTabbedPaneClosable tabbedPanel = getTabbedPanel(panel.getAlign());
2257
            for (int i = 0; i < tabbedPanel.getTabCount(); i++) {
2258
                java.awt.Component component = tabbedPanel.getComponentAt(i);
2259
                if (component == panel.getComponent().asJComponent()) {
2260
                    return i;
2261
                }
2262
            }
2263
            return -1;
2264
        }
2265

    
2266
        @Override
2267
        public void setModified(DockedPanel panel, boolean modified) {
2268
            final int index = this.getIndex(panel);
2269
            if (index < 0) {
2270
                return;
2271
            }
2272
            final JTabbedPaneClosable tabbedPanel = getTabbedPanel(panel.getAlign());
2273
            tabbedPanel.setTabModified(index, modified);
2274
        }
2275

    
2276
        @Override
2277
        public boolean getModified(DockedPanel panel) {
2278
            final int index = this.getIndex(panel);
2279
            if (index < 0) {
2280
                return false;
2281
            }
2282
            final JTabbedPaneClosable tabbedPanel = getTabbedPanel(panel.getAlign());
2283
            return tabbedPanel.isTabModified(index);
2284
        }
2285

    
2286
        @Override
2287
        public DockedPanel getSelected(String align) {
2288
            final JTabbedPaneClosable tabbedPanel = getTabbedPanel(align);
2289
            java.awt.Component selected = tabbedPanel.getSelectedComponent();
2290
            return this.getDockedPanel(selected);
2291
        }
2292

    
2293
        @Override
2294
        public DockedPanel add(String id, String title, final Component component, String align) {
2295
            final JTabbedPaneClosable tabbedPanel = getTabbedPanel(align);
2296
            DockedPanel panel = this.panels.get(id);
2297
            if (panel != null) {
2298
                tabbedPanel.remove(panel.getComponent().asJComponent());
2299
            }
2300
            panel = new DefaultDockedPanel(id, title, component, align);
2301
            this.panels.put(id, panel);
2302
            tabbedPanel.add(panel.getTitle(), panel.getComponent().asJComponent());
2303
            return panel;
2304
        }
2305

    
2306
        @Override
2307
        public void remove(String id) {
2308
            DockedPanel panel = this.panels.get(id);
2309
            if (panel != null) {
2310
                final JTabbedPaneClosable tabbedPanel = getTabbedPanel(panel.getAlign());
2311
                tabbedPanel.remove(panel.getComponent().asJComponent());
2312
                this.panels.remove(id);
2313
            }
2314
        }
2315

    
2316
        @Override
2317
        public DockedPanel get(String id) {
2318
            DockedPanel panel = this.panels.get(id);
2319
            return panel;
2320
        }
2321

    
2322
        @Override
2323
        public void select(String id) {
2324
            DockedPanel panel = this.panels.get(id);
2325
            if (panel != null) {
2326
                final JTabbedPaneClosable tabbedPanel = getTabbedPanel(panel.getAlign());
2327
                tabbedPanel.setSelectedComponent(panel.getComponent().asJComponent());
2328
            }
2329
        }
2330

    
2331
        @Override
2332
        public Iterator<DockedPanel> iterator() {
2333
            return this.panels.values().iterator();
2334
        }
2335

    
2336
    }
2337

    
2338
    private static class ToolEntry {
2339

    
2340
        private String name;
2341
        private String text;
2342
        private Action action;
2343
        private JComponent component;
2344

    
2345
        public ToolEntry(String name, Action action, String text) {
2346
            this.name = name;
2347
            this.action = action;
2348
            this.text = text;
2349
        }
2350

    
2351
        public ToolEntry(String name, Action action) {
2352
            this(name, action, null);
2353
        }
2354

    
2355
        public String getName() {
2356
            return this.name;
2357
        }
2358

    
2359
        public String getText() {
2360
            return this.text;
2361
        }
2362

    
2363
        public Action getAction() {
2364
            return this.action;
2365
        }
2366

    
2367
        public JComponent getComponent() {
2368
            return this.component;
2369
        }
2370

    
2371
        public void setComponent(JComponent component) {
2372
            this.component = component;
2373
        }
2374
    }
2375

    
2376
    public class ButtonWithContext extends JButton {
2377

    
2378
        private static final long serialVersionUID = -7434255417630073101L;
2379

    
2380
        public ButtonWithContext(Action action) {
2381
            super(action);
2382
            this.setBorderPainted(false);
2383
            this.setText("");
2384
        }
2385

    
2386
        public Object getContext() {
2387
            return DefaultJScriptingComposer.this;
2388
        }
2389
    }
2390

    
2391
    private class FindReplaceSearchListener implements SearchListener {
2392

    
2393
        @Override
2394
        public void searchEvent(SearchEvent e) {
2395

    
2396
            RSyntaxTextArea textArea = getCurrentRSyntaxTextArea();
2397
            if (textArea == null) {
2398
                return;
2399
            }
2400

    
2401
            SearchEvent.Type type = e.getType();
2402
            SearchContext context = e.getSearchContext();
2403
            SearchResult result;
2404

    
2405
            switch (type) {
2406
                default: // Prevent FindBugs warning later
2407
                case MARK_ALL:
2408
                    result = SearchEngine.markAll(textArea, context);
2409
                    break;
2410
                case FIND:
2411
                    result = SearchEngine.find(textArea, context);
2412
                    if (!result.wasFound()) {
2413
                        UIManager.getLookAndFeel().provideErrorFeedback(textArea);
2414
                    }
2415
                    break;
2416
                case REPLACE:
2417
                    result = SearchEngine.replace(textArea, context);
2418
                    if (!result.wasFound()) {
2419
                        UIManager.getLookAndFeel().provideErrorFeedback(textArea);
2420
                    }
2421
                    break;
2422
                case REPLACE_ALL:
2423
                    result = SearchEngine.replaceAll(textArea, context);
2424
                    JOptionPane.showMessageDialog(null, result.getCount()
2425
                            + " occurrences replaced.");
2426
                    break;
2427
            }
2428
            String text;
2429
            if (result.wasFound()) {
2430
                text = "Text found; occurrences marked: " + result.getMarkedCount();
2431
            } else if (type == SearchEvent.Type.MARK_ALL) {
2432
                if (result.getMarkedCount() > 0) {
2433
                    text = "Occurrences marked: " + result.getMarkedCount();
2434
                } else {
2435
                    text = "";
2436
                }
2437
            } else {
2438
                text = "Text not found";
2439
            }
2440
            getStatusbar().message(text);
2441
        }
2442

    
2443
        @Override
2444
        public String getSelectedText() {
2445
            RSyntaxTextArea textArea = getCurrentRSyntaxTextArea();
2446
            if (textArea == null) {
2447
                return "";
2448
            }
2449
            return textArea.getSelectedText();
2450
        }
2451

    
2452
    }
2453
}