| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457 | 
							- using System;
 
- using System.Collections.Generic;
 
- using System.ComponentModel;
 
- using System.Drawing;
 
- using System.Reflection;
 
- using System.Windows;
 
- using System.Windows.Controls;
 
- using InABox.Clients;
 
- using InABox.Configuration;
 
- using InABox.Core;
 
- using InABox.DynamicGrid;
 
- namespace InABox.Wpf;
 
- public interface IPanelActionItem
 
- {
 
- }
 
- public interface IPanelActionEntry
 
- {
 
-     object? Data { get; set; }
 
-     string? Caption { get; set; }
 
-     Bitmap? Image { get; set; }
 
-     void Execute();
 
- }
 
- public class PanelActionEntry<T> : DependencyObject, IPanelActionEntry
 
- {
 
-     
 
-     public static readonly DependencyProperty DataProperty = DependencyProperty.Register(
 
-         nameof(Data),
 
-         typeof(T),
 
-         typeof(PanelActionEntry<T>)
 
-     );
 
-     public T? Data { get; set; }
 
-     object? IPanelActionEntry.Data
 
-     {
 
-         get => this.Data;
 
-         set => this.Data = value == null ? default(T) : (T)value;
 
-     }
 
-     
 
-     public static readonly DependencyProperty CaptionProperty = DependencyProperty.Register(
 
-         nameof(Caption),
 
-         typeof(string),
 
-         typeof(PanelActionEntry<T>),
 
-         new PropertyMetadata("")
 
-     );
 
-     public string? Caption { get; set; }
 
-     
 
-     public static readonly DependencyProperty ImageProperty = DependencyProperty.Register(
 
-         nameof(Image),
 
-         typeof(Bitmap),
 
-         typeof(PanelActionEntry<T>)
 
-     );    
 
-     public Bitmap? Image
 
-     { 
 
-         get => GetValue(ImageProperty) as Bitmap;
 
-         set => SetValue(ImageProperty, value);
 
-     }
 
-     
 
-     public Action<PanelActionEntry<T>>? OnExecute { get; set; }
 
-     public PanelActionEntry()
 
-     {
 
-         
 
-     }
 
-     
 
-     public PanelActionEntry(string? caption, Bitmap? image, T? data, Action<PanelActionEntry<T>>? onExecute)
 
-     {
 
-         Data = data;
 
-         Caption = caption;
 
-         Image = image;
 
-         OnExecute = onExecute;
 
-     }
 
-     public void Execute()
 
-     {
 
-         OnExecute?.Invoke(this);
 
-     }
 
-     
 
- }
 
- public class PanelAction : DependencyObject, IPanelActionItem
 
