]> git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/AutoComplete.cxx
Updated release notes for 2.9.5.
[wxWidgets.git] / src / stc / scintilla / src / AutoComplete.cxx
1 // Scintilla source code edit control
2 /** @file AutoComplete.cxx
3 ** Defines the auto completion list box.
4 **/
5 // Copyright 1998-2003 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 #include <string.h>
10 #include <stdio.h>
11 #include <assert.h>
12
13 #include <string>
14
15 #include "Platform.h"
16
17 #include "CharacterSet.h"
18 #include "AutoComplete.h"
19 #include "Scintilla.h"
20
21 #ifdef SCI_NAMESPACE
22 using namespace Scintilla;
23 #endif
24
25 AutoComplete::AutoComplete() :
26 active(false),
27 separator(' '),
28 typesep('?'),
29 ignoreCase(false),
30 chooseSingle(false),
31 lb(0),
32 posStart(0),
33 startLen(0),
34 cancelAtStartPos(true),
35 autoHide(true),
36 dropRestOfWord(false),
37 ignoreCaseBehaviour(SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE) {
38 lb = ListBox::Allocate();
39 stopChars[0] = '\0';
40 fillUpChars[0] = '\0';
41 }
42
43 AutoComplete::~AutoComplete() {
44 if (lb) {
45 lb->Destroy();
46 delete lb;
47 lb = 0;
48 }
49 }
50
51 bool AutoComplete::Active() const {
52 return active;
53 }
54
55 void AutoComplete::Start(Window &parent, int ctrlID,
56 int position, Point location, int startLen_,
57 int lineHeight, bool unicodeMode, int technology) {
58 if (active) {
59 Cancel();
60 }
61 lb->Create(parent, ctrlID, location, lineHeight, unicodeMode, technology);
62 lb->Clear();
63 active = true;
64 startLen = startLen_;
65 posStart = position;
66 }
67
68 void AutoComplete::SetStopChars(const char *stopChars_) {
69 strncpy(stopChars, stopChars_, sizeof(stopChars));
70 stopChars[sizeof(stopChars) - 1] = '\0';
71 }
72
73 bool AutoComplete::IsStopChar(char ch) {
74 return ch && strchr(stopChars, ch);
75 }
76
77 void AutoComplete::SetFillUpChars(const char *fillUpChars_) {
78 strncpy(fillUpChars, fillUpChars_, sizeof(fillUpChars));
79 fillUpChars[sizeof(fillUpChars) - 1] = '\0';
80 }
81
82 bool AutoComplete::IsFillUpChar(char ch) {
83 return ch && strchr(fillUpChars, ch);
84 }
85
86 void AutoComplete::SetSeparator(char separator_) {
87 separator = separator_;
88 }
89
90 char AutoComplete::GetSeparator() const {
91 return separator;
92 }
93
94 void AutoComplete::SetTypesep(char separator_) {
95 typesep = separator_;
96 }
97
98 char AutoComplete::GetTypesep() const {
99 return typesep;
100 }
101
102 void AutoComplete::SetList(const char *list) {
103 lb->SetList(list, separator, typesep);
104 }
105
106 int AutoComplete::GetSelection() const {
107 return lb->GetSelection();
108 }
109
110 std::string AutoComplete::GetValue(int item) const {
111 char value[maxItemLen];
112 lb->GetValue(item, value, sizeof(value));
113 return std::string(value);
114 }
115
116 void AutoComplete::Show(bool show) {
117 lb->Show(show);
118 if (show)
119 lb->Select(0);
120 }
121
122 void AutoComplete::Cancel() {
123 if (lb->Created()) {
124 lb->Clear();
125 lb->Destroy();
126 active = false;
127 }
128 }
129
130
131 void AutoComplete::Move(int delta) {
132 int count = lb->Length();
133 int current = lb->GetSelection();
134 current += delta;
135 if (current >= count)
136 current = count - 1;
137 if (current < 0)
138 current = 0;
139 lb->Select(current);
140 }
141
142 void AutoComplete::Select(const char *word) {
143 size_t lenWord = strlen(word);
144 int location = -1;
145 int start = 0; // lower bound of the api array block to search
146 int end = lb->Length() - 1; // upper bound of the api array block to search
147 while ((start <= end) && (location == -1)) { // Binary searching loop
148 int pivot = (start + end) / 2;
149 char item[maxItemLen];
150 lb->GetValue(pivot, item, maxItemLen);
151 int cond;
152 if (ignoreCase)
153 cond = CompareNCaseInsensitive(word, item, lenWord);
154 else
155 cond = strncmp(word, item, lenWord);
156 if (!cond) {
157 // Find first match
158 while (pivot > start) {
159 lb->GetValue(pivot-1, item, maxItemLen);
160 if (ignoreCase)
161 cond = CompareNCaseInsensitive(word, item, lenWord);
162 else
163 cond = strncmp(word, item, lenWord);
164 if (0 != cond)
165 break;
166 --pivot;
167 }
168 location = pivot;
169 if (ignoreCase
170 && ignoreCaseBehaviour == SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE) {
171 // Check for exact-case match
172 for (; pivot <= end; pivot++) {
173 lb->GetValue(pivot, item, maxItemLen);
174 if (!strncmp(word, item, lenWord)) {
175 location = pivot;
176 break;
177 }
178 if (CompareNCaseInsensitive(word, item, lenWord))
179 break;
180 }
181 }
182 } else if (cond < 0) {
183 end = pivot - 1;
184 } else if (cond > 0) {
185 start = pivot + 1;
186 }
187 }
188 if (location == -1 && autoHide)
189 Cancel();
190 else
191 lb->Select(location);
192 }
193