~ubuntu-branches/ubuntu/wily/geany/wily

« back to all changes in this revision

Viewing changes to scintilla/Selection.cxx

  • Committer: Package Import Robot
  • Author(s): Chow Loong Jin
  • Date: 2011-12-10 07:43:26 UTC
  • mfrom: (3.3.7 sid)
  • Revision ID: package-import@ubuntu.com-20111210074326-s8yqbew5i20h33tf
Tags: 0.21-1ubuntu1
* Merge from Debian Unstable, remaining changes:
  - debian/patches/20_use_evince_viewer.patch:
     + use evince as viewer for pdf and dvi files
  - debian/patches/20_use_x_terminal_emulator.patch:
     + use x-terminal-emulator as terminal
  - debian/control
     + Add breaks on geany-plugins-common << 0.20
* Also fixes bugs:
  - Filter for MATLAB/Octave files filters everythign (LP: 885505)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Scintilla source code edit control
2
 
/** @file Selection.cxx
3
 
 ** Classes maintaining the selection.
4
 
 **/
5
 
// Copyright 2009 by Neil Hodgson <neilh@scintilla.org>
6
 
// The License.txt file describes the conditions under which this software may be distributed.
7
 
 
8
 
#include <stdlib.h>
9
 
 
10
 
#include <vector>
11
 
 
12
 
#include "Platform.h"
13
 
 
14
 
#include "Scintilla.h"
15
 
 
16
 
#include "Selection.h"
17
 
 
18
 
#ifdef SCI_NAMESPACE
19
 
using namespace Scintilla;
20
 
#endif
21
 
 
22
 
void SelectionPosition::MoveForInsertDelete(bool insertion, int startChange, int length) {
23
 
        if (insertion) {
24
 
                if (position > startChange) {
25
 
                        position += length;
26
 
                }
27
 
        } else {
28
 
                if (position > startChange) {
29
 
                        int endDeletion = startChange + length;
30
 
                        if (position > endDeletion) {
31
 
                                position -= length;
32
 
                        } else {
33
 
                                position = startChange;
34
 
                        }
35
 
                }
36
 
        }
37
 
}
38
 
 
39
 
bool SelectionPosition::operator <(const SelectionPosition &other) const {
40
 
        if (position == other.position)
41
 
                return virtualSpace < other.virtualSpace;
42
 
        else
43
 
                return position < other.position;
44
 
}
45
 
 
46
 
bool SelectionPosition::operator >(const SelectionPosition &other) const {
47
 
        if (position == other.position)
48
 
                return virtualSpace > other.virtualSpace;
49
 
        else
50
 
                return position > other.position;
51
 
}
52
 
 
53
 
bool SelectionPosition::operator <=(const SelectionPosition &other) const {
54
 
        if (position == other.position && virtualSpace == other.virtualSpace)
55
 
                return true;
56
 
        else
57
 
                return other > *this;
58
 
}
59
 
 
60
 
bool SelectionPosition::operator >=(const SelectionPosition &other) const {
61
 
        if (position == other.position && virtualSpace == other.virtualSpace)
62
 
                return true;
63
 
        else
64
 
                return *this > other;
65
 
}
66
 
 
67
 
int SelectionRange::Length() const {
68
 
        if (anchor > caret) {
69
 
                return anchor.Position() - caret.Position();
70
 
        } else {
71
 
                return caret.Position() - anchor.Position();
72
 
        }
73
 
}
74
 
 
75
 
bool SelectionRange::Contains(int pos) const {
76
 
        if (anchor > caret)
77
 
                return (pos >= caret.Position()) && (pos <= anchor.Position());
78
 
        else
79
 
                return (pos >= anchor.Position()) && (pos <= caret.Position());
80
 
}
81
 
 
82
 
bool SelectionRange::Contains(SelectionPosition sp) const {
83
 
        if (anchor > caret)
84
 
                return (sp >= caret) && (sp <= anchor);
85
 
        else
86
 
                return (sp >= anchor) && (sp <= caret);
87
 
}
88
 
 
89
 
bool SelectionRange::ContainsCharacter(int posCharacter) const {
90
 
        if (anchor > caret)
91
 
                return (posCharacter >= caret.Position()) && (posCharacter < anchor.Position());
92
 
        else
93
 
                return (posCharacter >= anchor.Position()) && (posCharacter < caret.Position());
94
 
}
95
 
 
96
 
SelectionSegment SelectionRange::Intersect(SelectionSegment check) const {
97
 
        SelectionSegment inOrder(caret, anchor);
98
 
        if ((inOrder.start <= check.end) || (inOrder.end >= check.start)) {
99
 
                SelectionSegment portion = check;
100
 
                if (portion.start < inOrder.start)
101
 
                        portion.start = inOrder.start;
102
 
                if (portion.end > inOrder.end)
103
 
                        portion.end = inOrder.end;
104
 
                if (portion.start > portion.end)
105
 
                        return SelectionSegment();
106
 
                else
107
 
                        return portion;
108
 
        } else {
109
 
                return SelectionSegment();
110
 
        }
111
 
}
112
 
 
113
 
