using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Reflection; using System.Text; using System.Text.RegularExpressions; using System.Windows; using System.Windows.Controls; using System.Windows.Forms; 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 PRSServer; using WindowsShortcutFactory; using Button = System.Windows.Controls.Button; using Color = System.Windows.Media.Color; using ColorConverter = System.Windows.Media.ColorConverter; using Image = System.Windows.Controls.Image; using KeyEventArgs = System.Windows.Input.KeyEventArgs; using MessageBox = System.Windows.MessageBox; //using IWshRuntimeLibrary; namespace PRSDesktop { /// /// Interaction logic for DataBaseConfiguration.xaml /// public partial class DataBaseConfiguration : ThemableWindow { private string _current = ""; private Dictionary _settings; private bool bLoading = true; private List startscreens = new(); private Dictionary _servers; public DataBaseConfiguration() { InitializeComponent(); Help.Content = new Image { Source = PRSDesktop.Resources.help.AsBitmapImage() }; AutoUpdate.Content = new Image { Source = PRSDesktop.Resources.autoupdate.AsBitmapImage() }; ExportSettings.Content = new Image { Source = PRSDesktop.Resources.download.AsBitmapImage() }; ImportSettings.Content = new Image { Source = PRSDesktop.Resources.upload.AsBitmapImage() }; var version = CoreUtils.GetVersion(); var debug = string.Equals(version, "???"); var hasLocal = HasLocalServer(); if (!debug) { StandaloneHeader.Height = new GridLength(0, GridUnitType.Pixel); StandalonePath.Height = new GridLength(0, GridUnitType.Pixel); JobPrefixHeader.Height = new GridLength(0, GridUnitType.Pixel); JobPrefixContent.Height = new GridLength(0, GridUnitType.Pixel); POPrefixHeader.Height = new GridLength(0, GridUnitType.Pixel); POPrefixContent.Height = new GridLength(0, GridUnitType.Pixel); } if (!hasLocal) { LocalHeader.Height = new GridLength(0, GridUnitType.Pixel); LocalSelectionRow.Height = new GridLength(0, GridUnitType.Pixel); } else { var servers = GetLocalServerConfiguration().LoadAll(); LocalServerName.Items.Clear(); _servers = servers .Select(x => x.Value.CreateServer(x.Key)) .Where(x => x.Type == ServerType.Database) .ToDictionary(x => x.Key, x => x); LocalServerName.ItemsSource = _servers; LocalServerName.DisplayMemberPath = "Value"; } if (!debug && !hasLocal) { NetworkHeader.Height = new GridLength(0, GridUnitType.Pixel); NetworkPath.SetValue(Grid.ColumnProperty, 0); NetworkPath.SetValue(Grid.ColumnSpanProperty, 2); } AddProfile.Background = new ImageBrush(PRSDesktop.Resources.add.AsBitmapImage()); DeleteProfile.Background = new ImageBrush(PRSDesktop.Resources.delete.AsBitmapImage()); _settings = new LocalConfiguration().LoadAll(); Setup(); bLoading = false; } //private String GetVersion() //{ // String curfile = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "version.txt"); // //MessageBox.Show(curfile); // if (System.IO.File.Exists(curfile)) // return System.IO.File.ReadAllText(curfile); // return "???"; //} private LocalConfiguration GetLocalServerConfiguration(string? section = null) { return new LocalConfiguration(CoreUtils.GetCommonAppData("PRSServer"), section ?? ""); } private bool HasLocalServer() { var configuration = GetLocalServerConfiguration(); return File.Exists(configuration.GetFileName()); } private void Setup() { Profiles.ItemsSource = new ObservableCollection(_settings.Keys); _current = _settings.Keys.FirstOrDefault(); Profiles.SelectedItem = _current; ProfileName.Text = _current; LoadSettings(); Profiles.Focus(); } private void Profiles_SelectionChanged(object sender, SelectionChangedEventArgs e) { _current = Profiles.SelectedItem as string; if (!bLoading) { bLoading = true; ProfileName.Text = _current; LoadSettings(); bLoading = false; } Focus(); } private void AddProfile_MouseUp(object sender, MouseButtonEventArgs e) { var name = "PRS"; var i = 1; while (_settings.ContainsKey(name)) name = string.Format("PRS ({0})", i++); _settings[name] = new DatabaseSettings(); var options = Profiles.ItemsSource as ObservableCollection; options.Add(name); Profiles.SelectedItem = name; } private void DeleteProfile_MouseUp(object sender, MouseButtonEventArgs e) { if (_settings.Keys.Count > 1) { if (ShortcutExists(_current)) DeleteShortcut(_current); _settings.Remove(_current); var options = Profiles.ItemsSource as ObservableCollection; var index = options.IndexOf(_current); options.RemoveAt(index); Profiles.SelectedItem = options[Math.Min(index, Profiles.Items.Count - 1)]; } } private void LoadSettings() { if (_current == null || !_settings.ContainsKey(_current)) return; bLoading = true; var settings = _settings[_current]; if (ShortcutExists(_current)) CreateLink.Content = "Delete Link"; else CreateLink.Content = "Create Link"; IsActiveCheck.IsChecked = settings.IsActive; SplashSelect.Tag = settings.Logo; try { ColorScheme.SelectedColor = (System.Windows.Media.Color)ColorConverter.ConvertFromString(settings.ColorScheme); } catch { ColorScheme.SelectedColor = Colors.CornflowerBlue; } DBLocation.Text = settings.FileName; ServerURL.Text = settings.URL; ServerPort.Text = settings.Port.ToString(); var prot = Math.Max(0, Math.Min((int)settings.Protocol, Protocol.Items.Count - 1)); Protocol.SelectedIndex = prot; var debug = string.Equals(CoreUtils.GetVersion(), "???"); var hasLocal = HasLocalServer(); var databaseType = settings.DatabaseType; if (!debug && databaseType == DatabaseType.Standalone) databaseType = DatabaseType.Networked; if (!hasLocal && databaseType == DatabaseType.Local) databaseType = DatabaseType.Local; if (hasLocal) { LocalServerName.SelectedItem = _servers.Where(x => x.Key == settings.LocalServerName).FirstOrDefault(); } StandaloneOption.IsChecked = databaseType == DatabaseType.Standalone; NetworkOption.IsChecked = databaseType == DatabaseType.Networked; LocalOption.IsChecked = databaseType == DatabaseType.Local; SelectOption(databaseType); LoginType.SelectedIndex = (int)settings.LoginType; SelectLogin(settings.LoginType); UserID.Text = settings.LoginType == Comal.Classes.LoginType.UserID ? settings.UserID : ""; Password.Password = settings.LoginType == Comal.Classes.LoginType.UserID ? settings.Password : ""; AutoLogin.IsChecked = settings.LoginType == Comal.Classes.LoginType.UserID ? settings.Autologin : false; //UpdateType.SelectedIndex = settings.UpdateType == AutoUpdateType.Url ? 0 : 1; //UpdateLocation.Text = settings.UpdateLocation; //UpdateAdmin.SelectedIndex = settings.UpdateAdmin ? 0 : 1; //UpdateChannel.SelectedIndex = settings.UpdateChannel == Comal.Classes.AutoUpdateChannel.Stable ? 0 : 1; LibraryLocation.Text = settings.LibraryLocation; GoogleAPIKey.Text = settings.GoogleAPIKey; JobPrefix.Text = settings.JobPrefix; PurchaseorderPrefix.Text = settings.PurchaseOrderPrefix; bLoading = false; } private static string MakeValidFileName(string name) { var invalidChars = Regex.Escape(new string(Path.GetInvalidFileNameChars())); var invalidRegStr = string.Format(@"([{0}]*\.+$)|([{0}]+)", invalidChars); return Regex.Replace(name, invalidRegStr, "_"); } private bool ShortcutExists(string profile) { var filename = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.Desktop), string.Format("{0}.lnk", MakeValidFileName(profile)) ); return File.Exists(filename); } private void DeleteShortcut(string profile) { var filename = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.Desktop), string.Format("{0}.lnk", MakeValidFileName(profile)) ); if (File.Exists(filename)) File.Delete(filename); } private void CreateShortcut(string profile) { string filename = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.Desktop), String.Format("{0}.lnk", MakeValidFileName(profile)) ); if (System.IO.File.Exists(filename)) return; using var shortcut = new WindowsShortcut { Path = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName, Arguments = String.Format("/profile=\"{0}\"", profile), Description = String.Format("PRS - {0}",profile) }; shortcut.Save(filename); //MessageBox.Show("Not Yet Implemented in .NET6!"); // string filename = Path.Combine( // Environment.GetFolderPath(Environment.SpecialFolder.Desktop), // String.Format("{0}.lnk", MakeValidFileName(profile)) // ); // // if (System.IO.File.Exists(filename)) // return; // // WshShell shell = new WshShell(); // // IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(filename); // shortcut.Description = String.Format("PRS - {0}",profile); // shortcut.TargetPath = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName; // shortcut.Arguments = String.Format("/profile=\"{0}\"", profile); // shortcut.Save(); } private void UnloadSettings() { if (bLoading) return; if (!_settings.ContainsKey(_current)) return; var settings = _settings[_current]; settings.IsActive = IsActiveCheck.IsChecked == true; settings.Logo = (byte[])SplashSelect.Tag; settings.ColorScheme = ColorScheme.SelectedColor.ToString(); settings.DatabaseType = StandaloneOption.IsChecked == true ? DatabaseType.Standalone : NetworkOption.IsChecked == true ? DatabaseType.Networked : LocalOption.IsChecked == true ? DatabaseType.Local : DatabaseType.Networked; settings.FileName = DBLocation.Text; settings.URL = ServerURL.Text; settings.Port = Convert.ToInt32(ServerPort.Text); settings.Protocol = (SerializerProtocol)Protocol.SelectedIndex; settings.LocalServerName = LocalServerName.SelectedItem != null ? ((KeyValuePair)LocalServerName.SelectedItem).Key : ""; settings.LoginType = (LoginType)LoginType.SelectedIndex; settings.Autologin = settings.LoginType == Comal.Classes.LoginType.UserID ? AutoLogin.IsChecked == true : false; settings.UserID = settings.LoginType == Comal.Classes.LoginType.UserID ? UserID.Text : ""; settings.Password = settings.LoginType == Comal.Classes.LoginType.UserID ? Password.Password : ""; //settings.UpdateType = UpdateType.SelectedIndex == 0 ? AutoUpdateType.Url : AutoUpdateType.File; //settings.UpdateLocation = UpdateLocation.Text; //settings.UpdateAdmin = UpdateAdmin.SelectedIndex < 1; //settings.UpdateChannel = UpdateChannel.SelectedIndex < 1 ? Comal.Classes.AutoUpdateChannel.Stable : Comal.Classes.AutoUpdateChannel.PreRelease; settings.LibraryLocation = LibraryLocation.Text; settings.Provider = DatabaseProvider.SQLite; settings.GoogleAPIKey = GoogleAPIKey.Text; settings.JobPrefix = JobPrefix.Text; settings.PurchaseOrderPrefix = PurchaseorderPrefix.Text; } private void ProfileName_TextChanged(object sender, TextChangedEventArgs e) { if (bLoading) return; bLoading = true; var defset = _settings[_current]; _settings.Remove(_current); _settings[ProfileName.Text] = defset; var options = Profiles.ItemsSource as ObservableCollection; var cur = options.IndexOf(_current); options[cur] = ProfileName.Text; if (_current != null && ShortcutExists(_current)) { DeleteShortcut(_current); CreateShortcut(ProfileName.Text); } _current = ProfileName.Text; bLoading = false; } #region DatabaseSettings private void SelectOption(DatabaseType databaseType) { DBLocation.IsEnabled = databaseType == DatabaseType.Standalone; // && (DbProvider.SelectedIndex == 1); DBButton.IsEnabled = databaseType == DatabaseType.Standalone; // && (DbProvider.SelectedIndex != 1); ColorScheme.IsEnabled = databaseType == DatabaseType.Standalone; SplashView.IsEnabled = databaseType == DatabaseType.Standalone; SplashSelect.IsEnabled = databaseType == DatabaseType.Standalone; ServerURL.IsEnabled = databaseType == DatabaseType.Networked; ServerPort.IsEnabled = databaseType == DatabaseType.Networked; Protocol.IsEnabled = databaseType == DatabaseType.Networked; LocalServerName.IsEnabled = databaseType == DatabaseType.Local; } private void DBButton_Click(object sender, RoutedEventArgs e) { using (var sfd = new SaveFileDialog()) { //var provider = (DatabaseProvider)DbProvider.SelectedIndex; //if (provider == DatabaseProvider.SQLite) //{ sfd.Filter = "SQLite Database Files (*.dbs)|*.dbs"; sfd.DefaultExt = "dbs"; //} //else //{ // ofd.Filter = "LiteDB Database Files (*.db; *.dbl)|*.db;*.dbl"; // ofd.DefaultExt = "dbl"; //} sfd.InitialDirectory = Path.GetDirectoryName(DBLocation.Text); sfd.FileName = Path.GetFileName(DBLocation.Text); sfd.CheckFileExists = false; var result = sfd.ShowDialog(); if (result == System.Windows.Forms.DialogResult.OK && !string.IsNullOrWhiteSpace(sfd.FileName)) { DBLocation.Text = sfd.FileName; UnloadSettings(); } } } private void Option_Checked(object sender, RoutedEventArgs e) { var databaseType = sender == StandaloneOption ? DatabaseType.Standalone : sender == NetworkOption ? DatabaseType.Networked : DatabaseType.Local; SelectOption(databaseType); UnloadSettings(); } private void StandaloneLabel_Click(object sender, MouseButtonEventArgs e) { StandaloneOption.IsChecked = true; } private void NetworkLabel_Click(object sender, MouseButtonEventArgs e) { NetworkOption.IsChecked = true; } private void LocalLabel_Click(object sender, MouseButtonEventArgs e) { LocalOption.IsChecked = true; } private void LocalServerName_SelectionChanged(object sender, SelectionChangedEventArgs e) { UnloadSettings(); } private void ServerPort_TextChanged(object sender, TextChangedEventArgs e) { UnloadSettings(); } private void ServerURL_TextChanged(object sender, TextChangedEventArgs e) { UnloadSettings(); } private void Protocol_SelectionChanged(object sender, SelectionChangedEventArgs e) { UnloadSettings(); } #endregion private void SelectLogin(LoginType Login) { UserID.IsEnabled = Login == Comal.Classes.LoginType.UserID; Password.IsEnabled = Login == Comal.Classes.LoginType.UserID; AutoLogin.IsEnabled = Login == Comal.Classes.LoginType.UserID; } //private void UpdateButton_Click(object sender, RoutedEventArgs e) //{ // if (UpdateType.SelectedIndex != 1) // return; // using (var ofd = new OpenFileDialog()) // { // ofd.Filter = "Executable Files (*.exe)|*.exe"; // ofd.InitialDirectory = !String.IsNullOrEmpty(UpdateLocation.Text) ? Path.GetDirectoryName(UpdateLocation.Text) : ""; // ofd.FileName = UpdateLocation.Text; // ofd.Multiselect = false; // ofd.CheckFileExists = false; // DialogResult result = ofd.ShowDialog(); // if ((result == System.Windows.Forms.DialogResult.OK) && (!string.IsNullOrWhiteSpace(ofd.FileName))) // { // UpdateLocation.Text = ofd.FileName; // UnloadSettings(); // } // } //} private void AutoDiscover_Click(object sender, RoutedEventArgs e) { Progress.Show("Looking for available Servers..."); try { var Client = new UdpClient(); Client.Client.SendTimeout = 10000; Client.Client.ReceiveTimeout = 20000; var RequestData = Encoding.ASCII.GetBytes(""); var ServerEp = new IPEndPoint(IPAddress.Any, 0); Client.EnableBroadcast = true; Client.Send(RequestData, RequestData.Length, new IPEndPoint(IPAddress.Broadcast, 8888)); Progress.SetMessage("Scanning local network..."); var ServerResponseData = Client.Receive(ref ServerEp); var ServerResponse = Encoding.ASCII.GetString(ServerResponseData); var autodiscover = Serialization.Deserialize(ServerResponse); ProfileName.Text = autodiscover.Name; IsActiveCheck.IsChecked = true; SplashSelect.Tag = autodiscover.Logo; StandaloneOption.IsChecked = false; DBLocation.Text = ""; NetworkOption.IsChecked = true; Protocol.SelectedIndex = Math.Max(0, Math.Min((int)autodiscover.Protocol, Protocol.Items.Count - 1)); ServerURL.Text = autodiscover.URL; ServerPort.Text = autodiscover.Port.ToString(); //UpdateType.SelectedIndex = autodiscover.UpdateType == AutoUpdateType.Url ? 0 : 1; //UpdateLocation.Text = autodiscover.UpdateLocation; //UpdateAdmin.SelectedIndex = autodiscover.UpdateAdmin ? 0 : 1; //UpdateChannel.SelectedIndex = autodiscover.UpdateChannel == Comal.Classes.AutoUpdateChannel.Stable ? 0 : 1; LibraryLocation.Text = autodiscover.LibraryLocation; GoogleAPIKey.Text = autodiscover.GoogleAPIKey; Client.Close(); Progress.Close(); MessageBox.Show(string.Format("Server found at {0}:{1}", autodiscover.URL, autodiscover.Port)); UnloadSettings(); } catch (Exception err) { Progress.Close(); MessageBox.Show("No Server Found!"); } } private void LoginType_SelectionChanged(object sender, SelectionChangedEventArgs e) { SelectLogin((LoginType)LoginType.SelectedIndex); UnloadSettings(); } private void LibraryButton_Click(object sender, RoutedEventArgs e) { using (var ofd = new FolderBrowserDialog()) { if (Directory.Exists(LibraryLocation.Text)) ofd.SelectedPath = LibraryLocation.Text; var result = ofd.ShowDialog(); if (result == System.Windows.Forms.DialogResult.OK && !string.IsNullOrWhiteSpace(ofd.SelectedPath)) { LibraryLocation.Text = ofd.SelectedPath; UnloadSettings(); } } } //private void UpdateType_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) //{ // UpdateButton.Visibility = UpdateType.SelectedIndex == 1 ? Visibility.Visible : Visibility.Collapsed; // UnloadSettings(); //} //private void UpdateAdmin_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) //{ // UnloadSettings(); //} //private void UpdateChannel_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) //{ // UnloadSettings(); //} private void IsActive_Checked(object sender, RoutedEventArgs e) { UnloadSettings(); } private void UserID_TextChanged(object sender, TextChangedEventArgs e) { UnloadSettings(); } private void Password_KeyUp(object sender, KeyEventArgs e) { UnloadSettings(); } private void AutoLogin_Checked(object sender, RoutedEventArgs e) { UnloadSettings(); } //private void UpdateLocation_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e) //{ // UnloadSettings(); //} private void LibraryLocation_TextChanged(object sender, TextChangedEventArgs e) { UnloadSettings(); } private void UpdateAdmin_Checked(object sender, RoutedEventArgs e) { UnloadSettings(); } private void GoogleAPIKey_TextChanged(object sender, TextChangedEventArgs e) { UnloadSettings(); } private void JobPrefix_TextChanged(object sender, TextChangedEventArgs e) { UnloadSettings(); } private void PurchaseOrderPrefix_TextChanged(object sender, TextChangedEventArgs e) { UnloadSettings(); } private void ColorScheme_OnSelectedColorChanged(object sender, RoutedPropertyChangedEventArgs e) { UnloadSettings(); } private void SplashSelect_Click(object sender, RoutedEventArgs e) { using (var ofd = new OpenFileDialog()) { ofd.Filter = "Image Files (*.bmp; *.jpg; *.jpeg; *.png)|*.bmp;*.jpg;*.jpeg;*.png"; ofd.DefaultExt = "png"; ofd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); ofd.Multiselect = false; ofd.CheckFileExists = true; var result = ofd.ShowDialog(); if (result == System.Windows.Forms.DialogResult.OK && !string.IsNullOrWhiteSpace(ofd.FileName)) { var image = System.Drawing.Image.FromFile(ofd.FileName); var size = image.Size.Adjust(450, 450); image = new Bitmap(image, size); SplashSelect.Tag = new ImageConverter().ConvertTo(image, typeof(byte[])); UnloadSettings(); } } } private void SplashView_Click(object sender, RoutedEventArgs e) { var data = SplashSelect.Tag != null ? (byte[])SplashSelect.Tag : null; if (data == null || !data.Any()) return; var type = ImageUtils.GetImageType(data); var file = Path.ChangeExtension(Path.GetTempFileName(), type.ToString()); File.WriteAllBytes(file, data); var gsProcessInfo = new ProcessStartInfo(); gsProcessInfo.Verb = "open"; gsProcessInfo.WindowStyle = ProcessWindowStyle.Normal; gsProcessInfo.FileName = file; gsProcessInfo.UseShellExecute = true; Process.Start(gsProcessInfo); } private void CreateLink_Click(object sender, RoutedEventArgs e) { var button = sender as Button; var action = button.Content as string; if (string.Equals("Delete Link", action)) { DeleteShortcut(_current); button.Content = "Create Link"; } else { CreateShortcut(_current); button.Content = "Delete Link"; } } private void OKButton_Click(object sender, RoutedEventArgs e) { // Delete All var olds = new LocalConfiguration().Sections(); foreach (var old in olds) new LocalConfiguration(old).Delete(); foreach (var key in _settings.Keys) new LocalConfiguration(key).Save(_settings[key]); DialogResult = true; Close(); } private void CancelButton_Click(object sender, RoutedEventArgs e) { DialogResult = false; Close(); } private void Export_Click(object sender, RoutedEventArgs e) { using (var sfd = new SaveFileDialog()) { sfd.Filter = "Settings Files (*.settings)|*.settings"; sfd.DefaultExt = "settings"; sfd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); var result = sfd.ShowDialog(); if (result == System.Windows.Forms.DialogResult.OK && !string.IsNullOrWhiteSpace(sfd.FileName)) { var json = Serialization.Serialize(_settings); File.WriteAllText(sfd.FileName, json); MessageBox.Show("Settings exported!"); } } } private void Import_Click(object sender, RoutedEventArgs e) { using (var ofd = new OpenFileDialog()) { ofd.Filter = "Settings Files (*.settings)|*.settings"; ofd.DefaultExt = "settings"; ofd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); ofd.Multiselect = false; ofd.CheckFileExists = true; var result = ofd.ShowDialog(); if (result == System.Windows.Forms.DialogResult.OK && !string.IsNullOrWhiteSpace(ofd.FileName)) { var json = File.ReadAllText(ofd.FileName); _settings = Serialization.Deserialize>(json); Setup(); } } } private void AutoUpdate_Click(object sender, RoutedEventArgs e) { var editable = App.AutoUpdateSettings.ToEditable(); var buttons = new DynamicEditorButtons() { new DynamicEditorButton( "", PRSDesktop.Resources.help.AsBitmapImage(), null, (o, e) => ShowHelp("Automatic_Updates")) }; var propertyEditor = new DynamicEditorForm(typeof(EditableAutoUpdateSettings), null, buttons); propertyEditor.OnDefineLookups += editor => { var values = (editor.EditorDefinition as ILookupEditor).Values(editor.ColumnName); editor.LoadLookups(values); }; propertyEditor.OnDefineEditor += PropertyEditor_OnDefineEditor; propertyEditor.Items = new BaseObject[] { editable }; if (propertyEditor.ShowDialog() == true) { App.AutoUpdateSettings.FromEditable(editable); new LocalConfiguration().Save(App.AutoUpdateSettings); } } private BaseEditor? PropertyEditor_OnDefineEditor(object item, DynamicGridColumn column) { if (!string.Equals(column.ColumnName, "Elevated")) return new NullEditor(); return null; } private void ShowHelp(string slug) { Process.Start(new ProcessStartInfo("https://prsdigital.com.au/wiki/index.php/" + slug) { UseShellExecute = true }); } private void ShowHelp_OnClick(object sender, RoutedEventArgs e) { ShowHelp("Database_Configuration"); } } }