b25127fcb596f96dde6d1f5ff5270d6060e8701e
[scilab.git] / scilab / modules / scinotes / src / java / org / scilab / modules / scinotes / HelpOnTypingManager.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
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.1-en.txt
10  *
11  */
12
13 package org.scilab.modules.scinotes;
14
15 import java.awt.event.KeyListener;
16 import java.awt.event.KeyEvent;
17
18 import javax.swing.text.BadLocationException;
19
20 import org.scilab.modules.commons.xml.XConfiguration;
21
22 /**
23  * This class handles the help on typing
24  * @author Calixte DENIZET
25  */
26 public final class HelpOnTypingManager implements KeyListener {
27
28     private static HelpOnTypingManager instance;
29     private static boolean openers;
30     private static boolean keywords;
31
32     /**
33      * Constructor
34      */
35     private HelpOnTypingManager() {
36         super();
37         instance = this;
38         openers = SciNotesOptions.getSciNotesDisplay().autoCompleteOpeners;
39         keywords = SciNotesOptions.getSciNotesDisplay().autoCompleteKeywords;
40     }
41
42     /**
43      * Clean
44      */
45     public static void close() {
46         instance = null;
47     }
48
49     /**
50      * @return the singleton instance of HelpOnTypingManager
51      */
52     public static HelpOnTypingManager getInstance() {
53         if (instance == null) {
54             instance = new HelpOnTypingManager();
55         }
56
57         return instance;
58     }
59
60     /**
61      * @param b true if autocompletion on '(', '{', ...
62      */
63     public static void enableOpeners(boolean b) {
64         openers = b;
65         SciNotesOptions.getSciNotesDisplay().autoCompleteOpeners = b;
66         XConfiguration.set(XConfiguration.getXConfigurationDocument(), SciNotesOptions.DISPLAYPATH + "/@auto-complete-openers", Boolean.toString(b));
67     }
68
69     /**
70      * @param b true if autocompletion on 'if', 'function', ...
71      */
72     public static void enableKeywords(boolean b) {
73         keywords = b;
74         SciNotesOptions.getSciNotesDisplay().autoCompleteKeywords = b;
75         XConfiguration.set(XConfiguration.getXConfigurationDocument(), SciNotesOptions.DISPLAYPATH + "/@auto-complete-keywords", Boolean.toString(b));
76     }
77
78     /**
79      * @return true if help on typing is active
80      */
81     public static boolean isActive() {
82         return openers || keywords;
83     }
84
85     /**
86      * @return true if help on typing for the openers is active
87      */
88     public static boolean isOpenersActive() {
89         return openers;
90     }
91
92     /**
93      * @return true if help on typing for the openers is active
94      */
95     public static boolean isKeywordsActive() {
96         return keywords;
97     }
98
99     /**
100      * Nothing !
101      * @param e the event
102      */
103     public void keyPressed(KeyEvent e) { }
104
105     /**
106      * Nothing !
107      * @param e the event
108      */
109     public void keyReleased(KeyEvent e) { }
110
111     /**
112      * Called when a key is typed
113      * @param e the event
114      */
115     public void keyTyped(KeyEvent e) {
116         char c = e.getKeyChar();
117         ScilabEditorPane textPane = ScilabEditorPane.getFocusedPane();
118         ScilabDocument doc = (ScilabDocument) textPane.getDocument();
119         if (isActive() && c != KeyEvent.CHAR_UNDEFINED && textPane.getSelectionStart() == textPane.getSelectionEnd()) {
120             int pos = textPane.getCaretPosition();
121             if (c == ' ' && e.getModifiers() == 0) {
122                 int end = doc.getDefaultRootElement().getElement(doc.getDefaultRootElement().getElementIndex(pos)).getEndOffset() - 1;
123                 /* the following test is used to know if an insertion in the line is done */
124                 if (pos == end) {
125                     try {
126                         doc.insertString(pos, " ", null);
127                         e.consume();
128                         KeywordEvent kwe = textPane.getKeywordEvent(pos);
129                         int[] ret;
130                         String kw;
131                         switch (kwe.getType()) {
132                             case ScilabLexerConstants.OSKEYWORD :
133                                 kw = doc.getText(kwe.getStart(), kwe.getLength());
134                                 if ("if".equals(kw)) {
135                                     doc.insertString(pos + 1, " then\nend", null);
136                                     ret = textPane.getIndentManager().indentDoc(pos + 1, pos + 9);
137                                     textPane.setCaretPosition(ret[0]);
138                                 } else if (!"end".equals(kw)) {
139                                     doc.insertString(pos + 1, "\nend", null);
140                                     ret = textPane.getIndentManager().indentDoc(pos + 1, pos + 4);
141                                     textPane.setCaretPosition(ret[0]);
142                                 }
143                                 break;
144                             case ScilabLexerConstants.SKEYWORD :
145                                 kw = doc.getText(kwe.getStart(), kwe.getLength());
146                                 if ("elseif".equals(kw)) {
147                                     doc.insertString(pos + 1, " then", null);
148                                     textPane.setCaretPosition(pos + 1);
149                                 }
150                                 break;
151                             case ScilabLexerConstants.FKEYWORD :
152                                 /* We have 'function' or 'endfunction' */
153                                 if ("f".equals(doc.getText(kwe.getStart(), 1))) {
154                                     doc.insertString(pos + 1, "()\nendfunction", null);
155                                     textPane.getIndentManager().indentDoc(pos + 3, pos + 14);
156                                     textPane.setCaretPosition(pos + 1);
157                                 }
158                                 break;
159                             default :
160                         }
161                     } catch (BadLocationException exc) {
162                         System.err.println(exc);
163                     }
164                 }
165             } else if (openers) {
166                 try {
167                     char ch = doc.getText(pos, 1).charAt(0);
168                     if (c == ch && (c == ')' || c == ']' || c == '}' || c == '\"')) {
169                         e.consume();
170                         textPane.setCaretPosition(pos + 1);
171                         return;
172                     }
173                 } catch (BadLocationException exc) {
174                     System.err.println(exc);
175                 }
176
177                 String str = null;
178                 switch (c) {
179                     case '(' :
180                         str = "()";
181                         break;
182                     case '[' :
183                         str = "[]";
184                         break;
185                     case '{' :
186                         str = "{}";
187                         break;
188                     case '\"' :
189                         str = "\"\"";
190                         break;
191                     default :
192                 }
193
194                 if (str != null) {
195                     try {
196                         doc.insertString(pos, str, null);
197                         e.consume();
198                         textPane.setCaretPosition(pos + 1);
199                     } catch (BadLocationException exc) {
200                         System.err.println(exc);
201                     }
202                 }
203             }
204         }
205     }
206 }