bool SelectionRange::Trim(SelectionRange range) {
114
 
        SelectionPosition startRange = range.Start();
115
 
        SelectionPosition endRange = range.End();
116
 
        SelectionPosition start = Start();
117
 
        SelectionPosition end = End();
118
 
        PLATFORM_ASSERT(start <= end);
119
 
        PLATFORM_ASSERT(startRange <= endRange);
120
 
        if ((startRange <= end) && (endRange >= start)) {
121
 
                if ((start > startRange) && (end < endRange)) {
122
 
                        // Completely covered by range -> empty at start
123
 
                        end = start;
124
 
                } else if ((start < startRange) && (end > endRange)) {
125
 
                        // Completely covers range -> empty at start
126
 
                        end = start;
127
 
                } else if (start <= startRange) {
128
 
                        // Trim end
129
 
                        end = startRange;
130
 
                } else { //
131
 
                        PLATFORM_ASSERT(end >= endRange);
132
 
                        // Trim start
133
 
                        start = endRange;
134
 
                }
135
 
                if (anchor > caret) {
136
 
                        caret = start;
137
 
                        anchor = end;
138
 
                } else {
139
 
                        anchor = start;
140
 
                        caret = end;
141
 
                }
142
 
                return Empty();
143
 
        } else {
144
 
                return false;
145
 
        }
146
 
}
147
 
 
148
 
// If range is all virtual collapse to start of virtual space
149
 
void SelectionRange::MinimizeVirtualSpace() {
150
 
        if (caret.Position() == anchor.Position()) {
151
 
                int virtualSpace = caret.VirtualSpace();
152
 
                if (virtualSpace > anchor.VirtualSpace())
153
 
                        virtualSpace = anchor.VirtualSpace();
154
 
                caret.SetVirtualSpace(virtualSpace);
155
 
                anchor.SetVirtualSpace(virtualSpace);
156
 
        }
157
 
}
158
 
 
159
 
Selection::Selection() : mainRange(0), moveExtends(false), tentativeMain(false), selType(selStream) {
160
 
        AddSelection(SelectionPosition(0));
161
 
}
162
 
 
163
 
Selection::~Selection() {
164
 
}
165
 
 
166
 
bool Selection::IsRectangular() const {
167
 
        return (selType == selRectangle) || (selType == selThin);
168
 
}
169
 
 
170
 
int Selection::MainCaret() const {
171
 
        return ranges[mainRange].caret.Position();
172
 
}
173
 
 
174
 
int Selection::MainAnchor() const {
175
 
        return ranges[mainRange].anchor.Position();
176
 
}
177
 
 
178
 
SelectionRange &Selection::Rectangular() {
179
 
        return rangeRectangular;
180
 
}
181
 
 
182
 
SelectionSegment Selection::Limits() const {
183
 
        if (ranges.empty()) {
184
 
                return SelectionSegment();
185
 
        } else {
186
 
                SelectionSegment sr(ranges[0].anchor, ranges[0].caret);
187
 
                for (size_t i=1; i<ranges.size(); i++) {
188
 
                        sr.Extend(ranges[i].anchor);
189
 
                        sr.Extend(ranges[i].caret);
190
 
                }
191
 
                return sr;
192
 
        }
193
 
}
194
 
 
195
 
SelectionSegment Selection::LimitsForRectangularElseMain() const {
196
 
        if (IsRectangular()) {
197
 
                return Limits();
198
 
        } else {
199
 
                return SelectionSegment(ranges[mainRange].caret, ranges[mainRange].anchor);
200
 
        }
201
 
}
202
 
 
203
 
size_t Selection::Count() const {
204
 
        return ranges.size();
205
 
}
206
 
 
207
 
size_t Selection::Main() const {
208
 
        return mainRange;
209
 
}
210
 
 
211
 
void Selection::SetMain(size_t r) {
212
 
        PLATFORM_ASSERT(r < ranges.size());
213
 
        mainRange = r;
214
 
}
215
 
 
216
 
SelectionRange &Selection::Range(size_t r) {
217
 
        return ranges[r];
218
 
}
219
 
 
220
 
SelectionRange &Selection::RangeMain() {
221
 
        return ranges[mainRange];
222
 
}
223
 
 
224
 
bool Selection::MoveExtends() const {
225
 
        return moveExtends;
226
 
}
227
 
 
228
 
void Selection::SetMoveExtends(bool moveExtends_) {
229
 
        moveExtends = moveExtends_;
230
 
}
231
 
 
232
 
bool Selection::Empty() const {
233
 
        for (size_t i=0; i<ranges.size(); i++) {
234
 
                if (!ranges[i].Empty())
235
 
                        return false;
236
 
        }
237
 
        return true;
238
 
}
239
 
 
240
 
