VERSION 5.00
Object = "{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}#2.1#0"; "mscomctl.OCX"
Begin VB.UserControl ArmCheckView 
   ClientHeight    =   3975
   ClientLeft      =   0
   ClientTop       =   0
   ClientWidth     =   3690
   ScaleHeight     =   3975
   ScaleWidth      =   3690
   Begin MSComctlLib.ImageCombo Combo 
      Height          =   330
      Left            =   240
      TabIndex        =   1
      Top             =   120
      Visible         =   0   'False
      Width           =   3255
      _ExtentX        =   5741
      _ExtentY        =   582
      _Version        =   393216
      ForeColor       =   -2147483640
      BackColor       =   -2147483643
      Locked          =   -1  'True
   End
   Begin MSComctlLib.ListView ListView 
      Height          =   3255
      Left            =   120
      TabIndex        =   0
      Top             =   600
      Width           =   3375
      _ExtentX        =   5953
      _ExtentY        =   5741
      View            =   3
      LabelEdit       =   1
      LabelWrap       =   -1  'True
      HideSelection   =   0   'False
      HideColumnHeaders=   -1  'True
      FullRowSelect   =   -1  'True
      _Version        =   393217
      ForeColor       =   -2147483640
      BackColor       =   -2147483643
      BorderStyle     =   1
      Appearance      =   1
      NumItems        =   0
   End
   Begin VB.Menu MenuPopup 
      Caption         =   ""
   End
   Begin VB.Menu PopupMenu 
      Caption         =   "Set rep as special"
   End
End
Attribute VB_Name = "ArmCheckView"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit

'fired when control is resized
Public Event Resize()
'fired when control is clicked
Public Event Click()
'fired when control is double clicked
Public Event DblClick()
'fired when node is collapsed
Public Event KeyDown(KeyCode As Integer, Shift As Integer)
'fired when key is pressed
Public Event KeyPress(KeyAscii As Integer)
'fired when key is up
Public Event KeyUp(KeyCode As Integer, Shift As Integer)
'fired when node is checked
Public Event ItemCheck(ByVal Item As MSComctlLib.ListItem)
'fired when node is clicked
Public Event ItemClick(ByVal Item As MSComctlLib.ListItem)
'fired when item was changed and needs to be updated (deleted, inserted) in database
Public Event ItemSave(ByVal ao_ItemInfo As ArmItemInfo, ByRef Saved As Boolean)

'windows API call from user32 to send message to a window (control)
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
                            (ByVal hwnd As Long, _
                            ByVal wMsg As Long, _
                            wParam As Any, _
                           lParam As Any) As Long   ' <--- !!

'checkview messages for driving checkview behaviour
Private Const LVM_FIRST = &H1000
Private Const LVM_GETCOLUMNWIDTH = LVM_FIRST + 29
Private Const LVM_SETCOLUMNWIDTH = LVM_FIRST + 30
Private Const LVSCW_AUTOSIZE = -1
Private Const LVSCW_AUTOSIZE_USEHEADER = -2

'main database access component
Private mo_Db As Object
'if true component created its own connection
Private mb_InternalConnection As Boolean
'collection of all checklists (one view and other edit)
Private mo_CheckLists As Collection
'store name of business component which uses this checkview
Private ms_Driven_By As String
'store array of link fields between view checklist and edit checklists
Private mv_Link_Key_Fields As Variant
'array of calling key fields (common fields for all checklists)
Private mv_Calling_Key_Fields As Variant
'array of common key field values
Private mv_Calling_Key_Values As Variant
'current active (displayed) checklist
Private mo_ActiveCheckList As ArmCheckList
'one and only view checklist
Private mo_ViewCheckList As ArmCheckList
'flag which control loading all edit checklists from one request
Private mb_Common_List_Load As Boolean
'flag which indicate edit lists are loaded
Private mb_Edit_List_Loaded As Boolean
'type of key
Private mu_Type_Of_Key As CVTypeOfKey
Private mb_Synchronize_View As Boolean
Private mb_Combo_Visible As Boolean
'connect parameters
Private ms_Server As String
Private ms_Db As String
Private ms_User As String
Private ms_Pwd As String
Private ms_App As String
'array of error, information or error messages which should be translated by LoadConstants
Private ma_Messages As Variant
'trace component to report programm flow and errors
Private mo_Trace As Object

'Windows message constant to enable or disable redrawing of control
Private Const WM_SETREDRAW = &HB
Private Const CH_PHOLDER = "$"
Private Const SEP = "ой"                  'standard armstrong separator

'type of key for each item in checklist
Public Enum CVTypeOfKey
  tkDependant
  tkIndependant
End Enum

'constant type - parameter is separated string with translated text or request to get this string
Public Enum CVConstParamType
  CVptSQL
  CVptStatic
End Enum

'constant enumeration for constant type in LoadConstants method
Public Enum CVConstType
  CVctCombo
  CVctColumns
  CVctMessages
End Enum

'******************************************************************************
' public properties
'******************************************************************************

'main database access component
Public Property Get ArmDb() As Object

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:ArmDB_Get")
#End If
  
  ArmDb = mo_Db

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:ArmDB_Get")
#End If
End Property

Public Property Set ArmDb(ByVal vNewValue As Object)

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:ArmDB_Set")
#End If
  
  Set mo_Db = vNewValue

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:ArmDB_Set")
#End If
End Property

'main trace component
Public Property Set ArmTrace(ByVal lo_NewValue As Object)

  Set mo_Trace = lo_NewValue
End Property

Public Property Get ArmTrace() As Object
  Set ArmTrace = mo_Trace
End Property

'property to store component name which uses this instance of ArmCheckView
Public Property Let Driven_By(as_Value As String)

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:Driven_By_Let")
#End If
  
  ms_Driven_By = as_Value

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:Driven_By_Let")
#End If
End Property

Public Property Get Driven_By() As String

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:Driven_By_Get")
#End If
  
  Driven_By = ms_Driven_By

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:Driven_By_Get")
#End If
End Property

'type of key property - dependend or independend
Public Property Let Type_Of_Key(au_Value As CVTypeOfKey)

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:Type_Of_Key_Let")
#End If
  
  mu_Type_Of_Key = au_Value

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:Type_Of_Key_Let")
#End If
End Property

Public Property Get Type_Of_Key() As CVTypeOfKey

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:Type_Of_Key_Get")
#End If
  
  Type_Of_Key = mu_Type_Of_Key

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:Type_Of_Key_Get")
#End If
End Property

'all edit checklists will be loaded from one request or not
Public Property Let Common_List_Load(ab_Value As Boolean)

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:Common_List_Load_Let")
#End If
  
  mb_Common_List_Load = ab_Value

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:Common_List_Load_Let")
#End If
End Property

Public Property Get Common_List_Load() As Boolean

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:Common_List_Load_Get")
#End If

  Common_List_Load = mb_Common_List_Load
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:Common_List_Load_Get")
#End If
End Property

'connection parameters in case component shold create connection itself
Property Let ConnectString(as_Value As String)
Dim la_Params() As String

