Preferences: continue to connect SciNotes
[scilab.git] / scilab / modules / scinotes / src / java / org / scilab / modules / scinotes / SciNotesGUI.java
1 /* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2  * Copyright (C) 2009 - DIGITEO
3  * Copyright (C) 2010 - Calixte DENIZET
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 package org.scilab.modules.scinotes;
14
15 import java.lang.reflect.InvocationTargetException;
16 import java.lang.reflect.Method;
17 import java.util.Map;
18 import java.util.HashMap;
19 import java.io.File;
20 import java.io.IOException;
21
22 import javax.swing.JPopupMenu;
23 import javax.swing.KeyStroke;
24 import javax.xml.parsers.DocumentBuilder;
25 import javax.xml.parsers.DocumentBuilderFactory;
26 import javax.xml.parsers.ParserConfigurationException;
27
28 import org.w3c.dom.Document;
29 import org.w3c.dom.Element;
30 import org.w3c.dom.Node;
31 import org.w3c.dom.NodeList;
32 import org.xml.sax.SAXException;
33
34 import org.scilab.modules.commons.xml.ScilabDocumentBuilderFactory;
35 import org.scilab.modules.gui.menu.Menu;
36 import org.scilab.modules.gui.menu.ScilabMenu;
37 import org.scilab.modules.gui.bridge.menu.SwingScilabMenu;
38 import org.scilab.modules.gui.menubar.MenuBar;
39 import org.scilab.modules.gui.menubar.ScilabMenuBar;
40 import org.scilab.modules.gui.bridge.menuitem.SwingScilabMenuItem;
41 import org.scilab.modules.gui.menuitem.MenuItem;
42 import org.scilab.modules.gui.checkboxmenuitem.CheckBoxMenuItem;
43 import org.scilab.modules.gui.bridge.checkboxmenuitem.SwingScilabCheckBoxMenuItem;
44 import org.scilab.modules.gui.pushbutton.PushButton;
45 import org.scilab.modules.gui.textbox.ScilabTextBox;
46 import org.scilab.modules.gui.textbox.TextBox;
47 import org.scilab.modules.gui.toolbar.ScilabToolBar;
48 import org.scilab.modules.gui.toolbar.ToolBar;
49 import org.scilab.modules.gui.window.SimpleWindow;
50 import org.scilab.modules.localization.Messages;
51 import org.scilab.modules.scinotes.utils.ConfigSciNotesManager;
52
53 /**
54  * Class SciNotesGUI handles menus, bar, ...
55  */
56 public final class SciNotesGUI {
57
58     private static final String MENU_CONF = System.getenv("SCI") + "/modules/scinotes/etc/scinotesGUIConfiguration.xml";
59     private static final String ERROR_READ = "Could not load file: ";
60     private static final String MENUBAR = "MenuBar";
61     private static final String TOOLBAR = "ToolBar";
62     private static final String RIGHTCLICKMENU = "RightClickMenu";
63     private static final String MENU = "menu";
64     private static final String MNEMONIC = "mnemonic";
65     private static final String LABEL = "label";
66     private static final String MENUITEM = "menuitem";
67     private static final String ACTION = "action";
68     private static final String SEPARATOR = "separator";
69     private static final String TOOLTIP = "tooltip";
70     private static final String ICON = "icon";
71     private static final String BUTTON = "button";
72     private static final String DOT = ".";
73
74     private static final String DEFAULTACTIONPATH = "org.scilab.modules.scinotes.actions";
75
76     private static Document menuConf;
77
78     private static Map<SciNotes, MenuBar> mapMenuBar = new HashMap<SciNotes, MenuBar>();
79     private static Map<SciNotes, ToolBar> mapToolBar = new HashMap<SciNotes, ToolBar>();
80     private static Map<SciNotes, JPopupMenu> mapPopup = new HashMap<SciNotes, JPopupMenu>();
81     private static Map<SciNotes, TextBox> mapInfoBar = new HashMap<SciNotes, TextBox>();
82
83     /**
84      * initialize the window
85      * @param mainWindow Windows
86      * @param editorInstance SciNotes
87      * @param title the title
88      */
89     public static void init(SimpleWindow mainWindow, final SciNotes editorInstance, String title) {
90         mainWindow.setTitle(title);
91         mainWindow.addTab(editorInstance);
92
93         // Set SciNotes Window position /size
94         mainWindow.setTitle(title);
95         mainWindow.setVisible(true);
96
97         init(editorInstance);
98     }
99
100     /**
101      * Initialize SciNotes
102      * @param editorInstance SciNotes
103      */
104     public static void init(SciNotes editorInstance) {
105         editorInstance.setMenuBar(generateMenuBar(editorInstance));
106         editorInstance.setToolBar(generateToolBar(editorInstance));
107         editorInstance.setInfoBar(generateInfoBar(editorInstance));
108     }
109
110     /**
111      * Initialize SciNotes
112      * @param editorInstance SciNotes
113      */
114     public static void reinitMenus(SciNotes editorInstance) {
115         mapMenuBar.remove(editorInstance);
116         mapPopup.remove(editorInstance);
117         editorInstance.setMenuBar(generateMenuBar(editorInstance));
118     }
119
120     /**
121      * @param editor the editor
122      * @return the infobar of the editor
123      */
124     public static TextBox generateInfoBar(SciNotes editor) {
125         if (mapInfoBar.containsKey(editor)) {
126             return mapInfoBar.get(editor);
127         }
128
129         TextBox info = ScilabTextBox.createTextBox();
130         mapInfoBar.put(editor, info);
131
132         return info;
133     }
134
135     /**
136      * @param editor the editor
137      * @return the JPopupMenu read in the conf file
138      */
139     public static JPopupMenu generateRightClickPopup(SciNotes editor) {
140         if (mapPopup.containsKey(editor)) {
141             return mapPopup.get(editor);
142         }
143
144         readMenusConf();
145         JPopupMenu popup = new JPopupMenu();
146         Element root = menuConf.getDocumentElement();
147         Element rightmenu = (Element) root.getElementsByTagName(RIGHTCLICKMENU).item(0);
148         NodeList menus = rightmenu.getChildNodes();
149         for (int i = 0; i < menus.getLength(); i++) {
150             Node item = menus.item(i);
151             if (MENUITEM.equals(item.getNodeName())) {
152                 Element elem = (Element) item;
153                 Object menuitem = getMenuItem(elem.getAttribute(ACTION), elem.getAttribute(LABEL), editor);
154                 if (menuitem != null) {
155                     if (menuitem instanceof CheckBoxMenuItem) {
156                         SwingScilabCheckBoxMenuItem checkbox = (SwingScilabCheckBoxMenuItem) ((CheckBoxMenuItem) menuitem).getAsSimpleCheckBoxMenuItem();
157                         popup.add(checkbox);
158                     } else if (menuitem instanceof MenuItem) {
159                         SwingScilabMenuItem smi = (SwingScilabMenuItem) ((MenuItem) menuitem).getAsSimpleMenuItem();
160                         popup.add(smi);
161                     } else if (menuitem instanceof Menu) {
162                         SwingScilabMenu sm = (SwingScilabMenu) ((Menu) menuitem).getAsSimpleMenu();
163                         popup.add(sm);
164                     }
165                 }
166             } else if (SEPARATOR.equals(item.getNodeName())) {
167                 popup.addSeparator();
168             } else if (MENU.equals(item.getNodeName())) {
169                 SwingScilabMenu sm = (SwingScilabMenu) getMenu(editor, (Element) item).getAsSimpleMenu();
170                 popup.add(sm);
171             }
172         }
173         mapPopup.put(editor, popup);
174
175         return popup;
176     }
177
178     /**
179      * @param editor the editor
180      * @return the ToolBar read in the conf file
181      */
182     public static ToolBar generateToolBar(SciNotes editor) {
183         if (mapToolBar.containsKey(editor)) {
184             return mapToolBar.get(editor);
185         }
186
187         readMenusConf();
188         ToolBar toolBar = ScilabToolBar.createToolBar();
189         Element root = menuConf.getDocumentElement();
190         Element toolbar = (Element) root.getElementsByTagName(TOOLBAR).item(0);
191         NodeList buttons = toolbar.getChildNodes();
192         for (int i = 0; i < buttons.getLength(); i++) {
193             Node node = buttons.item(i);
194             if (BUTTON.equals(node.getNodeName())) {
195                 Element elem = (Element) node;
196                 PushButton pb = (PushButton) getButton(elem.getAttribute(ACTION), elem.getAttribute(TOOLTIP), elem.getAttribute(ICON), editor);
197                 toolBar.add(pb);
198             } else if (SEPARATOR.equals(node.getNodeName())) {
199                 toolBar.addSeparator();
200             }
201         }
202         mapToolBar.put(editor, toolBar);
203
204         return toolBar;
205     }
206
207     /**
208      * @param editor the editor
209      * @return the MenuBar read in the conf file
210      */
211     public static MenuBar generateMenuBar(SciNotes editor) {
212         if (mapMenuBar.containsKey(editor)) {
213             return mapMenuBar.get(editor);
214         }
215
216         readMenusConf();
217         MenuBar menuBar = ScilabMenuBar.createMenuBar();
218         Element root = menuConf.getDocumentElement();
219         Element menubar = (Element) root.getElementsByTagName(MENUBAR).item(0);
220         NodeList menus = menubar.getChildNodes();
221         for (int i = 0; i < menus.getLength(); i++) {
222             Node node = menus.item(i);
223             if (MENU.equals(node.getNodeName())) {
224                 menuBar.add(getMenu(editor, (Element) node));
225             }
226         }
227         mapMenuBar.put(editor, menuBar);
228
229         return menuBar;
230     }
231
232     /**
233      * Read the conf file
234      */
235     private static void readMenusConf() {
236         File xml = null;
237         DocumentBuilder docBuilder = null;
238
239         try {
240             if (menuConf == null) {
241                 DocumentBuilderFactory factory = ScilabDocumentBuilderFactory.newInstance();
242                 docBuilder = factory.newDocumentBuilder();
243                 xml = new File(MENU_CONF);
244                 menuConf = docBuilder.parse(xml);
245             }
246         } catch (ParserConfigurationException pce) {
247             System.err.println(ERROR_READ + MENU_CONF);
248         } catch (SAXException se) {
249             System.err.println(ERROR_READ + MENU_CONF);
250         } catch (IOException ioe) {
251             System.err.println(ERROR_READ + MENU_CONF);
252         }
253     }
254
255     /**
256      * @param editor the editor
257      * @param node the node containing the informations
258      * @return the Menu
259      */
260     private static Menu getMenu(SciNotes editor, Element node) {
261         Menu menu = ScilabMenu.createMenu();
262         menu.setText(Messages.gettext(node.getAttribute(LABEL)));
263         String mnemonic = node.getAttribute(MNEMONIC);
264         if (mnemonic != null && mnemonic.length() != 0) {
265             menu.setMnemonic(mnemonic.charAt(0));
266         }
267         NodeList elements = node.getChildNodes();
268         for (int i = 0; i < elements.getLength(); i++) {
269             Node item = elements.item(i);
270             if (MENUITEM.equals(item.getNodeName())) {
271                 Element elem = (Element) item;
272                 Object menuitem = getMenuItem(elem.getAttribute(ACTION), elem.getAttribute(LABEL), editor);
273                 if (menuitem != null) {
274                     if (menuitem instanceof CheckBoxMenuItem) {
275                         menu.add((CheckBoxMenuItem) menuitem);
276                     } else if (menuitem instanceof MenuItem) {
277                         menu.add((MenuItem) menuitem);
278                     } else if (menuitem instanceof Menu) {
279                         menu.add((Menu) menuitem);
280                     }
281                 }
282             } else if (SEPARATOR.equals(item.getNodeName())) {
283                 menu.addSeparator();
284             } else if (MENU.equals(item.getNodeName())) {
285                 menu.add(getMenu(editor, (Element) item));
286             }
287         }
288
289         return menu;
290     }
291
292     /**
293      * @param action a string with the action associated with the button
294      * @param label the title of the menu
295      * @param editor the editor
296      * @return a MenuItem or a CheckBoxMenuItem or a Menu
297      */
298     private static Object getMenuItem(String action, String label, SciNotes editor) {
299         ClassLoader loader = ClassLoader.getSystemClassLoader();
300         String className = "";
301         Method method = null;
302         String actionClass = SciNotes.getActionName().get(action);
303         try {
304             if (action.lastIndexOf(DOT) != -1)  {
305                 className = actionClass;
306             } else {
307                 className = DEFAULTACTIONPATH + DOT + actionClass;
308             }
309             Class clazz = loader.loadClass(className);
310             method = clazz.getMethod("createMenu", new Class[] {String.class, SciNotes.class, KeyStroke.class});
311         } catch (ClassNotFoundException e) {
312             System.err.println("No action: " + className);
313         } catch (NoSuchMethodException e) {
314             System.err.println("No valid method createMenu in action: " + className);
315         }
316
317         if (method == null) {
318             return null;
319         }
320
321         try {
322             return method.invoke(null, new Object[] {Messages.gettext(label), editor, SciNotes.getActionKeys().get(action)});
323         } catch (InvocationTargetException e) {
324             System.err.println("Warning: problem to create the menu for action: " + className);
325             System.err.println("The menu label is: " + Messages.gettext(label));
326             System.err.println("English version will be used instead.");
327             System.err.println("Please report a bug at: http://bugzilla.scilab.org");
328             try {
329                 return method.invoke(null, new Object[] {label, editor, SciNotes.getActionKeys().get(action)});
330             } catch (InvocationTargetException ex) {
331                 System.err.println("Problem to create menu of the action: " + className);
332             } catch (IllegalAccessException ex) {
333                 System.err.println("The method createMenu must be public: " + className);
334             }
335         } catch (IllegalAccessException e) {
336             System.err.println("The method createMenu must be public: " + className);
337         }
338
339         return null;
340     }
341
342     /**
343      * @param action a string with the action associated with the button
344      * @param tooltip a string with the tooltip
345      * @param icon the icon name
346      * @param editor the editor
347      * @return the button
348      */
349     private static Object getButton(String action, String tooltip, String icon, SciNotes editor) {
350         ClassLoader loader = ClassLoader.getSystemClassLoader();
351         String className = "";
352         String actionClass = SciNotes.getActionName().get(action);
353         try {
354             if (action.lastIndexOf(DOT) != -1)  {
355                 className = actionClass;
356             } else {
357                 className = DEFAULTACTIONPATH + DOT + actionClass;
358             }
359             Class clazz = loader.loadClass(className);
360             Method method = clazz.getMethod("createButton", new Class[] {String.class, String.class, SciNotes.class});
361             return method.invoke(null, new Object[] {Messages.gettext(tooltip), icon, editor});
362         } catch (ClassNotFoundException e) {
363             System.err.println("No action: " + className);
364         } catch (NoSuchMethodException e) {
365             System.err.println("No valid method createButton in action: " + className);
366         } catch (IllegalAccessException e) {
367             System.err.println("The method createButton must be public: " + className);
368         } catch (InvocationTargetException e) {
369             System.err.println("The method createButton in " + className + " threw an exception :");
370             e.printStackTrace();
371         }
372
373         return null;
374     }
375 }