SelectionPosition Selection::Last() const {
241
 
        SelectionPosition lastPosition;
242
 
        for (size_t i=0; i<ranges.size(); i++) {
243
 
                if (lastPosition < ranges[i].caret)
244
 
                        lastPosition = ranges[i].caret;
245
 
                if (lastPosition < ranges[i].anchor)
246
 
                        lastPosition = ranges[i].anchor;
247
 
        }
248
 
        return lastPosition;
249
 
}
250
 
 
251
 
int Selection::Length() const {
252
 
        int len = 0;
253
 
        for (size_t i=0; i<ranges.size(); i++) {
254
 
                len += ranges[i].Length();
255
 
        }
256
 
        return len;
257
 
}
258
 
 
259
 
void Selection::MovePositions(bool insertion, int startChange, int length) {
260
 
        for (size_t i=0; i<ranges.size(); i++) {
261
 
                ranges[i].caret.MoveForInsertDelete(insertion, startChange, length);
262
 
                ranges[i].anchor.MoveForInsertDelete(insertion, startChange, length);
263
 
        }
264
 
}
265
 
 
266
 
void Selection::TrimSelection(SelectionRange range) {
267
 
        for (size_t i=0; i<ranges.size();) {
268
 
                if ((i != mainRange) && (ranges[i].Trim(range))) {
269
 
                        // Trimmed to empty so remove
270
 
                        for (size_t j=i; j<ranges.size()-1; j++) {
271
 
                                ranges[j] = ranges[j+1];
272
 
                                if (j == mainRange-1)
273
 
                                        mainRange--;
274
 
                        }
275
 
                        ranges.pop_back();
276
 
                } else {
277
 
                        i++;
278
 
                }
279
 
        }
280
 
}
281
 
 
282
 
void Selection::SetSelection(SelectionRange range) {
283
 
        ranges.clear();
284
 
        ranges.push_back(range);
285
 
        mainRange = ranges.size() - 1;
286
 
}
287
 
 
288
 
void Selection::AddSelection(SelectionRange range) {
289
 
        TrimSelection(range);
290
 
        ranges.push_back(range);
291
 
        mainRange = ranges.size() - 1;
292
 
}
293
 
 
294
 
void Selection::TentativeSelection(SelectionRange range) {
295
 
        if (!tentativeMain) {
296
 
                rangesSaved = ranges;
297
 
        }
298
 
        ranges = rangesSaved;
299
 
        AddSelection(range);
300
 
        TrimSelection(ranges[mainRange]);
301
 
        tentativeMain = true;
302
 
}
303
 
 
304
 
void Selection::CommitTentative() {
305
 
        rangesSaved.clear();
306
 
        tentativeMain = false;
307
 
}
308
 
 
309
 
int Selection::CharacterInSelection(int posCharacter) const {
310
 
        for (size_t i=0; i<ranges.size(); i++) {
311
 
                if (ranges[i].ContainsCharacter(posCharacter))
312
 
                        return i == mainRange ? 1 : 2;
313
 
        }
314
 
        return 0;
315
 
}
316
 
 
317
 
int Selection::InSelectionForEOL(int pos) const {
318
 
        for (size_t i=0; i<ranges.size(); i++) {
319
 
                if (!ranges[i].Empty() && (pos > ranges[i].Start().Position()) && (pos <= ranges[i].End().Position()))
320
 
                        return i == mainRange ? 1 : 2;
321
 
        }
322
 
        return 0;
323
 
}
324
 
 
325
 
int Selection::VirtualSpaceFor(int pos) const {
326
 
        int virtualSpace = 0;
327
 
        for (size_t i=0; i<ranges.size(); i++) {
328
 
                if ((ranges[i].caret.Position() == pos) && (virtualSpace < ranges[i].caret.VirtualSpace()))
329
 
                        virtualSpace = ranges[i].caret.VirtualSpace();
330
 
                if ((ranges[i].anchor.Position() == pos) && (virtualSpace < ranges[i].anchor.VirtualSpace()))
331
 
                        virtualSpace = ranges[i].anchor.VirtualSpace();
332
 
        }
333
 
        return virtualSpace;
334
 
}
335
 
 
336
 
void Selection::Clear() {
337
 
        ranges.clear();
338
 
        ranges.push_back(SelectionRange());
339
 
        mainRange = ranges.size() - 1;
340
 
        selType = selStream;
341
 
        moveExtends = false;
342
 
        ranges[mainRange].Reset();
343
 
        rangeRectangular.Reset();
344
 
}
345
 
 
346
 
void Selection::RemoveDuplicates() {
347
 
        for (size_t i=0; i<ranges.size()-1; i++) {
348
 
                if (ranges[i].Empty()) {
349
 
                        size_t j=i+1;
350
 
                        while (j<ranges.size()) {
351
 
                                if (ranges[i] == ranges[j]) {
352
 
                                        ranges.erase(ranges.begin() + j);
353
 
                                        if (mainRange >= j)
354
 
                                                mainRange--;
355
 
                                } else {
356
 
                                        j++;
357
 
                                }
358
 
                        }
359
 
                }
360
 
        }
361
 
}
362
 
 
363
 
void Selection::RotateMain() {
364
 
        mainRange = (mainRange + 1) % ranges.size();
365
 
}
366