Preferences: continue to connect SciNotes
[scilab.git] / scilab / modules / scinotes / src / java / org / scilab / modules / scinotes / SciNotes.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2009 - DIGITEO - Bruno JOFRET
4  * Copyright (C) 2010 - 2011 - Calixte DENIZET
5  *
6  * This file must be used under the terms of the CeCILL.
7  * This source file is licensed as described in the file COPYING, which
8  * you should have received as part of this distribution.  The terms
9  * are also available at
10  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
11  *
12  */
13
14 package org.scilab.modules.scinotes;
15
16 import java.awt.Color;
17 import java.awt.Component;
18 import java.io.BufferedWriter;
19 import java.io.File;
20 import java.io.FileOutputStream;
21 import java.io.IOException;
22 import java.io.OutputStreamWriter;
23 import java.io.StringReader;
24 import java.lang.reflect.Constructor;
25 import java.lang.reflect.InvocationTargetException;
26 import java.util.ArrayList;
27 import java.util.Collections;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.UUID;
33 import java.util.logging.Logger;
34
35 import javax.swing.BorderFactory;
36 import javax.swing.JComponent;
37 import javax.swing.JFileChooser;
38 import javax.swing.JFrame;
39 import javax.swing.JOptionPane;
40 import javax.swing.JSplitPane;
41 import javax.swing.KeyStroke;
42 import javax.swing.SwingUtilities;
43 import javax.swing.event.ChangeEvent;
44 import javax.swing.event.ChangeListener;
45 import javax.swing.text.BadLocationException;
46 import javax.swing.text.EditorKit;
47 import javax.swing.text.View;
48 import javax.swing.undo.UndoManager;
49
50 import org.w3c.dom.Document;
51
52 import org.flexdock.docking.event.DockingEvent;
53 import org.scilab.modules.commons.xml.ScilabXMLUtilities;
54 import org.scilab.modules.commons.xml.XConfiguration;
55 import static org.scilab.modules.commons.xml.XConfiguration.XConfAttribute;
56 import org.scilab.modules.core.Scilab;
57 import org.scilab.modules.gui.bridge.filechooser.SwingScilabFileChooser;
58 import org.scilab.modules.gui.bridge.tab.SwingScilabTab;
59 import org.scilab.modules.gui.bridge.window.SwingScilabWindow;
60 import org.scilab.modules.gui.filechooser.Juigetfile;
61 import org.scilab.modules.gui.filechooser.ScilabFileChooser;
62 import org.scilab.modules.gui.menubar.MenuBar;
63 import org.scilab.modules.gui.messagebox.MessageBox;
64 import org.scilab.modules.gui.messagebox.ScilabMessageBox;
65 import org.scilab.modules.gui.messagebox.ScilabModalDialog;
66 import org.scilab.modules.gui.messagebox.ScilabModalDialog.AnswerOption;
67 import org.scilab.modules.gui.messagebox.ScilabModalDialog.ButtonType;
68 import org.scilab.modules.gui.messagebox.ScilabModalDialog.IconType;
69 import org.scilab.modules.gui.pushbutton.PushButton;
70 import org.scilab.modules.gui.tab.SimpleTab;
71 import org.scilab.modules.gui.tabfactory.ScilabTabFactory;
72 import org.scilab.modules.gui.textbox.TextBox;
73 import org.scilab.modules.gui.toolbar.ToolBar;
74 import org.scilab.modules.gui.utils.ClosingOperationsManager;
75 import org.scilab.modules.gui.utils.ConfigManager;
76 import org.scilab.modules.gui.utils.Position;
77 import org.scilab.modules.gui.utils.SciFileFilter;
78 import org.scilab.modules.gui.utils.Size;
79 import org.scilab.modules.gui.utils.WindowsConfigurationManager;
80 import org.scilab.modules.scinotes.actions.EncodingAction;
81 import org.scilab.modules.scinotes.actions.EndOfLineAction;
82 import org.scilab.modules.scinotes.actions.ExitAction;
83 import org.scilab.modules.scinotes.actions.FindAction;
84 import org.scilab.modules.scinotes.actions.IncrementalSearchAction;
85 import org.scilab.modules.scinotes.actions.InsertOverwriteAction;
86 import org.scilab.modules.scinotes.actions.LineBeautifierAction;
87 import org.scilab.modules.scinotes.actions.OpenSourceFileOnKeywordAction;
88 import org.scilab.modules.scinotes.actions.RecentFileAction;
89 import org.scilab.modules.scinotes.actions.RestoreOpenedFilesAction;
90 import org.scilab.modules.scinotes.actions.SciNotesCompletionAction;
91 import org.scilab.modules.scinotes.actions.SearchWordInFilesAction;
92 import org.scilab.modules.scinotes.tabfactory.CodeNavigatorTab;
93 import org.scilab.modules.scinotes.tabfactory.SciNotesTab;
94 import org.scilab.modules.scinotes.tabfactory.SciNotesTabFactory;
95 import org.scilab.modules.scinotes.tabfactory.SearchInFilesTab;
96 import org.scilab.modules.scinotes.utils.ConfigSciNotesManager;
97 import org.scilab.modules.scinotes.utils.DropFilesListener;
98 import org.scilab.modules.scinotes.utils.NavigatorWindow;
99 import org.scilab.modules.scinotes.utils.SaveFile;
100 import org.scilab.modules.scinotes.utils.SciNotesContents;
101 import org.scilab.modules.scinotes.utils.SciNotesMessages;
102 import org.scilab.modules.scinotes.utils.ScilabTabbedPane;
103 import org.scilab.modules.scinotes.utils.SearchFile;
104
105 /**
106  * Main SciNotes class.
107  *
108  * @author Bruno JOFRET
109  * @author Calixte DENIZET
110  */
111 public class SciNotes extends SwingScilabTab {
112
113     private static final long serialVersionUID = -6410183357490518676L;
114
115     private static final String XPATH_SCINOTES_KEY = "//general/shortcuts/body/actions/action-folder[@name='Scinotes']/action";
116     private static final String XPATH_SCINOTES_ACTION = "/map/scinotes/entry";
117
118     private static final String SCINOTES = "SciNotes";
119     private static final String SCI_EXTENSION = ".sci";
120     private static final String SCE_EXTENSION = ".sce";
121     private static final String TST_EXTENSION = ".tst";
122     private static final String QUIT_EXTENSION = ".quit";
123     private static final String DEM_EXTENSION = ".dem";
124     private static final String START_EXTENSION = ".start";
125     private static final String ALL_TST_FILES = "*.tst";
126     private static final String ALL_QUIT_FILES = "*.quit";
127     private static final String ALL_START_FILES = "*.start";
128     private static final String ALL_SCI_FILES = "*.sci";
129     private static final String ALL_SCE_FILES = "*.sce";
130     private static final String ALL_DEM_FILES = "*.dem";
131     private static final String ALL_SCX_FILES = "*.sc*";
132     private static final String ALL_SCILAB = "all";
133     private static final String ALL_FILES = "*.*";
134     private static final String DOT = ".";
135
136     private static final String DEFAULTACTIONPATH = "org.scilab.modules.scinotes.actions";
137
138     private static final Map<String, String> actionToName;
139     private static Map<String, KeyStroke> actionKeys;
140
141     private static List<SciNotes> scinotesList = new ArrayList<SciNotes>();
142     private static SciNotes editor;
143     private static boolean mustWrapLines;
144
145     private SwingScilabWindow parentWindow;
146     private UUID uuid;
147
148     private ScilabTabbedPane tabPane;
149     private final SciNotesContents contentPane;
150     private NavigatorWindow navigator;
151     private SearchFile searchInFiles;
152
153     private int numberOfUntitled;
154     private EditorKit editorKit;
155
156     private PushButton undoButton;
157     private PushButton redoButton;
158
159     private boolean protectOpenFileList;
160     private boolean restored;
161
162     private final List<Integer> tabList = new ArrayList<Integer>();
163     private final List<Integer> closedTabList = new ArrayList<Integer>();
164
165     static {
166         ConfigSciNotesManager.createUserCopy();
167         ScilabTabFactory.getInstance().addTabFactory(SciNotesTabFactory.getInstance());
168         Scilab.registerInitialHook(new Runnable() {
169             @Override
170             public void run() {
171                 updateSciNotes();
172             }
173         });
174
175         Document doc = ScilabXMLUtilities.readDocument(System.getenv("SCI") + "/modules/console/etc/Actions-Configuration.xml");
176         actionToName = XConfiguration.get(doc, "name", String.class, "action", String.class, XPATH_SCINOTES_ACTION);
177         XConfiguration.addXConfigurationListener(new SciNotesConfiguration());
178     }
179
180     /**
181      * Create SciNotes instance
182      */
183     public SciNotes(String uuid) {
184         super(SCINOTES, uuid);
185         setAssociatedXMLIDForHelp("scinotes");
186         this.uuid = UUID.fromString(uuid);
187         editor = this;
188         scinotesList.add(this);
189         numberOfUntitled = 0;
190         mustWrapLines = SciNotesOptions.getSciNotesDisplay().wrapLines;
191         editorKit = new ScilabEditorKit(!mustWrapLines);
192         protectOpenFileList = false;
193         contentPane = new SciNotesContents(this);
194         tabPane = contentPane.getScilabTabbedPane();
195         tabPane.addChangeListener(new ChangeListener() {
196             @Override
197             public void stateChanged(ChangeEvent e) {
198                 if (getTextPane() != null) {
199                     // updateUI();
200                     getTextPane().updateInfosWhenFocused();
201                     getTextPane().requestFocus();
202                     getTextPane().highlightWords(IncrementalSearchAction.getWord(SciNotes.this), IncrementalSearchAction.getExact(SciNotes.this));
203
204                     // Update encoding menu
205                     EncodingAction.updateEncodingMenu((ScilabDocument) getTextPane().getDocument());
206
207                     // Update End Of Line menu
208                     EndOfLineAction.updateEolMenu((ScilabDocument) getTextPane().getDocument());
209                     setTitle(getTextPane().getTitle());
210                 }
211             }
212         });
213         this.setContentPane(contentPane);
214     }
215
216     /**
217      * Default constructor
218      */
219     public SciNotes() {
220         this(UUID.randomUUID().toString());
221     }
222
223     public static void configurationChanged(SciNotesConfiguration.Conf conf) {
224         setWhereamiLineNumbering();
225         setAutoIndent();
226         setHorizontalWrap();
227         setDefaultTabulation();
228         if (conf.keymap) {
229             actionKeys = null;
230             setKeyStrokeActions();
231             setAllMenus();
232         }
233         updatePanes(conf);
234     }
235
236     public static Map<String, KeyStroke> getActionKeys() {
237         if (actionKeys == null) {
238             Document doc = XConfiguration.getXConfigurationDocument();
239             actionKeys = XConfiguration.get(doc, "name", String.class, "key", KeyStroke.class, XPATH_SCINOTES_KEY);
240         }
241
242         return actionKeys;
243     }
244
245     public static Map<String, String> getActionName() {
246         return actionToName;
247     }
248
249     /**
250      * Get an opened editor from its uuid
251      *
252      * @param uuid
253      *            the uuid
254      * @return the corresponding editor
255      */
256     public static SciNotes getEditorFromUUID(String uuid) {
257         for (SciNotes ed : scinotesList) {
258             if (ed.getPersistentId().equals(uuid)) {
259                 return ed;
260             }
261         }
262
263         return null;
264     }
265
266     public void setParentWindow() {
267         this.parentWindow = new SwingScilabWindow();
268         setWindowIcon("accessories-text-editor");
269         Position pos = ConfigSciNotesManager.getMainWindowPosition();
270         parentWindow.setLocation(pos.getX(), pos.getY());
271         Size size = ConfigSciNotesManager.getMainWindowSize();
272         parentWindow.setSize(size.getWidth(), size.getHeight());
273     }
274
275     /**
276      * {@inheritDoc}
277      */
278     @Override
279     public void setTitle(String title) {
280         super.setTitle(title);
281         SwingScilabWindow window = (SwingScilabWindow) SwingUtilities.getAncestorOfClass(SwingScilabWindow.class, tabPane);
282         if (window != null) {
283             window.setTitle(title);
284         }
285     }
286
287     public void insertBottomComponent(Component c) {
288         contentPane.insertBottomComponent(c);
289     }
290
291     /**
292      * @return the SwingScilabWindow containing this editor
293      */
294     public SwingScilabWindow getSwingParentWindow() {
295         return (SwingScilabWindow) SwingUtilities.getAncestorOfClass(SwingScilabWindow.class, this);
296     }
297
298     /**
299      * {@inheritDoc}
300      */
301     @Override
302     public void undockingComplete(DockingEvent evt) {
303         super.undockingComplete(evt);
304         if (navigator != null) {
305             navigator.addToolBar(null);
306         }
307         if (searchInFiles != null) {
308             searchInFiles.addToolBar(null);
309         }
310     }
311
312     /**
313      * {@inheritDoc}
314      */
315     @Override
316     public void dockingComplete(DockingEvent evt) {
317         super.dockingComplete(evt);
318         if (navigator != null) {
319             navigator.changeToolBar();
320         }
321         if (searchInFiles != null) {
322             searchInFiles.changeToolBar();
323         }
324     }
325
326     /**
327      * Add a code navigator
328      */
329     public void addNavigator() {
330         if (navigator == null) {
331             String navUUID = ConfigSciNotesManager.getCodeNavigatorStateForEditor(getPersistentId());
332             boolean success = WindowsConfigurationManager.restoreUUID(navUUID);
333             if (!success) {
334                 navigator = CodeNavigatorTab.getCodeNavigatorInstance(this, null);
335                 navigator.setParentWindow();
336             }
337             int count = getTabPane().getTabCount();
338             for (int i = 0; i < count; i++) {
339                 navigator.addEditorPane(getTextPane(i));
340             }
341         }
342     }
343
344     /**
345      * Add a code navigator
346      */
347     public void addNavigator(NavigatorWindow navigator) {
348         this.navigator = navigator;
349     }
350
351     /**
352      * Remove the navigator
353      */
354     public void removeNavigator() {
355         navigator = null;
356     }
357
358     /**
359      * @return the navigator associated with this editor
360      */
361     public NavigatorWindow getNavigator() {
362         return navigator;
363     }
364
365     /**
366      * Add a Search in files
367      */
368     public void addSearchInFiles() {
369         if (searchInFiles == null) {
370             String sfUUID = ConfigSciNotesManager.getSearchInFilesStateForEditor(getPersistentId());
371             boolean success = WindowsConfigurationManager.restoreUUID(sfUUID);
372             if (!success) {
373                 searchInFiles = SearchInFilesTab.getSearchInFilesTabInstance(this, null);
374                 searchInFiles.setParentWindow();
375             }
376         }
377     }
378
379     /**
380      * Add a Search In Files
381      */
382     public void addSearchInFiles(SearchFile sf) {
383         this.searchInFiles = sf;
384     }
385
386     /**
387      * Remove Search in Files
388      */
389     public void removeSearchInFiles() {
390         searchInFiles = null;
391     }
392
393     /**
394      * @return the Search In Files associated with this editor
395      */
396     public SearchFile getSearchInFiles() {
397         return searchInFiles;
398     }
399
400     /**
401      * Update the editor
402      */
403     public static void updateSciNotes() {
404         ScilabLexer.update();
405         for (SciNotes editor : scinotesList) {
406             if (editor.getTextPane() != null) {
407                 editor.getTextPane().repaint();
408             }
409         }
410     }
411
412     /**
413      * Launch SciNotes with an empty file
414      *
415      * This method *must not* be called on the EDT thread.
416      */
417     public static void scinotes() {
418         ScilabLexer.update();
419         try {
420             SwingUtilities.invokeAndWait(new Runnable() {
421
422                 @Override
423                 public void run() {
424                     launchSciNotes();
425                     // Open an empty file if no tabs were opened at launch.
426                     if (editor.getTabPane().getTabCount() == 0) {
427                         editor.openFile(null, 0, null);
428                     }
429                 }
430             });
431         } catch (InterruptedException e) {
432             Logger.getLogger(SciNotes.class.getName()).severe(e.toString());
433             throw new RuntimeException(e);
434         } catch (InvocationTargetException e) {
435             Logger.getLogger(SciNotes.class.getName()).severe(e.toString());
436             e.printStackTrace();
437             throw new RuntimeException(e);
438         }
439     }
440
441     /**
442      * Launch SciNotes with a file name to open.
443      *
444      * @param filePath
445      *            the name of the file to open
446      *
447      *            This method *must not* be called on the EDT thread.
448      */
449     public static void scinotes(final String filePath) {
450         ScilabLexer.update();
451         try {
452             SwingUtilities.invokeAndWait(new Runnable() {
453
454                 @Override
455                 public void run() {
456                     launchSciNotes();
457                     editor.openFile(filePath, 0, null);
458                 }
459             });
460         } catch (InterruptedException e) {
461             Logger.getLogger(SciNotes.class.getName()).severe(e.toString());
462             throw new RuntimeException(e);
463         } catch (InvocationTargetException e) {
464             e.printStackTrace();
465             Logger.getLogger(SciNotes.class.getName()).severe(e.toString());
466             throw new RuntimeException(e);
467         }
468     }
469
470     /**
471      * Launch SciNotes with a file name to open and a line to highlight.
472      *
473      * @param filePath
474      *            the name of the file to open
475      * @param lineNumber
476      *            the line to highlight
477      *
478      *            This method *must not* be called on the EDT thread.
479      */
480     public static void scinotes(final String filePath, final int lineNumber, final String functionName) {
481         ScilabLexer.update();
482         try {
483             SwingUtilities.invokeAndWait(new Runnable() {
484
485                 @Override
486                 public void run() {
487                     launchSciNotes();
488                     editor.openFile(filePath, lineNumber, functionName);
489                 }
490             });
491         } catch (InterruptedException e) {
492             Logger.getLogger(SciNotes.class.getName()).severe(e.toString());
493             throw new RuntimeException(e);
494         } catch (InvocationTargetException e) {
495             e.printStackTrace();
496             Logger.getLogger(SciNotes.class.getName()).severe(e.toString());
497             throw new RuntimeException(e);
498         }
499     }
500
501     /**
502      * Launch SciNotes with a file name to open and a line to highlight.
503      *
504      * @param filePath
505      *            the name of the file to open
506      * @param option
507      *            such as 'readonly'
508      *
509      *            This method *must not* be called on the EDT thread.
510      */
511     public static void scinotes(final String filePath, final String option) {
512         ScilabLexer.update();
513         try {
514             SwingUtilities.invokeAndWait(new Runnable() {
515
516                 @Override
517                 public void run() {
518                     launchSciNotes();
519                     editor.openFile(filePath, 0, option);
520                 }
521             });
522         } catch (InterruptedException e) {
523             Logger.getLogger(SciNotes.class.getName()).severe(e.toString());
524             throw new RuntimeException(e);
525         } catch (InvocationTargetException e) {
526             e.printStackTrace();
527             Logger.getLogger(SciNotes.class.getName()).severe(e.toString());
528             throw new RuntimeException(e);
529         }
530     }
531
532     /**
533      * Launch SciNotes with a provided text (from the help for example).
534      *
535      * @param text
536      *            the text which should be modified
537      */
538     public static void scinotesWithText(String text) {
539         ScilabLexer.update();
540         launchSciNotes();
541         ScilabEditorPane theTextPane;
542         if (editor.getTabPane().getTabCount() != 0) {
543             String name = editor.getTextPane(0).getName();
544             if (name == null) {
545                 theTextPane = editor.getTextPane(0);
546             } else {
547                 theTextPane = editor.addEmptyTab();
548             }
549         } else {
550             theTextPane = editor.addEmptyTab();
551         }
552
553         ScilabDocument styleDocument = (ScilabDocument) theTextPane.getDocument();
554         try {
555             editor.getEditorKit().read(new StringReader(text), styleDocument, theTextPane.getCaretPosition());
556         } catch (IOException e) {
557             System.err.println(SciNotesMessages.ERROR_WITH_STRING);
558         } catch (BadLocationException e) {
559             System.err.println(SciNotesMessages.ERROR_WITH_STRING);
560         }
561     }
562
563     /**
564      * Clone the current tab and if b is true close the tab
565      *
566      * @param ed
567      *            the editor where the tab is
568      * @param b
569      *            a boolean
570      */
571     public static void cloneAndCloseCurrentTab(SciNotes ed, boolean b) {
572         ScilabDocument cdoc = (ScilabDocument) ed.getTextPane().getDocument();
573         String title = ed.getTabPane().getScilabTitleAt(ed.getTabPane().getSelectedIndex());
574         ScilabEditorPane currentSep = ed.getTextPane();
575         String winTitle = ed.getTitle();
576
577         if (b) {
578             ed.closeTabAtWithoutConfirmation(ed.getTabPane().getSelectedIndex());
579             if (ed.getTabPane().getTabCount() == 0) {
580                 ClosingOperationsManager.startClosingOperationWithoutSave((SwingScilabTab) ed);
581                 ConfigSciNotesManager.removeEditorUUID(ed.uuid.toString());
582             }
583         }
584
585         editor = null;
586
587         scinotesWithText(cdoc.getText());
588         ScilabEditorPane sep = editor.getTextPane();
589
590         if (currentSep.getName() != null) {
591             editor.getTabPane().setTitleAt(0, title);
592             editor.setTitle(winTitle);
593         }
594
595         currentSep.copyProps(sep);
596         ScilabDocument sdoc = (ScilabDocument) sep.getDocument();
597         sdoc.setContentModified(cdoc.isContentModified());
598         sdoc.getUndoManager().discardAllEdits();
599         sep.setCaretPosition(0);
600         editor.enableUndoButton(false);
601         editor.enableRedoButton(false);
602         ConfigSciNotesManager.saveToOpenFiles(sep.getName(), editor, editor.getTextPane());
603     }
604
605     /**
606      * Clone the current tab and if b is true close the tab
607      *
608      * @param ed
609      *            the editor where the tab is
610      * @param b
611      *            a boolean
612      */
613     public static void cloneAndCloseCurrentTab(SciNotes ed, boolean b, int x, int y) {
614         cloneAndCloseCurrentTab(ed, b);
615         editor.getSwingParentWindow().setLocation(x, y);
616     }
617
618     /**
619      * Execute after when the restoration is finished
620      */
621     @Override
622     public void endedRestoration() {
623         if (!SwingUtilities.isEventDispatchThread()) {
624             try {
625                 SwingUtilities.invokeAndWait(new Runnable() {
626
627                     @Override
628                     public void run() {
629                         restorePreviousSession();
630                     }
631                 });
632             } catch (InterruptedException e) {
633                 Logger.getLogger(SciNotes.class.getName()).severe(e.toString());
634                 throw new RuntimeException(e);
635             } catch (InvocationTargetException e) {
636                 Logger.getLogger(SciNotes.class.getName()).severe(e.toString());
637                 throw new RuntimeException(e);
638             }
639         } else {
640             restorePreviousSession();
641         }
642     }
643
644     /**
645      * Restore the previous session
646      */
647     public void restorePreviousSession() {
648         restored = true;
649         if (!ConfigSciNotesManager.getRestoreOpenedFiles() || ConfigSciNotesManager.countExistingOpenFiles(getUUID()) == 0) {
650             if (getTabPane().getTabCount() != 1 || getTextPane(0).getName() != null) {
651                 openFile(null, 0, null);
652             }
653             setWindowIcon("accessories-text-editor");
654             WindowsConfigurationManager.restorationFinished(this);
655
656             return;
657         }
658
659         SwingUtilities.invokeLater(new Runnable() {
660             @Override
661             public void run() {
662                 RestoreOpenedFilesAction.displayDialog((JFrame) SwingUtilities.getAncestorOfClass(JFrame.class, SciNotes.this), getUUID().toString());
663                 List<File> list = RestoreOpenedFilesAction.getSelectedFiles();
664
665                 if (list != null && list.size() != 0) {
666                     for (File f : list) {
667                         openFile(f.getPath(), 0, null);
668                     }
669                 } else {
670                     if (getTabPane().getTabCount() == 0 || getTextPane(0).getName() == null) {
671                         openFile(null, 0, null);
672                     }
673                 }
674
675                 setWindowIcon("accessories-text-editor");
676
677                 if (navigator != null) {
678                     navigator.updateTree();
679                 }
680
681                 WindowsConfigurationManager.restorationFinished(SciNotes.this);
682             }
683         });
684     }
685
686     /**
687      * Create SciNotes instance
688      *
689      * @return the instance
690      */
691     public static void launchSciNotes() {
692         if (editor == null) {
693             List<String> uuids = ConfigSciNotesManager.getEditorsUUID();
694             boolean success = false;
695             if (!uuids.isEmpty()) {
696                 for (String uuid : uuids) {
697                     boolean exists = false;
698                     for (SciNotes ed : scinotesList) {
699                         if (ed.uuid.toString().equals(uuid)) {
700                             exists = true;
701                             break;
702                         }
703                     }
704                     if (!exists) {
705                         success = WindowsConfigurationManager.restoreUUID(uuid);
706                         break;
707                     }
708                 }
709             }
710             if (!success) {
711                 editor = SciNotesTab.getEditorInstance(null);
712                 editor.setParentWindow();
713                 ConfigSciNotesManager.saveEditorUUID(editor.getPersistentId());
714                 SciNotesGUI.init(editor.getParentWindow(), editor, SCINOTES);
715             }
716         }
717
718         if (!editor.restored) {
719             editor.restorePreviousSession();
720         }
721     }
722
723     /**
724      * Open a file.
725      *
726      * This method *must* be called on the EDT thread.
727      *
728      * @param filePath
729      *            the file path (may be null)
730      * @param lineNumber
731      *            the line number (use 0 for unspecified)
732      * @param option
733      *            the options (may be null)
734      */
735     public void openFile(String filePath, int lineNumber, String option) {
736         if (!SwingUtilities.isEventDispatchThread()) {
737             throw new RuntimeException("called outside the EDT thread.");
738         }
739
740         if (filePath == null) {
741             addEmptyTab();
742             return;
743         }
744
745         File f = fileToCanonicalFile(new File(filePath));
746         if (!f.getParentFile().exists()) {
747             JOptionPane.showMessageDialog(SciNotes.this, SciNotesMessages.OPEN_ERROR);
748             addEmptyTab();
749             return;
750         }
751
752         if (f.isDirectory()) { /* Bug 5131 */
753             ConfigManager.saveLastOpenedDirectory(f.getPath());
754             addEmptyTab();
755             return;
756         }
757
758         readFileAndWait(f);
759         if (option == null || option.length() == 0 || "readonly".equals(option.toLowerCase())) {
760             getTextPane().scrollTextToLineNumber(lineNumber, true);
761         } else {
762             getTextPane().scrollTextToLineNumberInWhereami(lineNumber, option, true);
763         }
764         if ((option != null && "readonly".equals(option.toLowerCase()))) {
765             getTextPane().setReadOnly(true);
766             getInfoBar().setText(getTextPane().getInfoBarText());
767             ConfigSciNotesManager.removeFromOpenFiles(this, getTextPane());
768         } else {
769             ConfigSciNotesManager.saveToRecentOpenedFiles(filePath);
770             RecentFileAction.updateRecentOpenedFilesMenu(this);
771         }
772     }
773
774     /**
775      * Close SciNotes instance including all tabs.
776      */
777     public void closeSciNotes() {
778         for (int i = 0; i < getTabPane().getTabCount(); i++) {
779             ScilabEditorPane textPaneAt = getTextPane(i);
780             textPaneAt.destroy();
781         }
782
783         FindAction.close();
784         IncrementalSearchAction.close(this);
785         OpenSourceFileOnKeywordAction.closeOpenSourceWindow();
786         SearchWordInFilesAction.closeWindow();
787
788         /*
789          * setProtectOpenFileList(true); while (getTabPane().getTabCount() > 0)
790          * { closeTabAt(0, true); } setProtectOpenFileList(false);
791          */
792
793         scinotesList.remove(this);
794         editor = null;
795         ConfigSciNotesManager.resetDocument();
796     }
797
798     public boolean canClose() {
799         int numberOfTab = getTabPane().getTabCount();
800         setProtectOpenFileList(true);
801
802         for (int i = 0; i < numberOfTab; i++) {
803             boolean ans = checkToCloseTabAt(i);
804             if (!ans) {
805                 setProtectOpenFileList(false);
806                 return false;
807             }
808         }
809         setProtectOpenFileList(false);
810
811         return true;
812     }
813
814     public String askForClosing() {
815         int numberOfTab = getTabPane().getTabCount();
816         boolean isContentModified = false;
817         for (int i = 0; i < getTabPane().getTabCount(); i++) {
818             ScilabEditorPane textPaneAt = getTextPane(i);
819             if (((ScilabDocument) textPaneAt.getDocument()).isContentModified()) {
820                 isContentModified = true;
821                 break;
822             }
823         }
824
825         if (isContentModified) {
826             return "SciNotes";
827         }
828
829         return null;
830     }
831
832     public static void closeEditor(SciNotes ed) {
833         if (scinotesList.size() > 1) {
834             ClosingOperationsManager.startClosingOperationWithoutSave((SwingScilabTab) ed);
835         } else {
836             ClosingOperationsManager.startClosingOperation((SwingScilabTab) ed);
837         }
838     }
839
840     /**
841      * Close a tab using its index.
842      *
843      * @param indexTab
844      *            the index of the tab
845      * @return if the tab has been really closed
846      */
847     public boolean closeTabAtWithoutConfirmation(int indexTab) {
848         return closeTabAt(indexTab, false, false);
849     }
850
851     /**
852      * Close a tab using its index.
853      *
854      * @param indexTab
855      *            the index of the tab
856      * @return if the tab has been really closed
857      */
858     public boolean closeTabAt(int indexTab) {
859         return closeTabAt(indexTab, false, true);
860     }
861
862     /**
863      * Close a tab using its index.
864      *
865      * @param indexTab
866      *            the index of the tab
867      * @param scilabClose
868      *            if true, save dialog confirmation cannot be canceled
869      * @return if the tab has been really closed
870      */
871     public boolean closeTabAt(int indexTab, boolean scilabClose, boolean confirmation) {
872         ScilabEditorPane textPaneAt = getTextPane(indexTab);
873
874         /*
875          * Test for modification added after bug 5103 fix: do not ask the user
876          * for an Untitled not-modified file saving when closing SciNotes
877          */
878         if (confirmation && ((ScilabDocument) textPaneAt.getDocument()).isContentModified()) {
879             if (!save(indexTab, false, scilabClose)) {
880                 return false;
881             }
882         }
883
884         textPaneAt.close();
885
886         if (textPaneAt.getName() == null) {
887             String closedTabName = tabPane.getScilabTitleAt(indexTab);
888             String closedTabNameIndex = closedTabName.substring(closedTabName.length() - 1, closedTabName.length());
889             tabList.remove(Integer.valueOf(closedTabNameIndex));
890             closedTabList.add(Integer.valueOf(closedTabNameIndex));
891         }
892
893         // correction for bug 5404, closing the last tabPane generate an
894         // exception
895         // that's why we need to remove ChangeListeners before closing
896         if ((indexTab == 0) && (getTabPane().getTabCount() == 1)) {
897             for (int i = 0; i < tabPane.getChangeListeners().length; i++) {
898                 tabPane.removeChangeListener(tabPane.getChangeListeners()[i]);
899             }
900         }
901
902         // Remove the filename associated with the tab from the list of open
903         // files.
904         if (!protectOpenFileList) {
905             ConfigSciNotesManager.removeFromOpenFiles(this, textPaneAt);
906         }
907
908         if (navigator != null) {
909             navigator.removePane(textPaneAt);
910         }
911
912         textPaneAt.close();
913         tabPane.remove(indexTab);
914
915         textPaneAt = getTextPane();
916         if (textPaneAt != null) {
917             if (navigator != null) {
918                 navigator.update((ScilabDocument) textPaneAt.getDocument());
919             }
920         }
921         return true;
922     }
923
924     public boolean checkToCloseTabAt(int index) {
925         ScilabEditorPane textPaneAt = getTextPane(index);
926
927         /*
928          * Test for modification added after bug 5103 fix: do not ask the user
929          * for an Untitled not-modified file saving when closing SciNotes
930          */
931         if (((ScilabDocument) textPaneAt.getDocument()).isContentModified()) {
932             if (!save(index, false, false)) {
933                 return false;
934             }
935         }
936
937         return true;
938     }
939
940     /**
941      * Set or unset protection of the currently open file list. Call before
942      * closing tabs if the tabs should be restored when scinotes restarts.
943      *
944      * @param protect
945      *            Enables protection of the open file list if true.
946      */
947     public void setProtectOpenFileList(boolean protect) {
948         protectOpenFileList = protect;
949     }
950
951     /**
952      * Determines if this editor is the only editor instance.
953      *
954      * @return true if this is the last editor instance.
955      */
956     public boolean isOnlyInstance() {
957         if (scinotesList.size() > 1) {
958             return false;
959         }
960
961         return true;
962     }
963
964     /**
965      * @return the list of the different openened editors
966      */
967     public static List<SciNotes> getSciNotesList() {
968         return scinotesList;
969     }
970
971     /**
972      * Save a file.
973      *
974      * @param indexTab
975      *            the textPane index containing the file contents
976      * @return execution status
977      */
978     public boolean save(int indexTab) {
979         return save(indexTab, false, false);
980     }
981
982     /**
983      * Save a file.
984      *
985      * @param indexTab
986      *            the textPane index containing the file contents
987      * @param force
988      *            : force save without confirmation dialog ( SaveAction )
989      * @return execution status
990      */
991     public boolean save(int indexTab, boolean force) {
992         return save(indexTab, force, false);
993     }
994
995     /**
996      * Save a file.
997      *
998      * @param indexTab
999      *            the textPane index containing the file contents
1000      * @param force
1001      *            : force save without confirmation dialog ( SaveAction )
1002      * @param scilabClose
1003      *            : if true, save dialog confirmation cannot be canceled
1004      * @return execution status
1005      */
1006     public boolean save(int indexTab, boolean force, boolean scilabClose) {
1007         ScilabEditorPane textPaneAt = getTextPane(indexTab);
1008         getTabPane().setSelectedIndex(indexTab);
1009
1010         // if the file ( empty, new or loaded ) is not modified, exit save
1011         // process and return true
1012         if (!textPaneAt.checkExternalModif() && !((ScilabDocument) textPaneAt.getDocument()).isContentModified() && (textPaneAt.getName() != null)) {
1013             /*
1014              * Bug
1015              * 5103
1016              * fix
1017              */
1018             return true;
1019         }
1020
1021         if (!force) {
1022             AnswerOption answer;
1023             if (scilabClose) {
1024                 answer = ScilabModalDialog.show(this, getTabPane().getScilabTitleAt(indexTab) + SciNotesMessages.MODIFIED, SciNotesMessages.SCILAB_EDITOR,
1025                                                 IconType.QUESTION_ICON, ButtonType.YES_NO);
1026             } else {
1027                 answer = ScilabModalDialog.show(this, getTabPane().getScilabTitleAt(indexTab) + SciNotesMessages.MODIFIED, SciNotesMessages.SCILAB_EDITOR,
1028                                                 IconType.QUESTION_ICON, ButtonType.YES_NO_CANCEL);
1029             }
1030
1031             switch (answer) {
1032                 case YES_OPTION: // Yes, continue
1033                     break;
1034                 case NO_OPTION:// No, exit and returns true
1035                     return true;
1036                 case CANCEL_OPTION: // Cancel, exit and return false
1037                     return false;
1038                 default:
1039                     break;
1040             }
1041         }
1042
1043         String fileToSave = textPaneAt.getName();
1044         if (fileToSave == null) {
1045             // need a filename, call chooseFileToSave
1046             fileToSave = chooseFileToSave(SciNotesMessages.SAVE);
1047         } else {
1048             // check if the file has been modified by external software
1049             fileToSave = checkExternalModification(fileToSave);
1050         }
1051
1052         if (fileToSave == null || fileToSave.length() == 0) {
1053             return true; /*
1054                           * Bug 5189: The user cancels ==> do not want an error
1055                           * message
1056                           */
1057         }
1058
1059         File newSavedFile = new File(fileToSave);
1060
1061         if (!SaveFile.doSave(textPaneAt, indexTab, newSavedFile, editorKit)) {
1062             return false;
1063         }
1064
1065         ScilabDocument styledDocument = (ScilabDocument) textPaneAt.getDocument();
1066         styledDocument.setContentModified(false);
1067
1068         textPaneAt.setLastModified(newSavedFile.lastModified());
1069
1070         if (textPaneAt.getName() == null) {
1071             String name = getTabPane().getScilabTitleAt(indexTab);
1072             String index = name.substring(name.length() - 1, name.length());
1073             tabList.remove(Integer.valueOf(index));
1074             closedTabList.add(Integer.valueOf(index));
1075         }
1076
1077         textPaneAt.setName(fileToSave);
1078         getTabPane().setTitleAt(indexTab, newSavedFile.getName());
1079
1080         setTitle(textPaneAt.getTitle());
1081         ConfigSciNotesManager.saveToOpenFiles(fileToSave, this, textPaneAt);
1082
1083         return true;
1084     }
1085
1086     /**
1087      * Overwrite the file at a given index.
1088      *
1089      * @param indexTab
1090      *            the textPane index containing the file contents
1091      * @return execution status
1092      */
1093     public boolean overwrite(int indexTab) {
1094         ScilabEditorPane textPaneAt = getTextPane(indexTab);
1095         String fileToSave = textPaneAt.getName();
1096         if (fileToSave == null) {
1097             return true;
1098         }
1099
1100         File newSavedFile = new File(fileToSave);
1101         if (!newSavedFile.exists()) {
1102             return true;
1103         }
1104
1105         if (!SaveFile.doSave(textPaneAt, indexTab, newSavedFile, editorKit)) {
1106             return false;
1107         }
1108
1109         ScilabDocument styledDocument = (ScilabDocument) textPaneAt.getDocument();
1110         styledDocument.setContentModified(false);
1111
1112         getTabPane().setTitleAt(getTabPane().getSelectedIndex(), newSavedFile.getName());
1113
1114         // Get current file path for Execute file into Scilab
1115         getTextPane().setLastModified(newSavedFile.lastModified());
1116
1117         textPaneAt.setName(fileToSave);
1118         setTitle(textPaneAt.getTitle());
1119
1120         return true;
1121     }
1122
1123     /**
1124      * Check for external modification. If it is the case, propose to select a
1125      * new file name.
1126      *
1127      * @param filename
1128      *            The name of the file
1129      * @return the filename where to save
1130      */
1131     public String checkExternalModification(String filename) {
1132         File newSavedFile = new File(filename);
1133         if (newSavedFile.lastModified() > getTextPane().getLastModified()) {
1134             if (ScilabModalDialog.show(this, String.format(SciNotesMessages.EXTERNAL_MODIFICATION, newSavedFile.getPath()),
1135                                        SciNotesMessages.REPLACE_FILE_TITLE, IconType.QUESTION_ICON, ButtonType.YES_NO) == AnswerOption.NO_OPTION) {
1136                 return chooseFileToSave(SciNotesMessages.SAVE);
1137             }
1138         }
1139         return filename;
1140     }
1141
1142     /**
1143      * Return through a file selector the name of the selected file.
1144      *
1145      * @param title
1146      *            the title for JFileChooser
1147      * @return the file picked up by the user
1148      */
1149     public String chooseFileToSave(String title) {
1150         return chooseFileToSave(title, null);
1151     }
1152
1153     /**
1154      * Return through a file selector the name of the selected file.
1155      *
1156      * @param title
1157      *            the title for JFileChooser
1158      * @param path
1159      *            the path where to open the filechooser
1160      * @return the file picked up by the user
1161      */
1162     public String chooseFileToSave(String title, String path) {
1163         String extension = new String();
1164
1165         String initialDirectoryPath = path;
1166         if (initialDirectoryPath == null) {
1167             initialDirectoryPath = getTextPane().getName();
1168         }
1169         if (initialDirectoryPath == null) {
1170             initialDirectoryPath = ConfigManager.getLastOpenedDirectory();
1171         }
1172
1173         SciFileFilter sceFilter = new SciFileFilter(ALL_SCE_FILES, null, 0);
1174         SciFileFilter sciFilter = new SciFileFilter(ALL_SCI_FILES, null, 1);
1175         SciFileFilter scxFilter = new SciFileFilter(ALL_SCX_FILES, null, 2);
1176         SciFileFilter tstFilter = new SciFileFilter(ALL_TST_FILES, null, 3);
1177         SciFileFilter startFilter = new SciFileFilter(ALL_START_FILES, null, 4);
1178         SciFileFilter quitFilter = new SciFileFilter(ALL_QUIT_FILES, null, 5);
1179         SciFileFilter demFilter = new SciFileFilter(ALL_DEM_FILES, null, 6);
1180         SciFileFilter allFilter = new SciFileFilter(ALL_FILES, null, 7);
1181         SciFileFilter allScilabFilter = new SciFileFilter(ALL_SCILAB, null, 8);
1182
1183         SwingScilabFileChooser fileChooser = ((SwingScilabFileChooser) ScilabFileChooser.createFileChooser().getAsSimpleFileChooser());
1184
1185         fileChooser.setInitialDirectory(ConfigManager.getLastOpenedDirectory());
1186         fileChooser.setAcceptAllFileFilterUsed(false);
1187         fileChooser.setInitialDirectory(initialDirectoryPath);
1188         fileChooser.setUiDialogType(Juigetfile.SAVE_DIALOG);
1189
1190         // order is also important here
1191         fileChooser.addChoosableFileFilter(sceFilter);
1192         fileChooser.addChoosableFileFilter(sciFilter);
1193         fileChooser.addChoosableFileFilter(scxFilter);
1194         fileChooser.addChoosableFileFilter(tstFilter);
1195         fileChooser.addChoosableFileFilter(startFilter);
1196         fileChooser.addChoosableFileFilter(quitFilter);
1197         fileChooser.addChoosableFileFilter(demFilter);
1198         fileChooser.addChoosableFileFilter(allFilter);
1199         fileChooser.addChoosableFileFilter(allScilabFilter);
1200
1201         // select default file type
1202         fileChooser.setFileFilter(sceFilter);
1203         fileChooser.setTitle(title);
1204
1205         String name = getTextPane().getName();
1206         if (name == null) {
1207             name = ((ScilabDocument) getTextPane().getDocument()).getFirstFunctionName();
1208             if (name != null) {
1209                 name += SCI_EXTENSION;
1210             }
1211         }
1212
1213         if (name != null) {
1214             fileChooser.setSelectedFile(new File(name));
1215         }
1216
1217         int retval = fileChooser.showSaveDialog(this);
1218
1219         if (retval == JFileChooser.APPROVE_OPTION) {
1220             File f = fileToCanonicalFile(fileChooser.getSelectedFile());
1221             initialDirectoryPath = f.getPath();
1222             if (f.exists()) {
1223                 if (ScilabModalDialog.show(this, SciNotesMessages.REPLACE_FILE_TITLE, SciNotesMessages.FILE_ALREADY_EXIST, IconType.QUESTION_ICON,
1224                                            ButtonType.YES_NO) == AnswerOption.NO_OPTION) {
1225                     return chooseFileToSave(SciNotesMessages.SAVE);
1226                 }
1227             }
1228
1229             /* we test if the file has already a scilab extension */
1230             boolean hasNoExtension = true;
1231
1232             // if the file name is like this : any character , a dot , then
1233             // 2,3or 4 characters, then
1234             // we consider the file has already an extension
1235             // we previously only check for .sci and .sce extension, but what if
1236             // the user open a txt file
1237             String fileName = f.getName();
1238             if (fileName.lastIndexOf(DOT) != -1) {
1239                 if (fileName.substring(fileName.lastIndexOf(DOT), fileName.length()).length() >= 2
1240                         && fileName.substring(fileName.lastIndexOf(DOT), fileName.length()).length() <= 4) {
1241                     hasNoExtension = false;
1242                 }
1243             }
1244
1245             /* if no extension , we add it */
1246             if (hasNoExtension) {
1247                 if (fileChooser.getFileFilter() == sciFilter) {
1248                     extension = SCI_EXTENSION;
1249                 } else if (fileChooser.getFileFilter() == sceFilter) {
1250                     extension = SCE_EXTENSION;
1251                 } else if (fileChooser.getFileFilter() == scxFilter) {
1252                     extension = SCE_EXTENSION;
1253                 } else if (fileChooser.getFileFilter() == tstFilter) {
1254                     extension = TST_EXTENSION;
1255                 } else if (fileChooser.getFileFilter() == startFilter) {
1256                     extension = START_EXTENSION;
1257                 } else if (fileChooser.getFileFilter() == quitFilter) {
1258                     extension = QUIT_EXTENSION;
1259                 } else if (fileChooser.getFileFilter() == demFilter) {
1260                     extension = DEM_EXTENSION;
1261                 } else {
1262                     extension = "";
1263                 }
1264                 return f.getPath() + extension;
1265             }
1266
1267             if (initialDirectoryPath != null) {
1268                 ConfigManager.saveLastOpenedDirectory(initialDirectoryPath);
1269             }
1270
1271             return f.getPath();
1272         } else if (retval == JFileChooser.CANCEL_OPTION) {
1273             return "";
1274         }
1275
1276         return null;
1277     }
1278
1279     /**
1280      * Save a file.
1281      *
1282      * @param path
1283      *            the initial path where the filechooser will be open
1284      * @return execution status
1285      */
1286     public boolean saveAs(String path) {
1287         String filename = chooseFileToSave(SciNotesMessages.SAVE_AS, path);
1288         if (filename == null || filename.length() == 0) {
1289             return true;
1290         }
1291
1292         File f = new File(filename);
1293         ScilabDocument styledDocument = (ScilabDocument) getTextPane().getDocument();
1294
1295         if (!SaveFile.doSave(getTextPane(), getTabPane().getSelectedIndex(), f, editorKit)) {
1296             return false;
1297         }
1298
1299         if (getTextPane().getName() == null) {
1300             String name = getTabPane().getScilabTitleAt(getTabPane().getSelectedIndex());
1301             String index = name.substring(name.length() - 1, name.length());
1302             tabList.remove(Integer.valueOf(index));
1303             closedTabList.add(Integer.valueOf(index));
1304         }
1305
1306         ConfigManager.saveLastOpenedDirectory(f.getPath());
1307         ConfigSciNotesManager.saveToRecentOpenedFiles(f.getPath());
1308         ConfigSciNotesManager.renameOpenFilesItem(f.getPath(), this, getTextPane());
1309         getTextPane().setName(f.getPath());
1310         getTabPane().setTitleAt(getTabPane().getSelectedIndex(), f.getName());
1311         setTitle(getTextPane().getTitle());
1312
1313         RecentFileAction.updateRecentOpenedFilesMenu(this);
1314
1315         if (navigator != null) {
1316             navigator.update(styledDocument);
1317         }
1318
1319         styledDocument.setContentModified(false);
1320         getTextPane().setLastModified(f.lastModified());
1321         getTextPane().setReadOnly(false);
1322         getInfoBar().setText(getTextPane().getInfoBarText());
1323
1324         return true;
1325     }
1326
1327     /**
1328      * Create a new tab in SciNotes.
1329      *
1330      * @param title
1331      *            the title of the tab
1332      * @return the text component inside the tab
1333      */
1334     public ScilabEditorPane addTab(String title) {
1335         return addTab(title, Integer.MAX_VALUE);
1336     }
1337
1338     /**
1339      * Create a new tab in SciNotes.
1340      *
1341      * @param title
1342      *            the title of the tab
1343      * @param index
1344      *            the index where to put the new tab
1345      * @return the text component inside the tab
1346      */
1347     public ScilabEditorPane addTab(String title, int index) {
1348         ScilabEditorPane sep = new ScilabEditorPane(this);
1349         initPane(sep);
1350         int ind = Math.min(Math.max(0, index), tabPane.getTabCount());
1351         tabPane.insertTab(title, null, sep.getEditorComponent(), "", ind);
1352         tabPane.setSelectedIndex(ind);
1353         initInputMap(sep);
1354         updateTabTitle();
1355         getInfoBar().setText(sep.getInfoBarText());
1356         repaint();
1357         sep.init();
1358         return sep;
1359     }
1360
1361     /**
1362      * Init a pane
1363      *
1364      * @param pane
1365      *            the pane to init
1366      */
1367     public void initPane(ScilabEditorPane pane) {
1368         initPane(pane, !SciNotesOptions.getSciNotesDisplay().wrapLines);
1369     }
1370
1371     /**
1372      * Init the EditorPane.
1373      *
1374      * @param pane
1375      *            the EditorPane
1376      * @param plain
1377      *            true for a plain view or false for a wrapped view
1378      */
1379     public void initPane(ScilabEditorPane pane, boolean plain) {
1380         setHighlight(pane);
1381         ScilabEditorKit kit = new ScilabEditorKit(plain);
1382         pane.setEditorKit(kit);
1383
1384         // Panel of line number for the text pane
1385         pane.getXln().setWhereamiLineNumbering(SciNotesOptions.getSciNotesDisplay().showLineNumbers, SciNotesOptions.getSciNotesDisplay().whereami);
1386         activateHelpOnTyping(pane);
1387
1388         pane.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
1389         pane.setFont(kit.getStylePreferences().tokenFonts[0]);
1390
1391         // TODO rajouter ca ds les prefs
1392         pane.setBackground(ConfigSciNotesManager.getSciNotesBackgroundColor());
1393         pane.setCaretColor(ConfigSciNotesManager.getSciNotesForegroundColor());
1394
1395         pane.setFocusable(true);
1396         pane.setRequestFocusEnabled(true);
1397         pane.setDragEnabled(true); /* Bug 5497 */
1398
1399         DropFilesListener dndTarget = new DropFilesListener(pane);
1400
1401         pane.setComponentPopupMenu(SciNotesGUI.generateRightClickPopup(this));
1402     }
1403
1404     /**
1405      * Init the EditorPane with the InputMap found in ConfigSciNotesManager
1406      *
1407      * @param pane
1408      *            the EditorPane
1409      */
1410     public void initInputMap(ScilabEditorPane pane) {
1411         setKeyStrokeAction(pane, this);
1412         LineBeautifierAction.putInInputMap(pane);
1413         InsertOverwriteAction.putInInputMap(pane);
1414     }
1415
1416     /**
1417      * Split the EditorPane
1418      *
1419      * @param vertical
1420      *            true for a vertical split
1421      */
1422     public void splitTab(boolean vertical) {
1423         ScilabEditorPane pane = getTextPane();
1424         Component bottom = pane.getEditorComponent().getBottom();
1425         int state = pane.getXln().getState();
1426         ScilabEditorPane leftPane = new ScilabEditorPane(editor);
1427         ScilabEditorPane rightPane = new ScilabEditorPane(editor);
1428         if (navigator != null) {
1429             navigator.changePaneOnSplit(pane, leftPane);
1430         }
1431         initPane(leftPane, true);
1432         initPane(rightPane, true);
1433         leftPane.setOtherPaneInSplit(rightPane);
1434         rightPane.setOtherPaneInSplit(leftPane);
1435         pane.copyProps(leftPane);
1436         pane.copyProps(rightPane);
1437         ScilabDocument doc = (ScilabDocument) pane.getDocument();
1438         leftPane.setDocument(doc);
1439         rightPane.setDocument(doc);
1440         leftPane.setCaretPosition(0);
1441         rightPane.setCaretPosition(0);
1442         JSplitPane split;
1443         if (vertical) {
1444             split = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
1445         } else {
1446             split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
1447         }
1448         leftPane.getXln().setWhereamiLineNumbering(state);
1449         rightPane.getXln().setWhereamiLineNumbering(state);
1450         split.setLeftComponent(leftPane.getScrollPane());
1451         split.setRightComponent(rightPane.getScrollPane());
1452         split.setResizeWeight(0.5);
1453         rightPane.setEditorComponent(leftPane.getEditorComponent());
1454         leftPane.setSplitPane(split);
1455         rightPane.setSplitPane(split);
1456
1457         activateHelpOnTyping(leftPane);
1458         activateHelpOnTyping(rightPane);
1459         initInputMap(leftPane);
1460         initInputMap(rightPane);
1461         if (doc.getBinary()) {
1462             leftPane.setBinary(true);
1463             rightPane.setBinary(true);
1464         }
1465         getInfoBar().setText(leftPane.getInfoBarText());
1466         updateTabTitle();
1467         tabPane.setComponentAt(tabPane.getSelectedIndex(), leftPane.getEditorComponent());
1468         leftPane.getEditorComponent().insertBottomComponent(bottom);
1469         leftPane.requestFocus();
1470     }
1471
1472     /**
1473      * Remove a split
1474      */
1475     public void removeSplit() {
1476         if (((EditorComponent) tabPane.getSelectedComponent()).isSplited()) {
1477             ScilabEditorPane pane = new ScilabEditorPane(editor);
1478             ScilabEditorPane textpane = getTextPane();
1479             Component bottom = textpane.getEditorComponent().getBottom();
1480             if (navigator != null) {
1481                 navigator.changePaneOnSplit(textpane, pane);
1482             }
1483             initPane(pane);
1484             textpane.setOtherPaneInSplit(null);
1485             textpane.copyProps(pane);
1486             ScilabDocument doc = (ScilabDocument) textpane.getDocument();
1487             pane.setDocument(doc);
1488             pane.setCaretPosition(0);
1489             activateHelpOnTyping(pane);
1490             tabPane.setComponentAt(tabPane.getSelectedIndex(), pane.getEditorComponent());
1491             initInputMap(pane);
1492             if (doc.getBinary()) {
1493                 pane.setBinary(true);
1494             }
1495             getInfoBar().setText(pane.getInfoBarText());
1496             updateTabTitle();
1497             pane.getEditorComponent().insertBottomComponent(bottom);
1498             pane.requestFocus();
1499         }
1500     }
1501
1502     /**
1503      * Create an empty tab inside SciNotes.
1504      *
1505      * @return the text component inside the tab
1506      */
1507     public ScilabEditorPane addEmptyTab() {
1508         ScilabEditorPane sep;
1509         int n = getNumberForEmptyTab();
1510         sep = addTab(SciNotesMessages.UNTITLED + n);
1511         sep.setShortName(SciNotesMessages.UNTITLED + n);
1512         sep.setTitle(SciNotesMessages.UNTITLED + n);
1513         setTitle(sep.getTitle());
1514
1515         return sep;
1516     }
1517
1518     /**
1519      * Get an integer used for untitled document
1520      */
1521     public int getNumberForEmptyTab() {
1522         if (closedTabList.size() > 0) {
1523             Integer n = Collections.min(closedTabList);
1524             closedTabList.remove(n);
1525             return n.intValue();
1526         } else {
1527             numberOfUntitled++;
1528             tabList.add(Integer.valueOf(numberOfUntitled));
1529             return numberOfUntitled;
1530         }
1531     }
1532
1533     /**
1534      * Add or remove '*' prefix in current tab tile according to
1535      * isContentModified().
1536      */
1537     public void updateTabTitle() {
1538         StringBuffer newTitle = new StringBuffer();
1539         ScilabEditorPane currentTextPane = getTextPane();
1540         if (((ScilabDocument) currentTextPane.getDocument()).isContentModified()) {
1541             newTitle.append('*');
1542         }
1543
1544         String textPaneName = currentTextPane.getName();
1545         try {
1546             File f = new File(textPaneName);
1547             newTitle.append(f.getName());
1548         } catch (NullPointerException e) { // not a file name, no path prefix to
1549             // remove, but maybe a '*'
1550             textPaneName = getTabPane().getScilabTitleAt(getTabPane().getSelectedIndex());
1551             if (textPaneName.charAt(0) == '*') {
1552                 newTitle.append(textPaneName.substring(1, textPaneName.length()));
1553             } else {
1554                 newTitle.append(textPaneName);
1555             }
1556         }
1557         getTabPane().setTitleAt(getTabPane().getSelectedIndex(), newTitle.toString());
1558     }
1559
1560     /**
1561      * @param button
1562      *            the UndoButton used in this editor
1563      */
1564     public void setUndoButton(PushButton button) {
1565         undoButton = button;
1566         enableUndoButton(false);
1567     }
1568
1569     /**
1570      * @param b
1571      *            true to enable the button
1572      */
1573     public void enableUndoButton(boolean b) {
1574         if (undoButton != null) {
1575             undoButton.setEnabled(b);
1576         }
1577     }
1578
1579     /**
1580      * Undo last modification.
1581      */
1582     public void undo() {
1583         ScilabDocument doc = (ScilabDocument) getTextPane().getDocument();
1584         synchronized (doc) {
1585             doc.getUndoManager().undo();
1586         }
1587     }
1588
1589     /**
1590      * @param button
1591      *            the RedoButton used in this editor
1592      */
1593     public void setRedoButton(PushButton button) {
1594         redoButton = button;
1595         enableRedoButton(false);
1596     }
1597
1598     /**
1599      * @param b
1600      *            true to enable the button
1601      */
1602     public void enableRedoButton(boolean b) {
1603         if (redoButton != null) {
1604             redoButton.setEnabled(b);
1605         }
1606     }
1607
1608     /**
1609      * Redo last modification.
1610      */
1611     public void redo() {
1612         ScilabDocument doc = (ScilabDocument) getTextPane().getDocument();
1613         synchronized (doc) {
1614             doc.getUndoManager().redo();
1615         }
1616     }
1617
1618     /**
1619      * Reload a file inside SciNotes.
1620      *
1621      * @param index
1622      *            the index
1623      */
1624     public void reload(int index) {
1625         ScilabEditorPane textPaneAt = getTextPane(index);
1626         if (textPaneAt.getName() != null) {
1627             if ((index == 0) && (getTabPane().getTabCount() == 1)) {
1628                 for (int j = 0; j < tabPane.getChangeListeners().length; j++) {
1629                     tabPane.removeChangeListener(tabPane.getChangeListeners()[j]);
1630                 }
1631             }
1632             ConfigSciNotesManager.removeFromOpenFiles(this, textPaneAt);
1633             tabPane.remove(index);
1634             File f = new File(textPaneAt.getName());
1635             if (f.exists()) {
1636                 loadFile(f, index);
1637             } else {
1638                 createNewFile(f);
1639             }
1640         }
1641     }
1642
1643     /**
1644      * Load a file inside SciNotes.
1645      *
1646      * @param f
1647      *            the file to open
1648      */
1649     public void readFile(File f) {
1650         /** Is this file already opened */
1651         boolean alreadyOpened = false;
1652         for (int i = 0; i < tabPane.getTabCount(); i++) {
1653             ScilabEditorPane textPaneAt = getTextPane(i);
1654             if (f.getAbsolutePath().equals(textPaneAt.getName())) {
1655                 /* File is already opnened */
1656                 tabPane.setSelectedIndex(i);
1657                 alreadyOpened = true;
1658                 break;
1659             }
1660         }
1661
1662         if (!alreadyOpened) {
1663             if (f.exists()) {
1664                 loadFile(f);
1665             } else {
1666                 createNewFile(f);
1667             }
1668         }
1669     }
1670
1671     /**
1672      * Load a file inside SciNotes.
1673      *
1674      * @param file
1675      *            the file to open
1676      */
1677     public void readFileAndWait(File file) {
1678         /** Is this file already opened */
1679         File f = file;
1680         boolean alreadyOpened = false;
1681         int index = -1;
1682         for (int i = 0; i < tabPane.getTabCount(); i++) {
1683             ScilabEditorPane textPaneAt = getTextPane(i);
1684             if (f.getAbsolutePath().equals(textPaneAt.getName())) {
1685                 /* File is already opened */
1686                 tabPane.setSelectedIndex(i);
1687                 if (f.lastModified() > textPaneAt.getLastModified()) {
1688
1689                     /*
1690                      * Create a new messagebox to know what the user wants to do
1691                      * if the file has been modified outside SciNotes
1692                      */
1693                     MessageBox messageBox = ScilabMessageBox.createMessageBox();
1694                     messageBox.setTitle(SciNotesMessages.REPLACE_FILE_TITLE);
1695                     messageBox.setMessage(String.format(SciNotesMessages.EXTERNAL_MODIFICATION, textPaneAt.getName()));
1696
1697                     String[] labels = new String[] { SciNotesMessages.RELOAD, SciNotesMessages.OVERWRITE, SciNotesMessages.IGNORE };
1698                     messageBox.setButtonsLabels(labels);
1699
1700                     messageBox.setIcon("question"); // Question icon
1701
1702                     messageBox.setParentForLocation(this); // Centered on
1703                     // SciNotes main
1704                     // window
1705
1706                     messageBox.displayAndWait(); // Waits for a user action
1707
1708                     switch (messageBox.getSelectedButton()) {
1709                         case 1: // Reload
1710                             if ((i == 0) && (getTabPane().getTabCount() == 1)) {
1711                                 for (int j = 0; j < tabPane.getChangeListeners().length; j++) {
1712                                     tabPane.removeChangeListener(tabPane.getChangeListeners()[j]);
1713                                 }
1714                             }
1715                             tabPane.remove(i);
1716                             f = new File(textPaneAt.getName());
1717                             index = i;
1718                             break;
1719                         case 2: // Overwrite 2
1720                             overwrite(i);
1721                             alreadyOpened = true;
1722                             break;
1723                         default: // Ignore
1724                             alreadyOpened = true;
1725                     }
1726                 } else {
1727                     alreadyOpened = true;
1728                 }
1729                 break;
1730             }
1731         }
1732
1733         if (!alreadyOpened) {
1734             if (f.exists()) {
1735                 loadFile(f, index);
1736             } else {
1737                 createNewFile(f);
1738             }
1739         }
1740     }
1741
1742     /**
1743      * Get current text component. If the window is splitted, then return the
1744      * focused text component.
1745      *
1746      * @return the text component
1747      */
1748     public ScilabEditorPane getTextPane() {
1749         try {
1750             EditorComponent c = (EditorComponent) tabPane.getSelectedComponent();
1751             return c.getEditorPane();
1752         } catch (NullPointerException e) {
1753             return null;
1754         } catch (ArrayIndexOutOfBoundsException e) {
1755             return null;
1756         }
1757     }
1758
1759     /**
1760      * Get text component at index.
1761      *
1762      * @param index
1763      *            the index of the textpane
1764      * @return the text component
1765      */
1766     public ScilabEditorPane getTextPane(int index) {
1767         try {
1768             EditorComponent c = (EditorComponent) tabPane.getComponentAt(index);
1769             return c.getEditorPane();
1770         } catch (NullPointerException e) {
1771             return null;
1772         } catch (ArrayIndexOutOfBoundsException e) {
1773             return null;
1774         }
1775     }
1776
1777     /**
1778      * Set the keystroke actions
1779      */
1780     public static void setAllMenus() {
1781         for (SciNotes ed : scinotesList) {
1782             SciNotesGUI.reinitMenus(ed);
1783             int n = ed.getTabPane().getTabCount();
1784             for (int i = 0; i < n; i++) {
1785                 ScilabEditorPane sep = ed.getTextPane(i);
1786                 sep.setComponentPopupMenu(SciNotesGUI.generateRightClickPopup(ed));
1787                 if (sep.getOtherPaneInSplit() != null) {
1788                     sep.getOtherPaneInSplit().setComponentPopupMenu(SciNotesGUI.generateRightClickPopup(ed));
1789                 }
1790             }
1791         }
1792     }
1793
1794     /**
1795      * Set the keystroke actions
1796      */
1797     public static void setKeyStrokeActions() {
1798         for (SciNotes ed : scinotesList) {
1799             int n = ed.getTabPane().getTabCount();
1800             for (int i = 0; i < n; i++) {
1801                 ScilabEditorPane sep = ed.getTextPane(i);
1802                 ed.initInputMap(sep);
1803                 if (sep.getOtherPaneInSplit() != null) {
1804                     ed.initInputMap(sep.getOtherPaneInSplit());
1805                 }
1806             }
1807         }
1808     }
1809
1810     /**
1811      * Enable the whereami-line numbering
1812      *
1813      * @param state
1814      *            int
1815      */
1816     public static void setWhereamiLineNumbering() {
1817         for (SciNotes ed : scinotesList) {
1818             int n = ed.getTabPane().getTabCount();
1819             for (int i = 0; i < n; i++) {
1820                 ScilabEditorPane sep = ed.getTextPane(i);
1821                 sep.getXln().setWhereamiLineNumbering(SciNotesOptions.getSciNotesDisplay().showLineNumbers, SciNotesOptions.getSciNotesDisplay().whereami);
1822                 if (sep.getOtherPaneInSplit() != null) {
1823                     sep.getOtherPaneInSplit().getXln().setWhereamiLineNumbering(SciNotesOptions.getSciNotesDisplay().showLineNumbers, SciNotesOptions.getSciNotesDisplay().whereami);
1824                 }
1825             }
1826             ed.repaint();
1827         }
1828     }
1829
1830     /**
1831      * Auto-indent mode management
1832      *
1833      * @param b
1834      *            true to activate auto-indent mode
1835      */
1836     public static void setAutoIndent() {
1837         for (SciNotes ed : scinotesList) {
1838             int n = ed.getTabPane().getTabCount();
1839             for (int i = 0; i < n; i++) {
1840                 ScilabEditorPane sep = ed.getTextPane(i);
1841                 ((ScilabDocument) sep.getDocument()).setAutoIndent(SciNotesOptions.getSciNotesDisplay().automaticIndent);
1842                 if (sep.getOtherPaneInSplit() != null) {
1843                     ((ScilabDocument) sep.getOtherPaneInSplit().getDocument()).setAutoIndent(SciNotesOptions.getSciNotesDisplay().automaticIndent);
1844                 }
1845             }
1846         }
1847     }
1848
1849     /**
1850      * Auto-indent mode management
1851      *
1852      * @param b
1853      *            true to activate auto-indent mode
1854      */
1855     public static void setSuppressComments(boolean b) {
1856         for (SciNotes ed : scinotesList) {
1857             int n = ed.getTabPane().getTabCount();
1858             for (int i = 0; i < n; i++) {
1859                 ScilabEditorPane sep = ed.getTextPane(i);
1860                 sep.suppressCommentsInExecutingCode(b);
1861                 if (sep.getOtherPaneInSplit() != null) {
1862                     sep.getOtherPaneInSplit().suppressCommentsInExecutingCode(b);
1863                 }
1864             }
1865         }
1866     }
1867
1868     /**
1869      * Horizontal Wrap mode management
1870      *
1871      * @param b
1872      *            true to activate horizontal wrapping mode
1873      */
1874     public static void setHorizontalWrap() {
1875         if (SciNotesOptions.getSciNotesDisplay().wrapLines != mustWrapLines) {
1876             mustWrapLines = SciNotesOptions.getSciNotesDisplay().wrapLines;
1877             for (SciNotes ed : scinotesList) {
1878                 int n = ed.getTabPane().getTabCount();
1879                 for (int i = 0; i < n; i++) {
1880                     ScilabEditorPane sep = ed.getTextPane(i);
1881                     if (sep.getOtherPaneInSplit() == null) {
1882                         ScilabEditorPane pane = new ScilabEditorPane(editor);
1883                         ed.initPane(pane, !mustWrapLines);
1884                         sep.copyProps(pane);
1885                         pane.setDocument(sep.getDocument());
1886                         pane.setCaretPosition(sep.getCaretPosition());
1887                         pane.getXln().setWhereamiLineNumbering(SciNotesOptions.getSciNotesDisplay().showLineNumbers, SciNotesOptions.getSciNotesDisplay().whereami);
1888                         ed.tabPane.setComponentAt(i, pane.getEditorComponent());
1889                         ed.activateHelpOnTyping(pane);
1890                         ed.initInputMap(pane);
1891                         if (((ScilabDocument) sep.getDocument()).getBinary()) {
1892                             pane.setBinary(true);
1893                         }
1894                         ed.getInfoBar().setText(pane.getInfoBarText());
1895                     }
1896                 }
1897             }
1898         }
1899     }
1900
1901     /**
1902      * Set a line numbering compatible with the whereami function
1903      * @param state 0 for nothing, 1 for normal and 2 for whereami
1904      */
1905
1906     /**
1907      * Enable the highlighted line in this editor
1908      *
1909      * @param b
1910      *            boolean
1911      */
1912     public static void enableHighlightedLine(boolean b) {
1913         for (SciNotes ed : scinotesList) {
1914             int n = ed.getTabPane().getTabCount();
1915             for (int i = 0; i < n; i++) {
1916                 ScilabEditorPane sep = ed.getTextPane(i);
1917                 sep.enableHighlightedLine(SciNotesOptions.getSciNotesDisplay().highlightCurrentLine);
1918                 if (sep.getOtherPaneInSplit() != null) {
1919                     sep.getOtherPaneInSplit().enableHighlightedLine(SciNotesOptions.getSciNotesDisplay().highlightCurrentLine);
1920                 }
1921             }
1922         }
1923     }
1924
1925     /**
1926      * Enable the help on typing in the current textPane
1927      *
1928      * @param pane
1929      *            the pane
1930      */
1931     public static void activateHelpOnTyping(ScilabEditorPane pane) {
1932         pane.activateHelpOnTyping();
1933     }
1934
1935     /**
1936      * Enable the help on typing in this editor
1937      */
1938     public static void activateHelpOnTyping() {
1939         for (SciNotes ed : scinotesList) {
1940             int n = ed.getTabPane().getTabCount();
1941             for (int i = 0; i < n; i++) {
1942                 ScilabEditorPane sep = ed.getTextPane(i);
1943                 sep.activateHelpOnTyping();
1944                 if (sep.getOtherPaneInSplit() != null) {
1945                     sep.getOtherPaneInSplit().activateHelpOnTyping();
1946                 }
1947             }
1948         }
1949     }
1950
1951     /**
1952      * Set the color of the highlighted line in this editor
1953      *
1954      * @param c
1955      *            Color
1956      */
1957     public static void setDefaultTabulation() {
1958         TabManager.Tabulation tab = new TabManager.Tabulation();
1959         for (SciNotes ed : scinotesList) {
1960             int n = ed.getTabPane().getTabCount();
1961             for (int i = 0; i < n; i++) {
1962                 ScilabEditorPane sep = ed.getTextPane(i);
1963                 sep.getTabManager().setTabulation(tab);
1964                 View view = ((ScilabDocument) sep.getDocument()).getView();
1965                 if (view != null) {
1966                     if (view instanceof ScilabView) {
1967                         ((ScilabView) view).setTabRepresentation(tab);
1968                         ((ScilabView) view).reinitialize();
1969                     } else {
1970                         ((ScilabPlainView) view).setTabRepresentation(tab);
1971                         ((ScilabPlainView) view).reinitialize();
1972                     }
1973                 }
1974             }
1975         }
1976     }
1977
1978     /**
1979      * Set the color of the highlighted line in this editor
1980      *
1981      * @param c
1982      *            Color
1983      */
1984     public static void updatePanes(SciNotesConfiguration.Conf conf) {
1985         for (SciNotes ed : scinotesList) {
1986             int n = ed.getTabPane().getTabCount();
1987             for (int i = 0; i < n; i++) {
1988                 ScilabEditorPane sep = ed.getTextPane(i);
1989                 sep.configurationChanged(conf);
1990                 if (sep.getOtherPaneInSplit() != null) {
1991                     sep.getOtherPaneInSplit().configurationChanged(conf);
1992                 }
1993                 sep.repaint();
1994             }
1995         }
1996     }
1997
1998     /**
1999      * Set the color of the highlighted line in this editor
2000      *
2001      * @param c
2002      *            Color
2003      */
2004     public static void setHighlightedLineColor() {
2005         for (SciNotes ed : scinotesList) {
2006             int n = ed.getTabPane().getTabCount();
2007             for (int i = 0; i < n; i++) {
2008                 ScilabEditorPane sep = ed.getTextPane(i);
2009                 sep.setHighlightedLineColor(SciNotesOptions.getSciNotesDisplay().currentLineColor);
2010                 if (sep.getOtherPaneInSplit() != null) {
2011                     sep.getOtherPaneInSplit().setHighlightedLineColor(SciNotesOptions.getSciNotesDisplay().currentLineColor);
2012                 }
2013             }
2014         }
2015     }
2016
2017     /**
2018      * Set the color of the contour of the highlighted line in this editor
2019      *
2020      * @param c
2021      *            Color
2022      */
2023     public static void setHighlightedContourColor() {
2024         for (SciNotes ed : scinotesList) {
2025             int n = ed.getTabPane().getTabCount();
2026             for (int i = 0; i < n; i++) {
2027                 ScilabEditorPane sep = ed.getTextPane(i);
2028                 sep.setHighlightedContourColor(null);
2029                 if (sep.getOtherPaneInSplit() != null) {
2030                     sep.getOtherPaneInSplit().setHighlightedContourColor(null);
2031                 }
2032             }
2033         }
2034     }
2035
2036     /**
2037      * Set the highlighted line in this textPane
2038      *
2039      * @param sep
2040      *            ScilabEditorPane
2041      */
2042     public static void setHighlight(ScilabEditorPane sep) {
2043         sep.enableHighlightedLine(SciNotesOptions.getSciNotesDisplay().highlightCurrentLine);
2044         sep.setHighlightedLineColor(SciNotesOptions.getSciNotesDisplay().currentLineColor);
2045         sep.setHighlightedContourColor(null);
2046     }
2047
2048     /**
2049      * Get SciNotes as a Tab.
2050      *
2051      * @return SciNotes instance
2052      * @see org.scilab.modules.gui.tab.Tab#getAsSimpleTab()
2053      */
2054     public SimpleTab getAsSimpleTab() {
2055         return this;
2056     }
2057
2058     /**
2059      * Get SciNotes parent Window.
2060      *
2061      * @return parent Window
2062      * @see org.scilab.modules.gui.tab.Tab#getParentWindow()
2063      */
2064     public SwingScilabWindow getParentWindow() {
2065         return parentWindow;
2066     }
2067
2068     /**
2069      * Get the UUID associated with the editor instance.
2070      *
2071      * @return unique identifier
2072      */
2073     public UUID getUUID() {
2074         return uuid;
2075     }
2076
2077     /**
2078      * Add a status bar to SciNotes.
2079      *
2080      * @param infoBarToAdd
2081      *            the status bar to be added
2082      * @see org.scilab.modules.gui.uielement.UIElement#addInfoBar(org.scilab.modules.gui.textbox.TextBox)
2083      */
2084     public void addInfoBar(TextBox infoBarToAdd) {
2085         setInfoBar(infoBarToAdd);
2086     }
2087
2088     /**
2089      * Add a menu bar to SciNotes.
2090      *
2091      * @param menuBarToAdd
2092      *            the menu bar to be added
2093      * @see org.scilab.modules.gui.uielement.UIElement#addMenuBar(org.scilab.modules.gui.menubar.MenuBar)
2094      */
2095     public void addMenuBar(MenuBar menuBarToAdd) {
2096         setMenuBar(menuBarToAdd);
2097     }
2098
2099     /**
2100      * Add a tool bar to SciNotes.
2101      *
2102      * @param toolBarToAdd
2103      *            the tool bar to be added
2104      * @see org.scilab.modules.gui.uielement.UIElement#addToolBar(org.scilab.modules.gui.toolbar.ToolBar)
2105      */
2106     public void addToolBar(ToolBar toolBarToAdd) {
2107         setToolBar(toolBarToAdd);
2108     }
2109
2110     /**
2111      * Get SciNotes main ScilabTabbedPane.
2112      *
2113      * @return SciNotes main ScilabTabbedPane
2114      */
2115     public ScilabTabbedPane getTabPane() {
2116         return tabPane;
2117     }
2118
2119     /**
2120      * Set SciNotes main ScilabTabbedPane.
2121      *
2122      * @param tabPane
2123      *            SciNotes main ScilabTabbedPane
2124      */
2125     public void setTabPane(ScilabTabbedPane tabPane) {
2126         this.tabPane = tabPane;
2127     }
2128
2129     /**
2130      * Load a file and add it at the end
2131      *
2132      * @param f
2133      *            the file to load
2134      */
2135     public void loadFile(File f) {
2136         loadFile(f, -1);
2137     }
2138
2139     /**
2140      * Load a file and add it at the index
2141      *
2142      * @param f
2143      *            the file to load
2144      * @param index
2145      *            the index where to put the file
2146      */
2147     public void loadFile(File f, int index) {
2148         ScilabDocument styleDocument = null;
2149         ScilabEditorPane theTextPane;
2150
2151         // File exist
2152         if (f.exists()) {
2153             if (!f.canRead()) {
2154                 ScilabModalDialog.show(this, SciNotesMessages.NOTREADABLE, SciNotesMessages.SCINOTES_ERROR, IconType.ERROR_ICON);
2155                 if (getTabPane().getTabCount() == 0) {
2156                     addEmptyTab();
2157                 }
2158                 return;
2159             }
2160
2161             getInfoBar().setText(SciNotesMessages.LOADING);
2162
2163             if (index != -1) {
2164                 theTextPane = addTab(f.getName(), index);
2165             } else {
2166                 theTextPane = addTab(f.getName());
2167             }
2168             styleDocument = (ScilabDocument) theTextPane.getDocument();
2169             styleDocument.disableUndoManager();
2170             theTextPane.setLastModified(f.lastModified());
2171
2172             try {
2173                 styleDocument.setUpdater(false);
2174                 boolean indentMode = styleDocument.getAutoIndent();
2175                 styleDocument.setAutoIndent(false);
2176                 try {
2177                     ((ScilabEditorKit) editorKit).read(this, f, styleDocument, 0);
2178                 } catch (BadLocationException e) {
2179                     e.printStackTrace();
2180                 }
2181                 styleDocument.setAutoIndent(indentMode);
2182                 styleDocument.setUpdater(true);
2183             } catch (IOException ioex) {
2184                 ioex.printStackTrace();
2185             }
2186
2187             theTextPane.setName(f.getAbsolutePath());
2188             getTabPane().setTitleAt(getTabPane().getSelectedIndex(), f.getName());
2189             setTitle(theTextPane.getTitle());
2190             styleDocument.setContentModified(false);
2191             styleDocument.enableUndoManager();
2192
2193             if (styleDocument.getBinary()) {
2194                 theTextPane.setBinary(true);
2195             }
2196
2197             if (!f.canWrite()) {
2198                 getTextPane().setReadOnly(true);
2199                 JOptionPane.showMessageDialog(SciNotes.this, SciNotesMessages.READONLY);
2200             }
2201
2202             getInfoBar().setText(theTextPane.getInfoBarText());
2203
2204             EncodingAction.updateEncodingMenu((ScilabDocument) getTextPane().getDocument());
2205
2206             ConfigManager.saveLastOpenedDirectory(f.getPath());
2207             ConfigSciNotesManager.saveToRecentOpenedFiles(f.getPath());
2208             ConfigSciNotesManager.saveToOpenFiles(f.getPath(), this, getTextPane());
2209
2210             // Empty the undo Manager
2211             UndoManager undo = ((ScilabDocument) getTextPane().getDocument()).getUndoManager();
2212             undo.discardAllEdits();
2213
2214             if (getTabPane().getTabCount() == 2) {
2215                 ScilabEditorPane pane = getTextPane(0);
2216                 if (pane.getName() == null && !((ScilabDocument) pane.getDocument()).isContentModified()) {
2217                     closeTabAt(0);
2218                 }
2219             }
2220         }
2221     }
2222
2223     /**
2224      * Creates a file if it doesn't exist
2225      *
2226      * @param f
2227      *            the file to create
2228      */
2229     public void createNewFile(File f) {
2230         ScilabEditorPane theTextPane = addEmptyTab();
2231         ScilabDocument styleDocument = null;
2232         int choice = JOptionPane.showConfirmDialog(SciNotes.this, String.format(SciNotesMessages.FILE_DOESNT_EXIST, f.getName()), SCINOTES,
2233                      JOptionPane.YES_NO_OPTION);
2234         if (choice == 0) { // OK
2235             styleDocument = (ScilabDocument) theTextPane.getDocument();
2236             styleDocument.disableUndoManager();
2237
2238             BufferedWriter bw = null;
2239             OutputStreamWriter osw = null;
2240             FileOutputStream fos = null;
2241
2242             try {
2243                 fos = new FileOutputStream(f);
2244                 osw = new OutputStreamWriter(fos, styleDocument.getEncoding());
2245                 bw = new BufferedWriter(osw);
2246                 editorKit.write(bw, styleDocument, 0, styleDocument.getLength());
2247                 bw.flush();
2248             } catch (IOException e) {
2249                 System.err.println(e);
2250             } catch (BadLocationException e) {
2251                 System.err.println(e);
2252             } finally {
2253                 try {
2254                     if (fos != null) {
2255                         fos.close();
2256                     }
2257                     if (osw != null) {
2258                         osw.close();
2259                     }
2260                     if (bw != null) {
2261                         bw.close();
2262                     }
2263                 } catch (IOException e) {
2264                     System.err.println(e);
2265                 }
2266             }
2267
2268             ConfigManager.saveLastOpenedDirectory(f.getPath());
2269             ConfigSciNotesManager.saveToRecentOpenedFiles(f.getPath());
2270             ConfigSciNotesManager.saveToOpenFiles(theTextPane.getName(), this, theTextPane);
2271
2272             theTextPane.setName(f.getPath());
2273             getTabPane().setTitleAt(getTabPane().getSelectedIndex(), f.getName());
2274             setTitle(theTextPane.getTitle());
2275             RecentFileAction.updateRecentOpenedFilesMenu(this);
2276
2277             styleDocument.setContentModified(false);
2278             styleDocument.enableUndoManager();
2279             theTextPane.setLastModified(f.lastModified());
2280         }
2281
2282         getInfoBar().setText("");
2283     }
2284
2285     /**
2286      * EditorKit Getter
2287      *
2288      * @return EditorKit
2289      */
2290     public EditorKit getEditorKit() {
2291         return editorKit;
2292     }
2293
2294     /**
2295      * @param scinotes
2296      *            the focused editor
2297      */
2298     public static void setEditor(SciNotes scinotes) {
2299         editor = scinotes;
2300     }
2301
2302     /**
2303      * @return the focused editor
2304      */
2305     public static SciNotes getEditor() {
2306         return editor;
2307     }
2308
2309     /**
2310      * EditorKit Setter
2311      *
2312      * @param editorKit
2313      *            EditorKit
2314      */
2315     public void setEditorKit(EditorKit editorKit) {
2316         this.editorKit = editorKit;
2317     }
2318
2319     /**
2320      * Close scinotes from scilab.
2321      *
2322      * This method can be called outside the EDT thread.
2323      */
2324     public static void closeSciNotesFromScilab() {
2325         try {
2326             SwingUtilities.invokeAndWait(new Runnable() {
2327
2328                 @Override
2329                 public void run() {
2330                     SciNotes[] arr = scinotesList.toArray(new SciNotes[0]);
2331                     for (int i = 0; i < arr.length; i++) {
2332                         arr[i].setProtectOpenFileList(true);
2333                         ExitAction.doExit(arr[i]);
2334                     }
2335                     scinotesList.clear();
2336                 }
2337             });
2338         } catch (InterruptedException e) {
2339             Logger.getLogger(SciNotes.class.getName()).severe(e.toString());
2340         } catch (InvocationTargetException e) {
2341             Logger.getLogger(SciNotes.class.getName()).severe(e.toString());
2342         }
2343     }
2344
2345     /**
2346      * @param f
2347      *            the file
2348      * @return the canonical file if possible
2349      */
2350     public static File fileToCanonicalFile(File f) {
2351         /* Fix bug 5648 */
2352         try {
2353             return f.getCanonicalFile();
2354         } catch (IOException e) {
2355             return f;
2356         }
2357     }
2358
2359     /**
2360      * Set the shortcuts in the pane relatively to the file
2361      * keysConfiguration.xml
2362      *
2363      * @param sep
2364      *            the textpane
2365      * @param ed
2366      *            the SciNotes editor
2367      */
2368     private static void setKeyStrokeAction(ScilabEditorPane sep, SciNotes ed) {
2369         if (ed.getTextPane(0) != sep) {
2370             ScilabEditorPane s = ed.getTextPane(0);
2371             sep.setInputMap(JComponent.WHEN_FOCUSED, s.getInputMap());
2372             return;
2373         }
2374
2375         Map<String, KeyStroke> map = getActionKeys();
2376
2377         ClassLoader loader = ClassLoader.getSystemClassLoader();
2378         Iterator<String> iter = map.keySet().iterator();
2379         while (iter.hasNext()) {
2380             String actionName = iter.next();
2381             KeyStroke key = map.get(actionName);
2382             String action = actionToName.get(actionName);
2383             if (key != null) {
2384                 if (!action.equals("SciNotesCompletionAction")) {
2385                     String className;
2386                     if (action.lastIndexOf(DOT) != -1) {
2387                         className = action;
2388                     } else {
2389                         className = DEFAULTACTIONPATH + DOT + action;
2390                     }
2391                     try {
2392                         Class clazz = loader.loadClass(className);
2393                         Constructor constructor = clazz.getConstructor(new Class[] { String.class, SciNotes.class });
2394                         Object act = constructor.newInstance(new Object[] { "", ed });
2395                         sep.getInputMap().put(key, act);
2396                     } catch (ClassNotFoundException e) {
2397                         System.err.println("No action: " + className);
2398                     } catch (InstantiationException e) {
2399                         System.err.println("Problem to instantiate in action: " + className);
2400                     } catch (NoSuchMethodException e) {
2401                         System.err.println("No valid constructor in action: " + className);
2402                     } catch (IllegalAccessException e) {
2403                         System.err.println("The constructor must be public: " + className);
2404                     } catch (InvocationTargetException e) {
2405                         System.err.println("The constructor in " + className + " threw an exception :");
2406                         e.printStackTrace();
2407                     }
2408                 } else {
2409                     sep.getInputMap().put(key, new SciNotesCompletionAction(sep, ed));
2410                 }
2411             }
2412         }
2413     }
2414 }