On Error GoTo ErrorHandler
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:ConnectString_Let")
#End If
  
  If (as_Value <> "") Then
    la_Params = Split(as_Value, SEP, 5)
    ms_Server = la_Params(0)
    ms_Db = la_Params(1)
    ms_User = la_Params(2)
    ms_Pwd = la_Params(3)
    If UBound(la_Params) >= 4 Then
      ms_App = la_Params(4)
    Else
      ms_App = "ArmCheckView"
    End If
  Else
    ms_Server = ""
    ms_Db = ""
    ms_User = ""
    ms_Pwd = ""
  End If

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:ConnectString_Let")
#End If
  Exit Property
ErrorHandler:
  #If CompDebugCV Then
    Call mo_Trace.WriteTraceError("ArmCheckView:ConnectString_Let", "as_Value=" & as_Value)
  #End If
End Property

'return back true if component is connected, false if not
Public Property Get IsConnected() As Boolean

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:IsConnected_Get")
#End If
  
  IsConnected = False
  If Not (mo_Db Is Nothing) Then
    IsConnected = mo_Db.IsConnected
  End If

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:IsConnected_Get")
#End If
End Property

'set number of checklists inside checkview (generate list of checklists)
Public Property Let RoleCount(al_Value As Long)
Dim lo_CheckList As ArmCheckList
Dim ll_Index As Long

On Error GoTo ErrorHandler
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:RoleCount_Let")
#End If
  
  Call Reset
  For ll_Index = 0 To al_Value - 1
    Set lo_CheckList = New ArmCheckList
    Set lo_CheckList.Trace = mo_Trace
    Set lo_CheckList.ArmDb = mo_Db
    Set lo_CheckList.ArmCheckView = Me
    Set lo_CheckList.ListView = ListView
    Call lo_CheckList.Load_A_COM
    Call mo_CheckLists.Add(lo_CheckList)
  Next

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:RoleCount_Let")
#End If
  Exit Property
ErrorHandler:
  #If CompDebugCV Then
    Call mo_Trace.WriteTraceError("ArmCheckView:RoleCount_Let", "al_Value=" & al_Value)
  #End If
End Property

'get number of checklists inside this checkview
Public Property Get RoleCount() As Long
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:RoleCount_Get")
#End If
  
  RoleCount = 0
  If Not (mo_CheckLists Is Nothing) Then
    RoleCount = mo_CheckLists.Count
  End If

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:RoleCount_Get")
#End If
End Property

'get checklist instance acording its name or index
Public Property Get RoleList(av_Role As Variant) As ArmCheckList
Dim ll_RoleIndex As Long

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:RoleList_Get")
#End If

  Set RoleList = Nothing
  If isNumeric(av_Role) Then
    ll_RoleIndex = av_Role
    If (ll_RoleIndex > 0) And (ll_RoleIndex <= RoleCount) Then
      Set RoleList = mo_CheckLists(ll_RoleIndex)
    End If
  Else
    Set RoleList = GetCheckList(av_Role)
  End If

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:RoleList_Get")
#End If
End Property

'set combobox visible or not
Public Property Let ComboVisible(ab_Value As Boolean)
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:ComboVisible_Let")
#End If
  
  Combo.Visible = ab_Value
  mb_Combo_Visible = ab_Value
  Call UserControl_Resize

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:ComboVisible_Let")
#End If
End Property

'get status of combobox visibility
Public Property Get ComboVisible() As Boolean

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:ComboVisible_Get")
#End If
  
  ComboVisible = Combo.Visible

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:ComboVisible_Get")
#End If
End Property

'set checkboxes visible in checkview or not
Public Property Let Checkboxes(ByVal vNewValue As Boolean)

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:Checkboxes_Let")
#End If
  
  ListView.Checkboxes = vNewValue

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:Checkboxes_Let")
#End If
End Property

'determine if checkboxes are visible
Public Property Get Checkboxes() As Boolean

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:Checkboxes_Get")
#End If
  
  Checkboxes = ListView.Checkboxes

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:Checkboxes_Get")
#End If
End Property

'enable column headers visible or hidden
Public Property Let HideColumnHeaders(ByVal vNewValue As Boolean)
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:HideColumnHeaders_Let")
#End If
  
  ListView.HideColumnHeaders = vNewValue

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:HideColumnHeaders_Let")
#End If
End Property

'get if column headers visible or hidden
Public Property Get HideColumnHeaders() As Boolean
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:HideColumnHeaders_Get")
#End If
  
  HideColumnHeaders = ListView.HideColumnHeaders

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:HideColumnHeaders_Get")
#End If
End Property

'get reference to column headers
Public Property Get ColumnHeaders() As ColumnHeaders
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:ColumnHeaders_Get")
#End If
  
  Set ColumnHeaders = ListView.ColumnHeaders

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:ColumnHeaders_Get")
#End If
End Property

'get reference to column headers
Public Property Get SelectedItem() As ListItem
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:SelectedItem_Get")
#End If
  
  Set SelectedItem = ListView.SelectedItem

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:SelectedItem_Get")
#End If
End Property



'enable or disable checkview
Public Property Let Enabled(ByVal vNewValue As Boolean)
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:Enabled_Let")
#End If
  
  ListView.Enabled = vNewValue
  Combo.Enabled = vNewValue

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:Enabled_Let")
#End If
End Property

Public Property Get Enabled() As Boolean
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:Enabled_Get")
#End If
  
  Enabled = ListView.Enabled

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:Enabled_Get")
#End If
End Property

'get reference to font object of armcheckview
Public Property Get Font() As Object
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:Font_Get")
#End If
  
  Set Font = ListView.Font

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:Font_Get")
#End If
End Property

'get reference to font object of armcheckview
Public Property Get FontCombo() As StdFont
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:FontCombo_Get")
#End If
  
  Set FontCombo = Combo.Font

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:FontCombo_Get")
#End If
End Property

'set link fields between view checklist and edit checklist
Public Property Let Link_Key_Fields(as_Value As String)
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:Link_Key_Fields_Let")
#End If
  
  mv_Link_Key_Fields = GetVariantArray(as_Value)

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:Link_Key_Fields_Let")
#End If
End Property

'set common field names for all checklists in checkview
Public Property Let Calling_Key_Fields(as_Value As String)
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:Calling_Key_Fields_Let")
#End If
  
  mv_Calling_Key_Fields = GetVariantArray(as_Value)
  ReDim mv_Calling_Key_Values(UBound(mv_Calling_Key_Fields))

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:Calling_Key_Fields_Let")
#End If
End Property

'set values for all common fields
Public Property Let Calling_Key_Values(as_Value As String)
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:Calling_Key_Values_Let")
#End If
  
  mv_Calling_Key_Values = GetVariantArray(as_Value)

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:Calling_Key_Values_Let")
#End If
End Property

'if this property is true, armcheckview tries synchronize view items with edit checklists
Public Property Let Synchronize_View(ab_Value As Boolean)
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:Synchronize_View_Let")
#End If
  
  mb_Synchronize_View = ab_Value

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:Synchronize_View_Let")
#End If
End Property