- {
 
-     public Func<PanelAction,IPanelActionEntry[]>? OnPopulate { get; set; }
 
-     public Action<PanelAction>? OnExecute { get; set; }
 
-     
 
-     
 
-     public static readonly DependencyProperty IsEnabledProperty = DependencyProperty.Register(
 
-         nameof(IsEnabled),
 
-         typeof(bool),
 
-         typeof(PanelAction),
 
-         new PropertyMetadata(true)
 
-     );
 
-     
 
-     public bool IsEnabled 
 
-     { 
 
-         get => (bool)GetValue(IsEnabledProperty);
 
-         set => SetValue(IsEnabledProperty, value);
 
-     }
 
-     
 
-     
 
-     public static readonly DependencyProperty VisibilityProperty = DependencyProperty.Register(
 
-         nameof(Visibility),
 
-         typeof(Visibility),
 
-         typeof(PanelAction),
 
-         new PropertyMetadata(Visibility.Visible)
 
-     );
 
-     
 
-     public Visibility Visibility 
 
-     { 
 
-         get => (Visibility)GetValue(VisibilityProperty);
 
-         set => SetValue(VisibilityProperty, value);
 
-     }
 
-     public static readonly DependencyProperty CaptionProperty = DependencyProperty.Register(
 
-         nameof(Caption),
 
-         typeof(string),
 
-         typeof(PanelAction),
 
-         new PropertyMetadata("")
 
-     );
 
-     
 
-     public string Caption 
 
-     { 
 
-         get => (string)GetValue(CaptionProperty);
 
-         set => SetValue(CaptionProperty, value);
 
-     }
 
-     public static readonly DependencyProperty ImageProperty = DependencyProperty.Register(
 
-         nameof(Image),
 
-         typeof(Bitmap),
 
-         typeof(PanelAction)
 
-     );    
 
-     public Bitmap? Image
 
-     { 
 
-         get => GetValue(ImageProperty) as Bitmap;
 
-         set => SetValue(ImageProperty, value);
 
-     }
 
-     
 
-     public static readonly DependencyProperty MenuProperty = DependencyProperty.Register(
 
-         nameof(Menu),
 
-         typeof(ContextMenu),
 
-         typeof(PanelAction)
 
-     );   
 
-     
 
-     public ContextMenu? Menu
 
-     { 
 
-         get => GetValue(MenuProperty) as ContextMenu;
 
-         set => SetValue(MenuProperty, value);
 
-     }
 
-     public PanelAction()
 
-     {
 
-     }
 
-     public PanelAction(string caption, Bitmap? image, Action<PanelAction>? onExecute,
 
-         Func<PanelAction, IPanelActionEntry[]>? onPopulate = null)
 
-     {
 
-         Caption = caption;
 
-         Image = image;
 
-         OnPopulate = onPopulate;
 
-         OnExecute = onExecute;
 
-     }
 
-     
 
-     public void Execute()
 
-     {
 
-         OnExecute?.Invoke(this);
 
-     }
 
-     public IPanelActionEntry[]? Populate()
 
-     {
 
-         return OnPopulate?.Invoke(this);
 
-     }
 
-     
 
- }
 
- public class PanelActionSeparator : IPanelActionItem
 
- {
 
- }
 
- public interface ICorePanel
 
- {
 
-     void Setup();
 
-     /// <summary>
 
-     /// Shutdown the panel.
 
-     /// </summary>
 
-     /// <param name="cancel">If the operation can be cancelled, this is not <see langword="null"/>.</param>
 
-     void Shutdown(CancelEventArgs? cancel);
 
-     void Refresh();
 
- }
 
- public interface IBasePanel : ICorePanel, IDataModelSource
 
- {
 
-     bool IsReady { get; set; }
 
-     void CreateToolbarButtons(IPanelHost host);
 
-     Dictionary<string, object[]> Selected();
 
-     void Heartbeat(TimeSpan time);
 
- }
 
- public interface IPanel<T> : IBasePanel
 
- {
 
- }
 
- public interface IPropertiesPanel<TProperties>
 
-     where TProperties : BaseObject, IGlobalConfigurationSettings, new()
 
- {
 
-     public TProperties Properties { get; set; }
 
- }
 
- public interface IPropertiesPanel<TProperties, TSecurity> : IPropertiesPanel<TProperties>
 
-     where TProperties : BaseObject, IGlobalConfigurationSettings, new()
 
-     where TSecurity : ISecurityDescriptor, new()
 
- {
 
- }
 
- public static class PanelUtils
 
