Compile function NDW_GAN_RETAIN_MANAGER_DEV_EVENTS(CtrlEntId, Event, @PARAMS)
/***********************************************************************************************************************

    Name        :   NDW_GAN_RETAIN_MANAGER_DEV_EVENTS

    Description :   Commuter module for the NDW_GAN_RETAIN_MANAGER form.

    Notes       :   Application errors should be logged using the Error Services module. There are a few methodological
                    assumptions built into way errors are managed which are important to understand in order to properly
                    work with Error Services:

                    - The term 'top' refers to the originating procedure of a call stack and the term 'bottom' refers to
                      the last routine (or the current routine) within a call stack. Within the OpenInsight Debugger
                      this will appear backwards since the originating procedure always appears at the bottom of the
                      list and the current routine appears at the top of the list. We are using this orientation because
                      it is common to refer to the process of calling other procedures as 'drilling down'.

                    - The reason for defining the orientation of the call stack is because Error_Services allows for
                      multiple error conditions to be appended to an original error. In most cases this will happen when
                      a procedure at the bottom of the stack generates an error condition and then returns to its
                      calling procedure. This higher level procedure can optionally add more information relevant to
                      itself. This continues as the call stack 'bubbles' its way back to the top to where the
                      originating procedure is waiting.

                    - Native OpenInsight commands that handle errors (e.g., Set_Status, Set_FSError, Set_EventStatus)
                      preserve their error state until explicitly cleared. This can hinder the normal execution of code
                      since subsequent procedures (usually SSPs) will fail if a pre-existing error condition exists.
                      Our philosophy is that error conditions should automatically be cleared before a new procedure
                      is executed to avoid this problem. However, the nature of Basic+ does not make this easy to
                      automate for any given stored procedure. Therefore, if a stored procedure wants to conform to our
                      philosophy then it should include a call into the 'Clear' service request at the top of the
                      program. Alternatively this can be done through a common insert (see SERVICE_SETUP for example.)

                    - Service modules will use the SERVICE_SETUP insert and therefore automatically clear out any
                      error conditions that were set before.

    Parameters  :
        Service         [in] -- Name of the service being requested
        Param1-10   [in/out] -- Additional request parameter holders
        Response       [out] -- Response to be sent back to the Controller (MCP) or requesting procedure

    Metadata    :

    History     :   (Date, Initials, Notes)
        03/11/20    djs     Original programmer. 

***********************************************************************************************************************/
#pragma precomp SRP_PreCompiler
#window NDW_GAN_RETAIN_MANAGER_DEV

$Insert LOGICAL
$Insert APPCOLORS
$Insert RETAINED_WAFERS_EQUATES

// OLE Edit Table Columns
Equ RUN_ID$      To  1
Equ RECIPE$      To  2
Equ POCKET$      To  3
Equ SCRIBE$      To  4
Equ GRADE$       To  5
Equ PART$        To  6
Equ WO_NO$       To  7
Equ RETAIN_BOX$  To  8
Equ RETAIN_SLOT$ To  9
Equ OPERATOR$    To 10
Equ RETAIN_DATE$ To 11
Equ RETAIN_LOC$  To 12
Equ STATUS$      To 13
Equ COMMENT$     To 14

// Reduce modes (for Select statement)
Equ NEW_EXIST$ To 0 
Equ NEXT_CUR$  To 1
Equ ADD_EXIST$ To 2

Declare Function   Form_Services, Get_Property, Utility, Database_Services, Error_Services
Declare Subroutine SRP_Show_Window, Set_Property, Send_Message, Post_Event, Reduce, FSMsg, Btree.Extract
Declare Subroutine SRP_Stopwatch

SubclassInfo    = Form_Services('FindSubclassControl')
Subclass        = SubclassInfo<1>

If Assigned(Param8) else Param8 = ''

// Update the arguments so that the OpenInsight OLE event will treate the ActiveX event as a native event handler.
If Event EQ 'OLE' then
    Transfer Event to OIEvent
    Transfer Param1 to Event
    Transfer Param2 to Param1
    Transfer Param3 to Param2
    Transfer Param4 to Param3
    Transfer Param5 to Param4
    Transfer Param6 to Param5
    Transfer Param7 to Param6
    Transfer Param8 to Param7
