fixed bug with the caret positioning after SetValue() introduced by the last commit
[wxWidgets.git] / samples / richedit / kbList.cpp
1 /*-*- c++ -*-********************************************************
2 * kbList.cc : a double linked list *
3 * *
4 * (C) 1998 by Karsten Ballüder (Ballueder@usa.net) *
5 * *
6 * $Id$ *
7 * *
8 * $Log$
9 * Revision 1.1 1999/06/07 09:57:12 KB
10 * Formerly known as wxLayout.
11 *
12 * Revision 1.3 1998/11/19 20:34:50 KB
13 * fixes
14 *
15 * Revision 1.8 1998/09/23 08:57:27 KB
16 * changed deletion behaviour
17 *
18 * Revision 1.7 1998/08/16 21:21:29 VZ
19 *
20 * 1) fixed config file bug: it was never created (attempt to create ~/.M/config
21 * always failed, must mkdir("~/.M") first)
22 * 2) "redesign" of "Folder properties" dialog and bug corrected, small change to
23 * MInputBox (it was too wide)
24 * 3) bug in ProvFC when it didn't reckognize the books as being in the correct
25 * format (=> messages "can't reopen book") corrected
26 * 4) I tried to enhance MDialog_About(), but it didn't really work... oh well,
27 * I've never said I was an artist
28 *
29 * Revision 1.6 1998/07/08 11:56:56 KB
30 * M compiles and runs on Solaris 2.5/gcc 2.8/c-client gso
31 *
32 * Revision 1.5 1998/06/27 20:07:18 KB
33 * several bug fixes for kbList
34 * started adding my layout stuff
35 *
36 * Revision 1.1.1.1 1998/06/13 21:51:12 karsten
37 * initial code
38 *
39 * Revision 1.4 1998/05/24 14:48:00 KB
40 * lots of progress on Python, but cannot call functions yet
41 * kbList fixes again?
42 *
43 * Revision 1.3 1998/05/18 17:48:34 KB
44 * more list<>->kbList changes, fixes for wxXt, improved makefiles
45 *
46 * Revision 1.2 1998/05/14 16:39:31 VZ
47 *
48 * fixed SIGSEGV in ~kbList if the list is empty
49 *
50 * Revision 1.1 1998/05/13 19:02:11 KB
51 * added kbList, adapted MimeTypes for it, more python, new icons
52 *
53 *******************************************************************/
54
55 #ifdef __GNUG__
56 # pragma implementation "kbList.h"
57 #endif
58
59 #include "kbList.h"
60
61
62 kbListNode::kbListNode( void *ielement,
63 kbListNode *iprev,
64 kbListNode *inext)
65 {
66 next = inext;
67 prev = iprev;
68 if(prev)
69 prev->next = this;
70 if(next)
71 next->prev = this;
72 element = ielement;
73 }
74
75 kbListNode::~kbListNode()
76 {
77 if(prev)
78 prev->next = next;
79 if(next)
80 next->prev = prev;
81 }
82
83
84 kbList::iterator::iterator(kbListNode *n)
85 {
86 node = n;
87 }
88
89 void *
90 kbList::iterator::operator*()
91 {
92 return node->element;
93 }
94
95 kbList::iterator &
96 kbList::iterator::operator++()
97 {
98 node = node ? node->next : NULL;
99 return *this;
100 }
101
102 kbList::iterator &
103 kbList::iterator::operator--()
104 {
105 node = node ? node->prev : NULL;
106 return *this;
107 }
108 kbList::iterator &
109 kbList::iterator::operator++(int /* foo */)
110 {
111 return operator++();
112 }
113
114 kbList::iterator &
115 kbList::iterator::operator--(int /* bar */)
116 {
117 return operator--();
118 }
119
120
121 bool
122 kbList::iterator::operator !=(kbList::iterator const & i) const
123 {
124 return node != i.node;
125 }
126
127 bool
128 kbList::iterator::operator ==(kbList::iterator const & i) const
129 {
130 return node == i.node;
131 }
132
133 kbList::kbList(bool ownsEntriesFlag)
134 {
135 first = NULL;
136 last = NULL;
137 ownsEntries = ownsEntriesFlag;
138 }
139
140 void
141 kbList::push_back(void *element)
142 {
143 if(! first) // special case of empty list
144 {
145 first = new kbListNode(element);
146 last = first;
147 return;
148 }
149 else
150 last = new kbListNode(element, last);
151 }
152
153 void
154 kbList::push_front(void *element)
155 {
156 if(! first) // special case of empty list
157 {
158 push_back(element);
159 return;
160 }
161 else
162 first = new kbListNode(element, NULL, first);
163 }
164
165 void *
166 kbList::pop_back(void)
167 {
168 iterator i;
169 void *data;
170 bool ownsFlagBak = ownsEntries;
171 i = tail();
172 data = *i;
173 ownsEntries = false;
174 erase(i);
175 ownsEntries = ownsFlagBak;
176 return data;
177 }
178
179 void *
180 kbList::pop_front(void)
181 {
182 iterator i;
183 void *data;
184 bool ownsFlagBak = ownsEntries;
185
186 i = begin();
187 data = *i;
188 ownsEntries = false;
189 erase(i);
190 ownsEntries = ownsFlagBak;
191 return data;
192
193 }
194
195 void
196 kbList::insert(kbList::iterator & i, void *element)
197 {
198 if(! i.Node())
199 return;
200 else if(i.Node() == first)
201 {
202 push_front(element);
203 i = first;
204 return;
205 }
206 i = kbList::iterator(new kbListNode(element, i.Node()->prev, i.Node()));
207 }
208
209 void
210 kbList::doErase(kbList::iterator & i)
211 {
212 kbListNode
213 *node = i.Node(),
214 *prev, *next;
215
216 if(! node) // illegal iterator
217 return;
218
219 prev = node->prev;
220 next = node->next;
221
222 // correct first/last:
223 if(node == first)
224 first = node->next;
225 if(node == last) // don't put else here!
226 last = node->prev;
227
228 // build new links:
229 if(prev)
230 prev->next = next;
231 if(next)
232 next->prev = prev;
233
234 // delete this node and contents:
235 // now done separately
236 //if(ownsEntries)
237 //delete *i;
238 delete i.Node();
239
240 // change the iterator to next element:
241 i = kbList::iterator(next);
242 }
243
244 kbList::~kbList()
245 {
246 kbListNode *next;
247
248 while ( first != NULL )
249 {
250 next = first->next;
251 if(ownsEntries)
252 delete first->element;
253 delete first;
254 first = next;
255 }
256 }
257
258 kbList::iterator
259 kbList::begin(void) const
260 {
261 return kbList::iterator(first);
262 }
263
264 kbList::iterator
265 kbList::tail(void) const
266 {
267 return kbList::iterator(last);
268 }
269
270 kbList::iterator
271 kbList::end(void) const
272 {
273 return kbList::iterator(NULL); // the one after the last
274 }
275
276 unsigned
277 kbList::size(void) const // inefficient
278 {
279 unsigned count = 0;
280 kbList::iterator i;
281 for(i = begin(); i != end(); i++, count++)
282 ;
283 return count;
284 }
285
286
287
288
289
290
291
292 #ifdef KBLIST_TEST
293
294 #include <iostream.h>
295
296 KBLIST_DEFINE(kbListInt,int);
297
298 int main(void)
299 {
300 int
301 n, *ptr;
302 kbListInt
303 l;
304 kbListInt::iterator
305 i;
306
307 for(n = 0; n < 10; n++)
308 {
309 ptr = new int;
310 *ptr = n*n;
311 l.push_back(ptr);
312 }
313
314 i = l.begin(); // first element
315 i++; // 2nd
316 i++; // 3rd
317 i++; // 4th, insert here:
318 ptr = new int;
319 *ptr = 4444;
320 l.insert(i,ptr);
321
322 // this cannot work, because l.end() returns NULL:
323 i = l.end(); // behind last
324 i--; // still behind last
325 l.erase(i); // doesn't do anything
326
327 // this works:
328 i = l.tail(); // last element
329 i--;
330 --i;
331 l.erase(i); // erase 3rd last element (49)
332
333 for(i = l.begin(); i != l.end(); i++)
334 cout << *i << '\t' << *((int *)*i) << endl;
335
336
337 return 0;
338 }
339 #endif