- {
 
-     #region Properties
 
-     public static void InitializePanelProperties(IBasePanel panel)
 
-     {
 
-         var propertiesInterface = panel.GetType().GetInterfaceDefinition(typeof(IPropertiesPanel<>));
 
-         if (propertiesInterface is not null)
 
-         {
 
-             var propertiesType = propertiesInterface.GenericTypeArguments[0];
 
-             var method = typeof(PanelUtils)
 
-                 .GetMethod(nameof(InitializePanelPropertiesGeneric), BindingFlags.Public | BindingFlags.Static)
 
-                 ?.MakeGenericMethod(panel.GetType(), propertiesType)
 
-                 .Invoke(null, new object?[] { panel });
 
-         }
 
-     }
 
-     public static void InitializePanelPropertiesGeneric<TPanel, TProperties>(TPanel panel)
 
-         where TPanel : IPropertiesPanel<TProperties>
 
-         where TProperties : BaseObject, IGlobalConfigurationSettings, new()
 
-     {
 
-         panel.Properties = LoadPanelProperties<TPanel, TProperties>();
 
-     }
 
-     public static TProperties LoadPanelProperties<TPanel, TProperties>()
 
-         where TPanel : IPropertiesPanel<TProperties>
 
-         where TProperties : BaseObject, IGlobalConfigurationSettings, new()
 
-     {
 
-         var config = new GlobalConfiguration<TProperties>();
 
-         return config.Load();
 
-     }
 
-     public static void SavePanelProperties<TPanel, TProperties>(TProperties properties)
 
-         where TPanel : IPropertiesPanel<TProperties>
 
-         where TProperties : BaseObject, IGlobalConfigurationSettings, new()
 
-     {
 
-         var config = new GlobalConfiguration<TProperties>();
 
-         config.Save(properties);
 
-     }
 
-     public static void EditPanelProperties<TPanel, TProperties>()
 
-         where TPanel : IPropertiesPanel<TProperties>
 
-         where TProperties : BaseObject, IGlobalConfigurationSettings, new()
 
-     {
 
-         var properties = LoadPanelProperties<TPanel, TProperties>();
 
-         bool result;
 
-         if (DynamicGridUtils.TryFindDynamicGrid(typeof(DynamicGrid<>), typeof(TProperties), out var gridType))
 
-         {
 
-             var grid = (Activator.CreateInstance(gridType) as DynamicGrid<TProperties>)!;
 
-             result = grid.EditItems(new TProperties[] { properties });
 
-         }
 
-         else
 
-         {
 
-             var grid = new DynamicItemsListGrid<TProperties>();
 
-             result = grid.EditItems(new TProperties[] { properties });
 
-         }
 
-         if (result)
 
-         {
 
-             SavePanelProperties<TPanel, TProperties>(properties);
 
-         }
 
-     }
 
-     public static void ConfigurePanel(IBasePanel panel)
 
-     {
 
-         var propertiesInterface = panel.GetType().GetInterfaceDefinition(typeof(IPropertiesPanel<>))!;
 
-         var propertiesType = propertiesInterface.GenericTypeArguments[0];
 
-         var basemethod = typeof(PanelUtils)
 
-             .GetMethod(nameof(EditPanelProperties), BindingFlags.Public | BindingFlags.Static);
 
-         if (basemethod == null)
 
-             return;
 
-         var method = basemethod?.MakeGenericMethod(panel.GetType(), propertiesType);
 
-         if (method != null)
 
-             method.Invoke(null, Array.Empty<object?>());
 
-     }
 
-     #endregion
 
-     public static T LoadPanel<T>() where T : class, IBasePanel, new()
 
-     {
 
-         var panel = new T();
 
-         InitializePanelProperties(panel);
 
-         panel.IsReady = false;
 
-         panel.Setup();
 
-         panel.IsReady = true;
 
-         return panel;
 
-     }
 
-     public static void UnloadPanel(IBasePanel panel, CancelEventArgs? cancel)
 
-     {
 
-         try
 
-         {
 
-             if(panel is ISubPanelHost host)
 
-             {
 
-                 host.ShutdownSubPanels(cancel);
 
-             }
 
-             panel.Shutdown(cancel);
 
-             if (cancel?.Cancel == true)
 
-             {
 
-                 return;
 
-             }
 
-         }
 
-         catch (Exception e)
 
-         {
 
-             Logger.Send(LogType.Error, ClientFactory.UserID, string.Format("Error in UnloadPanel(): {0}\n{1}", e.Message, e.StackTrace));
 
-         }
 
-     }
 
- }
 
- public interface IPanelHost
 
- {
 
-     void CreatePanelAction(PanelAction action);
 
-     void CreateReport(PanelAction action);
 
-     void CreateSetupAction(PanelAction action);
 
-     void CreateSetupSeparator();
 
- }
 
- public static class IPanelHostExtensions
 
