]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/stc/scintilla/src/AutoComplete.cxx
wxMessageBox off the main thread lost result code.
[wxWidgets.git] / src / stc / scintilla / src / AutoComplete.cxx
... / ...
CommitLineData
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
22using namespace Scintilla;
23#endif
24
25AutoComplete::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
43AutoComplete::~AutoComplete() {
44 if (lb) {
45 lb->Destroy();
46 delete lb;
47 lb = 0;
48 }
49}
50
51bool AutoComplete::Active() const {
52 return active;
53}
54
55void 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
68void AutoComplete::SetStopChars(const char *stopChars_) {
69 strncpy(stopChars, stopChars_, sizeof(stopChars));
70 stopChars[sizeof(stopChars) - 1] = '\0';
71}
72
73bool AutoComplete::IsStopChar(char ch) {
74 return ch && strchr(stopChars, ch);
75}
76
77void AutoComplete::SetFillUpChars(const char *fillUpChars_) {
78 strncpy(fillUpChars, fillUpChars_, sizeof(fillUpChars));
79 fillUpChars[sizeof(fillUpChars) - 1] = '\0';
80}
81
82bool AutoComplete::IsFillUpChar(char ch) {
83 return ch && strchr(fillUpChars, ch);
84}
85
86void AutoComplete::SetSeparator(char separator_) {
87 separator = separator_;
88}
89
90char AutoComplete::GetSeparator() const {
91 return separator;
92}
93
94void AutoComplete::SetTypesep(char separator_) {
95 typesep = separator_;
96}
97
98char AutoComplete::GetTypesep() const {
99 return typesep;
100}
101
102void AutoComplete::SetList(const char *list) {
103 lb->SetList(list, separator, typesep);
104}
105
106int AutoComplete::GetSelection() const {
107 return lb->GetSelection();
108}
109
110std::string AutoComplete::GetValue(int item) const {
111 char value[maxItemLen];
112 lb->GetValue(item, value, sizeof(value));
113 return std::string(value);
114}
115
116void AutoComplete::Show(bool show) {
117 lb->Show(show);
118 if (show)
119 lb->Select(0);
120}
121
122void AutoComplete::Cancel() {
123 if (lb->Created()) {
124 lb->Clear();
125 lb->Destroy();
126 active = false;
127 }
128}
129
130
131void 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
142void 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