Public Property Get Synchronize_View() As Boolean
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:Synchronize_View_Get")
#End If
  
  Synchronize_View = mb_Synchronize_View

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:Synchronize_View_Get")
#End If
End Property

'******************************************************************************
' public methods
'******************************************************************************

'standard armstrong constructor
Public Sub Load_A_COM()

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:Load_A_COM")
#End If
  
  Set mo_CheckLists = New Collection
  mb_Synchronize_View = False
  mb_InternalConnection = False
  mb_Common_List_Load = True

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:Load_A_COM")
#End If
End Sub

'standard armstrong destructor
Public Sub Unload_A_COM()
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:Unload_A_COM")
#End If
  
  Call Clear
  If mb_InternalConnection Then
    Call CloseConnection
  End If
  Set mo_Db = Nothing
  Set mo_CheckLists = Nothing

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:Unload_A_COM")
#End If
End Sub

'init all parameters for all checklists - main initialization routine
Public Function SetRoleList(av_RoleLists As Variant) As Boolean
Dim lb_Result As Boolean
Dim la_ColAttr() As String
Dim ll_ListIndex As Long, ll_AttrIndex As Long
Dim lv_List As Variant
Dim lo_CheckList As ArmCheckList
Dim ll_ViewCount As Long, ll_EditCount As Long

On Error GoTo ErrorHandler
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:SetRoleList")
#End If
  
  ll_ViewCount = 0
  ll_EditCount = 0
  
  'input parameter must be an array
  If Not IsArray(av_RoleLists) Then GoTo ErrorHandler
  'number of array elements must eb the same like number of role checklists
  If UBound(av_RoleLists) + 1 <> RoleCount Then GoTo ErrorHandler
  
  mb_Edit_List_Loaded = False
  For ll_ListIndex = 0 To UBound(av_RoleLists)
    lv_List = av_RoleLists(ll_ListIndex)
    Set lo_CheckList = mo_CheckLists(ll_ListIndex + 1)
    
    '0 - name of check list
    lo_CheckList.Name = lv_List(0)
    
    '1 - edit or view list
    If StrComp(lv_List(1), "VIEW", vbTextCompare) = 0 Then
      lo_CheckList.Mode = clModeView
      ll_ViewCount = ll_ViewCount + 1
      Set mo_ViewCheckList = lo_CheckList
    Else
      lo_CheckList.Mode = clModeEdit
      ll_EditCount = ll_EditCount + 1
    End If
    
    '2 - CommonRoleFields Names
    lo_CheckList.CommonRoleFields = GetVariantArray(lv_List(2))
    
    '3 - CommonRoleValues
    lo_CheckList.CommonRoleValues = GetVariantArray(lv_List(3))
    
    '4 -caption (title) of check view (will be in combobox)
    lo_CheckList.Caption = lv_List(4)
    
    '5 - data fields (will be store in list)
    lo_CheckList.DataFields = GetVariantArray(lv_List(5))
    
    '6 - display fields (will be displayed in check view)
    lo_CheckList.Visible_Fields = GetVariantArray(lv_List(6))
    
    '7 - display fields (will be displayed in check view)
    lo_CheckList.Visible_Fields_Width = GetVariantArray(lv_List(7))
    
    '8 - key fields inside one check list !!! not entire check view
    lo_CheckList.KeyFields = GetVariantArray(lv_List(8))
    
    '9 request which loads list
    lo_CheckList.RequestLoad = lv_List(9)
    
    '10 request which check item
    lo_CheckList.RequestCheck = lv_List(10)
    
    '11 request which uncheck item
    lo_CheckList.RequestUnCheck = lv_List(11)
    
    '12 readonly
    lo_CheckList.ReadOnly = lv_List(12)
    
    '13 one or many items
    lo_CheckList.One_Or_Many = lv_List(13)
    
    '14 it is radio check list or not
    lo_CheckList.Radio_List = lv_List(14)
    
    '15 caption is displayed in combo
    lo_CheckList.In_Combo = lv_List(15)
    
    '16 priority
    If isNumeric(lv_List(16)) Then
      lo_CheckList.Priority = CLng(lv_List(16))
    Else
      lo_CheckList.Priority = 0
    End If
    
    '17 display order
    If UBound(lv_List) >= 17 Then
      lo_CheckList.DisplayOrder = CLng(lv_List(17))
    Else
      lo_CheckList.DisplayOrder = 0
    End If
    
    lo_CheckList.Link_Key_Fields = mv_Link_Key_Fields
    Call lo_CheckList.InitIndexes
  Next
  'we need exactly one view checklist and one or more edit checklists
  If ll_ViewCount <> 1 Then GoTo ErrorHandler
  If ll_EditCount < 1 Then GoTo ErrorHandler
  'for each checklist init view checklist
  For Each lo_CheckList In mo_CheckLists
    Set lo_CheckList.ViewCheckList = mo_ViewCheckList
  Next
  Call LoadCombo
  SetRoleList = LoadEditLists

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:SetRoleList")
#End If
  Exit Function
ErrorHandler:
  Call Reset
  SetRoleList = False
  #If CompDebugCV Then
    Call mo_Trace.WriteTraceError("ArmCheckView:SetRoleList", "ll_ListIndex=" & ll_ListIndex)
  #End If
End Function

'load view list and initialize (update) all edit lists
Public Function LoadList() As Boolean
Dim ls_ViewRequest As String
Dim ll_Cursor As Long
Dim lo_CheckEditList As ArmCheckList
Dim lb_Result As Boolean

On Error GoTo ErrorHandler
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:LoadList")
#End If
  
  If Not mb_Edit_List_Loaded Then Call LoadEditLists
  
  lb_Result = False
  ll_Cursor = 0
  
  If Not (mo_ViewCheckList Is Nothing) Then
    'get view request string
    ls_ViewRequest = ReplaceRequest(mo_ViewCheckList.RequestLoad, mo_ViewCheckList)
    If ls_ViewRequest <> "" Then
      ll_Cursor = OpenCursor(ls_ViewRequest)
      If ll_Cursor Then
        'load view checklist from cursor
        lb_Result = mo_ViewCheckList.LoadListCursor(ll_Cursor)
        Call CloseCursor(ll_Cursor)
        If lb_Result Then
          'update all view checklists
          For Each lo_CheckEditList In mo_CheckLists
            If (lo_CheckEditList.Mode = clModeEdit) Then
              lb_Result = mo_ViewCheckList.UpdateEditList(lo_CheckEditList)
              If Not lb_Result Then Exit For
            End If
          Next
        End If
      End If
    End If
    'if there is active checklist, then refresh it
    If lb_Result And (Not (mo_ActiveCheckList Is Nothing)) Then
      mo_ActiveCheckList.DisplayList
    End If
  End If
  LoadList = lb_Result

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:LoadList")
#End If
  Exit Function