end

GoToEvent Event for CtrlEntId else
    // Event not implemented
end

Return EventFlow or 1

//-----------------------------------------------------------------------------
// EVENT HANDLERS
//-----------------------------------------------------------------------------

Event WINDOW.CREATE(CreateParam)
    
    GoSub SetupOLEControls
    GoSub FillSearchEDT
*    GoSub FillRetainedEDT
*    GoSub FillDestroyedEDT
    SRP_Show_Window(@Window, '', 'C', 'C', 1, '', False$, False$, '', 1)
    
End Event


Event OLE_EDT_SEARCH.OnHeaderClick(Cell, Point, Button, Shift, Ctrl)
    
    Begin Case
        Case Button EQ 'Left'
            // Present filter options
            FilterVisible = Get_Property(@Window:'.OLE_TRE_FILTER', 'VISIBLE')
            
            If FilterVisible EQ True$ then
                Set_Property(@Window:'.OLE_TRE_FILTER', 'VISIBLE', False$)
            end else
                
                Filter              = Get_Property(CtrlEntID, 'HeaderText[':Cell:']')
                CtrlEntIDSize       = Get_Property(CtrlEntID, 'SIZE')
                xPos                = Field(Point, ',', 1)
                TreeFilterSize      = Get_Property(@Window:'.OLE_TRE_FILTER', 'SIZE')
                TreeFilterSize<1>   = xPos
                TreeFilterSize<2>   = CtrlEntIDSize<2> + 20; // Place the tree filter 20 px below the top y position of the edit table
                Set_Property(@Window:'.OLE_TRE_FILTER', 'SIZE', TreeFilterSize)
                
                Begin Case
                    Case Filter _EQC 'Scribe'
                        FilterOptions   = '1234'    : @FM
                        FilterOptions  := '1235'    : @FM
                        FilterOptions  := '1236'    : @FM
                        FilterOptions  := '1237'    : @FM
                        FilterOptions  := '1238'
                        
                    Case Filter _EQC 'Recipe'
                        FilterOptions   = 'Example 1'  : @FM
                        FilterOptions  := 'Example 2'
                        
                    Case Filter _EQC 'Pocket'
                        FilterOptions   = '01' : @FM
                        FilterOptions  := '02' : @FM
                        FilterOptions  := '03' : @FM
                        FilterOptions  := '04' : @FM
                        FilterOptions  := '05' : @FM
                        FilterOptions  := '06' : @FM
                        FilterOptions  := '07' : @FM
                        FilterOptions  := '08'
                        
                    Case Filter _EQC 'Grade'
                        FilterOptions   = 'Prod'     : @FM
                        FilterOptions  := 'Scrap'
                        
                    Case Otherwise$
                        FilterOptions   = ''
                End Case
                
                Ctrl        = @Window : '.OLE_TRE_FILTER'
                ItemList    = ''
                For Each FilterOption in FilterOptions using @FM
                    ItemList   := 1 : @VM : FilterOption : @VM : FilterOption : @VM : @VM : @VM : @VM : @VM : @VM : @VM : @VM : 'Left' : @FM
                Next FilterOption
                ItemList[-1, 1] = ''
                Set_Property(Ctrl, 'OLE.ItemList', ItemList)
                Set_Property(Ctrl, 'OLE.ItemChecked[All]', True$)
                Post_Event(Ctrl, 'OLE', 'OnItemCheck')
                Set_Property(@Window:'.OLE_TRE_FILTER', 'VISIBLE', True$)
            end
            
        Case Button EQ 'Right'
            // Present sort options
    End Case
end event



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Internal GoSubs
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


