5
* $Date: 2001-01-04 19:58:30 $
10
* Declare file local prototypes.
12
static BINDFN_PROTO(adjustAlphalistCB);
13
static BINDFN_PROTO(completeWordCB);
14
static int preProcessEntryField (EObjectType cdktype, void *object, void *clientData, chtype input);
16
DeclareCDKObjects(my_funcs,Alphalist);
19
* This creates the alphalist widget.
21
CDKALPHALIST *newCDKAlphalist (CDKSCREEN *cdkscreen, int xplace, int yplace, int height, int width, char *title, char *label, char *list[], int listSize, chtype fillerChar, chtype highlight, boolean Box, boolean shadow)
23
/* Set up some variables. */
24
CDKALPHALIST *alphalist = newCDKObject(CDKALPHALIST, &my_funcs);
25
chtype *chtypeLabel = 0;
26
int parentWidth = getmaxx(cdkscreen->window);
27
int parentHeight = getmaxy(cdkscreen->window);
29
int boxHeight = height;
37
* If the height is a negative value, the height will
38
* be ROWS-height, otherwise, the height will be the
41
boxHeight = setWidgetDimension (parentHeight, height, 0);
44
* If the width is a negative value, the width will
45
* be COLS-width, otherwise, the width will be the
48
boxWidth = setWidgetDimension (parentWidth, width, 0);
50
/* Translate the label char *pointer to a chtype pointer. */
53
chtypeLabel = char2Chtype (label, &labelLen, &junk2);
54
freeChtype (chtypeLabel);
57
/* Rejustify the x and y positions if we need to. */
58
alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight);
60
/* Make the file selector window. */
61
alphalist->win = newwin (boxHeight + !!shadow, boxWidth + !!shadow, ypos, xpos);
63
if (alphalist->win == 0)
67
keypad (alphalist->win, TRUE);
69
/* Set some variables. */
70
ScreenOf(alphalist) = cdkscreen;
71
alphalist->parent = cdkscreen->window;
72
alphalist->highlight = highlight;
73
alphalist->fillerChar = fillerChar;
74
alphalist->boxHeight = boxHeight;
75
alphalist->boxWidth = boxWidth;
76
alphalist->exitType = vNEVER_ACTIVATED;
77
ObjOf(alphalist)->box = Box;
78
alphalist->shadow = shadow;
80
/* We need to sort the list before we use it. */
81
quickSort (list, 0, listSize-1);
83
/* Copy the list information. */
84
for (x=0; x < listSize; x++)
86
alphalist->list[x] = copyChar (list[x]);
88
alphalist->listSize = listSize;
90
/* Create the entry field. */
91
entryWidth = boxWidth - (labelLen + 2);
92
alphalist->entryField = newCDKEntry (cdkscreen,
93
getbegx(alphalist->win),
94
getbegy(alphalist->win),
97
vMIXED, entryWidth, 0, 512,
99
setCDKEntryLLChar (alphalist->entryField, ACS_LTEE);
100
setCDKEntryLRChar (alphalist->entryField, ACS_RTEE);
102
/* Set the key bindings for the entry field. */
103
bindCDKObject (vENTRY, alphalist->entryField, KEY_UP, adjustAlphalistCB, alphalist);
104
bindCDKObject (vENTRY, alphalist->entryField, KEY_DOWN, adjustAlphalistCB, alphalist);
105
bindCDKObject (vENTRY, alphalist->entryField, KEY_NPAGE, adjustAlphalistCB, alphalist);
106
bindCDKObject (vENTRY, alphalist->entryField, CONTROL('F'), adjustAlphalistCB, alphalist);
107
bindCDKObject (vENTRY, alphalist->entryField, KEY_PPAGE, adjustAlphalistCB, alphalist);
108
bindCDKObject (vENTRY, alphalist->entryField, CONTROL('B'), adjustAlphalistCB, alphalist);
109
bindCDKObject (vENTRY, alphalist->entryField, KEY_TAB, completeWordCB, alphalist);
111
/* Set up the post-process function for the entry field. */
112
setCDKEntryPreProcess (alphalist->entryField, preProcessEntryField, alphalist);
114
/* Create the scrolling list. */
115
alphalist->scrollField = newCDKScroll (cdkscreen,
116
getbegx(alphalist->win),
117
getbegy(alphalist->win) + (alphalist->entryField)->titleLines + 2,
119
boxHeight-((alphalist->entryField)->titleLines + 2),
122
NONUMBERS, A_REVERSE,
124
setCDKScrollULChar (alphalist->scrollField, ACS_LTEE);
125
setCDKScrollURChar (alphalist->scrollField, ACS_RTEE);
127
/* Register this baby. */
128
registerCDKObject (cdkscreen, vALPHALIST, alphalist);
130
/* Return the file selector pointer. */
135
* This erases the file selector from the screen.
137
static void _eraseCDKAlphalist (CDKOBJS *obj)
139
CDKALPHALIST *alphalist = (CDKALPHALIST *)obj;
141
eraseCDKScroll (alphalist->scrollField);
142
eraseCDKEntry (alphalist->entryField);
144
eraseCursesWindow (alphalist->win);
148
* This moves the alphalist field to the given location.
150
static void _moveCDKAlphalist (CDKOBJS *object, int xplace, int yplace, boolean relative, boolean refresh_flag)
152
CDKALPHALIST *alphalist = (CDKALPHALIST *)object;
155
* If this is a relative move, then we will adjust where we want
160
xplace += getbegx(alphalist->win);
161
yplace += getbegy(alphalist->win);
164
/* Adjust the window if we need to. */
165
alignxy (WindowOf(alphalist), &xplace, &yplace, alphalist->boxWidth, alphalist->boxHeight);
167
/* Move the window to the new location. */
168
moveCursesWindow(alphalist->win, xplace, yplace);
170
/* Move the sub-widgets. */
172
moveCDKEntry (alphalist->entryField, xplace, yplace, relative, FALSE);
173
moveCDKScroll (alphalist->scrollField, xplace, yplace, relative, FALSE);
175
/* Redraw the window, if they asked for it. */
178
drawCDKAlphalist (alphalist, ObjOf(alphalist)->box);
183
* This draws the file selector widget.
185
static void _drawCDKAlphalist (CDKOBJS *obj, boolean Box GCC_UNUSED)
187
CDKALPHALIST * alphalist = (CDKALPHALIST *)obj;
189
/* Draw in the entry field. */
190
drawCDKEntry (alphalist->entryField, ObjOf(alphalist->entryField)->box);
192
/* Draw in the scroll field. */
193
drawCDKScroll (alphalist->scrollField, ObjOf(alphalist->scrollField)->box);
197
* This activates the file selector.
199
char *activateCDKAlphalist (CDKALPHALIST *alphalist, chtype *actions)
203
/* Draw the widget. */
204
drawCDKAlphalist (alphalist, ObjOf(alphalist)->box);
206
/* Activate the widget. */
207
ret = activateCDKEntry (alphalist->entryField, actions);
209
/* Copy the exit type from the entry field. */
210
alphalist->exitType = alphalist->entryField->exitType;
212
/* Determine the exit status. */
213
if (alphalist->exitType != vEARLY_EXIT)
221
* This injects a single character into the alphalist.
223
char *injectCDKAlphalist (CDKALPHALIST *alphalist, chtype input)
227
/* Draw the widget. */
228
drawCDKAlphalist (alphalist, ObjOf(alphalist)->box);
230
/* Inject a character into the widget. */
231
ret = injectCDKEntry (alphalist->entryField, input);
233
/* Copy the exit type from the entry field. */
234
alphalist->exitType = alphalist->entryField->exitType;
236
/* Determine the exit status. */
237
if (alphalist->exitType != vEARLY_EXIT)
245
* This sets multiple attributes of the widget.
247
void setCDKAlphalist (CDKALPHALIST *alphalist, char *list[], int listSize, chtype fillerChar, chtype highlight, boolean Box)
249
setCDKAlphalistContents (alphalist, list, listSize);
250
setCDKAlphalistFillerChar (alphalist, fillerChar);
251
setCDKAlphalistHighlight (alphalist, highlight);
252
setCDKAlphalistBox (alphalist, Box);
256
* This function sets the information inside the file selector.
258
void setCDKAlphalistContents (CDKALPHALIST *alphalist, char *list[], int listSize)
260
/* Declare local variables. */
261
CDKSCROLL *scrollp = (CDKSCROLL *)alphalist->scrollField;
262
CDKENTRY *entry = (CDKENTRY *)alphalist->entryField;
265
freeCharList (alphalist->list, alphalist->listSize);
267
/* We need to sort the list before we use it. */
268
quickSort (list, 0, listSize-1);
270
/* Copy in the new information. */
271
alphalist->listSize = listSize;
272
for (x=0; x < listSize; x++)
274
alphalist->list[x] = copyChar (list[x]);
277
/* Set the information in the scrolling list. */
278
setCDKScroll (scrollp, list, listSize, NONUMBERS, scrollp->highlight, ObjOf(scrollp)->box);
280
/* Clean out the entry field. */
281
cleanCDKEntry (entry);
283
/* Redraw the alphalist. */
284
eraseCDKAlphalist (alphalist);
285
drawCDKAlphalist (alphalist, ObjOf(alphalist)->box);
289
* This returns the contents of the alphalist.
291
char **getCDKAlphalistContents (CDKALPHALIST *alphalist, int *size)
293
(*size) = alphalist->listSize;
294
return alphalist->list;
298
* This sets the filler character of the entry field of the alphalist.
300
void setCDKAlphalistFillerChar (CDKALPHALIST *alphalist, chtype fillerCharacter)
302
CDKENTRY *entry = (CDKENTRY *)alphalist->entryField;
304
alphalist->fillerChar = fillerCharacter;
306
setCDKEntryFillerChar (entry, fillerCharacter);
308
chtype getCDKAlphalistFillerChar (CDKALPHALIST *alphalist)
310
return alphalist->fillerChar;
314
* This sets the highlight bar attributes.
316
void setCDKAlphalistHighlight (CDKALPHALIST *alphalist, chtype highlight)
318
alphalist->highlight = highlight;
320
chtype getCDKAlphalistHighlight (CDKALPHALIST *alphalist)
322
return alphalist->highlight;
326
* This sets whether or not the widget will be drawn with a box.
328
void setCDKAlphalistBox (CDKALPHALIST *alphalist, boolean Box)
330
ObjOf(alphalist)->box = Box;
333
boolean getCDKAlphalistBox (CDKALPHALIST *alphalist)
335
return ObjOf(alphalist)->box;
339
* These functions set the drawing characters of the widget.
341
void setCDKAlphalistULChar (CDKALPHALIST *alphalist, chtype character)
343
setCDKEntryULChar (alphalist->entryField, character);
345
void setCDKAlphalistURChar (CDKALPHALIST *alphalist, chtype character)
347
setCDKEntryURChar (alphalist->entryField, character);
349
void setCDKAlphalistLLChar (CDKALPHALIST *alphalist, chtype character)
351
setCDKScrollLLChar (alphalist->scrollField, character);
353
void setCDKAlphalistLRChar (CDKALPHALIST *alphalist, chtype character)
355
setCDKScrollLRChar (alphalist->scrollField, character);
357
void setCDKAlphalistVerticalChar (CDKALPHALIST *alphalist, chtype character)
359
setCDKEntryVerticalChar (alphalist->entryField, character);
360
setCDKScrollVerticalChar (alphalist->scrollField, character);
362
void setCDKAlphalistHorizontalChar (CDKALPHALIST *alphalist, chtype character)
364
setCDKEntryHorizontalChar (alphalist->entryField, character);
365
setCDKScrollHorizontalChar (alphalist->scrollField, character);
367
void setCDKAlphalistBoxAttribute (CDKALPHALIST *alphalist, chtype character)
369
setCDKEntryBoxAttribute (alphalist->entryField, character);
370
setCDKScrollBoxAttribute (alphalist->scrollField, character);
374
* This sets the background color of the widget.
376
void setCDKAlphalistBackgroundColor (CDKALPHALIST *alphalist, char *color)
380
setCDKEntryBackgroundColor (alphalist->entryField, color);
381
setCDKScrollBackgroundColor (alphalist->scrollField, color);
386
* This destroys the file selector.
388
void destroyCDKAlphalist (CDKALPHALIST *alphalist)
390
/* Erase the file selector. */
391
eraseCDKAlphalist (alphalist);
393
freeCharList (alphalist->list, alphalist->listSize);
395
/* Destroy the other Cdk objects. */
396
destroyCDKEntry (alphalist->entryField);
397
destroyCDKScroll (alphalist->scrollField);
399
/* Free up the window pointers. */
400
deleteCursesWindow (alphalist->win);
402
/* Unregister the object. */
403
unregisterCDKObject (vALPHALIST, alphalist);
405
/* Free up the object pointer. */
410
* This function sets the pre-process function.
412
void setCDKAlphalistPreProcess (CDKALPHALIST *alphalist, PROCESSFN callback, void *data)
414
setCDKEntryPreProcess (alphalist->entryField, callback, data);
418
* This function sets the post-process function.
420
void setCDKAlphalistPostProcess (CDKALPHALIST *alphalist, PROCESSFN callback, void *data)
422
setCDKEntryPostProcess (alphalist->entryField, callback, data);
426
* Start of callback functions.
428
static void adjustAlphalistCB (EObjectType objectType GCC_UNUSED, void *object GCC_UNUSED, void *clientData, chtype key)
430
CDKALPHALIST *alphalist = (CDKALPHALIST *)clientData;
431
CDKSCROLL *scrollp = (CDKSCROLL*)alphalist->scrollField;
432
CDKENTRY *entry = (CDKENTRY*)alphalist->entryField;
435
/* Adjust the scrolling list. */
436
injectCDKScroll (alphalist->scrollField, (chtype)key);
438
/* Set the value in the entry field. */
439
current = chtype2Char (scrollp->item[scrollp->currentItem]);
440
setCDKEntryValue (entry, current);
441
drawCDKEntry (entry, ObjOf(entry)->box);
446
* This is the heart-beat of the widget.
448
static int preProcessEntryField (EObjectType cdktype GCC_UNUSED, void *object GCC_UNUSED, void *clientData, chtype input)
450
CDKALPHALIST *alphalist = (CDKALPHALIST *)clientData;
451
CDKSCROLL *scrollp = alphalist->scrollField;
452
CDKENTRY *entry = alphalist->entryField;
457
infoLen = (int)strlen (entry->info);
459
/* Check the input. */
460
if (isalnum (input) || ispunct (input) ||
461
input == DELETE || input == CONTROL('H') || input == KEY_DC)
463
/* Copy the information from the entry field. */
464
strcpy (pattern, entry->info);
466
/* Truncate/Concatenate to the information in the entry field. */
467
if (input == DELETE || input == CONTROL('H') || input == KEY_DC)
469
/* If we had only 1 item in the list; jump back to the top. */
472
setCDKScrollPosition (scrollp, 0);
473
drawCDKScroll (scrollp, ObjOf(scrollp)->box);
477
pattern[infoLen - 1] = '\0';
481
pattern[infoLen] = (char)input;
482
pattern[infoLen + 1] = '\0';
485
/* Look for the pattern in the list. */
486
Index = searchList (alphalist->list, alphalist->listSize, pattern);
489
setCDKScrollPosition (scrollp, Index);
490
drawCDKScroll (scrollp, ObjOf(scrollp)->box);
502
* This tries to complete the word in the entry field.
504
static void completeWordCB (EObjectType objectType GCC_UNUSED, void *object GCC_UNUSED, void *clientData, chtype key GCC_UNUSED)
506
CDKALPHALIST *alphalist = (CDKALPHALIST *)clientData;
507
CDKENTRY *entry = (CDKENTRY*)alphalist->entryField;
508
CDKSCROLL *scrollp = 0;
509
int currentIndex = 0;
518
char *altWords[MAX_LINES];
520
if (entry->info == 0)
525
wordLength = (int)strlen (entry->info);
527
/* If the word length is equal to zero, just leave. */
534
/* Look for a unique word match. */
535
Index = searchList (alphalist->list, alphalist->listSize, entry->info);
537
/* If the index is less than zero, return we didn't find a match. */
544
/* Did we find the last word in the list? */
545
if (Index == alphalist->listSize-1)
547
setCDKEntryValue (entry, alphalist->list[Index]);
548
drawCDKEntry (entry, ObjOf(entry)->box);
552
/* Ok, we found a match, is the next item similar? */
553
ret = strncmp (alphalist->list[Index + 1], entry->info, wordLength);
556
currentIndex = Index;
562
/* Start looking for alternate words. */
563
while ((currentIndex < alphalist->listSize)
564
&& (strncmp (alphalist->list[currentIndex], entry->info, wordLength) == 0))
566
altWords[altCount] = copyChar (alphalist->list[currentIndex]);
571
/* Determine the height of the scrolling list. */
572
height = MINIMUM (altCount + 3, 11);
574
/* Create a scrolling list of close matches. */
575
scrollp = newCDKScroll (entry->obj.screen, CENTER, CENTER, RIGHT, height, -30,
576
"<C></B/5>Possible Matches.",
577
altWords, altCount, NUMBERS,
578
A_REVERSE, TRUE, FALSE);
580
/* Allow them to select a close match. */
581
match = activateCDKScroll (scrollp, 0);
582
selected = scrollp->currentItem;
584
/* Check how they exited the list. */
585
if (scrollp->exitType == vESCAPE_HIT)
587
/* Beep at the user. */
590
/* Destroy the scrolling list. */
591
destroyCDKScroll (scrollp);
595
/* Destroy the scrolling list. */
596
destroyCDKScroll (scrollp);
598
/* Set the entry field to the selected value. */
599
setCDKEntryValue (entry, altWords[match]);
601
/* Move the highlight bar down to the selected value. */
602
for (x=0; x < selected; x++)
604
injectCDKScroll (alphalist->scrollField, KEY_DOWN);
609
freeCharList (altWords, altCount);
611
/* Redraw the alphalist. */
612
drawCDKAlphalist (alphalist, ObjOf(alphalist)->box);
616
/* Set the entry field with the found item. */
617
setCDKEntryValue (entry, alphalist->list[Index]);
618
drawCDKEntry (entry, ObjOf(entry)->box);