Forráskód Böngészése

Data Entry panel no longer converts everything to PDF.

Kenric Nugteren 1 éve
szülő
commit
b969682afc

+ 7 - 3
prs.desktop/Panels/DataEntry/DataEntryGrid.cs

@@ -147,7 +147,6 @@ public class DataEntryCache : DocumentCache<DataEntryCachedDocument>
             return loadedCached;
         }
     }
-
 }
 
 public class DataEntryGrid : DynamicDataGrid<DataEntryDocument>
@@ -349,9 +348,14 @@ public class DataEntryGrid : DynamicDataGrid<DataEntryDocument>
             Employee =
             {
                 ID = App.EmployeeID
-            },
-            Thumbnail = ImageUtils.GetPDFThumbnail(data, 256, 256)
+            }
         };
+
+        if(Path.GetExtension(filename) == ".pdf")
+        {
+            dataentry.Thumbnail = ImageUtils.GetPDFThumbnail(data, 256, 256);
+        }
+
         new Client<DataEntryDocument>().Save(dataentry, "");
 
         DataEntryCache.Cache.Add(new DataEntryCachedDocument(document));

+ 400 - 355
prs.desktop/Panels/DataEntry/DataEntryList.xaml.cs

@@ -29,463 +29,508 @@ using DragDropEffects = System.Windows.DragDropEffects;
 using DragEventArgs = System.Windows.DragEventArgs;
 using MessageBox = System.Windows.MessageBox;
 using UserControl = System.Windows.Controls.UserControl;
+using InABox.Wpf;
 
-namespace PRSDesktop
+namespace PRSDesktop;
+
+public static class PDFExtensions
 {
-    public static class PDFExtensions
+    public static IEnumerable<PdfPageBase> GetPages(this PdfDocumentBase doc)
     {
-        public static IEnumerable<PdfPageBase> GetPages(this PdfDocumentBase doc)
-        {
-            if (doc is PdfLoadedDocument lDoc)
-                return lDoc.Pages.Cast<PdfPageBase>();
-            if (doc is PdfDocument pdfDoc)
-                return pdfDoc.Pages.Cast<PdfPageBase>();
-            throw new Exception($"Unsupported PDF Document type {doc.GetType()}");
-        }
-        public static PdfPageBase GetPage(this PdfDocumentBase doc, int index)
-        {
-            if (doc is PdfLoadedDocument lDoc)
-                return lDoc.Pages[index];
-            if (doc is PdfDocument pdfDoc)
-                return pdfDoc.Pages[index];
-            throw new Exception($"Unsupported PDF Document type {doc.GetType()}");
-        }
-        public static int PageCount(this PdfDocumentBase doc)
-        {
-            if (doc is PdfLoadedDocument lDoc)
-                return lDoc.Pages.Count;
-            if (doc is PdfDocument pdfDoc)
-                return pdfDoc.Pages.Count;
-            throw new Exception($"Unsupported PDF Document type {doc.GetType()}");
-        }
-        public static PdfLoadedDocument AsLoadedDocument(this PdfDocumentBase doc)
-        {
-            if (doc is PdfLoadedDocument lDoc)
-                return lDoc;
-            if (doc is PdfDocument pdfDoc)
-            {
-                using var ms = new MemoryStream();
-                pdfDoc.Save(ms);
-                var array = ms.ToArray();
-                return new PdfLoadedDocument(array);
-            }
-            throw new Exception($"Unsupported PDF Document type {doc.GetType()}");
-        }
-
-        public static byte[] SaveToBytes(this PdfDocumentBase doc)
+        if (doc is PdfLoadedDocument lDoc)
+            return lDoc.Pages.Cast<PdfPageBase>();
+        if (doc is PdfDocument pdfDoc)
+            return pdfDoc.Pages.Cast<PdfPageBase>();
+        throw new Exception($"Unsupported PDF Document type {doc.GetType()}");
+    }
+    public static PdfPageBase GetPage(this PdfDocumentBase doc, int index)
+    {
+        if (doc is PdfLoadedDocument lDoc)
+            return lDoc.Pages[index];
+        if (doc is PdfDocument pdfDoc)
+            return pdfDoc.Pages[index];
+        throw new Exception($"Unsupported PDF Document type {doc.GetType()}");
+    }
+    public static int PageCount(this PdfDocumentBase doc)
+    {
+        if (doc is PdfLoadedDocument lDoc)
+            return lDoc.Pages.Count;
+        if (doc is PdfDocument pdfDoc)
+            return pdfDoc.Pages.Count;
+        throw new Exception($"Unsupported PDF Document type {doc.GetType()}");
+    }
+    public static PdfLoadedDocument AsLoadedDocument(this PdfDocumentBase doc)
+    {
+        if (doc is PdfLoadedDocument lDoc)
+            return lDoc;
+        if (doc is PdfDocument pdfDoc)
         {
             using var ms = new MemoryStream();
-            doc.Save(ms);
-            return ms.ToArray();
+            pdfDoc.Save(ms);
+            var array = ms.ToArray();
+            return new PdfLoadedDocument(array);
         }
+        throw new Exception($"Unsupported PDF Document type {doc.GetType()}");
     }
 
-    /// <summary>
-    /// Interaction logic for ScanPanel.xaml
-    /// </summary>
-    public partial class DataEntryList : UserControl, ICorePanel, IDockPanel
+    public static byte[] SaveToBytes(this PdfDocumentBase doc)
     {
-        private List<DataEntryDocument> SelectedScans = new();
+        using var ms = new MemoryStream();
+        doc.Save(ms);
+        return ms.ToArray();
+    }
+}
 
