Preferences: continue to connect SciNotes
[scilab.git] / scilab / modules / scinotes / src / java / org / scilab / modules / scinotes / TabManager.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2010 - Calixte DENIZET
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 package org.scilab.modules.scinotes;
14
15 import javax.swing.text.BadLocationException;
16 import javax.swing.text.Element;
17
18 /**
19  * This class handles the tabulation
20  * @author Calixte DENIZET
21  */
22 public class TabManager {
23
24     private static final String EOL = "\n";
25
26     private String tab;
27     private int lengthTab;
28     private ScilabDocument doc;
29     private Element elem;
30     private IndentManager indent;
31     private boolean isTabInsertable = true;
32
33     /**
34      * We can link this TabManager with an IndentManager just to say that the size of a tabulation changed
35      * @param doc the document
36      * @param indent an IndentManager
37      */
38     public TabManager(ScilabDocument doc, IndentManager indent) {
39         this.doc = doc;
40         this.elem = doc.getDefaultRootElement();
41         this.indent = indent;
42         setTabulation(' ', 3);
43     }
44
45     /**
46      * Set the type and the size of a tabulation
47      * @param tab is a char : ' ' or '\t'
48      * @param n is the length of a tab
49      */
50     public void setTabulation(char tab, int n) {
51         if (tab == ' ') {
52             char[] str = new char[n];
53             for (int i = 0; i < n; i++) {
54                 str[i] = ' ';
55             }
56             this.tab = new String(str);
57             lengthTab = n;
58         } else {
59             this.tab = "\t";
60             lengthTab = 1;
61         }
62         doc.putProperty("tabSize", new Integer(Math.max(n, 1)));
63         if (indent != null) {
64             indent.setProperties(tab, n);
65         }
66     }
67
68     /**
69      * Set the type and the size of a tabulation
70      * @param tabulation a Tabulation
71      */
72     public void setTabulation(Tabulation tabulation) {
73         setTabulation(tabulation.tab, tabulation.number);
74     }
75
76     /**
77      * Set the type and the size of a tabulation
78      */
79     public void setDefaultTabulation() {
80         setTabulation(new Tabulation());
81     }
82
83     /**
84      * Insert a tab inside a line (true) or tabify a line (false)
85      * @param b the boolean
86      */
87     public void setTabInsertable(boolean b) {
88         isTabInsertable = b;
89     }
90
91     /**
92      * @return a String which represents a tab
93      */
94     public String getTabulation() {
95         return tab;
96     }
97
98     /**
99      * Insert a tab just after the caret position (depends on setTabInsertable)
100      * @param position the position in the doc
101      * @return the length of a tab
102      */
103     public int insertTab(int position) {
104         try {
105             if (isTabInsertable) {
106                 doc.insertString(position, tab, null);
107             } else {
108                 tabifyLines(position, position - 1);
109             }
110         } catch (BadLocationException e) {
111             e.printStackTrace();
112         }
113
114         return lengthTab;
115     }
116
117     /**
118      * Tabify several lines.
119      * @param start the starting position in the doc
120      * @param end the ending position in the doc
121      * @return the new positions of the selected text
122      */
123     public int[] tabifyLines(int start, int end) {
124         Element startL = elem.getElement(elem.getElementIndex(start));
125         int sstart = startL.getStartOffset();
126         int[] ret = new int[] {0, 0};
127         int send = end;
128
129         try {
130             String str = doc.getText(sstart, send - sstart + 1);
131             if (str.charAt(str.length() - 1) == EOL.charAt(0)) {
132                 send--;
133                 str = str.substring(0, str.length() - 1);
134                 ret[1]++;
135             }
136             String rep = EOL + tab;
137             str = tab + str.replaceAll(EOL, rep);
138             ret[0] = start + lengthTab;
139             ret[1] += sstart + str.length();
140             doc.replace(sstart, send - sstart + 1, str, null);
141             return ret;
142         } catch (BadLocationException e) {
143             e.printStackTrace();
144             return null;
145         }
146     }
147
148     /**
149      * Suppress a tabulation just before the position or untabify line (depends on setTabInsertable)
150      * @param position of the caret
151      * @return the length of a tab
152      */
153     public int removeTab(int position) {
154         try {
155             if (isTabInsertable) {
156                 int pos = Math.max(0, position - lengthTab);
157                 if (tab.equals(doc.getText(pos, lengthTab))) {
158                     doc.remove(pos, lengthTab);
159                 } else {
160                     return 0;
161                 }
162             } else {
163                 untabifyLine(position);
164             }
165         } catch (BadLocationException e) {
166             e.printStackTrace();
167         }
168
169         return lengthTab;
170     }
171
172     /**
173      * Delete a tab at the beginning of a line where the caret is if possible.
174      * @param position the position in the doc
175      */
176     public void untabifyLine(int position) {
177         IndentScanner iscan = indent.getIndentScanner();
178         int line = elem.getElementIndex(position);
179         int n = iscan.getTabsAtBeginning(line);
180
181         try {
182             if (n >= lengthTab) {
183                 doc.remove(elem.getElement(line).getStartOffset(), lengthTab);
184             }
185         } catch (BadLocationException e) {
186             e.printStackTrace();
187         }
188     }
189
190     /**
191      * Remove one tabulation step from every line starting with tabulation between start and end
192      * @param start the starting position in the doc
193      * @param end the ending position in the doc
194      * @return the new positions of the selected text
195      */
196     public int[] untabifyLines(int start, int end) {
197         int sstart = elem.getElement(elem.getElementIndex(start)).getStartOffset();
198         int[] ret = new int[2];
199         ret[0] = start;
200
201         try {
202             String str = doc.getText(sstart, end - sstart + 1);
203             String untab = EOL + tab;
204             str = str.replaceAll(untab, EOL);
205             IndentScanner iscan = indent.getIndentScanner();
206             int n = iscan.getTabsAtBeginning(elem.getElementIndex(sstart));
207             if (n >= lengthTab) {
208                 str = str.substring(lengthTab);
209                 if (start - sstart + 1 >= lengthTab) {
210                     ret[0] = start - lengthTab;
211                 }
212             }
213             ret[1] = sstart + str.length();
214
215             doc.replace(sstart, end - sstart + 1, str, null);
216         } catch (BadLocationException e) {
217             e.printStackTrace();
218             return null;
219         }
220
221         return ret;
222     }
223
224     /**
225      * Inner class to represent a tabulation
226      */
227     public static class Tabulation {
228
229         /**
230          * Should be '\t' or ' '
231          */
232         public char tab;
233
234         /**
235          * The number of whites equivalent at this tabulation
236          */
237         public int number;
238
239         /**
240          * Should be one of the constants of ScilabView
241          */
242         public int type;
243
244         /**
245          * If type is ScilabView.TABCHARACTER, then rep is the char representing a tabulation
246          * in the view
247          */
248         public char rep;
249
250         /**
251          * Constructor
252          * @param tab '\t' or ' '
253          * @param number the number of whites
254          * @param type see the constants in ScilabView
255          * @param rep the char to represent a tabulation in a view
256          */
257         public Tabulation(char tab, int number, int type, char rep) {
258             this.tab = tab;
259             this.number = number;
260             this.type = type;
261             this.rep = rep;
262         }
263
264         public Tabulation() {
265             this.tab = SciNotesOptions.getSciNotesDisplay().useSpaces ? ' ' : '\t';
266             this.number = SciNotesOptions.getSciNotesDisplay().tabSize;
267             this.type = SciNotesOptions.getSciNotesDisplay().tabRepresentation;
268             this.rep = ' ';
269         }
270     }
271 }