SetupOLEControls:
    
    SearchCtrl     = @Window:'.OLE_EDT_SEARCH'
    NumSearchCols  = 14
    NumSearchRows  = 50   
    SearchCtrlList = '' 
    
    HeaderFontArray  = 'Segoe UI':@SVM:8:@SVM:700
    SearchDimArray   = NumSearchCols :@FM: NumSearchRows
    
    Set_Property(SearchCtrl, "OLE.CellFont[All; All]", 'Segoe UI':@SVM:8)
    Set_Property(SearchCtrl, "OLE.Dimension", SearchDimArray)
    Set_Property(SearchCtrl, "OLE.CellFont[1;All]", HeaderFontArray)
    Set_Property(SearchCtrl, "OLE.LIST", SearchCtrlList)
    Set_Property(SearchCtrl, "OLE.HeaderFont[All; 1]", HeaderFontArray)
    Set_Property(SearchCtrl, "OLE.HeaderFont[1; All]", HeaderFontArray)
    
    HeaderTitles  = 'Run ID':@VM:'Recipe':@VM:'Pocket':@VM:'Scribe':@VM:'Grade':@VM
    HeaderTitles := 'Part':@VM:'Work Order':@VM:'Retain Box':@VM:'Slot':@VM:'Operator':@VM
    HeaderTitles := 'Retain Date':@VM:'Location':@VM:'Status':@VM:'Comment'
    Set_Property(SearchCtrl, "OLE.TitleList", HeaderTitles)
    Set_Property(SearchCtrl, "OLE.HeaderAlignment[All; 1]", 'C':@FM:'C':@FM:'L')
    Set_Property(SearchCtrl, "OLE.CellAlignment[All; All]", 'C':@FM:'C':@FM:'L')
    Set_Property(SearchCtrl, "OLE.CellAlignment[1; All]", 'C':@FM:'L':@FM:'L')
    Set_Property(SearchCtrl, "OLE.AllowDeletions", False$)
    Set_Property(SearchCtrl, "OLE.AllowInserts", False$)
    
    // Set default header colors
    HeaderColorArray    = ''
    HeaderColorArray<1> = 'Auto'
    HeaderColorArray<2> = 'None'
    HeaderColorArray<3> = 'None'
    HeaderColorArray<4> = OI_HOT_BLUE$
    HeaderColorArray<5> = False$
    Set_Property(SearchCtrl, "OLE.HeaderColors[All; All]", HeaderColorArray)
    
    // Qualify OLE events that we want to intercept
    Qualifier       = ''
    Qualifier<1>    = 1
    Qualifier<4>    = 0 ; * process synchronously (i.e. immediately)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.OnClick',             Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.OnButtonClick',       Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.OnContextMenuClick',  Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.PosChanged',          Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.OnComboClicked',      Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.OnHeaderClick',       Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.OnCheckChanged',      Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.AfterUpdate',         Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.OnContextMenuClick',  Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.OnDblClick',          Qualifier)
    
    CellTypeArray        = ""
    CellTypeArray<1>     = "Combo"
    CellTypeArray<2, 1>  = ""
    CellTypeArray<2, 2>  = "L"
    CellTypeArray<2, 3>  = ''
    CellTypeArray<2, 4>  = 1                         ;// Column 1 contains the values we care about
    CellTypeArray<2, 5>  = 1                         ;// Auto fill on
    CellTypeArray<2, 6>  = 0                         ;// Case sensitive on
    CellTypeArray<2, 7>  = 10                        ;// 10 visible rows max
    CellTypeArray<2, 8>  = 0                         ;// Don't fire the OnOptionClick
    CellTypeArray<2, 9>  = 1                         ;// Reduce the list to partial matches
    CellTypeArray<2, 10> = 0                         ;// Only show the drop down when the user types
    CellTypeArray<2, 11> = 0                         ;// Do not use LIST Format
    CellTypeArray<2, 12> = 1                         ;// Autofill on Tool ID name
    CellTypeArray<2, 13> = 1                         ;// Hide dropdown when user clears cell
    CellTypeArray<2, 14> = 0                         ;// Let navigation keys show the drop down
    CellTypeArray<2, 15> = 0                         ;// Show the drop down regardless of the cell's contents
    CellTypeArray<2, 16> = 0                         ;// Show the drop down during autofill
    CellTypeArray<2, 17> = 1                         ;// Remove selection when user backspaces/deletes
    CellTypeArray<2, 18> = 0                         ;// Show Popup while in read only mode
    CellTypeArray<2, 19> = 1                         ;// Show Popup When Navigating
    CellTypeArray<2, 20> = 1                         ;// Always Tab Out on Enter
    CellTypeArray<2, 21> = -1                        ;// Always show the dropdown above when close to the screen bottom
    CellTypeArray<2, 23> = 1                         ;// Limit possible values to those in dropdown
    // Store this for later use elsewhere   
    Set_Property(@Window, '@COMBOBOX', CellTypeArray)
    
    // Cell selection style setup
    Set_Property(SearchCtrl,  "OLE.ResetSelPos", False$)  ;// Prevent cell selection from being reset upon lost focus event
    ReactorSelStyleArray    = Get_Property(SearchCtrl, "OLE.SelectionStyle")
    ReactorSelStyleArray<8> = True$
    Set_Property(SearchCtrl,  'OLE.SelectionStyle', ReactorSelStyleArray)
    
    CellSelStyleArray    = ''
    CellSelStyleArray<1> = 'White'                      ;// Selected cell foreground color
    CellSelStyleArray<2> = OI_BLUE$                     ;// Selected cell background color
    CellSelStyleArray<3> = 'None'                       ;// Selected record (row) foreground color - none = default
    CellSelStyleArray<4> = OI_HOT_BLUE$                 ;// Selected record (row) background color
    CellSelStyleArray<5> = 'None'                       ;// Selected field (column) foreground color - none = default
    CellSelStyleArray<6> = OI_HOT_BLUE$                 ;// Selected field (column) background color
    Set_Property(SearchCtrl,  'OLE.CellSelColors[2; All]', CellSelStyleArray)
    
    Set_Property(SearchCtrl, "OLE.HeaderArrow[All; 1]", 'Down')
    
    //////////////////////////////////// Code below here only runs once //////////////////////////////////////////
    
    FirstPassComp = Get_Property(@Window, '@FIRSTPASS')
    
    If FirstPassComp EQ '' or FirstPassComp EQ False$ then
        Set_Property(@Window, '@FIRSTPASS', True$)
        
        //////////////////////////////////// Setup Disposition OLE Edit Table //////////////////////////////////////////        
        
        // Disable resizing of the header row
        // Hide the header column
        HeaderRowArray      = Get_Property(SearchCtrl, "OLE.HeaderRow[1]")
        HeaderColArray      = Get_Property(SearchCtrl, "OLE.HeaderColumn[1]")
        HeaderRowArray<3>   = False$
        HeaderColArray<2>   = False$
        
        Set_Property(SearchCtrl, "OLE.HeaderColumn[1]", HeaderColArray)
        Set_Property(SearchCtrl, "OLE.HeaderRow[1]", HeaderRowArray)
        
        // Disable resizing of columns as there is no need for this on this form
        StageColSize    = Get_Property(SearchCtrl, "OLE.DataColumn[1]")
        StageColSize<3> = False$
        
        // Manually set the size of the columns
        Set_Property(SearchCtrl, "OLE.DataColumn[All]", StageColSize)
        WfrColSize      = Get_Property(SearchCtrl, "OLE.DataColumn[3]")
        WfrColSize<1>   = 85
        Set_Property(SearchCtrl, "OLE.DataColumn[All]", WfrColSize)
        WfrColSize<1>   = 95
        
        // Widen Work Order column
        Set_Property(SearchCtrl, "OLE.DataColumn[":WO_NO$:"]", WfrColSize)
        
        // Widen Retain Box column
        WfrColSize<1>   = 90
        Set_Property(SearchCtrl, "OLE.DataColumn[":RETAIN_BOX$:"]", WfrColSize)
        
        // Widen Retain Date column
        Set_Property(SearchCtrl, "OLE.DataColumn[":RETAIN_DATE$:"]", WfrColSize)       
        
        // Set Comments column to autosized so that the table resizes when scrollbars are necessary
        ColArray    = Get_Property(NCRCtrl, "OLE.DataColumn[14]")
        ColArray<4> = True$
        Set_Property(NCRCtrl, "OLE.DataColumn[14]", ColArray)
        
        // Disable resizing of rows as there is no need for this on this form
        RowSizeProps    = Get_Property(SearchCtrl, "OLE.DataRow[1]")
        RowSizeProps<3> = False$
        Set_Property(SearchCtrl, "OLE.DataRow[All]", RowSizeProps)
    end
    
    
    // Setup Retained Table
    SearchCtrl     = @Window:'.OLE_EDT_RETAINED'
    NumSearchCols  = 14
    NumSearchRows  = 50   
    SearchCtrlList = '' 
    
    HeaderFontArray  = 'Segoe UI':@SVM:8:@SVM:700
    SearchDimArray   = NumSearchCols :@FM: NumSearchRows
    
    Set_Property(SearchCtrl, "OLE.CellFont[All; All]", 'Segoe UI':@SVM:8)
    Set_Property(SearchCtrl, "OLE.Dimension", SearchDimArray)
    Set_Property(SearchCtrl, "OLE.CellFont[1;All]", HeaderFontArray)
    Set_Property(SearchCtrl, "OLE.LIST", SearchCtrlList)
    Set_Property(SearchCtrl, "OLE.HeaderFont[All; 1]", HeaderFontArray)
    Set_Property(SearchCtrl, "OLE.HeaderFont[1; All]", HeaderFontArray)
    
    HeaderTitles  = 'Run ID':@VM:'Recipe':@VM:'Pocket':@VM:'Scribe':@VM:'Grade':@VM
    HeaderTitles := 'Part':@VM:'Work Order':@VM:'Retain Box':@VM:'Slot':@VM:'Operator':@VM
    HeaderTitles := 'Retain Date':@VM:'Location':@VM:'Status':@VM:'Comment'
    Set_Property(SearchCtrl, "OLE.TitleList", HeaderTitles)
    Set_Property(SearchCtrl, "OLE.HeaderAlignment[All; 1]", 'C':@FM:'C':@FM:'L')
    Set_Property(SearchCtrl, "OLE.CellAlignment[All; All]", 'C':@FM:'C':@FM:'L')
    Set_Property(SearchCtrl, "OLE.CellAlignment[1; All]", 'C':@FM:'L':@FM:'L')
    Set_Property(SearchCtrl, "OLE.AllowDeletions", False$)
    Set_Property(SearchCtrl, "OLE.AllowInserts", False$)
    
    // Set default header colors
    HeaderColorArray    = ''
    HeaderColorArray<1> = 'Auto'
    HeaderColorArray<2> = 'None'
    HeaderColorArray<3> = 'None'
    HeaderColorArray<4> = OI_HOT_BLUE$
    HeaderColorArray<5> = False$
    Set_Property(SearchCtrl, "OLE.HeaderColors[All; All]", HeaderColorArray)
    
    // Qualify OLE events that we want to intercept
    Qualifier       = ''
    Qualifier<1>    = 1
    Qualifier<4>    = 0 ; * process synchronously (i.e. immediately)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.OnClick',             Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.OnButtonClick',       Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.OnContextMenuClick',  Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.PosChanged',          Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.OnComboClicked',      Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.OnHeaderClick',       Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.OnCheckChanged',      Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.AfterUpdate',         Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.OnContextMenuClick',  Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.OnDblClick',          Qualifier)
    
    CellTypeArray        = ""
    CellTypeArray<1>     = "Combo"
    CellTypeArray<2, 1>  = ""
    CellTypeArray<2, 2>  = "L"
    CellTypeArray<2, 3>  = ''
    CellTypeArray<2, 4>  = 1                         ;// Column 1 contains the values we care about
    CellTypeArray<2, 5>  = 1                         ;// Auto fill on
    CellTypeArray<2, 6>  = 0                         ;// Case sensitive on
    CellTypeArray<2, 7>  = 10                        ;// 10 visible rows max
    CellTypeArray<2, 8>  = 0                         ;// Don't fire the OnOptionClick
    CellTypeArray<2, 9>  = 1                         ;// Reduce the list to partial matches
    CellTypeArray<2, 10> = 0                         ;// Only show the drop down when the user types
    CellTypeArray<2, 11> = 0                         ;// Do not use LIST Format
    CellTypeArray<2, 12> = 1                         ;// Autofill on Tool ID name
    CellTypeArray<2, 13> = 1                         ;// Hide dropdown when user clears cell
    CellTypeArray<2, 14> = 0                         ;// Let navigation keys show the drop down
    CellTypeArray<2, 15> = 0                         ;// Show the drop down regardless of the cell's contents
    CellTypeArray<2, 16> = 0                         ;// Show the drop down during autofill
    CellTypeArray<2, 17> = 1                         ;// Remove selection when user backspaces/deletes
    CellTypeArray<2, 18> = 0                         ;// Show Popup while in read only mode
    CellTypeArray<2, 19> = 1                         ;// Show Popup When Navigating
    CellTypeArray<2, 20> = 1                         ;// Always Tab Out on Enter
    CellTypeArray<2, 21> = -1                        ;// Always show the dropdown above when close to the screen bottom
    CellTypeArray<2, 23> = 1                         ;// Limit possible values to those in dropdown
    // Store this for later use elsewhere   
    Set_Property(@Window, '@COMBOBOX', CellTypeArray)
    
    // Cell selection style setup
    Set_Property(SearchCtrl,  "OLE.ResetSelPos", False$)  ;// Prevent cell selection from being reset upon lost focus event
    ReactorSelStyleArray    = Get_Property(SearchCtrl, "OLE.SelectionStyle")
    ReactorSelStyleArray<8> = True$
    Set_Property(SearchCtrl,  'OLE.SelectionStyle', ReactorSelStyleArray)
    
    CellSelStyleArray    = ''
    CellSelStyleArray<1> = 'White'                      ;// Selected cell foreground color
    CellSelStyleArray<2> = OI_BLUE$                     ;// Selected cell background color
    CellSelStyleArray<3> = 'None'                       ;// Selected record (row) foreground color - none = default
    CellSelStyleArray<4> = OI_HOT_BLUE$                 ;// Selected record (row) background color
    CellSelStyleArray<5> = 'None'                       ;// Selected field (column) foreground color - none = default
    CellSelStyleArray<6> = OI_HOT_BLUE$                 ;// Selected field (column) background color
    Set_Property(SearchCtrl,  'OLE.CellSelColors[2; All]', CellSelStyleArray)
    
    Set_Property(SearchCtrl, "OLE.HeaderArrow[All; 1]", 'Down')    
    
    // Setup Destroyed Table
    SearchCtrl     = @Window:'.OLE_EDT_DESTROYED'
    NumSearchCols  = 14
    NumSearchRows  = 50   
    SearchCtrlList = '' 
    
    HeaderFontArray  = 'Segoe UI':@SVM:8:@SVM:700
    SearchDimArray   = NumSearchCols :@FM: NumSearchRows
    
    Set_Property(SearchCtrl, "OLE.CellFont[All; All]", 'Segoe UI':@SVM:8)
    Set_Property(SearchCtrl, "OLE.Dimension", SearchDimArray)
    Set_Property(SearchCtrl, "OLE.CellFont[1;All]", HeaderFontArray)
    Set_Property(SearchCtrl, "OLE.LIST", SearchCtrlList)
    Set_Property(SearchCtrl, "OLE.HeaderFont[All; 1]", HeaderFontArray)
    Set_Property(SearchCtrl, "OLE.HeaderFont[1; All]", HeaderFontArray)
    
    HeaderTitles  = 'Run ID':@VM:'Recipe':@VM:'Pocket':@VM:'Scribe':@VM:'Grade':@VM
    HeaderTitles := 'Part':@VM:'Work Order':@VM:'Retain Box':@VM:'Slot':@VM:'Operator':@VM
    HeaderTitles := 'Retain Date':@VM:'Location':@VM:'Status':@VM:'Comment'
    Set_Property(SearchCtrl, "OLE.TitleList", HeaderTitles)
    Set_Property(SearchCtrl, "OLE.HeaderAlignment[All; 1]", 'C':@FM:'C':@FM:'L')
    Set_Property(SearchCtrl, "OLE.CellAlignment[All; All]", 'C':@FM:'C':@FM:'L')
    Set_Property(SearchCtrl, "OLE.CellAlignment[1; All]", 'C':@FM:'L':@FM:'L')
    Set_Property(SearchCtrl, "OLE.AllowDeletions", False$)
    Set_Property(SearchCtrl, "OLE.AllowInserts", False$)
    
    // Set default header colors
    HeaderColorArray    = ''
    HeaderColorArray<1> = 'Auto'
    HeaderColorArray<2> = 'None'
    HeaderColorArray<3> = 'None'
    HeaderColorArray<4> = OI_HOT_BLUE$
    HeaderColorArray<5> = False$
    Set_Property(SearchCtrl, "OLE.HeaderColors[All; All]", HeaderColorArray)
    
    // Qualify OLE events that we want to intercept
    Qualifier       = ''
    Qualifier<1>    = 1
    Qualifier<4>    = 0 ; * process synchronously (i.e. immediately)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.OnClick',             Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.OnButtonClick',       Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.OnContextMenuClick',  Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.PosChanged',          Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.OnComboClicked',      Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.OnHeaderClick',       Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.OnCheckChanged',      Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.AfterUpdate',         Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.OnContextMenuClick',  Qualifier)
    Send_Message(SearchCtrl,  'QUALIFY_EVENT', 'OLE.OnDblClick',          Qualifier)
    
    CellTypeArray        = ""
    CellTypeArray<1>     = "Combo"
    CellTypeArray<2, 1>  = ""
    CellTypeArray<2, 2>  = "L"
    CellTypeArray<2, 3>  = ''
    CellTypeArray<2, 4>  = 1                         ;// Column 1 contains the values we care about
    CellTypeArray<2, 5>  = 1                         ;// Auto fill on
    CellTypeArray<2, 6>  = 0                         ;// Case sensitive on
    CellTypeArray<2, 7>  = 10                        ;// 10 visible rows max
    CellTypeArray<2, 8>  = 0                         ;// Don't fire the OnOptionClick
    CellTypeArray<2, 9>  = 1                         ;// Reduce the list to partial matches
    CellTypeArray<2, 10> = 0                         ;// Only show the drop down when the user types
    CellTypeArray<2, 11> = 0                         ;// Do not use LIST Format
    CellTypeArray<2, 12> = 1                         ;// Autofill on Tool ID name
    CellTypeArray<2, 13> = 1                         ;// Hide dropdown when user clears cell
    CellTypeArray<2, 14> = 0                         ;// Let navigation keys show the drop down
    CellTypeArray<2, 15> = 0                         ;// Show the drop down regardless of the cell's contents
    CellTypeArray<2, 16> = 0                         ;// Show the drop down during autofill
    CellTypeArray<2, 17> = 1                         ;// Remove selection when user backspaces/deletes
    CellTypeArray<2, 18> = 0                         ;// Show Popup while in read only mode
    CellTypeArray<2, 19> = 1                         ;// Show Popup When Navigating
    CellTypeArray<2, 20> = 1                         ;// Always Tab Out on Enter
    CellTypeArray<2, 21> = -1                        ;// Always show the dropdown above when close to the screen bottom
    CellTypeArray<2, 23> = 1                         ;// Limit possible values to those in dropdown
    // Store this for later use elsewhere   
    Set_Property(@Window, '@COMBOBOX', CellTypeArray)
    
    // Cell selection style setup
    Set_Property(SearchCtrl,  "OLE.ResetSelPos", False$)  ;// Prevent cell selection from being reset upon lost focus event
    ReactorSelStyleArray    = Get_Property(SearchCtrl, "OLE.SelectionStyle")
    ReactorSelStyleArray<8> = True$
    Set_Property(SearchCtrl,  'OLE.SelectionStyle', ReactorSelStyleArray)
    
    CellSelStyleArray    = ''
    CellSelStyleArray<1> = 'White'                      ;// Selected cell foreground color
    CellSelStyleArray<2> = OI_BLUE$                     ;// Selected cell background color
    CellSelStyleArray<3> = 'None'                       ;// Selected record (row) foreground color - none = default
    CellSelStyleArray<4> = OI_HOT_BLUE$                 ;// Selected record (row) background color
    CellSelStyleArray<5> = 'None'                       ;// Selected field (column) foreground color - none = default
    CellSelStyleArray<6> = OI_HOT_BLUE$                 ;// Selected field (column) background color
    Set_Property(SearchCtrl,  'OLE.CellSelColors[2; All]', CellSelStyleArray)
    
    Set_Property(SearchCtrl, "OLE.HeaderArrow[All; 1]", 'Down')    