-        public delegate void DateEntrySelectionHandler(String appliesTo, Guid entityID, bool allowprocess);
+/// <summary>
+/// Interaction logic for ScanPanel.xaml
+/// </summary>
+public partial class DataEntryList : UserControl, ICorePanel, IDockPanel
+{
+    private List<DataEntryDocument> SelectedScans = new();
 
-        public event DateEntrySelectionHandler? SelectionChanged;
-        
-        public DataEntryList()
-        {
-            InitializeComponent();
-        }
+    public delegate void DateEntrySelectionHandler(String appliesTo, Guid entityID, bool allowprocess);
 
-        #region Panel
+    public event DateEntrySelectionHandler? SelectionChanged;
+    
+    public DataEntryList()
+    {
+        InitializeComponent();
+    }
 
-        public void Setup()
-        {
-            _dataEntryGrid.HiddenColumns.Add(x => x.Document.ID);
-            _dataEntryGrid.Refresh(true, false);
-            _historyGrid.Refresh(true, false);
-        }
+    #region Panel
 
-        public void Refresh()
-        {
-            if (_pages.SelectedIndex == 0)
-                _dataEntryGrid.Refresh(false, true);
-            else if (_pages.SelectedIndex == 1)
-                _historyGrid.Refresh(false,true);
-                
-        }
+    public void Setup()
+    {
+        _dataEntryGrid.HiddenColumns.Add(x => x.Document.ID);
+        _dataEntryGrid.Refresh(true, false);
+        _historyGrid.Refresh(true, false);
+    }
 
-        public void Shutdown(CancelEventArgs? cancel)
-        {
-        }
+    public void Refresh()
+    {
+        if (_pages.SelectedIndex == 0)
+            _dataEntryGrid.Refresh(false, true);
+        else if (_pages.SelectedIndex == 1)
+            _historyGrid.Refresh(false,true);
+            
+    }
 
-        #endregion
+    public void Shutdown(CancelEventArgs? cancel)
+    {
+    }
 
-        #region View List
+    #endregion
+
+    #region View List
+
+    private static List<byte[]> RenderTextFile(string textData)
+    {
+        var pdfDocument = new PdfDocument();
+        var page = pdfDocument.Pages.Add();
 
-        private static List<byte[]> RenderTextFile(string textData)
+        var font = new PdfStandardFont(PdfFontFamily.Courier, 14);
+        var textElement = new PdfTextElement(textData, font);
+        var layoutFormat = new PdfLayoutFormat
         {
-            var pdfDocument = new PdfDocument();
-            var page = pdfDocument.Pages.Add();
+            Layout = PdfLayoutType.Paginate,
+            Break = PdfLayoutBreakType.FitPage
+        };
 
-            var font = new PdfStandardFont(PdfFontFamily.Courier, 14);
-            var textElement = new PdfTextElement(textData, font);
-            var layoutFormat = new PdfLayoutFormat
-            {
-                Layout = PdfLayoutType.Paginate,
-                Break = PdfLayoutBreakType.FitPage
-            };
+        textElement.Draw(page, new RectangleF(0, 0, page.GetClientSize().Width, page.GetClientSize().Height), layoutFormat);
 
-            textElement.Draw(page, new RectangleF(0, 0, page.GetClientSize().Width, page.GetClientSize().Height), layoutFormat);
+        using var docStream = new MemoryStream();
+        pdfDocument.Save(docStream);
 
-            using var docStream = new MemoryStream();
-            pdfDocument.Save(docStream);
+        var loadeddoc = new PdfLoadedDocument(docStream.ToArray());
+        Bitmap[] bmpImages = loadeddoc.ExportAsImage(0, loadeddoc.Pages.Count - 1);
 
-            var loadeddoc = new PdfLoadedDocument(docStream.ToArray());
-            Bitmap[] bmpImages = loadeddoc.ExportAsImage(0, loadeddoc.Pages.Count - 1);
+        var jpgEncoder = ImageUtils.GetEncoder(ImageFormat.Jpeg)!;
+        var quality = Encoder.Quality;
+        var encodeParams = new EncoderParameters(1);
+        encodeParams.Param[0] = new EncoderParameter(quality, 100L);
 
-            var jpgEncoder = ImageUtils.GetEncoder(ImageFormat.Jpeg)!;
-            var quality = Encoder.Quality;
-            var encodeParams = new EncoderParameters(1);
-            encodeParams.Param[0] = new EncoderParameter(quality, 100L);
+        var images = new List<byte[]>();
+        if (bmpImages != null)
+            foreach (var image in bmpImages)
+            {
+                using var data = new MemoryStream();
+                image.Save(data, jpgEncoder, encodeParams);
+                images.Add(data.ToArray());
+            }
+        return images;
+    }
 
-            var images = new List<byte[]>();
-            if (bmpImages != null)
-                foreach (var image in bmpImages)
+    private void UpdateViewList()
+    {
+        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();
+
+        Task.Run(() =>
+        {
+            try
+            {
+                var docs = DataEntryCache.Cache.LoadDocuments(SelectedScans.Select(x => x.Document.ID).Distinct(), checkTimestamp: true);
+                LoadDocuments(docs);
+            }
+            catch (Exception e)
+            {
+                Dispatcher.BeginInvoke(() =>
                 {
-                    using var data = new MemoryStream();
-                    image.Save(data, jpgEncoder, encodeParams);
-                    images.Add(data.ToArray());
-                }
-            return images;
-        }
+                    MessageWindow.ShowError("An error occurred while loading the documents", e);
+                });
+            }
+        });
+    }
 
