diff --git a/.github/update_release_pr.py b/.github/update_release_pr.py new file mode 100644 index 000000000..f90f6181d --- /dev/null +++ b/.github/update_release_pr.py @@ -0,0 +1,215 @@ +from os import getenv + +import requests + + +def get_github_prs(token: str, owner: str, repo: str, label: str = "", state: str = "all") -> list[dict]: + """ + Fetches pull requests from a GitHub repository that match a given milestone and label. + + Args: + token (str): GitHub token. + owner (str): The owner of the repository. + repo (str): The name of the repository. + label (str): The label name. + state (str): State of PR, e.g. open, closed, all + + Returns: + list: A list of dictionaries, where each dictionary represents a pull request. + Returns an empty list if no PRs are found or an error occurs. + """ + headers = { + "Authorization": f"token {token}", + "Accept": "application/vnd.github.v3+json", + } + + milestone_id = None + milestone_url = f"https://api.github.com/repos/{owner}/{repo}/milestones" + params = {"state": "open"} + + try: + response = requests.get(milestone_url, headers=headers, params=params) + response.raise_for_status() + milestones = response.json() + + if len(milestones) > 2: + print("More than two milestones found, unable to determine the milestone required.") + exit(1) + + # milestones.pop() + for ms in milestones: + if ms["title"] != "Future": + milestone_id = ms["number"] + print(f"Gathering PRs with milestone {ms['title']}...") + break + + if not milestone_id: + print(f"No suitable milestone found in repository '{owner}/{repo}'.") + exit(1) + + except requests.exceptions.RequestException as e: + print(f"Error fetching milestones: {e}") + exit(1) + + # This endpoint allows filtering by milestone and label. A PR in GH's perspective is a type of issue. + prs_url = f"https://api.github.com/repos/{owner}/{repo}/issues" + params = { + "state": state, + "milestone": milestone_id, + "labels": label, + "per_page": 100, + } + + all_prs = [] + page = 1 + while True: + try: + params["page"] = page + response = requests.get(prs_url, headers=headers, params=params) + response.raise_for_status() # Raise an exception for HTTP errors + prs = response.json() + + if not prs: + break # No more PRs to fetch + + # Check for pr key since we are using issues endpoint instead. + all_prs.extend([item for item in prs if "pull_request" in item]) + page += 1 + + except requests.exceptions.RequestException as e: + print(f"Error fetching pull requests: {e}") + exit(1) + + return all_prs + + +def get_prs(pull_request_items: list[dict], label: str = "", state: str = "all") -> list[dict]: + """ + Returns a list of pull requests after applying the label and state filters. + + Args: + pull_request_items (list[dict]): List of PR items. + label (str): The label name. + state (str): State of PR, e.g. open, closed, all + + Returns: + list: A list of dictionaries, where each dictionary represents a pull request. + Returns an empty list if no PRs are found. + """ + pr_list = [] + count = 0 + for pr in pull_request_items: + if pr["state"] == state and [item for item in pr["labels"] if item["name"] == label]: + pr_list.append(pr) + count += 1 + + print(f"Found {count} PRs with {label if label else 'no'} label and state as {state}") + + return pr_list + + +def get_pr_descriptions(pull_request_items: list[dict]) -> str: + """ + Returns the concatenated string of pr title and number in the format of + '- PR title 1 #3651 + - PR title 2 #3652 + - PR title 3 #3653 + ' + + Args: + pull_request_items (list[dict]): List of PR items. + + Returns: + str: a string of PR titles and numbers + """ + description_content = "" + for pr in pull_request_items: + description_content += f"- {pr['title']} #{pr['number']}\n" + + return description_content + + +def update_pull_request_description(token: str, owner: str, repo: str, pr_number: int, new_description: str) -> None: + """ + Updates the description (body) of a GitHub Pull Request. + + Args: + token (str): Token. + owner (str): The owner of the repository. + repo (str): The name of the repository. + pr_number (int): The number of the pull request to update. + new_description (str): The new content for the PR's description. + + Returns: + dict or None: The updated PR object (as a dictionary) if successful, + None otherwise. + """ + headers = { + "Authorization": f"token {token}", + "Accept": "application/vnd.github.v3+json", + "Content-Type": "application/json", + } + + url = f"https://api.github.com/repos/{owner}/{repo}/pulls/{pr_number}" + + payload = {"body": new_description} + + print(f"Attempting to update PR #{pr_number} in {owner}/{repo}...") + print(f"URL: {url}") + + try: + response = None + response = requests.patch(url, headers=headers, json=payload) + response.raise_for_status() + + print(f"Successfully updated PR #{pr_number}.") + + except requests.exceptions.RequestException as e: + print(f"Error updating pull request #{pr_number}: {e}") + if response is not None: + print(f"Response status code: {response.status_code}") + print(f"Response text: {response.text}") + exit(1) + + +if __name__ == "__main__": + github_token = getenv("GITHUB_TOKEN") + + if not github_token: + print("Error: GITHUB_TOKEN environment variable not set.") + exit(1) + + repository_owner = "flow-launcher" + repository_name = "flow.launcher" + state = "all" + + print(f"Fetching {state} PRs for {repository_owner}/{repository_name} ...") + + pull_requests = get_github_prs(github_token, repository_owner, repository_name) + + if not pull_requests: + print("No matching pull requests found") + exit(1) + + print(f"\nFound total of {len(pull_requests)} pull requests") + + release_pr = get_prs(pull_requests, "release", "open") + + if len(release_pr) != 1: + print(f"Unable to find the exact release PR. Returned result: {release_pr}") + exit(1) + + print(f"Found release PR: {release_pr[0]['title']}") + + enhancement_prs = get_prs(pull_requests, "enhancement", "closed") + bug_fix_prs = get_prs(pull_requests, "bug", "closed") + + description_content = "# Release notes\n" + description_content += f"## Features\n{get_pr_descriptions(enhancement_prs)}" if enhancement_prs else "" + description_content += f"## Bug fixes\n{get_pr_descriptions(bug_fix_prs)}" if bug_fix_prs else "" + + update_pull_request_description( + github_token, repository_owner, repository_name, release_pr[0]["number"], description_content + ) + + print(f"PR content updated to:\n{description_content}") diff --git a/.github/workflows/release_deploy.yml b/.github/workflows/release_deploy.yml new file mode 100644 index 000000000..9e082b95f --- /dev/null +++ b/.github/workflows/release_deploy.yml @@ -0,0 +1,34 @@ +--- + +name: New Release Deployments +on: + release: + types: [published] + workflow_dispatch: + +jobs: + deploy-website: + runs-on: ubuntu-latest + steps: + - name: Trigger dispatch event for deploying website + run: | + http_status=$(curl -L -f -s -o /dev/null -w "%{http_code}" \ + -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.DEPLOY_FLOW_WEBSITE }}" \ + https://api.github.com/repos/Flow-Launcher/flow-launcher.github.io/dispatches \ + -d '{"event_type":"deploy"}') + if [ "$http_status" -ne 204 ]; then echo "Error: Deploy website failed, HTTP status code is $http_status"; exit 1; fi + + publish-chocolatey: + runs-on: ubuntu-latest + steps: + - name: Trigger dispatch event for publishing to Chocolatey + run: | + http_status=$(curl -L -f -s -o /dev/null -w "%{http_code}" \ + -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.Publish_Chocolatey }}" \ + https://api.github.com/repos/Flow-Launcher/chocolatey-package/dispatches \ + -d '{"event_type":"publish"}') + if [ "$http_status" -ne 204 ]; then echo "Error: Publish Chocolatey package failed, HTTP status code is $http_status"; exit 1; fi diff --git a/.github/workflows/release_pr.yml b/.github/workflows/release_pr.yml new file mode 100644 index 000000000..451bf386c --- /dev/null +++ b/.github/workflows/release_pr.yml @@ -0,0 +1,25 @@ +name: Update release PR + +on: + pull_request: + types: [opened, reopened, synchronize] + branches: + - master + workflow_dispatch: + +jobs: + update-pr: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.x" + + - name: Run release PR update + env: + GITHUB_TOKEN: ${{ secrets.PR_TOKEN }} + run: | + pip install requests -q + python3 ./.github/update_release_pr.py diff --git a/.github/workflows/website_deploy.yml b/.github/workflows/website_deploy.yml deleted file mode 100644 index 2d44e4a2c..000000000 --- a/.github/workflows/website_deploy.yml +++ /dev/null @@ -1,21 +0,0 @@ ---- - -name: Deploy Website On Release -on: - release: - types: [published] - workflow_dispatch: - -jobs: - dispatch: - runs-on: ubuntu-latest - steps: - - name: Dispatch event - run: | - http_status=$(curl -L -f -s -o /dev/null -w "%{http_code}" \ - -X POST \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer ${{ secrets.DEPLOY_FLOW_WEBSITE }}" \ - https://api.github.com/repos/Flow-Launcher/flow-launcher.github.io/dispatches \ - -d '{"event_type":"deploy"}') - if [ "$http_status" -ne 204 ]; then echo "Error: Deploy trigger failed, HTTP status code is $http_status"; exit 1; fi diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs index aae8dd764..9b525f331 100644 --- a/Flow.Launcher.Core/Plugin/PluginManager.cs +++ b/Flow.Launcher.Core/Plugin/PluginManager.cs @@ -187,11 +187,21 @@ namespace Flow.Launcher.Core.Plugin { if (AllowedLanguage.IsDotNet(metadata.Language)) { + if (string.IsNullOrEmpty(metadata.AssemblyName)) + { + API.LogWarn(ClassName, $"AssemblyName is empty for plugin with metadata: {metadata.Name}"); + continue; // Skip if AssemblyName is not set, which can happen for erroneous plugins + } metadata.PluginSettingsDirectoryPath = Path.Combine(DataLocation.PluginSettingsDirectory, metadata.AssemblyName); metadata.PluginCacheDirectoryPath = Path.Combine(DataLocation.PluginCacheDirectory, metadata.AssemblyName); } else { + if (string.IsNullOrEmpty(metadata.Name)) + { + API.LogWarn(ClassName, $"Name is empty for plugin with metadata: {metadata.Name}"); + continue; // Skip if Name is not set, which can happen for erroneous plugins + } metadata.PluginSettingsDirectoryPath = Path.Combine(DataLocation.PluginSettingsDirectory, metadata.Name); metadata.PluginCacheDirectoryPath = Path.Combine(DataLocation.PluginCacheDirectory, metadata.Name); } diff --git a/Flow.Launcher.Core/Plugin/QueryBuilder.cs b/Flow.Launcher.Core/Plugin/QueryBuilder.cs index fae821736..25a32a728 100644 --- a/Flow.Launcher.Core/Plugin/QueryBuilder.cs +++ b/Flow.Launcher.Core/Plugin/QueryBuilder.cs @@ -16,7 +16,8 @@ namespace Flow.Launcher.Core.Plugin Search = string.Empty, RawQuery = string.Empty, SearchTerms = Array.Empty(), - ActionKeyword = string.Empty + ActionKeyword = string.Empty, + IsHomeQuery = true }; } @@ -53,7 +54,8 @@ namespace Flow.Launcher.Core.Plugin Search = search, RawQuery = rawQuery, SearchTerms = searchTerms, - ActionKeyword = actionKeyword + ActionKeyword = actionKeyword, + IsHomeQuery = false }; } } diff --git a/Flow.Launcher.Infrastructure/Http/Http.cs b/Flow.Launcher.Infrastructure/Http/Http.cs index 12edf34a4..a29f8accf 100644 --- a/Flow.Launcher.Infrastructure/Http/Http.cs +++ b/Flow.Launcher.Infrastructure/Http/Http.cs @@ -182,7 +182,6 @@ namespace Flow.Launcher.Infrastructure.Http public static Task GetStreamAsync([NotNull] string url, CancellationToken token = default) => GetStreamAsync(new Uri(url), token); - /// /// Send a GET request to the specified Uri with an HTTP completion option and a cancellation token as an asynchronous operation. /// @@ -212,7 +211,14 @@ namespace Flow.Launcher.Infrastructure.Http /// public static async Task SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption = HttpCompletionOption.ResponseContentRead, CancellationToken token = default) { - return await client.SendAsync(request, completionOption, token); + try + { + return await client.SendAsync(request, completionOption, token); + } + catch (System.Exception) + { + return new HttpResponseMessage(HttpStatusCode.InternalServerError); + } } } } diff --git a/Flow.Launcher.Infrastructure/NativeMethods.txt b/Flow.Launcher.Infrastructure/NativeMethods.txt index 0e50420b0..53c877c4f 100644 --- a/Flow.Launcher.Infrastructure/NativeMethods.txt +++ b/Flow.Launcher.Infrastructure/NativeMethods.txt @@ -22,7 +22,7 @@ SystemParametersInfo SetForegroundWindow -GetWindowLong +WINDOW_LONG_PTR_INDEX GetForegroundWindow GetDesktopWindow GetShellWindow @@ -57,3 +57,7 @@ LOCALE_TRANSIENT_KEYBOARD1 LOCALE_TRANSIENT_KEYBOARD2 LOCALE_TRANSIENT_KEYBOARD3 LOCALE_TRANSIENT_KEYBOARD4 + +SHParseDisplayName +SHOpenFolderAndSelectItems +CoTaskMemFree diff --git a/Flow.Launcher.Infrastructure/PInvokeExtensions.cs b/Flow.Launcher.Infrastructure/PInvokeExtensions.cs index 1a72ab7a6..18b992043 100644 --- a/Flow.Launcher.Infrastructure/PInvokeExtensions.cs +++ b/Flow.Launcher.Infrastructure/PInvokeExtensions.cs @@ -4,14 +4,16 @@ using Windows.Win32.UI.WindowsAndMessaging; namespace Windows.Win32; -// Edited from: https://github.com/files-community/Files internal static partial class PInvoke { + // SetWindowLong + // Edited from: https://github.com/files-community/Files + [DllImport("User32", EntryPoint = "SetWindowLongW", ExactSpelling = true)] - static extern int _SetWindowLong(HWND hWnd, int nIndex, int dwNewLong); + private static extern int _SetWindowLong(HWND hWnd, int nIndex, int dwNewLong); [DllImport("User32", EntryPoint = "SetWindowLongPtrW", ExactSpelling = true)] - static extern nint _SetWindowLongPtr(HWND hWnd, int nIndex, nint dwNewLong); + private static extern nint _SetWindowLongPtr(HWND hWnd, int nIndex, nint dwNewLong); // NOTE: // CsWin32 doesn't generate SetWindowLong on other than x86 and vice versa. @@ -22,4 +24,22 @@ internal static partial class PInvoke ? _SetWindowLong(hWnd, (int)nIndex, (int)dwNewLong) : _SetWindowLongPtr(hWnd, (int)nIndex, dwNewLong); } + + // GetWindowLong + + [DllImport("User32", EntryPoint = "GetWindowLongW", ExactSpelling = true)] + private static extern int _GetWindowLong(HWND hWnd, int nIndex); + + [DllImport("User32", EntryPoint = "GetWindowLongPtrW", ExactSpelling = true)] + private static extern nint _GetWindowLongPtr(HWND hWnd, int nIndex); + + // NOTE: + // CsWin32 doesn't generate GetWindowLong on other than x86 and vice versa. + // For more info, visit https://github.com/microsoft/CsWin32/issues/882 + public static unsafe nint GetWindowLongPtr(HWND hWnd, WINDOW_LONG_PTR_INDEX nIndex) + { + return sizeof(nint) is 4 + ? _GetWindowLong(hWnd, (int)nIndex) + : _GetWindowLongPtr(hWnd, (int)nIndex); + } } diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index a2d5a665a..696717b2a 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -50,6 +50,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings public string SelectPrevPageHotkey { get; set; } = $"PageDown"; public string OpenContextMenuHotkey { get; set; } = $"Ctrl+O"; public string SettingWindowHotkey { get; set; } = $"Ctrl+I"; + public string OpenHistoryHotkey { get; set; } = $"Ctrl+H"; public string CycleHistoryUpHotkey { get; set; } = $"{KeyConstant.Alt} + Up"; public string CycleHistoryDownHotkey { get; set; } = $"{KeyConstant.Alt} + Down"; @@ -176,7 +177,20 @@ namespace Flow.Launcher.Infrastructure.UserSettings } } - public bool ShowHistoryResultsForHomePage { get; set; } = false; + private bool _showHistoryResultsForHomePage = false; + public bool ShowHistoryResultsForHomePage + { + get => _showHistoryResultsForHomePage; + set + { + if (_showHistoryResultsForHomePage != value) + { + _showHistoryResultsForHomePage = value; + OnPropertyChanged(); + } + } + } + public int MaxHistoryResultsToShowForHomePage { get; set; } = 5; public int CustomExplorerIndex { get; set; } = 0; @@ -216,8 +230,8 @@ namespace Flow.Launcher.Infrastructure.UserSettings new() { Name = "Files", - Path = "Files", - DirectoryArgument = "-select \"%d\"", + Path = "Files-Stable", + DirectoryArgument = "\"%d\"", FileArgument = "-select \"%f\"" } }; @@ -418,29 +432,31 @@ namespace Flow.Launcher.Infrastructure.UserSettings var list = FixedHotkeys(); // Customizeable hotkeys - if(!string.IsNullOrEmpty(Hotkey)) + if (!string.IsNullOrEmpty(Hotkey)) list.Add(new(Hotkey, "flowlauncherHotkey", () => Hotkey = "")); - if(!string.IsNullOrEmpty(PreviewHotkey)) + if (!string.IsNullOrEmpty(PreviewHotkey)) list.Add(new(PreviewHotkey, "previewHotkey", () => PreviewHotkey = "")); - if(!string.IsNullOrEmpty(AutoCompleteHotkey)) + if (!string.IsNullOrEmpty(AutoCompleteHotkey)) list.Add(new(AutoCompleteHotkey, "autoCompleteHotkey", () => AutoCompleteHotkey = "")); - if(!string.IsNullOrEmpty(AutoCompleteHotkey2)) + if (!string.IsNullOrEmpty(AutoCompleteHotkey2)) list.Add(new(AutoCompleteHotkey2, "autoCompleteHotkey", () => AutoCompleteHotkey2 = "")); - if(!string.IsNullOrEmpty(SelectNextItemHotkey)) + if (!string.IsNullOrEmpty(SelectNextItemHotkey)) list.Add(new(SelectNextItemHotkey, "SelectNextItemHotkey", () => SelectNextItemHotkey = "")); - if(!string.IsNullOrEmpty(SelectNextItemHotkey2)) + if (!string.IsNullOrEmpty(SelectNextItemHotkey2)) list.Add(new(SelectNextItemHotkey2, "SelectNextItemHotkey", () => SelectNextItemHotkey2 = "")); - if(!string.IsNullOrEmpty(SelectPrevItemHotkey)) + if (!string.IsNullOrEmpty(SelectPrevItemHotkey)) list.Add(new(SelectPrevItemHotkey, "SelectPrevItemHotkey", () => SelectPrevItemHotkey = "")); - if(!string.IsNullOrEmpty(SelectPrevItemHotkey2)) + if (!string.IsNullOrEmpty(SelectPrevItemHotkey2)) list.Add(new(SelectPrevItemHotkey2, "SelectPrevItemHotkey", () => SelectPrevItemHotkey2 = "")); - if(!string.IsNullOrEmpty(SettingWindowHotkey)) + if (!string.IsNullOrEmpty(SettingWindowHotkey)) list.Add(new(SettingWindowHotkey, "SettingWindowHotkey", () => SettingWindowHotkey = "")); - if(!string.IsNullOrEmpty(OpenContextMenuHotkey)) + if (!string.IsNullOrEmpty(OpenHistoryHotkey)) + list.Add(new(OpenHistoryHotkey, "OpenHistoryHotkey", () => OpenHistoryHotkey = "")); + if (!string.IsNullOrEmpty(OpenContextMenuHotkey)) list.Add(new(OpenContextMenuHotkey, "OpenContextMenuHotkey", () => OpenContextMenuHotkey = "")); - if(!string.IsNullOrEmpty(SelectNextPageHotkey)) + if (!string.IsNullOrEmpty(SelectNextPageHotkey)) list.Add(new(SelectNextPageHotkey, "SelectNextPageHotkey", () => SelectNextPageHotkey = "")); - if(!string.IsNullOrEmpty(SelectPrevPageHotkey)) + if (!string.IsNullOrEmpty(SelectPrevPageHotkey)) list.Add(new(SelectPrevPageHotkey, "SelectPrevPageHotkey", () => SelectPrevPageHotkey = "")); if (!string.IsNullOrEmpty(CycleHistoryUpHotkey)) list.Add(new(CycleHistoryUpHotkey, "CycleHistoryUpHotkey", () => CycleHistoryUpHotkey = "")); @@ -471,7 +487,6 @@ namespace Flow.Launcher.Infrastructure.UserSettings new("Alt+Home", "HotkeySelectFirstResult"), new("Alt+End", "HotkeySelectLastResult"), new("Ctrl+R", "HotkeyRequery"), - new("Ctrl+H", "ToggleHistoryHotkey"), new("Ctrl+OemCloseBrackets", "QuickWidthHotkey"), new("Ctrl+OemOpenBrackets", "QuickWidthHotkey"), new("Ctrl+OemPlus", "QuickHeightHotkey"), diff --git a/Flow.Launcher.Infrastructure/Win32Helper.cs b/Flow.Launcher.Infrastructure/Win32Helper.cs index 783ade14e..1be803fd4 100644 --- a/Flow.Launcher.Infrastructure/Win32Helper.cs +++ b/Flow.Launcher.Infrastructure/Win32Helper.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; +using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Threading; @@ -17,6 +18,7 @@ using Windows.Win32; using Windows.Win32.Foundation; using Windows.Win32.Graphics.Dwm; using Windows.Win32.UI.Input.KeyboardAndMouse; +using Windows.Win32.UI.Shell.Common; using Windows.Win32.UI.WindowsAndMessaging; using Point = System.Windows.Point; using SystemFonts = System.Windows.SystemFonts; @@ -192,9 +194,9 @@ namespace Flow.Launcher.Infrastructure SetWindowStyle(hwnd, WINDOW_LONG_PTR_INDEX.GWL_STYLE, style); } - private static int GetWindowStyle(HWND hWnd, WINDOW_LONG_PTR_INDEX nIndex) + private static nint GetWindowStyle(HWND hWnd, WINDOW_LONG_PTR_INDEX nIndex) { - var style = PInvoke.GetWindowLong(hWnd, nIndex); + var style = PInvoke.GetWindowLongPtr(hWnd, nIndex); if (style == 0 && Marshal.GetLastPInvokeError() != 0) { throw new Win32Exception(Marshal.GetLastPInvokeError()); @@ -202,7 +204,7 @@ namespace Flow.Launcher.Infrastructure return style; } - private static nint SetWindowStyle(HWND hWnd, WINDOW_LONG_PTR_INDEX nIndex, int dwNewLong) + private static nint SetWindowStyle(HWND hWnd, WINDOW_LONG_PTR_INDEX nIndex, nint dwNewLong) { PInvoke.SetLastError(WIN32_ERROR.NO_ERROR); // Clear any existing error @@ -753,5 +755,36 @@ namespace Flow.Launcher.Infrastructure } #endregion + + #region Explorer + + // https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shopenfolderandselectitems + + public static unsafe void OpenFolderAndSelectFile(string filePath) + { + ITEMIDLIST* pidlFolder = null; + ITEMIDLIST* pidlFile = null; + + var folderPath = Path.GetDirectoryName(filePath); + + try + { + var hrFolder = PInvoke.SHParseDisplayName(folderPath, null, out pidlFolder, 0, null); + if (hrFolder.Failed) throw new COMException("Failed to parse folder path", hrFolder); + + var hrFile = PInvoke.SHParseDisplayName(filePath, null, out pidlFile, 0, null); + if (hrFile.Failed) throw new COMException("Failed to parse file path", hrFile); + + var hrSelect = PInvoke.SHOpenFolderAndSelectItems(pidlFolder, 1, &pidlFile, 0); + if (hrSelect.Failed) throw new COMException("Failed to open folder and select item", hrSelect); + } + finally + { + if (pidlFile != null) PInvoke.CoTaskMemFree(pidlFile); + if (pidlFolder != null) PInvoke.CoTaskMemFree(pidlFolder); + } + } + + #endregion } } diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs index d4eb02a90..cb60251ed 100644 --- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs +++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs @@ -88,6 +88,11 @@ namespace Flow.Launcher.Plugin /// Show the MainWindow when hiding /// void ShowMainWindow(); + + /// + /// Focus the query text box in the main window + /// + void FocusQueryTextBox(); /// /// Hide MainWindow diff --git a/Flow.Launcher.Plugin/Query.cs b/Flow.Launcher.Plugin/Query.cs index c3eede4c6..f50614699 100644 --- a/Flow.Launcher.Plugin/Query.cs +++ b/Flow.Launcher.Plugin/Query.cs @@ -21,6 +21,11 @@ namespace Flow.Launcher.Plugin /// public bool IsReQuery { get; internal set; } = false; + /// + /// Determines whether the query is a home query. + /// + public bool IsHomeQuery { get; internal init; } = false; + /// /// Search part of a query. /// This will not include action keyword if exclusive plugin gets it, otherwise it should be same as RawQuery. diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs index 942e94470..cedced181 100644 --- a/Flow.Launcher/App.xaml.cs +++ b/Flow.Launcher/App.xaml.cs @@ -32,7 +32,7 @@ namespace Flow.Launcher #region Public Properties public static IPublicAPI API { get; private set; } - public static bool Exiting => _mainWindow.CanClose; + public static bool LoadingOrExiting => _mainWindow == null || _mainWindow.CanClose; #endregion @@ -98,6 +98,10 @@ namespace Flow.Launcher .AddTransient() .AddTransient() .AddTransient() + // Use transient instance for dialog view models because + // settings will change and we need to recreate them + .AddTransient() + .AddTransient() ).Build(); Ioc.Default.ConfigureServices(host.Services); } diff --git a/Flow.Launcher/HotkeyControl.xaml.cs b/Flow.Launcher/HotkeyControl.xaml.cs index 262727127..e8961058c 100644 --- a/Flow.Launcher/HotkeyControl.xaml.cs +++ b/Flow.Launcher/HotkeyControl.xaml.cs @@ -100,6 +100,7 @@ namespace Flow.Launcher PreviewHotkey, OpenContextMenuHotkey, SettingWindowHotkey, + OpenHistoryHotkey, CycleHistoryUpHotkey, CycleHistoryDownHotkey, SelectPrevPageHotkey, @@ -130,6 +131,7 @@ namespace Flow.Launcher HotkeyType.PreviewHotkey => _settings.PreviewHotkey, HotkeyType.OpenContextMenuHotkey => _settings.OpenContextMenuHotkey, HotkeyType.SettingWindowHotkey => _settings.SettingWindowHotkey, + HotkeyType.OpenHistoryHotkey => _settings.OpenHistoryHotkey, HotkeyType.CycleHistoryUpHotkey => _settings.CycleHistoryUpHotkey, HotkeyType.CycleHistoryDownHotkey => _settings.CycleHistoryDownHotkey, HotkeyType.SelectPrevPageHotkey => _settings.SelectPrevPageHotkey, @@ -166,6 +168,9 @@ namespace Flow.Launcher case HotkeyType.SettingWindowHotkey: _settings.SettingWindowHotkey = value; break; + case HotkeyType.OpenHistoryHotkey: + _settings.OpenHistoryHotkey = value; + break; case HotkeyType.CycleHistoryUpHotkey: _settings.CycleHistoryUpHotkey = value; break; diff --git a/Flow.Launcher/Languages/ar.xaml b/Flow.Launcher/Languages/ar.xaml index b81c5c9b5..88e8fbc61 100644 --- a/Flow.Launcher/Languages/ar.xaml +++ b/Flow.Launcher/Languages/ar.xaml @@ -364,6 +364,7 @@ موقع بيانات المستخدم يتم حفظ إعدادات المستخدم والإضافات المثبتة في مجلد بيانات المستخدم. قد يختلف هذا الموقع اعتمادًا على ما إذا كان في وضع النقل أم لا. فتح المجلد + Advanced Log Level Debug Info @@ -371,6 +372,7 @@ اختر مدير الملفات + Learn more يرجى تحديد موقع ملف مدير الملفات الذي تستخدمه وإضافة الحجج حسب الحاجة. يمثل "%d" مسار الدليل المفتوح، ويستخدمه الحقل "الحجة للمجلد" للأوامر التي تفتح أدلة محددة. يمثل "%f" مسار الملف المفتوح، ويستخدمه الحقل "الحجة للملف" للأوامر التي تفتح ملفات محددة. على سبيل المثال، إذا كان مدير الملفات يستخدم أمرًا مثل "totalcmd.exe /A c:\windows" لفتح دليل c:\windows، فإن مسار مدير الملفات سيكون totalcmd.exe، وحجة المجلد ستكون /A "%d". قد تحتاج بعض مديري الملفات مثل QTTabBar فقط إلى توفير مسار، في هذه الحالة استخدم "%d" كمسار مدير الملفات واترك باقي الحقول فارغة. مدير الملفات @@ -378,6 +380,8 @@ مسار مدير الملفات حجة للمجلد حجة للملف + The file manager '{0}' could not be located at '{1}'. Would you like to continue? + File Manager Path Error متصفح الويب الافتراضي @@ -469,6 +473,14 @@ 1. Upload log file: {0} 2. Copy below exception message + + File Manager Error + + The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General. + + خطأ + An error occurred while opening the folder. {0} + يرجى الانتظار... diff --git a/Flow.Launcher/Languages/cs.xaml b/Flow.Launcher/Languages/cs.xaml index 71c9c8c6b..552f1a36d 100644 --- a/Flow.Launcher/Languages/cs.xaml +++ b/Flow.Launcher/Languages/cs.xaml @@ -364,6 +364,7 @@ User Data Location User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not. Open Folder + Advanced Log Level Debug Info @@ -371,6 +372,7 @@ Vybrat správce souborů + Learn more Please specify the file location of the file manager you using and add arguments as required. The "%d" represents the directory path to open for, used by the Arg for Folder field and for commands opening specific directories. The "%f" represents the file path to open for, used by the Arg for File field and for commands opening specific files. For example, if the file manager uses a command such as "totalcmd.exe /A c:\windows" to open the c:\windows directory, the File Manager Path will be totalcmd.exe, and the Arg For Folder will be /A "%d". Certain file managers like QTTabBar may just require a path to be supplied, in this instance use "%d" as the File Manager Path and leave the rest of the fileds blank. Správce souborů @@ -378,6 +380,8 @@ Cesta k správci souborů Argumenty pro složku Argumenty pro Soubor + The file manager '{0}' could not be located at '{1}'. Would you like to continue? + File Manager Path Error Výchozí prohlížeč @@ -469,6 +473,14 @@ Pokud před zkratku při zadávání přidáte znak "@", bude odpovíd 1. Upload log file: {0} 2. Copy below exception message + + File Manager Error + + The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General. + + Chyba + An error occurred while opening the folder. {0} + Počkejte prosím... diff --git a/Flow.Launcher/Languages/da.xaml b/Flow.Launcher/Languages/da.xaml index 37723dc9b..7fd6d478a 100644 --- a/Flow.Launcher/Languages/da.xaml +++ b/Flow.Launcher/Languages/da.xaml @@ -364,6 +364,7 @@ User Data Location User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not. Open Folder + Advanced Log Level Debug Info @@ -371,6 +372,7 @@ Select File Manager + Learn more Please specify the file location of the file manager you using and add arguments as required. The "%d" represents the directory path to open for, used by the Arg for Folder field and for commands opening specific directories. The "%f" represents the file path to open for, used by the Arg for File field and for commands opening specific files. For example, if the file manager uses a command such as "totalcmd.exe /A c:\windows" to open the c:\windows directory, the File Manager Path will be totalcmd.exe, and the Arg For Folder will be /A "%d". Certain file managers like QTTabBar may just require a path to be supplied, in this instance use "%d" as the File Manager Path and leave the rest of the fileds blank. Filhåndtering @@ -378,6 +380,8 @@ Sti til filhåndtering Arg for mappe Arg for fil + The file manager '{0}' could not be located at '{1}'. Would you like to continue? + File Manager Path Error Default Web Browser @@ -469,6 +473,14 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in 1. Upload log file: {0} 2. Copy below exception message + + File Manager Error + + The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General. + + Error + An error occurred while opening the folder. {0} + Please wait... diff --git a/Flow.Launcher/Languages/de.xaml b/Flow.Launcher/Languages/de.xaml index 895a2dab6..3c650920f 100644 --- a/Flow.Launcher/Languages/de.xaml +++ b/Flow.Launcher/Languages/de.xaml @@ -42,8 +42,8 @@ Spielmodus Aussetzen der Verwendung von Hotkeys. Position zurücksetzen - Reset search window position - Type here to search + Position des Suchfensters zurücksetzen + Zum Suchen hier tippen Einstellungen @@ -126,12 +126,12 @@ - Open Language and Region System Settings + Sprach- und Regionen-Systemeinstellungen öffnen Opens the Korean IME setting location. Go to Korean > Language Options > Keyboard - Microsoft IME > Compatibility Öffnen - Use Previous Korean IME + Vorherige koreanische IME verwenden You can change the Previous Korean IME settings directly from here - Home Page + Homepage Show home page results when query text is empty. Show History Results in Home Page Maximum History Results Shown in Home Page @@ -154,11 +154,11 @@ Aktions-Schlüsselwörter ändern Plugin search delay time Change Plugin Search Delay Time - Advanced Settings: + Erweiterte Einstellungen Aktiviert Priorität Search Delay - Home Page + Homepage Aktuelle Priorität Neue Priorität Priorität @@ -246,13 +246,13 @@ Acrylic Mica Mica Alt - This theme supports two (light/dark) modes. + Dieses Theme unterstützt zwei Modi (hell/dunkel). Dieses Theme unterstützt Unschärfe und transparenten Hintergrund. - Show placeholder + Platzhalter zeigen Display placeholder when query is empty - Placeholder text + Platzhaltertext Change placeholder text. Input empty will use: {0} - Fixed Window Size + Festgelegte Fenstergröße The window size is not adjustable by dragging. @@ -313,7 +313,7 @@ Segoe Fluent-Icons verwenden Segoe Fluent-Icons für Abfrageergebnisse verwenden, wo unterstützt Taste drücken - Show Result Badges + Ergebnis-Badges zeigen For supported plugins, badges are displayed to help distinguish them more easily. Show Result Badges for Global Query Only @@ -356,14 +356,15 @@ Ordner »Logs« Logs löschen Sind Sie sicher, dass Sie alle Logs löschen wollen? - Cache Folder - Clear Caches + Cache-Ordner + Cache leeren Are you sure you want to delete all caches? Failed to clear part of folders and files. Please see log file for more information Assistent Speicherort für Benutzerdaten Benutzereinstellungen und installierte Plug-ins werden im Ordner für Benutzerdaten gespeichert. Dieser Speicherort kann variieren, je nachdem, ob sich das Programm im portablen Modus befindet oder nicht. Ordner öffnen + Advanced Log-Ebene Debug Info @@ -371,6 +372,7 @@ Dateimanager auswählen + Mehr erfahren Bitte geben Sie den Dateiort des von Ihnen verwendeten Dateimanagers an und fügen Sie bei Bedarf Argumente hinzu. Das „%d“ repräsentiert den dafür zu öffnenden Verzeichnispfad, der vom Feld Arg for Folder und für Befehle zum Öffnen bestimmter Verzeichnisse verwendet wird. Das „%f“ repräsentiert den dafür zu öffnenden Dateipfad, der vom Feld Arg for File und für Befehle zum Öffnen bestimmter Dateien verwendet wird. Zum Beispiel, wenn der Dateimanager einen Befehl wie „totalcmd.exe /A c:\windows“ verwendet, um das Verzeichnis c:\windows zu öffnen, lautet der Dateimanager-Pfad „totalcmd.exe“ und der Arg for Folder „/A %d“. Bestimmte Dateimanager wie QTTabBar kann nur die Angabe eines Pfades erfordern, in diesem Fall verwenden Sie „%d“ als den Dateimanager-Pfad und lassen den Rest der Felder blank. Dateimanager @@ -378,6 +380,8 @@ Dateimanager-Pfad Arg For Folder Arg For File + The file manager '{0}' could not be located at '{1}'. Would you like to continue? + File Manager Path Error Webbrowser per Default @@ -413,7 +417,7 @@ Input the search delay time in ms you like to use for the plugin. Input empty if you don't want to specify any, and the plugin will use default search delay time. - Home Page + Homepage Enable the plugin home page state if you like to show the plugin results when query is empty. @@ -469,6 +473,14 @@ Wenn Sie bei der Eingabe eines Shortcuts ein '@'-Präfix hinzufügen, stimmt die 1. Logdatei hochladen: {0} 2. Kopieren Sie die Ausnahmemeldung unterhalb + + File Manager Error + + The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General. + + Fehler + An error occurred while opening the folder. {0} + Bitte warten Sie ... diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index f728f1095..ad0991175 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -361,6 +361,7 @@ User Data Location User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not. Open Folder + Advanced Log Level Debug Info @@ -368,6 +369,7 @@ Select File Manager + Learn more Please specify the file location of the file manager you using and add arguments as required. The "%d" represents the directory path to open for, used by the Arg for Folder field and for commands opening specific directories. The "%f" represents the file path to open for, used by the Arg for File field and for commands opening specific files. For example, if the file manager uses a command such as "totalcmd.exe /A c:\windows" to open the c:\windows directory, the File Manager Path will be totalcmd.exe, and the Arg For Folder will be /A "%d". Certain file managers like QTTabBar may just require a path to be supplied, in this instance use "%d" as the File Manager Path and leave the rest of the fileds blank. File Manager @@ -375,6 +377,8 @@ File Manager Path Arg For Folder Arg For File + The file manager '{0}' could not be located at '{1}'. Would you like to continue? + File Manager Path Error Default Web Browser @@ -464,6 +468,14 @@ 1. Upload log file: {0} 2. Copy below exception message + + File Manager Error + + The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General. + + Error + An error occurred while opening the folder. {0} + Please wait... diff --git a/Flow.Launcher/Languages/es-419.xaml b/Flow.Launcher/Languages/es-419.xaml index 902811a56..5bd77a8dd 100644 --- a/Flow.Launcher/Languages/es-419.xaml +++ b/Flow.Launcher/Languages/es-419.xaml @@ -364,6 +364,7 @@ User Data Location User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not. Open Folder + Advanced Log Level Debug Info @@ -371,6 +372,7 @@ Seleccionar Gestor de Archivos + Learn more Please specify the file location of the file manager you using and add arguments as required. The "%d" represents the directory path to open for, used by the Arg for Folder field and for commands opening specific directories. The "%f" represents the file path to open for, used by the Arg for File field and for commands opening specific files. For example, if the file manager uses a command such as "totalcmd.exe /A c:\windows" to open the c:\windows directory, the File Manager Path will be totalcmd.exe, and the Arg For Folder will be /A "%d". Certain file managers like QTTabBar may just require a path to be supplied, in this instance use "%d" as the File Manager Path and leave the rest of the fileds blank. Gestor de Archivos @@ -378,6 +380,8 @@ Ruta del Gestor de Archivos Arg para Carpeta Arg para Archivo + The file manager '{0}' could not be located at '{1}'. Would you like to continue? + File Manager Path Error Navegador Web Predeterminado @@ -469,6 +473,14 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in 1. Upload log file: {0} 2. Copy below exception message + + File Manager Error + + The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General. + + Error + An error occurred while opening the folder. {0} + Por favor espere... diff --git a/Flow.Launcher/Languages/es.xaml b/Flow.Launcher/Languages/es.xaml index 0dc6833af..7324fc01b 100644 --- a/Flow.Launcher/Languages/es.xaml +++ b/Flow.Launcher/Languages/es.xaml @@ -364,6 +364,7 @@ Ubicación de datos del usuario La configuración del usuario y los complementos instalados se guardan en la carpeta de datos del usuario. Esta ubicación puede variar dependiendo de si está en modo portable o no. Abrir carpeta + Advanced Nivel de registro Depurar Información @@ -371,6 +372,7 @@ Seleccionar administrador de archivos + Más información Especifique la ubicación del archivo del administrador de archivos que está utilizando y añada los argumentos necesarios. El argumento "%d" representa la ruta del directorio a abrir, utilizada por el campo Argumentos de la carpeta y por comandos que abren directorios específicos. El "%f" representa la ruta del archivo a abrir, utilizada por el campo Argumentos del archivo y por comandos que abren archivos específicos. Por ejemplo, si el administrador de archivos utiliza un comando como "totalcmd.exe /A c:\windows" para abrir el directorio c:\windows, la ruta del administrador de archivos será totalcmd.exe, y los Argumentos de la carpeta serán /A "%d". Ciertos administradores de archivos como QTTabBar pueden requerir solo la ruta, en este caso utilice "%d" como la ruta del administrador de archivos y deje el resto de los campos en blanco. Administrador de archivos @@ -378,6 +380,8 @@ Ruta del administrador de archivos Argumentos de la carpeta Argumentos del archivo + El administrador de archivos '{0}' no pudo ser localizado en '{1}'. ¿Desea continuar? + Error de ruta del administrador de archivos Navegador web predeterminado @@ -469,6 +473,14 @@ Si añade un prefijo "@" al introducir un acceso directo, éste coinci 1. Subir archivo de registro: {0} 2. Copiar el siguiente mensaje de excepción + + Error del administrador de archivos + + No se ha encontrado el administrador de archivos especificado. Compruebe la configuración del Administrador de archivos personalizado en Configuración > General. + + Error + Se ha producido un error al abrir la carpeta. {0} + Por favor espere... diff --git a/Flow.Launcher/Languages/fr.xaml b/Flow.Launcher/Languages/fr.xaml index 41fdbaa51..95ad58d6e 100644 --- a/Flow.Launcher/Languages/fr.xaml +++ b/Flow.Launcher/Languages/fr.xaml @@ -363,6 +363,7 @@ Emplacement des données utilisateur Les paramètres utilisateur et les plugins installés sont enregistrés dans le dossier des données utilisateur. Cet emplacement peut varier selon que vous soyez en mode portable ou non. Ouvrir le dossier + Avancé Niveau de journalisation Débogage Info @@ -370,6 +371,7 @@ Sélectionner le gestionnaire de fichiers + En savoir plus Veuillez spécifier l'emplacement du fichier de l'explorateur de fichiers que vous utilisez et ajouter des arguments si nécessaire. Le "%d" représente le chemin du répertoire à ouvrir, utilisé par le champ Arg for Folder et pour les commandes ouvrant des répertoires spécifiques. Le "%f" représente le chemin du fichier à ouvrir, utilisé par le champ Arg for File et pour les commandes ouvrant des fichiers spécifiques. Par exemple, si l'explorateur de fichiers utilise une commande telle que "totalcmd.exe /A c:\windows" pour ouvrir le répertoire c:\windows, le chemin de l'explorateur de fichiers sera totalcmd.exe et l'argument Arg For Folder sera /A "%d"". Certains explorateurs de fichiers comme QTTabBar peuvent simplement nécessiter qu'un chemin soit fourni, dans ce cas, utilisez "%d" comme chemin de l'explorateur de fichiers et laissez le reste des fichiers vides. Gestionnaire de fichiers @@ -377,6 +379,8 @@ Chemin du gestionnaire de fichiers Arguments pour le répertoire Arguments pour le fichier + Le gestionnaire de fichiers '{0}' n'a pas pu être situé à '{1}'. Souhaitez-vous continuer ? + Erreur de chemin du gestionnaire de fichiers Navigateur web par défaut @@ -468,6 +472,14 @@ Si vous ajoutez un préfixe "@" lors de la saisie d'un raccourci, celu 1. Télécharger le fichier journal : {0} 2. Copiez le message d’exception ci-dessous + + Erreur du gestionnaire de fichiers + + Le gestionnaire de fichiers spécifié n'a pas été trouvé. Veuillez vérifier le paramètre Gestionnaire de fichiers personnalisé dans Paramètres > Général. + + Erreur + Une erreur s'est produite lors de l'ouverture du dossier. {0} + Veuillez patienter... diff --git a/Flow.Launcher/Languages/he.xaml b/Flow.Launcher/Languages/he.xaml index 52eaf5e9f..d1688b647 100644 --- a/Flow.Launcher/Languages/he.xaml +++ b/Flow.Launcher/Languages/he.xaml @@ -67,7 +67,7 @@ מרכז עליון שמאל עליון ימין עליון - Custom Position + מיקום מותאם אישית שפה סגנון שאילתה אחרונה הצג/הסתר תוצאות קודמות כאשר Flow Launcher מופעל מחדש. @@ -102,7 +102,7 @@ נמוך Regular חפש באמצעות Pinyin - Allows using Pinyin to search. Pinyin is the standard system of romanized spelling for translating Chinese. + מאפשר חיפוש באמצעות Pinyin, מערכת הכתיבה הסטנדרטית לתרגום סינית. הצג תמיד תצוגה מקדימה פתח תמיד את לוח התצוגה המקדימה כאשר Flow מופעל. הקש על {0} כדי להחליף את התצוגה המקדימה. לא ניתן להחיל אפקט צל כאשר העיצוב הנוכחי מוגדר לאפקט טשטוש @@ -134,7 +134,7 @@ Show home page results when query text is empty. Show History Results in Home Page Maximum History Results Shown in Home Page - This can only be edited if plugin supports Home feature and Home Page is enabled. + ניתן לערוך זאת רק אם התוסף תומך בתכונת הבית ודף הבית מופעל. חפש תוסף @@ -151,7 +151,7 @@ מילת מפתח נוכחית לפעולה מילת מפתח חדשה לפעולה שנה מילות מפתח לפעולה - Plugin search delay time + זמן השהייה של חיפוש תוסף שנה את זמן השהיית חיפוש של תוסף הגדרות מתקדמות: מופעל @@ -313,7 +313,7 @@ השתמש ב-Segoe Fluent Icons לתוצאות חיפוש כאשר נתמך הקש על מקש הצג תגי תוצאות - For supported plugins, badges are displayed to help distinguish them more easily. + עבור תוספים נתמכים, מוצגים תגים כדי לעזור להבחין ביניהם ביתר קלות. Show Result Badges for Global Query Only @@ -363,6 +363,7 @@ מיקום נתוני משתמש הגדרות המשתמש והתוספים המותקנים נשמרים בתיקיית נתוני המשתמש. מיקום זה עשוי להשתנות אם התוכנה במצב נייד. פתח תיקיה + Advanced רמת יומן ניפוי שגיאות מידע @@ -370,6 +371,7 @@ בחר מנהל קבצים + למד עוד אנא ציין את מיקום הקובץ של מנהל הקבצים שבו אתה משתמש והוסף ארגומנטים כנדרש. "%d" מייצג את נתיב התיקייה שיש לפתוח, ומשמש בשדה ארגומנט לתיקייה ובפקודות לפתיחת תיקיות מסוימות. "%f" מייצג את נתיב הקובץ שיש לפתוח, ומשמש בשדה ארגומנט לקובץ ובפקודות לפתיחת קבצים מסוימים. לדוגמה, אם מנהל הקבצים משתמש בפקודה כגון "totalcmd.exe /A c:\windows" כדי לפתוח את התיקייה c:\windows, נתיב מנהל הקבצים יהיה totalcmd.exe, והארגומנט לתיקייה יהיה /A "%d". מנהלי קבצים מסוימים, כגון QTTabBar, עשויים לדרוש רק ציון נתיב, במקרה כזה השתמש ב-"%d" כנתיב מנהל הקבצים והשאר את שאר השדות ריקים. מנהל קבצים @@ -377,6 +379,8 @@ נתיב מנהל קבצים ארגומנט לתיקייה ארגומנט לקובץ + לא ניתן היה לאתר את מנהל הקבצים '{0}' ב-'{1}'. האם ברצונך להמשיך? + שגיאת נתיב למנהל הקבצים דפדפן ברירת מחדל @@ -413,7 +417,7 @@ דף הבית - Enable the plugin home page state if you like to show the plugin results when query is empty. + הפעל את מצב דף הבית של התוסף אם ברצונך להציג את תוצאות התוסף כאשר השאילתה ריקה. מקש קיצור לשאילתה מותאמת אישית @@ -468,6 +472,14 @@ 1. העלה קובץ יומן: {0} 2. העתק את הודעת החריגה למטה + + שגיאת מנהל הקבצים + + לא ניתן היה למצוא את מנהל הקבצים שצוין. אנא בדוק את ההגדרה של מנהל קבצים מותאם אישית תחת הגדרות > כללי. + + שגיאה + אירעה שגיאה בעת פתיחת התיקייה. {0} + אנא המתן... diff --git a/Flow.Launcher/Languages/it.xaml b/Flow.Launcher/Languages/it.xaml index 1a356ad65..64d9f5abe 100644 --- a/Flow.Launcher/Languages/it.xaml +++ b/Flow.Launcher/Languages/it.xaml @@ -364,6 +364,7 @@ Posizione Dati Utente Le impostazioni dell'utente e i plugin installati sono salvati nella cartella dati utente. Questa posizione può variare se è in modalità portable o no. Apri Cartella + Advanced Log Level Debug Info @@ -371,6 +372,7 @@ Seleziona Gestore File + Learn more Please specify the file location of the file manager you using and add arguments as required. The "%d" represents the directory path to open for, used by the Arg for Folder field and for commands opening specific directories. The "%f" represents the file path to open for, used by the Arg for File field and for commands opening specific files. For example, if the file manager uses a command such as "totalcmd.exe /A c:\windows" to open the c:\windows directory, the File Manager Path will be totalcmd.exe, and the Arg For Folder will be /A "%d". Certain file managers like QTTabBar may just require a path to be supplied, in this instance use "%d" as the File Manager Path and leave the rest of the fileds blank. Gestore File @@ -378,6 +380,8 @@ Percorso Gestore File Arg Per Cartella Arg Per Cartella + The file manager '{0}' could not be located at '{1}'. Would you like to continue? + File Manager Path Error Browser predefinito @@ -469,6 +473,14 @@ Se si aggiunge un prefisso '@' mentre si inserisce una scorciatoia, corrisponde 1. Upload log file: {0} 2. Copy below exception message + + File Manager Error + + The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General. + + Error + An error occurred while opening the folder. {0} + Attendere prego... diff --git a/Flow.Launcher/Languages/ja.xaml b/Flow.Launcher/Languages/ja.xaml index 949fe5c99..c2e64ae26 100644 --- a/Flow.Launcher/Languages/ja.xaml +++ b/Flow.Launcher/Languages/ja.xaml @@ -364,6 +364,7 @@ User Data Location User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not. Open Folder + Advanced Log Level Debug Info @@ -371,6 +372,7 @@ デフォルトのファイルマネージャー + Learn more Please specify the file location of the file manager you using and add arguments as required. The "%d" represents the directory path to open for, used by the Arg for Folder field and for commands opening specific directories. The "%f" represents the file path to open for, used by the Arg for File field and for commands opening specific files. For example, if the file manager uses a command such as "totalcmd.exe /A c:\windows" to open the c:\windows directory, the File Manager Path will be totalcmd.exe, and the Arg For Folder will be /A "%d". Certain file managers like QTTabBar may just require a path to be supplied, in this instance use "%d" as the File Manager Path and leave the rest of the fileds blank. File Manager @@ -378,6 +380,8 @@ File Manager Path Arg For Folder Arg For File + The file manager '{0}' could not be located at '{1}'. Would you like to continue? + File Manager Path Error デフォルトのウェブブラウザー @@ -469,6 +473,14 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in 1. Upload log file: {0} 2. Copy below exception message + + File Manager Error + + The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General. + + Error + An error occurred while opening the folder. {0} + Please wait... diff --git a/Flow.Launcher/Languages/ko.xaml b/Flow.Launcher/Languages/ko.xaml index 9ae2e0195..b78c86a82 100644 --- a/Flow.Launcher/Languages/ko.xaml +++ b/Flow.Launcher/Languages/ko.xaml @@ -122,10 +122,10 @@ 열기 이전 버전의 Microsoft IME 사용 이전 버전의 IME를 사용하도록 시스템 설정을 변경합니다 - Home Page - Show home page results when query text is empty. - Show History Results in Home Page - Maximum History Results Shown in Home Page + 홈페이지 + 쿼리 입력창이 비어있을때, 홈페이지의 결과를 표시합니다. + 히스토리를 홈페이지에 표시 + 홈페이지에 표시할 최대 히스토리 수 This can only be edited if plugin supports Home feature and Home Page is enabled. @@ -149,7 +149,7 @@ 중요 검색 지연 - Home Page + 홈페이지 현재 중요도: 새 중요도: 중요도 @@ -347,7 +347,7 @@ 로그 폴더 로그 삭제 정말 모든 로그를 삭제하시겠습니까? - Cache Folder + 캐시 폴더 캐시 지우기 모든 캐시를 삭제하시겠습니까? Failed to clear part of folders and files. Please see log file for more information @@ -355,13 +355,15 @@ 사용자 데이터 위치 사용자 설정과 설치된 플러그인은 사용자 데이터 폴더에 저장됩니다. 이 위치는 휴대용 모드 활성화 여부에 따라 달라질 수 있습니다. 폴더 열기 + Advanced 로그 레벨 Debug Info - Setting Window Font + 설정창 글꼴 파일관리자 선택 + 더 알아보기 사용 중인 파일 관리자의 파일 위치를 지정하고, 필요한 경우 인수를 추가하세요. "%d"는 열고자 하는 디렉터리 경로를 나타내며, 폴더용 인수 필드 및 특정 디렉터리를 여는 명령어에서 사용됩니다. "%f"는 열고자 하는 파일 경로를 나타내며, 파일용 인수 필드 및 특정 파일을 여는 명령어에서 사용됩니다. 예를 들어, 파일 관리자가 totalcmd.exe /A c:\windows와 같은 명령어로 c:\windows 디렉터리를 연다면, 파일 관리자 경로는 totalcmd.exe가 되고, 폴더용 인수는 /A "%d"가 됩니다. QTTabBar와 같은 일부 파일 관리자는 경로만 전달하면 되는 경우가 있으므로, 이 경우에는 파일 관리자 경로에 "%d"를 입력하고 나머지 필드는 비워두세요. 파일관리자 @@ -369,6 +371,8 @@ 파일관리자 경로 폴더경로 인수 파일경로 인수 + The file manager '{0}' could not be located at '{1}'. Would you like to continue? + File Manager Path Error 기본 웹 브라우저 @@ -404,7 +408,7 @@ 플러그인에서 사용할 검색 지연 시간(ms)을 입력하세요. 지정하지 않으려면 비워두세요. 기본 검색 지연 시간이 사용됩니다. - Home Page + 홈페이지 Enable the plugin home page state if you like to show the plugin results when query is empty. @@ -460,6 +464,14 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in 1. Upload log file: {0} 2. Copy below exception message + + File Manager Error + + The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General. + + Error + An error occurred while opening the folder. {0} + 잠시 기다려주세요... diff --git a/Flow.Launcher/Languages/nb.xaml b/Flow.Launcher/Languages/nb.xaml index 58571a1c4..9e62ec2cc 100644 --- a/Flow.Launcher/Languages/nb.xaml +++ b/Flow.Launcher/Languages/nb.xaml @@ -364,6 +364,7 @@ Plassering av brukerdata Brukerinnstillinger og installerte programtillegg lagres i brukerens datamappe. Denne plasseringen kan variere avhengig av om den er i portabel modus eller ikke. Åpne mappe + Advanced Log Level Debug Info @@ -371,6 +372,7 @@ Velg filbehandler + Learn more Vennligst spesifiser filplasseringen til filbehandleren du bruker, og legg til argumenter etter behov. "%d" representerer katalogbanen som skal åpnes for, brukt av Arg for mappe-feltet og for kommandoer som åpner spesifikke kataloger. "%f" representerer filbanen som skal åpnes for, brukt av Arg for fil-feltet og for kommandoer som åpner spesifikke filer. For eksempel, hvis filbehandleren bruker en kommando som "totalcmd.exe /A c:windows" for å åpne c:windows-katalogen, vil filbehandlingsbanen bli totalcmd.exe, og Arg For Folder vil være /A "%d". Enkelte filbehandlere som QTTabBar kan bare kreve at en bane oppgis, i dette tilfellet bruker du "%d" som filbehandlingsbane og lar resten av feltene stå tomme. Filbehandler @@ -378,6 +380,8 @@ Filbehandler sti Arg for mappe Arg for fil + The file manager '{0}' could not be located at '{1}'. Would you like to continue? + File Manager Path Error Standard nettleser @@ -469,6 +473,14 @@ Hvis du legger til et @-prefiks mens du legger inn en snarvei, samsvarer det med 1. Upload log file: {0} 2. Copy below exception message + + File Manager Error + + The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General. + + Feil + An error occurred while opening the folder. {0} + Vennligst vent... diff --git a/Flow.Launcher/Languages/nl.xaml b/Flow.Launcher/Languages/nl.xaml index 70a58e322..31e6ea768 100644 --- a/Flow.Launcher/Languages/nl.xaml +++ b/Flow.Launcher/Languages/nl.xaml @@ -364,6 +364,7 @@ Gegevenslocatie van gebruiker Gebruikersinstellingen en geïnstalleerde plug-ins worden opgeslagen in de gebruikersgegevensmap. Deze locatie kan variëren afhankelijk van of het in draagbare modus is of niet. Map openen + Advanced Log Level Debug Info @@ -371,6 +372,7 @@ Bestandsbeheerder selecteren + Learn more Please specify the file location of the file manager you using and add arguments as required. The "%d" represents the directory path to open for, used by the Arg for Folder field and for commands opening specific directories. The "%f" represents the file path to open for, used by the Arg for File field and for commands opening specific files. For example, if the file manager uses a command such as "totalcmd.exe /A c:\windows" to open the c:\windows directory, the File Manager Path will be totalcmd.exe, and the Arg For Folder will be /A "%d". Certain file managers like QTTabBar may just require a path to be supplied, in this instance use "%d" as the File Manager Path and leave the rest of the fileds blank. Bestandsbeheerder @@ -378,6 +380,8 @@ Bestandsbeheerder pad Arg voor map Arg voor bestand + The file manager '{0}' could not be located at '{1}'. Would you like to continue? + File Manager Path Error Standaard webbrowser @@ -469,6 +473,14 @@ Als u een '@' voorvoegsel toevoegt tijdens het invoeren van een snelkoppeling, m 1. Upload log file: {0} 2. Copy below exception message + + File Manager Error + + The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General. + + Error + An error occurred while opening the folder. {0} + Please wait... diff --git a/Flow.Launcher/Languages/pl.xaml b/Flow.Launcher/Languages/pl.xaml index 7cc6dfcb1..f32a38585 100644 --- a/Flow.Launcher/Languages/pl.xaml +++ b/Flow.Launcher/Languages/pl.xaml @@ -364,6 +364,7 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros Lokalizacja danych użytkownika Ustawienia użytkownika i zainstalowane wtyczki są zapisywane w folderze danych użytkownika. Ta lokalizacja może się różnić w zależności od tego, czy aplikacja jest w trybie przenośnym, czy nie. Otwórz folder + Advanced Poziom logowania Debug Info @@ -371,6 +372,7 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros Wybierz menedżer plików + Learn more Proszę określić lokalizację pliku menedżera plików, którego używasz i dodać argumenty według potrzeb. Symbol "%d" reprezentuje ścieżkę katalogu do otwarcia, używaną w polu Arg dla Folderu oraz dla poleceń otwierających konkretne katalogi. Symbol "%f" reprezentuje ścieżkę pliku do otwarcia, używaną w polu Arg dla Pliku oraz dla poleceń otwierających konkretne pliki. Na przykład, jeśli menedżer plików używa polecenia takiego jak „totalcmd.exe /A c:\windows" do otwarcia katalogu c:\windows, Ścieżka Menedżera Plików będzie totalcmd.exe, a Argument dla Folderu będzie /A "%d". Niektóre menedżery plików, takie jak QTTabBar, mogą wymagać jedynie podania ścieżki; w takim przypadku użyj "%d" jako Ścieżki Menedżera Plików, a pozostałe pola pozostaw puste. Menadżer plików @@ -378,6 +380,8 @@ Kliknij "nie", jeśli jest już zainstalowany. Zostaniesz wtedy popros Ścieżka menedżera plików Arg dla folderu Arg dla pliku + The file manager '{0}' could not be located at '{1}'. Would you like to continue? + File Manager Path Error Domyślna przeglądarka @@ -469,6 +473,14 @@ Jeśli dodasz prefiks '@' podczas wprowadzania skrótu, będzie on pasował do d 1. Prześlij plik dziennika: {0} 2. Skopiuj poniższą wiadomość wyjątku + + File Manager Error + + The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General. + + Błąd + An error occurred while opening the folder. {0} + Proszę czekać... @@ -488,7 +500,7 @@ Jeśli dodasz prefiks '@' podczas wprowadzania skrótu, będzie on pasował do d Anuluj Aktualizacja nie powiodła się Sprawdź połączenie i spróbuj zaktualizować ustawienia proxy do github-cloud.s3.amazonaws.com. - Aby dokończyć proces aktualizacji Flow Launcher musi zostać zresetowany + Aby dokończyć proces aktualizacji Flow Launcher musi zostać zrestartowany Następujące pliki zostaną zaktualizowane Aktualizuj pliki Opis aktualizacji diff --git a/Flow.Launcher/Languages/pt-br.xaml b/Flow.Launcher/Languages/pt-br.xaml index bd74d1d5f..bcbfa74af 100644 --- a/Flow.Launcher/Languages/pt-br.xaml +++ b/Flow.Launcher/Languages/pt-br.xaml @@ -364,6 +364,7 @@ User Data Location User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not. Open Folder + Advanced Log Level Debug Info @@ -371,6 +372,7 @@ Selecione o Gerenciador de Arquivos + Learn more Please specify the file location of the file manager you using and add arguments as required. The "%d" represents the directory path to open for, used by the Arg for Folder field and for commands opening specific directories. The "%f" represents the file path to open for, used by the Arg for File field and for commands opening specific files. For example, if the file manager uses a command such as "totalcmd.exe /A c:\windows" to open the c:\windows directory, the File Manager Path will be totalcmd.exe, and the Arg For Folder will be /A "%d". Certain file managers like QTTabBar may just require a path to be supplied, in this instance use "%d" as the File Manager Path and leave the rest of the fileds blank. Gerenciador de Arquivos @@ -378,6 +380,8 @@ Caminho do Gerenciador de Arquivos Arg para Pasta Arg para Arquivo + The file manager '{0}' could not be located at '{1}'. Would you like to continue? + File Manager Path Error Navegador da Web Padrão @@ -469,6 +473,14 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in 1. Upload log file: {0} 2. Copy below exception message + + File Manager Error + + The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General. + + Error + An error occurred while opening the folder. {0} + Por favor, aguarde... diff --git a/Flow.Launcher/Languages/pt-pt.xaml b/Flow.Launcher/Languages/pt-pt.xaml index cf7312956..4eca2c5c6 100644 --- a/Flow.Launcher/Languages/pt-pt.xaml +++ b/Flow.Launcher/Languages/pt-pt.xaml @@ -362,6 +362,7 @@ Localização dos dados do utilizador As definições e os plugins instalados são guardados na pasta de dados do utilizador. A localização pode variar, tendo em conta se a aplicação está instalada ou no modo portátil Abrir pasta + Avançado Nível de registo Depuração Informação @@ -369,6 +370,7 @@ Selecione o gestor de ficheiros + Saber mais Por favor, especifique a localização do executável do seu gestor de ficheiros e adicione os argumentos necessários. "%d" representa o caminho do diretório a abrir, usado pelo argumento do campo Pasta e para comandos que abrem diretórios específicos. "%f" representa o caminho do ficheiro a abrir, usado pelo argumento do campo Ficheiro e para comandos que abrem ficheiros específicos. Por exemplo, se o gestor de ficheiros utilizar o comando "totalcmd.exe /A c:\windows" para abrir o diretório c:\windows , o caminho para o gestor de ficheiros será totalcmd. exe e os argumentos para a Pasta serão /A "%d". Alguns gestores de ficheiros, como QTTabBar podem apenas exigir que especifique o caminho. Para estes, deve utilizar "%d" como caminho para o gestor de ficheiros e deixar o resto dos campos em branco. Gestor de ficheiros @@ -376,6 +378,8 @@ Caminho do gestor de ficheiros Argumento para pasta Argumento para ficheiro + Não foi possível encontrar o gestor de ficheiros '{0}' em '{1}'. Deseja continuar? + Erro no caminho do gestor de ficheiros Navegador web padrão @@ -467,6 +471,14 @@ Se adicionar o prefixo '@' durante a introdução do atalho, será utilizada qua 1. Carregue o ficheiro de registos: {0} 2. Copie a mensagem abaixo + + Erro do gestor de ficheiros + + Não foi possível encontrar o gestor de ficheiros. Verifique a definição 'Gestor de ficheiros personalizado' em Definições -> Geral. + + Erro + Ocorreu um erro ao abrir a pasta: {0} + Por favor aguarde... diff --git a/Flow.Launcher/Languages/ru.xaml b/Flow.Launcher/Languages/ru.xaml index 69069c5ec..3a63a4ea4 100644 --- a/Flow.Launcher/Languages/ru.xaml +++ b/Flow.Launcher/Languages/ru.xaml @@ -364,6 +364,7 @@ User Data Location User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not. Open Folder + Advanced Log Level Debug Info @@ -371,6 +372,7 @@ Выбор менеджера файлов + Learn more Please specify the file location of the file manager you using and add arguments as required. The "%d" represents the directory path to open for, used by the Arg for Folder field and for commands opening specific directories. The "%f" represents the file path to open for, used by the Arg for File field and for commands opening specific files. For example, if the file manager uses a command such as "totalcmd.exe /A c:\windows" to open the c:\windows directory, the File Manager Path will be totalcmd.exe, and the Arg For Folder will be /A "%d". Certain file managers like QTTabBar may just require a path to be supplied, in this instance use "%d" as the File Manager Path and leave the rest of the fileds blank. Файловый менеджер @@ -378,6 +380,8 @@ Путь к файловому менеджеру Аргумент для папки Аргумент для файла + The file manager '{0}' could not be located at '{1}'. Would you like to continue? + File Manager Path Error Браузер по умолчанию @@ -469,6 +473,14 @@ 1. Upload log file: {0} 2. Copy below exception message + + File Manager Error + + The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General. + + Ошибка + An error occurred while opening the folder. {0} + Пожалуйста, подождите... diff --git a/Flow.Launcher/Languages/sk.xaml b/Flow.Launcher/Languages/sk.xaml index 88ed1c9df..3c47d61fd 100644 --- a/Flow.Launcher/Languages/sk.xaml +++ b/Flow.Launcher/Languages/sk.xaml @@ -364,6 +364,7 @@ Cesta k používateľskému priečinku Nastavenia používateľa a nainštalované pluginy sa ukladajú do používateľského priečinka. Toto umiestnenie sa môže líšiť v závislosti od toho, či je v prenosnom režime alebo nie. Otvoriť priečinok + Rozšírené Úroveň logovania Debug Info @@ -371,6 +372,7 @@ Vyberte správcu súborov + Viac informácií Zadajte umiestnenie súboru správcu súborov, ktorý používate, a podľa potreby pridajte argumenty. "%d" predstavuje cestu k priečinku, ktorý sa má otvoriť, používa sa v poli Arg pre priečinok a pri príkazoch na otvorenie konkrétnych priečinkov. "%f" predstavuje cestu k súboru, ktorá sa má otvoriť a používa sa v poli Arg pre súbor a pri príkazoch na otvorenie konkrétnych súborov. Napríklad, ak správca súborov používa príkaz ako "totalcmd.exe /A c:\windows" na otvorenie priečinka c:\windows, cesta správcu súborov bude totalcmd.exe a Arg pre priečinok bude /A "%d". Niektorí správcovia súborov, ako napríklad QTTabBar, môžu vyžadovať len zadanie cesty, v tomto prípade použite "%d" ako cestu správcu súborov a zvyšok súborov nechajte prázdny. Správca súborov @@ -378,6 +380,8 @@ Cesta k správcovi súborov Arg. pre priečinok Arg. pre súbor + Správca súborov '{0}' sa nenachádza na '{1}'. Chcete pokračovať? + Chyba v ceste k správcovi súborov Predvolený webový prehliadač @@ -445,7 +449,7 @@ Ak pri zadávaní skratky pred ňu pridáte "@", bude sa zhodovať s Zrušiť Resetovať Odstrániť - Aktualizovať + OK Áno Nie Pozadie @@ -469,6 +473,14 @@ Ak pri zadávaní skratky pred ňu pridáte "@", bude sa zhodovať s 1. Nahrajte súbor logu: {0} 2. Skopírujte nižšie uvedenú správu o výnimke + + Chyba správcu súborov + + Zadaný správca súborov sa nenašiel. Skontrolujte nastavenie vlastného správcu súborov v Nastavenia > Všeobecné. + + Chyba + Počas otvárania priečinka sa vyskytla chyba. {0} + Čakajte, prosím... diff --git a/Flow.Launcher/Languages/sr.xaml b/Flow.Launcher/Languages/sr.xaml index 4b3e3bc0c..43f316a38 100644 --- a/Flow.Launcher/Languages/sr.xaml +++ b/Flow.Launcher/Languages/sr.xaml @@ -364,6 +364,7 @@ User Data Location User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not. Open Folder + Advanced Log Level Debug Info @@ -371,6 +372,7 @@ Select File Manager + Learn more Please specify the file location of the file manager you using and add arguments as required. The "%d" represents the directory path to open for, used by the Arg for Folder field and for commands opening specific directories. The "%f" represents the file path to open for, used by the Arg for File field and for commands opening specific files. For example, if the file manager uses a command such as "totalcmd.exe /A c:\windows" to open the c:\windows directory, the File Manager Path will be totalcmd.exe, and the Arg For Folder will be /A "%d". Certain file managers like QTTabBar may just require a path to be supplied, in this instance use "%d" as the File Manager Path and leave the rest of the fileds blank. File Manager @@ -378,6 +380,8 @@ File Manager Path Arg For Folder Arg For File + The file manager '{0}' could not be located at '{1}'. Would you like to continue? + File Manager Path Error Default Web Browser @@ -469,6 +473,14 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in 1. Upload log file: {0} 2. Copy below exception message + + File Manager Error + + The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General. + + Error + An error occurred while opening the folder. {0} + Please wait... diff --git a/Flow.Launcher/Languages/tr.xaml b/Flow.Launcher/Languages/tr.xaml index 665694ace..2f4e4d302 100644 --- a/Flow.Launcher/Languages/tr.xaml +++ b/Flow.Launcher/Languages/tr.xaml @@ -364,6 +364,7 @@ Kullanıcı Verisi Dizini Kullanıcı ayarları ve yüklü eklentiler bu klasörde saklanır. Klasörün konumu taşınabilir moda bağlı olarak değişebilir. Klasörü Aç + Advanced Log Level Debug Info @@ -371,6 +372,7 @@ Dosya Yöneticisi Seçenekleri + Learn more Please specify the file location of the file manager you using and add arguments as required. The "%d" represents the directory path to open for, used by the Arg for Folder field and for commands opening specific directories. The "%f" represents the file path to open for, used by the Arg for File field and for commands opening specific files. For example, if the file manager uses a command such as "totalcmd.exe /A c:\windows" to open the c:\windows directory, the File Manager Path will be totalcmd.exe, and the Arg For Folder will be /A "%d". Certain file managers like QTTabBar may just require a path to be supplied, in this instance use "%d" as the File Manager Path and leave the rest of the fileds blank. Dosya Yöneticisi @@ -378,6 +380,8 @@ Dosya Yöneticisi Yolu Klasör Açarken Dosya Açarken + The file manager '{0}' could not be located at '{1}'. Would you like to continue? + File Manager Path Error İnternet Tarayıcı Seçenekleri @@ -467,6 +471,14 @@ 1. Upload log file: {0} 2. Copy below exception message + + File Manager Error + + The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General. + + Error + An error occurred while opening the folder. {0} + Lütfen bekleyin... diff --git a/Flow.Launcher/Languages/uk-UA.xaml b/Flow.Launcher/Languages/uk-UA.xaml index b3dc2cd16..a7dfcda55 100644 --- a/Flow.Launcher/Languages/uk-UA.xaml +++ b/Flow.Launcher/Languages/uk-UA.xaml @@ -364,6 +364,7 @@ Розташування даних користувача Налаштування користувача та встановлені плагіни зберігаються у теці даних користувача. Це місце може змінюватися залежно від того, чи перебуває програма в портативному режимі, чи ні. Відкрити теку + Advanced Log Level Debug Info @@ -371,6 +372,7 @@ Виберіть файловий менеджер + Learn more Please specify the file location of the file manager you using and add arguments as required. The "%d" represents the directory path to open for, used by the Arg for Folder field and for commands opening specific directories. The "%f" represents the file path to open for, used by the Arg for File field and for commands opening specific files. For example, if the file manager uses a command such as "totalcmd.exe /A c:\windows" to open the c:\windows directory, the File Manager Path will be totalcmd.exe, and the Arg For Folder will be /A "%d". Certain file managers like QTTabBar may just require a path to be supplied, in this instance use "%d" as the File Manager Path and leave the rest of the fileds blank. Файловий менеджер @@ -378,6 +380,8 @@ Шлях до файлового менеджера Аргумент для папки Аргумент для файлу + The file manager '{0}' could not be located at '{1}'. Would you like to continue? + File Manager Path Error Веб-браузер за замовчуванням @@ -469,6 +473,14 @@ 1. Upload log file: {0} 2. Copy below exception message + + File Manager Error + + The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General. + + Помилка + An error occurred while opening the folder. {0} + Будь ласка, зачекайте... diff --git a/Flow.Launcher/Languages/vi.xaml b/Flow.Launcher/Languages/vi.xaml index b7b56213b..c51edaf23 100644 --- a/Flow.Launcher/Languages/vi.xaml +++ b/Flow.Launcher/Languages/vi.xaml @@ -366,6 +366,7 @@ Vị trí dữ liệu người dùng Thiết đặt người dùng và plugin đã cài đặt sẽ được lưu trong thư mục dữ liệu người dùng. Vị trí này có thể thay đổi tùy thuộc vào việc nó có ở chế độ di động hay không. Mở thư mục + Advanced Log Level Debug Info @@ -373,6 +374,7 @@ Chọn trình quản lý tệp + Learn more Please specify the file location of the file manager you using and add arguments as required. The "%d" represents the directory path to open for, used by the Arg for Folder field and for commands opening specific directories. The "%f" represents the file path to open for, used by the Arg for File field and for commands opening specific files. For example, if the file manager uses a command such as "totalcmd.exe /A c:\windows" to open the c:\windows directory, the File Manager Path will be totalcmd.exe, and the Arg For Folder will be /A "%d". Certain file managers like QTTabBar may just require a path to be supplied, in this instance use "%d" as the File Manager Path and leave the rest of the fileds blank. Trình quản lý ngày tháng @@ -380,6 +382,8 @@ Đường dẫn quản lý tệp Đối số cho thư mục Đối số cho tệp + The file manager '{0}' could not be located at '{1}'. Would you like to continue? + File Manager Path Error Trình duyệt web tiêu chuẩn @@ -473,6 +477,14 @@ 1. Upload log file: {0} 2. Copy below exception message + + File Manager Error + + The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General. + + Lỗi + An error occurred while opening the folder. {0} + Cảnh báo nhỏ... diff --git a/Flow.Launcher/Languages/zh-cn.xaml b/Flow.Launcher/Languages/zh-cn.xaml index bd3142992..95a97d5ed 100644 --- a/Flow.Launcher/Languages/zh-cn.xaml +++ b/Flow.Launcher/Languages/zh-cn.xaml @@ -8,9 +8,9 @@ 请选择 {0} 可执行文件 - Your selected {0} executable is invalid. + 您选择的 {0} 可执行文件无效。 {2}{2} - Click yes if you would like select the {0} executable agian. Click no if you would like to download {1} + 如果您希望重新选择 {0} 可执行文件,请点击“是”。如果需要下载 {1},请点击“否” 无法设置 {0} 可执行路径,请尝试从 Flow 的设置中设置(向下滚动到底部)。 无法初始化插件 @@ -18,7 +18,7 @@ 无法注册热键“{0}”。该热键可能正在被其他程序使用。更改为不同的热键,或退出其他程序。 - Failed to unregister hotkey "{0}". Please try again or see log for details + 未能取消注册快捷键"{0}"。请重试或查看日志以获取详细信息 Flow Launcher 启动命令 {0} 失败 无效的 Flow Launcher 插件文件格式 @@ -42,8 +42,8 @@ 游戏模式 暂停使用热键。 重置位置 - Reset search window position - Type here to search + 重置搜索窗口位置 + 在此处输入以搜索 设置 @@ -51,12 +51,12 @@ 便携模式 将所有设置和用户数据存储在一个文件夹中 (可用于可移除驱动器或云服务)。 开机自启 - Use logon task instead of startup entry for faster startup experience - After uninstallation, you need to manually remove this task (Flow.Launcher Startup) via Task Scheduler + 使用登录任务代替启动条目来更快地启动体验 + 卸载后,您需要通过任务计划程序手动移除此任务 (Flow.Launcher Startup) 设置开机自启时出错 失去焦点时自动隐藏 Flow Launcher 不显示新版本提示 - Search Window Location + 搜索窗口位置 记住上次的位置 鼠标光标所在显示器 聚焦窗口所在显示器 @@ -74,8 +74,8 @@ 保留上次搜索关键字 选择上次搜索关键字 清空上次搜索关键字 - Preserve Last Action Keyword - Select Last Action Keyword + 保留最后操作关键词 + 选择最后一个操作关键词 最大结果显示个数 您也可以通过使用 CTRL+ "+" 和 CTRL+ "-" 来快速调整它。 全屏模式下忽略热键 @@ -106,36 +106,36 @@ 始终打开预览 Flow 启动时总是打开预览面板。按 {0} 以切换预览。 当前主题已启用模糊效果,不允许启用阴影效果 - Search Delay - Adds a short delay while typing to reduce UI flicker and result load. Recommended if your typing speed is average. - Enter the wait time (in ms) until input is considered complete. This can only be edited if Search Delay is enabled. - Default Search Delay Time - Wait time before showing results after typing stops. Higher values wait longer. (ms) - Information for Korean IME user + 延迟搜索 + 在输入时添加一个短时间延迟以减少UI闪烁和加载结果的负载。建议您的输入速度是平均的。 + 输入等待时间(毫秒),直到输入被认为完成。这只能在启用搜索延迟时进行编辑。 + 默认搜索延迟时间 + 在输入停止后显示结果之前等待时间。更高的数值等待更长时间(毫秒) + 韩文输入法用户信息 - The Korean input method used in Windows 11 may cause some issues in Flow Launcher. + Windows 11中使用的韩国输入法可能会在Flow Launcher中引起一些问题。 - If you experience any problems, you may need to enable "Use previous version of Korean IME". + 如果您遇到任何问题,您可能需要启用"使用上一个版本的韩语IME"。 - Open Setting in Windows 11 and go to: + Windows 11中的打开设置,转到: - Time & Language > Language & Region > Korean > Language Options > Keyboard - Microsoft IME > Compatibility, + 时间和语言> 语言和区域 > 韩国语言选项 > 键盘-微软IME > 兼容性 - and enable "Use previous version of Microsoft IME". + 并启用"使用之前版本的 Microsoft IME"。 - Open Language and Region System Settings - Opens the Korean IME setting location. Go to Korean > Language Options > Keyboard - Microsoft IME > Compatibility + 打开语言和区域系统设置 + 打开韩语输入法设置位置。转到韩语> 语言选项 > 键盘-微软输入法 > 兼容性 打开 - Use Previous Korean IME - You can change the Previous Korean IME settings directly from here - Home Page - Show home page results when query text is empty. - Show History Results in Home Page - Maximum History Results Shown in Home Page - This can only be edited if plugin supports Home feature and Home Page is enabled. + 使用以前的韩语输入法 + 您可以直接从这里更改前韩语输入法设置 + 首页 + 当查询文本为空时显示主页结果。 + 在主页中显示历史记录 + 在主页显示的最大历史结果数 + 这只能在插件支持主页功能和主页启用时进行编辑。 搜索插件 @@ -152,13 +152,13 @@ 当前触发关键字 新触发关键字 更改触发关键字 - Plugin search delay time - Change Plugin Search Delay Time - Advanced Settings: + 插件搜索延迟时间 + 更改插件搜索延迟时间 + 高级设置: 启用 优先级 - Search Delay - Home Page + 延迟搜索 + 首页 当前优先级 新优先级 优先级 @@ -170,10 +170,10 @@ 版本 官方网站 卸载 - Fail to remove plugin settings - Plugins: {0} - Fail to remove plugin settings files, please remove them manually - Fail to remove plugin cache - Plugins: {0} - Fail to remove plugin cache files, please remove them manually + 移除插件设置失败 + 插件:{0} - 移除插件设置文件失败,请手动删除 + 移除插件缓存失败 + 插件:{0} - 移除插件设置文件失败,请手动删除 插件商店 @@ -210,9 +210,9 @@ 结果标题字体 结果字幕字体 重置 - Reset to the recommended font and size settings. - Import Theme Size - If a size value intended by the theme designer is available, it will be retrieved and applied. + 重置为推荐字体和大小设置。 + 导入主题尺寸 + 如果主题设计器想要的大小值可用,它将被检索和应用。 自定义 窗口模式 透明度 @@ -239,21 +239,21 @@ 自定义 时钟 日期 - Backdrop Type - The backdrop effect is not applied in the preview. - Backdrop supported starting from Windows 11 build 22000 and above + 返回类型 + 预览中没有应用背景效果。 + 自 Windows 11 Build 22000 起支持背景效果 - Acrylic - Mica - Mica Alt - This theme supports two (light/dark) modes. + 亚克力 + 云母 + 云母平替 + 该主题支持两种(浅色/深色)模式。 该主题支持模糊透明背景。 - Show placeholder - Display placeholder when query is empty - Placeholder text - Change placeholder text. Input empty will use: {0} - Fixed Window Size - The window size is not adjustable by dragging. + 显示占位符 + 当查询为空时显示占位符 + 占位符文本 + 更改占位符文本。输入空将使用:{0} + 固定窗口大小 + 窗口高度不能通过拖动来调整。 热键 @@ -313,9 +313,9 @@ 使用 Segoe Fluent 图标 在支持时在选项中显示 Segoe Fluent 图标 按下按键 - Show Result Badges - For supported plugins, badges are displayed to help distinguish them more easily. - Show Result Badges for Global Query Only + 显示结果徽章 + 对于支持的插件,将显示徽章以帮助更容易区分它们。 + 仅在全局查询下显示结果徽章 HTTP 代理 @@ -356,21 +356,23 @@ 日志目录 清除日志 你确定要删除所有的日志吗? - Cache Folder - Clear Caches - Are you sure you want to delete all caches? - Failed to clear part of folders and files. Please see log file for more information + 缓存文件夹 + 清除缓存 + 您确定要删除所有缓存吗? + 无法清除部分文件夹和文件。请查看日志文件以获取更多信息 向导 用户数据位置 用户设置和已安装的插件保存在用户数据文件夹中。此位置可能因是否处于便携模式而异。 打开文件夹 - Log Level - Debug - Info - Setting Window Font + 高级 + 日志等级 + 调试 + 信息 + 设置窗口字体 默认文件管理器 + 了解更多 请指定您使用的文件管理器的文件位置并根据需要添加参数。“%d”表示要打开的目录路径,由文件夹字段的参数和打开特定目录的命令使用。“%f”表示要打开的文件路径,由文件字段的参数和打开特定文件的命令使用。 例如,如果文件管理器使用诸如“totalcmd.exe /A c:\windows”之类的命令来打开 c:\windows 目录,则文件管理器路径将为 totalcmd.exe,文件夹参数将为 /A "%d"。某些文件管理器(如 QTTabBar)可能只需要提供路径,在本例中,使用“%d”作为文件管理器路径,其余字段留空。 文件管理器 @@ -378,6 +380,8 @@ 文件管理器路径 文件夹路径参数 选中文件路径参数 + 文件管理器 '{0}' 不能在 '{1}'中定位。您想要继续吗? + 文件管理器路径错误 默认浏览器 @@ -385,7 +389,7 @@ 浏览器 浏览器名称 浏览器路径 - 新窗户 + 新窗口 新标签 隐身模式 @@ -402,19 +406,19 @@ 找不到指定的插件 新触发关键字不能为空 此触发关键字已经被指派给其他插件了,请换一个关键字 - This new Action Keyword is the same as old, please choose a different one + 此触发关键字已经被指派给其他插件了,请换一个关键字 成功 成功完成 - Failed to copy - Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords. + 复制失败 + 请输入您希望用来启动插件的动作关键字,并使用空格进行分隔。若不想指定任何关键字,可直接输入*,此时插件将在未输入动作关键字的情况下被触发 - Search Delay Time Setting - Input the search delay time in ms you like to use for the plugin. Input empty if you don't want to specify any, and the plugin will use default search delay time. + 搜索延迟时间设置 + 请输入您希望插件使用的搜索延迟时间(单位:毫秒)。若不想指定,可留空,此时插件将采用默认的搜索延迟时间。 - Home Page - Enable the plugin home page state if you like to show the plugin results when query is empty. + 首页 + 如果您想在查询为空时显示插件的结果,请启用插件主页状态。 自定义查询热键 @@ -465,9 +469,17 @@ 发送成功 发送失败 Flow Launcher 出错啦 - Please open new issue in - 1. Upload log file: {0} - 2. Copy below exception message + 请打开新的问题在 + 1. 上传日志文件:{0} + 2. 复制下面的异常消息 + + + 文件管理器错误 + + 找不到指定的文件管理器。请在“设置 > 通用”下检查自定义文件管理器设置。 + + 错误 + 打开文件夹时发生错误。{0} 请稍等... diff --git a/Flow.Launcher/Languages/zh-tw.xaml b/Flow.Launcher/Languages/zh-tw.xaml index 1a71ae135..60531c6aa 100644 --- a/Flow.Launcher/Languages/zh-tw.xaml +++ b/Flow.Launcher/Languages/zh-tw.xaml @@ -364,6 +364,7 @@ User Data Location User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not. Open Folder + Advanced Log Level Debug Info @@ -371,6 +372,7 @@ 選擇檔案管理器 + Learn more Please specify the file location of the file manager you using and add arguments as required. The "%d" represents the directory path to open for, used by the Arg for Folder field and for commands opening specific directories. The "%f" represents the file path to open for, used by the Arg for File field and for commands opening specific files. For example, if the file manager uses a command such as "totalcmd.exe /A c:\windows" to open the c:\windows directory, the File Manager Path will be totalcmd.exe, and the Arg For Folder will be /A "%d". Certain file managers like QTTabBar may just require a path to be supplied, in this instance use "%d" as the File Manager Path and leave the rest of the fileds blank. 檔案管理器 @@ -378,6 +380,8 @@ 檔案管理器路徑 資料夾參數 檔案參數 + The file manager '{0}' could not be located at '{1}'. Would you like to continue? + File Manager Path Error 預設瀏覽器 @@ -469,6 +473,14 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in 1. Upload log file: {0} 2. Copy below exception message + + File Manager Error + + The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General. + + Error + An error occurred while opening the folder. {0} + 請稍後... diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml index 31bc2ba50..9ff38a564 100644 --- a/Flow.Launcher/MainWindow.xaml +++ b/Flow.Launcher/MainWindow.xaml @@ -64,10 +64,6 @@ Key="R" Command="{Binding ReQueryCommand}" Modifiers="Ctrl" /> - + - + @@ -373,7 +373,7 @@ - + @@ -419,7 +419,7 @@ diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs index fb4e4a46f..890ff0414 100644 --- a/Flow.Launcher/MainWindow.xaml.cs +++ b/Flow.Launcher/MainWindow.xaml.cs @@ -103,7 +103,7 @@ namespace Flow.Launcher private void ThemeManager_ActualApplicationThemeChanged(ModernWpf.ThemeManager sender, object args) { - _theme.RefreshFrameAsync(); + _ = _theme.RefreshFrameAsync(); } private void OnSourceInitialized(object sender, EventArgs e) @@ -115,7 +115,7 @@ namespace Flow.Launcher Win32Helper.DisableControlBox(this); } - private async void OnLoaded(object sender, RoutedEventArgs _) + private void OnLoaded(object sender, RoutedEventArgs _) { // Check first launch if (_settings.FirstLaunch) @@ -285,6 +285,7 @@ namespace Flow.Launcher InitializeContextMenu(); break; case nameof(Settings.ShowHomePage): + case nameof(Settings.ShowHistoryResultsForHomePage): if (_viewModel.QueryResultsSelected() && string.IsNullOrEmpty(_viewModel.QueryText)) { _viewModel.QueryResults(); @@ -299,14 +300,14 @@ namespace Flow.Launcher // QueryTextBox.Text change detection (modified to only work when character count is 1 or higher) QueryTextBox.TextChanged += (s, e) => UpdateClockPanelVisibility(); - // Detecting ContextMenu.Visibility changes + // Detecting ResultContextMenu.Visibility changes DependencyPropertyDescriptor - .FromProperty(VisibilityProperty, typeof(ContextMenu)) - .AddValueChanged(ContextMenu, (s, e) => UpdateClockPanelVisibility()); + .FromProperty(VisibilityProperty, typeof(ResultListBox)) + .AddValueChanged(ResultContextMenu, (s, e) => UpdateClockPanelVisibility()); // Detect History.Visibility changes DependencyPropertyDescriptor - .FromProperty(VisibilityProperty, typeof(StackPanel)) + .FromProperty(VisibilityProperty, typeof(ResultListBox)) .AddValueChanged(History, (s, e) => UpdateClockPanelVisibility()); // Initialize query state @@ -1020,7 +1021,7 @@ namespace Flow.Launcher private void UpdateClockPanelVisibility() { - if (QueryTextBox == null || ContextMenu == null || History == null || ClockPanel == null) + if (QueryTextBox == null || ResultContextMenu == null || History == null || ClockPanel == null) { return; } @@ -1035,20 +1036,20 @@ namespace Flow.Launcher }; var animationDuration = TimeSpan.FromMilliseconds(animationLength * 2 / 3); - // ✅ Conditions for showing ClockPanel (No query input & ContextMenu, History are closed) + // ✅ Conditions for showing ClockPanel (No query input / ResultContextMenu & History are closed) var shouldShowClock = QueryTextBox.Text.Length == 0 && - ContextMenu.Visibility != Visibility.Visible && + ResultContextMenu.Visibility != Visibility.Visible && History.Visibility != Visibility.Visible; - // ✅ 1. When ContextMenu opens, immediately set Visibility.Hidden (force hide without animation) - if (ContextMenu.Visibility == Visibility.Visible) + // ✅ 1. When ResultContextMenu opens, immediately set Visibility.Hidden (force hide without animation) + if (ResultContextMenu.Visibility == Visibility.Visible) { _viewModel.ClockPanelVisibility = Visibility.Hidden; _viewModel.ClockPanelOpacity = 0.0; // Set to 0 in case Opacity animation affects it return; } - // ✅ 2. When ContextMenu is closed, keep it Hidden if there's text in the query (remember previous state) + // ✅ 2. When ResultContextMenu is closed, keep it Hidden if there's text in the query (remember previous state) else if (QueryTextBox.Text.Length > 0) { _viewModel.ClockPanelVisibility = Visibility.Hidden; diff --git a/Flow.Launcher/MessageBoxEx.xaml.cs b/Flow.Launcher/MessageBoxEx.xaml.cs index a55aeb811..7296ff4ca 100644 --- a/Flow.Launcher/MessageBoxEx.xaml.cs +++ b/Flow.Launcher/MessageBoxEx.xaml.cs @@ -22,9 +22,6 @@ namespace Flow.Launcher InitializeComponent(); } - public static MessageBoxResult Show(string messageBoxText) - => Show(messageBoxText, string.Empty, MessageBoxButton.OK, MessageBoxImage.None, MessageBoxResult.OK); - public static MessageBoxResult Show( string messageBoxText, string caption = "", @@ -163,6 +160,7 @@ namespace Flow.Launcher private void KeyEsc_OnPress(object sender, ExecutedRoutedEventArgs e) { if (_button == MessageBoxButton.YesNo) + // Follow System.Windows.MessageBox behavior return; else if (_button == MessageBoxButton.OK) _result = MessageBoxResult.OK; @@ -191,6 +189,7 @@ namespace Flow.Launcher private void Button_Cancel(object sender, RoutedEventArgs e) { if (_button == MessageBoxButton.YesNo) + // Follow System.Windows.MessageBox behavior return; else if (_button == MessageBoxButton.OK) _result = MessageBoxResult.OK; diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs index 5b8e8c9af..c06c56039 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Specialized; +using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; @@ -37,6 +38,8 @@ namespace Flow.Launcher { public class PublicAPIInstance : IPublicAPI, IRemovable { + private static readonly string ClassName = nameof(PublicAPIInstance); + private readonly Settings _settings; private readonly MainViewModel _mainVM; @@ -90,6 +93,8 @@ namespace Flow.Launcher public void ShowMainWindow() => _mainVM.Show(); + public void FocusQueryTextBox() => _mainVM.FocusQueryTextBox(); + public void HideMainWindow() => _mainVM.Hide(); public bool IsMainWindowVisible() => _mainVM.MainWindowVisibilityStatus; @@ -313,27 +318,79 @@ namespace Flow.Launcher ((PluginJsonStorage)_pluginJsonStorages[type]).Save(); } - - public void OpenDirectory(string DirectoryPath, string FileNameOrFilePath = null) + + public void OpenDirectory(string directoryPath, string fileNameOrFilePath = null) { - using var explorer = new Process(); - var explorerInfo = _settings.CustomExplorer; - - explorer.StartInfo = new ProcessStartInfo + try { - FileName = explorerInfo.Path.Replace("%d", DirectoryPath), - UseShellExecute = true, - Arguments = FileNameOrFilePath is null - ? explorerInfo.DirectoryArgument.Replace("%d", DirectoryPath) - : explorerInfo.FileArgument - .Replace("%d", DirectoryPath) - .Replace("%f", - Path.IsPathRooted(FileNameOrFilePath) ? FileNameOrFilePath : Path.Combine(DirectoryPath, FileNameOrFilePath) - ) - }; - explorer.Start(); + var explorerInfo = _settings.CustomExplorer; + var explorerPath = explorerInfo.Path.Trim().ToLowerInvariant(); + var targetPath = fileNameOrFilePath is null + ? directoryPath + : Path.IsPathRooted(fileNameOrFilePath) + ? fileNameOrFilePath + : Path.Combine(directoryPath, fileNameOrFilePath); + + if (Path.GetFileNameWithoutExtension(explorerPath) == "explorer") + { + // Windows File Manager + if (fileNameOrFilePath is null) + { + // Only Open the directory + using var explorer = new Process(); + explorer.StartInfo = new ProcessStartInfo + { + FileName = directoryPath, + UseShellExecute = true + }; + explorer.Start(); + } + else + { + // Open the directory and select the file + Win32Helper.OpenFolderAndSelectFile(targetPath); + } + } + else + { + // Custom File Manager + using var explorer = new Process(); + explorer.StartInfo = new ProcessStartInfo + { + FileName = explorerInfo.Path.Replace("%d", directoryPath), + UseShellExecute = true, + Arguments = fileNameOrFilePath is null + ? explorerInfo.DirectoryArgument.Replace("%d", directoryPath) + : explorerInfo.FileArgument + .Replace("%d", directoryPath) + .Replace("%f", targetPath) + }; + explorer.Start(); + } + } + catch (Win32Exception ex) when (ex.NativeErrorCode == 2) + { + LogError(ClassName, "File Manager not found"); + ShowMsgBox( + string.Format(GetTranslation("fileManagerNotFound"), ex.Message), + GetTranslation("fileManagerNotFoundTitle"), + MessageBoxButton.OK, + MessageBoxImage.Error + ); + } + catch (Exception ex) + { + LogException(ClassName, "Failed to open folder", ex); + ShowMsgBox( + string.Format(GetTranslation("folderOpenError"), ex.Message), + GetTranslation("errorTitle"), + MessageBoxButton.OK, + MessageBoxImage.Error + ); + } } + private void OpenUri(Uri uri, bool? inPrivate = null) { if (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps) diff --git a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs index a3b008206..16252086e 100644 --- a/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs +++ b/Flow.Launcher/Resources/Pages/WelcomePage1.xaml.cs @@ -9,20 +9,19 @@ namespace Flow.Launcher.Resources.Pages { public partial class WelcomePage1 { - public Settings Settings { get; private set; } - private WelcomeViewModel _viewModel; + public Settings Settings { get; } = Ioc.Default.GetRequiredService(); + private readonly WelcomeViewModel _viewModel = Ioc.Default.GetRequiredService(); protected override void OnNavigatedTo(NavigationEventArgs e) { - if (!IsInitialized) - { - Settings = Ioc.Default.GetRequiredService(); - _viewModel = Ioc.Default.GetRequiredService(); - InitializeComponent(); - } // Sometimes the navigation is not triggered by button click, // so we need to reset the page number _viewModel.PageNum = 1; + + if (!IsInitialized) + { + InitializeComponent(); + } base.OnNavigatedTo(e); } diff --git a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs index a63edbcda..37767f128 100644 --- a/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs +++ b/Flow.Launcher/Resources/Pages/WelcomePage2.xaml.cs @@ -11,20 +11,19 @@ namespace Flow.Launcher.Resources.Pages { public partial class WelcomePage2 { - public Settings Settings { get; private set; } - private WelcomeViewModel _viewModel; + public Settings Settings { get; } = Ioc.Default.GetRequiredService(); + private readonly WelcomeViewModel _viewModel = Ioc.Default.GetRequiredService(); protected override void OnNavigatedTo(NavigationEventArgs e) { - if (!IsInitialized) - { - Settings = Ioc.Default.GetRequiredService(); - _viewModel = Ioc.Default.GetRequiredService(); - InitializeComponent(); - } // Sometimes the navigation is not triggered by button click, // so we need to reset the page number _viewModel.PageNum = 2; + + if (!IsInitialized) + { + InitializeComponent(); + } base.OnNavigatedTo(e); } diff --git a/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs index 4a6610e61..4c3184f8c 100644 --- a/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs +++ b/Flow.Launcher/Resources/Pages/WelcomePage3.xaml.cs @@ -7,20 +7,19 @@ namespace Flow.Launcher.Resources.Pages { public partial class WelcomePage3 { - public Settings Settings { get; private set; } - private WelcomeViewModel _viewModel; + public Settings Settings { get; } = Ioc.Default.GetRequiredService(); + private readonly WelcomeViewModel _viewModel = Ioc.Default.GetRequiredService(); protected override void OnNavigatedTo(NavigationEventArgs e) { - if (!IsInitialized) - { - Settings = Ioc.Default.GetRequiredService(); - _viewModel = Ioc.Default.GetRequiredService(); - InitializeComponent(); - } // Sometimes the navigation is not triggered by button click, // so we need to reset the page number _viewModel.PageNum = 3; + + if (!IsInitialized) + { + InitializeComponent(); + } base.OnNavigatedTo(e); } } diff --git a/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs index 1ee3284d2..63c9b9a7a 100644 --- a/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs +++ b/Flow.Launcher/Resources/Pages/WelcomePage4.xaml.cs @@ -7,20 +7,19 @@ namespace Flow.Launcher.Resources.Pages { public partial class WelcomePage4 { - public Settings Settings { get; private set; } - private WelcomeViewModel _viewModel; + public Settings Settings { get; } = Ioc.Default.GetRequiredService(); + private readonly WelcomeViewModel _viewModel = Ioc.Default.GetRequiredService(); protected override void OnNavigatedTo(NavigationEventArgs e) { - if (!IsInitialized) - { - Settings = Ioc.Default.GetRequiredService(); - _viewModel = Ioc.Default.GetRequiredService(); - InitializeComponent(); - } // Sometimes the navigation is not triggered by button click, // so we need to reset the page number _viewModel.PageNum = 4; + + if (!IsInitialized) + { + InitializeComponent(); + } base.OnNavigatedTo(e); } } diff --git a/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs b/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs index 6328c9914..8db0a9f7e 100644 --- a/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs +++ b/Flow.Launcher/Resources/Pages/WelcomePage5.xaml.cs @@ -10,20 +10,19 @@ namespace Flow.Launcher.Resources.Pages { public partial class WelcomePage5 { - public Settings Settings { get; private set; } - private WelcomeViewModel _viewModel; + public Settings Settings { get; } = Ioc.Default.GetRequiredService(); + private readonly WelcomeViewModel _viewModel = Ioc.Default.GetRequiredService(); protected override void OnNavigatedTo(NavigationEventArgs e) { - if (!IsInitialized) - { - Settings = Ioc.Default.GetRequiredService(); - _viewModel = Ioc.Default.GetRequiredService(); - InitializeComponent(); - } // Sometimes the navigation is not triggered by button click, // so we need to reset the page number _viewModel.PageNum = 5; + + if (!IsInitialized) + { + InitializeComponent(); + } base.OnNavigatedTo(e); } diff --git a/Flow.Launcher/SelectBrowserWindow.xaml b/Flow.Launcher/SelectBrowserWindow.xaml index 4a0928dc2..d51d597b7 100644 --- a/Flow.Launcher/SelectBrowserWindow.xaml +++ b/Flow.Launcher/SelectBrowserWindow.xaml @@ -6,10 +6,11 @@ xmlns:local="clr-namespace:Flow.Launcher" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:ui="http://schemas.modernwpf.com/2019" + xmlns:vm="clr-namespace:Flow.Launcher.ViewModel" Title="{DynamicResource defaultBrowserTitle}" Width="550" + d:DataContext="{d:DesignInstance vm:SelectBrowserViewModel}" Background="{DynamicResource PopuBGColor}" - DataContext="{Binding RelativeSource={RelativeSource Self}}" Foreground="{DynamicResource PopupTextColor}" ResizeMode="NoResize" SizeToContent="Height" @@ -97,11 +98,11 @@