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