-        private void UpdateViewList()
+    private void LoadDocuments(IEnumerable<Document> documents)
+    {
+        var bitmaps = new Dictionary<Guid, List<ImageSource>>();
+        foreach (var document in documents)
         {
-            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();
-
-            Task.Run(() =>
+            List<byte[]> images;
+            var bitmapImages = new List<ImageSource>();
+            var extension = Path.GetExtension(document.FileName).ToLower();
+            if (extension == ".pdf")
             {
+                images = new List<byte[]>();
                 try
                 {
-                    var docs = DataEntryCache.Cache.LoadDocuments(SelectedScans.Select(x => x.Document.ID).Distinct(), checkTimestamp: true);
-                    LoadDocuments(docs);
+                    bitmapImages = ImageUtils.RenderPDFToImageSources(document.Data);
                 }
                 catch (Exception e)
                 {
-                    CoreUtils.LogException(ClientFactory.UserID, e);
-                    MessageBox.Show("An error occurred while loading the documents");
+                    MessageBox.Show($"Cannot load document '{document.FileName}': {e.Message}");
                 }
-            });
-        }
+            }
+            else if (extension == ".jpg" || extension == ".jpeg" || extension == ".png" || extension == ".bmp")
+            {
+                images = new List<byte[]> { document.Data };
+            }
+            else
+            {
+                images = ImageUtils.RenderTextFileToImages(Encoding.UTF8.GetString(document.Data));
+            }
 
