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