Преглед на файлове

New DataEntry Document window that pops up when clicking an item and on a menu item.

Kenric Nugteren преди 1 година
родител
ревизия
65ecc40831

+ 1 - 1
prs.classes/Entities/Product/ProductGroup/ProductGroupLookups.cs

@@ -13,7 +13,7 @@ namespace Comal.Classes
             );
         }
 
-        public override Filter<ProductGroup> DefineFilter()
+        public override Filter<ProductGroup>? DefineFilter()
         {
             return null;
         }

+ 26 - 0
prs.desktop/Panels/DataEntry/DataEntryDocumentWindow.xaml

@@ -0,0 +1,26 @@
+<Window x:Class="PRSDesktop.Panels.DataEntry.DataEntryDocumentWindow"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        xmlns:local="clr-namespace:PRSDesktop.Panels.DataEntry"
+        xmlns:wpf="clr-namespace:InABox.Wpf;assembly=InABox.Wpf"
+        mc:Ignorable="d"
+        Title="DataEntryDocumentWindow" Height="800" Width="800"
+        x:Name="Window"
+        DataContext="{Binding ElementName=Window}">
+    <wpf:ZoomPanel Background="Gray">
+        <ItemsControl ItemsSource="{Binding Images}" x:Name="Items">
+            <ItemsControl.ItemsPanel>
+                <ItemsPanelTemplate>
+                    <StackPanel Orientation="Vertical"/>
+                </ItemsPanelTemplate>
+            </ItemsControl.ItemsPanel>
+            <ItemsControl.ItemTemplate>
+                <DataTemplate DataType="ImageSource">
+                    <Image Source="{Binding}"/>
+                </DataTemplate>
+            </ItemsControl.ItemTemplate>
+        </ItemsControl>
+    </wpf:ZoomPanel>
+</Window>

+ 38 - 0
prs.desktop/Panels/DataEntry/DataEntryDocumentWindow.xaml.cs

@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace PRSDesktop.Panels.DataEntry;
+/// <summary>
+/// Interaction logic for DataEntryDocumentWindow.xaml
+/// </summary>
+public partial class DataEntryDocumentWindow : Window, INotifyPropertyChanged
+{
+
+    public ObservableCollection<ImageSource> Images { get; set; } = new();
+
+    public DataEntryDocumentWindow()
+    {
+        InitializeComponent();
+    }
+
+    public event PropertyChangedEventHandler? PropertyChanged;
+
+    protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
+    {
+        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+    }
+}

+ 21 - 7
prs.desktop/Panels/DataEntry/DataEntryList.xaml

@@ -7,7 +7,9 @@
              xmlns:sf="http://schemas.syncfusion.com/wpf"
              xmlns:dynamic="clr-namespace:InABox.DynamicGrid;assembly=InABox.Wpf"
              mc:Ignorable="d" 
-             d:DesignHeight="450" d:DesignWidth="800">
+             d:DesignHeight="450" d:DesignWidth="800"
+             x:Name="Control"
+             DataContext="{Binding ElementName=Control}">
     <dynamic:DynamicTabControl 
         x:Name="_pages"
         TabStripPlacement="Bottom" 
@@ -58,18 +60,30 @@
                             AllowDrop="True"
                             DragOver="DynamicTabItem_DragOver"
                             Drop="DynamicTabItem_Drop">
-                        <ScrollViewer VerticalScrollBarVisibility="Auto">
-                            <StackPanel x:Name="ViewListPanel" Orientation="Vertical" Margin="10">
-                                <StackPanel.ContextMenu>
+                        <ScrollViewer x:Name="ViewListPanel" VerticalScrollBarVisibility="Auto">
+                            <ItemsControl Margin="10" ItemsSource="{Binding ViewList}">
+                                <ItemsControl.ItemsPanel>
+                                    <ItemsPanelTemplate>
+                                        <StackPanel Orientation="Vertical"/>
+                                    </ItemsPanelTemplate>
+                                </ItemsControl.ItemsPanel>
+                                <ItemsControl.ContextMenu>
                                     <ContextMenu
                                         x:Name="_contextMenu">
                                         <ContextMenu.Items>
                                             <MenuItem x:Name="_Explode" Header="Regroup Pages" Click="_Explode_OnClick"/>
+                                            <MenuItem x:Name="_ShowImage" Header="View Image" Click="_ShowImage_Click"
+                                                      ToolTip="Show this image in a separate window." Tag="{Binding}"/>
                                         </ContextMenu.Items>
                                     </ContextMenu>
-                                </StackPanel.ContextMenu>
-                                
-                            </StackPanel>
+                                </ItemsControl.ContextMenu>
+                                <ItemsControl.ItemTemplate>
+                                    <DataTemplate DataType="ImageSource">
+                                        <Image Source="{Binding}" Margin="0,0,0,20" ContextMenu="{Binding RelativeSource={RelativeSource AncestorType=ItemsControl,Mode=FindAncestor},Path=ContextMenu}"
+                                               MouseLeftButtonDown="Image_MouseLeftButtonDown"/>
+                                    </DataTemplate>
+                                </ItemsControl.ItemTemplate>
+                            </ItemsControl>
                         </ScrollViewer>
                     </Border>
                 </Grid>

+ 78 - 24
prs.desktop/Panels/DataEntry/DataEntryList.xaml.cs

@@ -30,6 +30,9 @@ using DragEventArgs = System.Windows.DragEventArgs;
 using MessageBox = System.Windows.MessageBox;
 using UserControl = System.Windows.Controls.UserControl;
 using InABox.Wpf;
