using System; using System.Diagnostics; using System.IO; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Navigation; using System.Windows.Threading; using BeWo.Core; using BeWo.ViewModel; using BeWo.ServiceProxy; using BS.Shared.DataContracts; using BS.Shared.Extensions; using BS.Shared; using BS.Shared.Core; using DevExpress.Xpf.Grid; using Microsoft.Win32; namespace BeWo.View { public partial class BeWoFileView { private TreeViewItem _SelectedTreeNode; private AbstractBaseVM _ViewModel; private object drag; private Point _MouseDownPosition = new Point(-1, -1); private readonly long? _ObjectOid; private readonly TableID _ObjectTid; private String _UploadFileName; private BeWoFolderVM selectedVM; public BeWoFileView(TableID pObjectTid, long? pObjectOid) { InitializeComponent(); CursorControl.Visibility = Visibility.Collapsed; _ObjectOid = pObjectOid; _ObjectTid = pObjectTid; ServiceFacade.DoOperationsServiceAsync( s => s.GetFolderTree(_ObjectTid, _ObjectOid ?? 0), r => this.Dispatch( delegate { if (r != null) { var vmList = r.Select(item => new BeWoFolderVM(item)).ToList(); if (vmList.Count == 0) { //erzeuge root } ViewModel = vmList[0]; treeview.DataContext = vmList; var treeviewitem = treeview.Items[0]; if (treeviewitem != null) { var container = treeview.ItemContainerGenerator.ContainerFromItem(treeviewitem); var ci = container as TreeViewItem; if (ci != null) { ci.IsSelected = true; ci.IsExpanded = true; } } } })); //BeWoFolderVM vm = new BeWoFolderVM(new BeWoFolderDC()) { Name = "root" }; //for (int i = 0; i < 10; i++) //{ // vm.SubFolders.Add(new BeWoFolderVM(new BeWoFolderDC()) { Name = "Folder " + i, ParentFolder = vm }); //} //for (int i = 0; i < 10; i++) //{ // for (int j = 0; j < 10; j++) // { // vm.SubFolders[i].Files.Add(new FileAttachmentVM(new FileAttachmentDC()) { FileName = "File " + i + " " + j, Folder = vm.SubFolders[i] }); // } //} if (!BeWoApp.LoggedOnUser.HasRight(UserRightType.DocumentsDownloadAll)) { ColumnDownload.Visible = false; ColumnDownload.ShowInColumnChooser = false; } PreviewMouseLeftButtonDown += treeview_PreviewMouseLeftButtonDown; PreviewMouseLeftButtonUp += treeview_PreviewMouseLeftButtonUp; PreviewMouseMove += treeview_PreviewMouseMove; } public override bool IsDirty { get { return ViewModel != null && ViewModel.IsDirty; } } private AbstractBaseVM ViewModel { get { return _ViewModel; } set { DataContext = value; _ViewModel = value; DocumentTableView.BestFitColumns(); } } private static void UpdateFile(FileAttachmentVM file) { ServiceFacade.DoOperationsServiceAsync( s => s.UpdateFileAttachment(file.CommitToDataContract()), r => file.DataContract.FileAttachmentVersion = r.FileAttachmentVersion); } private void InsertFolder(BeWoFolderVM folder) { ServiceFacade.DoOperationsServiceAsync( s => s.InsertNewFolder(folder.CommitToDataContract()), r => { folder.DataContract.BeWoFolderOid = r; folder.DataContract.BeWoFolderVersion = 1; }); } private static void UpdateFolder(BeWoFolderVM folder) { ServiceFacade.DoOperationsServiceAsync( s => s.UpdateFolder(folder.CommitToDataContract()), r => folder.DataContract.BeWoFolderVersion = r.BeWoFolderVersion); } private static void DeleteFolder(BeWoFolderVM folder) { if (folder.SubFolders != null) { foreach (var subfolder in folder.SubFolders) { DeleteFolder(subfolder); } } if (folder.ParentFolder != null && folder.Files != null) { foreach (var file in folder.Files) { folder.ParentFolder.Files.Add(file); file.Folder = folder.ParentFolder; } } ServiceFacade.DoOperationsServiceSync(s => s.DeleteFolder(folder.DataContract.BeWoFolderOid.Value, folder.DataContract.BeWoFolderVersion.Value)); } private void DeleteButton_Click(object sender, RoutedEventArgs e) { var lDC = this.datagrid_documents.GetCurrentValue(); if (lDC == null) { return; } if (MessageBox.Show("ACHTUNG: Das Löschen von Dateien kann nicht rückgängig gemacht werden!\nWollen Sie das Dokument '" + lDC.FileName + "' wirklich löschen?", "Löschen bestätigen", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.No) { return; } BeWoFolderVM parentFolder = lDC.Folder; if (lDC.DataContract.FileAttachmentOid.HasValue) { ServiceFacade.DoOperationsServiceAsync(s => s.DeleteFileAttachment(lDC.DataContract.FileAttachmentOid.Value, lDC.DataContract.FileAttachmentVersion.Value)); } if (parentFolder != null) parentFolder.Files.Remove(lDC); BeWoWpfUtils.RefreshDXGrid(this.datagrid_documents); } private void ContextMenu_Click(object sender, RoutedEventArgs e) { if (e.OriginalSource is MenuItem) { var twi = e.OriginalSource as MenuItem; if (twi.Header.Equals("Neu")) { var item = this.treeview.SelectedItem as BeWoFolderVM; var newItem = new BeWoFolderVM(new BeWoFolderDC()) { Name = "Neuer Ordner" }; this._SelectedTreeNode.ItemContainerGenerator.StatusChanged += this.ItemContainerGenerator_StatusChanged; item.SubFolders.Add(newItem); newItem.ParentFolder = item; InsertFolder(newItem); this._SelectedTreeNode.IsExpanded = true; } else if (twi.Header.Equals("Umbenennen")) { this.EditSelected(); } else if (twi.Header.Equals("Löschen")) { var child = this.treeview.SelectedItem as BeWoFolderVM; if (MessageBox.Show("ACHTUNG: Das Löschen von Ordnern kann nicht rückgängig gemacht werden.\n" + "Alle enthaltenen Dokumente bleiben erhalten und werden in den obersten Ordner \"Alle Ordner\" verschoben.\n\n" + "Wollen Sie den Ordner '" + child.Name + "' wirklich löschen?", "Löschen bestätigen", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes) { var p = ItemsControl.ItemsControlFromItemContainer(this._SelectedTreeNode) as TreeViewItem; p.IsSelected = true; var parent = this.treeview.SelectedItem as BeWoFolderVM; parent.SubFolders.Remove(child); DeleteFolder(child); } } } } private void EditSelected() { var textBox = BeWoWpfUtils.FindVisualChild(this._SelectedTreeNode); textBox.IsReadOnly = false; textBox.BorderThickness = new Thickness(1); textBox.Background = Brushes.White; textBox.Tag = treeview.SelectedItem; textBox.Focus(); textBox.SelectAll(); } private void ItemContainerGenerator_StatusChanged(object sender, EventArgs e) { var ig = (ItemContainerGenerator) sender; if (ig.Status != GeneratorStatus.ContainersGenerated) { return; } var n = ig.ContainerFromIndex(_SelectedTreeNode.Items.Count - 1) as TreeViewItem; n.IsSelected = true; new DispatcherTimer( TimeSpan.FromMilliseconds(200), DispatcherPriority.Background, (s1, e1) => { _SelectedTreeNode = n; EditSelected(); ((DispatcherTimer) s1).Stop(); }, Dispatcher).Start(); _SelectedTreeNode.ItemContainerGenerator.StatusChanged -= ItemContainerGenerator_StatusChanged; } private void TextBox_KeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Return) { UpdateSelectedTreeItemText((TextBox)sender); } } private void TextBox_LostFocus(object sender, RoutedEventArgs e) { UpdateSelectedTreeItemText((TextBox)sender); } private static void UpdateSelectedTreeItemText(TextBox textBox) { if (!textBox.IsReadOnly) { textBox.Background = Brushes.Transparent; textBox.IsReadOnly = true; textBox.BorderThickness = new Thickness(0); if (textBox.Tag != null) { var folder = textBox.Tag as BeWoFolderVM; if (folder != null) { folder.Name = textBox.Text; if (folder.IsDirty) { UpdateFolder(folder); } } } } } private void TreeViewItem_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e) { var source = e.OriginalSource as DependencyObject; while (source != null && !(source is TreeViewItem)) { source = VisualTreeHelper.GetParent(source); } if (source != null) { ((TreeViewItem)source).IsSelected = true; _SelectedTreeNode = (TreeViewItem)source; } else { _SelectedTreeNode = null; } } private void treeview_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { drag = treeview.GetDataItemUnderMouse(e) ?? datagrid_documents.GetRow(datagrid_documents.View.GetRowHandleByMouseEventArgs(e)); _MouseDownPosition = e.GetPosition(this); } private void treeview_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { if (drag == null) { return; } var node = drag as BeWoFolderVM; var file = drag as FileAttachmentVM; drag = null; CursorControl.Visibility = Visibility.Collapsed; //Mouse.SetCursor(Cursors.Arrow); var newParent = treeview.GetDataItemUnderMouse(e); if (newParent != null) { if (node != null) { var children = node.SubFolders.FlatOut(d => d.SubFolders).ToList(); if (newParent.Equals(node) || node.ParentFolder == null || children.Contains(newParent)) { return; } node.ParentFolder.SubFolders.Remove(node); newParent.SubFolders.Add(node); node.ParentFolder = newParent; UpdateFolder(node); } else if (file != null) { file.Folder.Files.Remove(file); newParent.Files.Add(file); file.Folder = newParent; UpdateFile(file); } } _MouseDownPosition = new Point(-1, -1); } private void treeview_PreviewMouseMove(object sender, MouseEventArgs e) { if (this.drag != null && _MouseDownPosition.X >= 0 && _MouseDownPosition.Y >= 0) { Point p = e.GetPosition(this); int distX = (int)Math.Abs(p.X - _MouseDownPosition.X); int distY = (int)Math.Abs(p.Y - _MouseDownPosition.Y); if (distX > 10 || distY > 10) { //Mouse.SetCursor(Cursors.Hand); Rect bounds = VisualTreeHelper.GetDescendantBounds(this); if ((bounds.Top < p.Y) && (bounds.Bottom > p.Y)) { Canvas.SetTop(this.CursorControl, p.Y); } if ((bounds.Left < p.X) && (bounds.Right > p.X)) { Canvas.SetLeft(this.CursorControl, p.X); } this.CursorControl.Visibility = Visibility.Visible; if (drag is BeWoFolderVM) { imageFolder.Visibility = System.Windows.Visibility.Visible; imageFile.Visibility = System.Windows.Visibility.Hidden; BeWoFolderVM folder = drag as BeWoFolderVM; labelFrom.Text = String.Format("Verzeichnis {0}", folder.Name); } else if (drag is FileAttachmentVM) { imageFolder.Visibility = System.Windows.Visibility.Hidden; imageFile.Visibility = System.Windows.Visibility.Visible; FileAttachmentVM file = drag as FileAttachmentVM; labelFrom.Text = String.Format("Datei {0}", file.FileName); } BeWoFolderVM targetFolder = this.treeview.GetDataItemUnderMouse(e); if (targetFolder != null) labelTo.Text = String.Format("-> Nach {0} verschieben", targetFolder.Name); else labelTo.Text = ""; } } } private void button_uploadDocument_Click(object sender, RoutedEventArgs pe) { if (!String.IsNullOrEmpty(popupedit_file.Text)) { long? bewoFolderOid = null; BeWoFolderVM folder = GetSelectedFolder(); if (folder != null) bewoFolderOid = folder.DataContract.BeWoFolderOid; try { var upload = new ProgressStream(File.OpenRead(_UploadFileName)); upload.ProgressChanged += (s, e) => Dispatcher.BeginInvoke( DispatcherPriority.Normal, (Action)(() => { progressbar_upload.Value = e.Data; text_progress.Content = string.Format("Bitte warten... {0:00}%", e.Data * 100); })); var lUlPackage = new UploadPackage(bewoFolderOid, 0, popupedit_file.Text, textbox_fileNotice.Text, _ObjectOid ?? 0, (int)_ObjectTid, upload); ServiceFacade.DoStreamingServiceAsync( s => s.UploadDocument(lUlPackage), r => this.Dispatch( delegate { selectedVM = (BeWoFolderVM)treeview.SelectedItem; var newFileVM = new FileAttachmentVM(r.Attachment); selectedVM.Files.Add(newFileVM); newFileVM.Folder = selectedVM; progressbar_upload.Value = 0; text_progress.Content = string.Empty; _UploadFileName = null; button_uploadDocument.IsEnabled = false; popupedit_file.Text = string.Empty; textbox_fileNotice.Text = string.Empty; upload.Dispose(); }), () => this.Dispatch( delegate { progressbar_upload.Value = 0; text_progress.Content = string.Empty; upload.Dispose(); })); } catch (Exception ex) { MessageBox.Show(ex.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Exclamation); } } } private BeWoFolderVM GetSelectedFolder() { return treeview.SelectedItem as BeWoFolderVM; } private void popupedit_file_PopUpClick(object sender, RoutedEventArgs ev) { var dlg = new OpenFileDialog(); if (dlg.ShowDialog() == true) { try { _UploadFileName = dlg.FileName; popupedit_file.Text = dlg.SafeFileName; button_uploadDocument.IsEnabled = true; } catch (Exception ex) { MessageBox.Show(ex.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Exclamation); } } } private void ContextMenu_Opened(object sender, RoutedEventArgs e) { if (e.OriginalSource is ContextMenu) { ContextMenu menu = e.OriginalSource as ContextMenu; BeWoFolderVM folder = this.treeview.SelectedItem as BeWoFolderVM; bool enabled = false; if (folder != null) { if (folder.ParentFolder != null) enabled = true; } foreach (var item in menu.Items) { if (item is MenuItem) { MenuItem menuitem = item as MenuItem; if (menuitem.Header.Equals("Umbenennen")) menuitem.IsEnabled = enabled; } } } } private void Hyperlink_OnRequestNavigate(object sender, RequestNavigateEventArgs eventargs) { var navitageUri = ((Hyperlink)sender).NavigateUri.ToString(); var splittedUri = navitageUri.Split('='); var fileOid = 0L; long.TryParse(splittedUri[1], out fileOid); try { var lFA = new FileAttachmentDC(); ServiceFacade.DoDownloadServiceAsync(d => lFA = d.GetFileAttachment(fileOid), cb => this.Dispatch(delegate { try { if (lFA.URL == null) return; var odialog = new OpenOrSaveDialog(lFA.FileName); odialog.ShowDialog(); if (odialog.Selection == null) return; if (!odialog.Selection.Value) { var tmp = Path.GetTempPath() + Path.GetFileName(lFA.URL); BeWoApp.CurrentBeWo.DocumentWatcher.FileCreated -= DocumentWatcher_FileCreated; BeWoApp.CurrentBeWo.DocumentWatcher.FileDeleted -= DocumentWatcher_FileDeleted; BeWoApp.CurrentBeWo.DocumentWatcher.StoppeDateiUeberwachung(tmp); if (File.Exists(tmp)) File.Delete(tmp); using (var uFileStream = File.Create(tmp)) { uFileStream.Write(lFA.BinaryData, 0, lFA.BinaryData.Length); } System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(tmp)); BeWoApp.CurrentBeWo.DocumentWatcher.StarteDateiUeberwachung(new DocumentWatcherInfo(tmp, cb.Description, cb.BeWoFolderOid, cb.FileAttachmentOid, cb.FileAttachmentVersion, _ObjectOid, _ObjectTid)); BeWoApp.CurrentBeWo.DocumentWatcher.FileCreated += DocumentWatcher_FileCreated; BeWoApp.CurrentBeWo.DocumentWatcher.FileDeleted += DocumentWatcher_FileDeleted; return; } if (odialog.Selection.Value) { var sf = new SaveFileDialog { FileName = Path.GetFileName(lFA.URL) }; if (sf.ShowDialog() != true) return; using (var myStream = (FileStream)sf.OpenFile()) { myStream.Write(lFA.BinaryData, 0, lFA.BinaryData.Length); myStream.Close(); } } } catch (Exception ex) { MessageBox.Show("Beim Öffnen des Dokuments ist leider ein Fehler aufgetreten:\n" + ex.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Exclamation); } })); } catch (Exception ex) { MessageBox.Show(ex.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Exclamation); } } private BeWoFolderVM GetFolderWithOid(long? folderOid) { BeWoFolderVM alleOrdnerFolder = _ViewModel as BeWoFolderVM; if (folderOid.HasValue) { //Durchsuche alle kinder und deren kinder bis folderoid gefunden return GetChildFolderWithOid(folderOid.Value, alleOrdnerFolder); } return alleOrdnerFolder; } private BeWoFolderVM GetChildFolderWithOid(long folderOid, BeWoFolderVM folder) { if (folder.DataContract.BeWoFolderOid.HasValue && folder.DataContract.BeWoFolderOid.Value == folderOid) return folder; foreach (var childFolder in folder.SubFolders) { var f = GetChildFolderWithOid(folderOid, childFolder); if (f != null) { return f; } } return null; } void DocumentWatcher_FileDeleted(long? folderOid, long? objectOid, TableID objectTid, long fileAttachmentOid) { if (objectOid == _ObjectOid && objectTid == _ObjectTid) { BeWoFolderVM parentFolder = GetFolderWithOid(folderOid); if (parentFolder != null) { FileAttachmentVM fileToDelete = null; foreach (var file in parentFolder.Files) { if (file.DataContract.FileAttachmentOid == fileAttachmentOid) { fileToDelete = file; } } if (fileToDelete != null) { parentFolder.Files.Remove(fileToDelete); BeWoWpfUtils.RefreshDXGrid(this.datagrid_documents); } } } } void DocumentWatcher_FileCreated(long? folderOid, long? objectOid, TableID objectTid, FileAttachmentDC fileAttachment) { if (objectOid == _ObjectOid && objectTid == _ObjectTid) { BeWoFolderVM folder = GetFolderWithOid(folderOid); if (folder != null) { var newFileVM = new FileAttachmentVM(fileAttachment); BeWoApp.CurrentBeWo.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)delegate { folder.Files.Add(newFileVM); newFileVM.Folder = folder; }); } } } private void DocumentTableView_OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e) { //DocumentTableView.BestFitColumns(); } private void Datagrid_documents_OnItemsSourceChanged(object sender, ItemsSourceChangedEventArgs e) { DocumentTableView.BestFitColumns(); } } }