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 Public Function FilterProfilesBySearchResults(Profiles As List(Of ProfileData)) As List(Of ProfileData) Dim oProfiles As New List(Of ProfileData) For Each oProfile In Profiles Dim oResultDocs As Integer = 0 Dim oResultData As Integer = 0 Dim oPatterns As New ClassPatterns(My.LogConfig) Dim oDataSearches As DataTable = My.Database.GetDatatable($"SELECT COUNT_COMMAND FROM TBCW_PROF_DATA_SEARCH WHERE ACTIVE = 1 AND PROFILE_ID = {oProfile.Guid}") Dim oDocSearches As DataTable = My.Database.GetDatatable($"SELECT COUNT_COMMAND FROM TBCW_PROF_DOC_SEARCH WHERE ACTIVE = 1 AND PROFILE_ID = {oProfile.Guid}") For Each oRow As DataRow In oDataSearches.Rows Dim oCountCommand = String.Empty Try oCountCommand = NotNull(oRow.Item("COUNT_COMMAND"), String.Empty) If oCountCommand = String.Empty Then Continue For End If oCountCommand = oPatterns.ReplaceAllValues(oCountCommand, My.Application.User) oResultData += NotNull(Of Integer)(My.Database.GetScalarValue(oCountCommand), 0) Catch ex As Exception _Logger.Warn("Invalid SQL Query for Counting Data in Profile {0}: {1}", oProfile.Guid, oCountCommand) End Try Next For Each oRow As DataRow In oDocSearches.Rows Dim oCountCommand = String.Empty Try oCountCommand = NotNull(oRow.Item("COUNT_COMMAND"), String.Empty) If oCountCommand = String.Empty Then Continue For End If oCountCommand = oPatterns.ReplaceAllValues(oCountCommand, My.Application.User) oResultDocs += NotNull(Of Integer)(My.Database.GetScalarValue(oCountCommand), 0) Catch ex As Exception _Logger.Warn("Invalid SQL Query for Counting Data in Profile {0}: {1}", oProfile.Guid, oCountCommand) End Try Next If oResultData > 0 Or oResultDocs > 0 Then oProfile.CountData = oResultData oProfile.CountDocs = oResultDocs oProfiles.Add(oProfile) End If Next Return oProfiles 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