Annotation of othersrc/dist/cdk/swindow.c, revision 1.3.8.1
1.1 garbled 1: #include <cdk.h>
2:
3: /*
1.3.8.1 ! tron 4: * $Author$
! 5: * $Date$
! 6: * $Revision$
1.1 garbled 7: */
8:
9: /*
10: * Declare file local prototypes.
11: */
12: static void drawCDKSwindowList (CDKSWINDOW *swindow);
13:
14: DeclareCDKObjects(my_funcs,Swindow);
15:
16: /*
17: * This function creates a scrolling window widget.
18: */
19: CDKSWINDOW *newCDKSwindow (CDKSCREEN *cdkscreen, int xplace, int yplace, int height, int width, char *title, int saveLines, boolean Box, boolean shadow)
20: {
21: /* Declare local variables. */
22: CDKSWINDOW *swindow = newCDKObject(CDKSWINDOW, &my_funcs);
23: chtype *holder = 0;
24: int parentWidth = getmaxx(cdkscreen->window);
25: int parentHeight = getmaxy(cdkscreen->window);
26: int boxWidth = width;
27: int boxHeight = height;
28: int maxWidth = INT_MIN;
29: int xpos = xplace;
30: int ypos = yplace;
31: char **temp = 0;
32: int x, len, junk2;
33:
34: /*
35: * If the height is a negative value, the height will
36: * be ROWS-height, otherwise, the height will be the
37: * given height.
38: */
39: boxHeight = setWidgetDimension (parentHeight, height, 0);
40:
41: /*
42: * If the width is a negative value, the width will
43: * be COLS-width, otherwise, the width will be the
44: * given width.
45: */
46: boxWidth = setWidgetDimension (parentWidth, width, 0);
47:
48: /* Translate the char * items to chtype * */
49: if (title != 0)
50: {
51: temp = CDKsplitString (title, '\n');
52: swindow->titleLines = CDKcountStrings (temp);
53:
54: /* We need to determine the widest title line. */
55: for (x=0; x < swindow->titleLines; x++)
56: {
57: holder = char2Chtype (temp[x], &len, &junk2);
58: maxWidth = MAXIMUM (maxWidth, len);
59: freeChtype (holder);
60: }
61: boxWidth = MAXIMUM (boxWidth, maxWidth + 2);
62:
63: /* For each line in the title, convert from char * to chtype * */
64: for (x=0; x < swindow->titleLines; x++)
65: {
66: swindow->title[x] = char2Chtype (temp[x],
67: &swindow->titleLen[x],
68: &swindow->titlePos[x]);
69: swindow->titlePos[x] = justifyString (boxWidth - 2,
70: swindow->titleLen[x],
71: swindow->titlePos[x]);
72: }
73:
74: CDKfreeStrings(temp);
75: }
76: else
77: {
78: /* No title? Set the required variables. */
79: swindow->titleLines = 0;
80: }
81:
82: swindow->fieldWidth = boxWidth - 2;
83: swindow->viewSize = boxHeight - 2 - swindow->titleLines;
84:
85: /*
86: * Make sure we didn't extend beyond the dimensions of the window.
87: */
88: boxWidth = MINIMUM (boxWidth, parentWidth);
89: boxHeight = MINIMUM (boxHeight, parentHeight);
90:
91: /* Rejustify the x and y positions if we need to. */
92: alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight);
93:
94: /* Make the scrolling window */
95: swindow->win = newwin (boxHeight + !!shadow, boxWidth + !!shadow, ypos, xpos);
96:
97: /* Is the window null?? */
98: if (swindow->win == 0)
99: {
100: /* Clean up. */
101: for (x=0; x < swindow->titleLines; x++)
102: {
103: freeChtype (swindow->title[x]);
104: }
105: free(swindow);
106:
107: /* Return a null pointer. */
108: return (0);
109: }
110: keypad (swindow->win, TRUE);
111: leaveok (swindow->win, TRUE);
112:
113: if (swindow->titleLines > 0)
114: {
115: /* Make the title window. */
116: swindow->titleWin = subwin (swindow->win,
117: swindow->titleLines, boxWidth - 2,
118: ypos + 1, xpos + 1);
119: }
120:
121: /* Create the viewing window. */
122: swindow->fieldWin = subwin (swindow->win,
123: swindow->viewSize, swindow->fieldWidth,
124: ypos + swindow->titleLines + 1,
125: xpos + 1);
126:
127: /* Set the rest of the variables */
128: ScreenOf(swindow) = cdkscreen;
129: swindow->parent = cdkscreen->window;
130: swindow->boxHeight = boxHeight;
131: swindow->boxWidth = boxWidth;
132: swindow->currentTop = 0;
133: swindow->maxTopLine = 0;
134: swindow->leftChar = 0;
135: swindow->maxLeftChar = 0;
136: swindow->itemCount = 0;
137: swindow->saveLines = saveLines;
138: swindow->exitType = vNEVER_ACTIVATED;
139: ObjOf(swindow)->box = Box;
140: swindow->shadow = shadow;
141: swindow->preProcessFunction = 0;
142: swindow->preProcessData = 0;
143: swindow->postProcessFunction = 0;
144: swindow->postProcessData = 0;
145: swindow->ULChar = ACS_ULCORNER;
146: swindow->URChar = ACS_URCORNER;
147: swindow->LLChar = ACS_LLCORNER;
148: swindow->LRChar = ACS_LRCORNER;
149: swindow->HChar = ACS_HLINE;
150: swindow->VChar = ACS_VLINE;
151: swindow->BoxAttrib = A_NORMAL;
152:
153: /* For each line in the window, set the value to null. */
154: for (x=0; x < MAX_LINES; x++)
155: {
156: swindow->info[x] = 0;
157: }
158:
159: /* Clean the key bindings. */
160: cleanCDKObjectBindings (vSWINDOW, swindow);
161:
162: /* Register this baby. */
163: registerCDKObject (cdkscreen, vSWINDOW, swindow);
164:
165: /* Return the scrolling window */
166: return (swindow);
167: }
168:
169: /*
170: * This sets the lines and the box attribute of the scrolling window.
171: */
172: void setCDKSwindow (CDKSWINDOW *swindow, char **info, int lines, boolean Box)
173: {
174: setCDKSwindowContents (swindow, info, lines);
175: setCDKSwindowBox (swindow, Box);
176: }
177:
178: /*
179: * This sets all the lines inside the scrolling window.
180: */
181: void setCDKSwindowContents (CDKSWINDOW *swindow, char **info, int lines)
182: {
183: /* Declare local variables. */
184: int widestItem, x;
185:
1.3.8.1 ! tron 186: widestItem = 0;
! 187:
1.1 garbled 188: /* First lets clean all the lines in the window. */
189: cleanCDKSwindow(swindow);
190:
191: /* Now lets set all the lines inside the window. */
192: for (x=0; x < lines; x++)
193: {
194: swindow->info[x] = char2Chtype (info[x],
195: &swindow->infoLen[x],
196: &swindow->infoPos[x]);
197: swindow->infoPos[x] = justifyString (swindow->fieldWidth,
198: swindow->infoLen[x],
199: swindow->infoPos[x]);
200: widestItem = MAXIMUM (widestItem, swindow->infoLen[x]);
201: }
202:
203: /* Set some of the more important members of the scrolling window. */
204: swindow->itemCount = lines;
205: swindow->maxTopLine = MAXIMUM (0, lines - swindow->viewSize);
206: swindow->maxLeftChar = MAXIMUM (0, widestItem - swindow->fieldWidth);
207: swindow->currentTop = 0;
208: swindow->leftChar = 0;
209: }
210: chtype **getCDKSwindowContents (CDKSWINDOW *swindow, int *size)
211: {
212: (*size) = swindow->itemCount;
213: return swindow->info;
214: }
215:
216: /*
217: * This sets the box attribute for the widget.
218: */
219: void setCDKSwindowBox (CDKSWINDOW *swindow, boolean Box)
220: {
221: ObjOf(swindow)->box = Box;
222: }
223: boolean getCDKSwindowBox (CDKSWINDOW *swindow)
224: {
225: return ObjOf(swindow)->box;
226: }
227:
228: /*
229: * This adds a line to the scrolling window.
230: */
231: void addCDKSwindow (CDKSWINDOW *swindow, char *info, int insertPos)
232: {
233: /* Declare variables. */
234: int x = 0;
235:
236: /*
237: * If we are at the maximum number of save lines. Erase
238: * the first position and bump everything up one spot.
239: */
240: if (swindow->itemCount == swindow->saveLines)
241: {
242: /* Free up the memory. */
243: freeChtype (swindow->info[0]);
244:
245: /* Bump everything up one spot. */
246: for (x=0; x < swindow->itemCount; x++)
247: {
248: swindow->info[x] = swindow->info[x + 1];
249: swindow->infoPos[x] = swindow->infoPos[x + 1];
250: swindow->infoLen[x] = swindow->infoLen[x + 1];
251: }
252:
253: /* Clean out the last position. */
254: swindow->info[x] = 0;
255: swindow->infoLen[x] = 0;
256: swindow->infoPos[x] = 0;
257: swindow->itemCount--;
258: }
259:
260: /* Determine where the line is being added. */
261: if (insertPos == TOP)
262: {
263: /* We need to 'bump' everything down one line... */
264: for (x=swindow->itemCount; x > 0; x--)
265: {
266: /* Copy in the new row. */
267: swindow->info[x] = swindow->info[x - 1];
268: swindow->infoPos[x] = swindow->infoPos[x - 1];
269: swindow->infoLen[x] = swindow->infoLen[x - 1];
270: }
271:
272: /* Add it into the scrolling window. */
273: swindow->info[0] = char2Chtype (info, &swindow->infoLen[0], &swindow->infoPos[0]);
274: swindow->infoPos[0] = justifyString (swindow->fieldWidth, swindow->infoLen[0], swindow->infoPos[0]);
275:
276: /* Set some variables. */
277: swindow->maxLeftChar = MAXIMUM (swindow->maxLeftChar, swindow->infoLen[0] - swindow->fieldWidth);
278: swindow->itemCount++;
279: swindow->maxTopLine = MAXIMUM (0, swindow->itemCount - swindow->viewSize);
280: swindow->currentTop = 0;
281: }
282: else
283: {
284: /* Add to the bottom. */
285: swindow->info[swindow->itemCount] = char2Chtype (info, &swindow->infoLen[swindow->itemCount], &swindow->infoPos[swindow->itemCount]);
286: swindow->infoPos[swindow->itemCount] = justifyString (swindow->fieldWidth, swindow->infoLen[swindow->itemCount], swindow->infoPos[swindow->itemCount]);
287:
288: /* Set some variables. */
289: swindow->maxLeftChar = MAXIMUM (swindow->maxLeftChar, swindow->infoLen[swindow->itemCount] - swindow->fieldWidth);
290: swindow->itemCount++;
291: swindow->maxTopLine = MAXIMUM (0, swindow->itemCount - swindow->viewSize);
292: swindow->currentTop = swindow->maxTopLine;
293: }
294:
295: /* Draw in the list. */
296: drawCDKSwindowList (swindow);
297: }
298:
299: /*
300: * This jumps to a given line.
301: */
302: void jumpToLineCDKSwindow (CDKSWINDOW *swindow, int line)
303: {
304: /*
305: * Make sure the line is in bounds.
306: */
307: if (line == BOTTOM || line >= swindow->itemCount)
308: {
309: /* We are moving to the last page. */
310: swindow->currentTop = swindow->maxTopLine;
311: }
312: else if (line == TOP || line <= 0)
313: {
314: /* We are moving to the top of the page. */
315: swindow->currentTop = 0;
316: }
317: else
318: {
319: /* We are moving in the middle somewhere. */
320: swindow->currentTop = MINIMUM (line, swindow->maxTopLine);
321: }
322:
323: /* Redraw the window. */
324: drawCDKSwindow (swindow, ObjOf(swindow)->box);
325: }
326:
327: /*
328: * This removes all the lines inside the scrolling window.
329: */
330: void cleanCDKSwindow (CDKSWINDOW *swindow)
331: {
332: /* Declare local variables. */
333: int x;
334:
335: /* Clean up the memory used ... */
336: for (x=0; x < swindow->itemCount; x++)
337: {
338: freeChtype (swindow->info[x]);
339: }
340:
341: /* Reset some variables. */
342: swindow->maxLeftChar = 0;
343: swindow->itemCount = 0;
344: swindow->maxTopLine = 0;
345: swindow->currentTop = 0;
346:
347: /* Redraw the window. */
348: drawCDKSwindow (swindow, ObjOf(swindow)->box);
349: }
350:
351: /*
352: * This trims lines from the scrolling window.
353: */
354: void trimCDKSwindow (CDKSWINDOW *swindow, int begin, int end)
355: {
356: int start, finish, x;
357:
358: /* Check the value of begin. */
359: if (begin < 0)
360: {
361: start = 0;
362: }
363: else if (begin >= swindow->itemCount)
364: {
365: start = swindow->itemCount-1;
366: }
367: else
368: {
369: start = begin;
370: }
371:
372: /* Check the value of end. */
373: if (end < 0)
374: {
375: finish = 0;
376: }
377: else if (end >= swindow->itemCount)
378: {
379: finish = swindow->itemCount-1;
380: }
381: else
382: {
383: finish = end;
384: }
385:
386: /* Make sure the start is lower than the end. */
387: if (start > finish)
388: {
389: return;
390: }
391:
392: /* Start nuking elements from the window. */
393: for (x=start; x <=finish; x++)
394: {
395: freeChtype (swindow->info[x]);
396:
397: swindow->info[x] = copyChtype (swindow->info[x + 1]);
398: swindow->infoPos[x] = swindow->infoPos[x + 1];
399: swindow->infoLen[x] = swindow->infoLen[x + 1];
400: }
401:
402: /* Adjust the item count correctly. */
403: swindow->itemCount = swindow->itemCount - (end - begin + 1);
404:
405: /* Redraw the window. */
406: drawCDKSwindow (swindow, ObjOf(swindow)->box);
407: }
408:
409: /*
410: * This allows the user to play inside the scolling window.
411: */
412: void activateCDKSwindow (CDKSWINDOW *swindow, chtype *actions)
413: {
414: /* Draw the scrolling list */
415: drawCDKSwindow (swindow, ObjOf(swindow)->box);
416:
417: /* Check if actions is null. */
418: if (actions == 0)
419: {
420: /* Declare some local variables. */
421: chtype input;
422: int ret;
423:
424: for (;;)
425: {
426: /* Get the input. */
427: wrefresh (swindow->win);
428: input = wgetch (swindow->win);
429:
430: /* Inject the character into the widget. */
431: ret = injectCDKSwindow (swindow, input);
432: if (swindow->exitType != vEARLY_EXIT)
433: {
434: return;
435: }
436: }
437: }
438: else
439: {
440: /* Declare some local variables. */
441: int length = chlen (actions);
442: int x, ret;
443:
444: /* Inject each character one at a time. */
445: for (x=0; x < length; x++)
446: {
447: ret = injectCDKSwindow (swindow, actions[x]);
448: if (swindow->exitType != vEARLY_EXIT)
449: {
450: return;
451: }
452: }
453: }
454:
455: /* Set the exit type and return. */
456: swindow->exitType = vEARLY_EXIT;
457: return;
458: }
459:
460: /*
461: * This injects a single character into the widget.
462: */
463: int injectCDKSwindow (CDKSWINDOW *swindow, chtype input)
464: {
465: /* Declare local variables. */
466: int ppReturn = 1;
467:
1.3 garbled 468: /* Set the exit type */
469: swindow->exitType = vEARLY_EXIT;
470:
1.1 garbled 471: /* Draw the window.... */
472: drawCDKSwindow (swindow, ObjOf(swindow)->box);
473:
474: /* Check if there is a pre-process function to be called. */
475: if (swindow->preProcessFunction != 0)
476: {
477: /* Call the pre-process function. */
478: ppReturn = ((PROCESSFN)(swindow->preProcessFunction)) (vSWINDOW, swindow, swindow->preProcessData, input);
479: }
480:
481: /* Should we continue? */
482: if (ppReturn != 0)
483: {
484: /* Check for a key binding. */
485: if (checkCDKObjectBind (vSWINDOW, swindow, input) != 0)
486: {
487: return -1;
488: }
489: else
490: {
491: switch (input)
492: {
493: case KEY_UP :
494: if (swindow->currentTop > 0)
495: {
496: swindow->currentTop--;
497: }
498: else
499: {
500: Beep();
501: }
502: break;
503:
504: case KEY_DOWN :
505: if (swindow->currentTop < swindow->maxTopLine)
506: {
507: swindow->currentTop++;
508: }
509: else
510: {
511: Beep();
512: }
513: break;
514:
515: case KEY_RIGHT :
516: if (swindow->leftChar < swindow->maxLeftChar)
517: {
518: swindow->leftChar++;
519: }
520: else
521: {
522: Beep();
523: }
524: break;
525:
526: case KEY_LEFT :
527: if (swindow->leftChar > 0)
528: {
529: swindow->leftChar--;
530: }
531: else
532: {
533: Beep();
534: }
535: break;
536:
537: case KEY_PPAGE :
538: case CONTROL('B') :
539: case 'b' :
540: case 'B' :
541: if (swindow->currentTop > 0)
542: {
543: if (swindow->currentTop - (swindow->viewSize - 1) >= 0)
544: {
545: swindow->currentTop -= (swindow->viewSize - 1);
546: }
547: else
548: {
549: swindow->currentTop = 0;
550: }
551: }
552: else
553: {
554: Beep();
555: }
556: break;
557:
558: case KEY_NPAGE :
559: case CONTROL('F') :
560: case ' ' :
561: case 'f' :
562: case 'F' :
563: if (swindow->currentTop < swindow->maxTopLine)
564: {
565: if (swindow->currentTop + (swindow->viewSize + 1) <= swindow->maxTopLine)
566: {
567: swindow->currentTop += (swindow->viewSize - 1);
568: }
569: else
570: {
571: swindow->currentTop = swindow->maxTopLine;
572: }
573: }
574: else
575: {
576: Beep();
577: }
578: break;
579:
580: case 'g' :
581: case '1' :
582: case KEY_HOME :
583: swindow->currentTop = 0;
584: break;
585:
586: case 'G' :
587: case KEY_END :
588: swindow->currentTop = swindow->maxTopLine;
589: break;
590:
591: case '|' :
592: swindow->leftChar = 0;
593: break;
594:
595: case '$' :
596: swindow->leftChar = swindow->maxLeftChar;
597: break;
598:
599: case 'l' :
600: case 'L' :
601: loadCDKSwindowInformation (swindow);
602: break;
603:
604: case 's' :
605: case 'S' :
606: saveCDKSwindowInformation (swindow);
607: break;
608:
609: case KEY_ESC :
610: swindow->exitType = vESCAPE_HIT;
611: return -1;
612:
613: case KEY_RETURN :
614: case KEY_TAB :
615: case KEY_ENTER :
1.2 garbled 616: case KEY_CR :
1.1 garbled 617: swindow->exitType = vNORMAL;
618: return 1;
619:
620: case CDK_REFRESH :
621: eraseCDKScreen (ScreenOf(swindow));
622: refreshCDKScreen (ScreenOf(swindow));
623: break;
624:
625: default :
626: Beep();
627: break;
628: }
629: }
630:
631: /* Should we call a post-process? */
632: if (swindow->postProcessFunction != 0)
633: {
634: ((PROCESSFN)(swindow->postProcessFunction)) (vSWINDOW, swindow, swindow->postProcessData, input);
635: }
636: }
637:
638: /* Redraw the list */
639: drawCDKSwindowList (swindow);
640:
641: /* Set the exit type and return. */
642: swindow->exitType = vEARLY_EXIT;
643: return -1;
644: }
645:
646: /*
647: * This moves the swindow field to the given location.
648: */
649: static void _moveCDKSwindow (CDKOBJS *object, int xplace, int yplace, boolean relative, boolean refresh_flag)
650: {
651: CDKSWINDOW *swindow = (CDKSWINDOW *)object;
652:
653: /*
654: * If this is a relative move, then we will adjust where we want
655: * to move to.
656: */
657: if (relative)
658: {
659: xplace += getbegx(swindow->win);
660: yplace += getbegy(swindow->win);
661: }
662:
663: /* Adjust the window if we need to. */
664: alignxy (WindowOf(swindow), &xplace, &yplace, swindow->boxWidth, swindow->boxHeight);
665:
666: /* Move the window to the new location. */
667: moveCursesWindow(swindow->win, xplace, yplace);
668:
669: /* Redraw the window, if they asked for it. */
670: if (refresh_flag)
671: {
672: drawCDKSwindow (swindow, ObjOf(swindow)->box);
673: }
674: }
675:
676: /*
677: * This function draws the swindow window widget.
678: */
679: static void _drawCDKSwindow (CDKOBJS *object, boolean Box)
680: {
681: CDKSWINDOW *swindow = (CDKSWINDOW *)object;
682: int x;
683:
684: /* Box the widget if needed */
685: if (Box)
686: {
687: attrbox (swindow->win,
688: swindow->ULChar, swindow->URChar,
689: swindow->LLChar, swindow->LRChar,
690: swindow->HChar, swindow->VChar,
691: swindow->BoxAttrib,
692: swindow->shadow);
693: }
694:
695: if (swindow->titleLines > 0)
696: {
697: /* Draw in the title if there is one */
698: for (x=0; x < swindow->titleLines; x++)
699: {
700: writeChtype (swindow->titleWin,
701: swindow->titlePos[x], x,
702: swindow->title[x],
703: HORIZONTAL, 0,
704: swindow->titleLen[x]);
705: }
706: wnoutrefresh (swindow->titleWin);
707: }
708:
709: /* Draw in the list. */
710: drawCDKSwindowList (swindow);
711: }
712:
713: /*
714: * This draws in the contents of the scrolling window.
715: */
716: static void drawCDKSwindowList (CDKSWINDOW *swindow)
717: {
718: /* Declare local variables. */
719: int screenPos, x;
720:
721: werase (swindow->fieldWin);
722:
723: /* Start drawing in each line. */
724: for (x=0; x < swindow->viewSize; x++)
725: {
726: if (x + swindow->currentTop >= swindow->itemCount)
727: {
728: break;
729: }
730:
731: screenPos = swindow->infoPos[x + swindow->currentTop] - swindow->leftChar;
732:
733: /* Write in the correct line. */
734: if (screenPos >= 0)
735: {
736: writeChtype (swindow->fieldWin,
737: screenPos, x,
738: swindow->info[x + swindow->currentTop],
739: HORIZONTAL, 0,
740: swindow->infoLen[x + swindow->currentTop]);
741: }
742: else
743: {
744: writeChtype (swindow->fieldWin,
745: 0, x,
746: swindow->info[x + swindow->currentTop],
747: HORIZONTAL, -screenPos,
748: swindow->infoLen[x + swindow->currentTop]);
749: }
750: }
751:
752: /* Refresh the window. */
753: wnoutrefresh (swindow->fieldWin);
754: wnoutrefresh (swindow->win);
755: }
756:
757: /*
758: * These functions set the drawing characters of the widget.
759: */
760: void setCDKSwindowULChar (CDKSWINDOW *swindow, chtype character)
761: {
762: swindow->ULChar = character;
763: }
764: void setCDKSwindowURChar (CDKSWINDOW *swindow, chtype character)
765: {
766: swindow->URChar = character;
767: }
768: void setCDKSwindowLLChar (CDKSWINDOW *swindow, chtype character)
769: {
770: swindow->LLChar = character;
771: }
772: void setCDKSwindowLRChar (CDKSWINDOW *swindow, chtype character)
773: {
774: swindow->LRChar = character;
775: }
776: void setCDKSwindowVerticalChar (CDKSWINDOW *swindow, chtype character)
777: {
778: swindow->VChar = character;
779: }
780: void setCDKSwindowHorizontalChar (CDKSWINDOW *swindow, chtype character)
781: {
782: swindow->HChar = character;
783: }
784: void setCDKSwindowBoxAttribute (CDKSWINDOW *swindow, chtype character)
785: {
786: swindow->BoxAttrib = character;
787: }
788:
789: /*
790: * This sets the background color of the widget.
791: */
792: void setCDKSwindowBackgroundColor (CDKSWINDOW *swindow, char *color)
793: {
794: chtype *holder = 0;
795: int junk1, junk2;
796:
797: /* Make sure the color isn't null. */
798: if (color == 0)
799: {
800: return;
801: }
802:
803: /* Convert the value of the environment variable to a chtype. */
804: holder = char2Chtype (color, &junk1, &junk2);
805:
806: /* Set the widgets background color. */
807: wbkgd (swindow->win, holder[0]);
808:
809: /* Clean up. */
810: freeChtype (holder);
811: }
812:
813: /*
814: * This function destroys the scrolling window widget.
815: */
816: void destroyCDKSwindow (CDKSWINDOW *swindow)
817: {
818: /* Declare local variables. */
819: int x;
820:
821: /* Erase the object. */
822: eraseCDKSwindow (swindow);
823:
824: /* Clear out the character pointers. */
825: for (x=0; x <= swindow->itemCount; x++)
826: {
827: freeChtype (swindow->info[x]);
828: }
829: for (x=0; x < swindow->titleLines; x++)
830: {
831: freeChtype (swindow->title[x]);
832: }
833:
834: /* Delete the windows. */
835: deleteCursesWindow (swindow->win);
836:
837: /* Unregister this object. */
838: unregisterCDKObject (vSWINDOW, swindow);
839:
840: /* Finish cleaning up. */
841: free (swindow);
842: }
843:
844: /*
845: * This function erases the scrolling window widget.
846: */
847: static void _eraseCDKSwindow (CDKOBJS *object)
848: {
849: CDKSWINDOW *swindow = (CDKSWINDOW *)object;
850:
851: eraseCursesWindow (swindow->win);
852: }
853:
854: /*
855: * This exec's a command and redirects the output to the scrolling window.
856: */
857: int execCDKSwindow (CDKSWINDOW *swindow, char *command, int insertPos)
858: {
859: /* Declare local variables. */
860: FILE *ps;
861: char temp[BUFSIZ];
862: int count = 0;
863: size_t len;
864:
865: /* Try to open the command. */
866: if ((ps = popen (command, "r")) == 0)
867: {
868: return -1;
869: }
870:
871: /* Start reading. */
872: while (fgets (temp, sizeof(temp), ps) != 0)
873: {
874: len = strlen (temp);
875: if (temp[len-1] == '\n')
876: {
877: temp[len-1] = '\0';
878: }
879: /* Add the line to the scrolling window. */
880: addCDKSwindow (swindow, temp, insertPos);
881: count++;
882: }
883:
884: /* Close the pipe. */
885: pclose (ps);
886: return count;
887: }
888:
889: /*
890: * This function allows the user to dump the information from the
891: * scrollong window to a file.
892: */
893: void saveCDKSwindowInformation (CDKSWINDOW *swindow)
894: {
895: /* Declare local variables. */
896: CDKENTRY *entry = 0;
897: char *filename = 0;
898: char temp[256], *mesg[10];
899: int linesSaved;
900:
901: /* Create the entry field to get the filename. */
902: entry = newCDKEntry (ScreenOf(swindow), CENTER, CENTER,
903: "<C></B/5>Enter the filename of the save file.",
904: "Filename: ",
905: A_NORMAL, '_', vMIXED,
906: 20, 1, 256,
907: TRUE, FALSE);
908:
909: /* Get the filename. */
910: filename = activateCDKEntry (entry, 0);
911:
912: /* Did they hit escape? */
913: if (entry->exitType == vESCAPE_HIT)
914: {
915: /* Popup a message. */
916: mesg[0] = "<C></B/5>Save Canceled.";
917: mesg[1] = "<C>Escape hit. Scrolling window information not saved.";
918: mesg[2] = " ";
919: mesg[3] = "<C>Press any key to continue.";
920: popupLabel (ScreenOf(swindow), mesg, 4);
921:
922: /* Clean up and exit. */
923: destroyCDKEntry (entry);
924: return;
925: }
926:
927: /* Write the contents of the scrolling window to the file. */
928: linesSaved = dumpCDKSwindow (swindow, filename);
929:
930: /* Was the save successful? */
931: if (linesSaved == -1)
932: {
933: /* Nope, tell 'em. */
934: mesg[0] = copyChar ("<C></B/16>Error");
935: mesg[1] = copyChar ("<C>Could not save to the file.");
936: sprintf (temp, "<C>(%s)", filename);
937: mesg[2] = copyChar (temp);
938: mesg[3] = copyChar (" ");
939: mesg[4] = copyChar ("<C>Press any key to continue.");
940: popupLabel (ScreenOf(swindow), mesg, 5);
941: freeCharList (mesg, 5);
942: }
943: else
944: {
945: /* Yep, let them know how many lines were saved. */
946: mesg[0] = copyChar ("<C></B/5>Save Successful");
947: sprintf (temp, "<C>There were %d lines saved to the file", linesSaved);
948: mesg[1] = copyChar (temp);
949: sprintf (temp, "<C>(%s)", filename);
950: mesg[2] = copyChar (temp);
951: mesg[3] = copyChar (" ");
952: mesg[4] = copyChar ("<C>Press any key to continue.");
953: popupLabel (ScreenOf(swindow), mesg, 5);
954: freeCharList (mesg, 5);
955: }
956:
957: /* Clean up and exit. */
958: destroyCDKEntry (entry);
959: eraseCDKScreen (ScreenOf(swindow));
960: drawCDKScreen (ScreenOf(swindow));
961: }
962:
963: /*
964: * This function allows the user to load new informatrion into the scrolling
965: * window.
966: */
967: void loadCDKSwindowInformation (CDKSWINDOW *swindow)
968: {
969: /* Declare local variables. */
970: CDKFSELECT *fselect = 0;
971: CDKDIALOG *dialog = 0;
972: char *filename = 0;
973: char temp[256], *mesg[15], *button[5], *fileInfo[MAX_LINES];
974: int lines, answer;
975:
976: /* Create the file selector to choose the file. */
977: fselect = newCDKFselect (ScreenOf(swindow), CENTER, CENTER, 20, 55,
978: "<C>Load Which File",
979: "Filename: ",
980: A_NORMAL, '_',
981: A_REVERSE,
982: "</5>", "</48>", "</N>", "</N>",
983: TRUE, FALSE);
984:
985: /* Get the filename to load. */
986: filename = activateCDKFselect (fselect, 0);
987:
988: /* Make sure they selected a file. */
989: if (fselect->exitType == vESCAPE_HIT)
990: {
991: /* Popup a message. */
992: mesg[0] = "<C></B/5>Load Canceled.";
993: mesg[1] = " ";
994: mesg[2] = "<C>Press any key to continue.";
995: popupLabel (ScreenOf(swindow), mesg, 3);
996:
997: /* Clean up and exit. */
998: destroyCDKFselect (fselect);
999: return;
1000: }
1001:
1002: /* Copy the filename and destroy the file selector. */
1003: filename = copyChar (fselect->pathname);
1004: destroyCDKFselect (fselect);
1005:
1006: /*
1007: * Maye we should check before nuking all the information
1008: * in the scrolling window...
1009: */
1010: if (swindow->itemCount > 0)
1011: {
1012: /* Create the dialog message. */
1013: mesg[0] = "<C></B/5>Save Information First";
1014: mesg[1] = "<C>There is information in the scrolling window.";
1015: mesg[2] = "<C>Do you want to save it to a file first?";
1016: button[0] = "(Yes)";
1017: button[1] = "(No)";
1018:
1019: /* Create the dialog widget. */
1020: dialog = newCDKDialog (ScreenOf(swindow), CENTER, CENTER,
1021: mesg, 2, button, 2,
1022: COLOR_PAIR(2)|A_REVERSE,
1023: TRUE, TRUE, FALSE);
1024:
1025: /* Activate the widget. */
1026: answer = activateCDKDialog (dialog, 0);
1027: destroyCDKDialog (dialog);
1028:
1029: /* Check the answer. */
1030: if (answer == -1 || answer == 0)
1031: {
1032: /* Save the information. */
1033: saveCDKSwindowInformation (swindow);
1034: }
1035: }
1036:
1037: /* Open the file and read it in. */
1038: lines = readFile (filename, fileInfo, MAX_LINES);
1039: if (lines == -1)
1040: {
1041: /* The file read didn't work. */
1042: mesg[0] = copyChar ("<C></B/16>Error");
1043: mesg[1] = copyChar ("<C>Could not read the file");
1044: sprintf (temp, "<C>(%s)", filename);
1045: mesg[2] = copyChar (temp);
1046: mesg[3] = copyChar (" ");
1047: mesg[4] = copyChar ("<C>Press any key to continue.");
1048: popupLabel (ScreenOf(swindow), mesg, 5);
1049: freeCharList (mesg, 5);
1050: freeChar (filename);
1051: return;
1052: }
1053:
1054: /* Clean out the scrolling window. */
1055: cleanCDKSwindow (swindow);
1056:
1057: /* Set the new information in the scrolling window. */
1058: setCDKSwindow (swindow, fileInfo, lines, ObjOf(swindow)->box);
1059:
1060: /* Clean up. */
1061: freeCharList (fileInfo, lines);
1062: freeChar (filename);
1063: }
1064:
1065: /*
1066: * This actually dumps the information from the scrolling window to a
1067: * file.
1068: */
1069: int dumpCDKSwindow (CDKSWINDOW *swindow, char *filename)
1070: {
1071: /* Declare local variables. */
1072: FILE *outputFile = 0;
1073: char *rawLine = 0;
1074: int x;
1075:
1076: /* Try to open the file. */
1077: if ((outputFile = fopen (filename, "w")) == 0)
1078: {
1079: return -1;
1080: }
1081:
1082: /* Start writing out the file. */
1083: for (x=0; x < swindow->itemCount; x++)
1084: {
1085: rawLine = chtype2Char (swindow->info[x]);
1086: fprintf (outputFile, "%s\n", rawLine);
1087: freeChar (rawLine);
1088: }
1089:
1090: /* Close the file and return the number of lines written. */
1091: fclose (outputFile);
1092: return swindow->itemCount;
1093: }
1094:
1095: /*
1096: * This function sets the pre-process function.
1097: */
1098: void setCDKSwindowPreProcess (CDKSWINDOW *swindow, PROCESSFN callback, void *data)
1099: {
1100: swindow->preProcessFunction = callback;
1101: swindow->preProcessData = data;
1102: }
1103:
1104: /*
1105: * This function sets the post-process function.
1106: */
1107: void setCDKSwindowPostProcess (CDKSWINDOW *swindow, PROCESSFN callback, void *data)
1108: {
1109: swindow->postProcessFunction = callback;
1110: swindow->postProcessData = data;
1111: }
CVSweb <webmaster@jp.NetBSD.org>