-        private void LoadDocuments(IEnumerable<Document> documents)
-        {
-            var bitmaps = new Dictionary<Guid, List<ImageSource>>();
-            foreach (var document in documents)
+            bitmapImages.AddRange(images.Select(x =>
             {
-                List<byte[]> images;
-                var bitmapImages = new List<ImageSource>();
-                var extension = Path.GetExtension(document.FileName).ToLower();
-                if (extension == ".pdf")
-                {
-                    images = new List<byte[]>();
-                    try
-                    {
-                        bitmapImages = ImageUtils.RenderPDFToImageSources(document.Data);
-                    }
-                    catch (Exception e)
-                    {
-                        MessageBox.Show($"Cannot load document '{document.FileName}': {e.Message}");
-                    }
-                }
-                else if (extension == ".jpg" || extension == ".jpeg" || extension == ".png" || extension == ".bmp")
-                {
-                    images = new List<byte[]> { document.Data };
-                }
-                else
+                try
                 {
-                    images = ImageUtils.RenderTextFileToImages(Encoding.UTF8.GetString(document.Data));
+                    return ImageUtils.LoadImage(x);
                 }
-
-                bitmapImages.AddRange(images.Select(x =>
+                catch (Exception e)
                 {
-                    try
+                    Dispatcher.BeginInvoke(() =>
                     {
-                        return ImageUtils.LoadImage(x);
-                    }
-                    catch (Exception e)
-                    {
-                        MessageBox.Show($"Cannot load document '{document.FileName}': {e.Message}");
-                    }
-                    return null;
-                }).Where(x => x != null).Cast<ImageSource>());
+                        MessageWindow.ShowError($"Cannot load document '{document.FileName}", e);
+                    });
+                }
+                return null;
+            }).Where(x => x != null).Cast<ImageSource>());
 
-                foreach (var image in bitmapImages)
+            foreach (var image in bitmapImages)
+            {
+                if (!bitmaps.TryGetValue(document.ID, out var list))
                 {
-                    if (!bitmaps.TryGetValue(document.ID, out var list))
-                    {
-                        list = new List<ImageSource>();
-                        bitmaps[document.ID] = list;
-                    }
-
-                    list.Add(image);
+                    list = new List<ImageSource>();
+                    bitmaps[document.ID] = list;
                 }
+
+                list.Add(image);
             }
+        }
 
-            Dispatcher.Invoke(() =>
+        Dispatcher.Invoke(() =>
+        {
+            foreach (var scan in SelectedScans)
             {
-                foreach (var scan in SelectedScans)
+                if (bitmaps.TryGetValue(scan.Document.ID, out var list))
                 {
-                    if (bitmaps.TryGetValue(scan.Document.ID, out var list))
+                    foreach (var bitmap in list)
                     {
-                        foreach (var bitmap in list)
+                        var image = new Image
                         {
-                            var image = new Image
-                            {
-                                Source = bitmap,
-                                Margin = new Thickness(0, 0, 0, 20),
-                                ContextMenu = ViewListPanel.ContextMenu
-                            };
-                            ViewListPanel.Children.Add(image);
-                        }
+                            Source = bitmap,
+                            Margin = new Thickness(0, 0, 0, 20),
+                            ContextMenu = ViewListPanel.ContextMenu
+                        };
+                        ViewListPanel.Children.Add(image);
                     }
                 }
-            });
-        }
+            }
+        });
+    }
 
-        #endregion
+    #endregion
 
-        #region Uploading
+    #region Uploading
 