- {
 
-     public static void CreateSetupAction(this IPanelHost host, string caption, Bitmap? image, Action<PanelAction> onExecute, ContextMenu? menu = null)
 
-     {
 
-         host.CreateSetupAction(new PanelAction(caption, image, onExecute) { Menu = menu });
 
-     }
 
-     public static void CreateSetupActionIf(this IPanelHost host, string caption, Bitmap? image, Action<PanelAction> onExecute, bool canView, ContextMenu? menu = null)
 
-     {
 
-         if (canView)
 
-         {
 
-             host.CreateSetupAction(new PanelAction(caption, image, onExecute) { Menu = menu });
 
-         }
 
-     }
 
-     public static void CreateSetupActionIf<TSecurity>(this IPanelHost host, string caption, Bitmap? image, Action<PanelAction> onExecute, ContextMenu? menu = null)
 
-         where TSecurity : ISecurityDescriptor, new()
 
-     {
 
-         host.CreateSetupActionIf(caption, image, onExecute, Security.IsAllowed<TSecurity>(), menu);
 
-     }
 
-     public static void CreateSetupActionIfCanView<T>(this IPanelHost host, string caption, Bitmap? image, Action<PanelAction> onExecute, ContextMenu? menu = null)
 
-         where T : Entity, new()
 
-     {
 
-         host.CreateSetupActionIf(caption, image, onExecute, Security.CanView<T>(), menu);
 
-     }
 
- }
 
- /// <summary>
 
- /// Implement this interface to cause a class to act as a host of <see cref="ISubPanel"/>. Then, you can use the extension functions
 
- /// <see cref="ISubPanelHostExtensions.ShutdownSubPanels(ISubPanelHost, CancelEventArgs?)"/> and
 
- /// <see cref="ISubPanelHostExtensions.AddSubPanel(ISubPanelHost, ISubPanel)"/> to interact with it.
 
- /// </summary>
 
- /// <remarks>
 
- /// If you mark an <see cref="IPanel{T}"/> as an <see cref="ISubPanelHost"/>, then the shutdown method is called automatically by <see cref="IPanelHost"/>.
 
- /// </remarks>
 
- public interface ISubPanelHost
 
- {
 
-     List<ISubPanel> SubPanels { get; }
 
-     static ISubPanelHost Global = new GlobalSubPanelHost();
 
-     private class GlobalSubPanelHost : ISubPanelHost
 
-     {
 
-         public List<ISubPanel> SubPanels { get; set; } = new();
 
-     }
 
- }
 
- public static class ISubPanelHostExtensions
 
- {
 
-     public static void ShutdownSubPanels(this ISubPanelHost host, CancelEventArgs? cancel)
 
-     {
 
-         ISubPanel[] panels;
 
-         lock (host.SubPanels)
 
-         {
 
-             panels = host.SubPanels.ToArray();
 
-             host.SubPanels.Clear();
 
-             var isCancelled = false;
 
-             foreach(var panel in panels)
 
-             {
 
-                 if (isCancelled)
 
-                 {
 
-                     host.SubPanels.Add(panel);
 
-                 }
 
-                 else
 
-                 {
 
-                     panel.Shutdown(cancel);
 
-                     if (cancel?.Cancel == true)
 
-                     {
 
-                         isCancelled = true;
 
-                         host.SubPanels.Add(panel);
 
-                     }
 
-                 }
 
-             }
 
-         }
 
-     }
 
-     public static void AddSubPanel(this ISubPanelHost host, ISubPanel panel)
 
-     {
 
-         host.SubPanels.Add(panel);
 
-         panel.SubPanelClosed += p =>
 
-         {
 
-             lock (host.SubPanels)
 
-             {
 
-                 host.SubPanels.Remove(p);
 
-             }
 
-         };
 
-     }
 
- }
 
- /// <summary>
 
- /// An <see cref="ISubPanel"/> is a non-modal window, which is tied to a parent 
 
- /// </summary>
 
- public interface ISubPanel
 
- {
 
-     public delegate void ClosedEvent(ISubPanel panel);
 
-     /// <summary>
 
-     /// Event to be called when a sub-panel closes itself; in this case, <see cref="Shutdown(CancelEventArgs?)"/> will not be called. This allows
 
-     /// the host to get rid of the sub-panel, instead of keeping it forever.
 
-     /// </summary>
 
-     /// <remarks>
 
-     /// You may call this after <see cref="Shutdown(CancelEventArgs?)"/> has been called.
 
-     /// </remarks>
 
-     public event ClosedEvent? SubPanelClosed;
 
-     /// <summary>
 
-     /// Shutdown the panel.
 
-     /// </summary>
 
-     /// <param name="cancel">If the operation can be cancelled, this is not <see langword="null"/></param>
 
-     void Shutdown(CancelEventArgs? cancel);
 
- }
 
 
  |