home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / vxcliser.zip / VXREXX.3 / SHARED / OBJECT.VRS
Text File  |  1994-12-23  |  27KB  |  809 lines

  1. /*:VRX         Object
  2. */
  3. Object: procedure expose Globals.
  4. return
  5.  
  6. /*
  7.     Object.VRS
  8.  
  9.     This file contains subroutines to help manage CUA '91 style views of objects.
  10.     There are two types of views to be considered, list views and individual views.
  11.     The list views are implemented by containers; the individual views by windows.
  12.     The routines in this file help to track the relationship between the views of
  13.     an object.  In particular, they ensure that objects in list views are marked
  14.     as in-use when the objects have individual views open, and that when a view is
  15.     already open an attempt to open it again displays the existing view rather
  16.     than opens a new view.
  17.  
  18.     Individual views are opened from list views, but in general the list views
  19.     can be closed without closing the individual views.  As a result, when a list
  20.     view is opened the some of the records in the view may need to be marked
  21.     as in-use.  Similarly, if the delta scroll feature of containers is used
  22.     records representing objects can scroll out of and back into a container
  23.     and must have their emphasis set dynamically.  More than one list view can
  24.     be open at a time (for example, a detail view and an icon view) so when an
  25.     individual view is opened or closed records in more than one container may
  26.     need to have their emphasis changed.
  27.  
  28.     In this implementation, objects are assumed to belong to groups and
  29.     to be identified by key values with in the group.  For example, the group
  30.     might correspond to a table in a database and the key values to the
  31.     primary key for the table.  It is assumed that a container displays information
  32.     from only one group.  The key for a record is either the record handle
  33.     or the values of fields within the container.  A record handle can only be
  34.     used in simple cases where the records in the container will not be
  35.     destroyed while a view is open, and only one list view can be opened.
  36.  
  37.     - External routines:
  38.         ObjectListOpened:       A list view has been opened.
  39.         ObjectListClosed:       A list view has been closed.
  40.         ObjectListChanged:      Records in a list view have changed.
  41.         ObjectListFindRecord:   Return the record that matches a specific
  42.                                 object.
  43.  
  44.         ObjectOpen:             Open an individual view.
  45.         ObjectClosed:           An individual view has been closed.
  46.         ObjectCloseAll:         Post close events to all individual views.
  47.         ObjectGetKeys:          Return the key value corresponding to an
  48.                                 individual view.
  49.  
  50.         ObjectRefresh:          Post refresh events to all views of an object.
  51.  
  52.     - Internal routines
  53.         Internal routines start with a double underscore and are not meant to be called
  54.         directly.  They generally assume the arguments have already been checked and are
  55.         in the correct format.
  56.  
  57.     - Global variables
  58.         - The code assumes that the global variables are initialized to 0 or to a non-numeric
  59.         value.
  60.  
  61.         - List of list views:
  62.             Globals.!__Objects.!Groups.0                Count.
  63.             Globals.!__Objects.!Groups.i.!Group         Group name.
  64.             Globals.!__Objects.!Groups.i.!Container     The internal name of the container.
  65.             Globals.!__Objects.!Groups.i.!KeyFields.0   Count.
  66.             Globals.!__Objects.!Groups.i.!KeyFields.j   The jth key field for this object.
  67.  
  68.             Note: A group name may appear more than once in the list, corresponding
  69.             to multiple list views.
  70.  
  71.         - List of open windows:
  72.             Globals.!__Objects.!Windows.0               Count.
  73.             Globals.!__Objects.!Windows.i.!Group        Group name ==> list views.
  74.             Globals.!__Objects.!Windows.i.!Keys.0       Count.
  75.             Globals.!__Objects.!Windows.i.!Keys.j       The value of the jth key for this object.
  76.             Globals.!__Objects.!Windows.i.!WindowName   The external name of the window.
  77.             Globals.!__Objects.!Windows.i.!Window       Internal name of the window.
  78.  
  79.             Note: Assume only ever one window of each type open per object, so the
  80.             !Window is a unique key as well as !Group + !Keys + !WindowName.
  81. */
  82. /*****************************************************************************
  83.     num = __ObjectCount( count )
  84.  
  85.     count           Possibly uninitialized count value.
  86.  
  87.     num             Count or 0
  88. *****************************************************************************/
  89. __ObjectCount: procedure
  90.  
  91.     parse arg count
  92.  
  93.     if DataType( count ) \= "NUM" then do
  94.         count = 0
  95.     end
  96.  
  97. return count
  98.  
  99.  
  100. /*****************************************************************************
  101.     keyFields.0 = <count>
  102.     keyFields.i = <ith key field>
  103.     ok = ObjectListOpened( group, container )
  104.  
  105.     group           The name of the group displayed in the list view (not case sensitive)
  106.     container       The name of the container.
  107.     keyFields.      A REXX array holding the key fields.
  108.  
  109.     ok              1 if OK; 0 if not.
  110.  
  111.     - Set keyFields.0 to 0 to use the container's record handles as keys.
  112.     - The keyFields.1 must be string type as this is assumed when searching the
  113.     container
  114.     - Use the same group name for all containers which are displaying
  115.     common objects.  All containers in a group must use the same
  116.     keyFields.
  117.     - Either ObjectListOpened after the container has been populated so
  118.     emphasis can be set on the records, or call ObjectListChanged after
  119.     adding the records.
  120. *****************************************************************************/
  121. ObjectListOpened: procedure expose Globals. keyFields.
  122. /*
  123.     say "ObjectListOpened"
  124.     trace r
  125. */
  126.     parse arg group, container
  127.  
  128.     /* Return value */
  129.     ok = 0
  130.  
  131.     /* Check arguments */
  132.     group = translate( group )
  133.  
  134.     if VRIsValidObject( container ) = 0 then signal ObjectListOpenedDone
  135.     container = VRGet( container, "Self" )
  136.  
  137.     if DataType( keyFields.0 ) \= "NUM" then signal ObjectListOpenedDone
  138.  
  139.     /* Record info */
  140.     count = __ObjectCount( Globals.!__Objects.!Groups.0 )
  141.     count = count + 1
  142.     Globals.!__Objects.!Groups.0 = count
  143.     Globals.!__Objects.!Groups.count.!Group = group
  144.     Globals.!__Objects.!Groups.count.!Container = container
  145.     do j = 0 to keyFields.0
  146.         Globals.!__Objects.!Groups.count.!KeyFields.j = keyFields.j
  147.     end
  148.  
  149.     call ObjectListChanged container
  150.  
  151.     ok = 1
  152.  
  153. ObjectListOpenedDone:
  154. return ok
  155.  
  156. /*****************************************************************************
  157.     index = __ObjectFindGroup( container )
  158.  
  159.     container       The internal name of the container.
  160.  
  161.     index           The index of the container in the group list, or 0.
  162. *****************************************************************************/
  163. __ObjectFindGroup: procedure expose Globals.
  164.  
  165.     parse arg container
  166.  
  167.     count = Globals.!__Objects.!Groups.0
  168.     index = 0
  169.     do i = 1 to count
  170.         if Globals.!__Objects.!Groups.i.!Container = container then do
  171.             index = i
  172.             leave
  173.         end
  174.     end
  175. return index
  176.  
  177.  
  178. /*****************************************************************************
  179.     ok = ObjectListClosed( container )
  180.  
  181.     container       The name of the container.
  182.  
  183.     ok              1 if OK; 0 if not.
  184.  
  185.     - If the container no longer exists the name passed must be the internal
  186.      name.
  187. *****************************************************************************/
  188. ObjectListClosed: procedure expose Globals.
  189. /* 
  190.     say "ObjectListClosed"
  191.     trace r
  192. */
  193.     parse arg container
  194.  
  195.     /* Return value */
  196.     ok = 0
  197.  
  198.     /* Check argument */
  199.     if VRIsValidObject( container ) then do
  200.         container = VRGet( container, "Self" )
  201.     end
  202.  
  203.     /* Unrecord info */
  204.     index = __ObjectFindGroup( container )
  205.     if index = 0 then signal ObjectListClosedDone
  206.     
  207.     count = Globals.!__Objects.!Groups.0
  208.     Globals.!__Objects.!Groups.0 = count - 1
  209.     do i = index to count - 1
  210.         j = i + 1
  211.         Globals.!__Objects.!Groups.i.!Group = Globals.!__Objects.!Groups.j.!Group
  212.         Globals.!__Objects.!Groups.i.!Container = Globals.!__Objects.!Groups.j.!Container
  213.         keyCount = Globals.!__Objects.!Groups.j.!KeyFields.0
  214.         do k = 0 to keyCount
  215.             Globals.!__Objects.!Groups.i.!KeyFields.k = Globals.!__Objects.!Groups.j.!KeyFields.k
  216.         end
  217.     end
  218.  
  219.     drop Globals.!__Objects.!Groups.count.!Group
  220.     drop Globals.!__Objects.!Groups.count.!Container
  221.     keyCount = Globals.!__Objects.!Groups.count.!KeyFields.0
  222.     do k = 0 to keyCount
  223.         drop Globals.!__Objects.!Groups.count.!KeyFields.k
  224.     end
  225.  
  226.     ok = 1
  227.  
  228. ObjectListClosedDone:
  229. return ok
  230.  
  231.  
  232. /*****************************************************************************
  233.     call __ObjectListGetKeys groupIndex, record
  234.  
  235.     groupIndex      The index of the container.
  236.     record          The current record.
  237.  
  238.     keys.           A REXX array holding the keys for the current record.
  239. *****************************************************************************/
  240. __ObjectListGetKeys: procedure expose Globals. keys.
  241.  
  242.     parse arg groupIndex, record
  243.  
  244.     /* Return value */
  245.     keys.0 = 1
  246.     keys.1 = record
  247.  
  248.     /* Fetch keys */
  249.     container = Globals.!__Objects.!Groups.groupIndex.!Container
  250.  
  251.     keyCount = Globals.!__Objects.!Groups.groupIndex.!KeyFields.0
  252.     if keyCount = 0 then signal __ObjectListGetKeysDone
  253.  
  254.     do i = 1 to keyCount
  255.         keyCol = Globals.!__Objects.!Groups.groupIndex.!KeyFields.i
  256.         keys.i = VRMethod( container, "GetFieldData", record, keyCol )
  257.     end
  258.     keys.0 = keyCount
  259.  
  260. __ObjectListGetKeysDone:
  261. return
  262.  
  263.  
  264. /*****************************************************************************
  265.     keys.0 = count
  266.     keys.i = ith key
  267.     record = __ObjectFindRecord( groupIndex )
  268.  
  269.     groupIndex      The index of the container.
  270.     targetKeys.     The object to match.
  271.  
  272.     record          The matching record or ""
  273. *****************************************************************************/
  274. __ObjectFindRecord: procedure expose Globals. targetKeys.
  275.  
  276.     parse arg groupIndex
  277.  
  278.     /* Return value */
  279.     record = ""
  280.  
  281.     /* Search for record with matching keys 
  282.  
  283.        NOTE: The first key must be a string type for that is all
  284.        the container FindRecord method handles.
  285.     */
  286.     container = Globals.!__Objects.!Groups.groupIndex.!Container
  287.  
  288.     keyCount = Globals.!__Objects.!Groups.groupIndex.!KeyFields.0
  289.     target = targetKeys.1
  290.  
  291.     if keyCount = 0 then do
  292.         if VRMethod( container, "ValidateRecord", target ) then do
  293.             record = target
  294.         end
  295.         signal __ObjectFindRecordDone
  296.     end
  297.  
  298.     record = "First"
  299.     do forever
  300.         record = VRMethod( container, "FindRecord", target, "Detail", record, "Case" )
  301.         if record = "" then signal __ObjectFindRecordDone
  302.         call __ObjectListGetKeys groupIndex, record
  303.         match = 1
  304.         do j = 0 to targetKeys.0
  305.             if keys.j \= targetKeys.j then do
  306.                 match = 0
  307.                 leave
  308.             end
  309.         end 
  310.         if match = 1 then leave
  311.     end
  312. __ObjectFindRecordDone:
  313. return record
  314.  
  315. /*****************************************************************************
  316.     ok = __ObjectSetInUse( groupIndex, windowIndex, onOff )
  317.  
  318.     groupIndex      Index of the container
  319.     windowIndex     Index of the window
  320.     onOff           1 for on; 0 for off.
  321.  
  322.     ok              1 for ok; 0 for not ok.
  323. *****************************************************************************/
  324. __ObjectSetInUse: procedure expose Globals.
  325.  
  326.     parse arg groupIndex, windowIndex, onOff
  327.  
  328.     keyCount = Globals.!__Objects.!Windows.windowIndex.!Keys.0
  329.     do i = 0 to keyCount
  330.         targetKeys.i = Globals.!__Objects.!Windows.windowIndex.!Keys.i
  331.     end
  332.  
  333.     targetKeys.0 = keyCount
  334.     record = __ObjectFindRecord( groupIndex )
  335.     if record = "" then signal __ObjectSetInUseDone
  336.  
  337.     container = Globals.!__Objects.!Groups.groupIndex.!Container
  338.     call VRMethod container, "SetRecordAttr", record, "InUse", onOff
  339.  
  340. __ObjectSetInUseDone:
  341. return record
  342.  
  343.  
  344. /*****************************************************************************
  345.     ok = ObjectListChanged( container )
  346.  
  347.     container       The name of the container.
  348.  
  349.     ok              1 if OK; 0 if not.
  350.  
  351.     - Call after adding records to a container to have their
  352.     emphasis set.
  353. *****************************************************************************/
  354. ObjectListChanged: procedure expose Globals.
  355. /*
  356.     say "ObjectListChanged"
  357.     trace r
  358. */
  359.     parse arg container
  360.  
  361.     /* Return value */
  362.     ok = 0
  363.  
  364.     /* Check arguments */
  365.     if VRIsValidObject( container ) = 0 then signal ObjectListChangedDone
  366.     container = VRGet( container, "Self" )
  367.  
  368.     /* Update hatching */
  369.     index = __ObjectFindGroup( container )
  370.     if index = 0 then signal ObjectListChangedDone
  371.  
  372.     group = Globals.!__Objects.!Groups.index.!Group
  373.  
  374.     count = __ObjectCount( Globals.!__Objects.!Windows.0 )
  375.     do i = 1 to count
  376.         if Globals.!__Objects.!Windows.i.!Group = group then do
  377.             call __ObjectSetInUse index, i, 1
  378.         end
  379.     end
  380.  
  381. ObjectListChangedDone:
  382. return ok
  383.  
  384. /*****************************************************************************
  385.     keys.0 = count
  386.     keys.i = ith key value
  387.     record = ObjectListFindRecord( container )
  388.  
  389.     container       The name of the container.
  390.     keys            The key value for the object to find
  391.  
  392. *****************************************************************************/
  393. ObjectListFindRecord: procedure expose Globals. keys.
  394. /*
  395.     say "ObjectListFindRecord"
  396.     trace r
  397. */
  398.     parse arg container
  399.  
  400.     /* Return value */
  401.     record = ""
  402.  
  403.     /* Check arguments */
  404.     if VRIsValidObject( container ) = 0 then signal ObjectListFindRecordDone
  405.     container = VRGet( container, "Self" )
  406.  
  407.     /* Find the group */
  408.     index = __ObjectFindGroup( container )
  409.     if index = 0 then signal ObjectListFindRecordDone
  410.  
  411.     /* Find the record */
  412.     keyCount = keys.0
  413.     do i = 0 to keyCount
  414.         targetKeys.i = keys.i
  415.     end
  416.  
  417.     record = __ObjectFindRecord( index )
  418.  
  419. ObjectListFindRecordDone:
  420. return record
  421.  
  422.  
  423. /*****************************************************************************
  424.     index = __ObjectFindWindow( group, windowName, start )
  425.  
  426.     group               The object's group
  427.     windowName          The name of the window (upper case), or ""
  428.     start               The start index
  429.     keys.               The list of key values.
  430.  
  431.     index               The index of the window or 0.
  432. *****************************************************************************/
  433. __ObjectFindWindow: procedure expose Globals. keys.
  434.  
  435.     parse arg group, windowName, start
  436.  
  437.     index = 0
  438.  
  439.     count = __ObjectCount( Globals.!__Objects.!Windows.0 )
  440.     if count = 0 then signal __ObjectFindWindowDone
  441.  
  442.     do i = start to count
  443.         if Globals.!__Objects.!Windows.i.!Group \= group then iterate i
  444.         do j = 1 to keys.0
  445.             if Globals.!__Objects.!Windows.i.!Keys.j \= keys.j then iterate i
  446.         end 
  447.         if windowName \= "" then do
  448.             if Globals.!__Objects.!Windows.i.!WindowName \= WindowName then iterate i
  449.         end
  450.  
  451.         /* Found match */
  452.         index = i
  453.         leave
  454.     end 
  455.  
  456. __ObjectFindWindowDone:
  457.  
  458. return index
  459.  
  460.  
  461. /*****************************************************************************
  462.     index = __ObjectFindWindowFromHandle( window )
  463.  
  464.     window              The name of the window (upper case)
  465.  
  466.     index               The index of the window or 0.
  467. *****************************************************************************/
  468. __ObjectFindWindowFromHandle: procedure expose Globals.
  469.     parse arg window
  470.  
  471.     index = 0
  472.  
  473.     count = Globals.!__Objects.!Windows.0
  474.     if count = 0 then signal __ObjectFindWindowFromHandleDone
  475.  
  476.     do i = 1 to count
  477.         if Globals.!__Objects.!Windows.i.!Window \= window then iterate i
  478.  
  479.         /* Found match */
  480.         index = i
  481.         leave
  482.     end
  483.  
  484. __ObjectFindWindowFromHandleDone:
  485.  
  486. return index
  487.  
  488.  
  489. /*****************************************************************************
  490.     window = ObjectOpen( container, record, windowName )
  491.  
  492.     container       The name of the container holding "record".
  493.     record          The handle of the record representing the object.
  494.     windowName      The external name of the secondary window to open.
  495.  
  496.     window          The internal name of the window opened.
  497.  
  498.     - ObjectOpen opens a window to view the object associated with the specified
  499.     record.
  500.  
  501.     - Reopening an open view activates the currently open window rather then
  502.     creating a new one.
  503.  
  504.     - You must call ObjectClosed when the window is closed so the list
  505.     of windows open for the object can be updated.
  506. *****************************************************************************/
  507.  
  508. ObjectOpen: procedure expose Globals.
  509. /*
  510.     say "ObjectOpen"
  511.     trace r
  512. */
  513.     parse arg container, record, windowName
  514.  
  515.     /* Return value */
  516.     window = ""
  517.  
  518.     /* Check arguments */
  519.     if VRIsValidObject( container ) = 0 then signal ObjectOpenDone
  520.     container = VRGet( container, "Self" )
  521.  
  522.     groupIndex = __ObjectFindGroup( container )
  523.     if groupIndex = 0 then signal ObjectOpenDone
  524.     group = Globals.!__Objects.!Groups.groupIndex.!Group
  525.  
  526.     if VRMethod( container, "ValidateRecord", record ) = 0 then signal ObjectOpenDone
  527.  
  528.     windowName = translate( windowName )
  529.  
  530.     call __ObjectListGetKeys groupIndex, record
  531.  
  532.     /* If the view is already open on the object just activate it */
  533.  
  534.     i = __ObjectFindWindow( group, windowName, 1 )
  535.     if i \= 0 then do
  536.         window = Globals.!__Objects.!Windows.i.!window
  537.         windowState = VRGet( window, "WindowState" )
  538.         if windowState = "Minimized" then do
  539.             call VRSet window, "WindowState", "Normal"
  540.         end
  541.         call VRSet window, "Visible", 1
  542.         call VRMethod window, "Activate"
  543.         signal ObjectOpenDone
  544.     end
  545.  
  546.     /* The view is not open so open and record it. */
  547.  
  548.     window = VRLoadSecondary( windowName )
  549.     if window = "" then signal ObjectOpenDone
  550.  
  551.     count = __ObjectCount( Globals.!__Objects.!Windows.0 )
  552.     count = count + 1
  553.  
  554.     Globals.!__Objects.!Windows.0 = count
  555.     Globals.!__Objects.!Windows.count.!Group = group
  556.     do j = 0 to keys.0
  557.         Globals.!__Objects.!Windows.count.!Keys.j = keys.j
  558.     end
  559.     Globals.!__Objects.!Windows.count.!WindowName = windowName
  560.     Globals.!__Objects.!Windows.count.!Window = window
  561.  
  562.     /* Hatch icons */
  563.     windowIndex = count
  564.     count = __ObjectCount( Globals.!__Objects.!Groups.0 )
  565.     do i = 1 to count
  566.         if Globals.!__Objects.!Groups.i.!Group = group then do
  567.             call __ObjectSetInUse i, windowIndex, 1 
  568.         end
  569.     end
  570.  
  571. ObjectOpenDone:
  572. return window
  573.  
  574.  
  575. /*****************************************************************************
  576.     ok = ObjectClosed( window )
  577.  
  578.     window      The internal name of the window that was closed.
  579.  
  580.     ok          1 if OK; 0 if not.
  581.  
  582.     - Update the object open window list and the corresponding container record's
  583.     state.
  584. *****************************************************************************/
  585.  
  586. ObjectClosed: procedure expose Globals.
  587. /*
  588.     say "ObjectClosed"
  589.     trace r
  590. */
  591.     parse arg window
  592.  
  593.     /* Return value */
  594.     closed = 0
  595.  
  596.     /* Check arguments */
  597.     index = __ObjectFindWindowFromHandle( window )
  598.     if index = 0 then signal ObjectClosedDone
  599.  
  600.     /* Unhatch icons if no other view open */
  601.  
  602.     group = Globals.!__Objects.!Windows.index.!Group
  603.  
  604.     keyCount = Globals.!__Objects.!Windows.index.!Keys.0
  605.     do k = 0 to keyCount
  606.         keys.k = Globals.!__Objects.!Windows.index.!Keys.k
  607.     end
  608.  
  609.     otherIndex = 0
  610.     do forever
  611.         otherIndex = __ObjectFindWindow( group, "", otherIndex+1 )
  612.         if otherIndex = 0 then leave                /* No other window */
  613.         if otherIndex \= index then leave           /* Found a different window */
  614.     end
  615.     if otherIndex = 0 then do
  616.         count = Globals.!__Objects.!Groups.0
  617.         do i = 1 to count
  618.             if Globals.!__Objects.!Groups.i.!Group = group then do
  619.                 call __ObjectSetInUse i, index, 0 
  620.             end
  621.         end
  622.     end
  623.     
  624.     /* Unrecord window */
  625.     count = Globals.!__Objects.!Windows.0
  626.     Globals.!__Objects.!Windows.0 = count - 1
  627.     do i = index to count - 1
  628.         j = i + 1
  629.         Globals.!__Objects.!Windows.i.!Group = Globals.!__Objects.!Windows.j.!Group
  630.         keyCount = Globals.!__Objects.!Windows.j.!Keys.0
  631.         do k = 0 to keyCount
  632.             Globals.!__Objects.!Windows.i.!Keys.k = Globals.!__Objects.!Windows.j.!Keys.k
  633.         end
  634.         Globals.!__Objects.!Windows.i.!WindowName = Globals.!__Objects.!Windows.j.!WindowName
  635.         Globals.!__Objects.!Windows.i.!Window = Globals.!__Objects.!Windows.j.!Window
  636.     end
  637.  
  638.     drop Globals.!__Objects.!Windows.count.!Group
  639.     keyCount = Globals.!__Objects.!Windows.count.!Keys.0
  640.     do k = 0 to keyCount
  641.         drop Globals.!__Objects.!Windows.count.!Keys.k
  642.     end
  643.     drop Globals.!__Objects.!Windows.count.!WindowName
  644.     drop Globals.!__Objects.!Windows.count.!Window
  645.  
  646.     closed = 1
  647.  
  648. ObjectClosedDone:
  649. return closed
  650.  
  651. /*****************************************************************************
  652.     ok = ObjectCloseAll( container, record )
  653.  
  654.     container       The name of the container.
  655.     record          The handle of the record corresponding to the object.
  656.  
  657.     ok              1 if OK; 0 if not.
  658.  
  659.     - Close all the opened windows of an object.
  660. *****************************************************************************/
  661.  
  662. ObjectCloseAll: procedure expose Globals.
  663. /*
  664.     say "ObjectCloseAll"
  665.     trace r
  666. */
  667.     parse arg container, record
  668.  
  669.     /* Return value */
  670.     closed = 0
  671.  
  672.     /* Check arguments, set container & keys */
  673.     if VRIsValidObject( container ) = 0 then signal ObjectCloseAllDone
  674.     container = VRGet( container, "Self" )
  675.  
  676.     groupIndex = __ObjectFindGroup( container )
  677.     group = Globals.__Objects.!Groups.groupIndex.!Group
  678.  
  679.     if VRMethod( container, "ValidateRecord", record ) = 0 then signal ObjectCloseAllDone
  680.     call __ObjectListGetKeys groupIndex, record
  681.  
  682.     /* Post close events to all matching windows */
  683.  
  684.     count = __ObjectCount( Globals.!__Objects.!Windows.0 )
  685.     do i = 1 to count
  686.         if Globals.!__Objects.!Windows.i.!Group \= group then iterate i
  687.         do j = 0 to keys.0
  688.             if Globals.!__Objects.!Windows.i.!Keys.j \= keys.j then iterate i
  689.         end 
  690.  
  691.         /* Found match */
  692.         window = Globals.!__Objects.!Windows.i.!Window
  693.         call VRMethod window, "PostEvent", "Close" 
  694.     end
  695.  
  696.     closed = 1
  697.  
  698. ObjectCloseAllDone:
  699. return closed
  700.  
  701. /*****************************************************************************
  702.     call ObjectGetKeys window
  703.  
  704.     window          The internal name of the individual view window.
  705.  
  706.     keys.           The key values for that window.
  707. *****************************************************************************/
  708.  
  709. ObjectGetKeys: procedure expose Globals. keys.
  710. /*
  711.     say "ObjectGetKeys"
  712.     trace r
  713. */
  714.     parse arg window
  715.  
  716.     /* Return value */
  717.     keys.0 = 0
  718.  
  719.     /* Check arguments */
  720.     index = __ObjectFindWindowFromHandle( window )
  721.     if index = 0 then signal ObjectGetKeysDone
  722.  
  723.     keyCount = Globals.!__Objects.!Windows.index.!Keys.0
  724.     do k = 0 to keyCount
  725.         keys.k = Globals.!__Objects.!Windows.index.!Keys.k
  726.     end
  727. ObjectGetKeysDone:
  728. return
  729.  
  730.  
  731. /*****************************************************************************
  732.  
  733.  
  734.     keys.0 = count
  735.     keys.i = ith key
  736.     call ObjectRefresh group, type
  737.  
  738.     keys.           An object identifier.
  739.     group           The group to refresh
  740.     type            The type of refresh to perform, passed as event info.
  741.  
  742.     ok              1 if OK; 0 it not.
  743.  
  744.     - Generates a "Refresh" event to all list views and all matching individual
  745.     views.
  746.  
  747.     - The following VRInfo is available:
  748.  
  749.         Object      The internal name of the object receiving the post
  750.         Window      The internal name of the object's parent window
  751.         Event       "Refresh"
  752.         Type        The value of the type parameter.
  753.  
  754.     - The refresh routines are called via a post rather than a call
  755.     so that the current object will be set correctly in case 
  756.     multiple instances of the object are loaded.
  757.  
  758. *****************************************************************************/
  759.  
  760. ObjectRefresh: procedure expose Globals. keys.
  761. /*
  762.     Say "ObjectRefresh"
  763.     trace r
  764. */
  765.     parse arg group, type
  766.  
  767.     group = translate( group )
  768.  
  769.     /* Post to all containers */
  770.  
  771.     count = __ObjectCount( Globals.!__Objects.!Groups.0 )
  772.     do i = 1 to count
  773.         if Globals.!__Objects.!Groups.i.!Group \= group then iterate i
  774.  
  775.         /* Found match */
  776.         container = Globals.!__Objects.!Groups.i.!Container
  777.  
  778.         containerName = VRGet( container, "Name" )
  779.         eventString = "Call " || containerName || "_Refresh"
  780.         call VRMethod "Application", "PostQueue", 0, 1, eventString,,
  781.                         "Object", container,,
  782.                         "Event", "Refresh",,
  783.                         "Type", type 
  784.     end
  785.  
  786.     /* Post to all matching windows */
  787.  
  788.     count = __ObjectCount( Globals.!__Objects.!Windows.0 )
  789.     do i = 1 to count
  790.         if Globals.!__Objects.!Windows.i.!Group \= group then iterate i
  791.         do j = 1 to keys.0
  792.             if Globals.!__Objects.!Windows.i.!Keys.j \= keys.j then iterate i
  793.         end 
  794.  
  795.         /* Found match */
  796.         window = Globals.!__Objects.!Windows.i.!window
  797.  
  798.         windowName = Globals.!__Objects.!Windows.i.!WindowName
  799.         eventString = "Call " || windowName || "_Refresh"
  800.         call VRMethod "Application", "PostQueue", 0, 1, eventString,,
  801.                         "Object", container,,
  802.                         "Event", "Refresh",,
  803.                         "Type", type 
  804.     end
  805.  
  806. return 
  807.  
  808.  
  809.