Typo: dictionnary -> dictionary
[scilab.git] / scilab / modules / scinotes / src / java / org / scilab / modules / scinotes / actions / SciNotesCompletionAction.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2010 - Calixte DENIZET
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  */
15
16 package org.scilab.modules.scinotes.actions;
17
18 import java.awt.Point;
19 import java.awt.Rectangle;
20 import java.awt.event.ActionEvent;
21 import java.awt.event.ActionListener;
22 import java.util.ArrayList;
23 import java.util.List;
24
25 import javax.swing.JComponent;
26 import javax.swing.KeyStroke;
27 import javax.swing.ActionMap;
28 import javax.swing.InputMap;
29 import javax.swing.text.Element;
30 import javax.swing.text.StyledDocument;
31 import javax.swing.text.BadLocationException;
32
33 import com.artenum.rosetta.core.CompletionItemImpl;
34 import com.artenum.rosetta.interfaces.core.CompletionItem;
35 import com.artenum.rosetta.interfaces.core.InputParsingManager;
36 import com.artenum.rosetta.interfaces.core.HistoryManager;
37 import com.artenum.rosetta.interfaces.core.GenericInterpreter;
38 import com.artenum.rosetta.interfaces.core.ConsoleConfiguration;
39 import com.artenum.rosetta.interfaces.core.CompletionManager;
40 import com.artenum.rosetta.interfaces.ui.CompletionWindow;
41 import com.artenum.rosetta.interfaces.ui.OutputView;
42 import com.artenum.rosetta.interfaces.ui.PromptView;
43 import com.artenum.rosetta.interfaces.ui.InputCommandView;
44
45 import org.scilab.modules.completion.Completion;
46 import org.scilab.modules.console.CompletionAction;
47 import org.scilab.modules.console.SciCompletionManager;
48 import org.scilab.modules.console.SciInputParsingManager;
49
50 import org.scilab.modules.gui.menuitem.MenuItem;
51 import org.scilab.modules.gui.menuitem.ScilabMenuItem;
52 import org.scilab.modules.gui.bridge.menuitem.SwingScilabMenuItem;
53
54 import org.scilab.modules.localization.Messages;
55
56 import org.scilab.modules.scinotes.KeywordEvent;
57 import org.scilab.modules.scinotes.SciNotes;
58 import org.scilab.modules.scinotes.ScilabDocument;
59 import org.scilab.modules.scinotes.ScilabEditorPane;
60 import org.scilab.modules.scinotes.ScilabLexerConstants;
61 import org.scilab.modules.scinotes.utils.SciNotesCompletionWindow;
62
63 /**
64  * @author Calixte DENIZET
65  */
66 @SuppressWarnings(value = { "serial" })
67 public final class SciNotesCompletionAction extends CompletionAction {
68
69     private SciNotes editor;
70
71     /**
72      * Constructor
73      * @param textPane the pane associated
74      * @param editor SciNotes
75      */
76     public SciNotesCompletionAction(JComponent textPane, SciNotes editor) {
77         this.editor = editor;
78         configuration = new SciNotesCompletionConfiguration();
79     }
80
81     /**
82      * Constructor
83      * @param editor SciNotes
84      */
85     public SciNotesCompletionAction(SciNotes editor) {
86         this.editor = editor;
87     }
88
89     /**
90      * Constructor
91      * @param name unused parameter
92      * @param editor SciNotes
93      */
94     public SciNotesCompletionAction(String name, SciNotes editor) {
95         this.editor = editor;
96     }
97
98     /**
99      * {@inheritDoc}
100      */
101     public void actionPerformed(ActionEvent actionEvent) {
102         if (configuration == null) {
103             configuration = new SciNotesCompletionConfiguration();
104         }
105         configuration.getCompletionWindow().setGraphicalContext(editor.getTextPane());
106         super.actionPerformed(actionEvent);
107     }
108
109     /**
110      * createMenu
111      * @param label label of the menu
112      * @param editor SciNotes
113      * @param key KeyStroke
114      * @return MenuItem
115      */
116     public static MenuItem createMenu(String label, final SciNotes editor, KeyStroke key) {
117         MenuItem menu = ScilabMenuItem.createMenuItem();
118         menu.setText(label);
119         ((SwingScilabMenuItem) menu.getAsSimpleMenuItem()).addActionListener(new ActionListener() {
120             private SciNotesCompletionAction action;
121             public void actionPerformed(ActionEvent actionEvent) {
122                 if (action == null) {
123                     action = new SciNotesCompletionAction(editor);
124                 }
125                 action.actionPerformed(actionEvent);
126             }
127         });
128
129         if (key != null) {
130             ((SwingScilabMenuItem) menu.getAsSimpleMenuItem()).setAccelerator(key);
131         }
132
133         return menu;
134     }
135
136     /**
137      * Inner class to manage the completion
138      */
139     class SciNotesInputParsingManager extends SciInputParsingManager {
140
141         /**
142          * Reset
143          */
144         public void reset() {
145             try {
146                 ((ScilabDocument) editor.getTextPane().getDocument()).setFocused(true);
147                 Element root = editor.getTextPane().getDocument().getDefaultRootElement();
148                 int pos = editor.getTextPane().getCaretPosition();
149                 int line = root.getElementIndex(pos);
150                 int start = root.getElement(line).getStartOffset();
151                 editor.getTextPane().getDocument().remove(start, pos - start);
152                 editor.getTextPane().setCaretPosition(start);
153             } catch (BadLocationException e) { }
154         }
155
156         /**
157          * @return the caret position
158          */
159         public int getCaretPosition() {
160             Element root = editor.getTextPane().getDocument().getDefaultRootElement();
161             int pos = editor.getTextPane().getCaretPosition();
162             int line = root.getElementIndex(pos);
163             int start = root.getElement(line).getStartOffset();
164             return pos - start;
165         }
166
167         /**
168          * @return the commandLine
169          */
170         public String getCommandLine() {
171             try {
172                 Element root = editor.getTextPane().getDocument().getDefaultRootElement();
173                 int pos = editor.getTextPane().getCaretPosition();
174                 int line = root.getElementIndex(pos);
175                 int start = root.getElement(line).getStartOffset();
176                 KeywordEvent ke = editor.getTextPane().getKeywordEvent();
177                 if (ke.getType() == ScilabLexerConstants.FIELD) {
178                     ke = editor.getTextPane().getKeywordEvent(ke.getStart() - 1);
179                     if (ke.getType() == ScilabLexerConstants.ID) {
180                         // Here we try to complete a field of an unknown variable so
181                         // we suppose that it will be a handle
182                         return "";
183                     }
184                 }
185                 return editor.getTextPane().getDocument().getText(start, pos - start);
186             } catch (BadLocationException e) { }
187             return "";
188         }
189
190         /**
191          * @param content to append
192          */
193         public void append(String content) {
194             try {
195                 ScilabDocument doc = (ScilabDocument) editor.getTextPane().getDocument();
196                 doc.setFocused(true);
197                 Element root = editor.getTextPane().getDocument().getDefaultRootElement();
198                 int pos = editor.getTextPane().getCaretPosition();
199                 doc.mergeEditsBegin();
200                 editor.getTextPane().getDocument().insertString(pos, content, null);
201                 doc.mergeEditsEnd();
202             } catch (BadLocationException e) { }
203         }
204
205         /**
206          * @return a Point where to put the completion window
207          */
208         public Point getWindowCompletionLocation() {
209             try {
210                 int pos = editor.getTextPane().getCaretPosition();
211                 Rectangle r = editor.getTextPane().modelToView(pos);
212                 return new Point(r.x, r.y + r.height);
213             } catch (BadLocationException e) { }
214             return new Point(0, 0);
215         }
216
217         /**
218          * @return an int
219          */
220         public int getCompletionLevel() {
221             return 0;
222         }
223
224         /**
225          * @param level an int
226          * @return a String to be completed
227          */
228         public String getPartLevel(int level) {
229             return Completion.getPartLevel(getCommandLine());
230         }
231
232         /**
233          * Return an empty string to be sure that word won't be completed
234          * into filename.
235          * @param level an unused int
236          * @return a String
237          */
238         public String getFilePartLevel(int level) {
239             return "";
240         }
241
242         /**
243          * @param completionResult a String
244          */
245         public void writeCompletionPart(String completionResult) { }
246
247         /**
248          * @return an int
249          */
250         public int getNumberOfLines() {
251             return 0;
252         }
253
254         /**
255          * @return a boolean
256          */
257         public boolean isBlockEditing() {
258             return true;
259         }
260
261         /**
262          * @param inputCommandView an InputCommandView
263          */
264         public void setInputCommandView(InputCommandView inputCommandView) { }
265
266         /**
267          * Put a backspace
268          */
269         public void backspace() {
270             try {
271                 Element root = editor.getTextPane().getDocument().getDefaultRootElement();
272                 int pos = editor.getTextPane().getCaretPosition();
273                 editor.getTextPane().getDocument().remove(pos - 1, 1);
274                 editor.getTextPane().setCaretPosition(pos - 1);
275             } catch (BadLocationException e) { }
276         }
277     }
278
279     /**
280      * Inner class to handle special completion case in SciNotes.
281      * When a field name is met, we can suppose that is a handle.
282      */
283     class SciNotesCompletionManager extends SciCompletionManager {
284
285         /**
286          * {@inheritDoc}
287          */
288         public SciNotesCompletionManager() {
289             super();
290         }
291
292         /**
293          * {@inheritDoc}
294          */
295         public List<CompletionItem> getCompletionItems() {
296             List<CompletionItem> list = super.getCompletionItems();
297             if (list.isEmpty()) {
298                 ScilabEditorPane sep = editor.getTextPane();
299                 KeywordEvent ke = sep.getKeywordEvent();
300                 String searchedPattern = null;
301                 boolean handle = false;
302                 try {
303                     if (ke.getType() == ScilabLexerConstants.OPERATOR) {
304                         String str = sep.getDocument().getText(ke.getStart(), ke.getLength());
305                         if (str.equals(".")) {
306                             searchedPattern = " ";
307                         }
308                     } else if (ke.getType() == ScilabLexerConstants.FIELD) {
309                         searchedPattern = sep.getDocument().getText(ke.getStart(), ke.getLength());
310                     }
311                 } catch (BadLocationException e) {
312                     System.err.println(e);
313                 }
314
315                 String[] scilabHandlesDictionary = Completion.searchHandleGraphicsPropertiesDictionary(searchedPattern);
316                 String type = Messages.gettext("Graphics handle field");
317
318                 list = new ArrayList<CompletionItem>();
319                 if (scilabHandlesDictionary != null) {
320                     for (String item : scilabHandlesDictionary) {
321                         dictionary.add(new CompletionItemImpl(type, item + " (" + type + ")", item, Messages.gettext("No help")));
322                     }
323                 }
324
325                 return dictionary;
326             }
327             return list;
328         }
329     }
330
331     /**
332      * Inner class which implements interface ConsoleConfiguration.
333      * Only use to be compatible with the way to complete in the console
334      */
335     class SciNotesCompletionConfiguration implements ConsoleConfiguration {
336
337         private SciNotesInputParsingManager xipm = new SciNotesInputParsingManager();
338         private SciCompletionManager scm = new SciNotesCompletionManager();
339         private SciNotesCompletionWindow cwi;
340
341         /**
342          * Constructor
343          * @param textPane where to complete
344          */
345         public SciNotesCompletionConfiguration() {
346             scm.setInputParsingManager(xipm);
347             cwi = new SciNotesCompletionWindow(editor, scm);
348             cwi.setInputParsingManager(xipm);
349             cwi.setGraphicalContext(editor.getTextPane());
350         }
351
352         /**
353          * @return an InputParsingManager
354          */
355         public InputParsingManager getInputParsingManager() {
356             return xipm;
357         }
358
359         /**
360          * Returns the current completion manager
361          * @return the completion manager
362          */
363         public CompletionManager getCompletionManager() {
364             return scm;
365         }
366
367         /**
368          * @return the CompletionWindow
369          */
370         public CompletionWindow getCompletionWindow() {
371             return cwi;
372         }
373
374         /**
375          * @return null
376          */
377         public PromptView getPromptView() {
378             return null;
379         }
380
381         /**
382          * @return null
383          */
384         public OutputView getOutputView() {
385             return null;
386         }
387
388         /**
389          * @return null
390          */
391         public InputCommandView getInputCommandView() {
392             return null;
393         }
394
395         /**
396          * @return null
397          */
398         public StyledDocument getOutputViewStyledDocument() {
399             return null;
400         }
401
402         /**
403          * @return null
404          */
405         public StyledDocument getInputCommandViewStyledDocument() {
406             return null;
407         }
408
409         /**
410          * @return null
411          */
412         public HistoryManager getHistoryManager() {
413             return null;
414         }
415
416         /**
417          * @return null
418          */
419         public String getBackgroundColor() {
420             return null;
421         }
422
423         /**
424          * @return null
425          */
426         public String getForegroundColor() {
427             return null;
428         }
429
430         /**
431          * @return 0
432          */
433         public int getScrollableUnitIncrement() {
434             return 0;
435         }
436
437         /**
438          * @return 0
439          */
440         public int getScrollableBlockIncrement() {
441             return 0;
442         }
443
444         /**
445          * @return true
446          */
447         public boolean getHorizontalWrapAllowed() {
448             return true;
449         }
450
451         /**
452          * @return true
453          */
454         public boolean getVerticalWrapAllowed() {
455             return true;
456         }
457
458         /**
459          * @return null
460          */
461         public String getFontName() {
462             return null;
463         }
464
465         /**
466          * @return 0
467          */
468         public int getFontStyle() {
469             return 0;
470         }
471
472         /**
473          * @return 0
474          */
475         public int getFontSize() {
476             return 0;
477         }
478
479         /**
480          * @return null
481          */
482         public String getWelcomeLine() {
483             return null;
484         }
485
486         /**
487          * @return null
488          */
489         public GenericInterpreter getGenericInterpreter() {
490             return null;
491         }
492
493         /**
494          * @return null
495          */
496         public ActionMap getActionMapping() {
497             return null;
498         }
499
500         /**
501          * @param profileName a String
502          */
503         public void setActiveProfile(String profileName) { }
504
505         /**
506          * @return null
507          */
508         public String getActiveProfile() {
509             return null;
510         }
511
512         /**
513          * @return null
514          */
515         public InputMap getKeyMapping() {
516             return null;
517         }
518     }
519 }