improved undo/redo , able to load xpad command into scilab -nw
[scilab.git] / scilab / modules / xpad / src / java / org / scilab / modules / xpad / style / ScilabStyleDocument.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.style;
14
15 import java.awt.Color;
16 import java.util.ArrayList;
17 import java.util.Collections;
18 import java.util.Hashtable;
19 import java.util.Vector;
20 import java.util.regex.Matcher;
21 import java.util.regex.Pattern;
22
23 import javax.swing.SwingUtilities;
24 import javax.swing.event.DocumentEvent;
25 import javax.swing.event.DocumentListener;
26 import javax.swing.event.UndoableEditEvent;
27 import javax.swing.text.BadLocationException;
28 import javax.swing.text.DefaultStyledDocument;
29 import javax.swing.text.Style;
30 import javax.swing.text.StyleConstants;
31 import javax.swing.undo.UndoManager;
32
33 import org.scilab.modules.xpad.ScilabKeywords;
34 import org.scilab.modules.xpad.Xpad;
35 import org.scilab.modules.xpad.actions.ColorizeAction;
36 import org.scilab.modules.xpad.actions.IndentAction;
37 import org.scilab.modules.xpad.utils.ConfigXpadManager;
38
39 public class ScilabStyleDocument extends DefaultStyledDocument implements DocumentListener {
40
41         private UndoManager undo = new UndoManager() {
42                 public void undoableEditHappened(UndoableEditEvent e) {
43                                         
44                         if ( (EventType.equals(DocumentEvent.EventType.INSERT.toString()) || EventType.equals(DocumentEvent.EventType.REMOVE.toString()) ) && (e.getEdit().canUndo()) ){
45                                 
46                                 System.out.println("add edit");
47                                 undo.addEdit(e.getEdit());
48                                 
49                                 EventType = "" ;
50                         }
51
52                                         
53                 }
54         };
55
56         private boolean autoIndent = true;
57         private boolean autoColorize = true;
58         private boolean colorizeInprogress = false;
59         private boolean indentInprogress = false;
60         private boolean updaterDisabled = false;
61
62         private String EventType ;
63         
64         //private final String[] quotations = {"[^A-Z](\"|')[^{\n}]*?(\"|')"};
65         private final String[] quotations = {"(\"|')[^{\n}]*?(\"|')"};
66         private final String[] bools = {"%T", "%F", "%t", "%f"};
67         private final String[] comments = {"//[^{\n}]*", "/\\*.*?\\*/"};
68         private final String[] operators = {"=", "\\+", "-", "\\*", "/", "\\\\", "\\^", 
69                         "\\./", "\\.\\\\", "\\.\\^", 
70                         "\\.\\*\\.", "\\./\\.", "\\.\\\\\\.",
71                         "==", "<", ">", "<=", ">=", "~=", "@=",
72                         "&", "\\|", "@", "~",
73         "\\.\\.[\\.]*"};
74
75         private final String IN = "IN";
76         private final String OUT = "OUT";
77         private final String TABULATION = "  ";
78         private final int BOOLS = 0;
79         private final int COMMANDS = 1;
80         private final int COMMENTS = 2;
81         private final int FUNCTIONS = 3;
82         private final int MACROS = 4;
83         private final int OPERATORS = 5;
84         private final int QUOTATIONS = 6;
85         
86         private int lineStartPosition;
87         private int lineEndPosition;
88         private boolean singleLine = false;
89         private int currentLine;
90         
91         private boolean contentModified ;
92         
93         //private XpadStyles xpadStyles ; 
94         
95         Hashtable<String, String[]> keywords;
96         String[] commands;
97         String[] functions;
98         String[] macros;
99         
100         Xpad editor;
101
102         /*if you want to add a new style just add it in the xml*/
103         private ArrayList<String> listStylesName ;
104         //private final String[] allStyles = {"Operator", "Command","String","Bool" ,"Comment"} ;
105         private Style defaultStyle;
106
107
108         public ScilabStyleDocument(Xpad editor) {
109                 super();
110                 EventType = new String();
111                 
112                 this.editor = editor ;
113                 Hashtable< String, Color>stylesColorsTable =  ConfigXpadManager.getAllForegroundColors();
114                 Hashtable< String, Boolean>stylesIsBoldTable = ConfigXpadManager.getAllisBold()  ;
115                 listStylesName  =  ConfigXpadManager.getAllStyleName();
116
117                 //xpadStyles = XpadStyles.getInstance() ;
118                 addDocumentListener(this);
119                 addUndoableEditListener(undo);
120                 defaultStyle = this.addStyle("Default", null);
121                 StyleConstants.setBold(defaultStyle, stylesIsBoldTable.get("Default"));
122                 StyleConstants.setFontFamily(defaultStyle, ConfigXpadManager.getFont().getFontName() );
123                 StyleConstants.setForeground(defaultStyle, stylesColorsTable.get("Default"));
124                 StyleConstants.setFontSize(defaultStyle, ConfigXpadManager.getFontSize());
125                 StyleConstants.setLeftIndent(defaultStyle, 0);
126
127                 /* set default style settings*/
128                 /*that way if we want to had a new style, we just need to had an element to the xml*/
129                 for(int i = 0 ; i < listStylesName.size() ; ++i) {
130                         Style otherStyle = this.addStyle(listStylesName.get(i), defaultStyle);
131                         StyleConstants.setBold(otherStyle, stylesIsBoldTable.get(listStylesName.get(i)));
132                         StyleConstants.setForeground(otherStyle, stylesColorsTable.get(listStylesName.get(i)));
133                 }
134                 
135                 loadingsForColorisation();
136                 setContentModified(false );
137                 
138                 this.addDocumentListener( new DocumentListener(){
139                         
140                          public void changedUpdate(DocumentEvent documentEvent) {
141
142                               }
143                               public void insertUpdate(DocumentEvent documentEvent) {
144                                 handleEvent(documentEvent);
145                               }
146                               public void removeUpdate(DocumentEvent documentEvent) {
147                                   handleEvent(documentEvent);
148                               }
149                               private void handleEvent(DocumentEvent documentEvent) {
150                                 DocumentEvent.EventType type = documentEvent.getType();
151                                 if (type.equals(DocumentEvent.EventType.INSERT) || type.equals(DocumentEvent.EventType.REMOVE) ) {
152                                  
153                                         int index = getEditor().getTabPane().getSelectedIndex();
154                                         if ( ! isContentModified()){
155                                                 getEditor().getTabPane().setTitleAt( index  , "*" + getEditor().getTabPane().getTitleAt(index ) );
156                                         }
157                                         setContentModified(true);
158                                 }  
159
160                               }
161                 });
162                 
163         }
164
165
166         
167         /**
168          * DOCUMENT COLORISATION START
169          */
170         
171         public void loadingsForColorisation() {
172                 // Scilab keywords to be colored
173                 keywords = getScilabKeywords();         
174                 commands = (String[])keywords.get("command");
175                 functions = (String[])keywords.get("function");
176                 macros = (String[])keywords.get("macro");
177
178                 // Regexp for Scilab keywords  (for commands, functions & macros) 
179                 for (int i = 0; i < commands.length; i++) {
180                         commands[i] = "\\b" + commands[i] + "\\b"; 
181                 }       
182                 for (int i = 0; i < functions.length; i++) {
183                         functions[i] = "\\b" + functions[i] + "\\b"; 
184                 }       
185                 for (int i = 0; i < macros.length; i++) {
186                         macros[i] = "\\b" + macros[i] + "\\b"; 
187                 }
188         }
189         
190         public void colorize() {
191                 
192                 singleLine = false;
193                 
194                 // We parse all words which are susceptible to be colored
195                 Vector<Vector<Integer>> boundaries_list = parse(bools, commands, comments, functions, macros, operators, quotations, singleLine, 0, 0);
196
197                 if (!colorizeInprogress) {
198                         colorizeInprogress = true;
199                         this.removeUndoableEditListener(undo);
200                         this.addUndoableEditListener(null);
201                         resetStyle();
202                         try {
203                                 applyStyle(boundaries_list.elementAt(BOOLS), getStyle("Bool"));
204                                 applyStyle(boundaries_list.get(COMMANDS), getStyle("Command"));
205                                 applyStyle(boundaries_list.get(FUNCTIONS), getStyle("Function"));
206                                 applyStyle(boundaries_list.get(MACROS), getStyle("Macro"));
207                                 applyStyle(boundaries_list.get(OPERATORS), getStyle("Operator"));
208                                 applyStyle(boundaries_list.get(QUOTATIONS), getStyle("String"));
209                                 applyStyle(boundaries_list.get(COMMENTS), getStyle("Comment"));
210                         } catch (BadLocationException e) {
211                                 e.printStackTrace();
212                         }
213                         finally {
214                                 this.addUndoableEditListener(undo);
215                                 colorizeInprogress = false;
216                         }
217                 }
218         }
219
220         
221         public void colorizeSingleLine(int lineStartPosition, int lineEndPosition) {
222
223                 singleLine = true;
224
225                 // We parse all words which are susceptible to be colored
226                 Vector<Vector<Integer>> boundaries_list = parse(bools, commands, comments, functions, macros, operators, quotations, singleLine, lineStartPosition, lineEndPosition);
227
228                 if (!colorizeInprogress) {
229                         colorizeInprogress = true;
230                         this.removeUndoableEditListener(undo);
231                         this.addUndoableEditListener(null);
232                         resetSingleLineStyle(lineStartPosition, lineEndPosition);
233                         try {
234                                 applyStyleToSingleLine(boundaries_list.elementAt(BOOLS), getStyle("Bool"), lineStartPosition, lineEndPosition);
235                                 applyStyleToSingleLine(boundaries_list.get(COMMANDS), getStyle("Command"), lineStartPosition, lineEndPosition);
236                                 applyStyleToSingleLine(boundaries_list.get(FUNCTIONS), getStyle("Function"), lineStartPosition, lineEndPosition);
237                                 applyStyleToSingleLine(boundaries_list.get(MACROS), getStyle("Macro"), lineStartPosition, lineEndPosition);
238                                 applyStyleToSingleLine(boundaries_list.get(OPERATORS), getStyle("Operator"), lineStartPosition, lineEndPosition);
239                                 applyStyleToSingleLine(boundaries_list.get(QUOTATIONS), getStyle("String"), lineStartPosition, lineEndPosition);
240                                 applyStyleToSingleLine(boundaries_list.get(COMMENTS), getStyle("Comment"), lineStartPosition, lineEndPosition);
241                         } catch (BadLocationException e) {
242                                 e.printStackTrace();
243                         }
244                         finally {
245                                 this.addUndoableEditListener(undo);
246                                 colorizeInprogress = false;
247                         }
248                 }
249         }
250         /*
251         public Style getStyle(String styleName ){
252                 Style plop =  xpadStyles.getStyle(styleName);
253                 
254                 return plop ;
255         }
256         */
257         private void resetStyle() {
258                 // Reset Color
259                 this.removeUndoableEditListener(undo);
260                 this.setCharacterAttributes(0, this.getLength(), this.getStyle("Default"), true);
261                 this.setParagraphAttributes(0, this.getLength(), this.getStyle("Default"), true);
262                 this.addUndoableEditListener(undo);
263         }
264         
265         private void resetSingleLineStyle(int line_start, int line_end) {
266                 // Reset Color
267                 this.removeUndoableEditListener(undo);
268                 this.setCharacterAttributes(line_start, line_end-line_start, this.getStyle("Default"), true);
269                 this.setParagraphAttributes(line_start, line_end-line_start, this.getStyle("Default"), true);
270                 this.addUndoableEditListener(undo);
271         }
272
273         
274         private void applyStyle(Vector<Integer> boundaries, Style style) throws BadLocationException {
275                 for(int i = 0 ; i < boundaries.size() ; i=i+2)  {
276                         this.setCharacterAttributes(boundaries.elementAt(i), boundaries.elementAt(i+1)-boundaries.elementAt(i), style, false);
277                         this.setParagraphAttributes(boundaries.elementAt(i), boundaries.elementAt(i+1)-boundaries.elementAt(i), style, false);
278                 }
279         }
280         
281         private void applyStyleToSingleLine(Vector<Integer> boundaries, Style style, int start, int end) throws BadLocationException {
282                 for(int i = 0 ; i < boundaries.size() ; i=i+2)  {
283                         this.setCharacterAttributes(boundaries.elementAt(i), boundaries.elementAt(i+1)-boundaries.elementAt(i), style, false);
284                         this.setParagraphAttributes(boundaries.elementAt(i), boundaries.elementAt(i+1)-boundaries.elementAt(i), style, false);
285                 }
286         }
287
288         public boolean getColorize() {
289                 //DEBUG("setColorize("+autoColorize+")");
290                 return autoColorize;
291         }
292
293         public void setColorize(boolean b) {
294                 //DEBUG("setColorize("+b+")");
295                 autoColorize = b;
296         }
297         /**
298          * DOCUMENT COLORISATION END
299          */
300
301
302         /**
303          * DOCUMENT INDENTATION START
304          */
305         public void indent() {
306                 if (!indentInprogress) {
307                         disableUpdaters();
308                         indentInprogress = true;
309                         resetStyle();
310                         
311                         applySelectionIndent();
312                         
313                         colorize();
314                         indentInprogress = false;
315                         enableUpdaters();
316                 }
317         }
318
319         public void applyIndent(int start, int end, String tabulation) throws BadLocationException {
320
321                 String indentedText = "";
322                 String tab = "";
323                 boolean got_case = false;
324
325                 String text_to_indent = ""; // the entire document
326                 Vector<String> command_list = new Vector<String>(); // list of commands in the document
327
328                 try {
329                         // Get the document text to indent
330                         text_to_indent = this.getText(start, end-start);
331                 } catch (BadLocationException e) {
332                         e.printStackTrace();
333                 }
334                 
335                 // Get all line break positions &
336                 // each line of the document
337                 Vector<Integer> line_break = new Vector<Integer>(); // positions of line break
338                 Vector<String> all_lines = new Vector<String>(); // the document line by line
339                 String line = "";
340                 for (int i = 0; i < text_to_indent.length(); i++) {
341                         line = line.concat(text_to_indent.charAt(i)+"");
342
343                         if (text_to_indent.charAt(i)=='\n') {
344                                 line_break.add(i);
345                                 all_lines.add(line);
346                                 line = "";
347                         }
348                         if (i==text_to_indent.length()-1) {
349                                 all_lines.add(line);
350                                 line = "";
351                         }
352                 }
353
354                 Vector<String> all_lines_without_spaces = new Vector<String>(); // the document line by line
355                 // without spaces
356                 for (int i = 0; i < all_lines.size(); i++) {
357                         String no_space_line = removeFirstSpaces(all_lines.elementAt(i));
358                         all_lines_without_spaces.add(no_space_line);
359                 }
360                 
361                 boolean got_select = false;
362
363                 for (int i = 0; i < all_lines_without_spaces.size(); i++) {
364                         // Get commands for each lines
365                         command_list = getOperatorList(all_lines_without_spaces.elementAt(i));
366                         
367                         // Here start the indentation process
368                         if (command_list.size() > 0) {
369                                 // Check if in one line all operators are matching,
370                                 // so we can know if the next line needs indentation or not
371                                 // ex: if %T then function foo(1) endfunction end => doesn't need indentation
372                                 // Warning: command_list looks like [IN, if, IN function, OUT, endfunction, OUT, end]
373                                 Vector<String> vector_match = matchingOperators(command_list);                  
374
375                                 // If we have 'IN' command
376                                 if (command_list.elementAt(0).equals(IN)) {
377                                         // No indentation in case of 'else' or 'elseif'
378                                         if ((command_list.elementAt(1).toLowerCase().equals("else")) || 
379                                                         (command_list.elementAt(1).toLowerCase().equals("elseif"))) {
380                                                 if (indentedText.length() >= 2) {
381                                                         indentedText = indentedText.substring(0, indentedText.length()-2);
382                                                 }
383                                                 //      If we have 'select' command
384                                         } else if (command_list.elementAt(1).toLowerCase().equals("select")) {
385                                                 tab += TABULATION;
386                                                 got_select = true;
387
388                                                 // If we have 'case' command
389                                         } else if ((command_list.elementAt(1).toLowerCase().equals("case")) && 
390                                                         (got_case == false) &&
391                                                         (got_select == true) ) {
392                                                 got_case = true;
393                                                 tab += TABULATION;
394
395                                         } else {
396                                                 if (got_case == false) {
397                                                         tab += TABULATION;
398                                                 } else if (indentedText.length() >= 2) {
399                                                         indentedText = indentedText.substring(0, indentedText.length()-2);
400                                                 }
401                                         }
402                                         indentedText += tabulation + all_lines_without_spaces.elementAt(i);
403
404                                         // If we have "OUT' operator
405                                 } else if (command_list.elementAt(0).equals(OUT)) {
406                                         if (indentedText.length() >= 2 && tab.length() >= 2) {  
407                                                 indentedText = indentedText.substring(0, indentedText.length()-2);
408                                                 tab = tab.substring(0, tab.length()-2);
409                                                 if (got_select == true && 
410                                                                 got_case == true &&
411                                                                 command_list.elementAt(1).toLowerCase().equals("end")) {
412                                                         tab = tab.substring(0, tab.length()-2);
413                                                         indentedText = indentedText.substring(0, indentedText.length()-2);
414                                                         got_select = false;
415                                                         got_case = false;
416                                                 }
417                                         }
418                                         indentedText += tabulation +  all_lines_without_spaces.elementAt(i);
419
420                                         // Line got operators and they match, so no need of indentation
421                                 } else {
422                                         indentedText += tabulation +  all_lines_without_spaces.elementAt(i);
423                                 }
424                                 // Line without operator
425                         } else {
426                                 indentedText += tabulation +  all_lines_without_spaces.elementAt(i);
427                         }
428
429                         // Add the indentation
430                         if (i != all_lines_without_spaces.size()-1) {
431                                 indentedText += tab;
432                         }
433                         command_list.clear();
434                 } // end for
435
436                 // Display the indentation
437                 this.replace(start, end-start, indentedText, null);
438                 
439                 // ATTENTION, ces cas ne sont pas traité: 
440                 //            - gestion des commentaire /* */
441                 //                        - analyser la ligne du document qui est modifie et non plus le document en entier pour la colorisation
442                 //                              dans le cas d'une quotation ou commentaire(/* */) analyser le document en entier
443         }
444
445         
446         public void applySelectionIndent() {
447
448                 editor = getEditor();
449                 String tab = "";
450                 int selection_start = 0;
451                 int selection_end = 0;
452                 
453                 // Get start & end offsets of the selected text
454                 selection_start = editor.getTextPane().getSelectionStart();
455                 selection_end = editor.getTextPane().getSelectionEnd();
456                 
457                 
458                 if (autoIndent) {
459                         int  caretPosition = editor.getTextPane().getCaretPosition();
460                         try {
461                                 if (editor.getTextPane().getText(caretPosition-1, 1).equals("\n")) {
462                                 selection_start = selection_start-1;
463                                 selection_end  =  selection_end-1;
464                                 }
465                         } catch (BadLocationException e) {
466                                 e.printStackTrace();
467                         }
468                 }
469
470                 // Get start offsets of the first selected line & end offsets of the last selected line
471                 lineStartPosition =  this.getParagraphElement(selection_start).getStartOffset();
472                 lineEndPosition = this.getParagraphElement(selection_end).getEndOffset()-1;
473                 
474                 
475                 System.out.println("lineStartPosition = "+lineStartPosition);
476                 System.out.println("lineEndPosition = "+lineEndPosition);
477
478                 // Scan document line by line
479 //              int selection_first_line_number = this.getDefaultRootElement().getElementIndex(lineStartPosition);
480 //              int selection_last_line_number = this.getDefaultRootElement().getElementIndex(lineEndPosition);
481                 
482                 
483                 if (lineStartPosition == 0) {
484                         tab = "";
485                 } else {
486                         // Get previous line
487                         int previous_line_start =  this.getParagraphElement(lineStartPosition-1).getStartOffset();
488                         int previous_line_end = this.getParagraphElement(lineStartPosition-1).getEndOffset()-1;
489                         String previous_line = "";
490                         
491                         int current_line_start = this.getParagraphElement(selection_start).getStartOffset();
492                         int current_line_end = this.getParagraphElement(selection_end).getEndOffset()-1;
493                         String current_line = "";
494                         
495                         try {
496                                 previous_line = this.getText(previous_line_start, previous_line_end-previous_line_start);
497                                 current_line = this.getText(current_line_start, current_line_end-current_line_start);
498                                 // Get previous line's tabulation
499                                 tab = getLineTabulations(previous_line);
500                                 // Check if we have commands and if they match in the previous line
501                                 Vector<String> previous_command_list = getOperatorList(previous_line);
502                                 Vector<String> previous_vector_match = matchingOperators(previous_command_list);
503                                 
504                                 // Check if we have commands and if they match in the current line
505                                 Vector<String> current_command_list = getOperatorList(current_line);
506                                 Vector<String> current_vector_match = matchingOperators(current_command_list);
507                                 
508                                 if (previous_vector_match.size() > 0) {
509                                         if (previous_vector_match.elementAt(0).equals(IN)) {
510                                                 tab += "  ";
511                                         } 
512                                 }
513                                 
514                                 if (current_vector_match.size() > 0) {
515                                         if (current_vector_match.elementAt(0).equals(OUT)) {
516                                                 if (tab.length() >= 2) {
517                                                         tab = tab.substring(0, tab.length()-2);
518                                                 }
519                                         }
520                                         if ((current_vector_match.elementAt(1).toLowerCase().equals("else")) || 
521                                                         (current_vector_match.elementAt(1).toLowerCase().equals("elseif"))) {
522                                                 if (tab.length() >= 2) {
523                                                         tab = tab.substring(0, tab.length()-2);
524                                                 }
525                                         }
526                                         if ((current_vector_match.elementAt(1).toLowerCase().equals("case"))) {
527                                                 if (tab.length() >= 2) {
528                                                         tab = tab.substring(0, tab.length()-2);
529                                                 }
530                                         }
531                                 }
532                         } catch (BadLocationException e) {
533                                 e.printStackTrace();
534                         }
535                 }
536                 
537                 if (autoIndent) {
538                         int  caretPosition = editor.getTextPane().getCaretPosition();
539                         try {
540                                 if (editor.getTextPane().getText(caretPosition-1, 1).equals("\n")) {
541
542
543                                         //try {
544                                         applyIndent(lineStartPosition, lineEndPosition, tab);
545                                         tab = "";
546                                         //} catch (BadLocationException e) {
547                                         //e.printStackTrace();
548                                         //}
549
550                                 }
551                         } catch (BadLocationException e) {
552                                 e.printStackTrace();
553                         }
554                 } else {
555                         try {
556                         applyIndent(lineStartPosition, lineEndPosition, tab);
557                         tab = "";
558                         } catch (BadLocationException e) {
559                         e.printStackTrace();
560                         }
561                 }
562                 
563
564         }
565         
566         public String getLineTabulations(String line) {
567                 String spaces = "";
568
569                 for (int j = 0; j < line.length(); j++) {
570                         if ((line.charAt(j) == '\t') || (line.charAt(j) == ' ')) {
571                                 spaces = spaces.concat(line.charAt(j)+"");
572                         } else {
573                                 break;
574                         }                               
575                 }                       
576
577                 return spaces;
578         }
579         
580         /*
581          * Remove all spaces or tabulations at the begining a string
582          * This function is used for the indentation only
583          * ex: '   hello world' will be tranformed into 'hello world'
584          */
585         public String removeFirstSpaces(String line) {
586                 int spaces = 0;
587
588                 for (int j = 0; j < line.length(); j++) {
589                         if ((line.charAt(j) == '\t') || (line.charAt(j) == ' ')) {
590                                 spaces++;
591                         } else {
592                                 break;
593                         }                               
594                 }                       
595                 line = line.substring(spaces, line.length());   
596
597                 return line;
598         }
599
600         /*
601          * Get all commands given in the string
602          * This function is used for the indentation only
603          */
604         public Vector<String> getOperatorList(String text) {
605                 Vector<String> operator_list = new Vector<String>();
606                 Vector<String> op = new Vector<String>();
607
608                 Vector<Integer> comments_boundaries = new Vector<Integer>();
609                 Vector<Integer> quotations_boundaries = new Vector<Integer>();
610                 Vector<Integer> tmp_comm_and_quot = new Vector<Integer>();
611
612                 Vector<Integer> commands_boundaries = new Vector<Integer>();
613
614                 String[] commands_in = {"if", "else", "elseif", "while", "for", "do", "select", "case", "function"};
615                 String[] commands_out = {"end", "endfunction"};
616
617                 String[] allCommands = {"if", "else", "elseif", "while", "for", "do", "select", "case", "function", "end", "endfunction"};
618
619                 // Regexp for Scilab commands
620                 for (int i = 0; i < allCommands.length; i++) {
621                         allCommands[i] = "\\b" + allCommands[i] + "\\b";
622                 }
623
624                 // Find command boundaries in the given text
625                 commands_boundaries = findBoundaries(allCommands, false, 0, this.getLength(), text);
626                 comments_boundaries = findBoundaries(comments, false, 0, this.getLength(), text);
627                 quotations_boundaries = findBoundaries(quotations, false, 0, this.getLength(), text);
628                 
629                 // Remove comments which are into quotations
630                 comments_boundaries = startNotIn(comments_boundaries, quotations_boundaries);
631                 // Remove quotations which are into comments
632                 quotations_boundaries = startNotIn(quotations_boundaries, comments_boundaries);
633
634                 // Union of comments & quotations to remove keywords
635                 tmp_comm_and_quot.addAll(comments_boundaries);
636                 tmp_comm_and_quot.addAll(quotations_boundaries);
637
638                 // Remove commads which are into quotations or comments
639                 commands_boundaries = startNotIn(commands_boundaries, tmp_comm_and_quot);
640
641                 // Sort commands_boudaries
642                 Collections.sort(commands_boundaries);
643                 
644                 // The function applyIndent needs a vector in this format, ex: IN,IF,OUT,END
645                 for (int i = 0; i < commands_boundaries.size(); i=i+2) {
646                         op.add(text.substring(commands_boundaries.elementAt(i), commands_boundaries.elementAt(i+1)));
647                 }
648                 
649                 for (int i = 0; i < op.size(); i++) {
650                         for (int j = 0; j < commands_in.length; j++) {
651                                 if (op.elementAt(i).toLowerCase().equals(commands_in[j])) {
652                                         operator_list.add(IN);
653                                         operator_list.add(op.elementAt(i));
654                                 }
655                         }
656                         for (int j = 0; j < commands_out.length; j++) {
657                                 if (op.elementAt(i).toLowerCase().equals(commands_out[j])) {
658                                         operator_list.add(OUT);
659                                         operator_list.add(op.elementAt(i));
660                                 }
661                         }
662                 }
663                 
664                 return operator_list;
665         }
666
667         /*
668          * Check if in one line all commands are matching,
669          * by this way we can know if the next line needs indentation or not
670          * ex: if %T then function foo(1) endfunction end => doesn't need indentation
671          * ex: if %T then foo(1) end for => need indentation
672          * This function is used for the indentation only
673          * WARNING: command_list looks like [IN, if, IN function, OUT, endfunction, OUT, end]
674          */
675         public Vector<String> matchingOperators(Vector<String> command_list) {
676
677                 int tmp_size = command_list.size();
678
679                 for (int i = 0; i < command_list.size() - 3; i=i+2) {
680                         if ((command_list.elementAt(i+1).toLowerCase().equals("function") && 
681                                         command_list.elementAt(i+3).toLowerCase().equals("endfunction"))
682                                         ||
683                                         (command_list.elementAt(i+3).toLowerCase().equals("end") && 
684                                                         !(command_list.elementAt(i+1).toLowerCase().equals("function")) &&
685                                                         !(command_list.elementAt(i+1).toLowerCase().equals("endfunction")) && 
686                                                         !(command_list.elementAt(i+1).toLowerCase().equals("end")) )) {
687                                 command_list.removeElementAt(i+3);                                      
688                                 command_list.removeElementAt(i+2);
689                                 command_list.removeElementAt(i+1);
690                                 command_list.removeElementAt(i);
691                                 i = i -2;
692                         } 
693                 }
694                 if (tmp_size == command_list.size()) {
695                         return command_list;
696                 }
697                 return matchingOperators(command_list);
698         }
699         /**
700          * DOCUMENT INDENTATION END
701          */
702
703
704         /**
705          * DOCUMENT COMMENT ACTION
706          */
707         public void commentText(int start_position, int end_position) {
708
709                 String text_to_comment = "";
710                 try {
711                         // Get the document text to comment
712                         text_to_comment = this.getText(start_position, end_position-start_position);
713                 } catch (BadLocationException e) {
714                         e.printStackTrace();
715                 }
716
717                 Vector<Integer> line_break = new Vector<Integer>(); // positions of line break
718                 Vector<String> all_lines = new Vector<String>(); // the document line by line
719                 String line = "";
720
721                 if (start_position != end_position) {
722                         for (int i = 0; i < text_to_comment.length(); i++) {
723                                 line = line.concat(text_to_comment.charAt(i)+"");
724
725                                 if (text_to_comment.charAt(i)=='\n') {
726                                         line_break.add(i);
727                                         all_lines.add(line);
728                                         line = "";
729                                 }
730                                 if (i==text_to_comment.length()-1) {
731                                         all_lines.add(line);
732                                         line = "";
733                                 }
734                         }
735
736                         String commented_text = "";
737                         for (int i = 0; i < all_lines.size(); i++) {
738                                 String tmp = "";
739                                 if (!(all_lines.elementAt(i).equals(""))) {
740                                         if (all_lines.elementAt(i).length() >= 2) {
741                                                 if (all_lines.elementAt(i).substring(0, 2).equals("//")) {
742                                                         tmp = all_lines.elementAt(i).substring(2, all_lines.elementAt(i).length());
743                                                 } else {
744                                                         tmp = "//" + all_lines.elementAt(i);
745                                                 }
746                                         }
747                                 }
748                                 commented_text += tmp;
749                         }
750
751                         // Display the text commented
752                         try {
753                                 this.replace(start_position, end_position-start_position, commented_text, null);
754                         } catch (BadLocationException e) {
755                                 e.printStackTrace();
756                         }
757                 }
758
759                 line_break.clear();
760                 all_lines.clear();
761         }
762         /**
763          * DOCUMENT COMMENT ACTION END
764          */
765
766
767         /**
768          * FIND AND REPLACE START
769          */
770         public ArrayList<Integer[]> findWord(String word, boolean caseSensitive , boolean wholeWord , boolean useRegexp ) {
771                 String fullText = getFullDocument(); 
772                 int lastIndex = 0;
773                 int wordSize = word.length();
774                 ArrayList<Integer[]> offsetList = new ArrayList<Integer[]>();
775
776                 //If we don't give any word to find
777                 if ( (word != null) && !(word.equals("")) ) {
778                         // prepare word for each kind of search
779                         if (wholeWord){
780                                 word = "\\b" + word + "\\b" ;
781                         }
782                         if (!caseSensitive){
783                                 if (useRegexp || wholeWord ){
784                                         word = "(?i)" + word ;
785                                 }
786                                 else{
787                                         fullText = fullText.toLowerCase();
788                                         word = word.toLowerCase();
789                                 }
790                         }               
791
792
793                         //We find matching words ...
794                         // ... for regexp or whole words
795                         if (useRegexp || wholeWord){
796                                 Pattern pattern = Pattern.compile(word);
797                                 Matcher matcher = pattern.matcher(fullText);
798
799                                 while (matcher.find()) {
800                                         offsetList.add(new Integer[] {matcher.start() ,matcher.end()});
801                                 }
802                                 // ... for other case
803                         }else {
804                                 while ((lastIndex = fullText.indexOf(word, lastIndex)) != -1) {
805                                         int endIndex = lastIndex + wordSize;
806                                         offsetList.add(new Integer[] {lastIndex,endIndex} );
807                                         lastIndex = endIndex;
808                                 }
809                         }
810                 }
811                 return offsetList;
812         }
813         
814         public ArrayList<Integer[]> findWord(String word,int currentSelectStart ,int currentSelectEnd, boolean caseSensitive , boolean wholeWord , boolean useRegexp ) {
815                 String fullText = getseletecDocumentLines(currentSelectStart, currentSelectEnd) ;
816                 
817                 int offset = this.getParagraphElement(currentSelectStart).getStartOffset() ;
818                 int lastIndex = 0;
819                 int wordSize = word.length();;
820                 ArrayList<Integer[]> offsetList = new ArrayList<Integer[]>();
821
822                 //If we don't give any word to find
823                 if ( (word != null) && !(word.equals("")) ) {
824                         // prepare word for each kind of search
825                         if (wholeWord){
826                                 word = "\\b" + word + "\\b" ;
827                         }
828                         if (!caseSensitive){
829                                 if (useRegexp || wholeWord ){
830                                         word = "(?i)" + word ;
831                                 }
832                                 else{
833                                         fullText = fullText.toLowerCase();
834                                         word = word.toLowerCase();
835                                 }
836                         }               
837
838
839                         //We find matching words ...
840                         // ... for regexp or whole words
841                         if (useRegexp || wholeWord){
842                                 Pattern pattern = Pattern.compile(word);
843                                 Matcher matcher = pattern.matcher(fullText);
844
845                                 while (matcher.find()) {
846                                         offsetList.add(new Integer[] {matcher.start()+offset ,matcher.end()+offset});
847                                 }
848                                 // ... for other case
849                         }else {
850                                 while ((lastIndex = fullText.indexOf(word, lastIndex)) != -1) {
851                                         int endIndex = lastIndex + wordSize;
852                                         offsetList.add(new Integer[] {lastIndex+offset ,endIndex+offset } );
853                                         lastIndex = endIndex;
854                                 }
855                         }
856                 }
857                 return offsetList;
858         }
859
860         public int[] readText(int s, int e) {
861                 int startOffset;
862                 int endOffset;
863                 String textLine = "";
864                 String text = "";
865                 Vector<Integer> min = new Vector<Integer>();
866                 Vector<Integer> max = new Vector<Integer>();
867                 int[] interval = new int[2];
868
869                 //We read the document
870                 for (int i = 0; i < this.getLength();) {
871                         startOffset = this.getParagraphElement(i).getStartOffset();
872                         endOffset = this.getParagraphElement(i).getEndOffset();
873                         min.add(startOffset);
874                         max.add(endOffset);
875
876                         try {
877                                 //Get the document line by line
878                                 textLine = this.getText(startOffset, endOffset - startOffset);
879                         } catch (BadLocationException ex) {
880                                 ex.printStackTrace();
881                         }
882                         i = endOffset;
883                         text += textLine;
884                 }
885
886                 //If we only select a part of a line
887                 for (int i = 0; i < min.size(); i++) {
888                         if (s > min.elementAt(i)) {
889                                 interval[0] = min.elementAt(i);
890                         }
891                 }
892                 for (int i = 0; i < max.size(); i++) {
893                         if (e > max.elementAt(i)) {
894                                 interval[1] = max.elementAt(i);
895                                 interval[1] = interval[1] - 1 ;
896                         }
897                 }
898                 return interval;
899         }
900
901         /**
902          * Get the next expression matching the search after the caret current position
903          * @param word , the word or regexp to find
904          * @param currentPos, the position where the search start
905          * @param caseSensitive , whether the search is sensitive or not to case
906          * @param wholeWord  , whether the search will only look to separate word or not
907          * @param useRegexp  , whether the string to search should be interpreted as a regexp or not
908          */
909         public int[] findNextWord (String word ,int currentPos, boolean caseSensitive , boolean wholeWord , boolean useRegexp ){
910                 String fullText = getFullDocument();
911                 int index = -1 ;
912                 int end = -1 ;
913
914
915
916                 if ( (word != null) && (!word.equals(""))  ) {
917                         // prepare word for each kind of search
918                         if (wholeWord){
919                                 word = "\\b" + word + "\\b" ;
920                         }
921                         if (!caseSensitive){
922                                 if (useRegexp || wholeWord ){
923                                         word = "(?i)" + word ;
924                                 }
925                                 else{
926                                         fullText = fullText.toLowerCase();
927                                         word = word.toLowerCase();
928                                 }
929                         }               
930
931
932                         //We find matching words ...
933                         // ... for regexp or whole words
934                         if (useRegexp || wholeWord){
935                                 Pattern pattern = Pattern.compile(word);
936                                 Matcher matcher = pattern.matcher(fullText.substring(currentPos));
937
938                                 if (matcher.find()) {
939                                         index = matcher.start()+currentPos;
940                                         end = matcher.end()+currentPos;
941                                 }else{
942                                         index = -1 ;
943                                         end  = -1 ;
944                                 }
945
946                                 // ... for other case
947                         }else {
948                                 index = fullText.indexOf(word,currentPos);
949                                 end = index + word.length();
950                         }
951                 }
952
953                         return new int [] {index , end } ;
954         }
955
956         public int[] findNextWord (String word ,int currentPos,int currentSelectStart ,int currentSelectEnd, boolean caseSensitive , boolean wholeWord , boolean useRegexp ){
957                 
958                 String fullText = getseletecDocumentLines(currentSelectStart, currentSelectEnd) ;
959                 int offset = this.getParagraphElement(currentSelectStart).getStartOffset() ;
960                 System.out.println(currentPos) ;
961                 currentPos -=  offset ;
962                 
963                 int index = -1 ;
964                 int end = -1 ;
965
966
967                 if ( (word != null) && (!word.equals(""))  ) {
968                         // prepare word for each kind of search
969                         if (wholeWord){
970                                 word = "\\b" + word + "\\b" ;
971                         }
972                         if (!caseSensitive){
973                                 if (useRegexp || wholeWord ){
974                                         word = "(?i)" + word ;
975                                 }
976                                 else{
977                                         fullText = fullText.toLowerCase();
978                                         word = word.toLowerCase();
979                                 }
980                         }               
981
982
983                         //We find matching words ...
984                         // ... for regexp or whole words
985                         if (useRegexp || wholeWord){
986                                 Pattern pattern = Pattern.compile(word);
987                                 Matcher matcher = pattern.matcher(fullText.substring(currentPos));
988
989                                 if (matcher.find()) {
990                                         index = matcher.start()+currentPos+offset;
991                                         end = matcher.end()+currentPos+offset;
992                                 }else{
993                                         index = -1 ;
994                                         end  = -1 ;
995                                 }
996
997                                 // ... for other case
998                         }else {
999                         
1000                                 index = fullText.indexOf(word,currentPos);
1001                                 if (index != -1) index += offset ;
1002                                 end = index + word.length();
1003                         }
1004                 }
1005
1006                         return new int [] {index , end } ;
1007         }
1008         
1009         
1010         
1011         /**
1012          * Get the previous expression matching the search before the caret current position
1013          * @param word , the word or regexp to find
1014          * @param currentPos, the position where the search start
1015          * @param caseSensitive , whether the search is sensitive or not to case
1016          * @param wholeWord  , whether the search will only look to separate word or not
1017          * @param useRegexp  , whether the string to search should be interpreted as a regexp or not
1018          */
1019         public int[] findPreviousWord (String word , int currentPos, boolean caseSensitive , boolean wholeWord , boolean useRegexp ){
1020                 String fullText = getFullDocument();
1021                 int index = -1 ;
1022                 int end = -1 ;
1023                 Pattern pattern;
1024
1025                 if ( (word != null) && (!word.equals(""))  ) {
1026
1027                         // prepare word for each kind of search
1028                         if (wholeWord){
1029                                 word = "\\b" + word + "\\b" ;
1030                         }
1031                         if (!caseSensitive){
1032                                 if (useRegexp || wholeWord ){
1033                                         word = "(?i)" + word ;
1034                                 }
1035                                 else{
1036                                         fullText = fullText.toLowerCase();
1037                                         word = word.toLowerCase();
1038                                 }
1039                         }               
1040
1041
1042                         //We find matching words ...
1043                         // ... for regexp or whole words
1044
1045                         if (useRegexp || wholeWord){
1046                                  pattern = Pattern.compile(word);
1047                         }else{// ... for other case
1048                                 // we use regexp in both case cause of a nasty bug when you have string like 
1049                                 //121212  and you search "121" forward then backward
1050                                 pattern = Pattern.compile(word , Pattern.LITERAL );
1051                                 
1052                         }
1053                                 Matcher matcher = pattern.matcher(fullText.substring(0,currentPos));
1054
1055                                 boolean found = false ;
1056                                 while (matcher.find()) {
1057                                         index = matcher.start();
1058                                         end = matcher.end();
1059                                         found = true ;
1060                                 }
1061
1062                                 if(!found){
1063                                         index = -1 ;
1064                                         end = -1;
1065                                 }
1066                 }
1067
1068
1069                 /*if nothing index and end will both be equal to -1*/
1070                 return new int [] {index , end } ;
1071
1072
1073         }
1074         
1075         
1076         public int[] findPreviousWord (String word , int currentPos,int currentSelectStart ,int currentSelectEnd, boolean caseSensitive , boolean wholeWord , boolean useRegexp ){
1077                 String fullText = getseletecDocumentLines(currentSelectStart, currentSelectEnd) ;
1078                 int offset = this.getParagraphElement(currentSelectStart).getStartOffset() ;
1079                 System.out.println(currentPos) ;
1080                 currentPos -=  offset ;
1081                 int index = -1 ;
1082                 int end = -1 ;
1083                 Pattern pattern;
1084
1085                 if ( (word != null) && (!word.equals(""))  ) {
1086
1087                         // prepare word for each kind of search
1088                         if (wholeWord){
1089                                 word = "\\b" + word + "\\b" ;
1090                         }
1091                         if (!caseSensitive){
1092                                 if (useRegexp || wholeWord ){
1093                                         word = "(?i)" + word ;
1094                                 }
1095                                 else{
1096                                         fullText = fullText.toLowerCase();
1097                                         word = word.toLowerCase();
1098                                 }
1099                         }               
1100
1101
1102                         //We find matching words ...
1103                         // ... for regexp or whole words
1104
1105                         if (useRegexp || wholeWord){
1106                                  pattern = Pattern.compile(word);
1107                         }else{// ... for other case
1108                                 // we use regexp in both case cause of a nasty bug when you have string like 
1109                                 //121212  and you search "121" forward then backward
1110                                 pattern = Pattern.compile(word , Pattern.LITERAL );
1111                                 
1112                         }
1113                                 System.out.println(currentPos) ;
1114                                 Matcher matcher = pattern.matcher(fullText.substring(0,currentPos));
1115
1116                                 boolean found = false ;
1117                                 while (matcher.find()) {
1118                                         index = matcher.start() + offset;
1119                                         end = matcher.end() + offset;
1120                                         found = true ;
1121                                 }
1122
1123                                 if(!found){
1124                                         index = -1 ;
1125                                         end = -1;
1126                                 }
1127                 }
1128
1129
1130                 /*if nothing index and end will both be equal to -1*/
1131                 return new int [] {index , end } ;
1132
1133
1134         }
1135         
1136         
1137         /**
1138          * FIND AND REPLACE END
1139          */
1140
1141
1142         /**
1143          * UTILITARIAN FUNCTIONS START
1144          */
1145         /*
1146          * Get all Scilab's keywords into a hashtable
1147          */
1148         public Hashtable<String, String[]> getScilabKeywords() {
1149                 //Get all Scilab keywords with SWIG
1150                 String[] commands =  ScilabKeywords.GetCommandsName();
1151                 String[] functions =  ScilabKeywords.GetFunctionsName();
1152                 String[] macros =  ScilabKeywords.GetMacrosName();
1153                 //String[] variables =  ScilabKeywords.GetVariablesName();
1154
1155                 Hashtable<String, String[]> keywords = new Hashtable<String, String[]>();
1156
1157                 for (int i = 0; i < commands.length; i++) {
1158                         keywords.put("command", commands);
1159                 }
1160                 for (int i = 0; i < functions.length; i++) {
1161                         keywords.put("function", functions);
1162                 }
1163                 for (int i = 0; i < macros.length; i++) {
1164                         keywords.put("macro", macros);
1165                 }
1166                 return keywords;
1167         }
1168
1169         /*
1170          * Parse all Scilab keywords
1171          * This function is used for the syntactic colorization
1172          */
1173         private Vector<Vector<Integer>> parse(String[] bools, String[] commands, String[] comments, 
1174                         String[] functions, String[] macros, String[] operators, String[] quotations, boolean singleLine, int start, int end) {
1175
1176                 Vector<Integer> boolsBoundaries, commandsBoundaries, 
1177                 commentsBoundaries, functionsBoundaries, 
1178                 macrosBoundaries, operatorsBoundaries, 
1179                 quotationsBoundaries;
1180
1181                 Vector<Vector<Integer>> boundaries_list = new Vector<Vector<Integer>>();
1182
1183                 boolsBoundaries = findBoundaries(bools, singleLine, start, end, null);
1184                 commandsBoundaries = findBoundaries(commands, singleLine, start, end, null);
1185                 commentsBoundaries = findBoundaries(comments, singleLine, start, end, null);
1186                 functionsBoundaries = findBoundaries(functions, singleLine, start, end, null);
1187                 macrosBoundaries = findBoundaries(macros, singleLine, start, end, null);
1188                 operatorsBoundaries = findBoundaries(operators, singleLine, start, end, null);
1189                 quotationsBoundaries = findBoundaries(quotations, singleLine, start, end, null);        
1190
1191
1192                 boundaries_list = organizeBoundaries(boolsBoundaries, commandsBoundaries, commentsBoundaries, functionsBoundaries, 
1193                                 macrosBoundaries, operatorsBoundaries, quotationsBoundaries);
1194
1195                 return boundaries_list;
1196         }
1197
1198         /*
1199          * Get start & end position for each keywords
1200          * String[] keyword is a type of keywords(ex: operators, commands, macros..)
1201          * String text is where we make the search, 
1202          * if text is null we apply the research to the entire document
1203          */
1204         private Vector<Integer> findBoundaries(String[] keyword, boolean singleLine, int start, int end, String text) {
1205
1206                 Pattern pattern;
1207                 Matcher matcher = null;
1208                 Vector<Integer> bound = new Vector<Integer>();
1209                 
1210                 for(int i = 0 ; i < keyword.length ; i++)       {
1211                         pattern = Pattern.compile(keyword[i], Pattern.DOTALL);
1212                         try {
1213                                 if (singleLine && text == null) {
1214                                         matcher = pattern.matcher(this.getText(start, end - start));
1215                                         while(matcher.find()){
1216                                                 //System.err.println("Match Found : "+(matcher.start())+","+(matcher.end()/*-matcher.start()*/));
1217                                                 bound.add(new Integer(matcher.start() + start));        
1218                                                 bound.add(new Integer(matcher.end() + start));
1219                                         }
1220
1221                                 } else {
1222                                         if (text != null) {
1223                                                 matcher = pattern.matcher(text);
1224                                         } else {
1225                                                 matcher = pattern.matcher(this.getText(0, this.getLength()));
1226                                         }
1227                                         
1228                                         while(matcher.find()){
1229                                                 //System.err.println("Match Found : "+(matcher.start())+","+(matcher.end()/*-matcher.start()*/));
1230                                                 bound.add(new Integer(matcher.start()));        
1231                                                 bound.add(new Integer(matcher.end()));
1232                                         }
1233                                 }
1234                         } catch (BadLocationException e) {
1235                                 e.printStackTrace();
1236                         }
1237                 }
1238                 return bound;
1239         }
1240
1241         /*
1242          * When we have all boundaries for each type of keywords
1243          * we filter 'bad' boundaries
1244          * ex: if we have quotations into comments (and the opposite), keywords into quotations or comments 
1245          */
1246         private Vector<Vector<Integer>> organizeBoundaries(Vector<Integer> boolsBoundaries, Vector<Integer> commandsBoundaries,
1247                         Vector<Integer> commentsBoundaries, Vector<Integer> functionsBoundaries, 
1248                         Vector<Integer> macrosBoundaries, Vector<Integer> operatorsBoundaries, 
1249                         Vector<Integer> quotationsBoundaries) {
1250
1251                 Vector<Integer> tmp_comm_and_quot = new Vector<Integer>();
1252                 Vector<Vector<Integer>> vector_list = new Vector<Vector<Integer>>();
1253
1254                 // Remove comments which are into quotations
1255                 commentsBoundaries = startNotIn(commentsBoundaries, quotationsBoundaries);
1256                 // Remove quotations which are into comments
1257                 quotationsBoundaries = startNotIn(quotationsBoundaries, commentsBoundaries);
1258
1259                 // Union of comments & quotations to remove keywords
1260                 tmp_comm_and_quot.addAll(commentsBoundaries);
1261                 tmp_comm_and_quot.addAll(quotationsBoundaries);
1262
1263                 // Remove keywords which are into comments & quotations
1264                 boolsBoundaries = strictlyNotIn(boolsBoundaries, tmp_comm_and_quot);
1265                 commandsBoundaries = strictlyNotIn(commandsBoundaries, tmp_comm_and_quot);
1266                 functionsBoundaries = strictlyNotIn(functionsBoundaries, tmp_comm_and_quot);
1267                 macrosBoundaries = strictlyNotIn(macrosBoundaries, tmp_comm_and_quot);
1268                 operatorsBoundaries = strictlyNotIn(operatorsBoundaries, tmp_comm_and_quot);
1269
1270                 vector_list.add(boolsBoundaries);
1271                 vector_list.add(commandsBoundaries);
1272                 vector_list.add(commentsBoundaries);
1273                 vector_list.add(functionsBoundaries);
1274                 vector_list.add(macrosBoundaries);
1275                 vector_list.add(operatorsBoundaries);
1276                 vector_list.add(quotationsBoundaries);
1277
1278                 return vector_list;
1279         }
1280
1281         private Vector<Integer> strictlyNotIn(Vector<Integer> v1, Vector<Integer> v2) {
1282                 int v1_start = 0;
1283                 int v1_end = 0;
1284                 int v2_start = 0;
1285                 int v2_end = 0;
1286
1287                 Vector<Integer> vector_strictlyNotIn = new Vector<Integer>();
1288
1289                 // Remove interval from v1 which are include in interval of v2
1290                 for(int i=0; i < v1.size(); i=i+2) {
1291                         boolean dropMe = false;
1292                         v1_start = v1.elementAt(i);
1293                         v1_end = v1.elementAt(i+1);
1294
1295                         for(int j=0; j < v2.size(); j=j+2) {
1296                                 v2_start = v2.elementAt(j);
1297                                 v2_end = v2.elementAt(j+1);
1298
1299                                 if(((v1_start >= v2_start) && (v1_start <= v2_end)) && ((v1_end >= v2_start) && (v1_end <= v2_end))) {
1300                                         dropMe = true;
1301                                 }
1302                         }
1303                         if (!dropMe) {
1304                                 vector_strictlyNotIn.addElement(v1.elementAt(i));
1305                                 vector_strictlyNotIn.addElement(v1.elementAt(i+1));
1306                         }
1307
1308                         //System.out.println("vector_strictlyNotIn"+vector_strictlyNotIn);
1309                 }
1310                 return vector_strictlyNotIn;
1311         }
1312
1313         private Vector<Integer> startNotIn(Vector<Integer> v1, Vector<Integer> v2) {
1314                 int v1_start = 0;
1315                 int v2_start = 0;
1316                 int v2_end = 0;
1317                 Vector<Integer> vector_startNotIn = new Vector<Integer>();
1318
1319                 for(int i=0; i < v1.size(); i=i+2) {
1320                         boolean dropMe = false;
1321                         v1_start = v1.elementAt(i);
1322
1323                         for(int j=0; j < v2.size(); j=j+2) {
1324                                 v2_start = v2.elementAt(j);
1325                                 v2_end = v2.elementAt(j+1);
1326
1327                                 if(((v1_start >= v2_start) && (v1_start <= v2_end))) {
1328                                         dropMe = true;
1329                                 }
1330                         }
1331                         if (!dropMe) {
1332                                 vector_startNotIn.addElement(v1.elementAt(i));
1333                                 vector_startNotIn.addElement(v1.elementAt(i+1));
1334                         }
1335
1336                         //System.out.println("vector_startNotIn"+vector_startNotIn);
1337                 }
1338                 return vector_startNotIn;
1339         }
1340         /**
1341          * UTILITARIAN FUNCTIONS END
1342          */
1343
1344         private final void DEBUG(String msg) {
1345                 System.err.println("[DEBUG] "+msg);
1346         }
1347         public void disableUpdaters() {
1348                 updaterDisabled = true;
1349         }
1350
1351         public String getFullDocument() {
1352                 int startOffset;
1353                 int endOffset;
1354                 String textLine = "";
1355                 String text = "";
1356
1357                 //We read the document and put the document into the String text
1358                 for (int i = 0; i < this.getLength();) {
1359                         startOffset = this.getParagraphElement(i).getStartOffset();
1360                         endOffset = this.getParagraphElement(i).getEndOffset();
1361
1362                         try {
1363                                 //Get the document line by line
1364                                 textLine = this.getText(startOffset, endOffset - startOffset);
1365                         } catch (BadLocationException ex) {
1366                                 ex.printStackTrace();
1367                         }
1368                         i = endOffset;
1369                         text += textLine;
1370                 }
1371                 return text;
1372         }
1373
1374         public String getseletecDocumentLines(int start , int end ) {
1375                 int startOffset;
1376                 int endOffset;
1377
1378                 String text = "";
1379
1380                 startOffset = this.getParagraphElement(start).getStartOffset();
1381                 endOffset = this.getParagraphElement(end).getEndOffset();
1382                 //We read the document and put the document into the String text
1383
1384                 try {
1385                         //Get the document line by line
1386                         text = this.getText(startOffset, endOffset - startOffset);
1387                 } catch (BadLocationException ex) {
1388                         ex.printStackTrace();
1389                 }
1390
1391
1392                 return text;
1393         }
1394
1395         public void enableUpdaters() {
1396                 updaterDisabled = false;
1397         }
1398
1399         public void insertUpdate(DocumentEvent e) {
1400                 
1401                 EventType = e.getType().toString();
1402                 //System.err.println("--- Calling insertUpdate");
1403                 if (!updaterDisabled) {
1404                         SwingUtilities.invokeLater(new Runnable() {
1405                                 public void run() {
1406                                         //resetStyle();
1407                                         if (autoIndent) {
1408                                                 //indent();
1409                                                 IndentAction.getXpadEditor();
1410                                                 editor = getEditor();
1411                                                 
1412 //                                              int  caretPosition = editor.getTextPane().getCaretPosition();
1413 //                                              
1414 //                                              
1415 //                                              try {
1416 //                                                      if (editor.getTextPane().getText(caretPosition-1, 1).equals("\n")) {
1417 //                                                              System.out.println("------------ SAUTE de LIGNE ------------");
1418 //                                                              System.out.println(caretPosition);
1419 //                                                      }
1420 //                                              } catch (BadLocationException e) {
1421 //                                                      e.printStackTrace();
1422 //                                              }
1423                                                 
1424                                                 indent();
1425                                         }
1426                                         if (autoColorize) {
1427                                                 //colorize();
1428                                                 setSingleLine(true);
1429                                                 ColorizeAction.getXpadEditor();
1430                                                 editor = getEditor();
1431                                                 
1432                                                 // Get the current line (position of the caret) 
1433                                                 int  caretPosition = editor.getTextPane().getCaretPosition();
1434                                                 currentLine = editor.getTextPane().getStyledDocument().getDefaultRootElement().getElementIndex(caretPosition);
1435
1436                                                 // Get current line's start & end offsets
1437                                                 lineStartPosition =  editor.getTextPane().getStyledDocument().getParagraphElement(caretPosition).getStartOffset();
1438                                                 lineEndPosition = editor.getTextPane().getStyledDocument().getParagraphElement(caretPosition).getEndOffset()-1;
1439                                                 
1440                                                 // If we add a line (by pressing return)
1441                                                 if (lineStartPosition == lineEndPosition) {
1442                                                         lineStartPosition = lineStartPosition + lineEndPosition;
1443                                                         lineEndPosition = lineEndPosition + lineEndPosition;
1444                                                 } 
1445                                                 
1446                                                 if (lineStartPosition != lineEndPosition) {
1447                                                         colorizeSingleLine(lineStartPosition, lineEndPosition);
1448                                                 }
1449                                                 setSingleLine(false);
1450                                         }
1451                                 }
1452                         });  
1453                 }
1454         }
1455         public void removeUpdate(DocumentEvent e) {
1456                 
1457                 EventType = e.getType().toString() ;
1458                 //System.err.println("--- Calling ScilabStyleDocument.removeUpdate");
1459                 if (!updaterDisabled) {
1460                         SwingUtilities.invokeLater(new Runnable() {
1461                                 public void run() {
1462                                         //resetStyle();
1463                                         if (autoIndent) {
1464                                                 //indent();
1465 //                                              IndentAction.getXpadEditor();
1466 //                                              editor = getEditor();
1467 //                                              int  caretPosition = editor.getTextPane().getCaretPosition();
1468 //                                              
1469 //                                              try {
1470 //                                                      if (!(caretPosition == 0)) {
1471 //                                                              caretPosition = caretPosition -1;
1472 //                                                      }
1473 //                                                      if (editor.getTextPane().getText(caretPosition, 1).equals("\n")) {
1474 //                                                              System.out.println("JE SAUTE UNE LIGNE");
1475 //
1476 //                                                              // Get start & end offsets of the selected text
1477 //                                                              int selection_start = editor.getTextPane().getSelectionStart();
1478 //                                                              int selection_end = editor.getTextPane().getSelectionEnd();
1479 //
1480 //                                                              // Get start offsets of the first selected line & end offsets of the last selected line
1481 //                                                              lineStartPosition =  editor.getTextPane().getStyledDocument().getParagraphElement(selection_start).getStartOffset();
1482 //                                                              lineEndPosition = editor.getTextPane().getStyledDocument().getParagraphElement(selection_end).getEndOffset()-1;
1483 //                                                              
1484 //                                                              indent();
1485 //                                                      }
1486 //                                              } catch (BadLocationException e) {
1487 //                                                      e.printStackTrace();
1488 //                                              }
1489                                         }
1490                                         if (autoColorize) {
1491                                                 //colorize();
1492                                                 setSingleLine(true);
1493                                                 ColorizeAction.getXpadEditor();
1494                                                 editor = getEditor();
1495                                                 
1496                                                 
1497                                                 // Get the current line (position of the caret) 
1498                                                 int  caretPosition = editor.getTextPane().getCaretPosition();
1499                                                 currentLine = editor.getTextPane().getStyledDocument().getDefaultRootElement().getElementIndex(caretPosition);
1500
1501                                                 // Get current line's start & end offsets
1502                                                 lineStartPosition =  editor.getTextPane().getStyledDocument().getParagraphElement(caretPosition).getStartOffset();
1503                                                 lineEndPosition = editor.getTextPane().getStyledDocument().getParagraphElement(caretPosition).getEndOffset()-1;
1504                                                 
1505                                                 // If we add a line (by pressing return)
1506                                                 if (lineStartPosition == lineEndPosition) {
1507                                                         lineStartPosition = lineStartPosition + lineEndPosition;
1508                                                         lineEndPosition = lineEndPosition + lineEndPosition;
1509                                                 } 
1510                                                 
1511                                                 if (lineStartPosition != lineEndPosition) {
1512                                                         colorizeSingleLine(lineStartPosition, lineEndPosition);
1513                                                 }
1514                                                 setSingleLine(false);
1515                                         }
1516                                 }
1517                         });
1518                 }
1519         }
1520
1521         public void changedUpdate(DocumentEvent arg0) {
1522                 
1523                 EventType = arg0.getType().toString() ;
1524                 // TODO Auto-generated method stub
1525         }
1526
1527         public void setAutoIndent(boolean b) {
1528                 //DEBUG("setAutoIndent("+b+")");
1529                 autoIndent = b;
1530         }
1531         public boolean getAutoIndent() {
1532                 //DEBUG("getAutoIndent("+autoIndent+")");
1533                 return autoIndent;
1534         }
1535         public UndoManager getUndoManager() {
1536                 return undo;
1537         }
1538
1539         
1540         public boolean isContentModified(){
1541                 return contentModified ;
1542         }
1543         
1544         public void setContentModified(boolean contentModified){
1545                 this.contentModified = contentModified ;
1546         }
1547         
1548         
1549         public boolean isSingleLine() {
1550                 return singleLine;
1551         }
1552
1553         public void setSingleLine(boolean singleLine) {
1554                 this.singleLine = singleLine;
1555         }
1556
1557         public int getLineToColor() {
1558                 return currentLine;
1559         }
1560
1561         public void setLineToColor(int lineToColor) {
1562                 this.currentLine = lineToColor;
1563         }
1564
1565         
1566         public int getLineEndPosition() {
1567                 return lineEndPosition;
1568         }
1569
1570         public void setLineEndPosition(int lineEndPosition) {
1571                 this.lineEndPosition = lineEndPosition;
1572         }
1573
1574         public int getLineStartPosition() {
1575                 return lineStartPosition;
1576         }
1577
1578         public void setLineStartPosition(int lineStartPosition) {
1579                 this.lineStartPosition = lineStartPosition;
1580         }
1581
1582         
1583         
1584         
1585         public Xpad getEditor() {
1586                 return editor;
1587         }
1588
1589         public void setEditor(Xpad editor) {
1590                 this.editor = editor;
1591         }
1592
1593         
1594
1595         
1596 }