]> git.saurik.com Git - wxWidgets.git/blob - contrib/src/stc/scintilla/src/AutoComplete.cxx
Updated to Scintilla 1.67
[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,
47 int position, Point location, int startLen_,
48 int lineHeight, bool unicodeMode) {
49 if (active) {
50 Cancel();
51 }
52 lb->Create(parent, ctrlID, location, lineHeight, unicodeMode);
53 lb->Clear();
54 active = true;
55 startLen = startLen_;
56 posStart = position;
57 }
58
59 void AutoComplete::SetStopChars(const char *stopChars_) {
60 strncpy(stopChars, stopChars_, sizeof(stopChars));
61 stopChars[sizeof(stopChars) - 1] = '\0';
62 }
63
64 bool AutoComplete::IsStopChar(char ch) {
65 return ch && strchr(stopChars, ch);
66 }
67
68 void AutoComplete::SetFillUpChars(const char *fillUpChars_) {
69 strncpy(fillUpChars, fillUpChars_, sizeof(fillUpChars));
70 fillUpChars[sizeof(fillUpChars) - 1] = '\0';
71 }
72
73 bool AutoComplete::IsFillUpChar(char ch) {
74 return ch && strchr(fillUpChars, ch);
75 }
76
77 void AutoComplete::SetSeparator(char separator_) {
78 separator = separator_;
79 }
80
81 char AutoComplete::GetSeparator() {
82 return separator;
83 }
84
85 void AutoComplete::SetTypesep(char separator_) {
86 typesep = separator_;
87 }
88
89 char AutoComplete::GetTypesep() {
90 return typesep;
91 }
92
93 void AutoComplete::SetList(const char *list) {
94 lb->SetList(list, separator, typesep);
95 }
96
97 void AutoComplete::Show(bool show) {
98 lb->Show(show);
99 if (show)
100 lb->Select(0);
101 }
102
103 void AutoComplete::Cancel() {
104 if (lb->Created()) {
105 lb->Clear();
106 lb->Destroy();
107 active = false;
108 }
109 }
110
111
112 void AutoComplete::Move(int delta) {
113 int count = lb->Length();
114 int current = lb->GetSelection();
115 current += delta;
116 if (current >= count)
117 current = count - 1;
118 if (current < 0)
119 current = 0;
120 lb->Select(current);
121 }
122
123 void AutoComplete::Select(const char *word) {
124 size_t lenWord = strlen(word);
125 int location = -1;
126 const int maxItemLen=1000;
127 char item[maxItemLen];
128 int start = 0; // lower bound of the api array block to search
129 int end = lb->Length() - 1; // upper bound of the api array block to search
130 while ((start <= end) && (location == -1)) { // Binary searching loop
131 int pivot = (start + end) / 2;
132 lb->GetValue(pivot, item, maxItemLen);
133 int cond;
134 if (ignoreCase)
135 cond = CompareNCaseInsensitive(word, item, lenWord);
136 else
137 cond = strncmp(word, item, lenWord);
138 if (!cond) {
139 // Find first match
140 while (pivot > start) {
141 lb->GetValue(pivot-1, item, maxItemLen);
142 if (ignoreCase)
143 cond = CompareNCaseInsensitive(word, item, lenWord);
144 else
145 cond = strncmp(word, item, lenWord);
146 if (0 != cond)
147 break;
148 --pivot;
149 }
150 location = pivot;
151 if (ignoreCase) {
152 // Check for exact-case match
153 for (; pivot <= end; pivot++) {
154 lb->GetValue(pivot, item, maxItemLen);
155 if (!strncmp(word, item, lenWord)) {
156 location = pivot;
157 break;
158 }
159 if (CompareNCaseInsensitive(word, item, lenWord))
160 break;
161 }
162 }
163 } else if (cond < 0) {
164 end = pivot - 1;
165 } else if (cond > 0) {
166 start = pivot + 1;
167 }
168 }
169 if (location == -1 && autoHide)
170 Cancel();
171 else
172 lb->Select(location);
173 }
174