Imports System.Threading Imports System.Globalization Imports System.Drawing Imports System.Windows.Forms Imports DevExpress.XtraEditors Imports DigitalData.GUIs.Common Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Language Imports DigitalData.Modules.ZooFlow Imports DigitalData.Modules.ZooFlow.Params Imports DigitalData.Modules.ZooFlow.Constants ''' ''' ''' Selfcontained: ''' - Config (Location of Window) ''' ''' Environment: ''' - Pattern Replacement Values ''' - User Info (isAdmin, etc) ''' - License Info? ''' - ConnectionString ''' ''' Parameters: ''' - Matching Profiles as List Of ProfileData ''' - Clipboard Content as String ''' Public Class frmMatch Private ReadOnly _LogConfig As LogConfig Private ReadOnly _Logger As Logger Private ReadOnly _Environment As Environment Private ReadOnly _Params As ClipboardWatcherParams Private ReadOnly _Language As String Private ReadOnly PrimaryFont As New Font("Segoe UI", 12, FontStyle.Bold) Private ReadOnly SecondaryFont As New Font("Segoe UI", 10) Private ReadOnly TileForeColor As Color = Color.Black Private ReadOnly TileBackColor As Color = Color.FromArgb(255, 214, 47) Private ReadOnly OpenForms As New List(Of IResultForm) Private ShouldHideInitially As Boolean = False Private Const NO_COUNT_SQL As Integer = 99998 Private Const INVALID_COUNT_SQL As Integer = 99999 Private Enum ProfileType ANY = 0 DOCS_ONLY = 1 DATA_ONLY = 2 End Enum Public Sub New(LogConfig As LogConfig, Environment As Environment, Params As ClipboardWatcherParams) ' Dieser Aufruf ist für den Designer erforderlich. InitializeComponent() ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu. _LogConfig = LogConfig _Logger = LogConfig.GetLogger() _Environment = Environment _Params = Params _Language = Utils.NotNull(_Environment.User.Language, State.UserState.LANG_EN_US) Thread.CurrentThread.CurrentUICulture = New CultureInfo(_Language) End Sub Private Function GetResultString(CreatedTiles, MatchedProfiles, ClipboardContents) As String Dim oLanguage = Utils.NotNull(_Environment.User.Language, State.UserState.LANG_EN_US) Select Case _Language Case State.UserState.LANG_DE_DE Dim oResultString = IIf(CreatedTiles = 1, "wurde ein Ergebnis", $"wurden {CreatedTiles} Ergebnisse") Dim oProfileString = IIf(MatchedProfiles = 1, "einem Profil", $"{MatchedProfiles} Profilen") Dim oBase = "Es {0} in {1} für Ihre Suche nach '{2}' gefunden:" Return String.Format(oBase, oResultString, oProfileString, _Params.ClipboardContents) Case Else Dim oResultString = IIf(CreatedTiles = 1, "One Result was", $"{CreatedTiles} Results were") Dim oProfileString = IIf(MatchedProfiles = 1, "one Profile", $"{MatchedProfiles} Profiles") Dim oBase = "{0} found in {1} for your search for '{2}':" Return String.Format(oBase, oResultString, oProfileString, _Params.ClipboardContents) End Select End Function Private Function GetResultWindowString(ClipboardContents As String) As String If _Language = State.UserState.LANG_DE_DE Then Return $"Suche Nach '{_Params.ClipboardContents}'" Else Return $"Search For '{_Params.ClipboardContents}'" End If End Function Private Function GetTileString(Profile As ProfileData, [Type] As ProfileType) As String If _Language = State.UserState.LANG_DE_DE Then If [Type] = ProfileType.DATA_ONLY Then Return $"{Profile.CountData} Datensätze" Else Return $"{Profile.CountDocs} Dateien" End If End If If [Type] = ProfileType.DATA_ONLY Then Return $"{Profile.CountData} Data Records" Else Return $"{Profile.CountDocs} Files" End If End Function Private Async Sub frmMatch_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim oResult As Tuple(Of Integer, Integer) = CreateTiles() Dim oCreatedTiles As Integer = oResult.Item1 Dim oMatchedProfiles As Integer = oResult.Item2 Try SplashScreenManager1.ShowWaitForm() TileControlMatch.Enabled = False If oCreatedTiles = -1 Then Exit Sub End If If oCreatedTiles = 0 Then _Logger.Warn("No Tiles Created: No Results found for ""{0}""", _Params.ClipboardContents) Close() End If Label1.Text = GetResultString(oCreatedTiles, oMatchedProfiles, _Params.ClipboardContents) _Logger.Debug($"Created Tiles: {oCreatedTiles} ") _Logger.Debug($"Matched Profiles: {oMatchedProfiles}") If oCreatedTiles = 1 Then Dim oProfile As ProfileData = _Params.MatchingProfiles.First() Dim oProfileSearch As New ProfileSearches(_LogConfig, _Environment, _Params) If oProfile.CountDocs > 0 And oProfile.CountData = 0 Then _Logger.Debug($"ONLY Docs") 'ONLY DOCS AND NÒ DATA Dim oSearches = Await oProfileSearch.LoadDocumentSearchesAsync(oProfile.Guid) _Logger.Debug($"Searches executed") OpenDocumentResults(oProfile, oSearches) _Logger.Debug($"OpenDocumentResults finished") Hide() ElseIf oProfile.CountDocs > 0 And oProfile.CountData > 0 Then _Logger.Debug($"Docs AND Data") ElseIf oProfile.CountDocs = 0 And oProfile.CountData > 0 Then _Logger.Debug($"ONLY Data") Dim oSearches = Await oProfileSearch.LoadDataSearchesAsync(oProfile.Guid) OpenDataResults(oProfile, oSearches) Hide() End If End If Catch ex As Exception _Logger.Error(ex) Finally TileControlMatch.Enabled = True SplashScreenManager1.CloseWaitForm() End Try End Sub Private Sub frmMatch_Activated(sender As Object, e As EventArgs) Handles Me.Activated TopMost = True End Sub Function CreateTiles() As Tuple(Of Integer, Integer) Try Dim oCreatedTiles As Integer = 0 Dim oMatchedProfiles As Integer = 0 Dim oDocumentGroup = TileControlMatch.Groups.Item("TileGroupDocuments") Dim oDataGroup = TileControlMatch.Groups.Item("TileGroupData") Dim oDataDocumentsGroup = TileControlMatch.Groups.Item("TileGroupDocumentsData") oDocumentGroup.Items.Clear() oDataGroup.Items.Clear() For Each oProfile As ProfileData In _Params.MatchingProfiles 'TODO: Add Support for Combined Result Lists 'If oProfile.ProfileType = ProfileType.ANY Then ' If oProfile.CountData > 0 And oProfile.CountDocs > 0 Then ' Dim oCountText = oProfile.CountData + oProfile.CountDocs ' Dim oItem = CreateTile(oProfile, $"{oCountText} Ergebnisse") ' oDataDocumentsGroup.Items.Add(oItem) ' oCreatedTiles += 1 ' End If 'End If Dim oProfileMatch As Boolean = False _Logger.NewBlock($"Profile {oProfile.Name}") If oProfile.ProfileType = ProfileType.ANY Or oProfile.ProfileType = ProfileType.DOCS_ONLY Then _Logger.Debug("ProfileType: DOCS_ONLY or ANY") If oProfile.CountDocs > 0 Then Dim oItem = CreateTile(oProfile, GetTileString(oProfile, ProfileType.DOCS_ONLY)) oDocumentGroup.Items.Add(oItem) oCreatedTiles += 1 oProfileMatch = True _Logger.Debug("{0} Doc-Results!", oProfile.CountDocs) Else _Logger.Debug("NO Doc-Results!") End If End If If oProfile.ProfileType = ProfileType.ANY Or oProfile.ProfileType = ProfileType.DATA_ONLY Then _Logger.Debug("ProfileType: DATA_ONLY or ANY") If oProfile.CountData > 0 Then Dim oItem = CreateTile(oProfile, GetTileString(oProfile, ProfileType.DATA_ONLY)) oDataGroup.Items.Add(oItem) oCreatedTiles += 1 oProfileMatch = True _Logger.Debug("{0} Data-Results!", oProfile.CountData) Else _Logger.Debug("NO Data-Results!") End If End If If oProfileMatch Then oMatchedProfiles += 1 End If Next Return New Tuple(Of Integer, Integer)(oCreatedTiles, oMatchedProfiles) Catch ex As Exception _Logger.Error(ex) MsgBox("Error while creating profile tiles!" & vbNewLine & ex.Message) Return New Tuple(Of Integer, Integer)(-1, -1) End Try End Function Private Function CreateTile(Profile As ProfileData, CountText As String) As TileItem Dim oItem As New TileItem() With {.Tag = Profile.Guid} oItem.AppearanceItem.Normal.BackColor = TileBackColor oItem.Elements.Clear() Dim oNameElement = New TileItemElement With { .Text = Profile.Name, .TextAlignment = TileItemContentAlignment.TopLeft } oNameElement.Appearance.Normal.Font = PrimaryFont oNameElement.Appearance.Normal.ForeColor = TileForeColor oItem.Elements.Add(oNameElement) Dim oCommentElement = New TileItemElement With { .Text = Profile.Comment, .TextAlignment = TileItemContentAlignment.MiddleLeft } oCommentElement.Appearance.Normal.Font = SecondaryFont oCommentElement.Appearance.Normal.ForeColor = TileForeColor oItem.Elements.Add(oCommentElement) Dim oCountElement = New TileItemElement With { .Text = GetCountText(Profile, CountText), .TextAlignment = TileItemContentAlignment.BottomRight } oCountElement.Appearance.Normal.Font = SecondaryFont oCountElement.Appearance.Normal.ForeColor = TileForeColor oItem.Elements.Add(oCountElement) Return oItem End Function Private Function GetCountText(Profile As ProfileData, CountText As String) As String Dim oText As String = "No implemented" If Profile.CountData = INVALID_COUNT_SQL Then oText = "Invalid SQL!" ElseIf Profile.CountData = NO_COUNT_SQL Then oText = "No SQL!" Else oText = CountText End If If Profile.CountDocs = INVALID_COUNT_SQL Then oText = "Invalid SQL!" ElseIf Profile.CountDocs = NO_COUNT_SQL Then oText = "No SQL!" Else oText = CountText End If Return oText End Function Private Sub Label2_Click(sender As Object, e As EventArgs) Handles Label2.Click Dim oForm As New frmTreeView(_Params.MatchTreeView.Nodes) With { .StartPosition = FormStartPosition.Manual, .Left = Left + Width, .Top = Top } oForm.ShowDialog() End Sub Private Async Sub TileControlMatch_ItemClick(sender As Object, e As TileItemEventArgs) Handles TileControlMatch.ItemClick Try SplashScreenManager1.ShowWaitForm() TileControlMatch.Enabled = False Dim oItem As TileItem = e.Item Dim oProfileId As Integer = oItem.Tag Dim oProfileSearch As New ProfileSearches(_LogConfig, _Environment, _Params) Dim oProfile As ProfileData = _Params.MatchingProfiles. Where(Function(p) p.Guid = oProfileId). ToList(). First() Select Case oItem.Group.Name Case TileGroupData.Name Dim oSearches = Await oProfileSearch.LoadDataSearchesAsync(oProfileId) OpenDataResults(oProfile, oSearches) Case TileGroupDocuments.Name Dim oSearches = Await oProfileSearch.LoadDocumentSearchesAsync(oProfileId) OpenDocumentResults(oProfile, oSearches) Case Else ' TODO: Load combined results 'OpenResultForms(oProfileId, ProfileType.ANY) End Select Hide() Catch ex As Exception MsgBox($"Error while loading Searches: " & vbNewLine & ex.Message, MsgBoxStyle.Critical, Text) _Logger.Error(ex) Finally SplashScreenManager1.CloseWaitForm() TileControlMatch.Enabled = True End Try End Sub Private Sub OpenDocumentResults(Profile As ProfileData, Searches As List(Of ProfileSearches.Search)) Dim oNameSlug = Utils.ConvertTextToSlug(Profile.Name) Dim oSearchGuids = Searches.Select(Function(s) s.Guid).ToArray Dim oWindowGuid = $"{Profile.Guid}-{oNameSlug}-{String.Join("-", oSearchGuids)}" Dim oParams = New DocumentResultParams() With { .WindowGuid = oWindowGuid, .WindowTitle = GetResultWindowString(_Params.ClipboardContents), .OperationModeOverride = _Params.OperationModeOverride } For Each oSearch In Searches oParams.Results.Add(New DocumentResult() With { .Title = oSearch.TabCaption, .Datatable = oSearch.DataTable }) Next Dim oForm As New frmDocumentResultList(_LogConfig, _Environment, oParams) AddHandler oForm.FormClosed, AddressOf ProfileResultForm_Closed OpenForms.Add(oForm) oForm.Show() End Sub Private Sub OpenDataResults(Profile As ProfileData, Searches As List(Of ProfileSearches.Search)) Dim oNameSlug = Utils.ConvertTextToSlug(Profile.Name) Dim oSearchGuids = Searches.Select(Function(s) s.Guid).ToArray Dim oWindowGuid = $"{Profile.Guid}-{oNameSlug}-{String.Join("-", oSearchGuids)}" Dim oParams = New DataResultParams() With { .WindowGuid = oWindowGuid } For Each oSearch In Searches oParams.Results.Add(New DataResult() With { .Title = oSearch.TabCaption, .Datatable = oSearch.DataTable }) Next Dim oForm As New frmDataResultList(_LogConfig, _Environment, oParams) AddHandler oForm.FormClosed, AddressOf ProfileResultForm_Closed OpenForms.Add(oForm) oForm.Show() End Sub Private Sub ProfileResultForm_Closed(sender As Object, e As FormClosedEventArgs) Dim oShouldOpenAgain As Boolean = False Dim oThisForm = New List(Of IResultForm) From {sender} If TypeOf sender Is frmDataResultList Or TypeOf sender Is frmDocumentResultList Then For Each oForm As IResultForm In OpenForms ' Determine if frmProfileMatch should be shown If oForm.ShouldReturnToPreviousForm Then oShouldOpenAgain = True End If Next End If ' If frmProfileMatch should be shown, close all windows of this profile If oShouldOpenAgain Then For Each oForm As Form In OpenForms.Except(oThisForm) ' Remove the Handler to prevent a loop RemoveHandler oForm.FormClosed, AddressOf ProfileResultForm_Closed oForm.Close() Next Show() End If End Sub End Class