+using System.Collections.ObjectModel;
+using System.Windows.Data;
+using PRSDesktop.Panels.DataEntry;
 
 namespace PRSDesktop;
 
@@ -91,9 +94,16 @@ public partial class DataEntryList : UserControl, ICorePanel, IDockPanel
     public delegate void DateEntrySelectionHandler(String appliesTo, Guid entityID, bool allowprocess);
 
     public event DateEntrySelectionHandler? SelectionChanged;
+
+    private readonly object _viewListLock = new object();
+    public ObservableCollection<ImageSource> ViewList { get; init; } = new();
+
+    private List<DataEntryDocumentWindow> OpenWindows = new();
     
     public DataEntryList()
     {
+        BindingOperations.EnableCollectionSynchronization(ViewList, _viewListLock);
+
         InitializeComponent();
     }
 
@@ -117,6 +127,7 @@ public partial class DataEntryList : UserControl, ICorePanel, IDockPanel
 
     public void Shutdown(CancelEventArgs? cancel)
     {
+        CloseImageWindows();
     }
 
     #endregion
@@ -165,25 +176,21 @@ public partial class DataEntryList : UserControl, ICorePanel, IDockPanel
         var selected = _dataEntryGrid.SelectedRows.Select(x => x.ToObject<DataEntryDocument>()).ToList();
         if (selected.Count == SelectedScans.Count && !selected.Any(x => SelectedScans.All(y => x.ID != y.ID)))
             return;
-     
+
         SelectedScans = selected;
-        ViewListPanel.Children.Clear();
+        ViewList.Clear();
 
         Task.Run(() =>
         {
-            try
-            {
-                var docs = DataEntryCache.Cache.LoadDocuments(SelectedScans.Select(x => x.Document.ID).Distinct(), checkTimestamp: true);
-                LoadDocuments(docs);
-            }
-            catch (Exception e)
+            var docs = DataEntryCache.Cache.LoadDocuments(SelectedScans.Select(x => x.Document.ID).Distinct(), checkTimestamp: true);
+            LoadDocuments(docs);
+        }).ContinueWith((task) =>
+        {
+            if(task.Exception is not null)
             {
-                Dispatcher.BeginInvoke(() =>
-                {
-                    MessageWindow.ShowError("An error occurred while loading the documents", e);
-                });
+                MessageWindow.ShowError("An error occurred while loading the documents", task.Exception);
             }
-        });
+        }, TaskScheduler.FromCurrentSynchronizationContext());
     }
 
     private void LoadDocuments(IEnumerable<Document> documents)
@@ -242,26 +249,20 @@ public partial class DataEntryList : UserControl, ICorePanel, IDockPanel
                 list.Add(image);
             }
         }
-
-        Dispatcher.Invoke(() =>
+        lock (_viewListLock)
         {
+            ViewList.Clear();
             foreach (var scan in SelectedScans)
             {
                 if (bitmaps.TryGetValue(scan.Document.ID, out var list))
                 {
                     foreach (var bitmap in list)
                     {
-                        var image = new Image
-                        {
-                            Source = bitmap,
-                            Margin = new Thickness(0, 0, 0, 20),
-                            ContextMenu = ViewListPanel.ContextMenu
-                        };
-                        ViewListPanel.Children.Add(image);
+                        ViewList.Add(bitmap);
                     }
                 }
             }
-        });
+        }
     }
 
     #endregion
@@ -364,13 +365,59 @@ public partial class DataEntryList : UserControl, ICorePanel, IDockPanel
             ? rows[0].Get<DataEntryDocument, DateTime>(x => x.Archived)
             : DateTime.MinValue;
         SelectionChanged?.Invoke(appliesTo, entityid, archived.IsEmpty());
+
+        CloseImageWindows();
     }
 
     private void _historyGrid_OnOnSelectItem(object sender, DynamicGridSelectionEventArgs e)
     {
         DoSelect(e.Rows);
     }
-    
+
+    private void CloseImageWindows()
+    {
+        while (OpenWindows.Count > 0)
+        {
+            var win = OpenWindows.Last();
+            OpenWindows.RemoveAt(OpenWindows.Count - 1);
+            win.Close();
+        }
+    }
+    private void OpenImageWindow(ImageSource image)
+    {
+        var window = OpenWindows.FirstOrDefault(x => x.Images.Contains(image));
+        if (window is not null)
+        {
+            window.Activate();
+        }
+        else
+        {
+            window = new DataEntryDocumentWindow();
+            window.Topmost = true;
+            window.Images.Add(image);
+            OpenWindows.Add(window);
+            window.Closed += OpenWindow_Closed;
+            window.Show();
+        }
+    }
+
+    private void Image_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
+    {
+        if (sender is not Image image) return;
+
+        if(e.ClickCount >= 2)
+        {
+            OpenImageWindow(image.Source);
+            e.Handled = true;
+        }
+    }
+
+    private void OpenWindow_Closed(object? sender, EventArgs e)
+    {
+        if (sender is not DataEntryDocumentWindow window) return;
+        OpenWindows.Remove(window);
+    }
+
     private void _Explode_OnClick(object sender, RoutedEventArgs e)
     {
        _dataEntryGrid.DoExplode();
@@ -536,4 +583,11 @@ public partial class DataEntryList : UserControl, ICorePanel, IDockPanel
     {
 
     }
+
+    private void _ShowImage_Click(object sender, RoutedEventArgs e)
+    {
+        if (sender is not MenuItem item || item.Tag is not ImageSource image) return;
+
+        OpenImageWindow(image);
+    }
 }