ErrorHandler:
  LoadList = False
  Call CloseCursor(ll_Cursor)
  #If CompDebugCV Then
    Call mo_Trace.WriteTraceError("ArmCheckView:LoadList")
  #End If
End Function

'change item state (check unchecked) in particular check list
Public Function SetItemState(as_Name As String, ByVal av_Key As Variant, ab_Value As Boolean) As Boolean
Dim lo_CheckList As ArmCheckList
Dim lb_Result As Boolean
Dim lo_ItemInfo As ArmItemInfo

  On Error GoTo ErrorHandler
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:SetItemState")
#End If
  
  lb_Result = False
  'find right checklist
  Set lo_CheckList = GetCheckList(as_Name)
  If Not (lo_CheckList Is Nothing) Then
    If lo_CheckList.Mode = clModeEdit Then
      If Not IsArray(av_Key) Then
        av_Key = Array(av_Key)
      End If
      'find item instance acording key
      Set lo_ItemInfo = lo_CheckList.GetItem(av_Key)
      If Not (lo_ItemInfo Is Nothing) Then
        'change item status
        lb_Result = lo_CheckList.ChangeItemValue(lo_ItemInfo, ab_Value, True)
        'refresh active checklist if success
        If lb_Result And (lo_CheckList Is mo_ActiveCheckList) Then
          Call lo_CheckList.DisplayList
        End If
      End If
    End If
  End If
  SetItemState = lb_Result

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:SetItemState")
#End If
  Exit Function
ErrorHandler:
  SetItemState = False
  #If CompDebugCV Then
    Call mo_Trace.WriteTraceError("ArmCheckView:SetItemState", "as_Name=" & as_Name)
  #End If
End Function

'change active visible checklist to checklist with name as_Name
Public Function SetVisibleList(as_Name As String) As Boolean
Dim lo_CheckList As ArmCheckList
Dim lb_Result As Boolean

On Error GoTo ErrorHandler
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:SetVisibleList")
#End If
  
  lb_Result = False
  Set lo_CheckList = GetCheckList(as_Name)
  If Not lo_CheckList Is Nothing Then
    
    lb_Result = lo_CheckList.DisplayList
    If lb_Result Then
      Set mo_ActiveCheckList = lo_CheckList
      Call SetCombo(lo_CheckList)
    End If
  End If
  SetVisibleList = lb_Result
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:SetVisibleList")
#End If
  Exit Function
ErrorHandler:
  SetVisibleList = False
  #If CompDebugCV Then
    Call mo_Trace.WriteTraceError("ArmCheckView:SetVisibleList", "as_Name=" & as_Name)
  #End If
End Function

'get name of active visible checklist
Public Function GetVisibleList() As String

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:GetVisibleList")
#End If
  
  GetVisibleList = ""
  If Not (mo_ActiveCheckList Is Nothing) Then
    GetVisibleList = mo_ActiveCheckList.Name
  End If

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:GetVisibleList")
#End If
End Function

'apply priority to all edit checklists and uncheck items which doesnt match priority rules
Public Function ApplyPriority() As Boolean
Dim lb_Result As Boolean
Dim lo_Keys As New Collection
Dim ll_Count As Long, ll_MinPriority As Long
Dim ll_Index As Long
Dim lo_CheckList As ArmCheckList
Dim lo_ItemInfo As ArmItemInfo

On Error GoTo ErrorHandler
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:ApplyPriority")
#End If
  
  ApplyPriority = True
  'create collection of all checked item keys
  Call FillKeyCollection(lo_Keys)
  'iterate all item keys in our collection
  For ll_Index = 1 To lo_Keys.Count
    ll_Count = 0
    'minimum (technicaly maximum) priority
    ll_MinPriority = 9999
    'iterate all edit checklists and get maximum (technicaly minimum) priority
    For Each lo_CheckList In mo_CheckLists
      If lo_CheckList.Mode = clModeEdit Then
        Set lo_ItemInfo = lo_CheckList.GetItem(lo_Keys(ll_Index))
        If Not (lo_ItemInfo Is Nothing) Then
          If lo_ItemInfo.CurrentChecked Then
            ll_Count = ll_Count + 1
            ll_MinPriority = Min(ll_MinPriority, lo_CheckList.Priority)
          End If
        End If
      End If
    Next lo_CheckList
    'if there was more than one item with this key, uncheck all with lower (technicaly higher) priority
    If ll_Count > 1 Then
      For Each lo_CheckList In mo_CheckLists
        If (lo_CheckList.Mode = clModeEdit) And (lo_CheckList.Priority > ll_MinPriority) Then
          Set lo_ItemInfo = lo_CheckList.GetItem(lo_Keys(ll_Index))
          If Not (lo_ItemInfo Is Nothing) Then
            If lo_ItemInfo.CurrentChecked Then
              'uncheck item when priority is lower
              If Not lo_CheckList.ChangeItemValue(lo_ItemInfo, False, True) Then
                MsgBox "Applying priority failed."
                ApplyPriority = False
              End If
            End If
          End If
        End If
      Next lo_CheckList
    End If
  Next ll_Index
  Set lo_Keys = Nothing

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:ApplyPriority")
#End If
  Exit Function
ErrorHandler:
  ApplyPriority = False
  #If CompDebugCV Then
    Call mo_Trace.WriteTraceError("ArmCheckView:ApplyPriority")
  #End If
End Function

'save all user or programatic changes into sql database
Public Function SaveList() As Boolean
Dim lo_CheckList As ArmCheckList
Dim lo_ItemInfo As ArmItemInfo
Dim lb_Success As Boolean
Dim lb_InTrans As Boolean

On Error GoTo ErrorHandler:
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:SaveList")
#End If
  
  lb_Success = False
  lb_InTrans = False
  Call SetMousePointer(False)
  If IsConnected Then
    'if applying priority rules was OK, start transaction
    If ApplyPriority Then
      If ExecuteRequest("BEGIN TRANSACTION") Then
        'flag - we are in transaction because of exception and cleanup
        lb_InTrans = True
        'estimate we will have success, this is changed in case of error only
        lb_Success = True
        
        'iterate all edit checklist and save all items which have difference between original and current checked
        For Each lo_CheckList In mo_CheckLists
          If (lo_CheckList.Mode = clModeEdit) Then
            'first save unchecked (delete) because of integrity of primary key
            For Each lo_ItemInfo In lo_CheckList.Items
              If (Not lo_ItemInfo.CurrentChecked) And (lo_ItemInfo.CurrentChecked <> lo_ItemInfo.OriginalChecked) Then
                lb_Success = SaveItem(lo_ItemInfo)
                If lb_Success Then
                  lo_ItemInfo.OriginalChecked = lo_ItemInfo.CurrentChecked
                Else
                  Exit For
                End If
              End If
            Next
            
            'do not continue to update DB  after first error
            If Not lb_Success Then Exit For
            
            'then save checked (insert) because of integrity of primary key
            For Each lo_ItemInfo In lo_CheckList.Items
              If lo_ItemInfo.CurrentChecked And (lo_ItemInfo.CurrentChecked <> lo_ItemInfo.OriginalChecked) Then
                lb_Success = SaveItem(lo_ItemInfo)
                If lb_Success Then
                  lo_ItemInfo.OriginalChecked = lo_ItemInfo.CurrentChecked
                Else
                  Exit For
                End If
              End If
            Next
            
            'do not continue to update DB after first error
            If Not lb_Success Then Exit For
          End If
        Next lo_CheckList
        
        If lb_Success Then
          'if everything before was success, then commit changes
          lb_Success = ExecuteRequest("COMMIT TRANSACTION")
        Else
          Call ExecuteRequest("ROLLBACK TRANSACTION")
        End If
        'set flag in transaction to false
        lb_InTrans = False
      End If
    End If
  End If
  SaveList = lb_Success
  Call SetMousePointer(True)
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:SaveList")
#End If
  Exit Function