-        private void DynamicTabItem_Drop(object sender, DragEventArgs e)
+    private static byte[] RenderData(ref string filename, byte[] data)
+    {
+        var extension = Path.GetExtension(filename).ToLower();
+        if ((extension == ".jpg" || extension == ".jpeg" || extension == ".png" || extension == ".bmp") && ImageUtils.TryGetImageType(data, out var format))
+        {
+            return data;
+        }
+        else if (extension == ".pdf")
+        {
+            return data;
+        }
+        else
         {
-            Task.Run(() =>
+            using var stream = new MemoryStream(data);
+            filename = Path.ChangeExtension(filename, "pdf");
+            return DataEntryReGroupWindow.RenderToPDF(filename, stream).SaveToBytes();
+        }
+        throw new Exception("Could not render file to PDF");
+    }
+
+    private void DynamicTabItem_Drop(object sender, DragEventArgs e)
+    {
+        Task.Run(() =>
+        {
+            try
             {
-                var docs = DataEntryReGroupWindow.HandleFileDrop(e);
-                if (docs is not null)
+                var result = DocumentUtils.HandleFileDrop(e);
+                if (result is not null)
                 {
-                    foreach(var (filename, doc) in docs)
+                    foreach (var (filename, stream) in result)
                     {
-                        _dataEntryGrid.UploadDocument(Path.ChangeExtension(filename, ".pdf"), doc.SaveToBytes(), Guid.Empty);
+                        var newFilename = filename;
+                        byte[] data;
+                        if (stream is null)
+                        {
+                            data = File.ReadAllBytes(newFilename);
+                        }
+                        else
+                        {
+                            using var memStream = new MemoryStream();
+                            stream.CopyTo(memStream);
+                            data = memStream.ToArray();
+                        }
+                        data = RenderData(ref newFilename, data);
+
+                        _dataEntryGrid.UploadDocument(newFilename, data, Guid.Empty);
                     }
-                    /*Dispatcher.Invoke(() =>
-                    {
-                        ScanGrid.ShowDocumentWindow(pages, filename);
-                    });*/
                 }
-            });
-        }
-
-        private void DynamicTabItem_DragOver(object sender, DragEventArgs e)
-        {
-            if (e.Data.GetDataPresent(DataFormats.FileDrop) || e.Data.GetDataPresent("FileGroupDescriptor"))
-            {
-                e.Effects = DragDropEffects.Copy;
             }
-            else
+            catch(Exception e)
             {
-                e.Effects = DragDropEffects.None;
+                Dispatcher.BeginInvoke(() =>
+                {
+                    MessageWindow.ShowError("Could not upload documents.", e);
+                });
             }
-            e.Handled = true;
-        }
-
-        #endregion
+        });
+    }
 
-        private void _documents_OnSelectItem(object sender, DynamicGridSelectionEventArgs e)
+    private void DynamicTabItem_DragOver(object sender, DragEventArgs e)
+    {
+        if (e.Data.GetDataPresent(DataFormats.FileDrop) || e.Data.GetDataPresent("FileGroupDescriptor"))
         {
-            UpdateViewList();
-
-            DoSelect(e.Rows);
+            e.Effects = DragDropEffects.Copy;
         }
-
-        private void DoSelect(CoreRow[] rows)
+        else
         {
-            var appliesTo = rows?.Length == 1
-                ? rows[0].Get<DataEntryDocument, string>(x => x.Tag.AppliesTo)
-                : "";
-            var entityid = rows?.Length == 1
-                ? rows[0].Get<DataEntryDocument, Guid>(x => x.EntityID)
-                : Guid.Empty;
-            var archived = rows?.Length == 1
-                ? rows[0].Get<DataEntryDocument, DateTime>(x => x.Archived)
-                : DateTime.MinValue;
-            SelectionChanged?.Invoke(appliesTo, entityid, archived.IsEmpty());
+            e.Effects = DragDropEffects.None;
         }
+        e.Handled = true;
+    }
+
+    #endregion
 
