using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Data; using System.Windows.Input; using System.Windows.Media; using System.Windows.Threading; using BeWo.Core; using BeWo.Core.Service; using BeWo.ServiceProxy; using BeWo.ViewModel; using BeWo.ViewModel.ListViewModel; using BS.Shared; using BS.Shared.Core; using BS.Shared.DataContracts; using BS.Shared.DataContracts.ClientPartials; using BS.Shared.Extensions; namespace BeWo.View.Detail { public partial class MassnahmenTreeViewView { private TreeViewItem _SelectedGoalTreeNode; public static bool IsAllowedToEditGoals { get { return BeWoApp.LoggedOnUser.HasRight(UserRightType.SupportConcept_AllowEditGoals); } } private GenericValueListEntryListVM viewModel; public GenericValueListEntryListVM ViewModel { get { return viewModel; } set { viewModel = value; InitGoalCategoriesTreeView(); treeview_individualGoals.ItemsSource = GoalTree; } } public ObservableSortCollection GoalTree { get; private set; } public MassnahmenTreeViewView(GenericValueListEntryListVM pViewModel) { InitializeComponent(); ViewModel = pViewModel; DataContext = this; } public override bool IsDirty { get { return ViewModel != null && ViewModel.IsDirty; } } protected override void Save() { var lToDos = new List>(); if (ViewModel.ChangedCount > 0) { lToDos.Add(s => s.UpdateValueListEntries(ViewModel.CommitChanged())); } if (ViewModel.AddedCount > 0) { var neueVMs = ViewModel.VMList.Where(w => w.IsNew).ToList(); TreeViewItemsList = new List(); GetAllTreeViewItems(); var obersteZiele = neueVMs.Where(w => w.IsNew && (w.ParentEntry != null && w.ParentEntry.ValueListEntryOid != null) || w.ParentEntry == null); foreach (var ziel in obersteZiele) { var ve = TreeViewItemsList.FirstOrDefault(f => f.GoalEntryVM != null && f.GoalEntryVM.Equals(ziel)); if (ve != null) { GoalService.RecursiveSynchronousValueListEntrySave(ve); } } } if (ViewModel.RemovedCount > 0) { var entfernte = Children2Delete.Where(w => w.ValueListEntryOid != null).ToList(); var entfernteDic = entfernte.ToDictionary(k => k.ValueListEntryOid.Value, v => v.ValueListEntryVersion.Value); entfernteDic.AddAndIgnoreDuplicates(ViewModel.GetRemoved().ToDictionary(dc => dc.ValueListEntryOid.Value, dc => dc.ValueListEntryVersion.Value)); lToDos.Add(s => s.DeactivateValueListEntries(entfernteDic)); } ServiceFacade.DoMultipleValueListServicesAsync(lToDos, ReloadViewModel); Cache.GetInstance().ClearAllValueListEntries(); } private bool IstGleichesZiel(ValueListEntryVM ziel1, ValueListEntryVM ziel2) { if (ziel1.DataContract.ValueListEntryOid.HasValue && ziel2.DataContract.ValueListEntryOid.HasValue) { return ziel1.DataContract.ValueListEntryOid.Value == ziel2.DataContract.ValueListEntryOid.Value; } else if (!ziel1.DataContract.ValueListEntryOid.HasValue && !ziel2.DataContract.ValueListEntryOid.HasValue) { if (ziel1.ParentEntry != null && ziel2.ParentEntry != null && ziel1.ParentEntry.Equals(ziel1.ParentEntry)) { bool test = ziel1.Equals(ziel2); return ziel1.Description == ziel2.Description; } else if (ziel1.ParentEntry == null && ziel2.ParentEntry == null) { return ziel1.Description == ziel2.Description; } } return false; } private void ReloadViewModel() { VMFactory.CreateGoalCategoryVMAsync(vm => this.Dispatch(() => { ViewModel = vm; })); } private void GoalTreeViewItem_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; _SelectedGoalTreeNode = (TreeViewItem)source; } else { _SelectedGoalTreeNode = null; } } private void TextBox_LostFocus(object sender, RoutedEventArgs e) { UpdateSelectedTreeItemText((TextBox)sender); } private void TextBox_KeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Return) { UpdateSelectedTreeItemText((TextBox)sender); } } private void ContextMenuGoals_Click(object sender, RoutedEventArgs e) { if (e.OriginalSource is MenuItem twi) { var selectedItem = treeview_individualGoals.SelectedItem as SupportConceptGoalTreeItem; if (twi.Header.Equals("Neue Maßnahme")) { if (_SelectedGoalTreeNode != null) { _SelectedGoalTreeNode.ItemContainerGenerator.StatusChanged += GoalTreeItemContainerGenerator_StatusChanged; AddMassnahme(selectedItem); } } else if (twi.Header.Equals("Neues Ziel")) { if (_SelectedGoalTreeNode != null) { _SelectedGoalTreeNode.ItemContainerGenerator.StatusChanged += GoalTreeItemContainerGenerator_StatusChanged; AddZiel(selectedItem); } } else if (twi.Header.Equals("Umbenennen")) { EditItem(treeview_individualGoals, _SelectedGoalTreeNode, selectedItem); } else if (twi.Header.Equals("Löschen")) { if (selectedItem != null) { var zielOderMassnahme = selectedItem.GoalEntryVM.Type == ValueListEntryType.SupportConceptGoalCategoryType ? "das Ziel" : "die Maßnahme"; var pluralendung = zielOderMassnahme.Equals("das Ziel") ? "en" : "n"; if (MessageBox.Show("ACHTUNG: Das Löschen von " + zielOderMassnahme.Substring(4) + pluralendung + " kann nicht rückgängig gemacht werden.\n" + "Alle verknüpften Eintragungen in der Zeiterfassung bleiben erhalten.\n\n" + "Wollen Sie " + zielOderMassnahme + " '" + selectedItem.ItemName + "' wirklich löschen?", "Löschen bestätigen", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes) { DeleteIndividualGoal(selectedItem); } } } else if(twi.Header.Equals("Notiz bearbeiten")) { EditItem(treeview_individualGoals, _SelectedGoalTreeNode, selectedItem, true); } } } private void ContextMenuGoals_Opened(object sender, RoutedEventArgs e) { if (e.OriginalSource is ContextMenu menu) { var goal = treeview_individualGoals.SelectedItem as SupportConceptGoalTreeItem; foreach (var menuitem in menu.Items.OfType().Select(item => item)) { if (menuitem.Header.Equals("Neue Maßnahme")) { menuitem.IsEnabled = goal != null && !goal.IsGoal; } else if (menuitem.Header.Equals("Neues Ziel")) { menuitem.IsEnabled = goal != null && !goal.IsGoal; } else if(menuitem.Header.Equals("Notiz bearbeiten")) { menuitem.IsEnabled = goal != null && goal.IsGoal; } menuitem.IsEnabled = menuitem.IsEnabled && IsAllowedToEditGoals; } } } private static void EditItem(TreeView tv, TreeViewItem tvi, object item, bool isNoticeTextBox = false) { if (item != null) { var treeItem = tvi; if (treeItem == null && tv != null) { treeItem = tv.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem; } if (treeItem != null) { var textBox = BeWoWpfUtils.FindItem(treeItem, isNoticeTextBox ? 1 : 0); if(textBox == null) { return; } textBox.IsReadOnly = false; textBox.Padding = new Thickness(1, 1, 1, 1); textBox.BorderThickness = new Thickness(1); textBox.Background = Brushes.White; textBox.Tag = tv.SelectedItem; textBox.Focus(); textBox.SelectAll(); } } } private void GoalTreeItemContainerGenerator_StatusChanged(object sender, EventArgs e) { var ig = (ItemContainerGenerator)sender; if (ig.Status != GeneratorStatus.ContainersGenerated) { return; } var n = ig.ContainerFromIndex(_SelectedGoalTreeNode.Items.Count - 1) as TreeViewItem; if (n != null) { n.IsSelected = true; new DispatcherTimer( TimeSpan.FromMilliseconds(200), DispatcherPriority.Background, (s1, e1) => { _SelectedGoalTreeNode = n; var item = ig.ItemFromContainer(n) as SupportConceptGoalDC; EditItem(treeview_individualGoals, _SelectedGoalTreeNode, item); ((DispatcherTimer)s1).Stop(); }, Dispatcher).Start(); } _SelectedGoalTreeNode.ItemContainerGenerator.StatusChanged -= GoalTreeItemContainerGenerator_StatusChanged; } private static void UpdateSelectedTreeItemText(TextBoxBase textBox) { if (!textBox.IsReadOnly) { textBox.Background = Brushes.Transparent; textBox.IsReadOnly = true; textBox.BorderThickness = new Thickness(0); textBox.Padding = new Thickness(1, 3, 1, 3); } } private void InitGoalCategoriesTreeView() { var categoriesWithParent = new List(); var goalList = GoalService.GetZieleMassnahmenTree(ViewModel.VMList.ToList(), false); var iGoalList = new ObservableSortCollection(); var dictOid2TreeItem = new Dictionary(); foreach (var category in goalList) { var item = new SupportConceptGoalTreeItem { GoalEntryDC = category.GoalEntryDC, GoalEntryVM = ViewModel.VMList.FirstOrDefault(f => f.DataContract.ValueListEntryOid.Value == category.GoalEntryDC.ValueListEntryOid.Value), IsExpanded = true, ParentGoal = category.ParentGoal }; if (item.GoalEntryDC.ParentOid == null) { iGoalList.Add(item); } else { categoriesWithParent.Add(item); } dictOid2TreeItem.Add(category.GoalEntryDC.ValueListEntryOid.Value, item); } foreach (var category in categoriesWithParent) { if (category.GoalEntryDC.ParentOid == null || category.GoalEntryDC.ValueListEntryOid == null) continue; if (dictOid2TreeItem.ContainsKey(category.GoalEntryDC.ParentOid.Value)) { var parent = dictOid2TreeItem[category.GoalEntryDC.ParentOid.Value]; parent.Items.Add(dictOid2TreeItem[category.GoalEntryDC.ValueListEntryOid.Value]); category.ParentGoal = parent; } } var categoriesWithParents = dictOid2TreeItem.Values.Where(w => w.GoalEntryDC.ParentOid != null).ToList(); foreach (var goalCategory in categoriesWithParents) { if (dictOid2TreeItem.ContainsKey(goalCategory.GoalEntryDC.ParentOid.Value)) { dictOid2TreeItem[goalCategory.GoalEntryDC.ParentOid.Value].Children.Add(goalCategory); } } foreach (var goal in ViewModel.VMList.Where(w => w.Type.Equals(ValueListEntryType.SupportConceptGoalType))) { var item = new SupportConceptGoalTreeItem { GoalEntryVM = goal }; if (goal.ParentEntry == null || !dictOid2TreeItem.ContainsKey(goal.ParentEntry.ValueListEntryOid.Value)) { iGoalList.Add(item); } else { var parent = dictOid2TreeItem[goal.ParentEntry.ValueListEntryOid.Value]; parent.Items.Add(item); item.ParentGoal = parent; } } GoalTree = iGoalList; } private List Children2Delete; internal void DeleteIndividualGoal(SupportConceptGoalTreeItem selectedItem) { Children2Delete = new List(); TraverseCollection(selectedItem); var parent = selectedItem.ParentGoal as SupportConceptGoalTreeItem; if (parent != null && parent.Items != null) parent.Items.Remove(selectedItem); else GoalTree.Remove(selectedItem); ViewModel.VMList.Remove(selectedItem.GoalEntryVM); } private void TraverseCollection(SupportConceptGoalTreeItem item) { var result = new List {item.GoalEntryDC ?? item.GoalEntryVM.CommitToDataContract()}; foreach (var child in item.Items) { TraverseCollection(child); } Children2Delete.AddRange(result); } public void AddMassnahme(SupportConceptGoalTreeItem parent) { var newItem = new SupportConceptGoalTreeItem(); var vm = ViewModel.NewVM; vm.Type = ValueListEntryType.SupportConceptGoalType; vm.Description = "Neue Maßnahme"; newItem.GoalEntryVM = vm; newItem.GoalEntryDC = vm.CommitToDataContract(); ViewModel.AddNewVMToList(); newItem.ParentGoal = parent; if (parent != null) { vm.ParentEntry = parent.GoalEntryDC ?? parent.GoalEntryVM.CommitToDataContract(); parent.GoalEntryVM = parent.GoalEntryVM; parent.Items.Add(newItem); parent.IsExpanded = true; } } public void AddZiel(SupportConceptGoalTreeItem parent) { var newItem = new SupportConceptGoalTreeItem(); var vm = ViewModel.NewVM; vm.Type = ValueListEntryType.SupportConceptGoalCategoryType; vm.Description = "Neues Ziel"; newItem.GoalEntryVM = vm; newItem.GoalEntryDC = vm.CommitToDataContract(); ViewModel.AddNewVMToList(); newItem.ParentGoal = parent; if (parent != null) { vm.ParentEntry = parent.GoalEntryDC ?? parent.GoalEntryVM.CommitToDataContract(); parent.GoalEntryVM = parent.GoalEntryVM; parent.Items.Add(newItem); parent.IsExpanded = true; } } private List TreeViewItemsList; private void GetAllTreeViewItems() { foreach (var parent in GoalTree) { TraverseTreeViewItem(parent); } } private void TraverseTreeViewItem(SupportConceptGoalTreeItem item) { TreeViewItemsList.Add(item); foreach (var child in item.Items) { TraverseTreeViewItem(child); } } private void ZielHinzufuegenButton_Click(object sender, RoutedEventArgs e) { var newItem = new SupportConceptGoalTreeItem(); var vm = ViewModel.NewVM; vm.Type = ValueListEntryType.SupportConceptGoalCategoryType; newItem.GoalEntryVM = vm; ViewModel.AddNewVMToList(); GoalTree.Add(newItem); GoalTree.Sort((x, y) => { if (x.ItemName == null) return String.Empty.CompareTo(y.ItemName); return x.ItemName.CompareTo(y.ItemName); }); } } public class ValueListEntryTypeToFontWeightConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var val = (bool)value; return val ? FontWeights.Normal : FontWeights.Bold; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } }