Preferences: continue to connect SciNotes
[scilab.git] / scilab / modules / preferences / src / java / org / scilab / modules / preferences / XConfigManager.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2011 - INRIA - Vincent COUVERT
4  * Copyright (C) 2011 -         Pierre GRADIT
5  * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET
6  *
7  * This file must be used under the terms of the CeCILL.
8  * This source file is licensed as described in the file COPYING, which
9  * you should have received as part of this distribution.  The terms
10  * are also available at
11  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
12  *
13  */
14
15 package org.scilab.modules.preferences;
16
17 import java.awt.Color;
18 import java.awt.Component;
19 import java.awt.BorderLayout;
20 import java.awt.Dimension;
21 import java.awt.Font;
22 import java.awt.Frame;
23 import java.awt.Toolkit;
24 import java.awt.event.ComponentAdapter;
25 import java.awt.event.ComponentEvent;
26 import java.awt.event.ComponentListener;
27 import java.io.File;
28 import java.util.HashMap;
29 import java.util.List;
30 import java.util.Map;
31
32 import javax.swing.JDialog;
33
34 import org.w3c.dom.Document;
35 import org.w3c.dom.DocumentFragment;
36 import org.w3c.dom.Element;
37 import org.w3c.dom.Node;
38 import org.w3c.dom.NodeList;
39
40 import org.scilab.modules.commons.ScilabCommons;
41 import org.scilab.modules.commons.xml.XConfiguration;
42 import org.scilab.modules.gui.utils.Position;
43 import org.scilab.modules.gui.utils.Size;
44 import org.scilab.modules.preferences.ScilabPreferences.ToolboxInfos;
45
46 /**
47  * Extended management of the Console configuration file.
48  *
49  * @author Pierre GRADIT
50  * @author Vincent COUVERT
51  */
52 public final class XConfigManager extends XCommonManager {
53
54     /** Exclusive activity flag between all XCommonManager descendants.*/
55     public static boolean active = false;
56
57     /** Scilab configuration file.*/
58     private static final String SCILAB_CONFIG_FILE = System.getenv("SCI") + "/modules/preferences/etc/XConfiguration.xml";
59
60     /** Scilab configuration stylesheet.*/
61     private static final String SCILAB_CONFIG_XSL = System.getenv("SCI") + "/modules/preferences/src/xslt/XConfiguration.xsl";
62
63     /** User configuration file.*/
64     private static final String USER_CONFIG_FILE = ScilabCommons.getSCIHOME() + "/XConfiguration.xml";
65
66     static {
67         //ScilabPreferences.addToolboxInfos("MyToolbox", System.getenv("SCI") + "/contrib/toolbox_skeleton/", System.getenv("SCI") + "/contrib/toolbox_skeleton/etc/toolbox_skeleton_preferences.xml");
68     }
69
70     /**
71      * Constructor blocked, singleton pattern.
72      */
73     private XConfigManager() {
74         throw new UnsupportedOperationException();
75     }
76
77     /** Display dialog and wait for events.
78      *
79      */
80     public static void displayAndWait() {
81         XConfigManager.active = true;
82         XWizardManager.active = false;
83
84         reloadTransformer(SCILAB_CONFIG_XSL);
85
86         // Set up Swing Side
87         dialog = new JDialog(getTopLevel(), "Scilab Preferences", true);
88         topSwing = dialog.getContentPane();
89         topSwing.setLayout(new BorderLayout());
90         // AWT implies to set layout at construction time.
91
92         // Set up DOM Side
93         readUserDocuments();
94         updated = false;
95
96         // Plug in resize
97         //dialog.setResizable(false);
98         dialog.addComponentListener(new ComponentAdapter() {
99             public void componentResized(ComponentEvent e) {
100                 Element element = document.getDocumentElement();
101                 Dimension dimension = dialog.getSize();
102                 int height = XConfigManager.getInt(element, "height", 0);
103                 int width = XConfigManager.getInt(element, "width",  0);
104                 if (Math.abs(((double) height) - dimension.getHeight()) > 0.1 && Math.abs(((double) width) - dimension.getWidth()) > 0.1 ) {
105                     element.setAttribute("height", Integer.toString((int) dimension.getHeight()));
106                     element.setAttribute("width", Integer.toString((int) dimension.getWidth()));
107                 }
108             }
109         });
110
111         // Set up correspondence
112         correspondance = new HashMap<Component, XSentinel>();
113
114         // Let the show begin!
115         if (refreshDisplay()) {
116             // Center the dialog on the parent window
117             Frame topWindow = XCommonManager.getTopLevel();
118             int x = topWindow.getX() + (topWindow.getWidth() - dialog.getWidth()) / 2;
119             int y = topWindow.getY() + (topWindow.getHeight() - dialog.getHeight()) / 2;
120             dialog.setLocation(x, y);
121
122             dialog.setVisible(true);
123         }
124     }
125
126     /**
127      * Opens a dialog to setup preferences.
128      */
129     public static void openPreferences() {
130         XConfigManager.displayAndWait();
131     }
132
133     /** Secondary dialog for help.*/
134     private static JDialog help = null;
135
136     /** Read files to modify (and possibly create it).
137      */
138     private static void readUserDocuments() {
139         /*
140          * The default document just contains an empty tag <toolboxes/>
141          * We add a body and the different toolbox entries to have something like
142          * <toolboxes>
143          *   <body/>
144          *   <mytoolbox1><body>...</body></mytoolbox1>
145          *   <mytoolbox2><body>...</body></mytoolbox2>
146          * </toolboxes>
147          */
148
149         document = XConfiguration.getXConfigurationDocument();
150
151         // We remove all the previous tags (should be empty but an error could have occured...)
152         NodeList toolboxes = document.getElementsByTagName("toolboxes");
153         for (int i = 0; i < toolboxes.getLength(); i++) {
154             try {
155                 document.getDocumentElement().removeChild(toolboxes.item(i));
156             } catch (Exception e) {
157                 // Maybe root is not the good parent...
158             }
159         }
160
161         Element tbxs = document.createElement("toolboxes");
162         document.getDocumentElement().appendChild(tbxs);
163
164         // Body (rendered as XConfiguration.xsl example)
165         Element body = document.createElement("body");
166         tbxs.appendChild(body);
167
168         List<ToolboxInfos> infos = ScilabPreferences.getToolboxesInfos();
169         for (ToolboxInfos info: infos) {
170             String filename = new File(info.getPrefFile()).getName();
171             String tbxTag = info.getName().replace(' ', '_');
172             String tbxFile = ScilabCommons.getSCIHOME() + "/" + filename;
173
174             // the copy is made only if needed
175             createUserCopy(info.getPrefFile(), tbxFile);
176
177             // Building document fragment
178             Element token = document.createElement(tbxTag);
179             token.setAttribute("title", info.getName());
180             DocumentFragment fragment = document.createDocumentFragment();
181             Document tbxDocument = readDocument(tbxFile);
182             Node transferred = tbxDocument.getDocumentElement();
183
184             transferred = document.importNode(transferred, true);
185             fragment.appendChild(transferred);
186             token.insertBefore(fragment, null);
187             tbxs.appendChild(token);
188         }
189     }
190
191     private static void WriteUserDocuments() {
192         // Toolboxes files
193         NodeList toolboxes = document.getElementsByTagName("toolboxes");
194         Element tbxs = null;
195         Element emptyTbxs;
196         if (toolboxes != null && toolboxes.getLength() != 0) {
197             tbxs = (Element) toolboxes.item(0);
198             List<ToolboxInfos> infos = ScilabPreferences.getToolboxesInfos();
199             for (ToolboxInfos info: infos) {
200                 String tbxTag = info.getName().replace(' ', '_');
201                 NodeList list = tbxs.getElementsByTagName(tbxTag);
202                 if (list != null && list.getLength() != 0) {
203                     Element mytbx = (Element) list.item(0);
204                     if (mytbx.hasChildNodes()) {
205                         String filename = new File(info.getPrefFile()).getName();
206                         String tbxFile = ScilabCommons.getSCIHOME() + "/" + filename;
207                         XConfiguration.writeDocument(tbxFile, mytbx.getFirstChild());
208                     }
209                 }
210             }
211         }
212
213         if (tbxs != null) {
214             document.getDocumentElement().removeChild(tbxs);
215         }
216
217         XConfiguration.writeDocument(USER_CONFIG_FILE, document);
218
219         if (tbxs != null) {
220             document.getDocumentElement().appendChild(tbxs);
221         }
222     }
223
224     /** Interpret action.
225      *
226      * @param action : to be interpreted.
227      * @param source : component source of the action (only class is needed).
228      * @return whether event was treated or not.
229      */
230     public static boolean xEvent(final Node[] actions, final Component source) {
231         if (generixEvent(actions, source)) {
232             return true;
233         }
234
235         if (actions.length == 0) {
236             return false;
237         }
238
239         Node action = actions[0];
240         String callback = getAttribute(action, "callback");
241         /** help deprecated
242             if (callback.equals("Help")) {
243             // TODO it can be a contextual help.
244             //System.err.println("Help not implemented yet!");
245             if (differential) {
246             System.out.println(": Help.");
247             }
248             return true;
249             }
250         **/
251         if (callback.equals("Ok")) {
252             WriteUserDocuments();
253             dialog.dispose();
254             XCommonManager.invalidateXSL();
255             updated = false;
256             XConfiguration.fireXConfigurationEvent();
257             XConfiguration.invalidate();
258             return true;
259         }
260         if (callback.equals("Apply")) {
261             updated = false;
262             WriteUserDocuments();
263             XConfiguration.fireXConfigurationEvent();
264             return true;
265         }
266         if (callback.equals("Default")) {
267             XConfiguration.invalidate();
268             XConfiguration.addModifiedPath("ALL");
269             reloadTransformer(SCILAB_CONFIG_XSL);
270             document = XConfiguration.createDocument();
271             writeDocument(USER_CONFIG_FILE, document);
272             List<ToolboxInfos> infos = ScilabPreferences.getToolboxesInfos();
273             for (ToolboxInfos info : infos) {
274                 String filename = new File(info.getPrefFile()).getName();
275                 String tbxFile = ScilabCommons.getSCIHOME() + "/" + filename;
276                 refreshUserCopy(info.getPrefFile(), tbxFile);
277             }
278             readUserDocuments();
279             updated = false;
280             refreshDisplay();
281
282             return true;
283         }
284         if (callback.equals("Cancel")) {
285             dialog.dispose();
286             XCommonManager.invalidateXSL();
287             XConfiguration.invalidate();
288             NodeList toolboxes = document.getElementsByTagName("toolboxes");
289             if (toolboxes != null && toolboxes.getLength() != 0) {
290                 Element tbxs = (Element) toolboxes.item(0);
291                 document.getDocumentElement().removeChild(tbxs);
292             }
293             updated = false;
294             refreshDisplay();
295             return true;
296         }
297         return false;
298     }
299 }