2 * Scilab (http://www.scilab.org/) - This file is part of Scilab
3 * Copyright (C) 2009 - INRIA - Allan SIMON
4 * Copyright (C) 2010 - Calixte DENIZET
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.1-en.txt
14 package org.scilab.modules.scinotes.utils;
16 import java.awt.Color;
18 import java.awt.Toolkit;
19 import java.awt.print.Paper;
22 import java.io.FileInputStream;
23 import java.io.FileNotFoundException;
24 import java.io.FileOutputStream;
25 import java.io.IOException;
26 import java.nio.charset.Charset;
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.List;
30 import java.util.Hashtable;
31 import java.util.Properties;
32 import java.util.Enumeration;
34 import java.util.UUID;
36 import javax.xml.parsers.DocumentBuilder;
37 import javax.xml.parsers.DocumentBuilderFactory;
38 import javax.xml.parsers.ParserConfigurationException;
39 import javax.xml.transform.OutputKeys;
40 import javax.xml.transform.Transformer;
41 import javax.xml.transform.TransformerConfigurationException;
42 import javax.xml.transform.TransformerException;
43 import javax.xml.transform.TransformerFactoryConfigurationError;
44 import javax.xml.transform.dom.DOMSource;
45 import javax.xml.transform.stream.StreamResult;
47 import org.scilab.modules.commons.ScilabCommons;
48 import org.scilab.modules.commons.ScilabConstants;
49 import org.scilab.modules.commons.ScilabCommonsUtils;
50 import org.scilab.modules.commons.xml.ScilabXMLUtilities;
51 import org.scilab.modules.commons.xml.ScilabDocumentBuilderFactory;
52 import org.scilab.modules.commons.xml.ScilabTransformerFactory;
53 import org.scilab.modules.gui.messagebox.ScilabModalDialog;
54 import org.scilab.modules.gui.messagebox.ScilabModalDialog.IconType;
55 import org.scilab.modules.gui.utils.Position;
56 import org.scilab.modules.gui.utils.Size;
58 import org.scilab.modules.scinotes.ScilabView;
59 import org.scilab.modules.scinotes.ScilabEditorPane;
60 import org.scilab.modules.scinotes.SciNotes;
61 import org.scilab.modules.scinotes.TabManager;
62 import org.scilab.modules.scinotes.MatchingBlockManager;
64 import org.w3c.dom.Document;
65 import org.w3c.dom.Element;
66 import org.w3c.dom.Node;
67 import org.w3c.dom.NodeList;
68 import org.w3c.dom.Text;
69 import org.xml.sax.SAXException;
72 * Configuration class which interacts with the file etc/scinotesConfiguration.xml
74 public final class ConfigSciNotesManager {
76 public static final String RECENTBASEDIR = "recentBaseDir";
77 public static final String BASEDIR = "baseDir";
78 public static final String RECENTFILEPATTERN = "recentFilePattern";
79 public static final String FILEPATTERN = "filePattern";
80 public static final String RECENTWORDPATTERN = "recentWordPattern";
81 public static final String WORDPATTERN = "wordPattern";
83 private static final int BUFSIZE = 1024;
85 private static final int MARGIN = 20;
87 private static final String ERROR_READ = "Could not load file: ";
88 private static final String ERROR_WRITE = "Could not save file: ";
89 private static final String VALUE = "value";
90 private static final String VERSION = "version";
91 private static final String STYLE = "style";
92 private static final String UNDERLINE = "underline";
93 private static final String DEFAULTUNDERLINE = "defaultUnderline";
94 private static final String STROKE = "stroke";
95 private static final String DEFAULTSTROKE = "defaultStroke";
96 private static final String FONT_SIZE = "FontSize";
97 private static final String FONT_STYLE = "FontStyle";
98 private static final String FONT_NAME = "FontName";
99 private static final String DEFAULT = "default";
100 private static final String WIDTH = "width";
101 private static final String HEIGHT = "height";
102 private static final String XCOORD = "x";
103 private static final String YCOORD = "y";
104 private static final String MAINWINPOSITION = "MainWindowPosition";
105 private static final String MAINWINSIZE = "MainWindowSize";
106 private static final String AUTOINDENT = "AutoIndent";
107 private static final String DEFAULTENCONDING = "DefaultEncoding";
108 private static final String LINEHIGHLIGHTER = "LineHighlighter";
109 private static final String HELPONTYPING = "HelpOnTyping";
110 private static final String LINENUMBERING = "LineNumbering";
111 private static final String EDITOR = "SciNotes";
113 private static final String FOREGROUNDCOLOR = "ForegroundColor";
114 private static final String BACKGROUNDCOLOR = "BackgroundColor";
115 private static final String ALTERNCOLORS = "AlternColors";
116 private static final String COLOR1 = "color1";
117 private static final String COLOR2 = "color2";
118 private static final String LINECOLOR = "linecolor";
119 private static final String CONTOURCOLOR = "contourcolor";
120 private static final String COLORPREFIX = "#";
122 private static final String NAME = "name";
123 private static final String NULL = "null";
125 private static final String PROFILE = "Profile";
127 private static final String RECENT_SEARCH = "recentSearch";
128 private static final String SEARCH = "search";
129 private static final String RECENT_REPLACE = "recentReplace";
130 private static final String REPLACE = "replace";
131 private static final String RECURSIVE = "recursiveSearch";
132 private static final String LINEBYLINE = "readLineByLine";
133 private static final String FILECASE = "fileCase";
134 private static final String SEARCHINFILES = "searchInFiles";
136 private static final String EXPRESSION = "exp";
137 private static final String REGULAR_EXPRESION = "regularExp";
138 private static final String CIRCULAR = "circularSearch";
139 private static final String WORD_WARP = "wordWarp";
140 private static final String WHOLE_WORD = "wholeWord";
141 private static final String CASE_SENSITIVE = "caseSensitive";
142 private static final String STATE_FLAG = "state";
144 private static final String SETTING = "Setting";
145 private static final String SCINOTES = "scinotes";
146 private static final String TRUE = "true";
147 private static final String FALSE = "false";
148 private static final String DOCUMENT = "document";
149 private static final String PATH = "path";
150 private static final String RECENT_FILES = "recentFiles";
151 private static final String OPEN_FILES = "openFiles";
152 private static final String RESTOREFILES = "RestoreFiles";
153 private static final String EDITORINST = "editorInstance";
154 private static final String EDITORUUID = "EditorUUID";
155 private static final String PANEINST = "paneInstance";
156 private static final String PANEINST_EX = "paneInstanceExtra";
158 private static final String FAVORITE_DIRS = "favoriteDirectories";
159 private static final String DIRECTORY = "Directory";
161 private static final String PAPER = "PaperFormat";
162 private static final String MARGINLEFT = "MarginLeft";
163 private static final String MARGINRIGHT = "MarginRight";
164 private static final String MARGINTOP = "MarginTop";
165 private static final String MARGINBOTTOM = "MarginBottom";
167 private static final String CODENAVIGATOR = "CodeNavigator";
169 private static final String SCI = "SCI";
170 private static final String SCINOTES_CONFIG_FILE = System.getenv(SCI) + "/modules/scinotes/etc/scinotesConfiguration.xml";
172 private static final int PLAIN = 0;
173 private static final int BOLD = 1;
174 private static final int ITALIC = 2;
175 private static final int BOLDITALIC = 3;
177 private static final int DEFAULT_WIDTH = 650;
178 private static final int DEFAULT_HEIGHT = 550;
180 private static final int MAXRECENT = 20;
182 private static Document document;
184 private static boolean updated;
185 private static boolean mustSave = true;
187 private static String USER_SCINOTES_CONFIG_FILE = ScilabConstants.SCIHOME.toString() + "/scinotesConfiguration.xml";
190 if (ScilabConstants.SCIHOME != null && ScilabConstants.SCIHOME.canRead() && ScilabConstants.SCIHOME.canWrite()) {
191 USER_SCINOTES_CONFIG_FILE = ScilabConstants.SCIHOME.toString() + "/scinotesConfiguration.xml";
193 USER_SCINOTES_CONFIG_FILE = SCINOTES_CONFIG_FILE;
201 private ConfigSciNotesManager() {
202 throw new UnsupportedOperationException();
206 * Create a copy of Scilab configuration file in the user directory
208 public static void createUserCopy() {
209 if (checkVersion() && mustSave) {
210 /* Create a local copy of the configuration file */
211 ScilabCommonsUtils.copyFile(new File(SCINOTES_CONFIG_FILE), new File(USER_SCINOTES_CONFIG_FILE));
218 * Get the name of the user configuration file
219 * @return the name of the configuration file
221 public static String getUserConfigFile() {
222 return USER_SCINOTES_CONFIG_FILE;
226 * @return true if scinotesConfiguration.xml in etc has a version greater than the version in home
228 public static boolean checkVersion() {
233 File fileConfig = new File(USER_SCINOTES_CONFIG_FILE);
235 if (fileConfig.exists()) {
237 readDocument(SCINOTES_CONFIG_FILE);
238 Node setting = getNodeChild(null, SETTING);
239 String str = ((Element) setting).getAttribute(VERSION);
240 if (str != null && str.length() != 0) {
241 float versionEtc = Float.parseFloat(str);
244 setting = getNodeChild(null, SETTING);
245 str = ((Element) setting).getAttribute(VERSION);
248 if (str != null && str.length() != 0) {
249 float versionHome = Float.parseFloat(str);
250 return versionEtc != versionHome;
259 * @return the paper format saved in previous session
261 public static Paper getPaperFormat() {
264 Element root = document.getDocumentElement();
266 NodeList profiles = root.getElementsByTagName(PROFILE);
267 Element scinotesProfile = (Element) profiles.item(0);
269 NodeList allSizeElements = scinotesProfile.getElementsByTagName(PAPER);
270 Element paper = (Element) allSizeElements.item(0);
276 Paper p = new Paper();
277 double width = Double.parseDouble(paper.getAttribute(WIDTH));
278 double height = Double.parseDouble(paper.getAttribute(HEIGHT));
279 double marginLeft = Double.parseDouble(paper.getAttribute(MARGINLEFT));
280 double marginRight = Double.parseDouble(paper.getAttribute(MARGINRIGHT));
281 double marginTop = Double.parseDouble(paper.getAttribute(MARGINTOP));
282 double marginBottom = Double.parseDouble(paper.getAttribute(MARGINBOTTOM));
283 p.setSize(width, height);
284 p.setImageableArea(marginLeft, marginTop, width - (marginLeft + marginRight), height - (marginTop + marginBottom));
290 * Save the paper format
291 * @param p the Paper to save
293 public static void savePaperFormat(Paper p) {
296 Element root = document.getDocumentElement();
298 NodeList profiles = root.getElementsByTagName(PROFILE);
299 Element scinotesProfile = (Element) profiles.item(0);
301 NodeList allSizeElements = scinotesProfile.getElementsByTagName(PAPER);
302 Element paper = (Element) allSizeElements.item(0);
305 paper = document.createElement(PAPER);
306 scinotesProfile.appendChild((Node) paper);
309 double width = p.getWidth();
310 double height = p.getHeight();
311 double marginLeft = p.getImageableX();
312 double marginRight = width - (marginLeft + p.getImageableWidth());
313 double marginTop = p.getImageableY();
314 double marginBottom = height - (marginTop + p.getImageableHeight());
316 paper.setAttribute(WIDTH, Double.toString(width));
317 paper.setAttribute(HEIGHT, Double.toString(height));
318 paper.setAttribute(MARGINLEFT, Double.toString(marginLeft));
319 paper.setAttribute(MARGINRIGHT, Double.toString(marginRight));
320 paper.setAttribute(MARGINTOP, Double.toString(marginTop));
321 paper.setAttribute(MARGINBOTTOM, Double.toString(marginBottom));
327 * @return the color the altern colors for inner function
329 public static Color[] getAlternColors() {
332 Element root = document.getDocumentElement();
334 NodeList profiles = root.getElementsByTagName(PROFILE);
335 Element scinotesProfile = (Element) profiles.item(0);
337 NodeList allSizeElements = scinotesProfile.getElementsByTagName(ALTERNCOLORS);
338 Element alternColors = (Element) allSizeElements.item(0);
339 Color[] arr = new Color[2];
342 if (NULL.equals(alternColors.getAttribute(COLOR1))) {
345 c = Color.decode(alternColors.getAttribute(COLOR1));
350 if (NULL.equals(alternColors.getAttribute(COLOR2))) {
353 c = Color.decode(alternColors.getAttribute(COLOR2));
361 * Get all the recent opened files
362 * @return an array of uri
364 public static List<File> getAllRecentOpenedFiles() {
365 List<File> files = new ArrayList<File>();
367 Element root = (Element) document.getDocumentElement().getElementsByTagName(RECENT_FILES).item(0);
369 NodeList recentFiles = root.getElementsByTagName(DOCUMENT);
370 for (int i = 0; i < recentFiles.getLength(); ++i) {
371 Element style = (Element) recentFiles.item(i);
373 File temp = new File(style.getAttribute(PATH));
378 root.removeChild((Node) style);
390 * Get all the favorite dirs
391 * @return a list of File
393 public static List<File> getAllFavoriteDirs() {
394 List<File> dirsList = new ArrayList<File>();
396 Element root = (Element) document.getDocumentElement().getElementsByTagName(FAVORITE_DIRS).item(0);
398 NodeList dirs = root.getElementsByTagName(DIRECTORY);
399 for (int i = 0; i < dirs.getLength(); i++) {
400 Element dir = (Element) dirs.item(i);
401 File temp = new File(dir.getAttribute(PATH));
406 root.removeChild((Node) dir);
418 * Add a path to a favorite directory
419 * @param path the path of the dir
421 public static void saveFavoriteDirectory(String path) {
424 Element root = (Element) document.getDocumentElement().getElementsByTagName(FAVORITE_DIRS).item(0);
425 Element newDir = document.createElement(DIRECTORY);
426 newDir.setAttribute(PATH, path);
427 root.appendChild((Node) newDir);
434 * Remove the last favorite directory
436 public static void rmLastFavoriteDirectory() {
439 Element root = (Element) document.getDocumentElement().getElementsByTagName(FAVORITE_DIRS).item(0);
440 NodeList dirs = root.getElementsByTagName(DIRECTORY);
442 if (dirs.getLength() != 0) {
443 root.removeChild(dirs.item(dirs.getLength() - 1));
451 * Add a file to recent Opened Files
452 * @param filePath the path of the files to add
454 public static void saveToRecentOpenedFiles(String filePath) {
457 Element root = (Element) document.getDocumentElement().getElementsByTagName(RECENT_FILES).item(0);
458 NodeList recentFiles = root.getElementsByTagName(DOCUMENT);
459 int numberOfFiles = recentFiles.getLength();
461 // we remove all the duplicate
462 for (int i = 0; i < recentFiles.getLength(); ++i) {
463 Element style = (Element) recentFiles.item(i);
464 if (filePath.equals(style.getAttribute(PATH))) {
465 root.removeChild((Node) style);
470 // if we have reached the maximun , we remove the oldest files
471 while (recentFiles.getLength() >= MAXRECENT) {
472 root.removeChild(root.getFirstChild());
475 Element newFile = document.createElement(DOCUMENT);
476 newFile.setAttribute(PATH, filePath);
477 root.appendChild((Node) newFile);
484 * @return true if open files should be restored upon restart.
486 public static boolean getRestoreOpenedFiles() {
489 Element root = document.getDocumentElement();
491 NodeList profiles = root.getElementsByTagName(PROFILE);
492 Element scinotesProfile = (Element) profiles.item(0);
494 NodeList allSizeElements = scinotesProfile.getElementsByTagName(RESTOREFILES);
495 Element restorefiles = (Element) allSizeElements.item(0);
497 return TRUE.equals(restorefiles.getAttribute(VALUE));
501 * Active/deactive restoration of open files upon restart of scinotes
502 * @param activated active or not
504 public static void saveRestoreOpenedFiles(boolean activated) {
507 Element root = document.getDocumentElement();
509 NodeList profiles = root.getElementsByTagName(PROFILE);
510 Element scinotesProfile = (Element) profiles.item(0);
512 NodeList allSizeElements = scinotesProfile.getElementsByTagName(RESTOREFILES);
513 Element restorefiles = (Element) allSizeElements.item(0);
514 if (restorefiles == null) {
515 Element restoreElement = document.createElement(RESTOREFILES);
516 restorefiles.setAttribute(VALUE, new Boolean(activated).toString());
517 restorefiles.appendChild((Node) restoreElement);
519 restorefiles.setAttribute(VALUE, new Boolean(activated).toString());
527 * Return a count of the open files that exist. New files, for instance, do not.
530 public static int countExistingOpenFiles(UUID uuid) {
533 Element root = (Element) document.getDocumentElement().getElementsByTagName(OPEN_FILES).item(0);
535 NodeList openFiles = root.getElementsByTagName(DOCUMENT);
536 for (int i = 0; i < openFiles.getLength(); ++i) {
537 Element style = (Element) openFiles.item(i);
538 if (style.getAttribute(EDITORINST).equals(uuid.toString())) {
539 File temp = new File(style.getAttribute(PATH));
550 * Get the list of open files associated with an editor instance hashcode.
551 * Only files that exist are returned.
552 * @param editorID unique id of an editor instance
553 * @return an array of uri
555 public static List<File> getOpenFilesByEditor(UUID editorID) {
556 List<File> files = new ArrayList<File>();
558 Element root = (Element) document.getDocumentElement().getElementsByTagName(OPEN_FILES).item(0);
560 NodeList openFiles = root.getElementsByTagName(DOCUMENT);
562 /* Loop through the list and return only the files with a matching hash code. */
564 for (; i < openFiles.getLength(); i++) {
565 Element doc = (Element) openFiles.item(i);
567 if (editorID.equals(UUID.fromString(doc.getAttribute(EDITORINST)))) {
568 File temp = new File(doc.getAttribute(PATH));
570 /* Check that the file exists and add to file list or else remove the node. */
571 if (temp.exists() && !files.contains(temp)) {
574 root.removeChild((Node) doc);
575 i--; // Adjust index to account for removed item.
587 * Get a list of unique editor instance identifiers in the list of open files.
588 * @return an array of editor instance identifiers
590 public static List<UUID> getOpenFilesEditorList() {
591 List<UUID> editorIDlist = new ArrayList<UUID>();
593 Element root = (Element) document.getDocumentElement().getElementsByTagName(OPEN_FILES).item(0);
595 NodeList openFiles = root.getElementsByTagName(DOCUMENT);
597 /* Loop through the list and return the list of IDs. */
598 for (int i = 0; i < openFiles.getLength(); ++i) {
599 Element style = (Element) openFiles.item(i);
601 UUID editorID = UUID.fromString(style.getAttribute(EDITORINST));
603 if (!editorIDlist.contains(editorID)) {
604 editorIDlist.add(editorID);
612 * Add a file to currently open files
613 * @param filePath the path of the files to add
614 * @param editorInstance instance of the editor to associate with the open file
615 * @param sep the pane
617 public static void saveToOpenFiles(String filePath, SciNotes editorInstance, ScilabEditorPane sep) {
618 saveToOpenFiles(filePath, editorInstance, sep, -1);
622 * Add a file to currently open files
623 * @param filePath the path of the files to add
624 * @param editorInstance instance of the editor to associate with the open file
625 * @param sep the pane
627 public static void saveToOpenFiles(String filePath, SciNotes editorInstance, ScilabEditorPane sep, int pos) {
629 removeFromOpenFiles(editorInstance.getUUID(), Arrays.asList(new String[] {filePath}));
630 UUID nil = new UUID(0, 0);
632 // Find the element containing the list of open files
633 Element root = (Element) document.getDocumentElement().getElementsByTagName(OPEN_FILES).item(0);
634 // Get the list of open files
635 NodeList openFiles = root.getElementsByTagName(DOCUMENT);
636 int numberOfFiles = openFiles.getLength();
639 if (pos != - 1 && pos < numberOfFiles) {
640 bef = openFiles.item(pos);
643 Element newFile = document.createElement(DOCUMENT);
644 newFile.setAttribute(PATH, filePath);
645 // Record the editor instance's hash code
646 newFile.setAttribute(EDITORINST, editorInstance.getUUID().toString());
647 //root.appendChild((Node) newFile);
648 // Record the text pane's hash code
649 newFile.setAttribute(PANEINST, sep.getUUID().toString());
650 newFile.setAttribute(PANEINST_EX, nil.toString());
652 root.insertBefore((Node) newFile, bef);
654 root.appendChild((Node) newFile);
662 * Remove a tab with an open file from the list of open files
663 * @param editorInstance instance of the editor
664 * @param sep instance of the editor pane.
666 public static void removeFromOpenFiles(SciNotes editorInstance, ScilabEditorPane sep) {
667 removeFromOpenFiles(editorInstance.getUUID(), sep.getUUID());
671 * Remove from the list of open files all files with a matching editor instance identifer
672 * @param editorID editor instance identifer
674 public static void removeFromOpenFiles(UUID editorID) {
675 removeFromOpenFiles(editorID, new UUID(0, 0) /* nil UUID */);
679 * Remove a tab with an open file from the list of open files
680 * @param editorID editor instance identifer
681 * @param sepID editor pane instance identifer. If a nil UUID is passed,
682 * all files with a matching editor instance identifer are removed.
684 public static void removeFromOpenFiles(UUID editorID, List<String> toRemove) {
687 Element root = (Element) document.getDocumentElement().getElementsByTagName(OPEN_FILES).item(0);
688 NodeList openFiles = root.getElementsByTagName(DOCUMENT);
690 // Remove item with matching editorID and sepID.
691 for (int i = openFiles.getLength() - 1; i >= 0; i--) {
692 Element doc = (Element) openFiles.item(i);
693 if (editorID.equals(UUID.fromString(doc.getAttribute(EDITORINST)))
694 && toRemove.contains(doc.getAttribute(PATH))) {
695 root.removeChild((Node) doc);
704 * Remove a tab with an open file from the list of open files
705 * @param editorID editor instance identifer
706 * @param sepID editor pane instance identifer. If a nil UUID is passed,
707 * all files with a matching editor instance identifer are removed.
709 public static void removeFromOpenFiles(UUID editorID, UUID sepID) {
712 Element root = (Element) document.getDocumentElement().getElementsByTagName(OPEN_FILES).item(0);
713 NodeList openFiles = root.getElementsByTagName(DOCUMENT);
715 // Remove item with matching editorID and sepID.
716 UUID nil = new UUID(0, 0);
717 for (int i = openFiles.getLength() - 1; i >= 0; i--) {
718 Element style = (Element) openFiles.item(i);
719 UUID paneID1 = UUID.fromString(style.getAttribute(PANEINST));
720 UUID paneID2 = UUID.fromString(style.getAttribute(PANEINST_EX));
722 if (editorID.equals(UUID.fromString(style.getAttribute(EDITORINST)))
723 && (sepID.equals(nil) || sepID.equals(paneID1) || sepID.equals(paneID2))) {
724 root.removeChild((Node) style);
734 * @param newfilePath new pathname of the file
735 * @param editorInstance instance of the editor
736 * @param sep instance of the editor pane
738 public static void renameOpenFilesItem(String newfilePath, SciNotes editorInstance, ScilabEditorPane sep) {
741 Element root = (Element) document.getDocumentElement().getElementsByTagName(OPEN_FILES).item(0);
742 Element style = findOpenFileItem(root, editorInstance.getUUID(), sep.getUUID());
745 style.setAttribute(PATH, newfilePath);
753 * Replace a single text pane ID with two pane IDs when a tab split occurs
754 * @param editorInstance instance of the editor
755 * @param old1 old instance of the editor pane
756 * @param new1 first new instance of the tabbed editor pane
757 * @param new2 second new instance of the tabbed editor pane
759 public static void tabSplitOpenFilesItem(SciNotes editorInstance, ScilabEditorPane old1, ScilabEditorPane new1, ScilabEditorPane new2) {
762 Element root = (Element) document.getDocumentElement().getElementsByTagName(OPEN_FILES).item(0);
763 Element style = findOpenFileItem(root, editorInstance.getUUID(), old1.getUUID());
766 style.setAttribute(PANEINST, new1.getUUID().toString());
767 style.setAttribute(PANEINST_EX, new2.getUUID().toString());
775 * Replace double pane IDs with a single ID when a tabbed pane is replaced by a single pane.
776 * @param editorInstance instance of the editor
777 * @param old1 one of the old tabbed editor pane
778 * @param new1 new editor pane
780 public static void removeTabSplitInOpenFilesItem(SciNotes editorInstance, ScilabEditorPane old1, ScilabEditorPane new1) {
783 Element root = (Element) document.getDocumentElement().getElementsByTagName(OPEN_FILES).item(0);
784 Element style = findOpenFileItem(root, editorInstance.getUUID(), old1.getUUID());
787 UUID nil = new UUID(0, 0);
788 style.setAttribute(PANEINST, new1.getUUID().toString());
789 style.setAttribute(PANEINST_EX, nil.toString());
797 * Find the first element with matching editor and pane identifiers
798 * @param root Document root
799 * @param editorID instance of the editor to find
800 * @param sepID instance of the editor pane to find
801 * @return the corresponding element
803 public static Element findOpenFileItem(Element root, UUID editorID, UUID sepID) {
804 NodeList openFiles = root.getElementsByTagName(DOCUMENT);
806 // Find item with matching editor and pane IDs
807 for (int i = 0; i < openFiles.getLength(); i++) {
808 Element style = (Element) openFiles.item(i);
809 UUID paneID1 = UUID.fromString(style.getAttribute(PANEINST));
810 UUID paneID2 = UUID.fromString(style.getAttribute(PANEINST_EX));
812 if (editorID.equals(UUID.fromString(style.getAttribute(EDITORINST)))
813 && (sepID.equals(paneID1) || sepID.equals(paneID2))) {
822 * Empty the list of open files. Performed when the editor is opened
823 * and the user opts not to restore the open files.
825 public static void removeAllOpenFiles() {
828 Element root = (Element) document.getDocumentElement().getElementsByTagName(OPEN_FILES).item(0);
829 NodeList openFiles = root.getElementsByTagName(DOCUMENT);
832 for (int i = openFiles.getLength() - 1; i >= 0; --i) {
833 Element style = (Element) openFiles.item(i);
834 root.removeChild((Node) style);
842 * Reset the current conf file
844 public static void resetDocument() {
849 * Read the file to modify
851 private static void readDocument() {
852 readDocument(USER_SCINOTES_CONFIG_FILE);
856 * Read the file to modify
858 private static void readDocument(String pathConfSci) {
859 File fileConfig = new File(USER_SCINOTES_CONFIG_FILE);
860 if (!fileConfig.exists()) {
864 DocumentBuilder docBuilder = null;
865 String factoryName = ScilabDocumentBuilderFactory.useDefaultDocumentBuilderFactoryImpl();
868 if (document == null) {
869 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
870 docBuilder = factory.newDocumentBuilder();
872 // read content of a XML file with DOM
873 xml = new File(pathConfSci);
874 document = docBuilder.parse(xml);
876 } catch (ParserConfigurationException pce) {
877 System.err.println(ERROR_READ + pathConfSci);
878 } catch (SAXException se) {
879 System.err.println(ERROR_READ + pathConfSci);
880 } catch (IOException ioe) {
881 System.err.println(ERROR_READ + pathConfSci);
884 ScilabDocumentBuilderFactory.restoreDocumentBuilderFactoryImpl(factoryName);
886 if (document == null && fileConfig.exists()) {
887 ScilabModalDialog.show(null, SciNotesMessages.CORRUPTED_CONF_FILE, SciNotesMessages.SCINOTES_ERROR, IconType.ERROR_ICON);
890 readDocument(pathConfSci);
895 * Save the modifications
897 private static void writeDocument() {
899 Transformer transformer = null;
901 transformer = ScilabTransformerFactory.newInstance().newTransformer();
902 } catch (TransformerConfigurationException e1) {
903 System.err.println(ERROR_WRITE + USER_SCINOTES_CONFIG_FILE);
904 System.err.println(e1);
905 } catch (TransformerFactoryConfigurationError e1) {
906 System.err.println(ERROR_WRITE + USER_SCINOTES_CONFIG_FILE);
907 System.err.println(e1);
910 if (transformer != null) {
911 transformer.setOutputProperty(OutputKeys.INDENT, "yes");
913 StreamResult result = new StreamResult(new File(USER_SCINOTES_CONFIG_FILE));
914 DOMSource source = new DOMSource(document);
916 transformer.transform(source, result);
917 } catch (TransformerException e) {
918 System.err.println(ERROR_WRITE + USER_SCINOTES_CONFIG_FILE);
919 System.err.println(e);
928 public static void saveCodeNavigatorState(String editorUUID, String navUUID) {
931 Element root = document.getDocumentElement();
932 NodeList navs = root.getElementsByTagName(CODENAVIGATOR);
933 boolean update = false;
934 for (int i = 0; i < navs.getLength(); i++) {
935 Element nav = (Element) navs.item(i);
936 if (nav.getAttribute("uuid").equals(navUUID)) {
937 nav.setAttribute("depends", editorUUID);
944 ScilabXMLUtilities.createNode(document, root, CODENAVIGATOR, new String[] {"uuid", navUUID, "depends", editorUUID});
953 public static String getCodeNavigatorState(String navUUID) {
956 Element root = document.getDocumentElement();
957 NodeList navs = root.getElementsByTagName(CODENAVIGATOR);
958 for (int i = 0; i < navs.getLength(); i++) {
959 Element nav = (Element) navs.item(i);
960 if (nav.getAttribute("uuid").equals(navUUID)) {
961 return nav.getAttribute("depends");
970 public static String getCodeNavigatorStateForEditor(String editorUUID) {
973 Element root = document.getDocumentElement();
974 NodeList navs = root.getElementsByTagName(CODENAVIGATOR);
975 for (int i = 0; i < navs.getLength(); i++) {
976 Element nav = (Element) navs.item(i);
977 if (nav.getAttribute("depends").equals(editorUUID)) {
978 return nav.getAttribute("uuid");
987 public static void saveSearchInFilesState(String editorUUID, String sfUUID) {
990 Element root = document.getDocumentElement();
991 NodeList sfs = root.getElementsByTagName(SEARCHINFILES);
992 boolean update = false;
993 for (int i = 0; i < sfs.getLength(); i++) {
994 Element sf = (Element) sfs.item(i);
995 if (sf.getAttribute("uuid").equals(sfUUID)) {
996 sf.setAttribute("depends", editorUUID);
1003 ScilabXMLUtilities.createNode(document, root, SEARCHINFILES, new String[] {"uuid", sfUUID, "depends", editorUUID});
1012 public static String getSearchInFilesState(String sfUUID) {
1015 Element root = document.getDocumentElement();
1016 NodeList sfs = root.getElementsByTagName(SEARCHINFILES);
1017 for (int i = 0; i < sfs.getLength(); i++) {
1018 Element sf = (Element) sfs.item(i);
1019 if (sf.getAttribute("uuid").equals(sfUUID)) {
1020 return sf.getAttribute("depends");
1029 public static String getSearchInFilesStateForEditor(String editorUUID) {
1032 Element root = document.getDocumentElement();
1033 NodeList sfs = root.getElementsByTagName(SEARCHINFILES);
1034 for (int i = 0; i < sfs.getLength(); i++) {
1035 Element sf = (Element) sfs.item(i);
1036 if (sf.getAttribute("depends").equals(editorUUID)) {
1037 return sf.getAttribute("uuid");
1046 public static void saveEditorUUID(String editorUUID) {
1049 Element root = document.getDocumentElement();
1050 NodeList eis = root.getElementsByTagName(EDITORUUID);
1051 for (int i = 0; i < eis.getLength(); i++) {
1052 Element ei = (Element) eis.item(i);
1053 if (ei.getAttribute("uuid").equals(editorUUID)) {
1058 ScilabXMLUtilities.createNode(document, root, EDITORUUID, new String[] {"uuid", editorUUID});
1066 public static void removeEditorUUID(String editorUUID) {
1069 Element root = document.getDocumentElement();
1070 NodeList eis = root.getElementsByTagName(EDITORUUID);
1071 for (int i = 0; i < eis.getLength(); i++) {
1072 Element ei = (Element) eis.item(i);
1073 if (ei.getAttribute("uuid").equals(editorUUID)) {
1074 root.removeChild(ei);
1078 root = (Element) document.getDocumentElement().getElementsByTagName(OPEN_FILES).item(0);
1080 NodeList openFiles = root.getElementsByTagName(DOCUMENT);
1081 for (int i = 0; i < openFiles.getLength(); ++i) {
1082 Element of = (Element) openFiles.item(i);
1083 if (of.getAttribute(EDITORINST).equals(editorUUID)) {
1084 root.removeChild(of);
1095 public static List<String> getEditorsUUID() {
1098 Element root = document.getDocumentElement();
1099 NodeList eis = root.getElementsByTagName(EDITORUUID);
1100 List<String> list = new ArrayList<String>();
1101 for (int i = 0; i < eis.getLength(); i++) {
1102 Element ei = (Element) eis.item(i);
1103 list.add(ei.getAttribute("uuid"));
1110 * Add a file to recent Opened Files
1111 * @param exp the path of the files to add
1113 public static void saveRecentSearch(String exp) {
1114 Node root = getXcosRoot();
1115 if (root == null || exp == null || exp.compareTo("") == 0) {
1119 Node recents = getNodeChild(root, RECENT_SEARCH);
1120 if (recents == null) {
1121 recents = document.createElement(RECENT_SEARCH);
1122 root.appendChild(recents);
1125 List<Node> search = getNodeChildren(recents, SEARCH);
1127 while (search.size() >= MAXRECENT) {
1128 removeRecentSearch(((Element) search.get(0)).getAttribute(EXPRESSION));
1129 search = getNodeChildren(recents, SEARCH);
1131 //if path already in file no need to add it
1132 for (Node item : search) {
1133 if (exp.compareTo(((Element) item).getAttribute(EXPRESSION)) == 0) {
1138 Element newSearch = document.createElement(SEARCH);
1139 newSearch.setAttribute(EXPRESSION, exp);
1140 recents.appendChild((Node) newSearch);
1147 * @param exp the expression to remove
1149 public static void removeRecentSearch(String exp) {
1150 Node root = getXcosRoot();
1155 Node recent = getNodeChild(root, RECENT_SEARCH);
1156 List<Node> search = getNodeChildren(recent, SEARCH);
1158 // remove node if exists
1159 for (Node file : search) {
1160 if (exp.compareTo(((Element) file).getAttribute(EXPRESSION)) == 0) {
1161 recent.removeChild(file);
1172 * @return a list of the recent searches
1174 public static List<String> getRecentSearch() {
1175 List<String> files = new ArrayList<String>();
1177 Node root = getXcosRoot();
1182 Node recent = getNodeChild(root, RECENT_SEARCH);
1183 List<Node> searches = getNodeChildren(recent, SEARCH);
1184 for (Node search : searches) {
1185 String exp = ((Element) search).getAttribute(EXPRESSION);
1186 if (exp != null && exp.compareTo("") != 0) {
1195 * Add a file to recent Opened Files
1196 * @param exp the path of the files to add
1198 public static void saveRecent(String exp, String nodeName, String childNodeName) {
1199 Node root = getXcosRoot();
1200 if (root == null || exp == null || exp.compareTo("") == 0) {
1204 Node recents = getNodeChild(root, nodeName);
1205 if (recents == null) {
1206 recents = document.createElement(nodeName);
1207 root.appendChild(recents);
1210 List<Node> list = getNodeChildren(recents, childNodeName);
1212 while (list.size() >= MAXRECENT) {
1213 removeRecent(((Element) list.get(0)).getAttribute(EXPRESSION), nodeName, childNodeName);
1214 list = getNodeChildren(recents, childNodeName);
1216 //if path already in file no need to add it
1217 for (Node item : list) {
1218 if (exp.compareTo(((Element) item).getAttribute(EXPRESSION)) == 0) {
1223 Element newNode = document.createElement(childNodeName);
1224 newNode.setAttribute(EXPRESSION, exp);
1225 recents.appendChild((Node) newNode);
1232 * @param exp the expression to remove
1234 public static void removeRecent(String exp, String nodeName, String childNodeName) {
1235 Node root = getXcosRoot();
1240 Node recent = getNodeChild(root, nodeName);
1241 List<Node> list = getNodeChildren(recent, childNodeName);
1243 // remove node if exists
1244 for (Node item : list) {
1245 if (exp.compareTo(((Element) item).getAttribute(EXPRESSION)) == 0) {
1246 recent.removeChild(item);
1256 * @return a list of the recent searches
1258 public static List<String> getRecent(String nodeName, String childNodeName) {
1259 List<String> files = new ArrayList<String>();
1261 Node root = getXcosRoot();
1266 Node recent = getNodeChild(root, nodeName);
1267 List<Node> list = getNodeChildren(recent, childNodeName);
1268 for (Node node : list) {
1269 String exp = ((Element) node).getAttribute(EXPRESSION);
1270 if (exp != null && exp.compareTo("") != 0) {
1280 * @param exp the recent expression for a replacement
1282 public static void saveRecentReplace(String exp) {
1283 Node root = getXcosRoot();
1284 if (root == null || exp == null || exp.compareTo("") == 0) {
1288 Node recent = getNodeChild(root, RECENT_REPLACE);
1289 if (recent == null) {
1290 recent = document.createElement(RECENT_REPLACE);
1291 root.appendChild(recent);
1294 List<Node> replace = getNodeChildren(recent, REPLACE);
1296 while (replace.size() >= MAXRECENT) {
1297 removeRecentReplace(((Element) replace.get(0)).getAttribute(EXPRESSION));
1298 replace = getNodeChildren(recent, REPLACE);
1300 //if path already in file no need to add it
1301 for (Node item : replace) {
1302 if (exp.compareTo(((Element) item).getAttribute(EXPRESSION)) == 0) {
1307 Element newReplace = document.createElement(REPLACE);
1308 newReplace.setAttribute(EXPRESSION, exp);
1309 recent.appendChild((Node) newReplace);
1316 * @param filePath remove recent replace in the this file
1318 public static void removeRecentReplace(String filePath) {
1320 Node root = getXcosRoot();
1325 Node recent = getNodeChild(root, RECENT_REPLACE);
1326 List<Node> replace = getNodeChildren(recent, REPLACE);
1328 // remove node if exists
1329 for (Node exp : replace) {
1330 if (filePath.compareTo(((Element) exp).getAttribute(EXPRESSION)) == 0) {
1331 recent.removeChild(exp);
1343 * @return the recent replace
1345 public static List<String> getRecentReplace() {
1346 List<String> exps = new ArrayList<String>();
1348 Node root = getXcosRoot();
1353 Node recent = getNodeChild(root, RECENT_REPLACE);
1354 List<Node> replace = getNodeChildren(recent, REPLACE);
1355 for (Node file : replace) {
1356 String exp = ((Element) file).getAttribute(EXPRESSION);
1357 if (exp != null && exp.compareTo("") != 0) {
1366 * @return true for a regexp search
1368 public static boolean getRegularExpression() {
1369 return getBooleanAttribute(REGULAR_EXPRESION, STATE_FLAG, false);
1373 * @param regualExp for a regexp search
1375 public static void saveRegularExpression(boolean regualExp) {
1376 saveBooleanAttribute(REGULAR_EXPRESION, STATE_FLAG, regualExp);
1380 * @return true for a wholeWord search
1382 public static boolean getWholeWord() {
1383 return getBooleanAttribute(WHOLE_WORD, STATE_FLAG, false);
1387 * @param wholeWord for a wholeWord search
1389 public static void saveWholeWord(boolean wholeWord) {
1390 saveBooleanAttribute(WHOLE_WORD, STATE_FLAG, wholeWord);
1394 * @return true for a recursive search
1396 public static boolean getRecursive() {
1397 return getBooleanAttribute(RECURSIVE, STATE_FLAG, true);
1401 * @param recursive for a recursive search
1403 public static void saveRecursive(boolean recursive) {
1404 saveBooleanAttribute(RECURSIVE, STATE_FLAG, recursive);
1408 * @return true for a line by line search
1410 public static boolean getLineByLine() {
1411 return getBooleanAttribute(LINEBYLINE, STATE_FLAG, true);
1415 * @param lineByLine for a line by line search
1417 public static void saveLineByLine(boolean lineByLine) {
1418 saveBooleanAttribute(LINEBYLINE, STATE_FLAG, lineByLine);
1422 * @return true for a case sensitive file name
1424 public static boolean getFileCase() {
1425 return getBooleanAttribute(FILECASE, STATE_FLAG, false);
1429 * @param fileCase for a case sensitive file name
1431 public static void saveFileCase(boolean fileCase) {
1432 saveBooleanAttribute(FILECASE, STATE_FLAG, fileCase);
1436 * @return true for a circular search
1438 public static boolean getCircularSearch() {
1439 return getBooleanAttribute(CIRCULAR, STATE_FLAG, true);
1443 * @param circular is true for a circular search
1445 public static void saveCircularSearch(boolean circular) {
1446 saveBooleanAttribute(CIRCULAR, STATE_FLAG, circular);
1450 * @return true for a case sensitive search
1452 public static boolean getCaseSensitive() {
1453 return getBooleanAttribute(CASE_SENSITIVE, STATE_FLAG, false);
1457 * @param caseSensitive for a case sensitive search
1459 public static void saveCaseSensitive(boolean caseSensitive) {
1460 saveBooleanAttribute(CASE_SENSITIVE, STATE_FLAG, caseSensitive);
1464 * getBooleanAttribute
1465 * @param node the node name
1466 * @param attrib the attribute of the node
1467 * @param defaultValue true or false
1468 * @return the found boolean value or defaultValue if not found
1470 private static boolean getBooleanAttribute(String node, String attrib, boolean defaultValue) {
1471 boolean flag = false;
1472 Node root = getXcosRoot();
1476 Node recent = getNodeChild(root, node);
1477 if (recent != null) {
1478 String exp = ((Element) recent).getAttribute(attrib);
1479 if (exp.compareTo(TRUE) == 0) {
1483 return defaultValue;
1489 * saveBooleanAttribute
1490 * @param node the node name
1491 * @param attrib the attribute of the node
1492 * @param state "true" or "false"
1494 private static void saveBooleanAttribute(String node, String attrib, boolean state) {
1495 Node root = getXcosRoot();
1500 Node recent = getNodeChild(root, node);
1501 if (recent == null) {
1502 recent = document.createElement(node);
1503 root.appendChild(recent);
1507 ((Element) recent).setAttribute(attrib, new Boolean(state).toString());
1509 root.appendChild(recent);
1518 * @param nodeName the name
1521 private static Node getNodeChild(Node par, String nodeName) {
1523 if (parent == null) {
1524 if (document == null) {
1526 if (document == null) {
1533 Node currentNode = parent.getFirstChild();
1534 while (currentNode != null) {
1535 if (currentNode.getNodeName().compareTo(nodeName) == 0) {
1538 currentNode = currentNode.getNextSibling();
1546 * @param childName the name
1547 * @return a list of nodes
1549 private static List<Node> getNodeChildren(Node par, String childName) {
1551 List<Node> nodes = new ArrayList<Node>();
1552 if (parent == null) {
1553 if (document == null) {
1555 if (document == null) {
1562 Node currentNode = parent.getFirstChild();
1563 while (currentNode != null) {
1564 if (currentNode.getNodeName().compareTo(childName) == 0) {
1565 nodes.add(currentNode);
1567 currentNode = currentNode.getNextSibling();
1576 private static Node getXcosRoot() {
1577 if (document == null) {
1579 if (document == null) {
1584 Node setting = getNodeChild(null, SETTING);
1586 if (setting != null) {
1587 List<Node> nodes = getNodeChildren(setting, PROFILE);
1588 for (Node node : nodes) {
1589 if (((Element) node).getAttribute(NAME).compareTo(SCINOTES) == 0) {
1598 * Remove text at the beginning and at the end
1599 * @param r the element to clean
1601 private static void clean(Node r) {
1602 Node n = r.getFirstChild();
1603 if (n != null && n instanceof Text) {
1606 n = r.getLastChild();
1607 if (n != null && n instanceof Text) {