diff --git a/Flow.Launcher.Core/Resource/Internationalization.cs b/Flow.Launcher.Core/Resource/Internationalization.cs index 64b949cbb..78e8c5cbf 100644 --- a/Flow.Launcher.Core/Resource/Internationalization.cs +++ b/Flow.Launcher.Core/Resource/Internationalization.cs @@ -9,6 +9,7 @@ using Flow.Launcher.Infrastructure; using Flow.Launcher.Infrastructure.Logger; using Flow.Launcher.Infrastructure.UserSettings; using Flow.Launcher.Plugin; +using System.Globalization; namespace Flow.Launcher.Core.Resource { @@ -96,7 +97,8 @@ namespace Flow.Launcher.Core.Resource } UpdatePluginMetadataTranslations(); Settings.Language = language.LanguageCode; - + CultureInfo.CurrentCulture = new CultureInfo(language.LanguageCode); + CultureInfo.CurrentUICulture = CultureInfo.CurrentCulture; } public bool PromptShouldUsePinyin(string languageCodeToSet) diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs index 4648aef63..6561419a1 100644 --- a/Flow.Launcher.Core/Resource/Theme.cs +++ b/Flow.Launcher.Core/Resource/Theme.cs @@ -189,22 +189,11 @@ namespace Flow.Launcher.Core.Resource new[] { resultItemStyle, resultSubItemStyle, resultItemSelectedStyle, resultSubItemSelectedStyle, resultHotkeyItemStyle, resultHotkeyItemSelectedStyle }, o => Array.ForEach(setters, p => o.Setters.Add(p))); } - + /* Ignore Theme Window Width and use setting */ var windowStyle = dict["WindowStyle"] as Style; - - var width = windowStyle?.Setters.OfType().Where(x => x.Property.Name == "Width") - .Select(x => x.Value).FirstOrDefault(); - - if (width == null) - { - windowStyle = dict["BaseWindowStyle"] as Style; - - width = windowStyle?.Setters.OfType().Where(x => x.Property.Name == "Width") - .Select(x => x.Value).FirstOrDefault(); - } - + var width = Settings.WindowSize; + windowStyle.Setters.Add(new Setter(Window.WidthProperty, width)); mainWindowWidth = (double)width; - return dict; } @@ -375,8 +364,6 @@ namespace Flow.Launcher.Core.Resource { var windowHelper = new WindowInteropHelper(w); - // this determines the width of the main query window - w.Width = mainWindowWidth; windowHelper.EnsureHandle(); var accent = new AccentPolicy { AccentState = state }; diff --git a/Flow.Launcher.Infrastructure/Constant.cs b/Flow.Launcher.Infrastructure/Constant.cs index a5b89c300..564e03638 100644 --- a/Flow.Launcher.Infrastructure/Constant.cs +++ b/Flow.Launcher.Infrastructure/Constant.cs @@ -33,7 +33,7 @@ namespace Flow.Launcher.Infrastructure public static readonly string QueryTextBoxIconImagePath = $"{ProgramDirectory}\\Images\\mainsearch.svg"; - public const string DefaultTheme = "Darker"; + public const string DefaultTheme = "Win11Light"; public const string Themes = "Themes"; diff --git a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj index ef76fd617..e01bc1efd 100644 --- a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj +++ b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj @@ -50,10 +50,15 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + diff --git a/Flow.Launcher.Infrastructure/UserSettings/CustomExplorerViewModel.cs b/Flow.Launcher.Infrastructure/UserSettings/CustomExplorerViewModel.cs new file mode 100644 index 000000000..7806debe1 --- /dev/null +++ b/Flow.Launcher.Infrastructure/UserSettings/CustomExplorerViewModel.cs @@ -0,0 +1,30 @@ +using Flow.Launcher.Plugin; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Flow.Launcher.ViewModel +{ + public class CustomExplorerViewModel : BaseModel + { + public string Name { get; set; } + public string Path { get; set; } + public string FileArgument { get; set; } = "\"%d\""; + public string DirectoryArgument { get; set; } = "\"%d\""; + public bool Editable { get; init; } = true; + + public CustomExplorerViewModel Copy() + { + return new CustomExplorerViewModel + { + Name = Name, + Path = Path, + FileArgument = FileArgument, + DirectoryArgument = DirectoryArgument, + Editable = Editable + }; + } + } +} diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index 102446158..34e86a3ed 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -1,22 +1,27 @@ using System; +using System.Collections.Generic; using System.Collections.ObjectModel; using System.Drawing; using System.Text.Json.Serialization; using Flow.Launcher.Plugin; using Flow.Launcher.Plugin.SharedModels; +using Flow.Launcher; +using Flow.Launcher.ViewModel; namespace Flow.Launcher.Infrastructure.UserSettings { public class Settings : BaseModel { private string language = "en"; - public string Hotkey { get; set; } = $"{KeyConstant.Alt} + {KeyConstant.Space}"; public string OpenResultModifiers { get; set; } = KeyConstant.Alt; public bool ShowOpenResultHotkey { get; set; } = true; + public double WindowSize { get; set; } = 580; + public string Language { - get => language; set + get => language; + set { language = value; OnPropertyChanged(); @@ -34,6 +39,49 @@ namespace Flow.Launcher.Infrastructure.UserSettings public string ResultFontStretch { get; set; } public bool UseGlyphIcons { get; set; } = true; + public int CustomExplorerIndex { get; set; } = 0; + + [JsonIgnore] + public CustomExplorerViewModel CustomExplorer + { + get => CustomExplorerList[CustomExplorerIndex < CustomExplorerList.Count ? CustomExplorerIndex : 0]; + set => CustomExplorerList[CustomExplorerIndex] = value; + } + + public List CustomExplorerList { get; set; } = new() + { + new() + { + Name = "Explorer", + Path = "explorer", + DirectoryArgument = "\"%d\"", + FileArgument = "/select, \"%f\"", + Editable = false + }, + new() + { + Name = "Total Commander", + Path = @"C:\Program Files\totalcmd\TOTALCMD64.exe", + DirectoryArgument = "/O /A /S /T \"%d\"", + FileArgument = "/O /A /S /T \"%f\"" + }, + new() + { + Name = "Directory Opus", + Path = @"C:\Program Files\GPSoftware\Directory Opus\dopusrt.exe", + DirectoryArgument = "/cmd Go \"%d\" NEW", + FileArgument = "/cmd Go \"%f\" NEW" + + }, + new() + { + Name = "Files", + Path = "Files", + DirectoryArgument = "-select \"%d\"", + FileArgument = "-select \"%f\"" + } + }; + /// /// when false Alphabet static service will always return empty results @@ -52,7 +100,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings try { var precisionScore = (SearchPrecisionScore)Enum - .Parse(typeof(SearchPrecisionScore), value); + .Parse(typeof(SearchPrecisionScore), value); QuerySearchPrecision = precisionScore; StringMatcher.Instance.UserSettingSearchPrecision = precisionScore; diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs index 974eafa96..3abdaf01f 100644 --- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs +++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs @@ -190,5 +190,12 @@ namespace Flow.Launcher.Plugin /// Type for Serialization /// void SaveSettingJsonStorage() where T : new(); + + /// + /// Open directory in an explorer configured by user via Flow's Settings. The default is Windows Explorer + /// + /// Directory Path to open + /// Extra FileName Info + public void OpenDirectory(string DirectoryPath, string FileName = null); } } diff --git a/Flow.Launcher/ActionKeywords.xaml b/Flow.Launcher/ActionKeywords.xaml index 9d032efd9..32892768d 100644 --- a/Flow.Launcher/ActionKeywords.xaml +++ b/Flow.Launcher/ActionKeywords.xaml @@ -1,13 +1,54 @@ + Height="365" Width="450" Background="#F3F3F3" BorderBrush="#cecece"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Flow.Launcher/App.xaml b/Flow.Launcher/App.xaml index 13d88e1c6..c5214d7ab 100644 --- a/Flow.Launcher/App.xaml +++ b/Flow.Launcher/App.xaml @@ -6,231 +6,11 @@ Startup="OnStartupAsync"> - - - - - - - - - + + diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml b/Flow.Launcher/CustomQueryHotkeySetting.xaml index a97f90733..23bd89906 100644 --- a/Flow.Launcher/CustomQueryHotkeySetting.xaml +++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml @@ -5,7 +5,8 @@ Icon="Images\app.png" ResizeMode="NoResize" WindowStartupLocation="CenterScreen" - Title="{DynamicResource customeQueryHotkeyTitle}" Height="200" Width="674.766"> + MouseDown="window_MouseDown" + Title="{DynamicResource customeQueryHotkeyTitle}" Height="345" Width="500" Background="#F3F3F3" BorderBrush="#cecece"> @@ -15,29 +16,42 @@ - - + - - - - - - + + + + + + + + + - - - - diff --git a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs index b18bbcfad..0109474e1 100644 --- a/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs +++ b/Flow.Launcher/CustomQueryHotkeySetting.xaml.cs @@ -7,6 +7,7 @@ using System.Collections.ObjectModel; using System.Linq; using System.Windows; using System.Windows.Input; +using System.Windows.Controls; namespace Flow.Launcher { @@ -99,5 +100,15 @@ namespace Flow.Launcher { Close(); } + + private void window_MouseDown(object sender, MouseButtonEventArgs e) /* for close hotkey popup */ + { + TextBox textBox = Keyboard.FocusedElement as TextBox; + if (textBox != null) + { + TraversalRequest tRequest = new TraversalRequest(FocusNavigationDirection.Next); + textBox.MoveFocus(tRequest); + } + } } } diff --git a/Flow.Launcher/HotkeyControl.xaml b/Flow.Launcher/HotkeyControl.xaml index ab786fd56..285a282ef 100644 --- a/Flow.Launcher/HotkeyControl.xaml +++ b/Flow.Launcher/HotkeyControl.xaml @@ -9,11 +9,18 @@ d:DesignHeight="300" d:DesignWidth="300"> - - + - - + + + + press key + + + + + + \ No newline at end of file diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 051891a2b..5ca6bdbfd 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -1,7 +1,8 @@ - - + + Failed to register hotkey: {0} Could not start {0} Invalid Flow Launcher plugin file format @@ -15,7 +16,7 @@ Exit Close - + Flow Launcher Settings General Portable Mode @@ -33,6 +34,8 @@ Maximum results shown Ignore hotkeys in fullscreen mode Disable Flow Launcher activation when a full screen application is active (Recommended for games). + Default File Manager + Select the file manager to use when opening the folder. Python Directory Auto Update Select @@ -44,11 +47,12 @@ Allows using Pinyin to search. Pinyin is the standard system of romanized spelling for translating Chinese Shadow effect is not allowed while current theme has blur effect enabled - + Plugins Find more plugins On Off + Action keyword Setting Action keyword Current action keyword: New action keyword: @@ -61,14 +65,15 @@ Query time: - + Plugin Store Refresh Install - + Theme - Browse for more themes + Theme Gallery + How to create a theme Hi There Query Box Font Result Item Font @@ -79,7 +84,7 @@ Theme Folder Open Theme Folder - + Hotkey Flow Launcher Hotkey Enter shortcut to show/hide Flow Launcher. @@ -96,10 +101,11 @@ Are you sure you want to delete {0} plugin hotkey? Query window shadow effect Shadow effect has a substantial usage of GPU. Not recommended if your computer performance is limited. + Window Width Size Use Segoe Fluent Icons Use Segoe Fluent Icons for query results where supported - + HTTP Proxy Enable HTTP Proxy HTTP Server @@ -115,7 +121,7 @@ Proxy configured correctly Proxy connection failed - + About Website Version @@ -124,18 +130,28 @@ New version {0} is available, would you like to restart Flow Launcher to use the update? Check updates failed, please check your connection and proxy settings to api.github.com. - Download updates failed, please check your connection and proxy settings to github-cloud.s3.amazonaws.com, + Download updates failed, please check your connection and proxy settings to github-cloud.s3.amazonaws.com, or go to https://github.com/Flow-Launcher/Flow.Launcher/releases to download updates manually. Release Notes Usage Tips: - + + Select File Manager + Please specify the file location of the file manager you using and add arguments if necessary. The default arguments is "%d", and a path is entered at that location. For example, If a command is required such as "totalcmd.exe /A c:\windows", argument is /A "%d". + "%f" is an argument that represent the file path. It is used to emphasize the file/folder name when opening a specific file location in 3rd party file manager. This argument is only available in the "Arg for File" item. If the file manager does not have that function, you can use "%d". + File Manager + Profile Name + File Manager Path + Arg For Folder + Arg For File + + Change Priority Greater the number, the higher the result will be ranked. Try setting it as 5. If you want the results to be lower than any other plugin's, provide a negative number Please provide an valid integer for Priority! - + Old Action Keyword New Action Keyword Cancel @@ -145,19 +161,20 @@ This new Action Keyword is already assigned to another plugin, please choose a different one Success Completed successfully - Use * if you don't want to specify an action keyword + Enter the action keyword you need to start the plug-in. Use * if you don't want to specify an action keyword. In the case, The plug-in works without keywords. - - Custom Plugin Hotkey + + Custom Query Hotkey + Press the custom hotkey to automatically insert the specified query. Preview Hotkey is unavailable, please select a new hotkey Invalid plugin hotkey Update - + Hotkey Unavailable - + Version Time Please tell us how application crashed so we can fix it @@ -173,16 +190,18 @@ Failed to send report Flow Launcher got an error - + Please wait... - + Checking for new update You already have the latest Flow Launcher version Update found Updating... - Flow Launcher was not able to move your user profile data to the new update version. - Please manually move your profile data folder from {0} to {1} + + Flow Launcher was not able to move your user profile data to the new update version. + Please manually move your profile data folder from {0} to {1} + New Update New Flow Launcher release {0} is now available An error occurred while trying to install software updates diff --git a/Flow.Launcher/Languages/sk.xaml b/Flow.Launcher/Languages/sk.xaml index 70a5d3b7c..4014d215f 100644 --- a/Flow.Launcher/Languages/sk.xaml +++ b/Flow.Launcher/Languages/sk.xaml @@ -13,51 +13,64 @@ Nastavenia O aplikácii Ukončiť + Zavrieť Nastavenia Flow Launchera Všeobecné Prenosný režim + Uloží všetky nastavenia a používateľské údaje do jedného centrálneho priečinka (Užitočné pri vyberateľných diskoch a cloudových službách). Spustiť Flow Launcher po štarte systému Schovať Flow Launcher po strate fokusu Nezobrazovať upozornenia na novú verziu Zapamätať si posledné umiestnenie Jazyk Posledné vyhľadávanie + Zobrazí/skryje predchádzajúce výsledky pri opätovnej aktivácii Flow Launchera. Ponechať Označiť Vymazať Max. výsledkov Ignorovať klávesové skratky v režime na celú obrazovku + Zakázať aktiváciu Flow Launchera, keď je aktívna aplikácia na celú obrazovku (odporúčané pre hry). Priečinok s Pythonom Automatická aktualizácia Vybrať Schovať Flow Launcher po spustení Schovať ikonu z oblasti oznámení Presnosť vyhľadávania + Mení minimálne skóre zhody potrebné na zobrazenie výsledkov. Použiť Pinyin Umožňuje vyhľadávanie pomocou Pinyin. Pinyin je štandardný systém romanizovaného pravopisu pre transliteráciu čínštiny Efekt tieňa nie je povolený, kým má aktuálny motív povolený efekt rozostrenia - + - Plugin + Pluginy Nájsť ďalšie pluginy - Povolené - Zakázané + Zap. + Vyp. + Nastavenie kľúčového slova akcie Skratka akcie Aktuálna akcia skratky: Nová akcia skratky: Aktuálna priorita: Nová priorita: - Priorita: + Priorita Priečinok s pluginmi - Autor + Autor: Príprava: Čas dopytu: + + + + Repozitár pluginov + Obnoviť + Inštalovať Motív - Prehliadať viac motívov + Galéria motívov + Ako vytvoriť motív Ahojte Písmo vyhľadávacieho poľa Písmo výsledkov @@ -65,12 +78,17 @@ Nepriehľadnosť Motív {0} neexistuje, návrat na predvolený motív Nepodarilo sa nečítať motív {0}, návrat na predvolený motív + Priečinok s motívmi + Otvoriť priečinok s motívmi Klávesové skratky Klávesová skratka pre Flow Launcher - Modifikáčné klávesy na otvorenie výsledkov + Zadajte skratku na zobrazenie/skrytie Flow Launchera. + Otvoriť výsledok modifikačným klávesom + Vyberte modifikačný kláves na otvorenie výsledku pomocou klávesnice. Zobraziť klávesovú skratku + Zobrazí klávesovú skratku spolu s výsledkami. Vlastná klávesová skratka na vyhľadávanie Dopyt Odstrániť @@ -88,7 +106,7 @@ Povoliť HTTP Proxy HTTP Server Port - Použív. meno + Používateľské meno Heslo Test Proxy Uložiť @@ -115,6 +133,7 @@ Tipy na používanie: + Zmena priority Vyššie číslo znamená, že výsledok bude vyššie. Skúste nastaviť napr. 5. Ak chcete, aby boli výsledky nižšie ako ktorékoľvek iné doplnky, zadajte záporné číslo Prosím, zadajte platné číslo pre prioritu! @@ -128,10 +147,11 @@ Nová skratka pre akciu bola priradená pre iný plugin, prosím, zvoľte inú skratku Úspešné Úspešne dokončené - Použite * ak nechcete určiť skratku pre akciu + Zadajte skratku akcie, ktorá je potrebná na spustenie pluginu. Ak nechcete zadať skratku akcie, použite *. V tom prípade plugin funguje bez kľúčových slov. - Vlastná klávesová skratka pre plugin + Klávesová skratka pre vlastné vyhľadávanie + Stlačením klávesovej skratky sa automaticky vloží zadaný výraz. Náhľad Klávesová skratka je nedostupná, prosím, zadajte novú Neplatná klávesová skratka pluginu @@ -160,8 +180,8 @@ Čakajte, prosím… - Kontrolujú sa akutalizácie - Už máte najnovšiu verizu Flow Launchera + Kontrolujú sa aktualizácie + Už máte najnovšiu verziu Flow Launchera Bola nájdená aktualizácia Aktualizuje sa… Flow Launcher nedokázal presunúť používateľské údaje do aktualizovanej verzie. diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml index b517faf19..daea406db 100644 --- a/Flow.Launcher/MainWindow.xaml +++ b/Flow.Launcher/MainWindow.xaml @@ -26,6 +26,8 @@ LocationChanged="OnLocationChanged" Deactivated="OnDeactivated" PreviewKeyDown="OnKeyDown" + MinWidth="{Binding MainWindowWidth, Mode=OneWay}" + MaxWidth="{Binding MainWindowWidth, Mode=OneWay}" Visibility="{Binding MainWindowVisibility, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" d:DataContext="{d:DesignInstance vm:MainViewModel}"> @@ -102,7 +104,25 @@ - + + + + + + diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs index 057c3f07d..16e4be8a0 100644 --- a/Flow.Launcher/MainWindow.xaml.cs +++ b/Flow.Launcher/MainWindow.xaml.cs @@ -11,6 +11,7 @@ using Flow.Launcher.Core.Resource; using Flow.Launcher.Helper; using Flow.Launcher.Infrastructure.UserSettings; using Flow.Launcher.ViewModel; +using Microsoft.AspNetCore.Authorization; using Application = System.Windows.Application; using Screen = System.Windows.Forms.Screen; using ContextMenuStrip = System.Windows.Forms.ContextMenuStrip; @@ -19,6 +20,7 @@ using DragEventArgs = System.Windows.DragEventArgs; using KeyEventArgs = System.Windows.Input.KeyEventArgs; using MessageBox = System.Windows.MessageBox; using NotifyIcon = System.Windows.Forms.NotifyIcon; +using System.Windows.Interop; namespace Flow.Launcher { @@ -30,6 +32,7 @@ namespace Flow.Launcher private bool isProgressBarStoryboardPaused; private Settings _settings; private NotifyIcon _notifyIcon; + private ContextMenu contextMenu; private MainViewModel _viewModel; #endregion @@ -53,7 +56,7 @@ namespace Flow.Launcher _viewModel.Save(); e.Cancel = true; await PluginManager.DisposePluginsAsync(); - Application.Current.Shutdown(); + Environment.Exit(0); } private void OnInitialized(object sender, EventArgs e) @@ -159,14 +162,10 @@ namespace Flow.Launcher private void UpdateNotifyIconText() { - var menu = _notifyIcon.ContextMenuStrip; - var open = menu.Items[0]; - var setting = menu.Items[1]; - var exit = menu.Items[2]; - - open.Text = InternationalizationManager.Instance.GetTranslation("iconTrayOpen"); - setting.Text = InternationalizationManager.Instance.GetTranslation("iconTraySettings"); - exit.Text = InternationalizationManager.Instance.GetTranslation("iconTrayExit"); + var menu = contextMenu; + ((MenuItem)menu.Items[1]).Header = InternationalizationManager.Instance.GetTranslation("iconTrayOpen"); + ((MenuItem)menu.Items[2]).Header = InternationalizationManager.Instance.GetTranslation("iconTraySettings"); + ((MenuItem)menu.Items[3]).Header = InternationalizationManager.Instance.GetTranslation("iconTrayExit"); } private void InitializeNotifyIcon() @@ -177,30 +176,46 @@ namespace Flow.Launcher Icon = Properties.Resources.app, Visible = !_settings.HideNotifyIcon }; - var menu = new ContextMenuStrip(); - var items = menu.Items; + contextMenu = new ContextMenu(); + + var header = new MenuItem + { + Header = "Flow Launcher", + IsEnabled = false + }; + var open = new MenuItem + { + Header = InternationalizationManager.Instance.GetTranslation("iconTrayOpen") + }; + var settings = new MenuItem + { + Header = InternationalizationManager.Instance.GetTranslation("iconTraySettings") + }; + var exit = new MenuItem + { + Header = InternationalizationManager.Instance.GetTranslation("iconTrayExit") + }; - var open = items.Add(InternationalizationManager.Instance.GetTranslation("iconTrayOpen")); open.Click += (o, e) => Visibility = Visibility.Visible; - var setting = items.Add(InternationalizationManager.Instance.GetTranslation("iconTraySettings")); - setting.Click += (o, e) => App.API.OpenSettingDialog(); - var exit = items.Add(InternationalizationManager.Instance.GetTranslation("iconTrayExit")); + settings.Click += (o, e) => App.API.OpenSettingDialog(); exit.Click += (o, e) => Close(); + contextMenu.Items.Add(header); + contextMenu.Items.Add(open); + contextMenu.Items.Add(settings); + contextMenu.Items.Add(exit); - _notifyIcon.ContextMenuStrip = menu; + _notifyIcon.ContextMenuStrip = new ContextMenuStrip(); // it need for close the context menu. if not, context menu can't close. _notifyIcon.MouseClick += (o, e) => { - if (e.Button == MouseButtons.Left) + switch (e.Button) { - if (menu.Visible) - { - menu.Close(); - } - else - { - var p = System.Windows.Forms.Cursor.Position; - menu.Show(p); - } + case MouseButtons.Left: + _viewModel.ToggleFlowLauncher(); + break; + + case MouseButtons.Right: + contextMenu.IsOpen = true; + break; } }; } diff --git a/Flow.Launcher/PriorityChangeWindow.xaml b/Flow.Launcher/PriorityChangeWindow.xaml index 60a289e61..bbe601010 100644 --- a/Flow.Launcher/PriorityChangeWindow.xaml +++ b/Flow.Launcher/PriorityChangeWindow.xaml @@ -1,57 +1,88 @@ - - + + - - - + - - - - - -  - - + + + + + + + + + - - - - - - - - - - - - - - + + + + + + - - - - - diff --git a/Flow.Launcher/PriorityChangeWindow.xaml.cs b/Flow.Launcher/PriorityChangeWindow.xaml.cs index 0adb1f080..fe846e78b 100644 --- a/Flow.Launcher/PriorityChangeWindow.xaml.cs +++ b/Flow.Launcher/PriorityChangeWindow.xaml.cs @@ -26,7 +26,6 @@ namespace Flow.Launcher private Settings settings; private readonly Internationalization translater = InternationalizationManager.Instance; private readonly PluginViewModel pluginViewModel; - public PriorityChangeWindow(string pluginId, Settings settings, PluginViewModel pluginViewModel) { InitializeComponent(); @@ -62,8 +61,17 @@ namespace Flow.Launcher private void PriorityChangeWindow_Loaded(object sender, RoutedEventArgs e) { - OldPriority.Text = pluginViewModel.Priority.ToString(); + tbAction.Text = pluginViewModel.Priority.ToString(); tbAction.Focus(); } + private void window_MouseDown(object sender, MouseButtonEventArgs e) /* for close hotkey popup */ + { + TextBox textBox = Keyboard.FocusedElement as TextBox; + if (textBox != null) + { + TraversalRequest tRequest = new TraversalRequest(FocusNavigationDirection.Next); + textBox.MoveFocus(tRequest); + } + } } } \ No newline at end of file diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs index 71f6f1be4..e90a53fc3 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -22,6 +22,8 @@ using System.Runtime.CompilerServices; using Flow.Launcher.Infrastructure.Logger; using Flow.Launcher.Infrastructure.Storage; using System.Collections.Concurrent; +using Flow.Launcher.Plugin.SharedCommands; +using System.Diagnostics; namespace Flow.Launcher { @@ -158,7 +160,7 @@ namespace Flow.Launcher if (!_pluginJsonStorages.ContainsKey(type)) _pluginJsonStorages[type] = new PluginJsonStorage(); - return ((PluginJsonStorage) _pluginJsonStorages[type]).Load(); + return ((PluginJsonStorage)_pluginJsonStorages[type]).Load(); } public void SaveSettingJsonStorage() where T : new() @@ -167,7 +169,7 @@ namespace Flow.Launcher if (!_pluginJsonStorages.ContainsKey(type)) _pluginJsonStorages[type] = new PluginJsonStorage(); - ((PluginJsonStorage) _pluginJsonStorages[type]).Save(); + ((PluginJsonStorage)_pluginJsonStorages[type]).Save(); } public void SaveJsonStorage(T settings) where T : new() @@ -175,7 +177,22 @@ namespace Flow.Launcher var type = typeof(T); _pluginJsonStorages[type] = new PluginJsonStorage(settings); - ((PluginJsonStorage) _pluginJsonStorages[type]).Save(); + ((PluginJsonStorage)_pluginJsonStorages[type]).Save(); + } + + public void OpenDirectory(string DirectoryPath, string FileName = null) + { + using Process explorer = new Process(); + var explorerInfo = _settingsVM.Settings.CustomExplorer; + explorer.StartInfo = new ProcessStartInfo + { + FileName = explorerInfo.Path, + Arguments = FileName is null ? + explorerInfo.DirectoryArgument.Replace("%d", DirectoryPath) : + explorerInfo.FileArgument.Replace("%d", DirectoryPath).Replace("%f", + Path.IsPathRooted(FileName) ? FileName : Path.Combine(DirectoryPath, FileName)) + }; + explorer.Start(); } public event FlowLauncherGlobalKeyboardEventHandler GlobalKeyboardEvent; @@ -188,7 +205,7 @@ namespace Flow.Launcher { if (GlobalKeyboardEvent != null) { - return GlobalKeyboardEvent((int) keyevent, vkcode, state); + return GlobalKeyboardEvent((int)keyevent, vkcode, state); } return true; diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml new file mode 100644 index 000000000..877a97645 --- /dev/null +++ b/Flow.Launcher/Resources/CustomControlTemplate.xaml @@ -0,0 +1,2569 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Flow.Launcher/SelectFileManagerWindow.xaml.cs b/Flow.Launcher/SelectFileManagerWindow.xaml.cs new file mode 100644 index 000000000..4f6fb3439 --- /dev/null +++ b/Flow.Launcher/SelectFileManagerWindow.xaml.cs @@ -0,0 +1,88 @@ +using Flow.Launcher.Infrastructure.UserSettings; +using Flow.Launcher.ViewModel; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; + +namespace Flow.Launcher +{ + public partial class SelectFileManagerWindow : Window, INotifyPropertyChanged + { + private int selectedCustomExplorerIndex; + + public event PropertyChangedEventHandler PropertyChanged; + + public Settings Settings { get; } + + public int SelectedCustomExplorerIndex + { + get => selectedCustomExplorerIndex; set + { + selectedCustomExplorerIndex = value; + PropertyChanged?.Invoke(this, new(nameof(CustomExplorer))); + } + } + public ObservableCollection CustomExplorers { get; set; } + + public CustomExplorerViewModel CustomExplorer => CustomExplorers[SelectedCustomExplorerIndex]; + public SelectFileManagerWindow(Settings settings) + { + Settings = settings; + CustomExplorers = new ObservableCollection(Settings.CustomExplorerList.Select(x => x.Copy())); + SelectedCustomExplorerIndex = Settings.CustomExplorerIndex; + InitializeComponent(); + } + + private void btnCancel_Click(object sender, RoutedEventArgs e) + { + Close(); + } + + private void btnDone_Click(object sender, RoutedEventArgs e) + { + Settings.CustomExplorerList = CustomExplorers.ToList(); + Settings.CustomExplorerIndex = SelectedCustomExplorerIndex; + Close(); + } + + private void btnAdd_Click(object sender, RoutedEventArgs e) + { + CustomExplorers.Add(new() + { + Name = "New Profile" + }); + SelectedCustomExplorerIndex = CustomExplorers.Count - 1; + } + + private void btnDelete_Click(object sender, RoutedEventArgs e) + { + CustomExplorers.RemoveAt(SelectedCustomExplorerIndex--); + } + + private void btnBrowseFile_Click(object sender, RoutedEventArgs e) + { + Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog(); + Nullable result = dlg.ShowDialog(); + + if (result == true) + { + TextBox path = (TextBox)(((FrameworkElement)sender).Parent as FrameworkElement).FindName("PathTextBox"); + path.Text = dlg.FileName; + path.Focus(); + ((Button)sender).Focus(); + } + } + } +} diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index ac6138644..2b5fd2397 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -1,27 +1,30 @@ - + @@ -31,7 +34,7 @@ - + @@ -45,9 +48,15 @@ - + - + @@ -59,47 +68,53 @@ - - + + - - - - + - - - - - + - +