home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / CSAPE32.ARJ / SOURCE / CSSRC / FNLIST.C < prev    next >
C/C++ Source or Header  |  1990-08-14  |  5KB  |  216 lines

  1. /*
  2.     fnlist.c         10/02/87
  3.  
  4.     % list_funcs
  5.  
  6.     List Functions:
  7.     A field has multiple choices.
  8.     A popup menu displays the choices.
  9.     The Variable is a char *
  10.     and contains the selected choice.
  11.  
  12.     The choices are contained in the field's second data pointer in
  13.     the form "choice 1, choice 2, choice 3"  (commas delimit).
  14.  
  15.     The cursor is turned off.
  16.  
  17.     C-scape 3.2
  18.     Copyright (c) 1987, 1988 by Oakland Group, Inc.
  19.     ALL RIGHTS RESERVED.
  20.  
  21.     Revision History:
  22.     -----------------
  23.      3/31/88 jmd    Removed tinkering of static strings
  24.      4/06/88 jmd     added call to sed_DoSpecial
  25.      4/13/88 jmd     changed MAX_FIELD_LEN to MAX_CHOICE_LEN
  26.      9/15/88 jmd     removed vid_Cursor calls
  27.      9/17/88 jmd     added std_ funcs
  28.     10/09/88 jmd     added SED_ABORT support
  29.     10/14/88 jdc    added var_size element to field_funcs_struct
  30.     11/05/88 jmd    removed menu_Close
  31.     12/14/88 jdc    remove pointer subtraction from list_GetChoice()
  32.     12/20/88 jmd    tests for missing list elements
  33.  
  34.      2/07/89 jmd    added char * cast
  35.      4/10/89 jmd    added oakpriv.h
  36.      6/07/89 jmd    added test for mouse code (later removed)
  37.  
  38.     11/29/89 jmd    added casts for DG
  39.      3/28/90 jmd    ansi-fied
  40.      8/05/89 jmd    added hilite support
  41.      8/13/89 jmd    added test of current record contents
  42. */
  43.  
  44. #include <stdio.h>
  45. #include <string.h>
  46. #include <ctype.h>
  47.  
  48. #include "cscape.h"
  49. #include "fnfunc.h"            /* for field functions */
  50. #include "scancode.h"
  51.  
  52. #include "msys.h"            /* for msys_ParseChoice */
  53.  
  54. #include "oakpriv.h"        /* for memmove() macro */
  55.  
  56. #define    DELIMITER    ','
  57.  
  58. OSTATIC char *list_GetChoice(char *list, int num, char *string);
  59.  
  60. #define MAX_CHOICE_LEN    80            /* maximum length of a choice */
  61.  
  62. OGLOBAL field_funcs_struct list_funcs = {
  63.     stdNoCur_fenter,
  64.     std_fexit,
  65.     list_fkey,
  66.     string_senter,
  67.     string_sexit,
  68.     VAR_STRING
  69. };
  70.  
  71. void list_fkey(sed_type sed)
  72. /*
  73.     Cycle through list of changes when the SPACE bar is pressed.
  74. */
  75. {
  76.     int         scancode;
  77.     menu_type     list_menu;
  78.     sed_type     list_sed;
  79.     int         fieldno, row, col;
  80.     char        *list, *rec, s[MAX_CHOICE_LEN + 1];
  81.     byte         reg, sel;
  82.     int          hichar;
  83.     int         i = 0, fno = -1;
  84.  
  85.     scancode = kb_Read();
  86.  
  87.     if (sed_DoSpecial(sed, scancode))
  88.         return;
  89.     if (special_key(sed, scancode))
  90.         return;
  91.     if (inter_field(sed, scancode))
  92.         return;
  93.     if (inter_page(sed, scancode))
  94.         return;
  95.  
  96.  
  97.     fieldno = sed_GetFieldNo(sed);
  98.  
  99.     if ((list = (char *) sed_GetCurrFieldData(sed, 1)) != NULL) {
  100.  
  101.         /* look at the current record contents */
  102.         rec = sed_GetCurrRecord(sed);
  103.  
  104.         list_menu = menu_Open();
  105.  
  106.         /* set the color of the list */
  107.         sed_GetFieldColors(sed, fieldno, ®, &sel);
  108.  
  109.         while (list_GetChoice(list, i, s) != NULL) {
  110.  
  111.             /* check for hilighted characters */
  112.             hichar = msys_ParseChoice(s, s, MAX_CHOICE_LEN);
  113.  
  114.             /* see if this choice matches the current record contents */
  115.             if (strcmp(rec, s) == 0) {
  116.                 fno = i;
  117.             }
  118.  
  119.             menu_Printf(list_menu, "@p[%d,0] @fh%d[%s] ", i++, NULL, &menu_funcs, hichar, s);
  120.         }
  121.  
  122.         menu_Flush(list_menu);
  123.  
  124.         list_sed = sed_Open(list_menu);
  125.         sed_SetColors(list_sed, sel, sel, reg);
  126.         sed_SetBorder(list_sed, bd_1);
  127.  
  128.         /* set higlghted colors, use bolded version of normal attrs */
  129.         sed_SetHiColors(list_sed, sel | 0x08, reg | 0x08);
  130.  
  131.         /* adjust the position of the list */
  132.         row = sed_GetFieldRow(sed, fieldno) - sed_GetBorderHeight(list_sed)/2;
  133.         row = (row < disp_GetHeight() - sed_GetBorderHeight(list_sed) - 1) ? row :
  134.                 disp_GetHeight() - sed_GetBorderHeight(list_sed) - 2;
  135.         row = (row > 0) ? row : 0;
  136.         col = sed_GetFieldLastCol(sed, fieldno);
  137.         col = (col + sed_GetBorderWidth(list_sed) < disp_GetWidth()) ? col :
  138.                 disp_GetWidth() - sed_GetBorderWidth(list_sed) - 2;
  139.  
  140.         if (sed_GetBorderHeight(list_sed) > disp_GetHeight() -1 ) {
  141.             sed_SetHeight(list_sed, disp_GetHeight() - 3);
  142.         }
  143.  
  144.         sed_SetPosition(list_sed, row, col);
  145.  
  146.         /* attach a mouse handler to the popup */
  147.         sed_SetMouse(list_sed, sedmou_GreedyTrack);
  148.  
  149.         /* go to the currently selected choice */
  150.         if (fno >= 0) {
  151.             sed_GotoField(list_sed, fno);
  152.         }
  153.  
  154.         /* put up list of choices */
  155.         sed_Repaint(list_sed);
  156.  
  157.         if (sed_Go(list_sed) != 0) {
  158.             sed_SetCurrRecord(sed, sed_GetCurrMerge(list_sed));
  159.         }
  160.         sed_UpdateCurrField(sed);
  161.         sed_Close(list_sed);
  162.     }
  163.  
  164.     /* reset baton */
  165.     sed_SetBaton(sed, -1);
  166. }
  167.  
  168. static char *list_GetChoice(char *list, int num, char *string)
  169. /*
  170.     Copies the num'th choice from the list into string.
  171.     Returns string.
  172.     List is of the form:
  173.     "choice 1,choice 2,choice 3"  (commas delimit).
  174.     returns NULL if num is too large.
  175.     Note: assumes that string is at least MAX_CHOICE_LEN + 1 chars long.
  176. */
  177. {
  178.     int p, q;
  179.     unsigned len;
  180.  
  181.     /* skip leading DELIMITERS */
  182.     for (p = 0; list[p] == DELIMITER; p++) {
  183.         ;
  184.     }
  185.  
  186.     for (q = p;; p++) {
  187.  
  188.         /* skip empty entries */
  189.         if ((list[p] == DELIMITER || list[p] == '\0') && num-- <= 0) {
  190.  
  191.             if ((len = p - q) > MAX_CHOICE_LEN) {
  192.                 len = MAX_CHOICE_LEN;
  193.             }
  194.             memmove((VOID *) string, (VOID *) (list + q), len);
  195.             string[len] = '\0';
  196.             break;
  197.         }
  198.         else if (list[p] == DELIMITER) {
  199.             /* point q to beginning of next entry */
  200.             for (q = p + 1; list[q] == DELIMITER; q++, p++) {
  201.                 ;
  202.             }
  203.             if (list[q] == '\0') {
  204.                 return(NULL);
  205.             }
  206.         }
  207.         else if (list[p] == '\0') {
  208.             
  209.             return(NULL);
  210.         }
  211.     }
  212.  
  213.     return(string);
  214. }
  215.  
  216.