From b28be74b367637e40abed128658bfa6c3d927535 Mon Sep 17 00:00:00 2001 From: Jonathan Jenne Date: Fri, 5 Feb 2021 15:06:03 +0100 Subject: [PATCH] Common/DocumentResultList: Add list of open files, prevent loading of open files, close document in viewer when opened externally, reopen file in viewer when closed externally, first version of creating file hashes for modification checks --- GUIs.Common/Common.vbproj | 8 ++ .../frmDocumentResultList.Designer.vb | 25 ++-- .../frmDocumentResultList.vb | 135 +++++++++++++----- GUIs.Common/My Project/Resources.Designer.vb | 10 ++ GUIs.Common/My Project/Resources.resx | 27 ++-- GUIs.Common/Resources/grid.svg | 22 +++ 6 files changed, 165 insertions(+), 62 deletions(-) create mode 100644 GUIs.Common/Resources/grid.svg diff --git a/GUIs.Common/Common.vbproj b/GUIs.Common/Common.vbproj index 26421b26..0e3ea5b8 100644 --- a/GUIs.Common/Common.vbproj +++ b/GUIs.Common/Common.vbproj @@ -112,6 +112,7 @@ Form + @@ -187,6 +188,10 @@ {25017513-0d97-49d3-98d7-ba76d9b251b0} EDMI.API + + {991d0231-4623-496d-8bd0-9ca906029cbc} + Filesystem + {d3c8cfed-d6f6-43a8-9bdf-454145d0352f} Language @@ -259,5 +264,8 @@ + + + \ No newline at end of file diff --git a/GUIs.Common/DocumentResultList/frmDocumentResultList.Designer.vb b/GUIs.Common/DocumentResultList/frmDocumentResultList.Designer.vb index 22a19878..e106fce6 100644 --- a/GUIs.Common/DocumentResultList/frmDocumentResultList.Designer.vb +++ b/GUIs.Common/DocumentResultList/frmDocumentResultList.Designer.vb @@ -84,8 +84,11 @@ Partial Class frmDocumentResultList Me.RibbonControl.Pages.AddRange(New DevExpress.XtraBars.Ribbon.RibbonPage() {Me.RibbonPage1}) Me.RibbonControl.RepositoryItems.AddRange(New DevExpress.XtraEditors.Repository.RepositoryItem() {Me.RepositoryItemTextEdit1, Me.RepositoryItemTextEdit2}) Me.RibbonControl.ShowApplicationButton = DevExpress.Utils.DefaultBoolean.[False] - Me.RibbonControl.Size = New System.Drawing.Size(1189, 157) + Me.RibbonControl.ShowPageHeadersMode = DevExpress.XtraBars.Ribbon.ShowPageHeadersMode.Hide + Me.RibbonControl.ShowToolbarCustomizeItem = False + Me.RibbonControl.Size = New System.Drawing.Size(1189, 132) Me.RibbonControl.StatusBar = Me.RibbonStatusBar + Me.RibbonControl.Toolbar.ShowCustomizeItem = False ' 'SwitchMainContainerHorizontal ' @@ -245,10 +248,10 @@ Partial Class frmDocumentResultList Me.RibbonStatusBar.ItemLinks.Add(Me.labelResultCount) Me.RibbonStatusBar.ItemLinks.Add(Me.labelCriticalError) Me.RibbonStatusBar.ItemLinks.Add(Me.labelWarning) - Me.RibbonStatusBar.Location = New System.Drawing.Point(0, 649) + Me.RibbonStatusBar.Location = New System.Drawing.Point(0, 647) Me.RibbonStatusBar.Name = "RibbonStatusBar" Me.RibbonStatusBar.Ribbon = Me.RibbonControl - Me.RibbonStatusBar.Size = New System.Drawing.Size(1189, 22) + Me.RibbonStatusBar.Size = New System.Drawing.Size(1189, 24) ' 'SplitContainerControl1 ' @@ -260,7 +263,7 @@ Partial Class frmDocumentResultList Me.SplitContainerControl1.Panel1.Text = "Panel1" Me.SplitContainerControl1.Panel2.Controls.Add(Me.SplitContainerControl2) Me.SplitContainerControl1.Panel2.Text = "Panel2" - Me.SplitContainerControl1.Size = New System.Drawing.Size(762, 492) + Me.SplitContainerControl1.Size = New System.Drawing.Size(762, 515) Me.SplitContainerControl1.SplitterPosition = 382 Me.SplitContainerControl1.TabIndex = 2 Me.SplitContainerControl1.Text = "SplitContainerControl1" @@ -272,7 +275,7 @@ Partial Class frmDocumentResultList Me.GridControl1.MainView = Me.GridView1 Me.GridControl1.MenuManager = Me.RibbonControl Me.GridControl1.Name = "GridControl1" - Me.GridControl1.Size = New System.Drawing.Size(382, 492) + Me.GridControl1.Size = New System.Drawing.Size(382, 515) Me.GridControl1.TabIndex = 0 Me.GridControl1.ViewCollection.AddRange(New DevExpress.XtraGrid.Views.Base.BaseView() {Me.GridView1}) ' @@ -313,7 +316,7 @@ Partial Class frmDocumentResultList Me.SplitContainerControl2.Panel1.Text = "Panel1" Me.SplitContainerControl2.Panel2.Controls.Add(Me.GridControl3) Me.SplitContainerControl2.Panel2.Text = "Panel2" - Me.SplitContainerControl2.Size = New System.Drawing.Size(370, 492) + Me.SplitContainerControl2.Size = New System.Drawing.Size(370, 515) Me.SplitContainerControl2.SplitterPosition = 223 Me.SplitContainerControl2.TabIndex = 0 Me.SplitContainerControl2.Text = "SplitContainerControl2" @@ -358,7 +361,7 @@ Partial Class frmDocumentResultList Me.GridControl3.MainView = Me.GridView3 Me.GridControl3.MenuManager = Me.RibbonControl Me.GridControl3.Name = "GridControl3" - Me.GridControl3.Size = New System.Drawing.Size(370, 259) + Me.GridControl3.Size = New System.Drawing.Size(370, 282) Me.GridControl3.TabIndex = 0 Me.GridControl3.ViewCollection.AddRange(New DevExpress.XtraGrid.Views.Base.BaseView() {Me.GridView3}) ' @@ -387,13 +390,13 @@ Partial Class frmDocumentResultList 'SplitContainerControl3 ' Me.SplitContainerControl3.Dock = System.Windows.Forms.DockStyle.Fill - Me.SplitContainerControl3.Location = New System.Drawing.Point(0, 157) + Me.SplitContainerControl3.Location = New System.Drawing.Point(0, 132) Me.SplitContainerControl3.Name = "SplitContainerControl3" Me.SplitContainerControl3.Panel1.Controls.Add(Me.SplitContainerControl1) Me.SplitContainerControl3.Panel1.Text = "Panel1" Me.SplitContainerControl3.Panel2.Controls.Add(Me.DocumentViewer1) Me.SplitContainerControl3.Panel2.Text = "Panel2" - Me.SplitContainerControl3.Size = New System.Drawing.Size(1189, 492) + Me.SplitContainerControl3.Size = New System.Drawing.Size(1189, 515) Me.SplitContainerControl3.SplitterPosition = 762 Me.SplitContainerControl3.TabIndex = 5 Me.SplitContainerControl3.Text = "SplitContainerControl3" @@ -404,7 +407,7 @@ Partial Class frmDocumentResultList Me.DocumentViewer1.FileLoaded = False Me.DocumentViewer1.Location = New System.Drawing.Point(0, 0) Me.DocumentViewer1.Name = "DocumentViewer1" - Me.DocumentViewer1.Size = New System.Drawing.Size(417, 492) + Me.DocumentViewer1.Size = New System.Drawing.Size(417, 515) Me.DocumentViewer1.TabIndex = 0 ' 'XtraSaveFileDialog @@ -421,8 +424,8 @@ Partial Class frmDocumentResultList Me.Controls.Add(Me.RibbonStatusBar) Me.Controls.Add(Me.RibbonControl) Me.IconOptions.Icon = CType(resources.GetObject("frmDocumentResultList.IconOptions.Icon"), System.Drawing.Icon) - Me.IconOptions.Image = Global.DigitalData.GUIs.Common.My.Resources.Resources.zoom_less Me.IconOptions.ShowIcon = False + Me.IconOptions.SvgImage = Global.DigitalData.GUIs.Common.My.Resources.Resources.grid Me.Name = "frmDocumentResultList" Me.Ribbon = Me.RibbonControl Me.StatusBar = Me.RibbonStatusBar diff --git a/GUIs.Common/DocumentResultList/frmDocumentResultList.vb b/GUIs.Common/DocumentResultList/frmDocumentResultList.vb index c4fd5b72..7526f329 100644 --- a/GUIs.Common/DocumentResultList/frmDocumentResultList.vb +++ b/GUIs.Common/DocumentResultList/frmDocumentResultList.vb @@ -1,23 +1,21 @@ -Imports System.Drawing +Imports System.ComponentModel Imports System.IO Imports System.Windows.Forms Imports DevExpress.Utils +Imports DevExpress.XtraEditors Imports DevExpress.XtraGrid Imports DevExpress.XtraGrid.Columns +Imports DevExpress.XtraGrid.Views.BandedGrid +Imports DevExpress.XtraGrid.Views.Base Imports DevExpress.XtraGrid.Views.Grid +Imports DevExpress.XtraGrid.Views.Grid.ViewInfo Imports DevExpress.XtraPrinting Imports DigitalData.Modules.Config -Imports DigitalData.Modules.Logging -Imports DigitalData.Modules.ZooFlow -Imports DigitalData.Modules.Language Imports DigitalData.Modules.EDMI.API Imports DigitalData.Modules.EDMI.API.Client -Imports DevExpress.XtraGrid.Views.Base -Imports DevExpress.XtraGrid.Views.BandedGrid -Imports System.ComponentModel -Imports DevExpress.XtraGrid.Views.Grid.ViewInfo -Imports DevExpress.XtraEditors.ViewInfo -Imports DevExpress.XtraEditors +Imports DigitalData.Modules.Language +Imports DigitalData.Modules.Logging +Imports DigitalData.Modules.ZooFlow Public Class frmDocumentResultList Implements IResultForm @@ -29,9 +27,10 @@ Public Class frmDocumentResultList Private COLUMN_DOCID As String = "DocID" Private COLUMN_ICON As String = "ICON" - Private _IsLoading As Boolean = True - Private _IDBClient As Client + Private Const FILE_OPEN_TIMER_INTERVAL As Integer = 500 + ' Helper Classes + Private _IDBClient As Client Private _LogConfig As LogConfig Private _Logger As Logger Private _Config As ConfigManager(Of DocumentResultConfig) @@ -39,12 +38,21 @@ Public Class frmDocumentResultList Private _Params As DocumentResultParams Private _ResultLists As List(Of DocumentResult) Private _Helpers As DocumentResultList + Private _Filesystem As DigitalData.Modules.Filesystem.File + ' Runtime variables + Private _IsLoading As Boolean = True Private _ActiveGrid As GridControl = Nothing Private _ActiveGridBand As GridBand = Nothing - Private _DocumentInfo As DocumentInfo = Nothing + ' 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 _FileOpenList As New Dictionary(Of Integer, String) + Private Property OperationMode As IResultForm.Mode Implements IResultForm.OperationMode Public Property ShouldReturnToPreviousForm As Boolean = False Implements IResultForm.ShouldReturnToPreviousForm @@ -64,10 +72,14 @@ Public Class frmDocumentResultList _Logger = LogConfig.GetLogger() _Config = New ConfigManager(Of DocumentResultConfig)(LogConfig, oConfigPath, oConfigPath) _Helpers = New DocumentResultList(LogConfig) + _Filesystem = New Modules.Filesystem.File(_LogConfig) _Environment = Environment _Params = Params _ResultLists = Params.Results + + _FileOpenTimer.Interval = FILE_OPEN_TIMER_INTERVAL + _FileOpenTimer.Start() End Sub Private Sub frmDocumentResultList_Load(sender As Object, e As EventArgs) Handles MyBase.Load @@ -140,21 +152,32 @@ Public Class frmDocumentResultList LoadFile_IDB(oRow) End If - If IsNothing(_DocumentInfo) Or DocumentViewer1.FileLoaded = False Then + If IsNothing(_DocumentInfo) Then Show_Warning("File could not be loaded!") End If If Not IsNothing(_DocumentInfo) Then - DocumentViewer1.LoadFile(_DocumentInfo.FullPath) - - If _DocumentInfo.AccessRight = Rights.AccessRight.VIEW_ONLY Then - DocumentViewer1.SetViewOnly(True) - RibbonPageGroup_Export.Visible = False + If _FileOpenList.ContainsValue(_DocumentInfo.FullPath) Then + Show_Warning("Die ausgewählte Datei befindet sich im Zugriff!") Else - DocumentViewer1.SetViewOnly(False) - RibbonPageGroup_Export.Visible = True + DocumentViewer1.LoadFile(_DocumentInfo.FullPath) + + If _DocumentInfo.AccessRight = Rights.AccessRight.VIEW_ONLY Then + DocumentViewer1.SetViewOnly(True) + RibbonPageGroup_Export.Visible = False + Else + DocumentViewer1.SetViewOnly(False) + RibbonPageGroup_Export.Visible = True + End If End If End If + + ' TODO: Create checksum after closing, compare and take action + If File.Exists(_DocumentInfo.FullPath) Then + _HashOriginalFile = _Filesystem.GetChecksum(_DocumentInfo.FullPath) + Else + _HashOriginalFile = Nothing + End If End If Catch ex As Exception _Logger.Error(ex) @@ -221,6 +244,10 @@ Public Class frmDocumentResultList End Try End Function + Private Sub ClearGridData() + GridControl1.DataSource = Nothing + End Sub + Private Sub LoadGridData(Result As DocumentResult) If Result.Datatable.Columns.Contains(COLUMN_DOCID) = False Then Throw New ApplicationException($"Datatable is missing DocId Column [{COLUMN_DOCID}] for search {Result.Title}!") @@ -556,17 +583,17 @@ Public Class frmDocumentResultList Private Sub OpenFile() Try - Dim oRow = GetActiveRow() - - If oRow IsNot Nothing Then - Dim oFilename = oRow.Item(COLUMN_FILEPATH) - Process.Start(oFilename) + If _DocumentInfo IsNot Nothing Then + Dim oFilename = _DocumentInfo.FullPath + DocumentPropertyMenu_FileOpened(Me, oFilename) End If Catch ex As Exception _Logger.Error(ex) End Try End Sub + + Private Sub CopyFileName() Try Dim oRow = GetActiveRow() @@ -630,7 +657,8 @@ Public Class frmDocumentResultList OpenFile() End Sub - Private Sub GridView_PopupMenuShowing(sender As Object, e As PopupMenuShowingEventArgs) Handles GridView2.PopupMenuShowing, GridView3.PopupMenuShowing + Private Sub GridView_PopupMenuShowing(sender As Object, e As PopupMenuShowingEventArgs) _ + Handles GridView2.PopupMenuShowing, GridView3.PopupMenuShowing, GridView1.PopupMenuShowing Try Dim oView As GridView = sender @@ -639,12 +667,7 @@ Public Class frmDocumentResultList Dim oRow As DataRow = oView.GetDataRow(oRowHandle) Dim oFilepath As String = oRow.Item(COLUMN_FILEPATH) Dim oObjectId As Long = oRow.Item(COLUMN_DOCID) - Dim oMenu As New DocumentPropertyMenu( - _LogConfig, - _Environment, - _IDBClient, - oFilepath, - oObjectId) + Dim oMenu As New DocumentPropertyMenu(_LogConfig, _Environment, _IDBClient, oFilepath, oObjectId) e.Menu.Items.Clear() @@ -653,7 +676,7 @@ Public Class frmDocumentResultList Next AddHandler oMenu.FileOpened, AddressOf DocumentPropertyMenu_FileOpened - AddHandler oMenu.FileClosed, AddressOf DocumentPropertyMenu_FileClosed + ' AddHandler oMenu.FileClosed, AddressOf DocumentPropertyMenu_FileClosed End If Catch ex As Exception _Logger.Error(ex) @@ -662,21 +685,55 @@ Public Class frmDocumentResultList End Sub Public Sub DocumentPropertyMenu_FileOpened(sender As Object, FilePath As String) + DocumentViewer1.CloseDocument() + Dim oProcess = Process.Start(New ProcessStartInfo With { + .FileName = FilePath + }) + _FileOpenList.Add(oProcess.Id, FilePath) End Sub - Public Sub DocumentPropertyMenu_FileClosed(sender As Object, FilePath As String) + 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 End Sub - Public Sub Show_CriticalError(Message As String) labelCriticalError.Visibility = DevExpress.XtraBars.BarItemVisibility.Always labelCriticalError.Caption = Message End Sub Public Sub Show_Warning(Message As String) - labelWarning.Visibility = DevExpress.XtraBars.BarItemVisibility.Never + labelWarning.Visibility = DevExpress.XtraBars.BarItemVisibility.Always labelWarning.Caption = Message End Sub @@ -689,8 +746,8 @@ Public Class frmDocumentResultList If Not IsNothing(_ActiveGrid) Then Try Dim oFile = GetDevexpressGrid_LayoutName(_ActiveGrid.MainView) - If File.Exists(oFile) Then - File.Delete(oFile) + If IO.File.Exists(oFile) Then + IO.File.Delete(oFile) End If UpdateGridData() Catch ex As Exception diff --git a/GUIs.Common/My Project/Resources.Designer.vb b/GUIs.Common/My Project/Resources.Designer.vb index 8cf1092f..f41318df 100644 --- a/GUIs.Common/My Project/Resources.Designer.vb +++ b/GUIs.Common/My Project/Resources.Designer.vb @@ -130,6 +130,16 @@ Namespace My.Resources End Get End Property + ''' + ''' Sucht eine lokalisierte Ressource vom Typ DevExpress.Utils.Svg.SvgImage. + ''' + Friend ReadOnly Property grid() As DevExpress.Utils.Svg.SvgImage + Get + Dim obj As Object = ResourceManager.GetObject("grid", resourceCulture) + Return CType(obj,DevExpress.Utils.Svg.SvgImage) + End Get + End Property + ''' ''' Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. ''' diff --git a/GUIs.Common/My Project/Resources.resx b/GUIs.Common/My Project/Resources.resx index ef093278..cd9cb0fe 100644 --- a/GUIs.Common/My Project/Resources.resx +++ b/GUIs.Common/My Project/Resources.resx @@ -127,6 +127,9 @@ ..\Resources\tiff.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\ZooFlow-Vergroessern.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v19.2, Version=19.2.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a + ..\Resources\pdf.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -148,28 +151,28 @@ ..\Resources\txt.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Article_32x32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\zoom_less.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\png.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\zoom_more.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\_blank.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\xls.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\dxf.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\_blank.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\ZooFlow-Vergroessern.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v19.2, Version=19.2.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a - - - ..\Resources\zoom_less.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Article_32x32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\zoom_more.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\grid.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v19.2, Version=19.2.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a \ No newline at end of file diff --git a/GUIs.Common/Resources/grid.svg b/GUIs.Common/Resources/grid.svg new file mode 100644 index 00000000..8e9d48b0 --- /dev/null +++ b/GUIs.Common/Resources/grid.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + \ No newline at end of file