| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564 | 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 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)        {            HumanResourcesSetupActions.EmployeePositions(host);            HumanResourcesSetupActions.EmployeeRoles(host);            if (Security.IsAllowed<CanEditOrgChart>())            {                host.CreateSetupSeparator();                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    }}
 |