-        private void _historyGrid_OnOnSelectItem(object sender, DynamicGridSelectionEventArgs e)
+    private void _documents_OnSelectItem(object sender, DynamicGridSelectionEventArgs e)
+    {
+        UpdateViewList();
+
+        DoSelect(e.Rows);
+    }
+
+    private void DoSelect(CoreRow[] rows)
+    {
+        var appliesTo = rows?.Length == 1
+            ? rows[0].Get<DataEntryDocument, string>(x => x.Tag.AppliesTo)
+            : "";
+        var entityid = rows?.Length == 1
+            ? rows[0].Get<DataEntryDocument, Guid>(x => x.EntityID)
+            : Guid.Empty;
+        var archived = rows?.Length == 1
+            ? rows[0].Get<DataEntryDocument, DateTime>(x => x.Archived)
+            : DateTime.MinValue;
+        SelectionChanged?.Invoke(appliesTo, entityid, archived.IsEmpty());
+    }
+
+    private void _historyGrid_OnOnSelectItem(object sender, DynamicGridSelectionEventArgs e)
+    {
+        DoSelect(e.Rows);
+    }
+    
+    private void _Explode_OnClick(object sender, RoutedEventArgs e)
+    {
+       _dataEntryGrid.DoExplode();
+    }
+
+    private List<DataEntryTag>? _tags;
+
+    private void _uploadMenu_OnOpened(object sender, RoutedEventArgs e)
+    {
+        if (Clipboard.ContainsText())
         {
-            DoSelect(e.Rows);
+            _pasteItem.Header = "Paste Text from Clipboard";
+            _pasteItem.Visibility = Visibility.Visible;
         }
-        
-        private void _Explode_OnClick(object sender, RoutedEventArgs e)
+        else if (Clipboard.ContainsImage())
         {
-           _dataEntryGrid.DoExplode();
+            _pasteItem.Header = "Paste Image from Clipboard";
+            _pasteItem.Visibility = Visibility.Visible;
         }
-
-        private List<DataEntryTag>? _tags;
-
-        private void _uploadMenu_OnOpened(object sender, RoutedEventArgs e)
+        else if (Clipboard.ContainsFileDropList())
         {
-            if (Clipboard.ContainsText())
+            int count = CheckAllowableFiles();
+            if (count > 0)
             {
-                _pasteItem.Header = "Paste Text from Clipboard";
+                _pasteItem.Header = $@"Paste {count} File{(count > 1 ? "s" : "")} from Clipboard";
                 _pasteItem.Visibility = Visibility.Visible;
             }
-            else if (Clipboard.ContainsImage())
-            {
-                _pasteItem.Header = "Paste Image from Clipboard";
-                _pasteItem.Visibility = Visibility.Visible;
-            }
-            else if (Clipboard.ContainsFileDropList())
-            {
-                int count = CheckAllowableFiles();
-                if (count > 0)
-                {
-                    _pasteItem.Header = $@"Paste {count} File{(count > 1 ? "s" : "")} from Clipboard";
-                    _pasteItem.Visibility = Visibility.Visible;
-                }
-            }
-            else
-                _pasteItem.Visibility = Visibility.Collapsed;
-            
-            _archive.Visibility = _dataEntryGrid.SelectedRows.Any() && Security.CanEdit<DataEntryDocument>()
-                ? Visibility.Visible
-                : Visibility.Collapsed;
+        }
+        else
+            _pasteItem.Visibility = Visibility.Collapsed;
+        
+        _archive.Visibility = _dataEntryGrid.SelectedRows.Any() && Security.CanEdit<DataEntryDocument>()
+            ? Visibility.Visible
+            : Visibility.Collapsed;
 
-            _archiveseparator.Visibility = _archive.Visibility;
-            
-            _tags ??= DataEntryGrid.GetVisibleTagList();
-            _changeTag.Items.Clear();
+        _archiveseparator.Visibility = _archive.Visibility;
+        
+        _tags ??= DataEntryGrid.GetVisibleTagList();
+        _changeTag.Items.Clear();
 
-            foreach (var tag in _tags)
-                _changeTag.Items.Add(new MenuItem()
-                {
-                    Header = tag.Name, 
-                    Command = new Command((_) => ChangeTag(tag)) { }
-                });
-            _changeTag.Items.Add(new Separator());
+        foreach (var tag in _tags)
             _changeTag.Items.Add(new MenuItem()
             {
-                Header= "Clear Tags",
-                Command = new Command((_) => ChangeTag(new DataEntryTag()))
+                Header = tag.Name, 
+                Command = new Command((_) => ChangeTag(tag)) { }
             });
-            
-            _changeTag.Visibility = _dataEntryGrid.SelectedRows.Any() && _tags.Any() && (Security.CanEdit<DataEntryDocument>() || Security.IsAllowed<CanSetupDataEntryTags>())
-                ? Visibility.Visible
-                : Visibility.Collapsed;
-            
-            _changetagseparator.Visibility = _archive.Visibility;
-            
-        }
+        _changeTag.Items.Add(new Separator());
+        _changeTag.Items.Add(new MenuItem()
+        {
+            Header= "Clear Tags",
+            Command = new Command((_) => ChangeTag(new DataEntryTag()))
+        });
+        
+        _changeTag.Visibility = _dataEntryGrid.SelectedRows.Any() && _tags.Any() && (Security.CanEdit<DataEntryDocument>() || Security.IsAllowed<CanSetupDataEntryTags>())
+            ? Visibility.Visible
+            : Visibility.Collapsed;
+        
+        _changetagseparator.Visibility = _archive.Visibility;
+        
+    }
 
