OSDN Git Service

Commit DialogBox compile Okay
[tortoisegit/TortoiseGitJp.git] / ext / scintilla / src / ContractionState.cxx
1 // Scintilla source code edit control\r
2 /** @file ContractionState.cxx\r
3  ** Manages visibility of lines for folding and wrapping.\r
4  **/\r
5 // Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org>\r
6 // The License.txt file describes the conditions under which this software may be distributed.\r
7 \r
8 #include <string.h>\r
9 \r
10 #include "Platform.h"\r
11 \r
12 #include "SplitVector.h"\r
13 #include "Partitioning.h"\r
14 #include "RunStyles.h"\r
15 #include "ContractionState.h"\r
16 \r
17 #ifdef SCI_NAMESPACE\r
18 using namespace Scintilla;\r
19 #endif\r
20 \r
21 ContractionState::ContractionState() : visible(0), expanded(0), heights(0), displayLines(0), linesInDocument(1) {\r
22         //InsertLine(0);\r
23 }\r
24 \r
25 ContractionState::~ContractionState() {\r
26         Clear();\r
27 }\r
28 \r
29 void ContractionState::EnsureData() {\r
30         if (OneToOne()) {\r
31                 visible = new RunStyles();\r
32                 expanded = new RunStyles();\r
33                 heights = new RunStyles();\r
34                 displayLines = new Partitioning(4);\r
35                 InsertLines(0, linesInDocument);\r
36         }\r
37 }\r
38 \r
39 void ContractionState::Clear() {\r
40         delete visible;\r
41         visible = 0;\r
42         delete expanded;\r
43         expanded = 0;\r
44         delete heights;\r
45         heights = 0;\r
46         delete displayLines;\r
47         displayLines = 0;\r
48         linesInDocument = 1;\r
49 }\r
50 \r
51 int ContractionState::LinesInDoc() const {\r
52         if (OneToOne()) {\r
53                 return linesInDocument;\r
54         } else {\r
55                 return displayLines->Partitions() - 1;\r
56         }\r
57 }\r
58 \r
59 int ContractionState::LinesDisplayed() const {\r
60         if (OneToOne()) {\r
61                 return linesInDocument;\r
62         } else {\r
63                 return displayLines->PositionFromPartition(LinesInDoc());\r
64         }\r
65 }\r
66 \r
67 int ContractionState::DisplayFromDoc(int lineDoc) const {\r
68         if (OneToOne()) {\r
69                 return lineDoc;\r
70         } else {\r
71                 if (lineDoc > displayLines->Partitions())\r
72                         lineDoc = displayLines->Partitions();\r
73                 return displayLines->PositionFromPartition(lineDoc);\r
74         }\r
75 }\r
76 \r
77 int ContractionState::DocFromDisplay(int lineDisplay) const {\r
78         if (OneToOne()) {\r
79                 return lineDisplay;\r
80         } else {\r
81                 if (lineDisplay <= 0) {\r
82                         return 0;\r
83                 }\r
84                 if (lineDisplay > LinesDisplayed()) {\r
85                         return displayLines->PartitionFromPosition(LinesDisplayed());\r
86                 }\r
87                 int lineDoc = displayLines->PartitionFromPosition(lineDisplay);\r
88                 PLATFORM_ASSERT(GetVisible(lineDoc));\r
89                 return lineDoc;\r
90         }\r
91 }\r
92 \r
93 void ContractionState::InsertLine(int lineDoc) {\r
94         if (OneToOne()) {\r
95                 linesInDocument++;\r
96         } else {\r
97                 visible->InsertSpace(lineDoc, 1);\r
98                 visible->SetValueAt(lineDoc, 1);\r
99                 expanded->InsertSpace(lineDoc, 1);\r
100                 expanded->SetValueAt(lineDoc, 1);\r
101                 heights->InsertSpace(lineDoc, 1);\r
102                 heights->SetValueAt(lineDoc, 1);\r
103                 int lineDisplay = DisplayFromDoc(lineDoc);\r
104                 displayLines->InsertPartition(lineDoc, lineDisplay);\r
105                 displayLines->InsertText(lineDoc, 1);\r
106         }\r
107 }\r
108 \r
109 void ContractionState::InsertLines(int lineDoc, int lineCount) {\r
110         for (int l = 0; l < lineCount; l++) {\r
111                 InsertLine(lineDoc + l);\r
112         }\r
113         Check();\r
114 }\r
115 \r
116 void ContractionState::DeleteLine(int lineDoc) {\r
117         if (OneToOne()) {\r
118                 linesInDocument--;\r
119         } else {\r
120                 if (GetVisible(lineDoc)) {\r
121                         displayLines->InsertText(lineDoc, -heights->ValueAt(lineDoc));\r
122                 }\r
123                 displayLines->RemovePartition(lineDoc);\r
124                 visible->DeleteRange(lineDoc, 1);\r
125                 expanded->DeleteRange(lineDoc, 1);\r
126                 heights->DeleteRange(lineDoc, 1);\r
127         }\r
128 }\r
129 \r
130 void ContractionState::DeleteLines(int lineDoc, int lineCount) {\r
131         for (int l = 0; l < lineCount; l++) {\r
132                 DeleteLine(lineDoc);\r
133         }\r
134         Check();\r
135 }\r
136 \r
137 bool ContractionState::GetVisible(int lineDoc) const {\r
138         if (OneToOne()) {\r
139                 return true;\r
140         } else {\r
141                 if (lineDoc >= visible->Length())\r
142                         return true;\r
143                 return visible->ValueAt(lineDoc) == 1;\r
144         }\r
145 }\r
146 \r
147 bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible_) {\r
148         if (OneToOne() && visible_) {\r
149                 return false;\r
150         } else {\r
151                 EnsureData();\r
152                 int delta = 0;\r
153                 Check();\r
154                 if ((lineDocStart <= lineDocEnd) && (lineDocStart >= 0) && (lineDocEnd < LinesInDoc())) {\r
155                         for (int line = lineDocStart; line <= lineDocEnd; line++) {\r
156                                 if (GetVisible(line) != visible_) {\r
157                                         int difference = visible_ ? heights->ValueAt(line) : -heights->ValueAt(line);\r
158                                         visible->SetValueAt(line, visible_ ? 1 : 0);\r
159                                         displayLines->InsertText(line, difference);\r
160                                         delta += difference;\r
161                                 }\r
162                         }\r
163                 } else {\r
164                         return false;\r
165                 }\r
166                 Check();\r
167                 return delta != 0;\r
168         }\r
169 }\r
170 \r
171 bool ContractionState::GetExpanded(int lineDoc) const {\r
172         if (OneToOne()) {\r
173                 return true;\r
174         } else {\r
175                 Check();\r
176                 return expanded->ValueAt(lineDoc) == 1;\r
177         }\r
178 }\r
179 \r
180 bool ContractionState::SetExpanded(int lineDoc, bool expanded_) {\r
181         if (OneToOne() && expanded_) {\r
182                 return false;\r
183         } else {\r
184                 EnsureData();\r
185                 if (expanded_ != (expanded->ValueAt(lineDoc) == 1)) {\r
186                         expanded->SetValueAt(lineDoc, expanded_ ? 1 : 0);\r
187                         Check();\r
188                         return true;\r
189                 } else {\r
190                         Check();\r
191                         return false;\r
192                 }\r
193         }\r
194 }\r
195 \r
196 int ContractionState::GetHeight(int lineDoc) const {\r
197         if (OneToOne()) {\r
198                 return 1;\r
199         } else {\r
200                 return heights->ValueAt(lineDoc);\r
201         }\r
202 }\r
203 \r
204 // Set the number of display lines needed for this line.\r
205 // Return true if this is a change.\r
206 bool ContractionState::SetHeight(int lineDoc, int height) {\r
207         if (OneToOne() && (height == 1)) {\r
208                 return false;\r
209         } else {\r
210                 EnsureData();\r
211                 if (GetHeight(lineDoc) != height) {\r
212                         if (GetVisible(lineDoc)) {\r
213                                 displayLines->InsertText(lineDoc, height - GetHeight(lineDoc));\r
214                         }\r
215                         heights->SetValueAt(lineDoc, height);\r
216                         Check();\r
217                         return true;\r
218                 } else {\r
219                         Check();\r
220                         return false;\r
221                 }\r
222         }\r
223 }\r
224 \r
225 void ContractionState::ShowAll() {\r
226         int lines = LinesInDoc();\r
227         Clear();\r
228         linesInDocument = lines;\r
229 }\r
230 \r
231 // Debugging checks\r
232 \r
233 void ContractionState::Check() const {\r
234 #ifdef CHECK_CORRECTNESS\r
235         for (int vline = 0;vline < LinesDisplayed(); vline++) {\r
236                 const int lineDoc = DocFromDisplay(vline);\r
237                 PLATFORM_ASSERT(GetVisible(lineDoc));\r
238         }\r
239         for (int lineDoc = 0;lineDoc < LinesInDoc(); lineDoc++) {\r
240                 const int displayThis = DisplayFromDoc(lineDoc);\r
241                 const int displayNext = DisplayFromDoc(lineDoc + 1);\r
242                 const int height = displayNext - displayThis;\r
243                 PLATFORM_ASSERT(height >= 0);\r
244                 if (GetVisible(lineDoc)) {\r
245                         PLATFORM_ASSERT(GetHeight(lineDoc) == height);\r
246                 } else {\r
247                         PLATFORM_ASSERT(0 == height);\r
248                 }\r
249         }\r
250 #endif\r
251 }\r