ErrorHandler:
  If lb_InTrans Then Call ExecuteRequest("ROLLBACK TRANSACTION")
  Call SetMousePointer(True)
  SaveList = False
  #If CompDebugCV Then
    Call mo_Trace.WriteTraceError("ArmCheckView:SaveList")
  #End If
End Function

'reset all checklist, remove all items and set checkview to initial state
Public Sub Reset()
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:Reset")
#End If
  
  Call Clear
  Call DeleteCollection
  Call ListView.ListItems.Clear
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:Reset")
#End If
End Sub

'uncheck all items in edit checkviews and remove all items from view checklist
Public Sub Init()
  Dim lo_CheckList As ArmCheckList
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:Init")
#End If
  
  For Each lo_CheckList In mo_CheckLists
    lo_CheckList.InitList
  Next
  'refresh checkview
  If Not (mo_ActiveCheckList Is Nothing) Then
    Call mo_ActiveCheckList.DisplayList
  End If

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:Init")
#End If
End Sub

'load constants and error messages
Public Function LoadConstants(au_ParamType As CVConstParamType, ByVal as_Param As String, au_ConstType As CVConstType) As Boolean
'Dim lb_Result As Boolean
Dim ll_Index As Long
Dim lo_CheckList As ArmCheckList
Dim la_Const() As String

On Error GoTo ErrorHandler
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:LoadConstants")
#End If
  
'  lb_Result = False
  'load constants from SQL and save it to as_Param string
  If (au_ParamType = CVptSQL) Then
    'convert request to static parameter
    as_Param = GetSQLValue(as_Param)
  End If
  
  la_Const = Split(as_Param, SEP)
  If Not IsArray(la_Const) Then GoTo ErrorHandler
  
  Select Case au_ConstType
    
    Case CVctCombo
      For ll_Index = 0 To UBound(la_Const)
        If ll_Index + 1 <= RoleCount Then
          mo_CheckLists(ll_Index + 1).Caption = la_Const(ll_Index)
        Else
          Exit For
        End If
      Next
      Call LoadCombo
      
    Case CVctColumns
      For Each lo_CheckList In mo_CheckLists
        lo_CheckList.ColumnCaptions = la_Const
      Next
      
    Case CVctMessages
      ma_Messages = la_Const
  End Select
  
  LoadConstants = True
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:LoadConstants")
#End If
  Exit Function
ErrorHandler:
  #If CompDebugCV Then
    Call mo_Trace.WriteTraceError("ArmCheckView:LoadConstants", "au_ParamType=" & au_ParamType, _
    "as_Param=" & as_Param, "au_ConstType=" & au_ConstType)
  #End If
  LoadConstants = False
End Function


'get number of checked items in particular checklist
Public Function CheckedCount(as_Name As String) As Long
Dim lo_CheckList As ArmCheckList

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:CheckedCount")
#End If
  
  CheckedCount = -1
  Set lo_CheckList = GetCheckList(as_Name)
  If Not (lo_CheckList Is Nothing) Then
    CheckedCount = lo_CheckList.CheckedCount
  End If

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:CheckedCount")
#End If
End Function

'uncheck all items in speicific checklist
Public Function UnCheckAll(as_Name As String) As Boolean
Dim lo_CheckList As ArmCheckList

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:UnCheckAll")
#End If
  
  UnCheckAll = False
  Set lo_CheckList = GetCheckList(as_Name)
  If Not (lo_CheckList Is Nothing) Then
    If lo_CheckList.Mode = clModeEdit Then
      UnCheckAll = lo_CheckList.UnCheckAll
    End If
  End If

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:UnCheckAll")
#End If
End Function

'undo all changes done by user or pragramaticaly since last load list
Public Function Undo() As Boolean
Dim lo_CheckList As ArmCheckList

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:Undo")
#End If
  
  Undo = True
  For Each lo_CheckList In mo_CheckLists
    If Not lo_CheckList.Undo Then
      Undo = False
    End If
  Next
  If Not (mo_ActiveCheckList Is Nothing) Then
    Call mo_ActiveCheckList.DisplayList
  End If

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:Undo")
#End If
End Function

'get array of all checked items in particular checklist
Public Function CheckedKeys(as_Name As String) As Variant
Dim lo_CheckList As ArmCheckList

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:CheckedKeys")
#End If
  
  CheckedKeys = Empty
  Set lo_CheckList = GetCheckList(as_Name)
  If Not (lo_CheckList Is Nothing) Then
    CheckedKeys = lo_CheckList.CheckedKeys
  End If

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:CheckedKeys")
#End If
End Function

'set property of all role checklists in one go, currently works for priority and readonly properties
Public Function SetRoleProperty(as_PropName As String, av_PropValue As Variant) As Boolean
Dim lb_Result As Boolean
Dim ll_Index As Long

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:SetRoleProperty")
#End If
On Error GoTo ErrorHandler
  lb_Result = False
  If IsArray(av_PropValue) Then
    If UBound(av_PropValue) = RoleCount - 1 Then
      lb_Result = True
      For ll_Index = 0 To UBound(av_PropValue)
        Select Case UCase(as_PropName)
        Case "PRIORITY"
          mo_CheckLists(ll_Index + 1).Priority = av_PropValue(ll_Index)
        Case "READONLY"
          mo_CheckLists(ll_Index + 1).ReadOnly = av_PropValue(ll_Index)
        Case Else
          lb_Result = False
          Exit For
        End Select
      Next
    End If
  End If
  SetRoleProperty = lb_Result
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:SetRoleProperty")
#End If
  Exit Function
ErrorHandler:
  SetRoleProperty = False
  #If CompDebugCV Then
    Call mo_Trace.WriteTraceError("ArmCheckView:SetRoleProperty", "as_PropName=" & as_PropName)
  #End If
End Function