-        private void ChangeTag(object obj)
+    private void ChangeTag(object obj)
+    {
+        if (obj is DataEntryTag tag)
+            _dataEntryGrid.DoChangeTags(tag.ID);
+    }
+
+    private void _addItem_OnClick(object sender, RoutedEventArgs e)
+    {
+        var ofd = new OpenFileDialog()
+        {
+            Filter = @"All Files (*.pdf, *.bmp, *.png, *.jpg, *.jpeg)|*.pdf;*.bmp;*.png;*.jpg;*.jpeg",
+            Multiselect = true,
+            Title = @"Select Files to Upload",
+            InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
+        };
+        if (ofd.ShowDialog() == DialogResult.OK)
         {
-            if (obj is DataEntryTag tag)
-                _dataEntryGrid.DoChangeTags(tag.ID);
+            foreach (var file in ofd.FileNames)
+                Upload(
+                    Path.GetFileName(file),
+                    new FileStream(file,FileMode.Open));
         }
+    }
 
-        private void _addItem_OnClick(object sender, RoutedEventArgs e)
+    private void _pasteItem_OnClick(object sender, RoutedEventArgs e)
+    {
+        if (Clipboard.ContainsText())
         {
-            var ofd = new OpenFileDialog()
-            {
-                Filter = @"All Files (*.pdf, *.bmp, *.png, *.jpg, *.jpeg)|*.pdf;*.bmp;*.png;*.jpg;*.jpeg",
-                Multiselect = true,
-                Title = @"Select Files to Upload",
-                InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
-            };
-            if (ofd.ShowDialog() == DialogResult.OK)
-            {
-                foreach (var file in ofd.FileNames)
-                    Upload(
-                        Path.GetFileName(file),
-                        new FileStream(file,FileMode.Open));
-            }
+            Upload(
+                $"Pasted Text {DateTime.Now:yyyy-MM-dd hh-mm-ss-fff}.txt",
+                new MemoryStream(new UTF8Encoding().GetBytes(Clipboard.GetText()))
+            );
         }
-
-        private void _pasteItem_OnClick(object sender, RoutedEventArgs e)
+        else if (Clipboard.ContainsImage())
         {
-            if (Clipboard.ContainsText())
-            {
-                Upload(
-                    $"Pasted Text {DateTime.Now:yyyy-MM-dd hh-mm-ss-fff}.txt",
-                    new MemoryStream(new UTF8Encoding().GetBytes(Clipboard.GetText()))
-                );
-            }
-            else if (Clipboard.ContainsImage())
-            {
-                var img = Clipboard.GetImage();
-                if (img != null)
-                {
-                    var bmp = ImageUtils.BitmapSourceToBitmap(img);
-                    using (var ms = new MemoryStream())
-                    {
-                        bmp.Save(ms, ImageFormat.Png);
-                        Upload(
-                            $"Pasted Image {DateTime.Now:yyyy-MM-dd hh-mm-ss-fff}.png",
-                            ms
-                        );
-                    }
-                }
-                
-            }
-            else if (CheckAllowableFiles() > 0)
+            var img = Clipboard.GetImage();
+            if (img != null)
             {
-                var files = Clipboard.GetFileDropList().OfType<String>().ToArray();
-                foreach (var file in files)
+                var bmp = ImageUtils.BitmapSourceToBitmap(img);
+                using (var ms = new MemoryStream())
                 {
+                    bmp.Save(ms, ImageFormat.Png);
                     Upload(
-                        Path.GetFileName(file), 
-                        new FileStream(file,FileMode.Open)
+                        $"Pasted Image {DateTime.Now:yyyy-MM-dd hh-mm-ss-fff}.png",
+                        ms
                     );
                 }
             }
+            
         }
-
-        private void Upload(string filename, Stream data)
-        {
-            var doc = DataEntryReGroupWindow.RenderToPDF(filename, data);
-            _dataEntryGrid.UploadDocument(Path.ChangeExtension(filename,"pdf"), doc.SaveToBytes(), Guid.Empty);
-        }
-        
-        private static int CheckAllowableFiles()
-        {
-            var extensions = Clipboard.GetFileDropList().OfType<String>().Select(x => Path.GetExtension(x.ToUpper())).ToArray();
-            return extensions.Count(x => 
-                String.Equals(x, "PDF")
-                || String.Equals(x, "PNG")
-                || String.Equals(x, "JPG")
-                || String.Equals(x, "JPEG")
-                || String.Equals(x, "BMP")
-                || String.Equals(x, "TXT")
-            );
-        }
-        
-        private void _pages_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
+        else if (CheckAllowableFiles() > 0)
         {
-            if (_pages.SelectedIndex == 0)
-                _dataEntryGrid.Refresh(false,true);
-            else if (_pages.SelectedIndex == 1)
-                _historyGrid.Refresh(false,true);
+            var files = Clipboard.GetFileDropList().OfType<String>().ToArray();
+            foreach (var file in files)
+            {
+                Upload(
+                    Path.GetFileName(file), 
+                    new FileStream(file,FileMode.Open)
+                );
+            }
         }
+    }
 
