Modules/ZooFlow/ClassProfileFilter.vb
2019-09-12 17:06:14 +02:00

496 lines
22 KiB
VB.net

Imports System.Text.RegularExpressions
Imports DigitalData.Modules.Language.Utils
Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.Windows
Imports DigitalData.Modules.ZooFlow.Params
Public Class ClassProfileFilter
Private _ProfileTable As DataTable
Private _ProcessTable As DataTable
Private _WindowTable As DataTable
Private _ControlTable As DataTable
Private _Profiles As List(Of ProfileData)
Private _DebugData As DebugData
Private _Logger As Logger
Private _Window As Window
Private _TreeView As New TreeView
' TODO: Fill this Class!!!! :D
Class DebugData
Public ProcessMatch As List(Of String)
Public ClipboardMatch As List(Of String)
Public WindowMatch As List(Of String)
Public WindowRegexMatch As List(Of String)
End Class
Public ReadOnly Property Profiles As List(Of ProfileData)
Get
Return _Profiles
End Get
End Property
Public ReadOnly Property DebugTree As TreeView
Get
Return _TreeView
End Get
End Property
Public Sub New(LogConfig As LogConfig, ProfileDatatable As DataTable, ProcessTable As DataTable, WindowDatatable As DataTable, ControlDatatable As DataTable)
Try
_Logger = LogConfig.GetLogger()
_DebugData = New DebugData()
_ProfileTable = ProfileDatatable
_ProcessTable = ProcessTable
_WindowTable = WindowDatatable
_ControlTable = ControlDatatable
_Profiles = TransformProfiles()
_Window = New Window(LogConfig)
Catch ex As Exception
_Logger.Error(ex)
Throw ex
End Try
End Sub
Public Function ToList() As List(Of ProfileData)
Return _Profiles
End Function
Private Function FindNode(ByVal Node As TreeNode, SearchTerm As String)
Dim oNode As TreeNode
For Each oNode In Node.Nodes
If oNode.Text = SearchTerm Then
Return oNode
End If
Next
Return Node
End Function
Private Function GetLowestNode(ByVal Node As TreeNode) As TreeNode
If Node.GetNodeCount(False) = 1 Then
Return GetLowestNode(Node.Nodes.Item(0))
Else
Return Node
End If
End Function
Public Function FilterProfilesByClipboardRegex(Profiles As List(Of ProfileData), ClipboardContents As String) As List(Of ProfileData)
Dim oFilteredProfiles As New List(Of ProfileData)
For Each oProfile In Profiles
_Logger.Debug("Current Profile: {0}", oProfile.Name)
Try
Dim oRegex As New Regex(oProfile.Regex)
Dim oMatch = oRegex.Match(ClipboardContents)
If oMatch.Success Then
_Logger.Debug("FilterProfilesByClipboardRegex: Clipboard Regex Matched: {0}", ClipboardContents)
'TODO: Add Debug Data
oFilteredProfiles.Add(oProfile)
oProfile.IsMatched = True
Dim oNode As New TreeNode($"Profile: {oProfile.Name}")
oNode.ImageIndex = 0
Dim f = New Font("Tahoma", 9, FontStyle.Bold)
oNode.NodeFont = f
_TreeView.Nodes.Add(oNode)
Dim oSubnode As New TreeNode($"MATCH on Global Clipboard Regex: {oProfile.Regex}")
oSubnode.ImageIndex = 1
oSubnode.Tag = oProfile.Name & "-REGEX"
oNode.Nodes.Add(oSubnode)
End If
Catch ex As Exception
_Logger.Warn("Regex '{0}' could not be processed for input '{1}'", oProfile.Regex, ClipboardContents)
_Logger.Error(ex)
End Try
Next
Return oFilteredProfiles
End Function
Public Function FilterProfilesByProcess(Profiles As List(Of ProfileData), CurrentProcessName As String) As List(Of ProfileData)
Dim oFilteredProfiles As New List(Of ProfileData)
Try
For Each oProfile In Profiles
Dim oGuid = oProfile.Guid
If oProfile.IsMatched = False Then
Continue For
End If
Dim oProcesses As New List(Of ProfileData.ProcessData)
For Each oProcessDef As ProfileData.ProcessData In oProfile.Processes
If oProcessDef.ProfileId <> oGuid Then
Continue For
End If
_Logger.Debug($"FilterProfilesByProcess: Checking Profile: {oProfile.Name} ...")
If oProcessDef.ProcessName.ToLower = CurrentProcessName.ToLower Then
_Logger.Debug($"Yes...Processname Matched: {oProcessDef.ProcessName}")
'oProfile.MATCH_PROCESSNAME = $"Processname Matched: {oProfile.ProcessName}"
'TODO: Add Debug Data
oFilteredProfiles.Add(oProfile)
oProfile.MatchedProcessID = oProcessDef.Guid
oProcessDef.IsMatched = True
oProcesses.Add(oProcessDef)
oProfile.IsMatched = True
oProfile.MatchedProcessID = oProcessDef.Guid
Dim oParentNode As TreeNode
Dim oExit = False
For Each oTreeNode As TreeNode In _TreeView.Nodes
For Each oNodes As TreeNode In oTreeNode.Nodes
If oExit = True Then Exit For
If oNodes.Tag = oProfile.Name & "-REGEX" Then
oParentNode = oNodes
oExit = True
Exit For
End If
Next
Next
If Not IsNothing(oParentNode) Then
Dim oNode As New TreeNode($"MATCH on Process: {oProcessDef.ProcessName}")
oNode.ImageIndex = 4
oNode.Tag = oProfile.Name & "-PROCESS"
oParentNode.Nodes.Add(oNode)
End If
End If
Next
If oFilteredProfiles.Count > 0 Then
oProfile.Processes = oProcesses
End If
Next
Return oFilteredProfiles
Catch ex As Exception
_Logger.Warn("Unexpected error in FilterProfilesByProcess...")
_Logger.Error(ex)
End Try
End Function
Public Function FilterWindowsByWindowTitleRegex(Profiles As List(Of ProfileData), WindowTitle As String) As List(Of ProfileData)
Dim oProfiles As New List(Of ProfileData)
For Each oProfile As ProfileData In Profiles
_Logger.Debug("Checking WindowDefinition for profile: {0}...", oProfile.Name)
If oProfile.IsMatched = False Then Continue For
Dim oWindows As New List(Of ProfileData.WindowData)
For Each oWindowDef As ProfileData.WindowData In oProfile.Windows
If oWindowDef.WindowProcessID <> oProfile.MatchedProcessID Then Continue For
Try
If oWindowDef.Regex = String.Empty Then
oProfile.MatchedWindowID = oWindowDef.Guid
oWindowDef.IsMatched = True
oWindows.Add(oWindowDef)
Exit For
End If
Dim oRegex As New Regex(oWindowDef.Regex)
Dim oMatch = oRegex.Match(WindowTitle)
If oMatch.Success Then
_Logger.Debug("MATCH on WindowTitle: {0}", WindowTitle)
'TODO: Add Debug Data
oProfile.MatchedWindowID = oWindowDef.Guid
oWindowDef.IsMatched = True
oWindows.Add(oWindowDef)
Dim olowestNode As TreeNode = Node_Get_Lowest_Node(oProfile.Name & "-REGEX")
If Not IsNothing(olowestNode) Then
Dim oNode As New TreeNode($"MATCH on WindowTitle: [{WindowTitle}]")
oNode.ImageIndex = 3
oNode.Tag = oProfile.Name & "-WINDOW"
olowestNode.Nodes.Add(oNode)
End If
Exit For
End If
Catch ex As Exception
_Logger.Warn("Regex '{0}' could not be processed for input '{1}'", oWindowDef.Regex, WindowTitle)
_Logger.Error(ex)
End Try
Next
If oWindows.Count > 0 Then
oProfile.Windows = oWindows
oProfile.IsMatched = True
oProfiles.Add(oProfile)
End If
Next
Return oProfiles
End Function
Public Function FilterWindowsByWindowClipboardRegex(Profiles As List(Of ProfileData), ClipboardContents As String) As List(Of ProfileData)
Dim oProfiles As New List(Of ProfileData)
For Each oProfile As ProfileData In Profiles
_Logger.Debug("Current Profile: {0}", oProfile.Name)
Dim oWindows As New List(Of ProfileData.WindowData)
For Each w As ProfileData.WindowData In oProfile.Windows
Try
If w.Regex = String.Empty Then
oWindows.Add(w)
End If
Dim oRegex As New Regex(w.Regex)
Dim oMatch = oRegex.Match(ClipboardContents)
If oMatch.Success Then
_Logger.Debug("Window Clipboard Regex Matched: {0}", ClipboardContents)
Dim oResult As TreeNode
For Each oTreeNode In _TreeView.Nodes
If Not IsNothing(oResult) Then Exit For
If oTreeNode.Tag = oProfile.Name & "-REGEX" Then
oResult = oTreeNode
End If
Next
If Not IsNothing(oResult) Then
Dim oNode As New TreeNode($"MATCH on WINDOW Clipboard Regex: [{w.Regex}]")
oNode.ImageIndex = 2
oNode.Tag = oProfile.Name & "-WINDOW_REGEX"
Dim olowestNode As TreeNode = GetLowestNode(oResult)
olowestNode.Nodes.Add(oNode)
End If
oWindows.Add(w)
End If
Catch ex As Exception
_Logger.Warn("Regex '{0}' could not be processed for input '{1}'", w.Regex, ClipboardContents)
_Logger.Error(ex)
End Try
Next
If oWindows.Count > 0 Then
oProfile.Windows = oWindows
oProfiles.Add(oProfile)
End If
Next
Return oProfiles
End Function
Public Function FilterProfilesByFocusedControl(Profiles As List(Of ProfileData), ClipboardContents As String, ControlFocusresult As String) As List(Of ProfileData)
Dim oWindow As Window.WindowInfo
Dim oFocusedControl As Window.WindowInfo
Dim oFocusedControlName As String = String.Empty
Try
oWindow = _Window.GetWindowInfo()
oFocusedControl = _Window.GetFocusedControl(oWindow.hWnd)
If oFocusedControl Is Nothing Then
_Logger.Info("Could not get FocusedControl in Window (Old method) {0}", oWindow.WindowTitle)
oFocusedControlName = String.Empty
Else
oFocusedControlName = oFocusedControl.ControlName
End If
Catch ex As Exception
_Logger.Warn("Error while getting Focused control (Old method)")
_Logger.Error(ex)
oFocusedControlName = String.Empty
End Try
Dim oFilteredProfiles As New List(Of ProfileData)
For Each oProfileMatchedSofar In Profiles
If oProfileMatchedSofar.IsMatched = False Then Continue For
_Logger.Debug("Checking ControlDefiniotion on profile: {0}", oProfileMatchedSofar.Name)
If oProfileMatchedSofar.Controls.Count = 0 Then
oFilteredProfiles.Add(oProfileMatchedSofar)
Dim oNode As New TreeNode($"No Controls configured!")
oNode.ImageIndex = 2
oNode.ForeColor = Color.Blue
oNode.Tag = oProfileMatchedSofar.Name & "-NOCONTROLCONFIG"
Dim f = New Font("Tahoma", 10, FontStyle.Bold)
oNode.NodeFont = f
_TreeView.Nodes.Add(oNode)
Continue For
End If
Dim oControls As New List(Of ProfileData.ControlData)
For Each oControlDefinition In oProfileMatchedSofar.Controls
Try
If oControlDefinition.WindowId <> oProfileMatchedSofar.MatchedWindowID Then Continue For
_Logger.Debug($"Working on ControlDefinition: {oControlDefinition.Guid}-{oControlDefinition.ControlName}...")
If oControlDefinition.Regex = String.Empty Then
oProfileMatchedSofar.MatchedControlID = oControlDefinition.Guid
oControlDefinition.IsMatched = True
oControls.Add(oControlDefinition)
Exit For
End If
'Dim oResult As TreeNode
'For Each oTreeNode In CurrMatchTreeView.Nodes
' oResult = NodeFind(oTreeNode, $"Global Clipboard Regex Matched [{oProfile.Regex}]")
'Next
'Dim oNode As TreeNode
Dim oNodeCaption As String
'Dim oAddNode As Boolean = False
Dim oRegex As New Regex(oControlDefinition.Regex)
Dim oFocusedControlResult As String = ""
If oControlDefinition.AutomationId <> String.Empty And oControlDefinition.ControlName = String.Empty Then
_Logger.Debug($"AutomationID should be used...")
If Not IsNothing(ControlFocusresult) Then
If ControlFocusresult <> String.Empty Then
_Logger.Debug($"AutomationID will be used...")
oFocusedControlResult = ControlFocusresult
End If
End If
ElseIf oControlDefinition.AutomationId = String.Empty And oControlDefinition.ControlName <> String.Empty Then
_Logger.Debug($"ControlName should be used...")
If Not IsNothing(oFocusedControlName) Then
If oFocusedControlName <> String.Empty Then
_Logger.Debug($"ControlName will be used...")
oFocusedControlResult = oFocusedControlName
End If
End If
End If
If oFocusedControlResult <> String.Empty Then
Dim oControlRegex As New Regex(oControlDefinition.Regex)
Dim oControlMatch = oRegex.Match(oFocusedControlResult)
If oControlMatch.Success Then
_Logger.Debug($"MATCH on Focused Control [{oFocusedControlResult}] with Regex [{oControlDefinition.Regex}]")
oProfileMatchedSofar.IsMatched = True
oProfileMatchedSofar.MatchedControlID = oControlDefinition.Guid
oControlDefinition.IsMatched = True
oControls.Add(oControlDefinition)
Dim olowestNode As TreeNode = Node_Get_Lowest_Node(oProfileMatchedSofar.Name & "-REGEX")
If Not IsNothing(olowestNode) Then
Dim oNode As New TreeNode($"MATCH on Focused Control [{oFocusedControlResult}] with Regex [{oControlDefinition.Regex}]")
oNode.ImageIndex = 2
oNode.Tag = oProfileMatchedSofar.Name & "-CONTROL"
olowestNode.Nodes.Add(oNode)
End If
Exit For
End If
End If
Catch ex As Exception
_Logger.Warn("Regex '{0}' could not be processed for input '{1}'", oControlDefinition.Regex, oFocusedControlName)
_Logger.Error(ex)
End Try
Next
If oControls.Count > 0 Then
oProfileMatchedSofar.Controls = oControls
oFilteredProfiles.Add(oProfileMatchedSofar)
Else
Dim olowestNode As TreeNode = Node_Get_Lowest_Node(oProfileMatchedSofar.Name & "-REGEX")
If Not IsNothing(olowestNode) Then
Dim oNode As New TreeNode($"NO MATCHES on Focused Control, Please check the Config")
oNode.ImageIndex = 2
oNode.Tag = oProfileMatchedSofar.Name & "-CONTROLNoMatch"
olowestNode.Nodes.Add(oNode)
End If
End If
Next
Return oFilteredProfiles
End Function
Private Function Node_Get_Lowest_Node(NodeTag As String) As TreeNode
Dim oExit = False
Dim oParentNode As TreeNode
For Each oTreeNode As TreeNode In _TreeView.Nodes
For Each oNodes As TreeNode In oTreeNode.Nodes
If oExit = True Then Exit For
If oNodes.Tag = NodeTag Then
oParentNode = oNodes
oExit = True
Exit For
End If
Next
Next
Dim olowestNode As TreeNode = GetLowestNode(oParentNode)
Return olowestNode
End Function
Public Function ClearNotMatchedProfiles(Profiles As List(Of ProfileData)) As List(Of ProfileData)
Dim oFilteredProfiles As New List(Of ProfileData)
For Each oProfile In Profiles
If oProfile.IsMatched Then
oFilteredProfiles.Add(oProfile)
End If
Next
Return oFilteredProfiles
End Function
Private Function TransformProfiles() As List(Of ProfileData)
Dim oList As New List(Of ProfileData)
For Each oRow As DataRow In _ProfileTable.Rows
Dim oProfileId = oRow.Item("GUID")
Dim oProcessList As List(Of ProfileData.ProcessData) = TransformProcesses(oProfileId, _ProcessTable)
Dim oWindowList As List(Of ProfileData.WindowData) = TransformWindows(oProfileId, _WindowTable)
Dim oControlList As List(Of ProfileData.ControlData) = TransformControls(oProfileId, _ControlTable)
oList.Add(New ProfileData() With {
.Guid = oRow.Item("GUID"),
.Regex = NotNull(oRow.Item("REGEX_EXPRESSION"), String.Empty),
.Name = NotNull(oRow.Item("NAME"), String.Empty),
.Comment = NotNull(oRow.Item("COMMENT"), String.Empty),
.ProfileType = NotNull(oRow.Item("PROFILE_TYPE"), String.Empty),
.Processes = oProcessList,
.Windows = oWindowList,
.Controls = oControlList
})
Next
Return oList
End Function
Private Function TransformControls(ProfileId As Integer, ControlDatatable As DataTable) As List(Of ProfileData.ControlData)
Dim oControlList As New List(Of ProfileData.ControlData)
For Each oRow As DataRow In ControlDatatable.Rows
If oRow.Item("PROFILE_ID") = ProfileId Then
oControlList.Add(New ProfileData.ControlData() With {
.Guid = oRow.Item("GUID"),
.Description = NotNull(oRow.Item("DESCRIPTION"), String.Empty),
.Regex = NotNull(oRow.Item("REGEX"), String.Empty),
.AutomationId = NotNull(oRow.Item("AUTOMATION_ID"), String.Empty),
.WindowId = oRow.Item("WINDOW_ID")
})
End If
Next
Return oControlList
End Function
Private Function TransformProcesses(ProfileId As Integer, ProcessDatatable As DataTable) As List(Of ProfileData.ProcessData)
Dim oProcessList As New List(Of ProfileData.ProcessData)
For Each oRow As DataRow In ProcessDatatable.Rows
oProcessList.Add(New ProfileData.ProcessData() With {
.Guid = oRow.Item("GUID"),
.ProfileId = oRow.Item("PROFILE_ID"),
.ProcessName = NotNull(oRow.Item("PROC_NAME"), String.Empty)
})
Next
Return oProcessList
End Function
Private Function TransformWindows(ProfileId As Integer, WindowDatatable As DataTable) As List(Of ProfileData.WindowData)
Dim oWindowList As New List(Of ProfileData.WindowData)
For Each oRow As DataRow In WindowDatatable.Rows
oWindowList.Add(New ProfileData.WindowData() With {
.Guid = oRow.Item("GUID"),
.WindowProcessID = oRow.Item("PROCESS_ID"),
.Title = NotNull(oRow.Item("DESCRIPTION"), String.Empty),
.Regex = NotNull(oRow.Item("REGEX"), String.Empty),
.Sequence = NotNull(oRow.Item("SEQUENCE"), 0)
})
Next
Return oWindowList
End Function
End Class