'set auto size fro all columns
Public Sub AutoSize()
Dim ll_Index As Long
Dim ll_Width As Long

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:AutoSize")
#End If
    
  For ll_Index = 0 To ListView.ColumnHeaders.Count - 1
    If ListView.ColumnHeaders(ll_Index + 1).Width > 0 Then
      ll_Width = SendMessage(ListView.hwnd, LVM_GETCOLUMNWIDTH, ByVal ll_Index, ByVal 0)
      Call SendMessage(ListView.hwnd, LVM_SETCOLUMNWIDTH, ByVal ll_Index, ByVal LVSCW_AUTOSIZE_USEHEADER)
      If ll_Width > SendMessage(ListView.hwnd, LVM_GETCOLUMNWIDTH, ByVal ll_Index, ByVal 0) Then
        Call SendMessage(ListView.hwnd, LVM_SETCOLUMNWIDTH, ByVal ll_Index, ByVal ll_Width)
      End If
    End If
  Next

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:AutoSize")
#End If
End Sub

'**************************************************************************************************************
'turn of on mouse pointer sand hour glass, use counter
Public Static Sub SetMousePointer(lb_Enable As Boolean)
Dim li_Count As Integer

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:SetMousePointer")
#End If
  
  If lb_Enable Then
    If li_Count > 0 Then li_Count = li_Count - 1
    If li_Count <= 0 Then Screen.MousePointer = vbDefault
  Else
    li_Count = li_Count + 1
    Screen.MousePointer = vbHourglass
  End If

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:SetMousePointer")
#End If
End Sub

'turn on off listview control redrawing
Public Sub SetRedraw(hwnd As Long, lb_Enable As Boolean)
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:SetRedraw")
#End If
  
  Call SendMessage(hwnd, WM_SETREDRAW, lb_Enable, 0)

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:SetRedraw")
#End If
End Sub

'******************************************************************************
' private methods
'******************************************************************************

'open request and return single value from first row and first field of result set
Private Function GetSQLValue(as_Request As String) As Variant
Dim ll_Cursor As Long

On Error GoTo ErrorHandler
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:GetSQLValue")
#End If
  
  GetSQLValue = Empty
  ll_Cursor = 0
  
  'try to open connection if component is not connected
  If Not IsConnected Then
    If Not OpenConnection(ms_Server, ms_Db, ms_User, ms_Pwd, ms_App) Then
      Call MsgBox("Open connection failed.")
    End If
  End If
  
  If IsConnected And (as_Request <> "") Then
    ll_Cursor = OpenCursor(as_Request)
    If ll_Cursor <> 0 Then
      If (mo_Db.RowCount(ll_Cursor) > 0) And (mo_Db.FieldCount(ll_Cursor) > 0) Then
        GetSQLValue = mo_Db.GetFields(ll_Cursor, 0)
      End If
      Call CloseCursor(ll_Cursor)
    End If
  End If

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:GetSQLValue")
#End If
  Exit Function
ErrorHandler:
  #If CompDebugCV Then
    Call mo_Trace.WriteTraceError("ArmCheckView:GetSQLValue", "as_Request=" & as_Request, _
    "IsConnected=" & IsConnected, "ll_Cursor=" & ll_Cursor)
  #End If
End Function

'clear checklists - this mean remove all items from view and uncheck all items in edit checklist
Private Sub Clear()
  Dim lo_CheckList As ArmCheckList
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:Clear")
#End If
  
  If Not mo_CheckLists Is Nothing Then
    For Each lo_CheckList In mo_CheckLists
      lo_CheckList.ClearList
    Next
  End If

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:Clear")
#End If
End Sub

'get variant array from separated string
Private Function GetVariantArray(ByVal as_Value As String) As Variant
Dim lv_StrArray As Variant, lv_Array As Variant
Dim ll_Index As Long

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:GetVariantArray")
#End If
  
  If as_Value = "" Then
    lv_Array = Array(as_Value)
  Else
    lv_StrArray = Split(as_Value, SEP)
    ReDim lv_Array(UBound(lv_StrArray))
    For ll_Index = 0 To UBound(lv_StrArray)
      lv_Array(ll_Index) = lv_StrArray(ll_Index)
    Next
  End If
  GetVariantArray = lv_Array

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:GetVariantArray")
#End If
End Function

'get checklist instance acording its name
Private Function GetCheckList(ByVal as_Name As String) As ArmCheckList
Dim ll_Index As Long

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:GetCheckList")
#End If
  
  Set GetCheckList = Nothing
  For ll_Index = 1 To mo_CheckLists.Count
    If StrComp(mo_CheckLists(ll_Index).Name, as_Name, vbTextCompare) = 0 Then
      Set GetCheckList = mo_CheckLists(ll_Index)
      Exit For
    End If
  Next

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:GetCheckList")
#End If
End Function

'select item in combo acording parameter checklist
Private Function SetCombo(ao_CheckList As ArmCheckList) As Boolean
Dim lb_Found As Boolean
Dim lo_ComboItem As ComboItem

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:SetCombo")
#End If
  
  lb_Found = False
  For Each lo_ComboItem In Combo.ComboItems
    If lo_ComboItem.Tag Is ao_CheckList Then
      lb_Found = True
      Exit For
    End If
  Next
  If lb_Found Then
    Set Combo.SelectedItem = lo_ComboItem
  Else
    'if checklist is not found in combo, clear combobox
    Set Combo.SelectedItem = Nothing
    Combo.Text = ""
  End If
  SetCombo = lb_Found

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:SetCombo")
#End If
End Function

'replace all field placeholders by its values acording checklist
Private Function ReplaceRequest(ByVal as_Request As String, ao_CheckList As ArmCheckList, Optional ao_ItemInfo As ArmItemInfo = Nothing) As String
Dim ll_FieldIndex As Long
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:ReplaceRequest")
#End If
  'replace placeholder for current time
  as_Request = Replace(as_Request, "$NOW()$", Format(Now, "yyyy-mm-dd"), , , vbTextCompare)
  'first try to replace all common fields for entire checkview (calling_key)
  For ll_FieldIndex = 0 To UBound(mv_Calling_Key_Fields)
    as_Request = Replace(as_Request, "$" & mv_Calling_Key_Fields(ll_FieldIndex) & "$", Replace(mv_Calling_Key_Values(ll_FieldIndex), "'", "''"), , , vbTextCompare)
  Next
  'then try to replace all common field for specific checkview
  For ll_FieldIndex = 0 To UBound(ao_CheckList.CommonRoleFields)
    as_Request = Replace(as_Request, "$" & ao_CheckList.CommonRoleFields(ll_FieldIndex) & "$", Replace(ao_CheckList.CommonRoleValues(ll_FieldIndex), "'", "''"), , , vbTextCompare)
  Next
  'then try to replace all data fields from specific item
  If Not (ao_ItemInfo Is Nothing) Then
    For ll_FieldIndex = 0 To UBound(ao_CheckList.DataFields)
      as_Request = Replace(as_Request, "$" & ao_CheckList.DataFields(ll_FieldIndex) & "$", Replace(ao_ItemInfo.GetData(ll_FieldIndex), "'", "''"), , , vbTextCompare)
    Next
  End If
  ReplaceRequest = as_Request

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:ReplaceRequest")
#End If
End Function

'compare two key, if equal return true
Private Function CompareKeys(av_Key1 As Variant, av_Key2 As Variant) As Boolean
Dim li_Index As Integer

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:CompareKeys")
#End If
  
  CompareKeys = True
  For li_Index = 0 To UBound(av_Key1)
    If CStr(av_Key1(li_Index)) <> CStr(av_Key2(li_Index)) Then
      CompareKeys = False
      Exit For
    End If
  Next

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:CompareKeys")
#End If
End Function

'add variant key into collection
Private Sub AddKey(ao_Keys As Collection, av_Key As Variant)
Dim ll_Index As Long
Dim lb_Found As Boolean

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:AddKey")
#End If
  
  lb_Found = False
  For ll_Index = 1 To ao_Keys.Count
    If CompareKeys(av_Key, ao_Keys(ll_Index)) Then
      lb_Found = True
      Exit For
    End If
  Next
  If Not lb_Found Then
    Call ao_Keys.Add(av_Key)
  End If

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:AddKey")
#End If
End Sub

'fill collection with all checked items in all edit checklists
Private Function FillKeyCollection(ao_Keys As Collection) As Boolean
Dim lo_CheckList As ArmCheckList
Dim lo_ItemInfo As ArmItemInfo

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:FillKeyCollection")
#End If
  
  For Each lo_CheckList In mo_CheckLists
    If lo_CheckList.Mode = clModeEdit Then
      For Each lo_ItemInfo In lo_CheckList.Items
        If lo_ItemInfo.CurrentChecked Then
          Call AddKey(ao_Keys, lo_CheckList.GetItemKey(lo_ItemInfo))
        End If
      Next lo_ItemInfo
    End If
  Next lo_CheckList

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:FillKeyCollection")
#End If
End Function

'load combobox with captions from checklists
Private Function LoadCombo() As Boolean
Dim lo_CheckList As ArmCheckList
Dim lo_ComboItem As ComboItem

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:LoadCombo")
#End If
  
  Combo.ComboItems.Clear
  Combo.Text = ""
  For Each lo_CheckList In mo_CheckLists
    If lo_CheckList.In_Combo Then
      Set lo_ComboItem = Combo.ComboItems.Add(, , lo_CheckList.Caption)
      Set lo_ComboItem.Tag = lo_CheckList
    End If
  Next
  LoadCombo = True

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:LoadCombo")
#End If
End Function

'init checkview -  load edit checklists
Public Function LoadEditLists() As Boolean
Dim lo_CheckList As ArmCheckList
Dim ll_Cursor As Long
Dim ls_EditRequest As String
Dim lb_Result As Boolean
  
On Error GoTo ErrorHandler
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:LoadEditLists")
#End If
  
  lb_Result = True
  ll_Cursor = 0
  ls_EditRequest = ""
  
  'load all edit lists with the same request (first one)
  If Common_List_Load Then
    'get first request from first edit checklist to load edit checklist
    For Each lo_CheckList In mo_CheckLists
      If (lo_CheckList.Mode = clModeEdit) Then
        ls_EditRequest = ReplaceRequest(lo_CheckList.RequestLoad, lo_CheckList)
        Exit For
      End If
    Next
    ll_Cursor = OpenCursor(ls_EditRequest)
    If ll_Cursor Then
      For Each lo_CheckList In mo_CheckLists
        If lo_CheckList.Mode = clModeEdit Then
          lb_Result = lo_CheckList.LoadListCursor(ll_Cursor)
          If Not lb_Result Then Exit For
        End If
      Next
      Call CloseCursor(ll_Cursor)
    Else
      lb_Result = False
    End If
  Else
    'load each check list with its own request
    For Each lo_CheckList In mo_CheckLists
      If lo_CheckList.Mode = clModeEdit Then
        ls_EditRequest = ReplaceRequest(lo_CheckList.RequestLoad, lo_CheckList)
        ll_Cursor = OpenCursor(ls_EditRequest)
        If ll_Cursor Then
          lb_Result = lo_CheckList.LoadListCursor(ll_Cursor)
          Call CloseCursor(ll_Cursor)
          If Not lb_Result Then Exit For
        Else
          lb_Result = False
        End If
      End If
    Next
  End If
  
  mb_Edit_List_Loaded = lb_Result
  LoadEditLists = lb_Result
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:LoadEditLists")
#End If
  Exit Function
ErrorHandler:
  Call CloseCursor(ll_Cursor)
  LoadEditLists = False
  mb_Edit_List_Loaded = False
  #If CompDebugCV Then
    Call mo_Trace.WriteTraceError("ArmCheckView:LoadEditLists")
  #End If
End Function

'execute SQL request on server
Private Function ExecuteRequest(as_Request As String) As Boolean
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:ExecuteRequest")
#End If
  
  ExecuteRequest = mo_Db.ExecuteSQL(as_Request)
  If Not ExecuteRequest Then
#If CompDebugCV Then
    Call mo_Trace.WriteTraceSQLError(mo_Db, "ArmCheckView:ExecuteRequest", "as_Request=" & as_Request)
#End If
  End If

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:ExecuteRequest")
#End If
End Function

'open cursor with request as_Request and return cursor
Private Function OpenCursor(as_Request As String) As Long
  
On Error GoTo ErrorHandler
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:OpenCursor")
#End If
  
  Call SetMousePointer(False)
  OpenCursor = 0
  If Not IsConnected Then
    If Not OpenConnection(ms_Server, ms_Db, ms_User, ms_Pwd, ms_App) Then
      #If CompDebugCV Then
        Call mo_Trace.WriteTraceSQLError(mo_Db, "ArmCheckView:OpenCursor", "ms_Server=" & ms_Server, _
          "ms_Db=" & ms_Db, "ms_User=" & ms_User, "ms_Pwd=" & ms_Pwd)
      #End If
    End If
  End If
  OpenCursor = mo_Db.OpenSQL(as_Request)
  If OpenCursor = 0 Then
    #If CompDebugCV Then
      Call mo_Trace.WriteTraceSQLError(mo_Db, "ArmCheckView:OpenCursor", "as_Request=" & as_Request)
    #End If
  End If
  Call SetMousePointer(True)

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:OpenCursor")
#End If
  Exit Function
ErrorHandler:
  Call SetMousePointer(True)
End Function

'close opened cursor with data
Private Function CloseCursor(ByRef al_Cursor As Long) As Boolean

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:CloseCursor")
#End If
  
  CloseCursor = False
  If al_Cursor Then
    CloseCursor = mo_Db.Close(al_Cursor)
    al_Cursor = 0
  End If

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:CloseCursor")
#End If
End Function