return


FillSearchEDT:
*    SRP_Stopwatch('Reset')
    SearchCtrl     = @Window:'.OLE_EDT_SEARCH'  
    SearchCtrlList = ''
    
    // Display all wafers at first
    * To do - Get wafer size from tab
    WaferSize   = '150 mm 6 in'
    hDict       = Database_Services('GetTableHandle', 'DICT.RETAINED_WAFERS')
    If Error_Services('NoError') then
        Query   = 'WAFER_SIZE' : @VM : WaferSize : @FM
        Query  := 'LOCATION' : @VM : 'Warehouse' : @VM : 'Cleanroom' : @FM
        KeyList = ''
        Option  = ''
        Flag    = ''
*        SRP_Stopwatch('Start', 'BTreeExtract')
        Btree.Extract(Query, 'RETAINED_WAFERS', hDict, KeyList, Option, Flag)
*        SRP_Stopwatch('Stop', 'BTreeExtract')
        NumKeys = DCount(KeyList, @VM)
        If Get_Status(ErrCode) else
*            SRP_Stopwatch('Start', 'Populate OLE Table')
            For each WfrID in keylist using @VM setting RowIndex
*                SRP_Stopwatch('Start', 'Read Data Row')
                WfrRec          = Database_Services('ReadDataRow', 'RETAINED_WAFERS', WfrID)
