home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c160 / 1.ddi / SOURCE / B4BROWSE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-11-21  |  21.1 KB  |  964 lines

  1.  
  2.  
  3.  
  4. /* b4browse.c    (c)Copyright Sequiter Software Inc., 1987-1990. All rights reserved.*/
  5.  
  6. #include "d4all.h"
  7. #include "w4.h"
  8. #include "g4char.h"
  9. #include "p4misc.h"
  10.  
  11. #include <string.h>
  12. #include <ctype.h>
  13.  
  14. static void b4set_row(int,long) ;
  15. static int  b4modify(int) ;
  16. static int  b4skip_one(int) ;
  17. static int  b4page(int) ;
  18. static int  b4top(int) ;
  19. static int  b4find(int) ;
  20. static int  b4bottom(int) ;
  21. static int  b4char(void) ;
  22. static void b4edit_setup(void) ;
  23. static void b4browse_setup(void) ;
  24. static int  b4setup(int (*)(void), int (*)(void)) ;
  25. static void b4deact_menu(void) ;
  26. static int  b4add_copy(int) ;
  27. static int  b4select_index(int) ;
  28. static int  b4delete(int) ;
  29. static int  b4undelete(int) ;
  30. static int  b4go_rec(void) ;     /* Goes to the record at 'b4cursor_row'. */
  31. static int  b4empty_check(void) ;
  32.  
  33. static int  (*user_edit_setup)(void)  =  0 ;
  34. static int  (*user_browse_setup)(void)=  0 ;
  35. static int  b4on_browse  =  -1 ;
  36. static int  b4cur_ref    =  -1 ;
  37.  
  38. static int  b4pull_ref   =  -1 ;
  39. static int  b4select_ref =  -1 ;
  40.  
  41. static int  b4page_size  =  -1 ;
  42. static int  b4top_margin =   3 ;
  43. static int  b4cur_top_margin =  -1 ;
  44. static int  b4bottom_margin =  1 ;
  45. static int  b4cursor_col =  -1 ;
  46. static int  last_read_char =  0 ;
  47. static int  is_empty =  0 ;
  48. static int  do_escape =  0 ;
  49.  
  50. /* Action routines assume that the record at 'b4cursor_row' is
  51.    'b4cursor_rec'. */
  52. static int  b4cursor_row ;
  53. static long b4cursor_rec ;   /* The record at 'b4cursor_row'.  This info
  54.                                 is filled in by 'b4display_recs'.
  55.                                 It becomes '-1L' if there was no record
  56.                                 at the cursor. */
  57. static long b4start_rec ;    /* Saved by 'b4display_assume'.
  58.                                 This is the starting record number. */
  59. static int  b4num_displayed; /* Saved by 'b4display_recs'. */
  60.  
  61. static int  b4display_one(int) ;
  62. static int  b4display_assume(void) ;   /* Assumes that 'b4cursor_rec'
  63.                                       is at 'b4cursor_row'. */
  64. static int  b4display_recs(long) ;
  65. static void b4display_cursor(void) ;
  66.  
  67. extern CB_WINDOW *v4window_ptr ;
  68. extern GET       *v4get ;
  69. extern INDEX     *v4index ;
  70.  
  71. static int  b4go_rec()
  72. {
  73.    if ( ! is_empty )
  74.       if ( b4cursor_rec != d4recno() )
  75.      d4go( b4cursor_rec ) ;
  76.    return 0 ;
  77. }
  78.  
  79. static int  b4empty_check()
  80. {
  81.    if ( d4eof() )
  82.       d4top() ;
  83.    else
  84.    {
  85.       if ( d4skip(1L) == -3 )
  86.          d4top() ;
  87.       else
  88.          d4skip(-1L) ;
  89.    }
  90.    is_empty =  1 ;
  91.    b4cursor_rec = 0L ;
  92.    if ( ! d4eof() )
  93.    {
  94.       is_empty =  0 ;
  95.       b4cursor_rec =  d4recno() ;
  96.    }
  97.    return 0 ;
  98. }
  99.  
  100. static int (*verify_routine)(int) =  0 ;
  101. #ifdef KR
  102.    void  b4verify( verify_rou )
  103.    int (*verify_rou)() ;
  104. #else
  105.    void  b4verify( int (*verify_rou)(int) )
  106. #endif
  107. {
  108.    verify_routine =  verify_rou ;
  109. }
  110.  
  111. static int (*call_routine)(int,int) =  0 ;
  112. #ifdef KR
  113.    void  b4call( call_rou )
  114.    int (*call_rou)() ;
  115. #else
  116.    void  b4call( int (*call_rou)(int,int) )
  117. #endif
  118. {
  119.    call_routine =  call_rou ;
  120. }
  121.  
  122.  
  123. static int  temp_ref = -1 ;
  124.  
  125. static void  b4deact_menu()
  126. {
  127.    if ( w4select(-1) != b4pull_ref && w4select(-1) != b4cur_ref )
  128.    {
  129.       temp_ref =  w4select(-1) ;
  130.       n4refresh( temp_ref ) ;
  131.       w4deactivate(temp_ref) ;
  132.    }
  133. }
  134.  
  135. static void  b4set_row( int new_row, long new_attribute )
  136. {
  137.    int get_on ;
  138.    GET *get_ptr ;
  139.  
  140.    new_row +=  b4cur_top_margin ;
  141.  
  142.    for ( get_on = v4window_ptr->first_get; get_on >= 0; get_on =  get_ptr->next)
  143.    {
  144.       get_ptr =  v4get+ get_on ;
  145.       if ( b4on_browse )
  146.          get_ptr->row =  new_row ;
  147.       get_ptr->attribute =  new_attribute ;
  148.    }
  149. }
  150.  
  151. static int  b4modify( int is_modify )
  152. {
  153.    int  rc ;
  154.  
  155.    if ( is_modify )
  156.       if ( is_empty )  return 0 ;
  157.  
  158.    b4deact_menu() ;
  159.    if ( is_modify )
  160.       b4go_rec() ;
  161.  
  162.    w4activate( b4cur_ref ) ;
  163.    b4set_row( b4cursor_row, (long) B_WHITE ) ;
  164.  
  165.    for( ;; )
  166.    {
  167.       if ( is_modify )
  168.          d4unlock(-1L) ;
  169.  
  170.       last_read_char =  g4read() ;
  171.       if ( last_read_char == ESC || last_read_char == CTRL_Q )
  172.       {
  173.          last_read_char = 0 ;
  174.          if ( is_modify )
  175.             d4go( b4cursor_rec ) ;
  176.          else
  177.             return ESC ;
  178.  
  179.          break ;
  180.       }
  181.       else
  182.       {
  183.          if ( ! u4ptr_equal( (void *) 0, (void *) verify_routine) )
  184.             rc = (*verify_routine)(b4cur_ref) ;
  185.          else
  186.             rc =  0 ;
  187.    
  188.          if ( rc == 0 )
  189.          {
  190.             if ( is_modify )   d4lock( d4recno(), 1 ) ;
  191.             if ( ! u4ptr_equal( (void *) call_routine, (void *) 0) )
  192.            (*call_routine)(b4cur_ref,b4cursor_row+b4cur_top_margin) ;
  193.  
  194.             if ( is_modify )
  195.            rc =  d4write( d4recno() ) ;
  196.             else
  197.                rc =  d4append() ;
  198.             if ( rc == -3 )   continue ;
  199.  
  200.             d4flush( d4select(-1) ) ;
  201.             if ( last_read_char == RETURN || last_read_char == DOWN )
  202.            last_read_char =  0 ;
  203.             break ;
  204.          }
  205.       }
  206.    }
  207.  
  208.    if ( is_modify )
  209.    {
  210.       b4display_assume() ;
  211.       b4display_cursor() ;
  212.    }
  213.  
  214.    d4unlock(-1L) ;
  215.    return 0 ;
  216. }
  217.  
  218. static int b4add_copy( int is_blank )
  219. {
  220.    int  rc, save_row ;
  221.  
  222.    if ( is_blank )
  223.       d4go(0L) ;
  224.    else
  225.       b4go_rec() ;
  226.  
  227.    save_row =  b4cursor_row ;
  228.    b4cursor_row =  b4num_displayed ;
  229.    if ( b4cursor_row >= b4page_size )
  230.       b4cursor_row-- ;
  231.  
  232.    rc =  b4modify(0) ;
  233.    if ( rc != 0 )
  234.       b4cursor_row =  save_row ;
  235.    else
  236.    {
  237.       b4cursor_rec =  d4recno() ;
  238.       b4go_rec() ;
  239.       b4empty_check() ;
  240.    }
  241.  
  242.    b4display_assume() ;
  243.    return 0 ;
  244. }
  245.  
  246.  
  247. static void b4display_cursor()
  248. {
  249.    w4select( b4cur_ref ) ;
  250.    w4cursor( b4cur_top_margin + b4cursor_row, b4cursor_col ) ;
  251. }
  252.  
  253. static int  b4display_one(int disp_row)
  254. {
  255.    int  first_get ;
  256.  
  257.    b4set_row(disp_row,F_WHITE) ;
  258.    first_get =  v4window_ptr->first_get ;
  259.  
  260.    if ( ! u4ptr_equal( (void *) call_routine, (void *) 0) )
  261.       (*call_routine)(b4cur_ref,disp_row+b4cur_top_margin) ;
  262.  
  263.    if ( d4deleted() )
  264.       w4( v4get[first_get].row, v4get[first_get].col-1, "*" ) ;
  265.    else
  266.       w4( v4get[first_get].row, v4get[first_get].col-1, " " ) ;
  267.  
  268.    g4display() ;
  269.    return 0 ;
  270. }
  271.  
  272. /* Returns the number of records displayed.
  273.    Stores record at cursor in 'b4cursor_rec'.
  274. */
  275.  
  276. static int  b4display_recs( long start_rec )
  277. {
  278.    int  i ;
  279.  
  280.    b4num_displayed =  0 ;
  281.    w4activate( b4cur_ref ) ;
  282.  
  283.    b4cursor_rec =  -1L ;
  284.    if ( is_empty )
  285.       d4go(0L) ;
  286.    else
  287.       d4go( start_rec ) ;
  288.  
  289.    for ( i = 0; i < b4page_size; i++ )
  290.    {
  291.       b4display_one(i) ;
  292.  
  293.       if ( ! d4eof())
  294.       {
  295.          b4num_displayed++ ;
  296.          if ( i ==  b4cursor_row )
  297.            b4cursor_rec =  d4recno() ;
  298.  
  299.          d4skip(1L) ;
  300.       }
  301.    }
  302.  
  303.    return 0 ;
  304. }
  305.  
  306. static int  b4display_assume()
  307. {
  308.    b4start_rec =  d4recno() ;
  309.    b4go_rec() ;
  310.    d4skip( (long) -b4cursor_row ) ;
  311.    b4display_recs( d4recno() ) ;
  312.    b4display_cursor() ;
  313.  
  314.    return 0 ;
  315. }
  316.  
  317. static int  b4top( int junk_parm )
  318. {
  319.    d4top() ;
  320.    b4cursor_row =  0 ;
  321.    b4cursor_rec =  d4recno() ;
  322.  
  323.    b4deact_menu() ;
  324.    b4display_assume() ;
  325.  
  326.    d4unlock(-1L) ;
  327.    return 0 ;
  328. }
  329.  
  330. static int  b4bottom( int junk_parm )
  331. {
  332.    long  bot_rec ;
  333.  
  334.    d4bottom() ;
  335.    bot_rec =  d4recno() ;
  336.    d4skip((long)(1-b4page_size) ) ;
  337.  
  338.    b4deact_menu() ;
  339.    b4display_recs(d4recno()) ;
  340.    b4cursor_rec =  bot_rec ;
  341.    b4cursor_row =  b4num_displayed-1 ;
  342.    b4display_cursor() ;
  343.  
  344.    d4unlock(-1L) ;
  345.    return 0 ;
  346. }
  347.  
  348. static int  b4skip_one( int n )
  349. {
  350.    int  rc ;
  351.  
  352.    b4go_rec() ;
  353.    rc =  d4skip( (long) n ) ;
  354.    if ( rc < 0 )  return -1 ;
  355.    if ( rc == 1 )  return 0 ;
  356.    if ( rc == 3 )  return 0 ;
  357.  
  358.    b4cursor_row +=  n ;
  359.    b4cursor_rec =  d4recno() ;
  360.    if ( b4cursor_row < 0 )
  361.    {
  362.       b4cursor_row =  0 ;
  363.       b4deact_menu() ;
  364.       b4display_assume() ;
  365.       return 0 ;
  366.    }
  367.  
  368.    if ( b4cursor_row >=  b4page_size )
  369.    {
  370.       b4cursor_row =  b4page_size -1 ;
  371.       b4deact_menu() ;
  372.       b4display_assume() ;
  373.       return 0 ;
  374.    }
  375.  
  376.    b4display_cursor() ;
  377.    d4unlock(-1L) ;
  378.    return 0 ;
  379. }
  380.  
  381. static int  b4page( int no_recs )
  382. {
  383.    b4go_rec() ;
  384.    if ( no_recs < 0  && b4cursor_row > 0 )
  385.    {
  386.       d4skip( (long) -b4cursor_row ) ;
  387.       b4cursor_rec =  d4recno() ;
  388.       b4cursor_row =  0 ;
  389.       b4display_cursor() ;
  390.       return 0 ;
  391.    }
  392.  
  393.    if ( no_recs > 0  &&  b4cursor_row < b4num_displayed-1 )
  394.    {
  395.       d4skip( (long) (b4num_displayed-1-b4cursor_row) ) ;
  396.       b4cursor_rec =  d4recno() ;
  397.       b4cursor_row =  b4num_displayed-1 ;
  398.       b4display_cursor() ;
  399.       return 0 ;
  400.    }
  401.  
  402.    d4skip( (long) no_recs ) ;
  403.    if ( d4eof()) d4skip(-1L) ;
  404.    b4cursor_rec =  d4recno() ;
  405.    b4deact_menu() ;
  406.    b4display_assume() ;
  407.    d4unlock(-1L) ;
  408.    return 0 ;
  409. }
  410.  
  411. void  b4margin( int top_margin, int bottom_margin )
  412. {
  413.    b4top_margin = top_margin ;
  414.    b4bottom_margin =  bottom_margin ;
  415. }
  416.  
  417. static int  b4help( int junk_parm )
  418. {
  419.    w4display( " Help ",
  420.               "You can use the menu to select an option or you can press",
  421.               "one of the following command keys:",
  422.               "",
  423.               "A  Add a blank record.",
  424.               "B  Move to the bottom database record.",
  425.               "C  Add a record by copying the current record.",
  426.           "D  Mark the current record for deletion.",
  427.           "E  Switch to the edit screen if possible.",
  428.               "F  Find a record.",
  429.               "H  Display this help screen.",
  430.               "M  Modify the current record.",
  431.               "R  Enter a record to move to.",
  432.           "S  Select a record ordering index.",
  433.               "T  Move to the top database record.",
  434.               "U  Remove the deletion mark from the current record.",
  435.           "Z  Switch to the browse screen if possible.",
  436.               "X  Exit.",
  437.               "<PgUp>  or <PgDn>   Move up/down one screen of records.",
  438.           "<Up or Down Arrow>  Move to the previous/next record.",
  439.           (char *) 0 ) ;
  440.    b4display_cursor() ;
  441.    return  0 ;
  442. }
  443.  
  444. static int  b4record( int junk_parm )
  445. {
  446.    long  rec ;
  447.    int     rc, w_ref ;
  448.  
  449.    rec =  b4cursor_rec ;
  450.    if ( rec < 0L )  rec =  0L ;
  451.  
  452.    w_ref =  w4define( 9,20,14,58 ) ;
  453.    w4border( DOUBLE, F_WHITE ) ;
  454.    w4popup() ;
  455.    w4title( 0,-1, " Record Number Command ", B_WHITE ) ;
  456.    w4activate( w_ref ) ;
  457.  
  458.    w4( 1,2, "Enter Record Number: " ) ;
  459.    g4long( w4row(), w4col(), &rec ) ;
  460.    w4( 2,2, "Records in Database:" ) ;
  461.    w4long( w4row(),w4col(), d4reccount(), 9 ) ;
  462.    rc = g4read() ;     /* Read the Record */
  463.  
  464.    w4deactivate( w_ref ) ;
  465.    w4close( w_ref ) ;
  466.  
  467.    if ( rc != ESC )
  468.    {
  469.       if ( rec > 0 && rec <= d4reccount() )
  470.       {
  471.          if ( is_empty )
  472.          {
  473.         w4display( " Message ",
  474.                "To display a record, there will be an immediate",
  475.                        "switch to record number ordering.", (char *) 0 ) ;
  476.         i4unselect() ;
  477.             b4empty_check() ;
  478.          }
  479.          b4cursor_rec =  rec ;
  480.          b4cursor_row =  0 ;
  481.  
  482.          b4deact_menu() ;
  483.          b4display_assume() ;
  484.       }
  485.    }
  486.  
  487.    b4display_cursor() ;
  488.    d4unlock(-1L) ;
  489.    return 0 ;
  490. }
  491.  
  492. static int  b4find( int junk_parm )
  493. {
  494.    int    index_ref, rc, w_ref ;
  495.    char seek_data[101] ;
  496.  
  497.    index_ref =    i4seek_ref() ;
  498.    if ( index_ref < 0 )  return 0 ;
  499.  
  500.    w_ref =  w4define( 9,21,16,58 ) ;
  501.    w4popup() ;
  502.    w4border( DOUBLE, F_WHITE ) ;
  503.    w4title( 0,-1, " Find ", B_WHITE ) ;
  504.    w4activate( w_ref ) ;
  505.  
  506.    w4( 1,3, "Find Index: ") ;
  507.    w4( 1,w4col(), i4name(index_ref)) ;
  508.  
  509.    memset( seek_data, 0, (size_t) sizeof(seek_data) ) ;
  510.    w4( 3,3, "Enter the Find Information:" ) ;
  511.    g4( 4,3, seek_data ) ;
  512.    if ( i4type(index_ref) == 'N' )
  513.       g4width( 24, 24 ) ;
  514.    else
  515.       g4width( 24, 100 ) ;
  516.    rc =  g4read() ;
  517.  
  518.    w4deactivate( w_ref ) ;
  519.    w4close( w_ref ) ;
  520.  
  521.    if ( rc == ESC )
  522.       b4display_cursor() ;
  523.    else
  524.    {
  525.       if ( i4type(index_ref) == 'N' )
  526.       {
  527.          if ( (rc =  d4seek_double( c4atod(seek_data,24) )) < 0)  return -1 ;
  528.       }
  529.       else
  530.          if ( (rc =  d4seek_str(seek_data))< 0)  return -1 ;
  531.  
  532.       if ( rc == 3 )
  533.       {
  534.      c4trim_n( seek_data, (int) sizeof(seek_data) ) ;
  535.      w4display( " The end of the file was reached finding data: ", seek_data, (char *) 0 ) ;
  536.      b4display_cursor() ;
  537.  
  538.          d4unlock(-1L) ;
  539.      return 0 ;
  540.       }
  541.  
  542.       b4cursor_rec =  d4recno() ;
  543.       b4cursor_row =  0 ;
  544.       b4deact_menu() ;
  545.       b4display_assume() ;
  546.    }
  547.  
  548.    d4unlock(-1L) ;
  549.    return 0 ;
  550. }
  551.  
  552.  
  553. static int  b4select_index( int item_ref )
  554. {
  555.    i4select( n4int_get(item_ref) ) ;
  556.    n4start_item( item_ref ) ;
  557.    last_read_char =  -2 ;
  558.    do_escape =  1 ;
  559.    return 0 ;
  560. }
  561.  
  562. static int  b4delete( int junk_parm )
  563. {
  564.    if ( b4cursor_rec > 0L )
  565.       d4delete( b4cursor_rec ) ;
  566.  
  567.    b4deact_menu() ;
  568.    w4select( b4cur_ref ) ;
  569.    b4display_one(b4cursor_row) ;
  570.    d4unlock(-1L) ;
  571.    return 0 ;
  572. }
  573.  
  574. static int  b4undelete( int junk_parm )
  575. {
  576.    if ( b4cursor_rec > 0L )
  577.       d4recall( b4cursor_rec ) ;
  578.  
  579.    b4deact_menu() ;
  580.    w4select( b4cur_ref ) ;
  581.    b4display_one(b4cursor_row) ;
  582.    d4unlock(-1L) ;
  583.    return 0 ;
  584. }
  585.  
  586. static int  b4browse_flip( int junk_parm )
  587. {
  588.    if ( u4ptr_equal( (void *) user_edit_setup, (void *) 0))  return 0 ;
  589.    if ( u4ptr_equal( (void *) user_browse_setup, (void *) 0)) return 0 ;
  590.  
  591.    b4deact_menu() ;
  592.    n4refresh( b4pull_ref ) ;
  593.  
  594.    w4close( b4cur_ref ) ;
  595.  
  596.    if ( b4on_browse )
  597.       b4edit_setup() ;
  598.    else
  599.       b4browse_setup() ;
  600.  
  601.    return 0 ;
  602. }
  603.  
  604. #ifdef KR
  605.    int  b4edit( browse_setup, edit_setup )
  606.    int (*browse_setup)() ;
  607.    int (*edit_setup)() ;
  608. #else
  609.    int  b4edit( int (*browse_setup)(void), int (*edit_setup)(void) )
  610. #endif
  611. {
  612.    b4on_browse =  0 ;
  613.    return( b4setup( browse_setup, edit_setup) ) ;
  614. }
  615.  
  616. #ifdef KR
  617.    int  b4browse( browse_setup, edit_setup )
  618.    int (*browse_setup)() ;
  619.    int (*edit_setup)() ;
  620. #else
  621.    int  b4browse( int (*browse_setup)(void), int (*edit_setup)(void) )
  622. #endif
  623. {
  624.    b4on_browse =  1 ;
  625.    return( b4setup( browse_setup, edit_setup) ) ;
  626. }
  627.  
  628. static char browse_or_edit[] =  "BROWSE" ;
  629.  
  630. static void b4edit_setup()
  631. {
  632.    b4cur_ref =  (*user_edit_setup)() ;
  633.    b4on_browse =  0 ;
  634.    b4cur_top_margin =  v4get[v4window_ptr->first_get].row ;
  635.    b4page_size =  1 ;
  636.    b4cursor_row = 0 ;
  637.    b4cursor_col =  v4get[v4window_ptr->first_get].col ;
  638.    strcpy( browse_or_edit, "Browse" ) ;
  639.    b4display_assume() ;
  640.    d4unlock(-1L) ;
  641. }
  642.  
  643. static void  b4browse_setup()
  644. {
  645.    b4cur_ref =  (*user_browse_setup)() ;
  646.    b4on_browse =  1 ;
  647.    b4cur_top_margin =  b4top_margin ;
  648.    b4page_size =  w4height(-1) - b4top_margin - b4bottom_margin ;
  649.    b4cursor_row =  0 ;
  650.    b4cursor_col =  v4get[v4window_ptr->first_get].col ;
  651.    strcpy( browse_or_edit, "Edit  " ) ;
  652.    b4display_assume() ;
  653.    d4unlock(-1L) ;
  654. }
  655.  
  656. #ifdef KR
  657.    static int  b4setup( browse_setup, edit_setup )
  658.    int (*browse_setup)() ;
  659.    int (*edit_setup)() ;
  660. #else
  661.    static int  b4setup( int (*browse_setup)(void), int (*edit_setup)(void) )
  662. #endif
  663. {
  664.    int  srch_ref, pos_ref, add_ref, ch_ref ;
  665.    int  i_ref, item_ref ;
  666.    int  start_lock_code ;
  667.  
  668.    w4clear(-1) ;
  669.  
  670.    user_edit_setup   =  edit_setup ;
  671.    user_browse_setup =  browse_setup ;
  672.    start_lock_code   =  d4lock_code(2) ;
  673.  
  674.    b4empty_check() ;
  675.  
  676.    if ( b4on_browse )
  677.       b4browse_setup() ;
  678.    else
  679.       b4edit_setup() ;
  680.  
  681.    b4select_ref =  -1 ;
  682.  
  683.    /* Define the index file selection menu. */
  684.    if ( d4ptr()->index_ref >= 0 )
  685.    {
  686.       i_ref =  h4first( (char **) &v4index, d4ptr()->index_ref ) ;
  687.  
  688.       b4select_ref =  w4define(-1,-1,-1,-1) ;
  689.       n4( "Record Number Ordering" ) ;
  690.       n4action( b4select_index ) ;
  691.       n4int_save( -1 ) ;
  692.       for (;i_ref >= 0; i_ref =  v4index[i_ref].next )
  693.       {
  694.      item_ref =  n4( v4index[i_ref].name ) ;
  695.      if ( i4seek_ref() == i_ref )
  696.         n4start_item( item_ref ) ;
  697.      n4action( b4select_index ) ;
  698.      n4int_save( i_ref ) ;
  699.       }
  700.    }
  701.  
  702.    /* Define the main pulldown menu. */
  703.    n4key_special( -1, CTRL_C, -1,-1 ) ;
  704.    b4pull_ref =  w4define( -1,-1,-1,-1 ) ;
  705.    n4key_special( ESC, CTRL_C, -1,-1 ) ;
  706.  
  707.    n4( "Help" ) ;
  708.    n4key( 0,0,-1) ;
  709.    n4action( b4help ) ;
  710.  
  711.    n4( "Modify" ) ;
  712.    n4key( 0,0,-1) ;
  713.    n4action( n4sub_menu ) ;
  714.    n4ptr_save( &ch_ref ) ;
  715.  
  716.    n4( "Add" ) ;
  717.    n4key( 0,0,-1) ;
  718.    n4action( n4sub_menu ) ;
  719.    n4ptr_save( &add_ref ) ;
  720.  
  721.    n4( "Position" ) ;
  722.    n4key( 0,0,-1) ;
  723.    n4action( n4sub_menu ) ;
  724.    n4ptr_save( &pos_ref ) ;
  725.  
  726.    if ( b4select_ref >= 0 )
  727.    {
  728.       n4( "Find" ) ;
  729.       n4key( 0,0,-1) ;
  730.       n4action( n4sub_menu ) ;
  731.       n4ptr_save( &srch_ref ) ;
  732.    }
  733.  
  734.    if ( ! u4ptr_equal((void *) user_edit_setup,(void *) 0) &&
  735.         ! u4ptr_equal((void *) user_edit_setup,(void *) 0))
  736.    {
  737.       n4( browse_or_edit ) ;
  738.       n4key( 0,0,-1) ;
  739.       n4action( b4browse_flip ) ;
  740.    }
  741.  
  742.    n4( "Exit" ) ;
  743.    n4key( 0,0,-1) ;
  744.    n4parm( -1 ) ;
  745.  
  746.    ch_ref =  w4define(-1,-1,-1,-1) ;
  747.    n4( "Modify Record" ) ;        n4action( b4modify ) ;  n4parm(1) ;
  748.    n4( "Delete Record" ) ;        n4action( b4delete ) ;
  749.    n4( "Undelete Record" ) ;      n4action( b4undelete ) ;
  750.  
  751.    if ( b4select_ref >= 0 )
  752.    {
  753.       srch_ref =  w4define(-1,-1,-1,-1) ;
  754.       n4( "Find" ) ;              n4action( b4find ) ;
  755.       if ( b4select_ref >= 0 )
  756.       {
  757.          n4( "Select Record Ordering Index" ) ;
  758.          n4action( n4sub_menu ) ;
  759.          n4ptr_save( &b4select_ref ) ;
  760.       }
  761.    }
  762.  
  763.    pos_ref =  w4define(-1,-1,-1,-1) ;
  764.    n4( "Record" ) ;               n4action( b4record ) ;
  765.    n4( "Top" ) ;                  n4action( b4top ) ;
  766.    n4( "Bottom" ) ;               n4action( b4bottom ) ;
  767.  
  768.    add_ref =  w4define(-1,-1,-1,-1) ;
  769.    n4( "Add Blank" ) ;            n4action( b4add_copy ) ;  n4parm(1) ;
  770.    n4( "Add Copy" ) ;             n4action( b4add_copy ) ;  n4parm(0) ;
  771.    n4key( (int) 'C', 1, 4 ) ;
  772.  
  773.    n4pulldown( b4pull_ref ) ;
  774.    w4select( b4pull_ref ) ;
  775.    w4memory() ;
  776.    n4char_routine( b4char ) ;
  777.    n4activate( b4pull_ref ) ;
  778.  
  779.    w4close( b4cur_ref ) ;
  780.  
  781.    w4deactivate( b4pull_ref ) ;
  782.    w4close( b4pull_ref ) ;
  783.    n4char_routine( 0 ) ;
  784.  
  785.    if ( b4select_ref >= 0 )
  786.    {
  787.       w4close( b4select_ref ) ;
  788.       w4close( srch_ref ) ;
  789.    }
  790.  
  791.    w4close( pos_ref ) ;
  792.    w4close( add_ref ) ;
  793.    w4close( ch_ref ) ;
  794.  
  795.    d4lock_code( start_lock_code  ) ;
  796.    w4clear(-1) ;
  797.  
  798.    return 0 ;
  799. }
  800.  
  801. static int  b4char()
  802. {
  803.    int  rc ;
  804.  
  805.    if ( do_escape )
  806.    {
  807.       do_escape =  0 ;
  808.       return ESC ;
  809.    }
  810.  
  811.    if ( last_read_char != 0 )
  812.    {
  813.       rc =  last_read_char ;
  814.       last_read_char =  0 ;
  815.    }
  816.    else
  817.       rc =  g4char() ;
  818.  
  819.    if ( rc > 0 && rc < 0xFF )
  820.       rc =  u4toupper(rc) ;
  821.  
  822.    if ( w4select(-1) != b4pull_ref )
  823.       if ( rc >= (int) 'A' && rc <= (int) 'Z' )  return rc ;
  824.  
  825.    switch( rc )
  826.    {
  827.       case PGUP:
  828.      b4page( -b4page_size ) ;
  829.          break ;
  830.  
  831.       case PGDN:
  832.      b4page( b4page_size ) ;
  833.          break ;
  834.  
  835.       #ifndef UNIX
  836.       case ALT_A:
  837.       #endif
  838.       case 'A':
  839.      b4add_copy(1) ;
  840.          break ;
  841.  
  842.       #ifndef UNIX
  843.       case ALT_B:
  844.       #endif
  845.       case 'B':
  846.          b4bottom(0) ;
  847.          break ;
  848.  
  849.       #ifndef UNIX
  850.       case ALT_C:
  851.       #endif
  852.       case 'C':
  853.          b4add_copy(0) ;
  854.          break ;
  855.  
  856.       #ifndef UNIX
  857.       case ALT_D:
  858.       #endif
  859.       case 'D':
  860.          b4delete(0) ;
  861.      break ;
  862.  
  863.       #ifndef UNIX
  864.       case ALT_E:
  865.       #endif
  866.       case 'E':
  867.      if ( b4on_browse )
  868.         b4browse_flip(0) ;
  869.      break ;
  870.  
  871.       #ifndef UNIX
  872.       case ALT_F:
  873.       #endif
  874.       case 'F':
  875.      b4find(0) ;
  876.      break ;
  877.  
  878.       #ifndef UNIX
  879.       case ALT_H:
  880.       #endif
  881.       case 'H':
  882.          b4help(0) ;
  883.          break ;
  884.  
  885.       #ifndef UNIX
  886.       case ALT_M:
  887.       #endif
  888.       case 'M':
  889.          b4modify(1) ;
  890.          break ;
  891.  
  892.       #ifndef UNIX
  893.       case ALT_R:
  894.       #endif
  895.       case 'R':
  896.          b4record(0) ;
  897.      break ;
  898.  
  899.       #ifndef UNIX
  900.       case ALT_S:
  901.       #endif
  902.       case 'S':
  903.          if ( b4select_ref >= 0 )
  904.             n4activate( b4select_ref ) ;
  905.          break ;
  906.  
  907.       case -2:  /* After 'b4select_index' to refresh the display. */
  908.      b4deact_menu() ;
  909.      b4go_rec() ;
  910.          b4empty_check() ;
  911.          b4display_assume() ;
  912.          if ( b4cursor_rec == -1L )
  913.          {
  914.             b4cursor_rec =  b4start_rec ;
  915.             b4cursor_row =  0 ;
  916.          }
  917.          d4unlock(-1L) ;
  918.          break ;
  919.  
  920.       #ifndef UNIX
  921.       case ALT_T:
  922.       #endif
  923.       case 'T':
  924.          b4top(0) ;
  925.          break ;
  926.  
  927.       #ifndef UNIX
  928.       case ALT_U:
  929.       #endif
  930.       case 'U':
  931.          b4undelete(0) ;
  932.      break ;
  933.  
  934.       #ifndef UNIX
  935.       case ALT_Z:
  936.       #endif
  937.       case 'Z':
  938.      if ( ! b4on_browse )
  939.         b4browse_flip(0) ;
  940.      break ;
  941.  
  942.       #ifndef UNIX
  943.       case ALT_X:
  944.       #endif
  945.       case 'X':
  946.      return CTRL_C ;
  947.  
  948.       case UP:
  949.      if ( v4window_ptr->horizontal )
  950.         b4skip_one(-1) ;
  951.      return rc ;
  952.  
  953.       case DOWN:
  954.      if ( v4window_ptr->horizontal )
  955.         b4skip_one(1) ;
  956.      return rc ;
  957.  
  958.       default:
  959.          return rc ;
  960.    }
  961.  
  962.    return 0 ;
  963. }
  964.