123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559 |
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.IO;
- using System.Linq;
- using System.Threading.Tasks;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Data;
- using System.Windows.Input;
- using System.Windows.Media;
- using Comal.Classes;
- using InABox.Clients;
- using InABox.Configuration;
- using InABox.Core;
- using InABox.DynamicGrid;
- using InABox.WPF;
- using Microsoft.Win32;
- using Syncfusion.UI.Xaml.Diagram;
- using System.ComponentModel;
- using NPOI.SS.Formula.Functions;
- namespace PRSDesktop
- {
- /// <summary>
- /// Interaction logic for OrganizationalChart.xaml
- /// </summary>
- public partial class OrgChartPanel : UserControl, IPanel<Employee>
- {
- private OrgChartSettings _settings;
- private readonly OrgChartDataModel model = new();
- public OrgChartPanel()
- {
- InitializeComponent();
- }
- public event DataModelUpdateEvent? OnUpdateDataModel;
- public bool IsReady { get; set; }
- #region IPanel Support
- public void CreateToolbarButtons(IPanelHost host)
- {
- if (Security.IsAllowed<CanEditOrgChart>())
- {
- host.CreateSetupAction(new PanelAction
- {
- Caption = "Org Chart Settings",
- OnExecute = OrgChartSettings_Click
- });
- }
- }
- private void OrgChartSettings_Click(PanelAction obj)
- {
- var settings = new GlobalConfiguration<OrgChartSettings>().Load();
- var grid = new DynamicItemsListGrid<OrgChartSettings>();
- if (grid.EditItems(new OrgChartSettings[] { settings }))
- {
- new GlobalConfiguration<OrgChartSettings>().Save(settings);
- _settings = settings;
- }
- }
- public Dictionary<string, object[]> Selected()
- {
- return new Dictionary<string, object[]>();
- }
- public void Heartbeat(TimeSpan time)
- {
- }
- public void Setup()
- {
- _settings = new GlobalConfiguration<OrgChartSettings>().Load();
- model.Appearance = _settings.Appearance;
- model.Layout = _settings.Layout;
- //Zoom.Value = _settings.Zoom;
- diagram.DataContext = model;
- (diagram.Info as IGraphInfo).ItemAdded += ApplyItemTemplate;
- model.Active = true;
- }
- public void Shutdown(CancelEventArgs? cancel)
- {
- }
- public string SectionName => "Organisational Chart";
- public DataModel DataModel(Selection selection)
- {
- return new BaseDataModel<Employee>(null);
- }
- public void Refresh()
- {
- model.Refresh();
- var graphinfo = diagram.Info as IGraphInfo;
- graphinfo.Commands.FitToPage.Execute(null);
- }
- private void ApplyItemTemplate(object sender, ItemAddedEventArgs args)
- {
- var node = args.Item as NodeViewModel;
- if (node == null)
- return;
- node.ContentTemplate = TemplateGenerator.CreateDataTemplate(() =>
- {
- var image = new Border
- {
- BorderBrush = new SolidColorBrush(Colors.Gray),
- BorderThickness = new Thickness(0.75),
- CornerRadius = new CornerRadius(25.0),
- Width = 50,
- Height = 50,
- Margin = new Thickness(0, 0, 5, 0)
- };
- image.SetBinding(TagProperty, new Binding("ID"));
- image.SetBinding(Border.BackgroundProperty, new Binding("Image"));
- image.SetBinding(VisibilityProperty, new Binding("ImageVisible"));
- image.SetValue(Grid.ColumnProperty, 0);
- image.SetValue(Grid.RowProperty, 0);
- image.SetValue(Grid.RowSpanProperty, 2);
- image.SetValue(VerticalAlignmentProperty, VerticalAlignment.Center);
- var position = new Label();
- position.FontWeight = FontWeights.DemiBold;
- position.HorizontalContentAlignment = HorizontalAlignment.Center;
- //description.Background = new SolidColorBrush(Colors.Blue);
- position.VerticalContentAlignment = VerticalAlignment.Top;
- position.SetBinding(TagProperty, new Binding("ID"));
- position.SetBinding(ContentProperty, "Position");
- position.SetValue(Grid.ColumnProperty, 1);
- position.SetValue(Grid.RowProperty, 0);
- var name = new Label();
- //name.Background = new SolidColorBrush(Colors.Green);
- name.HorizontalContentAlignment = HorizontalAlignment.Center;
- name.VerticalContentAlignment = VerticalAlignment.Center;
- name.SetBinding(TagProperty, new Binding("ID"));
- name.SetBinding(ContentProperty, "Name");
- name.Background = new SolidColorBrush(Colors.Transparent);
- var nameborder = new Border
- {
- BorderBrush = new SolidColorBrush(Colors.Transparent),
- BorderThickness = new Thickness(0.75),
- CornerRadius = new CornerRadius(5.0),
- Padding = new Thickness(0)
- };
- nameborder.SetValue(Grid.ColumnProperty, 1);
- nameborder.SetValue(Grid.RowProperty, 1);
- nameborder.SetBinding(TagProperty, new Binding("ID"));
- nameborder.SetBinding(Border.BackgroundProperty, "WarningColor");
- nameborder.Child = name;
- var layout = new Grid();
- layout.RowDefinitions.Add(new RowDefinition { Height = new GridLength(25, GridUnitType.Pixel) });
- layout.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });
- layout.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) });
- layout.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
- layout.Children.Add(image);
- layout.Children.Add(position);
- layout.Children.Add(nameborder);
- var border = new Border
- {
- MinWidth = 150,
- BorderBrush = new SolidColorBrush(Colors.Gray),
- BorderThickness = new Thickness(0.75),
- CornerRadius = new CornerRadius(5.0),
- Padding = new Thickness(5),
- Child = layout
- };
- border.MouseDown += Border_MouseDown;
- border.SetBinding(TagProperty, "ID");
- border.SetBinding(Border.BackgroundProperty, "Color");
- return border;
- });
- }
- #endregion
- #region Menu Actions
- private void AddExistingItemClick(object sender, RoutedEventArgs e)
- {
- var entry = (sender as MenuItem).Tag as System.Tuple<OrgChartEntry, OrgChartEntry>;
- entry.Item2.ParentID = entry.Item1.ID;
- entry.Item2.Visible = true;
- UpdateItems(new[] { entry.Item2 });
- }
- private void CreateNewItemClick(object sender, RoutedEventArgs e)
- {
- var menu = sender as MenuItem;
- var parent = menu.Tag as OrgChartEntry;
- var entry = new OrgChartEntry { ParentID = parent != null ? parent.ID : Guid.Empty };
- EditItem(entry);
- }
- private void EditItemClick(object sender, RoutedEventArgs e)
- {
- var entry = (sender as MenuItem).Tag as OrgChartEntry;
- EditItem(entry);
- }
- private void RemoveItemClick(object sender, RoutedEventArgs e)
- {
- var entry = (sender as MenuItem).Tag as OrgChartEntry;
- var updates = model.Data.Where(x => x.ParentID == entry.ID).ToList();
- foreach (var child in updates)
- child.ParentID = entry.ParentID;
- entry.ParentID = Guid.Empty;
- entry.Visible = false;
- updates.Add(entry);
- UpdateItems(updates);
- }
- private void ChanegColorClick(object sender, RoutedEventArgs e)
- {
- var entry = (sender as MenuItem).Tag as OrgChartEntry;
- var color = ImageUtils.StringToColor(entry.Color);
- if (ColorEdit.Execute("Change Color", ref color))
- {
- entry.Color = ImageUtils.ColorToString(color);
- UpdateItems(new[] { entry });
- }
- }
- private void StartNewTreeClick(object sender, RoutedEventArgs e)
- {
- var entry = (sender as MenuItem).Tag as OrgChartEntry;
- entry.ParentID = Guid.Empty;
- UpdateItems(new[] { entry });
- }
- private void MoveToClick(object sender, RoutedEventArgs e)
- {
- var entry = (sender as MenuItem).Tag as System.Tuple<OrgChartEntry, OrgChartEntry>;
- entry.Item1.ParentID = entry.Item2.ID;
- UpdateItems(new[] { entry.Item1 });
- }
- private void EditItem(OrgChartEntry entry)
- {
- if (_settings.Layout == OrgChartLayout.Employee)
- {
- var employee = entry.ID == Guid.Empty
- ? new Employee()
- : new Client<Employee>().Load(new Filter<Employee>(x => x.ID).IsEqualTo(entry.ID)).FirstOrDefault();
- if (employee != null)
- {
- if (employee.ID == Guid.Empty)
- employee.OrgChart.ReportsTo.ID = entry.ID;
- var bOK = new EmployeeGrid().EditItems(new[] { employee });
- if (bOK)
- model.Refresh();
- }
- else
- {
- MessageBox.Show("Unable to Locate Employee!");
- }
- }
- else if (_settings.Layout == OrgChartLayout.Position)
- {
- var position = entry.ID == Guid.Empty
- ? new EmployeePosition()
- : new Client<EmployeePosition>().Load(new Filter<EmployeePosition>(x => x.ID).IsEqualTo(entry.ID)).FirstOrDefault();
- if (position != null)
- {
- if (position.ID == Guid.Empty)
- position.OrgChart.ReportsTo.ID = entry.ID;
- var bOK = new DynamicDataGrid<EmployeePosition>().EditItems(new[] { position });
- if (bOK)
- model.Refresh();
- }
- else
- {
- MessageBox.Show("Unable to Locate Position!");
- }
- }
- else if (_settings.Layout == OrgChartLayout.Role)
- {
- var role = entry.ID == Guid.Empty
- ? new Role()
- : new Client<Role>().Load(new Filter<Role>(x => x.ID).IsEqualTo(entry.ID)).FirstOrDefault();
- if (role != null)
- {
- if (role.ID == Guid.Empty)
- role.OrgChart.ReportsTo.ID = entry.ID;
- var bOK = new DynamicDataGrid<Role>().EditItems(new[] { role });
- if (bOK)
- model.Refresh();
- }
- else
- {
- MessageBox.Show("Unable to Locate Role!");
- }
- }
- }
- private void UpdateItems(IEnumerable<OrgChartEntry> entries)
- {
- if (_settings.Layout == OrgChartLayout.Employee)
- {
- var updates = new List<Employee>();
- foreach (var entry in entries)
- {
- var update = new Employee();
- update.ID = entry.ID;
- update.OrgChart.ReportsTo.ID = entry.ParentID;
- update.OrgChart.Color = entry.Color;
- update.OrgChart.Visible = entry.Visible;
- updates.Add(update);
- }
- using (new WaitCursor())
- {
- new Client<Employee>().Save(updates, "Updated from Org Chart");
- //model.Refresh();
- }
- }
- else if (_settings.Layout == OrgChartLayout.Position)
- {
- var updates = new List<EmployeePosition>();
- foreach (var entry in entries)
- {
- var update = new EmployeePosition();
- update.ID = entry.ID;
- update.OrgChart.ReportsTo.ID = entry.ParentID;
- update.OrgChart.Color = entry.Color;
- update.OrgChart.Visible = entry.Visible;
- updates.Add(update);
- }
- using (new WaitCursor())
- {
- new Client<EmployeePosition>().Save(updates, "Updated from Org Chart");
- //model.Refresh();
- }
- }
- else if (_settings.Layout == OrgChartLayout.Role)
- {
- var updates = new List<Role>();
- foreach (var entry in entries)
- {
- var update = new Role();
- update.ID = entry.ID;
- update.OrgChart.ReportsTo.ID = entry.ParentID;
- update.OrgChart.Color = entry.Color;
- update.OrgChart.Visible = entry.Visible;
- updates.Add(update);
- }
- using (new WaitCursor())
- {
- new Client<Role>().Save(updates, "Updated from Org Chart");
- //model.Refresh();
- }
- }
- diagram.Visibility = Visibility.Collapsed;
- model.Refresh();
- diagram.Visibility = Visibility.Visible;
- }
- #endregion
- #region Menu Setup
- private void LoadNewItemsMenu(ItemsControl menu)
- {
- menu.Items.Clear();
- var parent = menu.Tag as OrgChartEntry;
- foreach (var entry in model.Data.Where(x => x.Visible == false))
- {
- var item = new MenuItem { Header = _settings.Layout == OrgChartLayout.Employee ? entry.Name : entry.Position };
- item.Click += AddExistingItemClick;
- item.Tag = new System.Tuple<OrgChartEntry, OrgChartEntry>(parent, entry);
- menu.Items.Add(item);
- }
- }
- private void LoadMoveToOptions(OrgChartEntry current, MenuItem moveto)
- {
- foreach (var entry in model.Data.OrderBy(x => x.Name))
- if (!model.Data.IsChildOf(entry, current))
- {
- var item = new MenuItem { Header = _settings.Layout == OrgChartLayout.Employee ? entry.Name : entry.Position };
- item.Tag = new System.Tuple<OrgChartEntry, OrgChartEntry>(current, entry);
- item.Click += MoveToClick;
- moveto.Items.Add(item);
- }
- if (moveto.Items.Count > 0 && current.ParentID != Guid.Empty)
- moveto.Items.Add(new Separator());
- if (current.ParentID != Guid.Empty)
- {
- var noone = new MenuItem { Header = "Start New Tree" };
- noone.Click += StartNewTreeClick;
- noone.Tag = current;
- moveto.Items.Add(noone);
- }
- }
- private void Diagram_MouseDown(object sender, MouseButtonEventArgs e)
- {
- if (e.RightButton == MouseButtonState.Pressed && Security.IsAllowed<CanEditOrgChart>())
- {
- var menu = new ContextMenu();
- var additem = new MenuItem { Header = "Add Existing" };
- LoadNewItemsMenu(additem);
- additem.IsEnabled = additem.Items.Count > 0;
- menu.Items.Add(additem);
- menu.Items.Add(new Separator());
- var createitem = new MenuItem { Header = "Create New" };
- createitem.Click += CreateNewItemClick;
- menu.Items.Add(createitem);
- menu.IsOpen = true;
- }
- }
- private void Border_MouseDown(object sender, MouseButtonEventArgs e)
- {
- if (e.RightButton == MouseButtonState.Pressed && Security.IsAllowed<CanEditOrgChart>())
- {
- var id = (Guid)(sender as Border).Tag;
- var current = model.Data.FirstOrDefault(x => x.ID == id);
- if (current == null)
- return;
- e.Handled = true;
- if (e.ClickCount == 2)
- {
- EditItem(current);
- }
- else
- {
- var menu = new ContextMenu();
- var moveto = new MenuItem { Header = "Move To.." };
- menu.Items.Add(moveto);
- LoadMoveToOptions(current, moveto);
- var changecolor = new MenuItem { Header = "Change Color" };
- changecolor.Click += ChanegColorClick;
- changecolor.Tag = current;
- menu.Items.Add(changecolor);
- var edititem = new MenuItem { Header = "Edit Properties" };
- edititem.Click += EditItemClick;
- edititem.Tag = current;
- menu.Items.Add(edititem);
- menu.Items.Add(new Separator());
- var additem = new MenuItem { Header = "Add Existing" };
- menu.Items.Add(additem);
- LoadNewItemsMenu(additem);
- additem.IsEnabled = additem.Items.Count > 0;
- var newitem = new MenuItem { Header = "Create New" };
- newitem.Click += CreateNewItemClick;
- menu.Items.Add(newitem);
- menu.Items.Add(new Separator());
- var removeitem = new MenuItem { Header = "Remove" };
- removeitem.Click += RemoveItemClick;
- removeitem.Tag = current;
- menu.Items.Add(removeitem);
- menu.IsOpen = true;
- }
- }
- }
- #endregion
- #region Toolbar Actions
- private void Zoom_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
- {
- if (diagram == null)
- return;
- //if (model.Active)
- // SaveSettings();
- var graphinfo = diagram.Info as IGraphInfo;
- graphinfo.Commands.Zoom.Execute(new ZoomPositionParameter
- {
- ZoomCommand = ZoomCommand.Zoom,
- ZoomTo = e.NewValue / 100
- });
- }
- private void PrintButton_Click(object sender, RoutedEventArgs e)
- {
- if (diagram == null)
- return;
- diagram.PrintingService.ShowDialog = true;
- diagram.PrintingService.Print();
- }
- private void ExportButton_Click(object sender, RoutedEventArgs e)
- {
- if (diagram == null)
- return;
- var dlg = new SaveFileDialog();
- dlg.Filter = "PNG Files (*.png)|*.png|PDF Files (*.pdf)|*.pdf";
- dlg.FilterIndex = 0;
- dlg.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
- dlg.FileName = Path.Combine(dlg.InitialDirectory, "Organizational Chart.png");
- if (dlg.ShowDialog() == true)
- {
- var tempfile = Path.GetTempFileName();
- var finalfile = Path.ChangeExtension(dlg.FileName, dlg.FilterIndex > 1 ? "pdf" : "png");
- diagram.ExportSettings = new ExportSettings
- {
- IsSaveToXps = dlg.FilterIndex > 1,
- FileName = dlg.FilterIndex > 1 ? tempfile : finalfile,
- ExportMode = ExportMode.Content
- };
- diagram.Export();
- if (dlg.FilterIndex > 1)
- {
- MessageBox.Show("PDF Functions broken .in .NET6");
- return;
- // XPSToPdfConverter converter = new XPSToPdfConverter();
- // PdfDocument pdfDocument = converter.Convert(tempfile);
- // pdfDocument.Save(finalfile);
- // pdfDocument.Close(true);
- // System.IO.File.Delete(tempfile);
- }
- Process.Start(finalfile);
- }
- }
- #endregion
- }
- }
|