]>
Commit | Line | Data |
---|---|---|
9ce192d4 RD |
1 | // Scintilla source code edit control |
2 | // ContractionState.cxx - manages visibility of lines for folding | |
3 | // Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org> | |
4 | // The License.txt file describes the conditions under which this software may be distributed. | |
5 | ||
6 | #include "Platform.h" | |
7 | ||
8 | #include "ContractionState.h" | |
9 | ||
10 | OneLine::OneLine() { | |
11 | displayLine = 0; | |
12 | docLine = 0; | |
13 | visible = true; | |
14 | expanded = true; | |
15 | } | |
16 | ||
17 | ContractionState::ContractionState() { | |
18 | lines = 0; | |
19 | size = 0; | |
20 | linesInDoc = 1; | |
21 | linesInDisplay = 1; | |
22 | valid = false; | |
23 | } | |
24 | ||
25 | ContractionState::~ContractionState() { | |
26 | Clear(); | |
27 | } | |
28 | ||
29 | void ContractionState::MakeValid() const { | |
30 | if (!valid) { | |
31 | // Could be cleverer by keeping the index of the last still valid entry | |
32 | // rather than invalidating all. | |
9ce192d4 RD |
33 | int lineDisplay = 0; |
34 | for (int line=0; line<linesInDoc; line++) { | |
35 | lines[line].displayLine = lineDisplay; | |
36 | if (lines[line].visible) { | |
37 | lines[lineDisplay].docLine = line; | |
38 | lineDisplay++; | |
39 | } | |
40 | } | |
41 | valid = true; | |
42 | } | |
43 | } | |
44 | ||
45 | void ContractionState::Clear() { | |
46 | delete []lines; | |
47 | lines = 0; | |
48 | size = 0; | |
49 | linesInDoc = 1; | |
50 | linesInDisplay = 1; | |
51 | } | |
52 | ||
53 | int ContractionState::LinesInDoc() const { | |
54 | return linesInDoc; | |
55 | } | |
56 | ||
57 | int ContractionState::LinesDisplayed() const { | |
58 | return linesInDisplay; | |
59 | } | |
60 | ||
61 | int ContractionState::DisplayFromDoc(int lineDoc) const { | |
62 | if (size == 0) { | |
63 | return lineDoc; | |
64 | } | |
65 | MakeValid(); | |
66 | if ((lineDoc >= 0) && (lineDoc < linesInDoc)) { | |
67 | return lines[lineDoc].displayLine; | |
68 | } | |
69 | return -1; | |
70 | } | |
71 | ||
72 | int ContractionState::DocFromDisplay(int lineDisplay) const { | |
73 | if (lineDisplay <= 0) | |
74 | return 0; | |
75 | if (lineDisplay >= linesInDisplay) | |
76 | return linesInDoc-1; | |
77 | if (size == 0) | |
78 | return lineDisplay; | |
79 | MakeValid(); | |
80 | return lines[lineDisplay].docLine; | |
81 | } | |
82 | ||
83 | void ContractionState::Grow(int sizeNew) { | |
84 | OneLine *linesNew = new OneLine[sizeNew]; | |
85 | if (linesNew) { | |
86 | int i = 0; | |
87 | for (; i < size; i++) { | |
88 | linesNew[i] = lines[i]; | |
89 | } | |
90 | for (; i < sizeNew; i++) { | |
91 | linesNew[i].displayLine = i; | |
92 | } | |
93 | delete []lines; | |
94 | lines = linesNew; | |
95 | size = sizeNew; | |
96 | valid = false; | |
97 | } else { | |
98 | Platform::DebugPrintf("No memory available\n"); | |
99 | // TODO: Blow up | |
100 | } | |
101 | } | |
102 | ||
103 | void ContractionState::InsertLines(int lineDoc, int lineCount) { | |
104 | if (size == 0) { | |
105 | linesInDoc += lineCount; | |
106 | linesInDisplay += lineCount; | |
107 | return; | |
108 | } | |
109 | //Platform::DebugPrintf("InsertLine[%d] = %d\n", lineDoc); | |
f6bcfd97 BP |
110 | if ((linesInDoc + lineCount + 2) >= size) { |
111 | Grow(linesInDoc + lineCount + growSize); | |
9ce192d4 RD |
112 | } |
113 | linesInDoc += lineCount; | |
114 | linesInDisplay += lineCount; | |
f6bcfd97 | 115 | for (int i = linesInDoc; i >= lineDoc + lineCount; i--) { |
9ce192d4 RD |
116 | lines[i].visible = lines[i - lineCount].visible; |
117 | lines[i].expanded = lines[i - lineCount].expanded; | |
118 | } | |
119 | for (int d=0;d<lineCount;d++) { | |
120 | lines[lineDoc+d].visible = true; // Should inherit visibility from context ? | |
121 | lines[lineDoc+d].expanded = true; | |
122 | } | |
123 | valid = false; | |
124 | } | |
125 | ||
126 | void ContractionState::DeleteLines(int lineDoc, int lineCount) { | |
127 | if (size == 0) { | |
128 | linesInDoc -= lineCount; | |
129 | linesInDisplay -= lineCount; | |
130 | return; | |
131 | } | |
f6bcfd97 BP |
132 | int deltaDisplayed = 0; |
133 | for (int d=0;d<lineCount;d++) { | |
9ce192d4 | 134 | if (lines[lineDoc+d].visible) |
f6bcfd97 BP |
135 | deltaDisplayed--; |
136 | } | |
9ce192d4 | 137 | for (int i = lineDoc; i < linesInDoc-lineCount; i++) { |
f6bcfd97 BP |
138 | if (i != 0) // Line zero is always visible |
139 | lines[i].visible = lines[i + lineCount].visible; | |
9ce192d4 RD |
140 | lines[i].expanded = lines[i + lineCount].expanded; |
141 | } | |
142 | linesInDoc -= lineCount; | |
f6bcfd97 | 143 | linesInDisplay += deltaDisplayed; |
9ce192d4 RD |
144 | valid = false; |
145 | } | |
146 | ||
147 | bool ContractionState::GetVisible(int lineDoc) const { | |
148 | if (size == 0) | |
149 | return true; | |
150 | if ((lineDoc >= 0) && (lineDoc < linesInDoc)) { | |
151 | return lines[lineDoc].visible; | |
152 | } else { | |
153 | return false; | |
154 | } | |
155 | } | |
156 | ||
157 | bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible) { | |
f6bcfd97 BP |
158 | if (lineDocStart == 0) |
159 | lineDocStart++; | |
160 | if (lineDocStart > lineDocEnd) | |
161 | return false; | |
9ce192d4 | 162 | if (size == 0) { |
f6bcfd97 | 163 | Grow(linesInDoc + growSize); |
9ce192d4 RD |
164 | } |
165 | // TODO: modify docLine members to mirror displayLine | |
166 | int delta = 0; | |
167 | // Change lineDocs | |
168 | if ((lineDocStart <= lineDocEnd) && (lineDocStart >= 0) && (lineDocEnd < linesInDoc)) { | |
169 | for (int line=lineDocStart; line <= lineDocEnd; line++) { | |
170 | if (lines[line].visible != visible) { | |
171 | delta += visible ? 1 : -1; | |
172 | lines[line].visible = visible; | |
173 | } | |
9ce192d4 RD |
174 | } |
175 | } | |
176 | linesInDisplay += delta; | |
177 | valid = false; | |
178 | return delta != 0; | |
179 | } | |
180 | ||
181 | bool ContractionState::GetExpanded(int lineDoc) const { | |
182 | if (size == 0) | |
183 | return true; | |
184 | if ((lineDoc >= 0) && (lineDoc < linesInDoc)) { | |
185 | return lines[lineDoc].expanded; | |
186 | } else { | |
187 | return false; | |
188 | } | |
189 | } | |
190 | ||
191 | bool ContractionState::SetExpanded(int lineDoc, bool expanded) { | |
192 | if (size == 0) { | |
f6bcfd97 | 193 | Grow(linesInDoc + growSize); |
9ce192d4 RD |
194 | } |
195 | if ((lineDoc >= 0) && (lineDoc < linesInDoc)) { | |
196 | if (lines[lineDoc].expanded != expanded) { | |
197 | lines[lineDoc].expanded = expanded; | |
198 | return true; | |
199 | } | |
200 | } | |
201 | return false; | |
202 | } | |
d134f170 RD |
203 | |
204 | void ContractionState::ShowAll() { | |
205 | delete []lines; | |
206 | lines = 0; | |
207 | size = 0; | |
208 | } |