*                SRP_Stopwatch('Stop', 'Read Data Row')
*                SRP_Stopwatch('Start', 'List Building')
                SearchCtrlList := WfrRec<RETAINED_WAFERS.RUN_ID$>       : @VM : WfrRec<RETAINED_WAFERS.RECIPE$>     : @VM : WfrRec<RETAINED_WAFERS.POCKET$>     : @VM : WfrRec<RETAINED_WAFERS.SCRIBE$>     : @VM
                SearchCtrlList := WfrRec<RETAINED_WAFERS.GRADE$>        : @VM : WfrRec<RETAINED_WAFERS.PART_NO$>    : @VM : Field(WfrID, '*', 1)                : @VM : WfrRec<RETAINED_WAFERS.RETAIN_BOX$> : @VM
                SearchCtrlList := WfrRec<RETAINED_WAFERS.RETAIN_SLOT$>  : @VM : WfrRec<RETAINED_WAFERS.RETAIN_SIG$> : @VM : WfrRec<RETAINED_WAFERS.RETAIN_DT$>  : @VM : WfrRec<RETAINED_WAFERS.LOCATION$>   : @VM
                SearchCtrlList := WfrRec<RETAINED_WAFERS.STATUS$>       : @VM : WfrRec<RETAINED_WAFERS.COMMENT$>    : @FM
*                SRP_Stopwatch('Stop', 'List Building')
            Next WfrID
            SearchCtrlList[-1, 1] = ''
*            SRP_Stopwatch('Stop', 'Populate OLE Table')
        end            
        
    end else
        ErrCode = Get_status()
    end
    
*    SRP_Stopwatch('Start', 'Display OLE Table')
    Set_Property(SearchCtrl, 'OLE.LIST', SearchCtrlList)
*    SRP_Stopwatch('Stop', 'Display OLE Table')
*    SRP_Stopwatch('ShowAll')
return