-        private void _remove_OnClick(object sender, RoutedEventArgs e)
-        {
-            _dataEntryGrid.DoRemove();
-        }
+    private void Upload(string filename, Stream data)
+    {
+        var doc = DataEntryReGroupWindow.RenderToPDF(filename, data);
+        _dataEntryGrid.UploadDocument(Path.ChangeExtension(filename,"pdf"), doc.SaveToBytes(), Guid.Empty);
+    }
+    
+    private static int CheckAllowableFiles()
+    {
+        var extensions = Clipboard.GetFileDropList().OfType<String>().Select(x => Path.GetExtension(x.ToUpper())).ToArray();
+        return extensions.Count(x => 
+            String.Equals(x, "PDF")
+            || String.Equals(x, "PNG")
+            || String.Equals(x, "JPG")
+            || String.Equals(x, "JPEG")
+            || String.Equals(x, "BMP")
+            || String.Equals(x, "TXT")
+        );
+    }
+    
+    private void _pages_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
+    {
+        if (_pages.SelectedIndex == 0)
+            _dataEntryGrid.Refresh(false,true);
+        else if (_pages.SelectedIndex == 1)
+            _historyGrid.Refresh(false,true);
+    }
 
-        private void _reopen_OnClick(object sender, RoutedEventArgs e)
-        {
-            _historyGrid.DoReopen();
-        }
+    private void _remove_OnClick(object sender, RoutedEventArgs e)
+    {
+        _dataEntryGrid.DoRemove();
+    }
 
-        private void _dataEntryGrid_OnContextMenuOpening(object sender, ContextMenuEventArgs e)
-        {
+    private void _reopen_OnClick(object sender, RoutedEventArgs e)
+    {
+        _historyGrid.DoReopen();
+    }
+
+    private void _dataEntryGrid_OnContextMenuOpening(object sender, ContextMenuEventArgs e)
+    {
 
-        }
     }
 }