Update of German translation
[geany-mirror.git] / scintilla / src / ContractionState.cxx
blob80f79de295a850582152c6dc8600746766a01545
1 // Scintilla source code edit control
2 /** @file ContractionState.cxx
3 ** Manages visibility of lines for folding and wrapping.
4 **/
5 // Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org>
6 // The License.txt file describes the conditions under which this software may be distributed.
8 #include <string.h>
10 #include <stdexcept>
11 #include <algorithm>
13 #include "Platform.h"
15 #include "Position.h"
16 #include "SplitVector.h"
17 #include "Partitioning.h"
18 #include "RunStyles.h"
19 #include "ContractionState.h"
21 #ifdef SCI_NAMESPACE
22 using namespace Scintilla;
23 #endif
25 ContractionState::ContractionState() : visible(0), expanded(0), heights(0), displayLines(0), linesInDocument(1) {
26 //InsertLine(0);
29 ContractionState::~ContractionState() {
30 Clear();
33 void ContractionState::EnsureData() {
34 if (OneToOne()) {
35 visible = new RunStyles();
36 expanded = new RunStyles();
37 heights = new RunStyles();
38 displayLines = new Partitioning(4);
39 InsertLines(0, linesInDocument);
43 void ContractionState::Clear() {
44 delete visible;
45 visible = 0;
46 delete expanded;
47 expanded = 0;
48 delete heights;
49 heights = 0;
50 delete displayLines;
51 displayLines = 0;
52 linesInDocument = 1;
55 int ContractionState::LinesInDoc() const {
56 if (OneToOne()) {
57 return linesInDocument;
58 } else {
59 return displayLines->Partitions() - 1;
63 int ContractionState::LinesDisplayed() const {
64 if (OneToOne()) {
65 return linesInDocument;
66 } else {
67 return displayLines->PositionFromPartition(LinesInDoc());
71 int ContractionState::DisplayFromDoc(int lineDoc) const {
72 if (OneToOne()) {
73 return (lineDoc <= linesInDocument) ? lineDoc : linesInDocument;
74 } else {
75 if (lineDoc > displayLines->Partitions())
76 lineDoc = displayLines->Partitions();
77 return displayLines->PositionFromPartition(lineDoc);
81 int ContractionState::DisplayLastFromDoc(int lineDoc) const {
82 return DisplayFromDoc(lineDoc) + GetHeight(lineDoc) - 1;
85 int ContractionState::DocFromDisplay(int lineDisplay) const {
86 if (OneToOne()) {
87 return lineDisplay;
88 } else {
89 if (lineDisplay <= 0) {
90 return 0;
92 if (lineDisplay > LinesDisplayed()) {
93 return displayLines->PartitionFromPosition(LinesDisplayed());
95 int lineDoc = displayLines->PartitionFromPosition(lineDisplay);
96 PLATFORM_ASSERT(GetVisible(lineDoc));
97 return lineDoc;
101 void ContractionState::InsertLine(int lineDoc) {
102 if (OneToOne()) {
103 linesInDocument++;
104 } else {
105 visible->InsertSpace(lineDoc, 1);
106 visible->SetValueAt(lineDoc, 1);
107 expanded->InsertSpace(lineDoc, 1);
108 expanded->SetValueAt(lineDoc, 1);
109 heights->InsertSpace(lineDoc, 1);
110 heights->SetValueAt(lineDoc, 1);
111 int lineDisplay = DisplayFromDoc(lineDoc);
112 displayLines->InsertPartition(lineDoc, lineDisplay);
113 displayLines->InsertText(lineDoc, 1);
117 void ContractionState::InsertLines(int lineDoc, int lineCount) {
118 for (int l = 0; l < lineCount; l++) {
119 InsertLine(lineDoc + l);
121 Check();
124 void ContractionState::DeleteLine(int lineDoc) {
125 if (OneToOne()) {
126 linesInDocument--;
127 } else {
128 if (GetVisible(lineDoc)) {
129 displayLines->InsertText(lineDoc, -heights->ValueAt(lineDoc));
131 displayLines->RemovePartition(lineDoc);
132 visible->DeleteRange(lineDoc, 1);
133 expanded->DeleteRange(lineDoc, 1);
134 heights->DeleteRange(lineDoc, 1);
138 void ContractionState::DeleteLines(int lineDoc, int lineCount) {
139 for (int l = 0; l < lineCount; l++) {
140 DeleteLine(lineDoc);
142 Check();
145 bool ContractionState::GetVisible(int lineDoc) const {
146 if (OneToOne()) {
147 return true;
148 } else {
149 if (lineDoc >= visible->Length())
150 return true;
151 return visible->ValueAt(lineDoc) == 1;
155 bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool isVisible) {
156 if (OneToOne() && isVisible) {
157 return false;
158 } else {
159 EnsureData();
160 int delta = 0;
161 Check();
162 if ((lineDocStart <= lineDocEnd) && (lineDocStart >= 0) && (lineDocEnd < LinesInDoc())) {
163 for (int line = lineDocStart; line <= lineDocEnd; line++) {
164 if (GetVisible(line) != isVisible) {
165 int difference = isVisible ? heights->ValueAt(line) : -heights->ValueAt(line);
166 visible->SetValueAt(line, isVisible ? 1 : 0);
167 displayLines->InsertText(line, difference);
168 delta += difference;
171 } else {
172 return false;
174 Check();
175 return delta != 0;
179 bool ContractionState::HiddenLines() const {
180 if (OneToOne()) {
181 return false;
182 } else {
183 return !visible->AllSameAs(1);
187 bool ContractionState::GetExpanded(int lineDoc) const {
188 if (OneToOne()) {
189 return true;
190 } else {
191 Check();
192 return expanded->ValueAt(lineDoc) == 1;
196 bool ContractionState::SetExpanded(int lineDoc, bool isExpanded) {
197 if (OneToOne() && isExpanded) {
198 return false;
199 } else {
200 EnsureData();
201 if (isExpanded != (expanded->ValueAt(lineDoc) == 1)) {
202 expanded->SetValueAt(lineDoc, isExpanded ? 1 : 0);
203 Check();
204 return true;
205 } else {
206 Check();
207 return false;
212 int ContractionState::ContractedNext(int lineDocStart) const {
213 if (OneToOne()) {
214 return -1;
215 } else {
216 Check();
217 if (!expanded->ValueAt(lineDocStart)) {
218 return lineDocStart;
219 } else {
220 int lineDocNextChange = expanded->EndRun(lineDocStart);
221 if (lineDocNextChange < LinesInDoc())
222 return lineDocNextChange;
223 else
224 return -1;
229 int ContractionState::GetHeight(int lineDoc) const {
230 if (OneToOne()) {
231 return 1;
232 } else {
233 return heights->ValueAt(lineDoc);
237 // Set the number of display lines needed for this line.
238 // Return true if this is a change.
239 bool ContractionState::SetHeight(int lineDoc, int height) {
240 if (OneToOne() && (height == 1)) {
241 return false;
242 } else if (lineDoc < LinesInDoc()) {
243 EnsureData();
244 if (GetHeight(lineDoc) != height) {
245 if (GetVisible(lineDoc)) {
246 displayLines->InsertText(lineDoc, height - GetHeight(lineDoc));
248 heights->SetValueAt(lineDoc, height);
249 Check();
250 return true;
251 } else {
252 Check();
253 return false;
255 } else {
256 return false;
260 void ContractionState::ShowAll() {
261 int lines = LinesInDoc();
262 Clear();
263 linesInDocument = lines;
266 // Debugging checks
268 void ContractionState::Check() const {
269 #ifdef CHECK_CORRECTNESS
270 for (int vline = 0; vline < LinesDisplayed(); vline++) {
271 const int lineDoc = DocFromDisplay(vline);
272 PLATFORM_ASSERT(GetVisible(lineDoc));
274 for (int lineDoc = 0; lineDoc < LinesInDoc(); lineDoc++) {
275 const int displayThis = DisplayFromDoc(lineDoc);
276 const int displayNext = DisplayFromDoc(lineDoc + 1);
277 const int height = displayNext - displayThis;
278 PLATFORM_ASSERT(height >= 0);
279 if (GetVisible(lineDoc)) {
280 PLATFORM_ASSERT(GetHeight(lineDoc) == height);
281 } else {
282 PLATFORM_ASSERT(0 == height);
285 #endif