home *** CD-ROM | disk | FTP | other *** search
/ The Developer Connection…ice Driver Kit for OS/2 3 / DEV3-D1.ISO / devtools / dataflex / table.pkg < prev    next >
Encoding:
Text File  |  1993-08-10  |  27.3 KB  |  899 lines

  1. //************************************************************************
  2. //
  3. // Copyright 1987-1992 Data Access Corporation, Miami FL, USA
  4. // All Rights reserved
  5. // DataFlex is a registered trademark of Data Access Corporation.
  6. //
  7. //
  8. //     $Source: /u3/source.30/product/pkg/RCS/table.pkg,v $
  9. //     $Revision: 1.1 $
  10. //     $State: Exp $
  11. //     $Author: james $
  12. //     $Date: 1992/09/08 14:43:09 $
  13. //     $Locker:  $
  14. //
  15. //     $Log: table.pkg,v $
  16. //Revision 1.1  1992/09/08  14:43:09  james
  17. //Initial revision
  18. //
  19. //Revision 1.26  92/07/02  18:18:21  lee
  20. //added guard in beginning/end_of_data for no items to prevent invalid item
  21. //refrerence.
  22. //
  23. //Revision 1.25  92/06/28  16:08:03  lee
  24. //added goto_top/bottom_row messages for keys: these do the same thing
  25. //as the recent top/bottom_of_panel message were doing. top/bottom_of_panel
  26. //now revert to superclass behavior: moves to first/last item on row.
  27. //beginning_of_data corrected to respect noSaveFlag (like it had been for a
  28. //short while).
  29. //
  30. //Revision 1.24  92/06/27  09:33:54  lee
  31. //child_wrapping corrected to handle table in ringing client. also using
  32. //recurseClient flag in inqure msgs.
  33. //
  34. //Revision 1.23  92/06/19  16:31:57  james
  35. //Last minute changes made to correct problem with 
  36. //SWITCH_BACK
  37. //
  38. //Revision 1.22  92/06/17  23:57:27  lee
  39. //fixed various bugs in table: only validates on same row and during save
  40. //childwrapping moves to last enterable item when moving backward
  41. //request_delete disables validation during removal of row.
  42. //beginning/end_of panel moves to top/biottom row, same column
  43. //
  44. //Revision 1.21  92/06/10  06:09:10  lee
  45. //various fixes for bugs introduced during "overhaul"
  46. //
  47. //Revision 1.19  92/06/06  08:11:41  lee
  48. //complete overhaul of add-mode mechanism. lots and lots of changes!
  49. //
  50. //Revision 1.18  92/06/05  16:32:36  steve-l
  51. //altered set current_item occurrances to use set item false/true/2/3 instead,
  52. //in order to properly handle displayonly/noenter items on top-of-panel et al.
  53. //
  54. //Revision 1.17  92/06/03  15:20:57  steve-l
  55. //altered child_wrapping for proper dereferencing of new argument
  56. //
  57. //Revision 1.16  92/06/03  15:10:08  steve-l
  58. //altered child_wrapping for new argument
  59. //
  60. //Revision 1.15  92/06/01  17:58:07  steve-l
  61. //guarded REQUEST_SAVE behavior with server=0 | not(read-only(server))
  62. //
  63. //Revision 1.14  92/05/14  17:14:44  SWM
  64. //Updated Copyright slug.
  65. //
  66. //Revision 1.13  92/04/30  13:21:38  lee
  67. //altered add_or_remove_row to not delete the last row of the table
  68. //
  69. //Revision 1.12  92/04/28  14:45:08  lee
  70. //actually declared the noSaveFlag argument this time!
  71. //
  72. //Revision 1.11  92/04/28  14:32:08  lee
  73. //Added nosave flag to beginning_of data to allow initialize list to
  74. //not cause a save.
  75. //
  76. //Revision 1.10  92/04/24  15:41:59  lee
  77. //update_row now checks to see if there are any rows in the table before
  78. //checking to see if the row changed. this prevents an item number out of
  79. //range error.
  80. //
  81. //Revision 1.9  92/03/18  12:39:39  steve-l
  82. //altered all calls to vfind to perform a relate if successful]
  83. //
  84. //Revision 1.8  92/03/10  17:07:50  steve-l
  85. //CLEAR altered to just clear row instead of inserting blank row when the
  86. //row's recnum is already 0, e.g. the row was "remotely" deleted (e.g.
  87. //from a zoom)
  88. //
  89. //Revision 1.7  92/03/09  19:04:51  james
  90. //Added #CHKSUB directive to insure source
  91. //only compiled with correct revision of 
  92. //compiler.
  93. //
  94. //Revision 1.6  92/03/05  15:43:35  steve-l
  95. //Request_Superfind changed to set ERR false before calling server and to
  96. //check err (with found) afterward, in case of non-file-boundary errors
  97. //
  98. //Revision 1.5  92/02/12  16:48:20  steve-l
  99. //row_changing altered to correct blank-row rotation problem
  100. //
  101. //Revision 1.4  92/01/13  11:20:28  james
  102. //Cleaned up header.
  103. //
  104. //Revision 1.3  91/11/26  09:19:35  steve-l
  105. //sparky
  106. //
  107.  
  108. //************************************************************************/
  109.  
  110. //************************************************************************
  111. //     File Name: Table.Pkg
  112. // Creation Date: January 1, 1991
  113. // Modified Date: Apr 30, 1992
  114. //     Author(s): Steven A. Lowe
  115. //
  116. // This module contains the Table class definition.
  117. //************************************************************************/
  118.  
  119. #CHKSUB 1 1 // Verify the UI subsystem.
  120.  
  121. Use DataList
  122. Use Verify
  123. Use FindEdit
  124.  
  125.  
  126. class Table is a Data_List
  127.  
  128.   procedure construct_object integer img
  129.     forward send construct_object img
  130.     Property integer Wrapping_State         PUBLIC 0
  131.     on_key kADD_MODE send add_or_remove_row PRIVATE
  132.     send define_Verify    //invoke verify support constructor
  133.     send define_find_edit //invoke find/edit support constructor
  134.     set Auto_Save_State to TRUE   //tables change default for wrap-around save
  135.     set No_Create_State  to FALSE //tables permit creation by default
  136.   end_procedure
  137.  
  138.   IMPORT_CLASS_PROTOCOL VERIFY_Mixin   //include Verification support module
  139.   IMPORT_CLASS_PROTOCOL FIND_EDIT_Mixin //include finding/editing support module
  140.  
  141.   procedure Request_Clear
  142.     local integer obj# retval base
  143.  
  144.     if (no_create_state(current_object)) procedure_return
  145.  
  146.     //
  147.     // modification for Server support
  148.     //
  149.     get Server to obj#
  150.     //
  151.     // modification for Verify support
  152.     //
  153.     if ((Changed_State(current_object) OR ;           //(self changed OR
  154.         (obj# <> 0 AND Changed_State(obj#)))) begin   //server changed)
  155.       if (Verify_Data_Loss(current_object)) NE 0 ;  //don't abandon changes
  156.           procedure_return                          //means don't clear
  157.       else send find_record (current_record(current_object))
  158.     end
  159.  
  160.     get Object_Validation to retval
  161.     set Object_Validation to false
  162.  
  163.     if obj# ne 0 send clear to obj#
  164.     else send clear
  165.  
  166. //    if (auto_top_panel_state(current_object)) begin
  167. //      get base_item to base
  168. //      if (current_item(current_object)) NE base ;
  169. //          set current_item to (base_item(current_object))
  170. //    end
  171.  
  172.     set Object_Validation to retval
  173.   end_procedure
  174.  
  175.   procedure Request_Clear_All
  176.     local integer obj# isChgd retval
  177.  
  178.     if (no_create_state(current_object)) procedure_return
  179.  
  180.     get Object_Validation to retval
  181.     set Object_Validation to false
  182.     get Server to obj#
  183.     if ((obj# <> 0 AND Changed_State(obj#)) OR ;
  184.         Changed_State(current_object)) begin
  185.       if (Verify_Data_Loss(current_object)) NE 0 begin
  186.         set Object_Validation to retval
  187.         procedure_return
  188.       end
  189.     end
  190.     if obj# ne 0 send clear_all to obj#
  191.     else send entry_clear_all 0
  192.     if (Auto_Top_Panel_State(current_object)) send beginning_of_panel
  193.     set Object_Validation to retval
  194.   end_procedure
  195.  
  196.   procedure entry_autofind integer mode
  197.     local integer srvr# file# datafile# field# oldDisp oldChg item#
  198.     get Changing_State to oldChg
  199.     set Changing_State to TRUE
  200.     get Server to srvr#
  201.     get main_file to file# 
  202.     get autofind_item to item#
  203.     get data_file item item# to datafile#
  204.     get data_field item item# to field#
  205.     if (srvr# <> 0 AND datafile# > 0) begin
  206.       if datafile# eq file# ;      //if finding on main file, redisplay page
  207.           send Item_Find to srvr# mode datafile# field# TRUE FALSE ;
  208.           (Deferred_State(current_object))
  209.       else begin  //if finding on parent file, redisplay current row only
  210.         get line_display_State to oldDisp
  211.         set line_display_State to true
  212.         send Item_Find to srvr# mode datafile# field# TRUE FALSE ;
  213.           (Deferred_State(current_object))
  214.         set line_display_State to oldDisp
  215.       end
  216.     end
  217.     else begin
  218.       forward send entry_autofind mode
  219.       if datafile# eq file# send fill_page DOWNWARD_DIRECTION
  220.     end
  221.     set Changing_State to oldChg
  222.   end_procedure
  223.  
  224.   //
  225.   // FindEdit support behavior
  226.   //
  227.   procedure Request_Find integer mode integer entUpdtFlag
  228.     local integer dataFile ser# dfrdState mainfile
  229.     get Data_File to dataFile
  230.     get Server to ser#
  231.     get Deferred_State to dfrdState
  232.     get main_file to mainfile
  233.  
  234.     //
  235.     // server augmentation
  236.     //
  237.     if (ser# <> 0 AND dataFile > 0) begin
  238.       send Item_Find to ser# mode dataFile ;
  239.         (Data_Field(current_object,CURRENT)) entUpdtFlag TRUE dfrdState
  240.       [found] if dfrdState begin
  241.         if dataFile eq mainfile send display
  242.         else send entry_display 0 0
  243.       end
  244.     end
  245.  
  246.     //
  247.     // standard form behavior
  248.     //
  249.     else begin
  250.       send Entry_Find mode
  251.       [found] begin
  252.         if dataFile eq mainfile send fill_page DOWNWARD_DIRECTION
  253.         else send entry_display 0 0
  254.       end
  255.     end
  256.   end_procedure
  257.  
  258.   //
  259.   // FindEdit support behavior
  260.   //
  261.   procedure Request_SuperFind integer mode
  262.     local integer obj# file# mainfile#
  263.     get Server to obj#
  264.     get data_file to file#
  265.     if file# gt 0 begin
  266.       get main_file to mainfile#
  267.       if obj# ne 0 begin
  268.         if mainfile# eq 0 get main_file of obj# to mainfile#
  269.         indicate err false
  270.         send Request_SuperFind to obj# mode file# ;
  271.             (data_field(current_object,CURRENT))
  272.         [not found not err] begin
  273.           if mode lt 2 error 41
  274.           else error 42
  275.         end
  276.       end
  277.       else begin
  278.         send entry_superfind mode mainfile#
  279.         [found] begin
  280.           if file# eq mainfile# send fill_page DOWNWARD_DIRECTION
  281.           else send entry_display 0 0
  282.         end
  283.       end
  284.     end
  285.   end_procedure
  286.  
  287.   Register_Function Save returns integer
  288.  
  289.   function row_changed INTEGER row# RETURNS INTEGER
  290.     local integer count maxx base lim obj#
  291.     get item_limit to lim
  292.     calc (row# * lim) to base
  293.     calc (base + lim - 1) to maxx
  294.     for count from base to maxx
  295.       if (item_changed_State(current_object,count)) function_return 1
  296.     loop
  297.     get server to obj#
  298.     if (obj# <> 0 AND Should_Save_Row(obj#)) function_Return 1
  299.   end_function
  300.  
  301.   function validate_range integer from# integer to# returns integer
  302.     local integer count retval oldcuritem
  303.     move 0 to retval
  304.     get current_item to oldcuritem
  305.     for count from from# to to#
  306.       set new_item to count
  307.       move (exec_Validate(Current_Object,count)) to retval
  308.     until retval ne 0
  309.     set new_item to oldcuritem
  310.     if retval ne 0 function_return count  //return item# that failed
  311.     else function_return -1               //-1 means all ok
  312.   end_function
  313.  
  314.   function update_row integer row# returns integer
  315.     local integer srvr# lineDisp retval rec# base mainfile oldVal
  316.  
  317.     //
  318.     // if the specified row is changed, save the changes as required
  319.     //
  320.     if ((Row_Count(Current_Object) > 0) AND ;
  321.             Row_Changed(current_object,row#)) begin 
  322.  
  323.       //
  324.       // if we're not supposed to save (auto-save is false, or we're trying to
  325.       // create a new record with no_create=true), abandon changes.
  326.       //
  327.       if (not(auto_save_state(current_object)) OR ;
  328.           (no_create_state(current_object) AND ;
  329.           record_number(current_object,row#) = 0)) begin
  330.         if (verify_data_loss(current_object)) NE 0 ; // user disallowed abandon
  331.             function_return 2
  332.         else send find_record (record_number(current_object,row#))
  333.       end
  334.       else begin
  335.         //
  336.         // calculate the base-item for the designated row
  337.         //
  338.         calc (row# * item_limit(Current_Object)) to base
  339.  
  340.         //
  341.         // get the server
  342.         //
  343.         get Server to srvr#
  344.    
  345.         //
  346.         // if this list has a server, save the changes as required
  347.         //
  348.         if Srvr# ne 0 begin
  349.         
  350.           //
  351.           // validate the items of this list and all other DEOs for this
  352.           // list's server
  353.           //
  354.           get object_validation to oldVal
  355.           set object_validation to TRUE
  356.  
  357.           get Request_Validate of Srvr# to retval
  358.  
  359.           set object_validation to oldVal
  360.    
  361.           //
  362.           // if validation failed, exit
  363.           //
  364.           if retval ne 0 function_return 1
  365.    
  366.           //
  367.           // if the user verifies the save, save the changes
  368.           //
  369.           if (Verify_Save(current_object) = 0) begin
  370.    
  371.             //
  372.             // get the record number for the designated row
  373.             //
  374.             get record_number item row# to rec#
  375.    
  376.             //
  377.             // get the main_file of the list
  378.             //
  379.             move (main_file(current_object)) to mainfile
  380.    
  381.             //
  382.             // use Read_By_RecNum of the server to locate the designated
  383.             // row's record
  384.             //
  385.             send Read_By_RecNum to Srvr# mainfile rec#
  386.    
  387.             //
  388.             // if this list is Deferred, make sure the server is latched on
  389.             // to the proper record
  390.             //
  391.             if (Deferred_State(current_object)) ;
  392.                 send Request_Assign to Srvr# mainfile
  393.    
  394.             //
  395.             // save the changes to the designated (current) row
  396.             //
  397.             send Save_Row
  398.    
  399.             //
  400.             // if an error occurred, exit
  401.             //
  402.             [err] function_return 3
  403.    
  404.           end
  405.    
  406.           //
  407.           // if the user cancels the save, exit
  408.           //
  409.           else function_return 2
  410.    
  411.         end
  412.       end
  413.     end
  414.   end_function
  415.  
  416.   //
  417.   //kADD_MODE toggling procedure
  418.   //
  419.   procedure add_or_Remove_row
  420.     local integer ser# retval
  421.  
  422.     if (no_create_state(current_object)) procedure_return
  423.  
  424.     get server to ser#
  425.  
  426.     //
  427.     // if not an a clear row, or on last row, clear
  428.     //
  429.     if ((current_Record(current_object) <> 0) OR ;
  430.         (current_row(current_object) = (row_count(current_object) - 1)) ) ;
  431.       send request_clear
  432.     else begin
  433.       //
  434.       // if the current row is changed, ask the user if they want to
  435.       // abandon the changes; if not, exit, otherwise, close the "hole"
  436.       // and regerate the display page
  437.       //
  438.       if (row_changed(current_object,current_row(current_object)) AND ;
  439.          (Verify_Data_Loss(current_object) <> 0)) ; //don't abandon changes
  440.          procedure_return                          //means don't clear
  441.  
  442.       get Exit_Add_Mode TRUE TRUE (current_item(current_object)) ;
  443.           to retval
  444.  
  445.       send Find_Record (current_record(current_object))
  446.       
  447.     end
  448.   end_procedure
  449.  
  450.   procedure Toggle_Shadow //shadow/unshadow current row of items
  451.     local integer counter shadowValue wdth baseItem lim
  452.     get item_limit to wdth
  453.     get base_item to baseItem
  454.     if (shadow_state(current_object,baseItem)) eq 0 begin
  455.       move 1 to shadowValue              //else set items shadowed
  456.       set changed_state to true
  457.     end
  458.     else move 0 to shadowValue     //else set items unshadowed
  459.     calc (baseItem + wdth - 1) to lim
  460.     for counter from baseItem to lim
  461.       set shadow_state item counter to shadowValue
  462.     loop
  463.   end_procedure
  464.  
  465.   procedure Child_Wrapping integer direction integer xorigID
  466.     local integer targetItem origID
  467.  
  468.     if NUM_ARGUMENTS gt 1 move xorigID to origID
  469.     else get focus of desktop to origID
  470.     if origID eq 0 move current_object to origID
  471.  
  472.     send activate
  473.  
  474.     if direction ne 0 begin     //wrapping forward
  475.       calc (base_item(current_object) + item_limit(current_object)) ;
  476.           to targetItem
  477.         if targetItem GE (item_count(current_object)) send add_row
  478.  
  479.       //
  480.       // save only when wrapping forward
  481.       //
  482.       if ((origID <> current_object) AND auto_Save_State(origID)) ;
  483.           send request_Save to origID
  484.       else if (auto_save_state(current_object) AND ;
  485.           not(advancing_state(current_object))) send request_save
  486.  
  487.     end
  488.     else calc (base_item(current_object) - 1) to targetItem // wrapping backward
  489.  
  490.     set Wrapping_State to true
  491.     set current_item to targetItem
  492.  
  493.     set Wrapping_State to false
  494.     procedure_return 1
  495.   end_procedure
  496.  
  497.   procedure Request_Delete
  498.     local integer obj# dynUpdt oldItem oldDisp rec# retval item# oldDyn
  499.     local integer oldVal oldEntEx base
  500.  
  501.     indicate err false
  502.     get Server to obj#
  503.  
  504.     if (obj# <> 0 AND can_Delete(obj#)) begin
  505.       if (Verify_Delete(current_object)) NE 0 procedure_return
  506.  
  507.       if (Batch_State(current_object)) send toggle_shadow
  508.       else if obj# ne 0 begin
  509.         set changed_state to false
  510.  
  511.         if (Deferred_State(current_object)) ;
  512.             send Request_Assign to obj# 0  //0 means main_file of Server
  513.  
  514.         send Request_Delete to obj#
  515.  
  516.         [not err] begin
  517.           get dynamic_update_state to oldDyn
  518.           set dynamic_update_state to FALSE
  519.  
  520.           get object_validation to oldVal
  521.           set object_validation to FALSE
  522.           get object_item_entry_exit to oldEntEx
  523.           set object_item_entry_exit to FALSE
  524.  
  525.           get current_item to item#
  526.           get Exit_Add_Mode TRUE FALSE item# to retval
  527.           set current_item to item#
  528.  
  529.           if (current_record(current_object)) NE 0 ;
  530.               send Find_Record (current_record(current_object))
  531.           else send clear_row (current_row(current_object))
  532.  
  533.           set object_item_entry_exit to oldEntEx
  534.  
  535. //          if (auto_top_panel_state(current_object)) begin
  536. //            get base_item to base
  537. //            if ((current_record(current_object) = 0) AND ;
  538. //                (current_item(current_object) <> base)) ;
  539. //              set current_item to (base_item(current_object))
  540. //          end
  541.  
  542.           set object_validation to oldVal
  543.  
  544.           set dynamic_update_state to oldDyn
  545.         end
  546.       end
  547.     end
  548.   end_procedure
  549.  
  550.   procedure save_row
  551.     local integer obj#
  552.  
  553.     indicate err false
  554.     get Server to obj#
  555.  
  556.     if obj# ne 0 begin
  557.       send Request_Save to obj#
  558.  
  559.       [not err] begin
  560.         get main_file to filenumber
  561.         move 0 to fieldindex
  562.         set current_record to Indirect_File.RECNUM
  563.       end
  564.     end
  565.   end_procedure
  566.  
  567.   procedure Request_Save
  568.     local integer curItem obj# retval wasNew oldWasNew file# oldVal
  569.  
  570.     if (not(no_create_state(current_object)) OR ;
  571.         (current_record(current_object) <> 0)) begin
  572.  
  573.       get Server to obj#
  574.       if (obj# = 0 OR not(Read_Only_State(obj#))) begin
  575.  
  576.         get current_item to curItem
  577.  
  578.         get main_file to file#
  579.  
  580.         if ((obj# <> 0 AND Should_Save(obj#)) OR ;
  581.             Changed_State(current_object)) begin
  582.  
  583.           get object_validation to oldVal
  584.           set object_validation to TRUE
  585.  
  586.           if obj# ne 0 get Request_Validate of obj# to retval
  587.           else get Validate_Items FALSE to retval
  588.  
  589.           set object_validation to oldVal
  590.  
  591.           if (retval OR (Verify_Save(Current_object) <> 0)) procedure_return
  592.  
  593.           if (Deferred_State(current_object)) ;
  594.               send Request_Assign to obj# file#
  595.  
  596.           move (current_record(current_object) = 0) to wasNew
  597.   
  598.           get was_new_row_state to oldWasNew
  599.           set was_new_row_state to wasNew
  600.           send save_row  //save the current row
  601.           set was_new_row_state to oldWasNew
  602.   
  603.           if wasNew get Exit_Add_Mode FALSE TRUE ;
  604.               (current_item(current_object)) to retval
  605.         end
  606.       end
  607.     end
  608.   end_procedure
  609.  
  610.   //
  611.   // returns -1 if all went ok, else returns item# which failed
  612.   //
  613.   function row_changing integer fromItem integer toItem returns integer
  614.  
  615.     local integer from# to# retval toRow fromRow lim wasNew oldWasNew
  616.     local integer rowChgd btch adv
  617.  
  618.     //
  619.     // initialize working origin and destination item numbers
  620.     // and other variables representing properties
  621.     //
  622.     move fromItem to from#
  623.     move toItem to to#
  624.     get row item from# to fromRow
  625.     get item_limit to lim
  626.  
  627.     //
  628.     // if origin row's record_number is zero, wasNew is TRUE
  629.     // else it is FALSE
  630.     //
  631.     move (record_number(current_object,fromRow) = 0) to wasNew
  632.  
  633.     get was_new_row_state to oldWasNew    //required for forwarded function
  634.     set was_new_row_state to wasNew    //required for forwarded function
  635.  
  636.     move (row_changed(current_object,fromRow)) to rowChgd
  637.  
  638.     get batch_state to btch
  639.     get advancing_state to adv
  640.  
  641.     if not btch begin
  642.       //
  643.       // if row was changed
  644.       //
  645.       if rowChgd begin
  646.         //
  647.         // if in add-mode, but row will not be saved,
  648.         // wrap to first item on same row
  649.         //
  650.         if (wasNew AND adv AND (no_create_state(current_object) OR ;
  651.             not(auto_save_state(current_object)))) ;
  652.             function_return (base_item(current_object))
  653.  
  654.         if (Update_Row(current_object,fromRow)) NE 0 ;
  655.           function_return (current_item(current_object))
  656.       end
  657.       //
  658.       // else row was NOT changed and in add-mode;
  659.       // wrap to first item on same row
  660.       //
  661.       else if (wasNew AND adv) ;
  662.         function_return (base_item(current_object))
  663.  
  664.     end
  665.  
  666.     forward get row_changing from# to# to to#
  667.  
  668.     set was_new_row_state to oldWasNew  //reset (required for forwarded function)
  669.  
  670.     //
  671.     // new row was just saved, but we're not continuing add_mode, exit_add_mode
  672.     //
  673.     if (wasNew AND rowChgd AND not(btch) AND (not(adv) OR ;
  674.             not(auto_clear_deo_state(current_object)))) begin
  675.  
  676.         get current_item to from#
  677.  
  678.         set new_item to to#
  679.         get Exit_Add_Mode FALSE TRUE to# to to#  //returns adjusted dest item
  680.         set new_item to from#
  681.     end
  682.  
  683.     //
  684.     // get destination item's row
  685.     //
  686.     get row item to# to toRow
  687.  
  688.     //
  689.     // if we're moving to some column other than the first column in the
  690.     // destination row, validate the preceding items in the row
  691.     //
  692.     if to# gt (toRow * lim) begin
  693.  
  694.       //
  695.       // validate all items from the first column to the item just prior
  696.       // to the destination item
  697.       //
  698.       move (validate_range(Current_Object,(toRow * lim),(to# - 1))) to retval
  699.  
  700.       //
  701.       // if validate_range returned anything other than -1 (0..n-1),
  702.       // the return value is the item number of the item that failed
  703.       // validation; return this item as the destination
  704.       //
  705.       if retval ne -1 function_return retval
  706.  
  707.     end
  708.  
  709.     //
  710.     // return the destination item number
  711.     //
  712.     function_return to#
  713.  
  714.   end_function
  715.  
  716.   function exit_and_save integer dir returns integer
  717.     local integer curItem base lim ret_val
  718.  
  719.     get current_item to curItem
  720.     get base_item to base
  721.     get item_limit to lim
  722.  
  723.     if (exec_exit(current_object,curItem)) NE 0 function_return 1 // failed
  724.  
  725.     if (update_row(current_object,current_row(current_object))) NE 0 ;
  726.         function_return 1 // failed
  727.  
  728.     function_return 0 // success
  729.   end_function
  730.  
  731.   function validate_and_enter returns integer
  732.     local integer curItem base ret_val
  733.  
  734.     get current_item to curItem
  735.     get base_item to base
  736.  
  737.     //
  738.     // validate up to current item
  739.     //
  740.     if curItem NE base begin
  741.       get validate_range base (curItem - 1) to ret_val
  742.  
  743.       if ret_val NE -1 begin
  744.         set current_item to ret_val
  745.         function_return 1 // failed
  746.       end
  747.     end
  748.  
  749.     //
  750.     // enter current item
  751.     //
  752.     if (exec_entry(current_object,curItem)) NE 0 function_return 1 // failed
  753.  
  754.     function_return 0
  755.   end_function
  756.  
  757.   procedure item_change integer from# integer to# returns integer
  758.     local integer oldObjVal base retVal suspendValidate
  759.  
  760.     if (Changing_State(Current_Object)) begin
  761.       set Advancing_State to FALSE
  762.       procedure_Return to#
  763.     end
  764.  
  765.     //
  766.     // suspend validation if moving off the current row
  767.     //
  768.     get base_item to base
  769.     move (not(batch_state(current_object)) AND ;
  770.         ((to# > (base + item_limit(current_object) - 1)) OR (to# < base))) ;
  771.         to suspendValidate
  772.     if suspendValidate begin
  773.       get object_validation to oldObjVal
  774.       set object_validation to FALSE
  775.     end
  776.     //
  777.     // forward the ITEM_CHANGE message to perform the inherited behavior
  778.     //
  779.     forward get msg_item_change from# to# to to#
  780.     //
  781.     // if validation qwazs suspended, restore it
  782.     //
  783.     if suspendValidate begin
  784.       set object_validation to oldObjVal
  785.  
  786.       //
  787.       // validate up to new current item
  788.       //
  789.       get base_item to base
  790.       if to# GT base begin
  791.         get validate_range base (to# - 1) to retVal
  792.         if retVal NE -1 move retVal to to#
  793.       end
  794.     end
  795.  
  796.     //
  797.     // return the destination item number
  798.     //
  799.     procedure_Return to#
  800.   end_procedure
  801.  
  802.   procedure scroll integer dir integer dist 
  803.     local integer oldObjVal oldObjEntEx ret_val
  804.  
  805.     if not (batch_state(current_object)) begin
  806.       if (exit_and_save(current_object,dir)) NE 0 procedure_return
  807.  
  808.       get object_item_entry_exit to oldObjEntEx
  809.       set object_item_entry_exit to FALSE
  810.       get object_validation to oldObjVal
  811.       set object_validation to FALSE
  812.     end
  813.  
  814.     //
  815.     // forward the scroll message
  816.     //
  817.     forward send scroll dir dist
  818.  
  819.     if not (batch_state(current_object)) begin
  820.       set object_validation to oldObjVal
  821.       set object_item_entry_exit to oldObjEntEx
  822.       //
  823.       // the validate and entry messages cannot inhibit movement because
  824.       // original row is gone
  825.       // 
  826.       if (validate_and_enter(current_object)) NE 0 procedure_return
  827.     end
  828.   end_procedure
  829.  
  830.   procedure beginning_of_data integer noSaveFlag
  831.     local integer oldObjVal oldObjEntEx ret_val
  832.  
  833.     if not (batch_state(current_object)) begin
  834.       if (item_count (current_object)) GT 0 begin
  835.         if ((NUM_ARGUMENTS > 0) AND noSaveFlag) begin
  836.           if (exec_exit(current_object,current_item(current_object))) NE 0 ;
  837.               procedure_return
  838.         end
  839.         else if (exit_and_save(current_object,UPWARD_DIRECTION) <> 0) ;
  840.             procedure_return
  841.       end
  842.  
  843.       get object_item_entry_exit to oldObjEntEx
  844.       set object_item_entry_exit to FALSE
  845.       get object_validation to oldObjVal
  846.       set object_validation to FALSE
  847.     end
  848.  
  849.     if NUM_ARGUMENTS GT 0 forward send beginning_of_data noSaveFlag
  850.     else forward send beginning_of_data
  851.  
  852.     if not (batch_state(current_object)) begin
  853.       set object_validation to oldObjVal
  854.       set object_item_entry_exit to oldObjEntEx
  855.       //
  856.       // the validate and entry messages cannot inhibit movement because
  857.       // original row is gone
  858.       // 
  859.       if (validate_and_enter(current_object)) NE 0 procedure_return
  860.     end
  861.   end_procedure
  862.  
  863.   procedure end_of_data
  864.     local integer oldObjVal oldObjEntEx ret_val
  865.  
  866.     if not (batch_state(current_object)) begin
  867.       if ((item_count(current_object) > 0) AND ;
  868.       (exit_and_save(current_object,DOWNWARD_DIRECTION) <> 0)) procedure_return
  869.  
  870.       get object_item_entry_exit to oldObjEntEx
  871.       set object_item_entry_exit to FALSE
  872.       get object_validation to oldObjVal
  873.       set object_validation to FALSE
  874.     end
  875.  
  876.     forward send end_of_data
  877.  
  878.     if not (batch_state(current_object)) begin
  879.       set object_validation to oldObjVal
  880.       set object_item_entry_exit to oldObjEntEx
  881.       //
  882.       // the validate and entry messages cannot inhibit movement because
  883.       // original row is gone
  884.       // 
  885.       if (validate_and_enter(current_object)) NE 0 procedure_return
  886.     end
  887.   end_procedure
  888.  
  889.   procedure entry_display integer file integer flag
  890.     if (flag eq 0 AND file eq 0) begin
  891.       is_file_included (main_file(current_object)) 1
  892.       [found] send assign_current_record
  893.     end
  894.     forward send entry_display file flag
  895.   end_procedure
  896.  
  897. end_class
  898.  
  899.