0acdfe3227d3a0be38bb97429e9941c5e574b352
[scilab.git] / scilab / modules / xpad / src / java / org / scilab / modules / xpad / Xpad.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2009 - DIGITEO - Bruno JOFRET
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.xpad;
14
15 import java.awt.Color;
16 import java.awt.Event;
17 import java.awt.event.KeyEvent;
18 import java.io.File;
19 import java.io.IOException;
20 import java.util.ArrayList;
21 import java.util.Scanner;
22
23 import javax.swing.BorderFactory;
24 import javax.swing.JOptionPane;
25 import javax.swing.JScrollPane;
26 import javax.swing.JTabbedPane;
27 import javax.swing.JTextPane;
28 import javax.swing.KeyStroke;
29 import javax.swing.undo.CannotRedoException;
30 import javax.swing.undo.CannotUndoException;
31 import javax.swing.undo.UndoManager;
32
33 import org.scilab.modules.gui.bridge.tab.SwingScilabTab;
34 import org.scilab.modules.gui.menu.Menu;
35 import org.scilab.modules.gui.menu.ScilabMenu;
36 import org.scilab.modules.gui.menubar.MenuBar;
37 import org.scilab.modules.gui.menubar.ScilabMenuBar;
38 import org.scilab.modules.gui.tab.SimpleTab;
39 import org.scilab.modules.gui.tab.Tab;
40 import org.scilab.modules.gui.textbox.TextBox;
41 import org.scilab.modules.gui.toolbar.ToolBar;
42 import org.scilab.modules.gui.window.ScilabWindow;
43 import org.scilab.modules.gui.window.Window;
44 import org.scilab.modules.xpad.actions.ASCIIEncodingAction;
45 import org.scilab.modules.xpad.actions.AboutAction;
46 import org.scilab.modules.xpad.actions.AutoIndentAction;
47 import org.scilab.modules.xpad.actions.CloseAction;
48 import org.scilab.modules.xpad.actions.ColorizeAction;
49 import org.scilab.modules.xpad.actions.CommentAction;
50 import org.scilab.modules.xpad.actions.CopyAction;
51 import org.scilab.modules.xpad.actions.CutAction;
52 import org.scilab.modules.xpad.actions.DeleteAction;
53 import org.scilab.modules.xpad.actions.EvaluateSelectionAction;
54 import org.scilab.modules.xpad.actions.ExitAction;
55 import org.scilab.modules.xpad.actions.FindAction;
56 import org.scilab.modules.xpad.actions.FindNextAction;
57 import org.scilab.modules.xpad.actions.FindPreviousAction;
58 import org.scilab.modules.xpad.actions.GotoLineAction;
59 import org.scilab.modules.xpad.actions.HelpAction;
60 import org.scilab.modules.xpad.actions.HighlightCurrentLineAction;
61 import org.scilab.modules.xpad.actions.IndentAction;
62 import org.scilab.modules.xpad.actions.LineNumbersAction;
63 import org.scilab.modules.xpad.actions.LoadIntoScilabAction;
64 import org.scilab.modules.xpad.actions.NewAction;
65 import org.scilab.modules.xpad.actions.OpenAction;
66 import org.scilab.modules.xpad.actions.PageSetupAction;
67 import org.scilab.modules.xpad.actions.PasteAction;
68 import org.scilab.modules.xpad.actions.PrintAction;
69 import org.scilab.modules.xpad.actions.PrintPreviewAction;
70 import org.scilab.modules.xpad.actions.RecentFileAction;
71 import org.scilab.modules.xpad.actions.RedoAction;
72 import org.scilab.modules.xpad.actions.ResetFontAction;
73 import org.scilab.modules.xpad.actions.SaveAction;
74 import org.scilab.modules.xpad.actions.SaveAsAction;
75 import org.scilab.modules.xpad.actions.ScilabStyleAction;
76 import org.scilab.modules.xpad.actions.SelectAllAction;
77 import org.scilab.modules.xpad.actions.SetColorsAction;
78 import org.scilab.modules.xpad.actions.SetFontAction;
79 import org.scilab.modules.xpad.actions.ShowToolBarAction;
80 import org.scilab.modules.xpad.actions.TextStyleAction;
81 import org.scilab.modules.xpad.actions.UTF8EncodingAction;
82 import org.scilab.modules.xpad.actions.UnCommentAction;
83 import org.scilab.modules.xpad.actions.UndoAction;
84 import org.scilab.modules.xpad.actions.WordWrapAction;
85 import org.scilab.modules.xpad.actions.XMLStyleAction;
86 import org.scilab.modules.xpad.style.ScilabStyleDocument;
87 import org.scilab.modules.xpad.utils.ConfigXpadManager;
88
89 public class Xpad extends SwingScilabTab implements Tab { 
90
91         private final Window parentWindow;
92         private JTabbedPane tabPane;
93         private JTextPane textPane;
94         private JScrollPane scrollingText;
95         private XpadLineNumberPanel xln;
96
97         private static Xpad editor = null;
98
99         public static void main(String[] args) {
100                 xpad();
101         }
102
103         public static void xpad() {
104                 Xpad editor = launchXpad();
105                 editor.addEmptyTab();
106         }
107
108         public static void xpad(String filePath) {
109                 Xpad editor = launchXpad();
110                 editor.readFile(new File(filePath));
111         }
112
113         private static Xpad launchXpad() {
114                 if (editor == null) {
115                         editor = createEditor();
116                 }
117                 return editor;
118         }
119
120         public static void closeXpad() {
121                 editor = null;
122         }
123
124         private static Xpad createEditor() {
125                 ConfigXpadManager.createUserCopy();     
126                 ArrayList<File> recentFiles = ConfigXpadManager.getAllRecentOpenedFiles() ;
127
128                 Window mainWindow = ScilabWindow.createWindow();
129                 Xpad editor = new Xpad(mainWindow);
130
131                 mainWindow.setTitle("Xpad");
132                 mainWindow.addTab(editor);
133
134                 // Set Xpad Window position /size 
135                 mainWindow.setPosition( ConfigXpadManager.getMainWindowPosition());
136                 mainWindow.setDims(ConfigXpadManager.getMainWindowSize());
137
138                 MenuBar menuBar = ScilabMenuBar.createMenuBar();
139                 //Create FILE menubar
140                 Menu fileMenu = ScilabMenu.createMenu();
141                 fileMenu.setText("File");
142                 fileMenu.setMnemonic('F');
143                 fileMenu.add(new NewAction(editor));
144                 fileMenu.add(new OpenAction(editor));
145                 Menu recentsMenu = ScilabMenu.createMenu();
146                 recentsMenu.setText("Recent Files");
147                 for (int i = 0 ; i < recentFiles.size() ; i++ ){
148                         recentsMenu.add(new RecentFileAction(editor , recentFiles.get(i)));
149                 }
150                 
151                 
152                 fileMenu.add(recentsMenu);
153                 
154                 fileMenu.addSeparator();
155                 fileMenu.add(new SaveAction(editor));
156                 fileMenu.add(new SaveAsAction(editor));
157                 
158                 fileMenu.addSeparator();
159                 fileMenu.add(new PageSetupAction(editor));
160                 fileMenu.add(new PrintPreviewAction(editor));
161                 fileMenu.add(new PrintAction(editor));
162                 
163                 fileMenu.addSeparator();
164                 fileMenu.add(new CloseAction(editor));
165                 
166                 fileMenu.addSeparator();
167                 fileMenu.add(new ExitAction(editor));
168                 menuBar.add(fileMenu);
169
170                 //Create EDIT menubar
171                 Menu editMenu = ScilabMenu.createMenu();
172                 editMenu.setText("Edit"); 
173                 editMenu.setMnemonic('E');
174                 editMenu.add(new UndoAction(editor));
175                 editMenu.add(new RedoAction(editor));
176                 editMenu.addSeparator(); 
177                 editMenu.add(new CutAction(editor));
178                 editMenu.add(new CopyAction(editor));
179                 editMenu.add(new PasteAction(editor));
180                 editMenu.addSeparator(); 
181                 editMenu.add(new SelectAllAction(editor));
182                 editMenu.add(new DeleteAction(editor));
183                 editMenu.addSeparator();
184                 editMenu.add(new CommentAction(editor));
185                 editMenu.add(new UnCommentAction(editor));
186                 editMenu.addSeparator();
187                 editMenu.add(new IndentAction(editor));
188                 menuBar.add(editMenu);
189
190                 // Create SEARCH menubar
191                 Menu searchMenu = ScilabMenu.createMenu(); 
192                 searchMenu.setText("Search");
193                 searchMenu.setMnemonic('S');
194                 searchMenu.add(new FindAction(editor));
195                 searchMenu.add(new FindNextAction(editor));
196                 searchMenu.add(new FindPreviousAction(editor));
197                 searchMenu.add(new GotoLineAction(editor));
198                 menuBar.add(searchMenu);
199
200                 // Create VIEW Menubar
201                 Menu viewMenu = ScilabMenu.createMenu();
202                 viewMenu.setText("View");
203                 viewMenu.add(new ShowToolBarAction(editor));
204                 viewMenu.addSeparator();
205                 viewMenu.add(new HighlightCurrentLineAction(editor));
206                 viewMenu.add(new WordWrapAction(editor));
207                 viewMenu.add(new LineNumbersAction(editor));
208                 viewMenu.add(new SetColorsAction(editor));
209                 viewMenu.add(new SetFontAction(editor));
210                 viewMenu.add(new ResetFontAction(editor));
211                 menuBar.add(viewMenu);
212
213                 // Create DOCUMENT MenuBar
214                 Menu documentMenu = ScilabMenu.createMenu();
215                 documentMenu.setText("Document");
216                 Menu syntaxTypeMenu = ScilabMenu.createMenu();
217                 syntaxTypeMenu.setText("Syntax Type");
218                 documentMenu.add(syntaxTypeMenu);
219                 syntaxTypeMenu.add(new TextStyleAction(editor));
220                 syntaxTypeMenu.add(new ScilabStyleAction(editor));
221                 syntaxTypeMenu.add(new XMLStyleAction(editor));
222                 documentMenu.addSeparator();
223                 Menu encodingTypeMenu = ScilabMenu.createMenu();
224                 encodingTypeMenu.setText("Encoding Type");
225                 documentMenu.add(encodingTypeMenu);
226                 encodingTypeMenu.add(new ASCIIEncodingAction(editor));
227                 encodingTypeMenu.add(new UTF8EncodingAction(editor));
228                 documentMenu.addSeparator();
229                 documentMenu.add(new ColorizeAction(editor));
230                 documentMenu.add(new AutoIndentAction(editor));
231                 menuBar.add(documentMenu);
232
233                 // Create EXECUTE menubar
234                 Menu executeMenu = ScilabMenu.createMenu();
235                 executeMenu.setText("Execute");
236                 executeMenu.setMnemonic('e');
237                 executeMenu.add(new LoadIntoScilabAction(editor));
238                 executeMenu.add(new EvaluateSelectionAction(editor));
239                 menuBar.add(executeMenu);
240
241                 //Create HELP menubar
242                 Menu helpMenu = ScilabMenu.createMenu();
243                 helpMenu.setText("?");
244                 helpMenu.add(new HelpAction(editor));
245                 helpMenu.add(new AboutAction(editor));
246                 menuBar.add(helpMenu);
247
248                 editor.setMenuBar(menuBar);
249                 mainWindow.setTitle("XPad");
250                 mainWindow.setVisible(true);
251                 editor.setCallback((new ExitAction(editor)).getCallback());
252                 return editor;
253         }
254
255         public Xpad(Window parentWindow) {
256                 super("Xpad");
257                 this.parentWindow = parentWindow;
258                 tabPane = new JTabbedPane();
259                 this.setContentPane(tabPane);
260         }
261
262         public void closeCurrentTab() {
263                 tabPane.remove(tabPane.getSelectedComponent());
264         }
265
266         public JTextPane addTab(String title) {
267                 textPane = new JTextPane();
268 // {
269 //                      public boolean getScrollableTracksViewportWidth() {
270 //                              return false;
271 //                      };
272 //              };
273
274                 scrollingText = new JScrollPane(textPane);
275                 
276                 // Panel of line number for the text pane
277                 xln = new XpadLineNumberPanel(textPane);
278                 scrollingText.setRowHeaderView(xln);
279                 
280                 tabPane.add(title, scrollingText);
281                 tabPane.setSelectedIndex(tabPane.getTabCount() - 1);
282                 this.setContentPane(tabPane);
283                 textPane.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
284                 textPane.setFont(ConfigXpadManager.getFont());
285
286                 textPane.setBackground(ConfigXpadManager.getXpadBackgroundColor());
287                 textPane.setCaretColor(Color.BLACK);
288                 textPane.setStyledDocument(new ScilabStyleDocument());
289                 textPane.setCharacterAttributes(textPane.getStyle("Default"), true);
290
291                 textPane.setFocusable(true);
292
293                 KeyStroke key;
294                 key = KeyStroke.getKeyStroke(KeyEvent.VK_Z, Event.CTRL_MASK);
295                 textPane.getInputMap().put(key, new UndoAction(this));
296                 key = KeyStroke.getKeyStroke(KeyEvent.VK_Y, Event.CTRL_MASK);
297                 textPane.getInputMap().put(key, new RedoAction(this));
298                 key = KeyStroke.getKeyStroke(KeyEvent.VK_F, Event.CTRL_MASK);
299                 textPane.getInputMap().put(key, new FindAction(this));
300                 
301                 return textPane;
302         }
303
304         public JTextPane addEmptyTab() {
305                 return addTab("Untitled");
306         }
307
308         public void setAutoIndent(boolean b) {
309                 ((ScilabStyleDocument) getTextPane().getStyledDocument()).setAutoIndent(b);
310         }
311
312         public void undo() {
313                 UndoManager undo = ((ScilabStyleDocument) getTextPane().getStyledDocument()).getUndoManager();
314                 try {
315                         System.err.println("Will undo "+undo.getUndoPresentationName());
316                         undo.undo();
317                 } catch (CannotUndoException ex) {
318                         System.out.println("Unable to undo: " + ex);
319                         ex.printStackTrace();
320                 }
321         }
322
323         public void redo() {
324                 UndoManager redo = ((ScilabStyleDocument) getTextPane().getStyledDocument()).getUndoManager();
325                 try {
326                         System.err.println("Will redo "+redo.getRedoPresentationName());
327                         redo.redo();
328                 } catch (CannotRedoException ex) {
329                         System.out.println("Unable to redo: " + ex);
330                         ex.printStackTrace();
331                 }
332         }
333
334         public void readFile(File f) {
335                 /* First try to open file before creating tab */
336                 try {
337                         StringBuilder contents = new StringBuilder();
338                         Scanner scanner = new Scanner(f);
339                         while (scanner.hasNextLine()) {
340                                 contents.append(scanner.nextLine());
341                                 contents.append(System.getProperty("line.separator"));
342                         }
343                         JTextPane textPane = addTab(f.getName()); 
344                         System.out.println("File = "+f.getAbsolutePath());
345                         textPane.setName(f.getAbsolutePath());
346
347                         ((ScilabStyleDocument) textPane.getStyledDocument()).disableUpdaters(); 
348                         textPane.setText(contents.toString());
349                         if (((ScilabStyleDocument) textPane.getStyledDocument()).getColorize()) {
350                                 ((ScilabStyleDocument) textPane.getStyledDocument()).colorize();
351                         }
352                         if (((ScilabStyleDocument) textPane.getStyledDocument()).getAutoIndent()) {
353                                 ((ScilabStyleDocument) textPane.getStyledDocument()).indent();
354                         }
355                         ((ScilabStyleDocument) textPane.getStyledDocument()).enableUpdaters();
356                 } catch (IOException ioex) {
357                         JOptionPane.showMessageDialog(this, ioex.getMessage());
358                 }
359         }
360
361         public JTextPane getTextPane() {
362                 return (JTextPane) ((JScrollPane) tabPane.getSelectedComponent()).getViewport().getComponent(0);
363         }
364
365         public SimpleTab getAsSimpleTab() {
366                 return this;
367         }
368
369         public Window getParentWindow() {
370                 return parentWindow;
371         }
372
373         public void addInfoBar(TextBox infoBarToAdd) {
374                 setInfoBar(infoBarToAdd);
375         }
376
377         public void addMenuBar(MenuBar menuBarToAdd) {
378                 setMenuBar(menuBarToAdd);
379         }
380
381         public void addToolBar(ToolBar toolBarToAdd) {
382                 setToolBar(toolBarToAdd);
383         }
384
385         public JTabbedPane getTabPane() {
386                 return tabPane;
387         }
388
389         public void setTabPane(JTabbedPane tabPane) {
390                 this.tabPane = tabPane;
391         }
392
393         public XpadLineNumberPanel getXln() {
394                 return xln;
395         }
396
397         public void setXln(XpadLineNumberPanel xln) {
398                 this.xln = xln;
399         }
400         
401         public void displayLineNumbers(boolean display) {
402                 if (display) {
403                         scrollingText.setRowHeaderView(xln);
404                         repaint();
405                 } else {
406                         scrollingText.setRowHeaderView(null);
407                         repaint();
408                 }
409         }
410         
411         public void enableLineHighlight(boolean display) {
412                 xln.setCurrentLineHighlightColor(display);
413                 repaint();
414         }
415
416 }