From f5ec035772b877b711bbbeebafe9276ceca840ec Mon Sep 17 00:00:00 2001 From: Jonathan Jenne Date: Tue, 18 Jan 2022 13:27:20 +0100 Subject: [PATCH] Common: Rework of DocumentResultList WIP --- GUIs.ClipboardWatcher/frmMatch.vb | 4 +- GUIs.Common/Common.vbproj | 23 +-- .../DataResultList/frmDataResultList.vb | 4 +- GUIs.Common/DocumentResultList/Cache.vb | 120 ++++++++++++ GUIs.Common/DocumentResultList/Config.vb | 13 ++ GUIs.Common/DocumentResultList/Document.vb | 35 ++++ .../DocumentResultList/DocumentLoader.vb | 102 ----------- .../DocumentResultList/DocumentResultCache.vb | 116 ------------ .../DocumentResultConfig.vb | 10 - .../DocumentResultList/DocumentResultInfo.vb | 33 ---- .../DocumentResultList/DocumentResultList.vb | 61 ------- .../DocumentResultParams.vb | 23 --- GUIs.Common/DocumentResultList/Helpers.vb | 63 +++++++ GUIs.Common/DocumentResultList/Loader.vb | 105 +++++++++++ GUIs.Common/DocumentResultList/Opener.vb | 51 ++++++ GUIs.Common/DocumentResultList/Params.vb | 26 +++ GUIs.Common/My Project/licenses.licx | 3 + .../frmDocumentResultList.Designer.vb | 0 .../frmDocumentResultList.en-US.resx | 0 .../frmDocumentResultList.fr-FR.resx | 0 .../frmDocumentResultList.resx | 0 .../frmDocumentResultList.vb | 171 ++++++------------ GUIs.ZooFlow/Search/frmFlowSearch.vb | 4 +- GUIs.ZooFlow/Search/frmSearchStart.vb | 4 +- 24 files changed, 490 insertions(+), 481 deletions(-) create mode 100644 GUIs.Common/DocumentResultList/Cache.vb create mode 100644 GUIs.Common/DocumentResultList/Config.vb create mode 100644 GUIs.Common/DocumentResultList/Document.vb delete mode 100644 GUIs.Common/DocumentResultList/DocumentLoader.vb delete mode 100644 GUIs.Common/DocumentResultList/DocumentResultCache.vb delete mode 100644 GUIs.Common/DocumentResultList/DocumentResultConfig.vb delete mode 100644 GUIs.Common/DocumentResultList/DocumentResultInfo.vb delete mode 100644 GUIs.Common/DocumentResultList/DocumentResultList.vb delete mode 100644 GUIs.Common/DocumentResultList/DocumentResultParams.vb create mode 100644 GUIs.Common/DocumentResultList/Helpers.vb create mode 100644 GUIs.Common/DocumentResultList/Loader.vb create mode 100644 GUIs.Common/DocumentResultList/Opener.vb create mode 100644 GUIs.Common/DocumentResultList/Params.vb rename GUIs.Common/{DocumentResultList => }/frmDocumentResultList.Designer.vb (100%) rename GUIs.Common/{DocumentResultList => }/frmDocumentResultList.en-US.resx (100%) rename GUIs.Common/{DocumentResultList => }/frmDocumentResultList.fr-FR.resx (100%) rename GUIs.Common/{DocumentResultList => }/frmDocumentResultList.resx (100%) rename GUIs.Common/{DocumentResultList => }/frmDocumentResultList.vb (86%) diff --git a/GUIs.ClipboardWatcher/frmMatch.vb b/GUIs.ClipboardWatcher/frmMatch.vb index cc5f7ac9..e345b9bc 100644 --- a/GUIs.ClipboardWatcher/frmMatch.vb +++ b/GUIs.ClipboardWatcher/frmMatch.vb @@ -342,14 +342,14 @@ Public Class frmMatch 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 { + Dim oParams = New DocumentResultList.Params() With { .WindowGuid = oWindowGuid, .WindowTitle = GetResultWindowString(_Params.ClipboardContents), .OperationModeOverride = _Params.OperationModeOverride } For Each oSearch In Searches - oParams.Results.Add(New DocumentResult() With { + oParams.Results.Add(New DocumentResultList.DocumentResult() With { .Title = oSearch.TabCaption, .Datatable = oSearch.DataTable }) diff --git a/GUIs.Common/Common.vbproj b/GUIs.Common/Common.vbproj index 07dbebca..8c51b766 100644 --- a/GUIs.Common/Common.vbproj +++ b/GUIs.Common/Common.vbproj @@ -107,18 +107,19 @@ Form - - - - - - + + + + + + + frmDocumentResultList.vb - + Form - + @@ -148,13 +149,13 @@ frmDataResultList.vb - + frmDocumentResultList.vb - + frmDocumentResultList.vb - + frmDocumentResultList.vb diff --git a/GUIs.Common/DataResultList/frmDataResultList.vb b/GUIs.Common/DataResultList/frmDataResultList.vb index 57b20cb1..c4a080b4 100644 --- a/GUIs.Common/DataResultList/frmDataResultList.vb +++ b/GUIs.Common/DataResultList/frmDataResultList.vb @@ -27,7 +27,7 @@ Public Class frmDataResultList Private _ActiveGrid As GridControl = Nothing Private _ActiveGridBand As GridBand = Nothing - Private _Helpers As DocumentResultList + Private _Helpers As DocumentResultList.Helpers Public Property ShouldReturnToPreviousForm As Boolean Implements IResultForm.ShouldReturnToPreviousForm @@ -43,7 +43,7 @@ Public Class frmDataResultList _LogConfig = LogConfig _Logger = LogConfig.GetLogger() _Config = New ConfigManager(Of DataResultConfig)(LogConfig, oConfigPath, Application.StartupPath) - _Helpers = New DocumentResultList(_LogConfig) + _Helpers = New DocumentResultList.Helpers(_LogConfig) _Environment = Environment _Params = Params _ResultLists = Params.Results diff --git a/GUIs.Common/DocumentResultList/Cache.vb b/GUIs.Common/DocumentResultList/Cache.vb new file mode 100644 index 00000000..1285cd5d --- /dev/null +++ b/GUIs.Common/DocumentResultList/Cache.vb @@ -0,0 +1,120 @@ +Imports DigitalData.Modules.EDMI.API.Client + +Namespace DocumentResultList + + Public Class Cache + Implements ICollection(Of Document) + + Private Const _DefaultCapacity As Long = 1000 + + Public Shared ReadOnly Property DefaultCapacity As Long + Get + Return _DefaultCapacity + End Get + End Property + + Friend ReadOnly List As New LinkedList(Of Document) + Private ReadOnly Index As New Dictionary(Of String, LinkedListNode(Of Document)) + Private ReadOnly Lock As New Object + + Public Sub New() + Me.New(_DefaultCapacity) + End Sub + + Public Sub New(capacity As Long) + If capacity < 0 Then + Throw New InvalidOperationException("DocumentResultCache capacity must be positive.") + End If + + Me.Capacity = capacity + End Sub + + Public Event DiscardingOldestItem As EventHandler + Public Property Capacity As Long + Public Property Count As Integer Implements ICollection(Of Document).Count + + Public ReadOnly Property Oldest As Document + Get + Return List.First.Value + End Get + End Property + + Public Sub Add(pItem As Document) Implements ICollection(Of Document).Add + SyncLock Lock + If Index.ContainsKey(pItem.Id) Then + List.Remove(Index(pItem.Id)) + Index(pItem.Id) = List.AddLast(pItem) + Return + End If + + If Count >= Capacity AndAlso Capacity <> 0 Then + RaiseEvent DiscardingOldestItem(Me, New EventArgs()) + Remove(Oldest) + End If + + Index.Add(pItem.Id, List.AddLast(pItem)) + + If pItem.Contents IsNot Nothing Then + Count += pItem.Contents?.Length + End If + End SyncLock + End Sub + + Public Function Contains(pItem As Document) As Boolean Implements ICollection(Of Document).Contains + Return Index.ContainsKey(pItem.Id) + End Function + + Public Sub CopyTo(pArray As Document(), pIndex As Integer) Implements ICollection(Of Document).CopyTo + SyncLock Lock + For Each item As Document In Me + pArray(Math.Min(System.Threading.Interlocked.Increment(pIndex), pIndex - 1)) = item + Next + End SyncLock + End Sub + + Public Sub Clear() Implements ICollection(Of Document).Clear + SyncLock Lock + List.Clear() + Index.Clear() + End SyncLock + End Sub + + Public ReadOnly Property IsReadOnly As Boolean Implements ICollection(Of Document).IsReadOnly + Get + Return False + End Get + End Property + + Public Function Remove(pItem As Document) As Boolean Implements ICollection(Of Document).Remove + SyncLock Lock + + If Index.ContainsKey(pItem.Id) Then + List.Remove(Index(pItem.Id)) + Index.Remove(pItem.Id) + + If pItem.Contents IsNot Nothing Then + Count -= pItem.Contents.Length + End If + + Return True + End If + + Return False + End SyncLock + End Function + + Private Iterator Function GetEnumerator() As IEnumerator(Of Document) Implements ICollection(Of Document).GetEnumerator + Dim node As LinkedListNode(Of Document) = List.First + + While node IsNot Nothing + Yield node.Value + node = node.[Next] + End While + End Function + + Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator + Return DirectCast(List, IEnumerable).GetEnumerator() + End Function + End Class +End Namespace + diff --git a/GUIs.Common/DocumentResultList/Config.vb b/GUIs.Common/DocumentResultList/Config.vb new file mode 100644 index 00000000..63e1640f --- /dev/null +++ b/GUIs.Common/DocumentResultList/Config.vb @@ -0,0 +1,13 @@ +Imports System.Drawing + +Namespace DocumentResultList + Public Class Config + Public Property WindowLocation As Point + Public Property WindowSize As Size + Public Property SplitContainer1Distance As Integer = 500 + Public Property SplitContainer1Horizontal As Boolean = True + Public Property SplitContainer2Distance As Integer = 250 + Public Property SplitContainer2Horizontal As Boolean = False + End Class + +End Namespace \ No newline at end of file diff --git a/GUIs.Common/DocumentResultList/Document.vb b/GUIs.Common/DocumentResultList/Document.vb new file mode 100644 index 00000000..13052367 --- /dev/null +++ b/GUIs.Common/DocumentResultList/Document.vb @@ -0,0 +1,35 @@ +Imports DigitalData.Modules.EDMI.API.Client +Imports DigitalData.Modules.EDMI.API.Rights + +Namespace DocumentResultList + Public Class Document + ''' + ''' Primary identifier of the Document. + ''' Can be a Windream DocId or an IDB ObjectId. + ''' + Public Property Id As Long + + Public Property AccessRight As AccessRight + + ''' + ''' Extension is needed for determining the type of file + ''' and showing it in the DocumentViewer + ''' + Public Property Extension As String + ''' + ''' Binary contents of the file. + ''' + Public Property Contents As Byte() + + + + ' Optional properties + Public Property LastWriteTime As Date = Nothing + Public Property FullPath As String = Nothing + Public Property TempPath As String = Nothing + + Public Sub New(pPrimaryKey As Long) + Id = pPrimaryKey + End Sub + End Class +End Namespace \ No newline at end of file diff --git a/GUIs.Common/DocumentResultList/DocumentLoader.vb b/GUIs.Common/DocumentResultList/DocumentLoader.vb deleted file mode 100644 index 03aacfde..00000000 --- a/GUIs.Common/DocumentResultList/DocumentLoader.vb +++ /dev/null @@ -1,102 +0,0 @@ -Imports System.IO -Imports DigitalData.Modules.EDMI.API -Imports DigitalData.Modules.EDMI.API.Client -Imports DigitalData.Modules.EDMI.API.EDMIServiceReference -Imports DigitalData.Modules.Logging -Imports DigitalData.Modules.ZooFlow.Constants -Imports DigitalData.Modules.ZooFlow.State - -Public Class DocumentLoader - Inherits Modules.ZooFlow.Base.BaseClass - - Private ReadOnly Client As Client - Private ReadOnly Mode As OperationMode - Private ReadOnly User As DigitalData.Modules.ZooFlow.State.UserState - - Public Sub New(pLogConfig As LogConfig, pMode As OperationMode, pClient As Client, pUser As DigitalData.Modules.ZooFlow.State.UserState) - MyBase.New(pLogConfig) - Client = pClient - Mode = pMode - User = pUser - End Sub - - Public Function Load(pObjectId As Long, pFullPath As String) As DocumentResultInfo - Select Case Mode - Case OperationMode.NoAppServer - Return Load_FromWindream(pObjectId, pFullPath) - - Case OperationMode.WithAppServer - Return Load_FromIDB(pObjectId) - - Case OperationMode.ZooFlow - Return Load_FromZooflow(pObjectId) - - Case Else - Return Nothing - End Select - End Function - - Private Function Load_FromWindream(pObjectId As Long, pFullPath As String) As DocumentResultInfo - Dim oFileInfo As New FileInfo(pFullPath) - Dim oResultDocumentInfo = New DocumentResultInfo(pObjectId) With { - .Contents = Load_FromDisk(pFullPath), - .AccessRight = Rights.AccessRight.FULL, - .FullPath = pFullPath, - .Extension = oFileInfo.Extension.Substring(1) - } - - Return oResultDocumentInfo - End Function - - Private Function Load_FromIDB(pObjectId As Long) As DocumentResultInfo - Try - Dim oDocumentInfo As DocumentInfo = Client.GetDocumentInfo(User.UserId, pObjectId) - Dim oFileInfo As New FileInfo(oDocumentInfo.FullPath) - Dim oResultDocumentInfo As New DocumentResultInfo(pObjectId) With { - .Contents = Load_FromDisk(oDocumentInfo.FullPath), - .AccessRight = oDocumentInfo.AccessRight, - .FullPath = oDocumentInfo.FullPath, - .Extension = oFileInfo.Extension.Substring(1) - } - - Return oResultDocumentInfo - Catch ex As Exception - Logger.Error(ex) - Return Nothing - End Try - End Function - - Private Function Load_FromZooflow(pObjectId As Long) As DocumentResultInfo - Dim oFileObject As FileObject = Client.Zooflow_GetFileObject(pObjectId, pLoadFileContents:=True) - - If oFileObject Is Nothing Then - Return Nothing - End If - - Dim oResultDocumentInfo As New DocumentResultInfo(pObjectId) With { - .Contents = oFileObject._FileContents, - .Extension = oFileObject._FileExtension, - .AccessRight = Rights.AccessRight.FULL, - .FullPath = Nothing - } - - Return oResultDocumentInfo - End Function - - Private Function Load_FromDisk(pFullPath) As Byte() - Try - Logger.Debug("Loading file [{0}]", pFullPath) - Using oStream = File.OpenRead(pFullPath) - Using oMemoryStream = New MemoryStream() - oStream.CopyTo(oMemoryStream) - Logger.Debug("Loaded file [{0}] successfully.", pFullPath) - Return oMemoryStream.ToArray() - End Using - End Using - Catch ex As Exception - Logger.Warn("Loading file [{0}] failed.", pFullPath) - Logger.Error(ex) - Return Nothing - End Try - End Function -End Class diff --git a/GUIs.Common/DocumentResultList/DocumentResultCache.vb b/GUIs.Common/DocumentResultList/DocumentResultCache.vb deleted file mode 100644 index a9068712..00000000 --- a/GUIs.Common/DocumentResultList/DocumentResultCache.vb +++ /dev/null @@ -1,116 +0,0 @@ -Imports DigitalData.Modules.EDMI.API.Client - -Public Class DocumentResultCache - Implements ICollection(Of DocumentResultInfo) - - Private Const _DefaultCapacity As Long = 1000 - - Public Shared ReadOnly Property DefaultCapacity As Long - Get - Return _DefaultCapacity - End Get - End Property - - Friend ReadOnly List As New LinkedList(Of DocumentResultInfo) - Private ReadOnly Index As New Dictionary(Of String, LinkedListNode(Of DocumentResultInfo)) - Private ReadOnly Lock As New Object - - Public Sub New() - Me.New(_DefaultCapacity) - End Sub - - Public Sub New(capacity As Long) - If capacity < 0 Then - Throw New InvalidOperationException("DocumentResultCache capacity must be positive.") - End If - - Me.Capacity = capacity - End Sub - - Public Event DiscardingOldestItem As EventHandler - Public Property Capacity As Long - Public Property Count As Integer Implements ICollection(Of DocumentResultInfo).Count - - Public ReadOnly Property Oldest As DocumentResultInfo - Get - Return List.First.Value - End Get - End Property - - Public Sub Add(pItem As DocumentResultInfo) Implements ICollection(Of DocumentResultInfo).Add - SyncLock Lock - If Index.ContainsKey(pItem.Id) Then - List.Remove(Index(pItem.Id)) - Index(pItem.Id) = List.AddLast(pItem) - Return - End If - - If Count >= Capacity AndAlso Capacity <> 0 Then - RaiseEvent DiscardingOldestItem(Me, New EventArgs()) - Remove(Oldest) - End If - - Index.Add(pItem.Id, List.AddLast(pItem)) - - If pItem.Contents IsNot Nothing Then - Count += pItem.Contents?.Length - End If - End SyncLock - End Sub - - Public Function Contains(pItem As DocumentResultInfo) As Boolean Implements ICollection(Of DocumentResultInfo).Contains - Return Index.ContainsKey(pItem.Id) - End Function - - Public Sub CopyTo(pArray As DocumentResultInfo(), pIndex As Integer) Implements ICollection(Of DocumentResultInfo).CopyTo - SyncLock Lock - For Each item As DocumentResultInfo In Me - pArray(Math.Min(System.Threading.Interlocked.Increment(pIndex), pIndex - 1)) = item - Next - End SyncLock - End Sub - - Public Sub Clear() Implements ICollection(Of DocumentResultInfo).Clear - SyncLock Lock - List.Clear() - Index.Clear() - End SyncLock - End Sub - - Public ReadOnly Property IsReadOnly As Boolean Implements ICollection(Of DocumentResultInfo).IsReadOnly - Get - Return False - End Get - End Property - - Public Function Remove(pItem As DocumentResultInfo) As Boolean Implements ICollection(Of DocumentResultInfo).Remove - SyncLock Lock - - If Index.ContainsKey(pItem.Id) Then - List.Remove(Index(pItem.Id)) - Index.Remove(pItem.Id) - - If pItem.Contents IsNot Nothing Then - Count -= pItem.Contents.Length - End If - - Return True - End If - - Return False - End SyncLock - End Function - - Private Iterator Function GetEnumerator() As IEnumerator(Of DocumentResultInfo) Implements ICollection(Of DocumentResultInfo).GetEnumerator - Dim node As LinkedListNode(Of DocumentResultInfo) = List.First - - While node IsNot Nothing - Yield node.Value - node = node.[Next] - End While - End Function - - Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator - Return DirectCast(List, IEnumerable).GetEnumerator() - End Function -End Class diff --git a/GUIs.Common/DocumentResultList/DocumentResultConfig.vb b/GUIs.Common/DocumentResultList/DocumentResultConfig.vb deleted file mode 100644 index 72061369..00000000 --- a/GUIs.Common/DocumentResultList/DocumentResultConfig.vb +++ /dev/null @@ -1,10 +0,0 @@ -Imports System.Drawing - -Public Class DocumentResultConfig - Public Property WindowLocation As Point - Public Property WindowSize As Size - Public Property SplitContainer1Distance As Integer = 500 - Public Property SplitContainer1Horizontal As Boolean = True - Public Property SplitContainer2Distance As Integer = 250 - Public Property SplitContainer2Horizontal As Boolean = False -End Class diff --git a/GUIs.Common/DocumentResultList/DocumentResultInfo.vb b/GUIs.Common/DocumentResultList/DocumentResultInfo.vb deleted file mode 100644 index bb151ea3..00000000 --- a/GUIs.Common/DocumentResultList/DocumentResultInfo.vb +++ /dev/null @@ -1,33 +0,0 @@ -Imports DigitalData.Modules.EDMI.API.Client -Imports DigitalData.Modules.EDMI.API.Rights - -Public Class DocumentResultInfo - ''' - ''' Primary identifier of the Document. - ''' Can be a Windream DocId or an IDB ObjectId. - ''' - Public Property Id As Long - - Public Property AccessRight As AccessRight - - ''' - ''' Extension is needed for determining the type of file - ''' and showing it in the DocumentViewer - ''' - Public Property Extension As String - ''' - ''' Binary contents of the file. - ''' - Public Property Contents As Byte() - - - - ' Optional properties - Public Property LastWriteTime As Date = Nothing - Public Property FullPath As String = Nothing - Public Property TempPath As String = Nothing - - Public Sub New(pPrimaryKey As Long) - Id = pPrimaryKey - End Sub -End Class \ No newline at end of file diff --git a/GUIs.Common/DocumentResultList/DocumentResultList.vb b/GUIs.Common/DocumentResultList/DocumentResultList.vb deleted file mode 100644 index b52c6ac5..00000000 --- a/GUIs.Common/DocumentResultList/DocumentResultList.vb +++ /dev/null @@ -1,61 +0,0 @@ -Imports System.Drawing -Imports System.IO -Imports DevExpress.XtraGrid.Views.Base -Imports DigitalData.Modules.Logging - -Public Class DocumentResultList - Private ReadOnly Logger As Logger - - Public Property ActiveRowHandle As Integer = Constants.NO_ROW_HANDLE - - Public Sub New(LogConfig As LogConfig) - Logger = LogConfig.GetLogger() - End Sub - - Public Sub SetRowHandle(e As FocusedRowChangedEventArgs) - ActiveRowHandle = e.FocusedRowHandle - End Sub - - Public Function GetIconByExtension(FilePath As String) As Bitmap - Dim oFileextension = Path.GetExtension(FilePath) - - Select Case oFileextension.ToUpper - Case ".csv".ToUpper - Return My.Resources.xls - Case ".txt".ToUpper - Return My.Resources.txt - Case ".pdf".ToUpper - Return My.Resources.pdf - Case ".doc".ToUpper - Return My.Resources.doc - Case ".docx".ToUpper - Return My.Resources.doc - Case ".xls".ToUpper - Return My.Resources.xls - Case ".xlsx".ToUpper - Return My.Resources.xls - Case ".xlsm".ToUpper - Return My.Resources.xls - Case ".ppt".ToUpper - Return My.Resources.ppt - Case ".pptx".ToUpper - Return My.Resources.ppt - Case ".dwg".ToUpper - Return My.Resources.dwg - Case ".dxf".ToUpper - Return My.Resources.dxf - Case ".msg".ToUpper - Return My.Resources._page - Case ".msg".ToUpper - Return My.Resources._page - Case ".tif".ToUpper - Return My.Resources.tiff - Case ".tiff".ToUpper - Return My.Resources.tiff - Case ".jpg".ToUpper - Return My.Resources.jpg - Case Else - Return My.Resources._blank - End Select - End Function -End Class diff --git a/GUIs.Common/DocumentResultList/DocumentResultParams.vb b/GUIs.Common/DocumentResultList/DocumentResultParams.vb deleted file mode 100644 index b02e086b..00000000 --- a/GUIs.Common/DocumentResultList/DocumentResultParams.vb +++ /dev/null @@ -1,23 +0,0 @@ -Imports DigitalData.Modules.ZooFlow.Constants - -Public Class DocumentResultParams - ''' - ''' WindowGuid is used to save layout data - ''' - Public WindowGuid As String - Public WindowTitle As String = "" - Public Results As New List(Of DocumentResult) - Public ColumnNames As New ColumnNames - Public OperationModeOverride As OperationMode = OperationMode.None -End Class - -Public Class DocumentResult - Inherits BaseResult -End Class - -Public Class ColumnNames - Public ObjectIdColumn As String = "DocId" - Public FullPathColumn As String = "FULL_FILENAME" - Public FilenameColumn As String = "Name" - Public IconColumn As String = "ICON" -End Class diff --git a/GUIs.Common/DocumentResultList/Helpers.vb b/GUIs.Common/DocumentResultList/Helpers.vb new file mode 100644 index 00000000..64bfac6d --- /dev/null +++ b/GUIs.Common/DocumentResultList/Helpers.vb @@ -0,0 +1,63 @@ +Imports System.Drawing +Imports System.IO +Imports DevExpress.XtraGrid.Views.Base +Imports DigitalData.Modules.Logging + +Namespace DocumentResultList + Public Class Helpers + Private ReadOnly Logger As Logger + + Public Property ActiveRowHandle As Integer = Constants.NO_ROW_HANDLE + + Public Sub New(LogConfig As LogConfig) + Logger = LogConfig.GetLogger() + End Sub + + Public Sub SetRowHandle(e As FocusedRowChangedEventArgs) + ActiveRowHandle = e.FocusedRowHandle + End Sub + + Public Function GetIconByExtension(FilePath As String) As Bitmap + Dim oFileextension = Path.GetExtension(FilePath) + + Select Case oFileextension.ToUpper + Case ".csv".ToUpper + Return My.Resources.xls + Case ".txt".ToUpper + Return My.Resources.txt + Case ".pdf".ToUpper + Return My.Resources.pdf + Case ".doc".ToUpper + Return My.Resources.doc + Case ".docx".ToUpper + Return My.Resources.doc + Case ".xls".ToUpper + Return My.Resources.xls + Case ".xlsx".ToUpper + Return My.Resources.xls + Case ".xlsm".ToUpper + Return My.Resources.xls + Case ".ppt".ToUpper + Return My.Resources.ppt + Case ".pptx".ToUpper + Return My.Resources.ppt + Case ".dwg".ToUpper + Return My.Resources.dwg + Case ".dxf".ToUpper + Return My.Resources.dxf + Case ".msg".ToUpper + Return My.Resources._page + Case ".msg".ToUpper + Return My.Resources._page + Case ".tif".ToUpper + Return My.Resources.tiff + Case ".tiff".ToUpper + Return My.Resources.tiff + Case ".jpg".ToUpper + Return My.Resources.jpg + Case Else + Return My.Resources._blank + End Select + End Function + End Class +End Namespace diff --git a/GUIs.Common/DocumentResultList/Loader.vb b/GUIs.Common/DocumentResultList/Loader.vb new file mode 100644 index 00000000..18ec0d42 --- /dev/null +++ b/GUIs.Common/DocumentResultList/Loader.vb @@ -0,0 +1,105 @@ +Imports System.IO +Imports DigitalData.Modules.EDMI.API +Imports DigitalData.Modules.EDMI.API.Client +Imports DigitalData.Modules.EDMI.API.EDMIServiceReference +Imports DigitalData.Modules.Logging +Imports DigitalData.Modules.ZooFlow.Constants +Imports DigitalData.Modules.ZooFlow.State + +Namespace DocumentResultList + + Public Class Loader + Inherits Modules.ZooFlow.Base.BaseClass + + Private ReadOnly Client As Client + Private ReadOnly Mode As OperationMode + Private ReadOnly User As DigitalData.Modules.ZooFlow.State.UserState + + Public Sub New(pLogConfig As LogConfig, pMode As OperationMode, pClient As Client, pUser As DigitalData.Modules.ZooFlow.State.UserState) + MyBase.New(pLogConfig) + Client = pClient + Mode = pMode + User = pUser + End Sub + + Public Function Load(pObjectId As Long, pFullPath As String) As Document + Select Case Mode + Case OperationMode.NoAppServer + Return Load_FromWindream(pObjectId, pFullPath) + + Case OperationMode.WithAppServer + Return Load_FromIDB(pObjectId) + + Case OperationMode.ZooFlow + Return Load_FromZooflow(pObjectId) + + Case Else + Return Nothing + End Select + End Function + + Private Function Load_FromWindream(pObjectId As Long, pFullPath As String) As Document + Dim oFileInfo As New FileInfo(pFullPath) + Dim oResultDocumentInfo = New Document(pObjectId) With { + .Contents = Load_FromDisk(pFullPath), + .AccessRight = Rights.AccessRight.FULL, + .FullPath = pFullPath, + .Extension = oFileInfo.Extension.Substring(1) + } + + Return oResultDocumentInfo + End Function + + Private Function Load_FromIDB(pObjectId As Long) As Document + Try + Dim oDocumentInfo As Client.DocumentInfo = Client.GetDocumentInfo(User.UserId, pObjectId) + Dim oFileInfo As New FileInfo(oDocumentInfo.FullPath) + Dim oResultDocumentInfo As New Document(pObjectId) With { + .Contents = Load_FromDisk(oDocumentInfo.FullPath), + .AccessRight = oDocumentInfo.AccessRight, + .FullPath = oDocumentInfo.FullPath, + .Extension = oFileInfo.Extension.Substring(1) + } + + Return oResultDocumentInfo + Catch ex As Exception + Logger.Error(ex) + Return Nothing + End Try + End Function + + Private Function Load_FromZooflow(pObjectId As Long) As Document + Dim oFileObject As FileObject = Client.Zooflow_GetFileObject(pObjectId, pLoadFileContents:=True) + + If oFileObject Is Nothing Then + Return Nothing + End If + + Dim oResultDocumentInfo As New Document(pObjectId) With { + .Contents = oFileObject._FileContents, + .Extension = oFileObject._FileExtension, + .AccessRight = Rights.AccessRight.FULL, + .FullPath = Nothing + } + + Return oResultDocumentInfo + End Function + + Private Function Load_FromDisk(pFullPath) As Byte() + Try + Logger.Debug("Loading file [{0}]", pFullPath) + Using oStream = File.OpenRead(pFullPath) + Using oMemoryStream = New MemoryStream() + oStream.CopyTo(oMemoryStream) + Logger.Debug("Loaded file [{0}] successfully.", pFullPath) + Return oMemoryStream.ToArray() + End Using + End Using + Catch ex As Exception + Logger.Warn("Loading file [{0}] failed.", pFullPath) + Logger.Error(ex) + Return Nothing + End Try + End Function + End Class +End Namespace diff --git a/GUIs.Common/DocumentResultList/Opener.vb b/GUIs.Common/DocumentResultList/Opener.vb new file mode 100644 index 00000000..8e03f5c5 --- /dev/null +++ b/GUIs.Common/DocumentResultList/Opener.vb @@ -0,0 +1,51 @@ +Imports DigitalData.Modules.Logging +Imports DigitalData.Modules.ZooFlow.Base + +Namespace DocumentResultList + Public Class Opener + Inherits BaseClass + + Public Sub New(pLogConfig As LogConfig) + MyBase.New(pLogConfig) + End Sub + + Public Sub OpenDocument(pDocument As Document) + Dim oProcessId As Integer = Nothing + + If pDocument.FullPath Is Nothing OrElse pDocument.FullPath.Trim = String.Empty Then + oProcessId = OpenFileFromPath(pDocument) + ElseIf pDocument.Extension IsNot Nothing AndAlso pDocument.Contents IsNot Nothing Then + + + End If + + + + + End Sub + + Private Function OpenFileFromByteArry(pDocument As Document) As Integer + Try + ' TODO: Open file from temp folder + Dim oTempPath = IO.Path.GetTempPath() + Catch ex As Exception + + End Try + End Function + + + Private Function OpenFileFromPath(pDocument As Document) As Integer + Try + Dim oProcess = Process.Start(New ProcessStartInfo With { + .FileName = pDocument.FullPath + }) + + Return oProcess.Id + Catch ex As Exception + Logger.Error(ex) + Return Nothing + End Try + End Function + End Class + +End Namespace \ No newline at end of file diff --git a/GUIs.Common/DocumentResultList/Params.vb b/GUIs.Common/DocumentResultList/Params.vb new file mode 100644 index 00000000..defd37fb --- /dev/null +++ b/GUIs.Common/DocumentResultList/Params.vb @@ -0,0 +1,26 @@ +Imports DigitalData.Modules.ZooFlow.Constants + +Namespace DocumentResultList + Public Class Params + ''' + ''' WindowGuid is used to save layout data + ''' + Public WindowGuid As String + Public WindowTitle As String = "" + Public Results As New List(Of DocumentResult) + Public ColumnNames As New ColumnNames + Public OperationModeOverride As OperationMode = OperationMode.None + End Class + + Public Class DocumentResult + Inherits BaseResult + End Class + + Public Class ColumnNames + Public ObjectIdColumn As String = "DocId" + Public FullPathColumn As String = "FULL_FILENAME" + Public FilenameColumn As String = "Name" + Public IconColumn As String = "ICON" + End Class + +End Namespace \ No newline at end of file diff --git a/GUIs.Common/My Project/licenses.licx b/GUIs.Common/My Project/licenses.licx index e69de29b..7b200139 100644 --- a/GUIs.Common/My Project/licenses.licx +++ b/GUIs.Common/My Project/licenses.licx @@ -0,0 +1,3 @@ +DevExpress.XtraGrid.GridControl, DevExpress.XtraGrid.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a +DevExpress.XtraEditors.Repository.RepositoryItemTextEdit, DevExpress.XtraEditors.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a +DevExpress.XtraBars.Ribbon.RibbonControl, DevExpress.XtraBars.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a diff --git a/GUIs.Common/DocumentResultList/frmDocumentResultList.Designer.vb b/GUIs.Common/frmDocumentResultList.Designer.vb similarity index 100% rename from GUIs.Common/DocumentResultList/frmDocumentResultList.Designer.vb rename to GUIs.Common/frmDocumentResultList.Designer.vb diff --git a/GUIs.Common/DocumentResultList/frmDocumentResultList.en-US.resx b/GUIs.Common/frmDocumentResultList.en-US.resx similarity index 100% rename from GUIs.Common/DocumentResultList/frmDocumentResultList.en-US.resx rename to GUIs.Common/frmDocumentResultList.en-US.resx diff --git a/GUIs.Common/DocumentResultList/frmDocumentResultList.fr-FR.resx b/GUIs.Common/frmDocumentResultList.fr-FR.resx similarity index 100% rename from GUIs.Common/DocumentResultList/frmDocumentResultList.fr-FR.resx rename to GUIs.Common/frmDocumentResultList.fr-FR.resx diff --git a/GUIs.Common/DocumentResultList/frmDocumentResultList.resx b/GUIs.Common/frmDocumentResultList.resx similarity index 100% rename from GUIs.Common/DocumentResultList/frmDocumentResultList.resx rename to GUIs.Common/frmDocumentResultList.resx diff --git a/GUIs.Common/DocumentResultList/frmDocumentResultList.vb b/GUIs.Common/frmDocumentResultList.vb similarity index 86% rename from GUIs.Common/DocumentResultList/frmDocumentResultList.vb rename to GUIs.Common/frmDocumentResultList.vb index 283a433b..8ec4aaaa 100644 --- a/GUIs.Common/DocumentResultList/frmDocumentResultList.vb +++ b/GUIs.Common/frmDocumentResultList.vb @@ -14,8 +14,6 @@ Imports DevExpress.XtraGrid.Views.Grid.ViewInfo Imports DevExpress.XtraPrinting Imports DigitalData.Modules.Config Imports DigitalData.Modules.EDMI.API -Imports DigitalData.Modules.EDMI.API.Client -Imports DigitalData.Modules.EDMI.API.EDMIServiceReference Imports DigitalData.Modules.Language Imports DigitalData.Modules.Logging Imports DigitalData.Modules.ZooFlow @@ -44,41 +42,38 @@ Public Class frmDocumentResultList Private _IDBClient As Client Private ReadOnly _LogConfig As LogConfig Private ReadOnly _Logger As Logger - Private ReadOnly _Config As ConfigManager(Of DocumentResultConfig) + Private ReadOnly _Config As ConfigManager(Of DocumentResultList.Config) Private ReadOnly _Environment As Environment - Private ReadOnly _Params As DocumentResultParams - Private ReadOnly _ResultLists As List(Of DocumentResult) - Private ReadOnly _Helpers As DocumentResultList + Private ReadOnly _Params As DocumentResultList.Params + Private ReadOnly _ResultLists As List(Of DocumentResultList.DocumentResult) + Private ReadOnly _Helpers As DocumentResultList.Helpers Private ReadOnly _Filesystem As Modules.Filesystem.File Private ReadOnly _GridBuilder As GridBuilder Private ReadOnly _File As Modules.Windows.File - Private ReadOnly _Cache As New DocumentResultCache(50000000) - + Private ReadOnly _Cache As New DocumentResultList.Cache(50000000) + Private _Documentloader As DocumentResultList.Loader ' Runtime variables Private _IsLoading As Boolean = True Private _ActiveGrid As GridControl = Nothing Private _ActiveGridBand As GridBand = Nothing - Private _documentloader As DocumentLoader - Private _tempDocuments As New List(Of DocumentResultList) - - ' TODO: Hashes for checking if the opened file was modified externally - 'Private _HashOriginalFile As String = Nothing - 'Private _HashOpenedFile As String = Nothing - Private _DragBoxFromMouseDown As Rectangle Private _ScreenOffset As Point - - Private Property _CurrentDocument As DocumentResultInfo = Nothing + Private _CurrentDocument As DocumentResultList.Document = Nothing + Private _FileOpenList As New Dictionary(Of Integer, String) Private ReadOnly _Language As String + ' TODO: Hashes for checking if the opened file was modified externally + Private _HashOriginalFile As String = Nothing + Private _HashOpenedFile As String = Nothing + Private WithEvents _FileOpenTimer As New Timer Private Property OperationMode As OperationMode Implements IResultForm.OperationMode Public Property ShouldReturnToPreviousForm As Boolean = False Implements IResultForm.ShouldReturnToPreviousForm - Public Sub New(LogConfig As LogConfig, Environment As Environment, Params As DocumentResultParams) + Public Sub New(LogConfig As LogConfig, Environment As Environment, Params As DocumentResultList.Params) ' Dieser Aufruf ist für den Designer erforderlich. InitializeComponent() @@ -92,8 +87,8 @@ Public Class frmDocumentResultList _LogConfig = LogConfig _Logger = LogConfig.GetLogger() - _Config = New ConfigManager(Of DocumentResultConfig)(LogConfig, oConfigPath, oConfigPath) - _Helpers = New DocumentResultList(LogConfig) + _Config = New ConfigManager(Of DocumentResultList.Config)(LogConfig, oConfigPath, oConfigPath) + _Helpers = New DocumentResultList.Helpers(LogConfig) _Filesystem = New Modules.Filesystem.File(_LogConfig) _GridBuilder = New GridBuilder(New List(Of GridView) From {GridView1, GridView2, GridView3}) _Environment = Environment @@ -129,7 +124,7 @@ Public Class frmDocumentResultList InitAppServer() End If - _documentLoader = New DocumentLoader(_LogConfig, OperationMode, _IDBClient, _Environment.User) + _Documentloader = New DocumentResultList.Loader(_LogConfig, OperationMode, _IDBClient, _Environment.User) If _Params.WindowTitle <> "" Then @@ -206,11 +201,11 @@ Public Class frmDocumentResultList Dim oRow = sender.GetDataRow(_Helpers.ActiveRowHandle) Dim oObjectId = oRow.ItemEx(Of Long)(COLUMN_DOCID, 0) Dim oFullPath = oRow.ItemEx(Of String)(COLUMN_FILEPATH, "") - Dim oDocumentInfo As DocumentResultInfo = Nothing + Dim oDocumentInfo As DocumentResultList.Document = Nothing DocumentViewer1.CloseDocument() - oDocumentInfo = _documentloader.Load(oObjectId, oFullPath) + oDocumentInfo = _Documentloader.Load(oObjectId, oFullPath) ' Check DocumentInfo If IsNothing(oDocumentInfo) Then @@ -256,63 +251,6 @@ Public Class frmDocumentResultList Return True End Function - 'Private Function LoadFile_AsByteArray(DocumentInfo As DocumentResultInfo) As DocumentResultInfo - ' Try - ' _Logger.Debug("Loading File [{0}]", DocumentInfo.FullPath) - ' Dim oFullPath As String = DocumentInfo.FullPath - ' Dim oPathExists = From oFile In _Cache - ' Where oFile.FullPath = oFullPath And oFile.Contents IsNot Nothing - ' Select oFile - - ' Dim oExistsInCache = oPathExists.Count() > 0 - ' Dim oSizeChanged = False - ' Dim oWriteTimeChanged = False - - ' _Logger.Debug("File exists in Cache: [{0}]", oExistsInCache) - - ' ' Get Information about the file on the filesystem - ' Dim oFileInfo As New FileInfo(oFullPath) - - ' If oExistsInCache Then - ' _Logger.Debug("Loading file from cache.") - - ' Dim oCachedItem = oPathExists.First() - - ' If oCachedItem.Contents Is Nothing Then - ' oSizeChanged = False - ' Else - ' oSizeChanged = Not (oFileInfo.Length = oCachedItem.Contents.Length) - ' End If - ' _Logger.Debug("Filesize changed: [{0}]", oSizeChanged) - - ' If oCachedItem.LastWriteTime = Nothing Then - ' oWriteTimeChanged = False - ' Else - ' oWriteTimeChanged = Not oFileInfo.LastWriteTime.Equals(oCachedItem.LastWriteTime) - ' End If - ' _Logger.Debug("Write-time changed: [{0}]", oWriteTimeChanged) - - ' If oSizeChanged Or oWriteTimeChanged Then - ' _Logger.Debug("Size or Write-time changed, loading from disk.") - - ' Return LoadFile_FromDisk(DocumentInfo, oFileInfo) - ' Else - ' _Logger.Debug("Loading from cache") - - ' Return oCachedItem - ' End If - - ' Else - ' _Logger.Debug("File exists in cache, loading from disk.") - - ' Return LoadFile_FromDisk(DocumentInfo, oFileInfo) - ' End If - - ' Catch ex As Exception - ' _Logger.Error(ex) - ' Return DocumentInfo - ' End Try - 'End Function Public Function RefreshResults(pResults As IEnumerable(Of BaseResult)) As Boolean Implements IResultForm.RefreshResults _IsLoading = True @@ -330,7 +268,7 @@ Public Class frmDocumentResultList End Try End Function - Private Sub LoadGridData(Result As DocumentResult) + Private Sub LoadGridData(Result As DocumentResultList.DocumentResult) If Result.Datatable.Columns.Contains(COLUMN_DOCID) = False Then Throw New ApplicationException($"Datatable is missing DocId Column [{COLUMN_DOCID}] for search {Result.Title}!") End If @@ -348,7 +286,7 @@ Public Class frmDocumentResultList For oIndex = 0 To _ResultLists.Count - 1 Select Case oIndex Case 0 - Dim oResult As DocumentResult = _ResultLists.Item(0) + Dim oResult As DocumentResultList.DocumentResult = _ResultLists.Item(0) LoadGridData(oResult) CreateDocumentGrid(GridView1, oResult) @@ -356,7 +294,7 @@ Public Class frmDocumentResultList UpdateGridHeader(_ResultLists, oIndex, oResult.Datatable.Rows.Count) Case 1 - Dim oResult As DocumentResult = _ResultLists.Item(1) + Dim oResult As DocumentResultList.DocumentResult = _ResultLists.Item(1) LoadGridData(oResult) CreateDocumentGrid(GridView2, oResult) @@ -364,7 +302,7 @@ Public Class frmDocumentResultList UpdateGridHeader(_ResultLists, oIndex, oResult.Datatable.Rows.Count) Case 2 - Dim oResult As DocumentResult = _ResultLists.Item(2) + Dim oResult As DocumentResultList.DocumentResult = _ResultLists.Item(2) LoadGridData(oResult) CreateDocumentGrid(GridView3, oResult) @@ -416,7 +354,7 @@ Public Class frmDocumentResultList labelResultCount.Caption = String.Format(labelResultCount.Caption, oTotalResults) End Sub - Private Sub UpdateGridHeader(pResultList As List(Of DocumentResult), pIndex As Integer, pCount As Integer) + Private Sub UpdateGridHeader(pResultList As List(Of DocumentResultList.DocumentResult), pIndex As Integer, pCount As Integer) Select Case pIndex Case 0 Dim oResult = pResultList.Item(0) @@ -432,7 +370,7 @@ Public Class frmDocumentResultList End Select End Sub - Private Sub CreateDocumentGrid(GridView As BandedGridView, Result As DocumentResult) + Private Sub CreateDocumentGrid(GridView As BandedGridView, Result As DocumentResultList.DocumentResult) Try If IsNothing(GridView.Columns("ICON")) Then Dim oIconColumn = GridView.Columns.AddVisible("ICON", "ICON") @@ -672,37 +610,36 @@ Public Class frmDocumentResultList Public Sub FileOpenTimer_Elapsed() Handles _FileOpenTimer.Tick - 'Try - ' Dim oProcesses = Process.GetProcesses() - ' Dim oIds = (From oProc In oProcesses - ' Select oProc.Id). - ' ToList() - - ' Dim oNewFileOpenList As New Dictionary(Of Integer, String) - ' For Each oOpenFile In _FileOpenList - ' If oIds.Contains(oOpenFile.Key) Then - ' oNewFileOpenList.Add(oOpenFile.Key, oOpenFile.Value) - ' End If - ' Next - - ' If oNewFileOpenList.Count < _FileOpenList.Count Then - ' Dim oClosedFiles = _FileOpenList. - ' Except(oNewFileOpenList). - ' ToList() - - ' If oClosedFiles.Count = 1 Then - ' Dim oOpenFile = oClosedFiles.First() - ' DocumentViewer1.LoadFile(oOpenFile.Value) - ' Else - ' ClearGridData() - ' UpdateGridData() - ' End If - - ' _FileOpenList = oNewFileOpenList - ' End If - 'Catch ex As Exception - ' _Logger.Error(ex) - 'End Try + Try + Dim oIds = Process.GetProcesses(). + Select(Function(process) process.Id). + ToList() + + Dim oNewFileOpenList As New Dictionary(Of Integer, String) + For Each oOpenFile In _FileOpenList + If oIds.Contains(oOpenFile.Key) Then + oNewFileOpenList.Add(oOpenFile.Key, oOpenFile.Value) + End If + Next + + If oNewFileOpenList.Count < _FileOpenList.Count Then + Dim oClosedFiles = _FileOpenList. + Except(oNewFileOpenList). + ToList() + + If oClosedFiles.Count = 1 Then + Dim oOpenFile = oClosedFiles.First() + DocumentViewer1.LoadFile(oOpenFile.Value) + Else + 'ClearGridData() + UpdateGridData() + End If + + _FileOpenList = oNewFileOpenList + End If + Catch ex As Exception + _Logger.Error(ex) + End Try End Sub #Region "Context Menu" diff --git a/GUIs.ZooFlow/Search/frmFlowSearch.vb b/GUIs.ZooFlow/Search/frmFlowSearch.vb index 91078724..5e14be25 100644 --- a/GUIs.ZooFlow/Search/frmFlowSearch.vb +++ b/GUIs.ZooFlow/Search/frmFlowSearch.vb @@ -230,8 +230,8 @@ Public Class frmFlowSearch Dim oWindowGuid = $"FLOWSEARCH-{My.User.Name}" Dim oParams = New DocumentResultParams() With { .WindowGuid = oWindowGuid, - .Results = New List(Of DocumentResult) From { - New DocumentResult() With { + .Results = New List(Of DocumentResultList) From { + New DocumentResultList() With { .Title = "FlowSearchResult", .Datatable = pDTRESULT } diff --git a/GUIs.ZooFlow/Search/frmSearchStart.vb b/GUIs.ZooFlow/Search/frmSearchStart.vb index b31a8900..aa23a1bd 100644 --- a/GUIs.ZooFlow/Search/frmSearchStart.vb +++ b/GUIs.ZooFlow/Search/frmSearchStart.vb @@ -953,8 +953,8 @@ Public Class frmSearchStart Dim oWindowGuid = $"{SEARCH_ID.ToString}-{My.User.Name}" Dim oParams = New DocumentResultParams() With { .WindowGuid = oWindowGuid, - .Results = New List(Of DocumentResult) From { - New DocumentResult() With { + .Results = New List(Of DocumentResultList) From { + New DocumentResultList() With { .Title = SelectedTab.Text, .Datatable = oDTSearchResult }