From 2285040857425c1127fb43c4f5283a40218968d5 Mon Sep 17 00:00:00 2001 From: Yusyuriv Date: Mon, 29 Apr 2024 12:25:10 +0600 Subject: [PATCH] "General" pane in settings fully functional except for auto-updater and portable mode switches --- .../ViewModels/DropdownDataGeneric.cs | 27 ++ .../ViewModels/GeneralViewModel.cs | 255 ------------------ .../SettingsPaneGeneralViewModel.cs | 218 +++++++++++++++ .../Views/SettingsPaneGeneral.xaml | 6 + .../Views/SettingsPaneGeneral.xaml.cs | 55 +--- 5 files changed, 264 insertions(+), 297 deletions(-) create mode 100644 Flow.Launcher/SettingPages/ViewModels/DropdownDataGeneric.cs delete mode 100644 Flow.Launcher/SettingPages/ViewModels/GeneralViewModel.cs create mode 100644 Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs diff --git a/Flow.Launcher/SettingPages/ViewModels/DropdownDataGeneric.cs b/Flow.Launcher/SettingPages/ViewModels/DropdownDataGeneric.cs new file mode 100644 index 000000000..025c73f85 --- /dev/null +++ b/Flow.Launcher/SettingPages/ViewModels/DropdownDataGeneric.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using Flow.Launcher.Core.Resource; +using Flow.Launcher.Plugin; + +namespace Flow.Launcher.SettingPages.ViewModels; + +public class DropdownDataGeneric : BaseModel where TValue : Enum +{ + public string Display { get; set; } + public TValue Value { get; set; } + + public static List GetValues(string keyPrefix) where TR : DropdownDataGeneric, new() + { + var data = new List(); + var enumValues = (TValue[])Enum.GetValues(typeof(TValue)); + + foreach (var value in enumValues) + { + var key = keyPrefix + value; + var display = InternationalizationManager.Instance.GetTranslation(key); + data.Add(new TR { Display = display, Value = value }); + } + + return data; + } +} diff --git a/Flow.Launcher/SettingPages/ViewModels/GeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/GeneralViewModel.cs deleted file mode 100644 index 693d1db51..000000000 --- a/Flow.Launcher/SettingPages/ViewModels/GeneralViewModel.cs +++ /dev/null @@ -1,255 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Windows.Forms; -using CommunityToolkit.Mvvm.ComponentModel; -using CommunityToolkit.Mvvm.Input; -using Flow.Launcher.Core; -using Flow.Launcher.Core.Configuration; -using Flow.Launcher.Core.Plugin; -using Flow.Launcher.Helper; -using Flow.Launcher.Core.Resource; -using Flow.Launcher.Infrastructure.UserSettings; -using Flow.Launcher.Plugin; -using Flow.Launcher.Plugin.SharedModels; -using static Flow.Launcher.SettingPages.ViewModels.GeneralViewModel; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Windows.Forms; -using CommunityToolkit.Mvvm.ComponentModel; -using CommunityToolkit.Mvvm.Input; -using Flow.Launcher.Core; -using Flow.Launcher.Core.Configuration; -using Flow.Launcher.Core.Plugin; -using Flow.Launcher.Helper; -using Flow.Launcher.Core.Resource; -using Flow.Launcher.Infrastructure.UserSettings; -using Flow.Launcher.Plugin; -using Flow.Launcher.Plugin.SharedModels; -using Flow.Launcher.Infrastructure; -using static Flow.Launcher.ViewModel.SettingWindowViewModel; - -namespace Flow.Launcher.SettingPages.ViewModels -{ - public partial class GeneralViewModel - { - public Settings Settings { get; set; } - private readonly Updater _updater; - private readonly IPortable _portable; - - public GeneralViewModel(Settings settings) - { - Settings = settings; - } - - public class SearchWindowScreen - { - public string Display { get; set; } - public SearchWindowScreens Value { get; set; } - } - - - public bool StartFlowLauncherOnSystemStartup - { - get => Settings.StartFlowLauncherOnSystemStartup; - set - { - Settings.StartFlowLauncherOnSystemStartup = value; - - try - { - if (value) - AutoStartup.Enable(); - else - AutoStartup.Disable(); - } - catch (Exception e) - { - Notification.Show(InternationalizationManager.Instance.GetTranslation("setAutoStartFailed"), - e.Message); - } - } - } - - - private Internationalization _translater => InternationalizationManager.Instance; - public List SearchWindowScreens - { - get - { - List modes = new List(); - var enums = (SearchWindowScreens[])Enum.GetValues(typeof(SearchWindowScreens)); - foreach (var e in enums) - { - var key = $"SearchWindowScreen{e}"; - var display = _translater.GetTranslation(key); - var m = new SearchWindowScreen { Display = display, Value = e, }; - modes.Add(m); - } - - return modes; - } - - - } - - public List SearchWindowAligns - { - get - { - List modes = new List(); - var enums = (SearchWindowAligns[])Enum.GetValues(typeof(SearchWindowAligns)); - foreach (var e in enums) - { - var key = $"SearchWindowAlign{e}"; - var display = _translater.GetTranslation(key); - var m = new SearchWindowAlign { Display = display, Value = e, }; - modes.Add(m); - } - - return modes; - } - } - - public List ScreenNumbers - { - get - { - var screens = System.Windows.Forms.Screen.AllScreens; - var screenNumbers = new List(); - for (int i = 1; i <= screens.Length; i++) - { - screenNumbers.Add(i); - } - - return screenNumbers; - } - } - - // This is only required to set at startup. When portable mode enabled/disabled a restart is always required - private bool _portableMode = DataLocation.PortableDataLocationInUse(); - - public bool PortableMode - { - get => _portableMode; - set - { - if (!_portable.CanUpdatePortability()) - return; - - if (DataLocation.PortableDataLocationInUse()) - { - _portable.DisablePortableMode(); - } - else - { - _portable.EnablePortableMode(); - } - } - } - - - // todo a better name? - public class LastQueryMode : BaseModel - { - public string Display { get; set; } - public Infrastructure.UserSettings.LastQueryMode Value { get; set; } - } - - private List _lastQueryModes = new List(); - - public List LastQueryModes - { - get - { - if (_lastQueryModes.Count == 0) - { - _lastQueryModes = InitLastQueryModes(); - } - - return _lastQueryModes; - } - } - - private List InitLastQueryModes() - { - var modes = new List(); - var enums = (Infrastructure.UserSettings.LastQueryMode[])Enum.GetValues( - typeof(Infrastructure.UserSettings.LastQueryMode)); - foreach (var e in enums) - { - var key = $"LastQuery{e}"; - var display = _translater.GetTranslation(key); - var m = new LastQueryMode { Display = display, Value = e, }; - modes.Add(m); - } - - return modes; - } - - private void UpdateLastQueryModeDisplay() - { - foreach (var item in LastQueryModes) - { - item.Display = _translater.GetTranslation($"LastQuery{item.Value}"); - } - } - - public string Language - { - get - { - return Settings.Language; - } - set - { - InternationalizationManager.Instance.ChangeLanguage(value); - - if (InternationalizationManager.Instance.PromptShouldUsePinyin(value)) - ShouldUsePinyin = true; - - UpdateLastQueryModeDisplay(); - } - } - - public bool ShouldUsePinyin - { - get - { - return Settings.ShouldUsePinyin; - } - set - { - Settings.ShouldUsePinyin = value; - } - } - - public List QuerySearchPrecisionStrings - { - get - { - var precisionStrings = new List(); - - var enumList = Enum.GetValues(typeof(SearchPrecisionScore)).Cast().ToList(); - - enumList.ForEach(x => precisionStrings.Add(x.ToString())); - - return precisionStrings; - } - } - - public List OpenResultModifiersList => new List - { - KeyConstant.Alt, KeyConstant.Ctrl, $"{KeyConstant.Ctrl}+{KeyConstant.Alt}" - }; - - public List Languages => _translater.LoadAvailableLanguages(); - public IEnumerable MaxResultsRange => Enumerable.Range(2, 16); - - public string AlwaysPreviewToolTip => - string.Format(_translater.GetTranslation("AlwaysPreviewToolTip"), Settings.PreviewHotkey); - } -} diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs new file mode 100644 index 000000000..ed74cbb2d --- /dev/null +++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs @@ -0,0 +1,218 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Forms; +using CommunityToolkit.Mvvm.Input; +using Flow.Launcher.Core; +using Flow.Launcher.Core.Configuration; +using Flow.Launcher.Core.Resource; +using Flow.Launcher.Helper; +using Flow.Launcher.Infrastructure; +using Flow.Launcher.Infrastructure.UserSettings; +using Flow.Launcher.Plugin.SharedModels; + +namespace Flow.Launcher.SettingPages.ViewModels; + +// TODO: _updater, _portable +public partial class SettingsPaneGeneralViewModel +{ + private static Internationalization Translator => InternationalizationManager.Instance; + + public Settings Settings { get; set; } + private readonly Updater _updater; + private readonly IPortable _portable; + + public SettingsPaneGeneralViewModel(Settings settings) + { + Settings = settings; + } + + public class SearchWindowScreen : DropdownDataGeneric { } + public class SearchWindowAlign : DropdownDataGeneric { } + // todo a better name? + public class LastQueryMode : DropdownDataGeneric { } + + public bool StartFlowLauncherOnSystemStartup + { + get => Settings.StartFlowLauncherOnSystemStartup; + set + { + Settings.StartFlowLauncherOnSystemStartup = value; + + try + { + if (value) + AutoStartup.Enable(); + else + AutoStartup.Disable(); + } + catch (Exception e) + { + Notification.Show(InternationalizationManager.Instance.GetTranslation("setAutoStartFailed"), + e.Message); + } + } + } + + + public List SearchWindowScreens => + DropdownDataGeneric.GetValues("SearchWindowScreen"); + + public List SearchWindowAligns => + DropdownDataGeneric.GetValues("SearchWindowAlign"); + + public List ScreenNumbers + { + get + { + var screens = Screen.AllScreens; + var screenNumbers = new List(); + for (int i = 1; i <= screens.Length; i++) + { + screenNumbers.Add(i); + } + + return screenNumbers; + } + } + + // This is only required to set at startup. When portable mode enabled/disabled a restart is always required + private bool _portableMode = DataLocation.PortableDataLocationInUse(); + + public bool PortableMode + { + get => _portableMode; + set + { + if (!_portable.CanUpdatePortability()) + return; + + if (DataLocation.PortableDataLocationInUse()) + { + _portable.DisablePortableMode(); + } + else + { + _portable.EnablePortableMode(); + } + } + } + + private List _lastQueryModes = new(); + + public List LastQueryModes + { + get + { + if (_lastQueryModes.Count == 0) + { + _lastQueryModes = + DropdownDataGeneric + .GetValues("LastQuery"); + } + + return _lastQueryModes; + } + } + + private void UpdateLastQueryModeDisplay() + { + foreach (var item in LastQueryModes) + { + item.Display = Translator.GetTranslation($"LastQuery{item.Value}"); + } + } + + public string Language + { + get => Settings.Language; + set + { + InternationalizationManager.Instance.ChangeLanguage(value); + + if (InternationalizationManager.Instance.PromptShouldUsePinyin(value)) + ShouldUsePinyin = true; + + UpdateLastQueryModeDisplay(); + } + } + + public bool ShouldUsePinyin + { + get => Settings.ShouldUsePinyin; + set => Settings.ShouldUsePinyin = value; + } + + public List QuerySearchPrecisionStrings => Enum + .GetValues(typeof(SearchPrecisionScore)) + .Cast() + .Select(v => v.ToString()) + .ToList(); + + public List OpenResultModifiersList => new List + { + KeyConstant.Alt, + KeyConstant.Ctrl, + $"{KeyConstant.Ctrl}+{KeyConstant.Alt}" + }; + + public List Languages => Translator.LoadAvailableLanguages(); + public IEnumerable MaxResultsRange => Enumerable.Range(2, 16); + + public string AlwaysPreviewToolTip => + string.Format(Translator.GetTranslation("AlwaysPreviewToolTip"), Settings.PreviewHotkey); + + private string GetFileFromDialog(string title, string filter = "") + { + var dlg = new OpenFileDialog + { + InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), + Multiselect = false, + CheckFileExists = true, + CheckPathExists = true, + Title = title, + Filter = filter + }; + + return dlg.ShowDialog() switch + { + DialogResult.OK => dlg.FileName, + _ => string.Empty + }; + } + + [RelayCommand] + private void SelectPython() + { + var selectedFile = GetFileFromDialog( + Translator.GetTranslation("selectPythonExecutable"), + "Python|pythonw.exe" + ); + + if (!string.IsNullOrEmpty(selectedFile)) + Settings.PluginSettings.PythonExecutablePath = selectedFile; + } + + [RelayCommand] + private void SelectNode() + { + var selectedFile = GetFileFromDialog(Translator.GetTranslation("selectNodeExecutable"), "*.exe"); + + if (!string.IsNullOrEmpty(selectedFile)) + Settings.PluginSettings.NodeExecutablePath = selectedFile; + } + + [RelayCommand] + private void SelectFileManager() + { + var fileManagerChangeWindow = new SelectFileManagerWindow(Settings); + fileManagerChangeWindow.ShowDialog(); + } + + [RelayCommand] + private void SelectBrowser() + { + var browserWindow = new SelectBrowserWindow(Settings); + browserWindow.ShowDialog(); + } +} diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml index 64a8cbfb1..f6e38795d 100644 --- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml +++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml @@ -7,7 +7,9 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:ui="http://schemas.modernwpf.com/2019" xmlns:userSettings="clr-namespace:Flow.Launcher.Infrastructure.UserSettings;assembly=Flow.Launcher.Infrastructure" + xmlns:settingsViewModels="clr-namespace:Flow.Launcher.SettingPages.ViewModels" Title="General" + d:DataContext="{d:DesignInstance settingsViewModels:SettingsPaneGeneralViewModel}" d:DesignHeight="450" d:DesignWidth="800" mc:Ignorable="d"> @@ -292,6 +294,7 @@ Width="160" MaxWidth="250" Margin="10,0,0,0" + Command="{Binding SelectFileManagerCommand}" Content="{Binding Settings.CustomExplorer.Name}" /> @@ -303,6 +306,7 @@ Width="160" MaxWidth="250" Margin="10,0,0,0" + Command="{Binding SelectBrowserCommand}" Content="{Binding Settings.CustomBrowser.Name}" /> @@ -315,6 +319,7 @@