'save item data into database
Private Function SaveItem(ByRef ao_ItemInfo As ArmItemInfo) As Boolean
Dim lb_Saved As Boolean
Dim ls_Request As String
Dim ll_Index As Long

 On Error GoTo ErrorHandler
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:SaveItem")
#End If
  
  lb_Saved = False
  RaiseEvent ItemSave(ao_ItemInfo, lb_Saved)
  'if item was not saved in event by framework, try to save automaticaly
  If Not lb_Saved Then
    If ao_ItemInfo.CurrentChecked Then
      ls_Request = ao_ItemInfo.CheckList.RequestCheck
    Else
      ls_Request = ao_ItemInfo.CheckList.RequestUnCheck
    End If
    
    ls_Request = ReplaceRequest(ls_Request, ao_ItemInfo.CheckList, ao_ItemInfo)
    If ls_Request <> "" Then
      lb_Saved = ExecuteRequest(ls_Request)
    End If
  End If
  SaveItem = lb_Saved
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:SaveItem")
#End If
  Exit Function
ErrorHandler:
  SaveItem = False
End Function

'open conection and create own instance of ArmDB if it was not passed through property
Private Function OpenConnection(as_Server As String, as_Db As String, as_User As String, _
    as_Pwd As String, as_App As String) As Boolean
Dim lb_Result As Boolean

On Error GoTo ErrorHandler
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:OpenConnection")
#End If
  
  If IsConnected Then
    lb_Result = False
  Else
    mb_InternalConnection = True
    If mo_Db Is Nothing Then
      Set mo_Db = CreateObject("ARMSYSCOM.ArmDb")
    End If

    If (as_Server <> "") And (as_Db <> "") And (as_User <> "") Then
        lb_Result = mo_Db.Connect(as_Server, as_Db, as_User, as_Pwd, as_App)
        If Not lb_Result Then
          #If CompDebugCV Then
            Call mo_Trace.WriteTraceSQLError(mo_Db, "ArmCheckView:OpenConnection", "as_Server=" & as_Server, _
            "as_Db=" & as_Db, "as_User=" & as_User)
          #End If
        End If
    End If
  End If
  OpenConnection = lb_Result
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:OpenConnection")
#End If
  Exit Function
ErrorHandler:
  OpenConnection = False
  #If CompDebugCV Then
    Call mo_Trace.WriteTraceError("ArmCheckView:OpenConnection", "as_Server=" & as_Server, _
    "as_Db=" & as_Db, "as_User=" & as_User)
  #End If
End Function

'close connection if connection was created with OpenConnection method and
Private Sub CloseConnection()

 On Error GoTo ErrorHandler
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:CloseConnection")
#End If
  
  If IsConnected Then
    Call mo_Db.Disconnect
    mb_InternalConnection = False
  End If
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:CloseConnection")
#End If
  Exit Sub
ErrorHandler:
  #If CompDebugCV Then
    Call mo_Trace.WriteTraceError("ArmCheckView:CloseConnection")
  #End If
End Sub

'clear (delete items from) collection
Private Sub DeleteCollection()
Dim lo_CheckList As ArmCheckList

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:DeleteCollection")
#End If
  
  Set mo_ActiveCheckList = Nothing
  Set mo_ViewCheckList = Nothing
  Combo.ComboItems.Clear
  If Not (mo_CheckLists Is Nothing) Then
    While mo_CheckLists.Count > 0
      Set lo_CheckList = mo_CheckLists(1)
      Call lo_CheckList.Unload_A_COM
      Call mo_CheckLists.Remove(1)
      Set lo_CheckList = Nothing
    Wend
  End If

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:DeleteCollection")
#End If
End Sub

'get maximum of those two parameters
Private Function Max(lv_Op1 As Variant, lv_Op2 As Variant) As Variant
  Max = IIf(lv_Op1 >= lv_Op2, lv_Op1, lv_Op2)
End Function
'get minimum of those two parameters
Private Function Min(lv_Op1 As Variant, lv_Op2 As Variant) As Variant
  Min = IIf(lv_Op1 <= lv_Op2, lv_Op1, lv_Op2)
End Function

'******************************************************************************
' private events
'******************************************************************************

'fired when user change combobox selection
Private Sub Combo_Click()
Dim lo_CheckList As ArmCheckList

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:Combo_Click")
#End If
  
  If Not (Combo.SelectedItem Is Nothing) Then
    Set lo_CheckList = Combo.SelectedItem.Tag
    If Not (lo_CheckList Is Nothing) Then
      Set mo_ActiveCheckList = lo_CheckList
      Call lo_CheckList.DisplayList
    End If
  End If

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:Combo_Click")
#End If
End Sub

'fired when user click on some item in checkview
Private Sub ListView_Click()
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:ListView_Click")
#End If
  
  RaiseEvent Click

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:ListView_Click")
#End If
End Sub

'fired on double click on item in checkview
Private Sub ListView_DblClick()

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:ListView_DblClick")
#End If
  
  RaiseEvent DblClick

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:ListView_DblClick")
#End If
End Sub

'fired when user check or uncheck item in checkview
Private Sub ListView_ItemCheck(ByVal Item As MSComctlLib.ListItem)
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:ListView_ItemCheck")
#End If
  
  If Item.Tag.CheckList.ChangeItemValue(Item.Tag, Item.Checked, False) Then
    RaiseEvent ItemCheck(Item)
  Else
    Item.Checked = Not Item.Checked
  End If

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:ListView_ItemCheck")
#End If
End Sub

'fired when user click on item in checkview
Private Sub ListView_ItemClick(ByVal Item As MSComctlLib.ListItem)
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:ListView_ItemClick")
#End If
  
  RaiseEvent ItemClick(Item)

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:ListView_ItemClick")
#End If
End Sub

'fired when user press key on checkview
Private Sub ListView_KeyDown(KeyCode As Integer, Shift As Integer)
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:ListView_KeyDown")
#End If
  
  RaiseEvent KeyDown(KeyCode, Shift)

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:ListView_KeyDown")
#End If
End Sub

'fired when user press key on checkview
Private Sub ListView_KeyPress(KeyAscii As Integer)
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:ListView_KeyPress")
#End If
  
  RaiseEvent KeyPress(KeyAscii)

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:ListView_KeyPress")
#End If
End Sub

'fired when user press key on checkview
Private Sub ListView_KeyUp(KeyCode As Integer, Shift As Integer)
  
#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(True, "ArmCheckView:ListView_KeyUp")
#End If
  
  RaiseEvent KeyUp(KeyCode, Shift)

#If CompDebugCV Then
  Call mo_Trace.WriteTraceProc(False, "ArmCheckView:ListView_KeyUp")
#End If
End Sub

'fired when control is resized
Private Sub UserControl_Resize()
  
#If CompDebugCV Then
  If Not (mo_Trace Is Nothing) Then Call mo_Trace.WriteTraceProc(True, "ArmCheckView:UserControl_Resize")
#End If
  
  With ListView
    If mb_Combo_Visible Then
      Combo.Top = 0
      Combo.Left = 0
      Combo.Width = Width
      .Top = Combo.Height
      .Height = Height - Combo.Height
    Else
      .Top = 0
      .Height = Height
    End If
    .Width = Width
    .Left = 0
  End With
  RaiseEvent Resize

#If CompDebugCV Then
  If Not (mo_Trace Is Nothing) Then Call mo_Trace.WriteTraceProc(False, "ArmCheckView:UserControl_Resize")
#End If
End Sub


