Merge branch 'dev' into rename-quick-access-links

This commit is contained in:
Jack Ye 2025-06-07 13:39:00 +08:00 committed by GitHub
commit 37cab1b30c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
107 changed files with 2323 additions and 1374 deletions

View file

@ -16,6 +16,8 @@ body:
I have checked that this issue has not already been reported.
- label: >
I am using the latest version of Flow Launcher.
- label: >
I am using the prerelease version of Flow Launcher.
- type: textarea
attributes:

242
.github/update_release_pr.py vendored Normal file
View file

@ -0,0 +1,242 @@
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. Filter is not applied when empty string.
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. Filter is not applied when empty string.
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 state in [pr["state"], "all"] and (not label or [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 filter on'} label and state as {state}")
return pr_list
def get_prs_assignees(pull_request_items: list[dict], label: str = "", state: str = "all") -> list[str]:
"""
Returns a list of pull request assignees after applying the label and state filters, excludes jjw24.
Args:
pull_request_items (list[dict]): List of PR items.
label (str): The label name. Filter is not applied when empty string.
state (str): State of PR, e.g. open, closed, all
Returns:
list: A list of strs, where each string is an assignee name. List is not distinct, so can contain
duplicate names.
Returns an empty list if none are found.
"""
assignee_list = []
for pr in pull_request_items:
if state in [pr["state"], "all"] and (not label or [item for item in pr["labels"] if item["name"] == label]):
[assignee_list.append(assignee["login"]) for assignee in pr["assignees"] if assignee["login"] != "jjw24" ]
print(f"Found {len(assignee_list)} assignees with {label if label else 'no filter on'} label and state as {state}")
return assignee_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 ""
assignees = list(set(get_prs_assignees(pull_requests, "enhancement", "closed") + get_prs_assignees(pull_requests, "bug", "closed")))
assignees.sort(key=str.lower)
description_content += f"### Authors:\n{', '.join(assignees)}"
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}")

View file

@ -3,11 +3,10 @@ name: Publish Default Plugins
on:
push:
branches: ['master']
paths: ['Plugins/**']
workflow_dispatch:
jobs:
build:
publish:
runs-on: windows-latest
steps:
@ -17,39 +16,24 @@ jobs:
with:
dotnet-version: 7.0.x
- name: Determine New Plugin Updates
uses: dorny/paths-filter@v3
id: changes
with:
filters: |
browserbookmark:
- 'Plugins/Flow.Launcher.Plugin.BrowserBookmark/plugin.json'
calculator:
- 'Plugins/Flow.Launcher.Plugin.Calculator/plugin.json'
explorer:
- 'Plugins/Flow.Launcher.Plugin.Explorer/plugin.json'
pluginindicator:
- 'Plugins/Flow.Launcher.Plugin.PluginIndicator/plugin.json'
pluginsmanager:
- 'Plugins/Flow.Launcher.Plugin.PluginsManager/plugin.json'
processkiller:
- 'Plugins/Flow.Launcher.Plugin.ProcessKiller/plugin.json'
program:
- 'Plugins/Flow.Launcher.Plugin.Program/plugin.json'
shell:
- 'Plugins/Flow.Launcher.Plugin.Shell/plugin.json'
sys:
- 'Plugins/Flow.Launcher.Plugin.Sys/plugin.json'
url:
- 'Plugins/Flow.Launcher.Plugin.Url/plugin.json'
websearch:
- 'Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json'
windowssettings:
- 'Plugins/Flow.Launcher.Plugin.WindowsSettings/plugin.json'
base: 'master'
- name: Update Plugins To Production Version
run: |
$version = "1.0.0"
Get-Content appveyor.yml | ForEach-Object {
if ($_ -match "version:\s*'(\d+\.\d+\.\d+)\.") {
$version = $matches[1]
}
}
$jsonFiles = Get-ChildItem -Path ".\Plugins\*\plugin.json"
foreach ($file in $jsonFiles) {
$plugin_old_ver = Get-Content $file.FullName -Raw | ConvertFrom-Json
(Get-Content $file) -replace '"Version"\s*:\s*".*?"', "`"Version`": `"$version`"" | Set-Content $file
$plugin_new_ver = Get-Content $file.FullName -Raw | ConvertFrom-Json
Write-Host "Updated" $plugin_old_ver.Name "version from" $plugin_old_ver.Version "to" $plugin_new_ver.Version
}
- name: Get BrowserBookmark Version
if: steps.changes.outputs.browserbookmark == 'true'
id: updated-version-browserbookmark
uses: notiz-dev/github-action-json-property@release
with:
@ -57,14 +41,12 @@ jobs:
prop_path: 'Version'
- name: Build BrowserBookmark
if: steps.changes.outputs.browserbookmark == 'true'
run: |
dotnet publish 'Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj' --framework net7.0-windows -c Release -o "Flow.Launcher.Plugin.BrowserBookmark"
7z a -tzip "Flow.Launcher.Plugin.BrowserBookmark.zip" "./Flow.Launcher.Plugin.BrowserBookmark/*"
rm -r "Flow.Launcher.Plugin.BrowserBookmark"
- name: Publish BrowserBookmark
if: steps.changes.outputs.browserbookmark == 'true'
uses: softprops/action-gh-release@v2
with:
repository: "Flow-Launcher/Flow.Launcher.Plugin.BrowserBookmark"
@ -76,7 +58,6 @@ jobs:
- name: Get Calculator Version
if: steps.changes.outputs.calculator == 'true'
id: updated-version-calculator
uses: notiz-dev/github-action-json-property@release
with:
@ -84,14 +65,12 @@ jobs:
prop_path: 'Version'
- name: Build Calculator
if: steps.changes.outputs.calculator == 'true'
run: |
dotnet publish 'Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj' --framework net7.0-windows -c Release -o "Flow.Launcher.Plugin.Calculator"
7z a -tzip "Flow.Launcher.Plugin.Calculator.zip" "./Flow.Launcher.Plugin.Calculator/*"
rm -r "Flow.Launcher.Plugin.Calculator"
- name: Publish Calculator
if: steps.changes.outputs.calculator == 'true'
uses: softprops/action-gh-release@v2
with:
repository: "Flow-Launcher/Flow.Launcher.Plugin.Calculator"
@ -103,7 +82,6 @@ jobs:
- name: Get Explorer Version
if: steps.changes.outputs.explorer == 'true'
id: updated-version-explorer
uses: notiz-dev/github-action-json-property@release
with:
@ -111,14 +89,12 @@ jobs:
prop_path: 'Version'
- name: Build Explorer
if: steps.changes.outputs.explorer == 'true'
run: |
dotnet publish 'Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj' --framework net7.0-windows -c Release -o "Flow.Launcher.Plugin.Explorer"
7z a -tzip "Flow.Launcher.Plugin.Explorer.zip" "./Flow.Launcher.Plugin.Explorer/*"
rm -r "Flow.Launcher.Plugin.Explorer"
- name: Publish Explorer
if: steps.changes.outputs.explorer == 'true'
uses: softprops/action-gh-release@v2
with:
repository: "Flow-Launcher/Flow.Launcher.Plugin.Explorer"
@ -130,7 +106,6 @@ jobs:
- name: Get PluginIndicator Version
if: steps.changes.outputs.pluginindicator == 'true'
id: updated-version-pluginindicator
uses: notiz-dev/github-action-json-property@release
with:
@ -138,14 +113,12 @@ jobs:
prop_path: 'Version'
- name: Build PluginIndicator
if: steps.changes.outputs.pluginindicator == 'true'
run: |
dotnet publish 'Plugins/Flow.Launcher.Plugin.PluginIndicator/Flow.Launcher.Plugin.PluginIndicator.csproj' --framework net7.0-windows -c Release -o "Flow.Launcher.Plugin.PluginIndicator"
7z a -tzip "Flow.Launcher.Plugin.PluginIndicator.zip" "./Flow.Launcher.Plugin.PluginIndicator/*"
rm -r "Flow.Launcher.Plugin.PluginIndicator"
- name: Publish PluginIndicator
if: steps.changes.outputs.pluginindicator == 'true'
uses: softprops/action-gh-release@v2
with:
repository: "Flow-Launcher/Flow.Launcher.Plugin.PluginIndicator"
@ -157,7 +130,6 @@ jobs:
- name: Get PluginsManager Version
if: steps.changes.outputs.pluginsmanager == 'true'
id: updated-version-pluginsmanager
uses: notiz-dev/github-action-json-property@release
with:
@ -165,14 +137,12 @@ jobs:
prop_path: 'Version'
- name: Build PluginsManager
if: steps.changes.outputs.pluginsmanager == 'true'
run: |
dotnet publish 'Plugins/Flow.Launcher.Plugin.PluginsManager/Flow.Launcher.Plugin.PluginsManager.csproj' --framework net7.0-windows -c Release -o "Flow.Launcher.Plugin.PluginsManager"
7z a -tzip "Flow.Launcher.Plugin.PluginsManager.zip" "./Flow.Launcher.Plugin.PluginsManager/*"
rm -r "Flow.Launcher.Plugin.PluginsManager"
- name: Publish PluginsManager
if: steps.changes.outputs.pluginsmanager == 'true'
uses: softprops/action-gh-release@v2
with:
repository: "Flow-Launcher/Flow.Launcher.Plugin.PluginsManager"
@ -184,7 +154,6 @@ jobs:
- name: Get ProcessKiller Version
if: steps.changes.outputs.processkiller == 'true'
id: updated-version-processkiller
uses: notiz-dev/github-action-json-property@release
with:
@ -192,14 +161,12 @@ jobs:
prop_path: 'Version'
- name: Build ProcessKiller
if: steps.changes.outputs.processkiller == 'true'
run: |
dotnet publish 'Plugins/Flow.Launcher.Plugin.ProcessKiller/Flow.Launcher.Plugin.ProcessKiller.csproj' --framework net7.0-windows -c Release -o "Flow.Launcher.Plugin.ProcessKiller"
7z a -tzip "Flow.Launcher.Plugin.ProcessKiller.zip" "./Flow.Launcher.Plugin.ProcessKiller/*"
rm -r "Flow.Launcher.Plugin.ProcessKiller"
- name: Publish ProcessKiller
if: steps.changes.outputs.processkiller == 'true'
uses: softprops/action-gh-release@v2
with:
repository: "Flow-Launcher/Flow.Launcher.Plugin.ProcessKiller"
@ -211,7 +178,6 @@ jobs:
- name: Get Program Version
if: steps.changes.outputs.program == 'true'
id: updated-version-program
uses: notiz-dev/github-action-json-property@release
with:
@ -219,14 +185,12 @@ jobs:
prop_path: 'Version'
- name: Build Program
if: steps.changes.outputs.program == 'true'
run: |
dotnet publish 'Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj' --framework net7.0-windows10.0.19041.0 -c Release -o "Flow.Launcher.Plugin.Program"
7z a -tzip "Flow.Launcher.Plugin.Program.zip" "./Flow.Launcher.Plugin.Program/*"
rm -r "Flow.Launcher.Plugin.Program"
- name: Publish Program
if: steps.changes.outputs.program == 'true'
uses: softprops/action-gh-release@v2
with:
repository: "Flow-Launcher/Flow.Launcher.Plugin.Program"
@ -238,7 +202,6 @@ jobs:
- name: Get Shell Version
if: steps.changes.outputs.shell == 'true'
id: updated-version-shell
uses: notiz-dev/github-action-json-property@release
with:
@ -246,14 +209,12 @@ jobs:
prop_path: 'Version'
- name: Build Shell
if: steps.changes.outputs.shell == 'true'
run: |
dotnet publish 'Plugins/Flow.Launcher.Plugin.Shell/Flow.Launcher.Plugin.Shell.csproj' --framework net7.0-windows -c Release -o "Flow.Launcher.Plugin.Shell"
7z a -tzip "Flow.Launcher.Plugin.Shell.zip" "./Flow.Launcher.Plugin.Shell/*"
rm -r "Flow.Launcher.Plugin.Shell"
- name: Publish Shell
if: steps.changes.outputs.shell == 'true'
uses: softprops/action-gh-release@v2
with:
repository: "Flow-Launcher/Flow.Launcher.Plugin.Shell"
@ -265,7 +226,6 @@ jobs:
- name: Get Sys Version
if: steps.changes.outputs.sys == 'true'
id: updated-version-sys
uses: notiz-dev/github-action-json-property@release
with:
@ -273,14 +233,12 @@ jobs:
prop_path: 'Version'
- name: Build Sys
if: steps.changes.outputs.sys == 'true'
run: |
dotnet publish 'Plugins/Flow.Launcher.Plugin.Sys/Flow.Launcher.Plugin.Sys.csproj' --framework net7.0-windows -c Release -o "Flow.Launcher.Plugin.Sys"
7z a -tzip "Flow.Launcher.Plugin.Sys.zip" "./Flow.Launcher.Plugin.Sys/*"
rm -r "Flow.Launcher.Plugin.Sys"
- name: Publish Sys
if: steps.changes.outputs.sys == 'true'
uses: softprops/action-gh-release@v2
with:
repository: "Flow-Launcher/Flow.Launcher.Plugin.Sys"
@ -292,7 +250,6 @@ jobs:
- name: Get Url Version
if: steps.changes.outputs.url == 'true'
id: updated-version-url
uses: notiz-dev/github-action-json-property@release
with:
@ -300,14 +257,12 @@ jobs:
prop_path: 'Version'
- name: Build Url
if: steps.changes.outputs.url == 'true'
run: |
dotnet publish 'Plugins/Flow.Launcher.Plugin.Url/Flow.Launcher.Plugin.Url.csproj' --framework net7.0-windows -c Release -o "Flow.Launcher.Plugin.Url"
7z a -tzip "Flow.Launcher.Plugin.Url.zip" "./Flow.Launcher.Plugin.Url/*"
rm -r "Flow.Launcher.Plugin.Url"
- name: Publish Url
if: steps.changes.outputs.url == 'true'
uses: softprops/action-gh-release@v2
with:
repository: "Flow-Launcher/Flow.Launcher.Plugin.Url"
@ -319,7 +274,6 @@ jobs:
- name: Get WebSearch Version
if: steps.changes.outputs.websearch == 'true'
id: updated-version-websearch
uses: notiz-dev/github-action-json-property@release
with:
@ -327,14 +281,12 @@ jobs:
prop_path: 'Version'
- name: Build WebSearch
if: steps.changes.outputs.websearch == 'true'
run: |
dotnet publish 'Plugins/Flow.Launcher.Plugin.WebSearch/Flow.Launcher.Plugin.WebSearch.csproj' --framework net7.0-windows -c Release -o "Flow.Launcher.Plugin.WebSearch"
7z a -tzip "Flow.Launcher.Plugin.WebSearch.zip" "./Flow.Launcher.Plugin.WebSearch/*"
rm -r "Flow.Launcher.Plugin.WebSearch"
- name: Publish WebSearch
if: steps.changes.outputs.websearch == 'true'
uses: softprops/action-gh-release@v2
with:
repository: "Flow-Launcher/Flow.Launcher.Plugin.WebSearch"
@ -346,7 +298,6 @@ jobs:
- name: Get WindowsSettings Version
if: steps.changes.outputs.windowssettings == 'true'
id: updated-version-windowssettings
uses: notiz-dev/github-action-json-property@release
with:
@ -354,14 +305,12 @@ jobs:
prop_path: 'Version'
- name: Build WindowsSettings
if: steps.changes.outputs.windowssettings == 'true'
run: |
dotnet publish 'Plugins/Flow.Launcher.Plugin.WindowsSettings/Flow.Launcher.Plugin.WindowsSettings.csproj' --framework net7.0-windows -c Release -o "Flow.Launcher.Plugin.WindowsSettings"
7z a -tzip "Flow.Launcher.Plugin.WindowsSettings.zip" "./Flow.Launcher.Plugin.WindowsSettings/*"
rm -r "Flow.Launcher.Plugin.WindowsSettings"
- name: Publish WindowsSettings
if: steps.changes.outputs.windowssettings == 'true'
uses: softprops/action-gh-release@v2
with:
repository: "Flow-Launcher/Flow.Launcher.Plugin.WindowsSettings"

25
.github/workflows/release_pr.yml vendored Normal file
View file

@ -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

View file

@ -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);
}

View file

@ -16,7 +16,8 @@ namespace Flow.Launcher.Core.Plugin
Search = string.Empty,
RawQuery = string.Empty,
SearchTerms = Array.Empty<string>(),
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
};
}
}

View file

@ -671,7 +671,15 @@ namespace Flow.Launcher.Core.Resource
windowBorderStyle.Setters.Remove(windowBorderStyle.Setters.OfType<Setter>().FirstOrDefault(x => x.Property.Name == "Background"));
windowBorderStyle.Setters.Add(new Setter(Border.BackgroundProperty, new SolidColorBrush(Colors.Transparent)));
}
// For themes with blur enabled, the window border is rendered by the system, so it's treated as a simple rectangle regardless of thickness.
//(This is to avoid issues when the window is forcibly changed to a rectangular shape during snap scenarios.)
var cornerRadiusSetter = windowBorderStyle.Setters.OfType<Setter>().FirstOrDefault(x => x.Property == Border.CornerRadiusProperty);
if (cornerRadiusSetter != null)
cornerRadiusSetter.Value = new CornerRadius(0);
else
windowBorderStyle.Setters.Add(new Setter(Border.CornerRadiusProperty, new CornerRadius(0)));
// Apply the blur effect
Win32Helper.DWMSetBackdropForWindow(mainWindow, backdropType);
ColorizeWindow(theme, backdropType);

View file

@ -182,7 +182,6 @@ namespace Flow.Launcher.Infrastructure.Http
public static Task<Stream> GetStreamAsync([NotNull] string url,
CancellationToken token = default) => GetStreamAsync(new Uri(url), token);
/// <summary>
/// Send a GET request to the specified Uri with an HTTP completion option and a cancellation token as an asynchronous operation.
/// </summary>
@ -212,7 +211,14 @@ namespace Flow.Launcher.Infrastructure.Http
/// </summary>
public static async Task<HttpResponseMessage> 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);
}
}
}
}

View file

@ -22,7 +22,7 @@ SystemParametersInfo
SetForegroundWindow
GetWindowLong
WINDOW_LONG_PTR_INDEX
GetForegroundWindow
GetDesktopWindow
GetShellWindow
@ -42,6 +42,11 @@ MONITORINFOEXW
WM_ENTERSIZEMOVE
WM_EXITSIZEMOVE
WM_NCLBUTTONDBLCLK
WM_SYSCOMMAND
SC_MAXIMIZE
SC_MINIMIZE
OleInitialize
OleUninitialize

View file

@ -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);
}
}

View file

@ -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";
@ -426,6 +427,8 @@ namespace Flow.Launcher.Infrastructure.UserSettings
list.Add(new(SelectPrevItemHotkey2, "SelectPrevItemHotkey", () => SelectPrevItemHotkey2 = ""));
if (!string.IsNullOrEmpty(SettingWindowHotkey))
list.Add(new(SettingWindowHotkey, "SettingWindowHotkey", () => SettingWindowHotkey = ""));
if (!string.IsNullOrEmpty(OpenHistoryHotkey))
list.Add(new(OpenHistoryHotkey, "OpenHistoryHotkey", () => OpenHistoryHotkey = ""));
if (!string.IsNullOrEmpty(OpenContextMenuHotkey))
list.Add(new(OpenContextMenuHotkey, "OpenContextMenuHotkey", () => OpenContextMenuHotkey = ""));
if (!string.IsNullOrEmpty(SelectNextPageHotkey))
@ -461,7 +464,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"),

View file

@ -194,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());
@ -204,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
@ -324,6 +324,11 @@ namespace Flow.Launcher.Infrastructure
public const int WM_ENTERSIZEMOVE = (int)PInvoke.WM_ENTERSIZEMOVE;
public const int WM_EXITSIZEMOVE = (int)PInvoke.WM_EXITSIZEMOVE;
public const int WM_NCLBUTTONDBLCLK = (int)PInvoke.WM_NCLBUTTONDBLCLK;
public const int WM_SYSCOMMAND = (int)PInvoke.WM_SYSCOMMAND;
public const int SC_MAXIMIZE = (int)PInvoke.SC_MAXIMIZE;
public const int SC_MINIMIZE = (int)PInvoke.SC_MINIMIZE;
#endregion

View file

@ -14,10 +14,10 @@
</PropertyGroup>
<PropertyGroup>
<Version>4.4.0</Version>
<PackageVersion>4.4.0</PackageVersion>
<AssemblyVersion>4.4.0</AssemblyVersion>
<FileVersion>4.4.0</FileVersion>
<Version>4.5.0</Version>
<PackageVersion>4.5.0</PackageVersion>
<AssemblyVersion>4.5.0</AssemblyVersion>
<FileVersion>4.5.0</FileVersion>
<PackageId>Flow.Launcher.Plugin</PackageId>
<Authors>Flow-Launcher</Authors>
<PackageLicenseExpression>MIT</PackageLicenseExpression>

View file

@ -21,6 +21,11 @@ namespace Flow.Launcher.Plugin
/// </summary>
public bool IsReQuery { get; internal set; } = false;
/// <summary>
/// Determines whether the query is a home query.
/// </summary>
public bool IsHomeQuery { get; internal init; } = false;
/// <summary>
/// Search part of a query.
/// This will not include action keyword if exclusive plugin gets it, otherwise it should be same as RawQuery.

View file

@ -1,8 +1,9 @@
using Microsoft.Win32;
using System;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Microsoft.Win32;
namespace Flow.Launcher.Plugin.SharedCommands
{
@ -13,7 +14,7 @@ namespace Flow.Launcher.Plugin.SharedCommands
{
private static string GetDefaultBrowserPath()
{
string name = string.Empty;
var name = string.Empty;
try
{
using var regDefault = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice", false);
@ -23,8 +24,7 @@ namespace Flow.Launcher.Plugin.SharedCommands
name = regKey.GetValue(null).ToString().ToLower().Replace("\"", "");
if (!name.EndsWith("exe"))
name = name.Substring(0, name.LastIndexOf(".exe") + 4);
name = name[..(name.LastIndexOf(".exe") + 4)];
}
catch
{
@ -65,12 +65,21 @@ namespace Flow.Launcher.Plugin.SharedCommands
{
Process.Start(psi)?.Dispose();
}
catch (System.ComponentModel.Win32Exception)
// This error may be thrown if browser path is incorrect
catch (Win32Exception)
{
Process.Start(new ProcessStartInfo
try
{
FileName = url, UseShellExecute = true
});
Process.Start(new ProcessStartInfo
{
FileName = url,
UseShellExecute = true
});
}
catch
{
throw; // Re-throw the exception if we cannot open the URL in the default browser
}
}
}
@ -100,12 +109,20 @@ namespace Flow.Launcher.Plugin.SharedCommands
Process.Start(psi)?.Dispose();
}
// This error may be thrown if browser path is incorrect
catch (System.ComponentModel.Win32Exception)
catch (Win32Exception)
{
Process.Start(new ProcessStartInfo
try
{
FileName = url, UseShellExecute = true
});
Process.Start(new ProcessStartInfo
{
FileName = url,
UseShellExecute = true
});
}
catch
{
throw; // Re-throw the exception if we cannot open the URL in the default browser
}
}
}
}

View file

@ -1,20 +1,21 @@
using System;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Exception;
using Flow.Launcher.Infrastructure.Logger;
using NLog;
namespace Flow.Launcher.Helper;
public static class ErrorReporting
{
private static void Report(Exception e, [CallerMemberName] string methodName = "UnHandledException")
private static void Report(Exception e, bool silent = false, [CallerMemberName] string methodName = "UnHandledException")
{
var logger = LogManager.GetLogger(methodName);
logger.Fatal(ExceptionFormatter.FormatExcpetion(e));
if (silent) return;
var reportWindow = new ReportWindow(e);
reportWindow.Show();
}
@ -35,8 +36,9 @@ public static class ErrorReporting
public static void TaskSchedulerUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
// handle unobserved task exceptions on UI thread
Application.Current.Dispatcher.Invoke(() => Report(e.Exception));
// log exception but do not handle unobserved task exceptions on UI thread
//Application.Current.Dispatcher.Invoke(() => Report(e.Exception, true));
Log.Exception(nameof(ErrorReporting), "Unobserved task exception occurred.", e.Exception);
// prevent application exit, so the user can copy the prompted error info
e.SetObserved();
}

View file

@ -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;

View file

@ -364,6 +364,7 @@
<system:String x:Key="userdatapath">موقع بيانات المستخدم</system:String>
<system:String x:Key="userdatapathToolTip">يتم حفظ إعدادات المستخدم والإضافات المثبتة في مجلد بيانات المستخدم. قد يختلف هذا الموقع اعتمادًا على ما إذا كان في وضع النقل أم لا.</system:String>
<system:String x:Key="userdatapathButton">فتح المجلد</system:String>
<system:String x:Key="advanced">Advanced</system:String>
<system:String x:Key="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>

View file

@ -364,6 +364,7 @@
<system:String x:Key="userdatapath">User Data Location</system:String>
<system:String x:Key="userdatapathToolTip">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.</system:String>
<system:String x:Key="userdatapathButton">Open Folder</system:String>
<system:String x:Key="advanced">Advanced</system:String>
<system:String x:Key="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>

View file

@ -364,6 +364,7 @@
<system:String x:Key="userdatapath">User Data Location</system:String>
<system:String x:Key="userdatapathToolTip">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.</system:String>
<system:String x:Key="userdatapathButton">Open Folder</system:String>
<system:String x:Key="advanced">Advanced</system:String>
<system:String x:Key="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>

View file

@ -42,8 +42,8 @@
<system:String x:Key="GameMode">Spielmodus</system:String>
<system:String x:Key="GameModeToolTip">Aussetzen der Verwendung von Hotkeys.</system:String>
<system:String x:Key="PositionReset">Position zurücksetzen</system:String>
<system:String x:Key="PositionResetToolTip">Reset search window position</system:String>
<system:String x:Key="queryTextBoxPlaceholder">Type here to search</system:String>
<system:String x:Key="PositionResetToolTip">Position des Suchfensters zurücksetzen</system:String>
<system:String x:Key="queryTextBoxPlaceholder">Zum Suchen hier tippen</system:String>
<!-- Setting General -->
<system:String x:Key="flowlauncher_settings">Einstellungen</system:String>
@ -126,12 +126,12 @@
</system:String>
<system:String x:Key="KoreanImeOpenLink">Open Language and Region System Settings</system:String>
<system:String x:Key="KoreanImeOpenLink">Sprach- und Regionen-Systemeinstellungen öffnen</system:String>
<system:String x:Key="KoreanImeOpenLinkToolTip">Opens the Korean IME setting location. Go to Korean &gt; Language Options &gt; Keyboard - Microsoft IME &gt; Compatibility</system:String>
<system:String x:Key="KoreanImeOpenLinkButton">Öffnen</system:String>
<system:String x:Key="KoreanImeRegistry">Use Previous Korean IME</system:String>
<system:String x:Key="KoreanImeRegistry">Vorherige koreanische IME verwenden</system:String>
<system:String x:Key="KoreanImeRegistryTooltip">You can change the Previous Korean IME settings directly from here</system:String>
<system:String x:Key="homePage">Home Page</system:String>
<system:String x:Key="homePage">Homepage</system:String>
<system:String x:Key="homePageToolTip">Show home page results when query text is empty.</system:String>
<system:String x:Key="historyResultsForHomePage">Show History Results in Home Page</system:String>
<system:String x:Key="historyResultsCountForHomePage">Maximum History Results Shown in Home Page</system:String>
@ -154,11 +154,11 @@
<system:String x:Key="actionKeywordsTooltip">Aktions-Schlüsselwörter ändern</system:String>
<system:String x:Key="pluginSearchDelayTime">Plugin search delay time</system:String>
<system:String x:Key="pluginSearchDelayTimeTooltip">Change Plugin Search Delay Time</system:String>
<system:String x:Key="FilterComboboxLabel">Advanced Settings:</system:String>
<system:String x:Key="FilterComboboxLabel">Erweiterte Einstellungen</system:String>
<system:String x:Key="DisplayModeOnOff">Aktiviert</system:String>
<system:String x:Key="DisplayModePriority">Priorität</system:String>
<system:String x:Key="DisplayModeSearchDelay">Search Delay</system:String>
<system:String x:Key="DisplayModeHomeOnOff">Home Page</system:String>
<system:String x:Key="DisplayModeHomeOnOff">Homepage</system:String>
<system:String x:Key="currentPriority">Aktuelle Priorität</system:String>
<system:String x:Key="newPriority">Neue Priorität</system:String>
<system:String x:Key="priority">Priorität</system:String>
@ -246,13 +246,13 @@
<system:String x:Key="BackdropTypesAcrylic">Acrylic</system:String>
<system:String x:Key="BackdropTypesMica">Mica</system:String>
<system:String x:Key="BackdropTypesMicaAlt">Mica Alt</system:String>
<system:String x:Key="TypeIsDarkToolTip">This theme supports two (light/dark) modes.</system:String>
<system:String x:Key="TypeIsDarkToolTip">Dieses Theme unterstützt zwei Modi (hell/dunkel).</system:String>
<system:String x:Key="TypeHasBlurToolTip">Dieses Theme unterstützt Unschärfe und transparenten Hintergrund.</system:String>
<system:String x:Key="ShowPlaceholder">Show placeholder</system:String>
<system:String x:Key="ShowPlaceholder">Platzhalter zeigen</system:String>
<system:String x:Key="ShowPlaceholderTip">Display placeholder when query is empty</system:String>
<system:String x:Key="PlaceholderText">Placeholder text</system:String>
<system:String x:Key="PlaceholderText">Platzhaltertext</system:String>
<system:String x:Key="PlaceholderTextTip">Change placeholder text. Input empty will use: {0}</system:String>
<system:String x:Key="KeepMaxResults">Fixed Window Size</system:String>
<system:String x:Key="KeepMaxResults">Festgelegte Fenstergröße</system:String>
<system:String x:Key="KeepMaxResultsToolTip">The window size is not adjustable by dragging.</system:String>
<!-- Setting Hotkey -->
@ -313,7 +313,7 @@
<system:String x:Key="useGlyphUI">Segoe Fluent-Icons verwenden</system:String>
<system:String x:Key="useGlyphUIEffect">Segoe Fluent-Icons für Abfrageergebnisse verwenden, wo unterstützt</system:String>
<system:String x:Key="flowlauncherPressHotkey">Taste drücken</system:String>
<system:String x:Key="showBadges">Show Result Badges</system:String>
<system:String x:Key="showBadges">Ergebnis-Badges zeigen</system:String>
<system:String x:Key="showBadgesToolTip">For supported plugins, badges are displayed to help distinguish them more easily.</system:String>
<system:String x:Key="showBadgesGlobalOnly">Show Result Badges for Global Query Only</system:String>
@ -356,14 +356,15 @@
<system:String x:Key="logfolder">Ordner »Logs«</system:String>
<system:String x:Key="clearlogfolder">Logs löschen</system:String>
<system:String x:Key="clearlogfolderMessage">Sind Sie sicher, dass Sie alle Logs löschen wollen?</system:String>
<system:String x:Key="cachefolder">Cache Folder</system:String>
<system:String x:Key="clearcachefolder">Clear Caches</system:String>
<system:String x:Key="cachefolder">Cache-Ordner</system:String>
<system:String x:Key="clearcachefolder">Cache leeren</system:String>
<system:String x:Key="clearcachefolderMessage">Are you sure you want to delete all caches?</system:String>
<system:String x:Key="clearfolderfailMessage">Failed to clear part of folders and files. Please see log file for more information</system:String>
<system:String x:Key="welcomewindow">Assistent</system:String>
<system:String x:Key="userdatapath">Speicherort für Benutzerdaten</system:String>
<system:String x:Key="userdatapathToolTip">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.</system:String>
<system:String x:Key="userdatapathButton">Ordner öffnen</system:String>
<system:String x:Key="advanced">Advanced</system:String>
<system:String x:Key="logLevel">Log-Ebene</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>
@ -371,7 +372,7 @@
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">Dateimanager auswählen</system:String>
<system:String x:Key="fileManager_learnMore">Learn more</system:String>
<system:String x:Key="fileManager_learnMore">Mehr erfahren</system:String>
<system:String x:Key="fileManager_tips">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.</system:String>
<system:String x:Key="fileManager_tips2">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.</system:String>
<system:String x:Key="fileManager_name">Dateimanager</system:String>
@ -416,7 +417,7 @@
<system:String x:Key="searchDelayTimeTips">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.</system:String>
<!-- Search Delay Settings Dialog -->
<system:String x:Key="homeTitle">Home Page</system:String>
<system:String x:Key="homeTitle">Homepage</system:String>
<system:String x:Key="homeTips">Enable the plugin home page state if you like to show the plugin results when query is empty.</system:String>
<!-- Custom Query Hotkey Dialog -->

View file

@ -359,6 +359,7 @@
<system:String x:Key="userdatapath">User Data Location</system:String>
<system:String x:Key="userdatapathToolTip">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.</system:String>
<system:String x:Key="userdatapathButton">Open Folder</system:String>
<system:String x:Key="advanced">Advanced</system:String>
<system:String x:Key="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>
@ -472,6 +473,7 @@
</system:String>
<system:String x:Key="errorTitle">Error</system:String>
<system:String x:Key="folderOpenError">An error occurred while opening the folder. {0}</system:String>
<system:String x:Key="browserOpenError">An error occurred while opening the URL in the browser. Please check your Default Web Browser configuration in the General section of the settings window</system:String>
<!-- General Notice -->
<system:String x:Key="pleaseWait">Please wait...</system:String>

View file

@ -364,6 +364,7 @@
<system:String x:Key="userdatapath">User Data Location</system:String>
<system:String x:Key="userdatapathToolTip">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.</system:String>
<system:String x:Key="userdatapathButton">Open Folder</system:String>
<system:String x:Key="advanced">Advanced</system:String>
<system:String x:Key="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>

View file

@ -364,6 +364,7 @@
<system:String x:Key="userdatapath">Ubicación de datos del usuario</system:String>
<system:String x:Key="userdatapathToolTip">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.</system:String>
<system:String x:Key="userdatapathButton">Abrir carpeta</system:String>
<system:String x:Key="advanced">Advanced</system:String>
<system:String x:Key="logLevel">Nivel de registro</system:String>
<system:String x:Key="LogLevelDEBUG">Depurar</system:String>
<system:String x:Key="LogLevelINFO">Información</system:String>
@ -371,7 +372,7 @@
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">Seleccionar administrador de archivos</system:String>
<system:String x:Key="fileManager_learnMore">Learn more</system:String>
<system:String x:Key="fileManager_learnMore">Más información</system:String>
<system:String x:Key="fileManager_tips">Especifique la ubicación del archivo del administrador de archivos que está utilizando y añada los argumentos necesarios. El argumento &quot;%d&quot; representa la ruta del directorio a abrir, utilizada por el campo Argumentos de la carpeta y por comandos que abren directorios específicos. El &quot;%f&quot; representa la ruta del archivo a abrir, utilizada por el campo Argumentos del archivo y por comandos que abren archivos específicos.</system:String>
<system:String x:Key="fileManager_tips2">Por ejemplo, si el administrador de archivos utiliza un comando como &quot;totalcmd.exe /A c:\windows&quot; para abrir el directorio c:\windows, la ruta del administrador de archivos será totalcmd.exe, y los Argumentos de la carpeta serán /A &quot;%d&quot;. Ciertos administradores de archivos como QTTabBar pueden requerir solo la ruta, en este caso utilice &quot;%d&quot; como la ruta del administrador de archivos y deje el resto de los campos en blanco.</system:String>
<system:String x:Key="fileManager_name">Administrador de archivos</system:String>
@ -379,8 +380,8 @@
<system:String x:Key="fileManager_path">Ruta del administrador de archivos</system:String>
<system:String x:Key="fileManager_directory_arg">Argumentos de la carpeta</system:String>
<system:String x:Key="fileManager_file_arg">Argumentos del archivo</system:String>
<system:String x:Key="fileManagerPathNotFound">The file manager '{0}' could not be located at '{1}'. Would you like to continue?</system:String>
<system:String x:Key="fileManagerPathError">File Manager Path Error</system:String>
<system:String x:Key="fileManagerPathNotFound">El administrador de archivos '{0}' no pudo ser localizado en '{1}'. ¿Desea continuar?</system:String>
<system:String x:Key="fileManagerPathError">Error de ruta del administrador de archivos</system:String>
<!-- DefaultBrowser Setting Dialog -->
<system:String x:Key="defaultBrowserTitle">Navegador web predeterminado</system:String>
@ -473,12 +474,12 @@ Si añade un prefijo &quot;@&quot; al introducir un acceso directo, éste coinci
<system:String x:Key="reportWindow_copy_below">2. Copiar el siguiente mensaje de excepción</system:String>
<!-- File Open Error -->
<system:String x:Key="fileManagerNotFoundTitle">File Manager Error</system:String>
<system:String x:Key="fileManagerNotFoundTitle">Error del administrador de archivos</system:String>
<system:String x:Key="fileManagerNotFound">
The specified file manager could not be found. Please check the Custom File Manager setting under Settings &gt; General.
No se ha encontrado el administrador de archivos especificado. Compruebe la configuración del Administrador de archivos personalizado en Configuración &gt; General.
</system:String>
<system:String x:Key="errorTitle">Error</system:String>
<system:String x:Key="folderOpenError">An error occurred while opening the folder. {0}</system:String>
<system:String x:Key="folderOpenError">Se ha producido un error al abrir la carpeta. {0}</system:String>
<!-- General Notice -->
<system:String x:Key="pleaseWait">Por favor espere...</system:String>

View file

@ -363,6 +363,7 @@
<system:String x:Key="userdatapath">Emplacement des données utilisateur</system:String>
<system:String x:Key="userdatapathToolTip">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.</system:String>
<system:String x:Key="userdatapathButton">Ouvrir le dossier</system:String>
<system:String x:Key="advanced">Avancé</system:String>
<system:String x:Key="logLevel">Niveau de journalisation</system:String>
<system:String x:Key="LogLevelDEBUG">Débogage</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>
@ -370,7 +371,7 @@
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">Sélectionner le gestionnaire de fichiers</system:String>
<system:String x:Key="fileManager_learnMore">Learn more</system:String>
<system:String x:Key="fileManager_learnMore">En savoir plus</system:String>
<system:String x:Key="fileManager_tips">Veuillez spécifier l'emplacement du fichier de l'explorateur de fichiers que vous utilisez et ajouter des arguments si nécessaire. Le &quot;%d&quot; 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 &quot;%f&quot; représente le chemin du fichier à ouvrir, utilisé par le champ Arg for File et pour les commandes ouvrant des fichiers spécifiques.</system:String>
<system:String x:Key="fileManager_tips2">Par exemple, si l'explorateur de fichiers utilise une commande telle que &quot;totalcmd.exe /A c:\windows&quot; 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 &quot;%d&quot;&quot;. Certains explorateurs de fichiers comme QTTabBar peuvent simplement nécessiter qu'un chemin soit fourni, dans ce cas, utilisez &quot;%d&quot; comme chemin de l'explorateur de fichiers et laissez le reste des fichiers vides.</system:String>
<system:String x:Key="fileManager_name">Gestionnaire de fichiers</system:String>
@ -378,8 +379,8 @@
<system:String x:Key="fileManager_path">Chemin du gestionnaire de fichiers</system:String>
<system:String x:Key="fileManager_directory_arg">Arguments pour le répertoire</system:String>
<system:String x:Key="fileManager_file_arg">Arguments pour le fichier</system:String>
<system:String x:Key="fileManagerPathNotFound">The file manager '{0}' could not be located at '{1}'. Would you like to continue?</system:String>
<system:String x:Key="fileManagerPathError">File Manager Path Error</system:String>
<system:String x:Key="fileManagerPathNotFound">Le gestionnaire de fichiers '{0}' n'a pas pu être situé à '{1}'. Souhaitez-vous continuer ?</system:String>
<system:String x:Key="fileManagerPathError">Erreur de chemin du gestionnaire de fichiers</system:String>
<!-- DefaultBrowser Setting Dialog -->
<system:String x:Key="defaultBrowserTitle">Navigateur web par défaut</system:String>
@ -472,12 +473,12 @@ Si vous ajoutez un préfixe &quot;@&quot; lors de la saisie d'un raccourci, celu
<system:String x:Key="reportWindow_copy_below">2. Copiez le message dexception ci-dessous</system:String>
<!-- File Open Error -->
<system:String x:Key="fileManagerNotFoundTitle">File Manager Error</system:String>
<system:String x:Key="fileManagerNotFoundTitle">Erreur du gestionnaire de fichiers</system:String>
<system:String x:Key="fileManagerNotFound">
The specified file manager could not be found. Please check the Custom File Manager setting under Settings &gt; General.
Le gestionnaire de fichiers spécifié n'a pas été trouvé. Veuillez vérifier le paramètre Gestionnaire de fichiers personnalisé dans Paramètres &gt; Général.
</system:String>
<system:String x:Key="errorTitle">Erreur</system:String>
<system:String x:Key="folderOpenError">An error occurred while opening the folder. {0}</system:String>
<system:String x:Key="folderOpenError">Une erreur s'est produite lors de l'ouverture du dossier. {0}</system:String>
<!-- General Notice -->
<system:String x:Key="pleaseWait">Veuillez patienter...</system:String>

View file

@ -67,7 +67,7 @@
<system:String x:Key="SearchWindowAlignCenterTop">מרכז עליון</system:String>
<system:String x:Key="SearchWindowAlignLeftTop">שמאל עליון</system:String>
<system:String x:Key="SearchWindowAlignRightTop">ימין עליון</system:String>
<system:String x:Key="SearchWindowAlignCustom">Custom Position</system:String>
<system:String x:Key="SearchWindowAlignCustom">מיקום מותאם אישית</system:String>
<system:String x:Key="language">שפה</system:String>
<system:String x:Key="lastQueryMode">סגנון שאילתה אחרונה</system:String>
<system:String x:Key="lastQueryModeToolTip">הצג/הסתר תוצאות קודמות כאשר Flow Launcher מופעל מחדש.</system:String>
@ -102,7 +102,7 @@
<system:String x:Key="SearchPrecisionLow">נמוך</system:String>
<system:String x:Key="SearchPrecisionRegular">Regular</system:String>
<system:String x:Key="ShouldUsePinyin">חפש באמצעות Pinyin</system:String>
<system:String x:Key="ShouldUsePinyinToolTip">Allows using Pinyin to search. Pinyin is the standard system of romanized spelling for translating Chinese.</system:String>
<system:String x:Key="ShouldUsePinyinToolTip">מאפשר חיפוש באמצעות Pinyin, מערכת הכתיבה הסטנדרטית לתרגום סינית.</system:String>
<system:String x:Key="AlwaysPreview">הצג תמיד תצוגה מקדימה</system:String>
<system:String x:Key="AlwaysPreviewToolTip">פתח תמיד את לוח התצוגה המקדימה כאשר Flow מופעל. הקש על {0} כדי להחליף את התצוגה המקדימה.</system:String>
<system:String x:Key="shadowEffectNotAllowed">לא ניתן להחיל אפקט צל כאשר העיצוב הנוכחי מוגדר לאפקט טשטוש</system:String>
@ -134,7 +134,7 @@
<system:String x:Key="homePageToolTip">Show home page results when query text is empty.</system:String>
<system:String x:Key="historyResultsForHomePage">Show History Results in Home Page</system:String>
<system:String x:Key="historyResultsCountForHomePage">Maximum History Results Shown in Home Page</system:String>
<system:String x:Key="homeToggleBoxToolTip">This can only be edited if plugin supports Home feature and Home Page is enabled.</system:String>
<system:String x:Key="homeToggleBoxToolTip">ניתן לערוך זאת רק אם התוסף תומך בתכונת הבית ודף הבית מופעל.</system:String>
<!-- Setting Plugin -->
<system:String x:Key="searchplugin">חפש תוסף</system:String>
@ -151,7 +151,7 @@
<system:String x:Key="currentActionKeywords">מילת מפתח נוכחית לפעולה</system:String>
<system:String x:Key="newActionKeyword">מילת מפתח חדשה לפעולה</system:String>
<system:String x:Key="actionKeywordsTooltip">שנה מילות מפתח לפעולה</system:String>
<system:String x:Key="pluginSearchDelayTime">Plugin search delay time</system:String>
<system:String x:Key="pluginSearchDelayTime">זמן השהייה של חיפוש תוסף</system:String>
<system:String x:Key="pluginSearchDelayTimeTooltip">שנה את זמן השהיית חיפוש של תוסף</system:String>
<system:String x:Key="FilterComboboxLabel">הגדרות מתקדמות:</system:String>
<system:String x:Key="DisplayModeOnOff">מופעל</system:String>
@ -313,7 +313,7 @@
<system:String x:Key="useGlyphUIEffect">השתמש ב-Segoe Fluent Icons לתוצאות חיפוש כאשר נתמך</system:String>
<system:String x:Key="flowlauncherPressHotkey">הקש על מקש</system:String>
<system:String x:Key="showBadges">הצג תגי תוצאות</system:String>
<system:String x:Key="showBadgesToolTip">For supported plugins, badges are displayed to help distinguish them more easily.</system:String>
<system:String x:Key="showBadgesToolTip">עבור תוספים נתמכים, מוצגים תגים כדי לעזור להבחין ביניהם ביתר קלות.</system:String>
<system:String x:Key="showBadgesGlobalOnly">Show Result Badges for Global Query Only</system:String>
<!-- Setting Proxy -->
@ -363,6 +363,7 @@
<system:String x:Key="userdatapath">מיקום נתוני משתמש</system:String>
<system:String x:Key="userdatapathToolTip">הגדרות המשתמש והתוספים המותקנים נשמרים בתיקיית נתוני המשתמש. מיקום זה עשוי להשתנות אם התוכנה במצב נייד.</system:String>
<system:String x:Key="userdatapathButton">פתח תיקיה</system:String>
<system:String x:Key="advanced">Advanced</system:String>
<system:String x:Key="logLevel">רמת יומן</system:String>
<system:String x:Key="LogLevelDEBUG">ניפוי שגיאות</system:String>
<system:String x:Key="LogLevelINFO">מידע</system:String>
@ -370,7 +371,7 @@
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">בחר מנהל קבצים</system:String>
<system:String x:Key="fileManager_learnMore">Learn more</system:String>
<system:String x:Key="fileManager_learnMore">למד עוד</system:String>
<system:String x:Key="fileManager_tips">אנא ציין את מיקום הקובץ של מנהל הקבצים שבו אתה משתמש והוסף ארגומנטים כנדרש. &quot;%d&quot; מייצג את נתיב התיקייה שיש לפתוח, ומשמש בשדה ארגומנט לתיקייה ובפקודות לפתיחת תיקיות מסוימות. &quot;%f&quot; מייצג את נתיב הקובץ שיש לפתוח, ומשמש בשדה ארגומנט לקובץ ובפקודות לפתיחת קבצים מסוימים.</system:String>
<system:String x:Key="fileManager_tips2">לדוגמה, אם מנהל הקבצים משתמש בפקודה כגון &quot;totalcmd.exe /A c:\windows&quot; כדי לפתוח את התיקייה c:\windows, נתיב מנהל הקבצים יהיה totalcmd.exe, והארגומנט לתיקייה יהיה /A &quot;%d&quot;. מנהלי קבצים מסוימים, כגון QTTabBar, עשויים לדרוש רק ציון נתיב, במקרה כזה השתמש ב-&quot;%d&quot; כנתיב מנהל הקבצים והשאר את שאר השדות ריקים.</system:String>
<system:String x:Key="fileManager_name">מנהל קבצים</system:String>
@ -378,8 +379,8 @@
<system:String x:Key="fileManager_path">נתיב מנהל קבצים</system:String>
<system:String x:Key="fileManager_directory_arg">ארגומנט לתיקייה</system:String>
<system:String x:Key="fileManager_file_arg">ארגומנט לקובץ</system:String>
<system:String x:Key="fileManagerPathNotFound">The file manager '{0}' could not be located at '{1}'. Would you like to continue?</system:String>
<system:String x:Key="fileManagerPathError">File Manager Path Error</system:String>
<system:String x:Key="fileManagerPathNotFound">לא ניתן היה לאתר את מנהל הקבצים '{0}' ב-'{1}'. האם ברצונך להמשיך?</system:String>
<system:String x:Key="fileManagerPathError">שגיאת נתיב למנהל הקבצים</system:String>
<!-- DefaultBrowser Setting Dialog -->
<system:String x:Key="defaultBrowserTitle">דפדפן ברירת מחדל</system:String>
@ -416,7 +417,7 @@
<!-- Search Delay Settings Dialog -->
<system:String x:Key="homeTitle">דף הבית</system:String>
<system:String x:Key="homeTips">Enable the plugin home page state if you like to show the plugin results when query is empty.</system:String>
<system:String x:Key="homeTips">הפעל את מצב דף הבית של התוסף אם ברצונך להציג את תוצאות התוסף כאשר השאילתה ריקה.</system:String>
<!-- Custom Query Hotkey Dialog -->
<system:String x:Key="customeQueryHotkeyTitle">מקש קיצור לשאילתה מותאמת אישית</system:String>
@ -472,12 +473,12 @@
<system:String x:Key="reportWindow_copy_below">2. העתק את הודעת החריגה למטה</system:String>
<!-- File Open Error -->
<system:String x:Key="fileManagerNotFoundTitle">File Manager Error</system:String>
<system:String x:Key="fileManagerNotFoundTitle">שגיאת מנהל הקבצים</system:String>
<system:String x:Key="fileManagerNotFound">
The specified file manager could not be found. Please check the Custom File Manager setting under Settings &gt; General.
לא ניתן היה למצוא את מנהל הקבצים שצוין. אנא בדוק את ההגדרה של מנהל קבצים מותאם אישית תחת הגדרות &gt; כללי.
</system:String>
<system:String x:Key="errorTitle">שגיאה</system:String>
<system:String x:Key="folderOpenError">An error occurred while opening the folder. {0}</system:String>
<system:String x:Key="folderOpenError">אירעה שגיאה בעת פתיחת התיקייה. {0}</system:String>
<!-- General Notice -->
<system:String x:Key="pleaseWait">אנא המתן...</system:String>

View file

@ -364,6 +364,7 @@
<system:String x:Key="userdatapath">Posizione Dati Utente</system:String>
<system:String x:Key="userdatapathToolTip">Le impostazioni dell'utente e i plugin installati sono salvati nella cartella dati utente. Questa posizione può variare se è in modalità portable o no.</system:String>
<system:String x:Key="userdatapathButton">Apri Cartella</system:String>
<system:String x:Key="advanced">Advanced</system:String>
<system:String x:Key="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>

View file

@ -364,6 +364,7 @@
<system:String x:Key="userdatapath">User Data Location</system:String>
<system:String x:Key="userdatapathToolTip">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.</system:String>
<system:String x:Key="userdatapathButton">Open Folder</system:String>
<system:String x:Key="advanced">Advanced</system:String>
<system:String x:Key="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>

View file

@ -122,10 +122,10 @@
<system:String x:Key="KoreanImeOpenLinkButton">열기</system:String>
<system:String x:Key="KoreanImeRegistry">이전 버전의 Microsoft IME 사용</system:String>
<system:String x:Key="KoreanImeRegistryTooltip">이전 버전의 IME를 사용하도록 시스템 설정을 변경합니다</system:String>
<system:String x:Key="homePage">Home Page</system:String>
<system:String x:Key="homePageToolTip">Show home page results when query text is empty.</system:String>
<system:String x:Key="historyResultsForHomePage">Show History Results in Home Page</system:String>
<system:String x:Key="historyResultsCountForHomePage">Maximum History Results Shown in Home Page</system:String>
<system:String x:Key="homePage">홈페이지</system:String>
<system:String x:Key="homePageToolTip">쿼리 입력창이 비어있을때, 홈페이지의 결과를 표시합니다.</system:String>
<system:String x:Key="historyResultsForHomePage">히스토리를 홈페이지에 표시</system:String>
<system:String x:Key="historyResultsCountForHomePage">홈페이지에 표시할 최대 히스토리 수</system:String>
<system:String x:Key="homeToggleBoxToolTip">This can only be edited if plugin supports Home feature and Home Page is enabled.</system:String>
<!-- Setting Plugin -->
@ -149,7 +149,7 @@
<system:String x:Key="DisplayModeOnOff">켬</system:String>
<system:String x:Key="DisplayModePriority">중요</system:String>
<system:String x:Key="DisplayModeSearchDelay">검색 지연</system:String>
<system:String x:Key="DisplayModeHomeOnOff">Home Page</system:String>
<system:String x:Key="DisplayModeHomeOnOff">홈페이지</system:String>
<system:String x:Key="currentPriority">현재 중요도:</system:String>
<system:String x:Key="newPriority">새 중요도:</system:String>
<system:String x:Key="priority">중요도</system:String>
@ -347,7 +347,7 @@
<system:String x:Key="logfolder">로그 폴더</system:String>
<system:String x:Key="clearlogfolder">로그 삭제</system:String>
<system:String x:Key="clearlogfolderMessage">정말 모든 로그를 삭제하시겠습니까?</system:String>
<system:String x:Key="cachefolder">Cache Folder</system:String>
<system:String x:Key="cachefolder">캐시 폴더</system:String>
<system:String x:Key="clearcachefolder">캐시 지우기</system:String>
<system:String x:Key="clearcachefolderMessage">모든 캐시를 삭제하시겠습니까?</system:String>
<system:String x:Key="clearfolderfailMessage">Failed to clear part of folders and files. Please see log file for more information</system:String>
@ -355,14 +355,15 @@
<system:String x:Key="userdatapath">사용자 데이터 위치</system:String>
<system:String x:Key="userdatapathToolTip">사용자 설정과 설치된 플러그인은 사용자 데이터 폴더에 저장됩니다. 이 위치는 휴대용 모드 활성화 여부에 따라 달라질 수 있습니다.</system:String>
<system:String x:Key="userdatapathButton">폴더 열기</system:String>
<system:String x:Key="advanced">Advanced</system:String>
<system:String x:Key="logLevel">로그 레벨</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>
<system:String x:Key="settingWindowFontTitle">Setting Window Font</system:String>
<system:String x:Key="settingWindowFontTitle">설정창 글꼴</system:String>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">파일관리자 선택</system:String>
<system:String x:Key="fileManager_learnMore">Learn more</system:String>
<system:String x:Key="fileManager_learnMore">더 알아보기</system:String>
<system:String x:Key="fileManager_tips">사용 중인 파일 관리자의 파일 위치를 지정하고, 필요한 경우 인수를 추가하세요. &quot;%d&quot;는 열고자 하는 디렉터리 경로를 나타내며, 폴더용 인수 필드 및 특정 디렉터리를 여는 명령어에서 사용됩니다. &quot;%f&quot;는 열고자 하는 파일 경로를 나타내며, 파일용 인수 필드 및 특정 파일을 여는 명령어에서 사용됩니다.</system:String>
<system:String x:Key="fileManager_tips2">예를 들어, 파일 관리자가 totalcmd.exe /A c:\windows와 같은 명령어로 c:\windows 디렉터리를 연다면, 파일 관리자 경로는 totalcmd.exe가 되고, 폴더용 인수는 /A &quot;%d&quot;가 됩니다. QTTabBar와 같은 일부 파일 관리자는 경로만 전달하면 되는 경우가 있으므로, 이 경우에는 파일 관리자 경로에 &quot;%d&quot;를 입력하고 나머지 필드는 비워두세요.</system:String>
<system:String x:Key="fileManager_name">파일관리자</system:String>
@ -407,7 +408,7 @@
<system:String x:Key="searchDelayTimeTips">플러그인에서 사용할 검색 지연 시간(ms)을 입력하세요. 지정하지 않으려면 비워두세요. 기본 검색 지연 시간이 사용됩니다.</system:String>
<!-- Search Delay Settings Dialog -->
<system:String x:Key="homeTitle">Home Page</system:String>
<system:String x:Key="homeTitle">홈페이지</system:String>
<system:String x:Key="homeTips">Enable the plugin home page state if you like to show the plugin results when query is empty.</system:String>
<!-- Custom Query Hotkey Dialog -->

View file

@ -364,6 +364,7 @@
<system:String x:Key="userdatapath">Plassering av brukerdata</system:String>
<system:String x:Key="userdatapathToolTip">Brukerinnstillinger og installerte programtillegg lagres i brukerens datamappe. Denne plasseringen kan variere avhengig av om den er i portabel modus eller ikke.</system:String>
<system:String x:Key="userdatapathButton">Åpne mappe</system:String>
<system:String x:Key="advanced">Advanced</system:String>
<system:String x:Key="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>

View file

@ -364,6 +364,7 @@
<system:String x:Key="userdatapath">Gegevenslocatie van gebruiker</system:String>
<system:String x:Key="userdatapathToolTip">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.</system:String>
<system:String x:Key="userdatapathButton">Map openen</system:String>
<system:String x:Key="advanced">Advanced</system:String>
<system:String x:Key="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>

View file

@ -364,6 +364,7 @@ Kliknij &quot;nie&quot;, jeśli jest już zainstalowany. Zostaniesz wtedy popros
<system:String x:Key="userdatapath">Lokalizacja danych użytkownika</system:String>
<system:String x:Key="userdatapathToolTip">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.</system:String>
<system:String x:Key="userdatapathButton">Otwórz folder</system:String>
<system:String x:Key="advanced">Advanced</system:String>
<system:String x:Key="logLevel">Poziom logowania</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>

View file

@ -364,6 +364,7 @@
<system:String x:Key="userdatapath">User Data Location</system:String>
<system:String x:Key="userdatapathToolTip">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.</system:String>
<system:String x:Key="userdatapathButton">Open Folder</system:String>
<system:String x:Key="advanced">Advanced</system:String>
<system:String x:Key="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>

View file

@ -362,6 +362,7 @@
<system:String x:Key="userdatapath">Localização dos dados do utilizador</system:String>
<system:String x:Key="userdatapathToolTip">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</system:String>
<system:String x:Key="userdatapathButton">Abrir pasta</system:String>
<system:String x:Key="advanced">Avançado</system:String>
<system:String x:Key="logLevel">Nível de registo</system:String>
<system:String x:Key="LogLevelDEBUG">Depuração</system:String>
<system:String x:Key="LogLevelINFO">Informação</system:String>

View file

@ -364,6 +364,7 @@
<system:String x:Key="userdatapath">User Data Location</system:String>
<system:String x:Key="userdatapathToolTip">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.</system:String>
<system:String x:Key="userdatapathButton">Open Folder</system:String>
<system:String x:Key="advanced">Advanced</system:String>
<system:String x:Key="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>

View file

@ -364,6 +364,7 @@
<system:String x:Key="userdatapath">Cesta k používateľskému priečinku</system:String>
<system:String x:Key="userdatapathToolTip">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.</system:String>
<system:String x:Key="userdatapathButton">Otvoriť priečinok</system:String>
<system:String x:Key="advanced">Rozšírené</system:String>
<system:String x:Key="logLevel">Úroveň logovania</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>

View file

@ -364,6 +364,7 @@
<system:String x:Key="userdatapath">User Data Location</system:String>
<system:String x:Key="userdatapathToolTip">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.</system:String>
<system:String x:Key="userdatapathButton">Open Folder</system:String>
<system:String x:Key="advanced">Advanced</system:String>
<system:String x:Key="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>

View file

@ -364,6 +364,7 @@
<system:String x:Key="userdatapath">Kullanıcı Verisi Dizini</system:String>
<system:String x:Key="userdatapathToolTip">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.</system:String>
<system:String x:Key="userdatapathButton">Klasörü Aç</system:String>
<system:String x:Key="advanced">Advanced</system:String>
<system:String x:Key="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>

View file

@ -364,6 +364,7 @@
<system:String x:Key="userdatapath">Розташування даних користувача</system:String>
<system:String x:Key="userdatapathToolTip">Налаштування користувача та встановлені плагіни зберігаються у теці даних користувача. Це місце може змінюватися залежно від того, чи перебуває програма в портативному режимі, чи ні.</system:String>
<system:String x:Key="userdatapathButton">Відкрити теку</system:String>
<system:String x:Key="advanced">Advanced</system:String>
<system:String x:Key="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>

View file

@ -42,7 +42,7 @@
<system:String x:Key="GameMode">Chế độ trò chơi</system:String>
<system:String x:Key="GameModeToolTip">Tạm dừng sử dụng phím nóng.</system:String>
<system:String x:Key="PositionReset">Đặt lại vị trí</system:String>
<system:String x:Key="PositionResetToolTip">Reset search window position</system:String>
<system:String x:Key="PositionResetToolTip">Cài lại vị trí cửa sổ tìm kiếm</system:String>
<system:String x:Key="queryTextBoxPlaceholder">Type here to search</system:String>
<!-- Setting General -->
@ -366,6 +366,7 @@
<system:String x:Key="userdatapath">Vị trí dữ liệu người dùng</system:String>
<system:String x:Key="userdatapathToolTip">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.</system:String>
<system:String x:Key="userdatapathButton">Mở thư mục</system:String>
<system:String x:Key="advanced">Advanced</system:String>
<system:String x:Key="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>

View file

@ -8,9 +8,9 @@
</system:String>
<system:String x:Key="runtimePluginChooseRuntimeExecutable">请选择 {0} 可执行文件</system:String>
<system:String x:Key="runtimeExecutableInvalidChooseDownload">
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},请点击“否”
</system:String>
<system:String x:Key="runtimePluginUnableToSetExecutablePath">无法设置 {0} 可执行路径,请尝试从 Flow 的设置中设置(向下滚动到底部)。</system:String>
<system:String x:Key="failedToInitializePluginsTitle">无法初始化插件</system:String>
@ -18,7 +18,7 @@
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">无法注册热键“{0}”。该热键可能正在被其他程序使用。更改为不同的热键,或退出其他程序。</system:String>
<system:String x:Key="unregisterHotkeyFailed">Failed to unregister hotkey &quot;{0}&quot;. Please try again or see log for details</system:String>
<system:String x:Key="unregisterHotkeyFailed">未能取消注册快捷键&quot;{0}&quot;。请重试或查看日志以获取详细信息</system:String>
<system:String x:Key="MessageBoxTitle">Flow Launcher</system:String>
<system:String x:Key="couldnotStartCmd">启动命令 {0} 失败</system:String>
<system:String x:Key="invalidFlowLauncherPluginFileFormat">无效的 Flow Launcher 插件文件格式</system:String>
@ -42,8 +42,8 @@
<system:String x:Key="GameMode">游戏模式</system:String>
<system:String x:Key="GameModeToolTip">暂停使用热键。</system:String>
<system:String x:Key="PositionReset">重置位置</system:String>
<system:String x:Key="PositionResetToolTip">Reset search window position</system:String>
<system:String x:Key="queryTextBoxPlaceholder">Type here to search</system:String>
<system:String x:Key="PositionResetToolTip">重置搜索窗口位置</system:String>
<system:String x:Key="queryTextBoxPlaceholder">在此处输入以搜索</system:String>
<!-- Setting General -->
<system:String x:Key="flowlauncher_settings">设置</system:String>
@ -51,12 +51,12 @@
<system:String x:Key="portableMode">便携模式</system:String>
<system:String x:Key="portableModeToolTIp">将所有设置和用户数据存储在一个文件夹中 (可用于可移除驱动器或云服务)。</system:String>
<system:String x:Key="startFlowLauncherOnSystemStartup">开机自启</system:String>
<system:String x:Key="useLogonTaskForStartup">Use logon task instead of startup entry for faster startup experience</system:String>
<system:String x:Key="useLogonTaskForStartupTooltip">After uninstallation, you need to manually remove this task (Flow.Launcher Startup) via Task Scheduler</system:String>
<system:String x:Key="useLogonTaskForStartup">使用登录任务代替启动条目来更快地启动体验</system:String>
<system:String x:Key="useLogonTaskForStartupTooltip">卸载后,您需要通过任务计划程序手动移除此任务 (Flow.Launcher Startup)</system:String>
<system:String x:Key="setAutoStartFailed">设置开机自启时出错</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">失去焦点时自动隐藏 Flow Launcher</system:String>
<system:String x:Key="dontPromptUpdateMsg">不显示新版本提示</system:String>
<system:String x:Key="SearchWindowPosition">Search Window Location</system:String>
<system:String x:Key="SearchWindowPosition">搜索窗口位置</system:String>
<system:String x:Key="SearchWindowScreenRememberLastLaunchLocation">记住上次的位置</system:String>
<system:String x:Key="SearchWindowScreenCursor">鼠标光标所在显示器</system:String>
<system:String x:Key="SearchWindowScreenFocus">聚焦窗口所在显示器</system:String>
@ -74,8 +74,8 @@
<system:String x:Key="LastQueryPreserved">保留上次搜索关键字</system:String>
<system:String x:Key="LastQuerySelected">选择上次搜索关键字</system:String>
<system:String x:Key="LastQueryEmpty">清空上次搜索关键字</system:String>
<system:String x:Key="LastQueryActionKeywordPreserved">Preserve Last Action Keyword</system:String>
<system:String x:Key="LastQueryActionKeywordSelected">Select Last Action Keyword</system:String>
<system:String x:Key="LastQueryActionKeywordPreserved">保留最后操作关键词</system:String>
<system:String x:Key="LastQueryActionKeywordSelected">选择最后一个操作关键词</system:String>
<system:String x:Key="maxShowResults">最大结果显示个数</system:String>
<system:String x:Key="maxShowResultsToolTip">您也可以通过使用 CTRL+ &quot;+&quot; 和 CTRL+ &quot;-&quot; 来快速调整它。</system:String>
<system:String x:Key="ignoreHotkeysOnFullscreen">全屏模式下忽略热键</system:String>
@ -106,36 +106,36 @@
<system:String x:Key="AlwaysPreview">始终打开预览</system:String>
<system:String x:Key="AlwaysPreviewToolTip">Flow 启动时总是打开预览面板。按 {0} 以切换预览。</system:String>
<system:String x:Key="shadowEffectNotAllowed">当前主题已启用模糊效果,不允许启用阴影效果</system:String>
<system:String x:Key="searchDelay">Search Delay</system:String>
<system:String x:Key="searchDelayToolTip">Adds a short delay while typing to reduce UI flicker and result load. Recommended if your typing speed is average.</system:String>
<system:String x:Key="searchDelayNumberBoxToolTip">Enter the wait time (in ms) until input is considered complete. This can only be edited if Search Delay is enabled.</system:String>
<system:String x:Key="searchDelayTime">Default Search Delay Time</system:String>
<system:String x:Key="searchDelayTimeToolTip">Wait time before showing results after typing stops. Higher values wait longer. (ms)</system:String>
<system:String x:Key="KoreanImeTitle">Information for Korean IME user</system:String>
<system:String x:Key="searchDelay">延迟搜索</system:String>
<system:String x:Key="searchDelayToolTip">在输入时添加一个短时间延迟以减少UI闪烁和加载结果的负载。建议您的输入速度是平均的。</system:String>
<system:String x:Key="searchDelayNumberBoxToolTip">输入等待时间(毫秒),直到输入被认为完成。这只能在启用搜索延迟时进行编辑。</system:String>
<system:String x:Key="searchDelayTime">默认搜索延迟时间</system:String>
<system:String x:Key="searchDelayTimeToolTip">在输入停止后显示结果之前等待时间。更高的数值等待更长时间(毫秒)</system:String>
<system:String x:Key="KoreanImeTitle">韩文输入法用户信息</system:String>
<system:String x:Key="KoreanImeGuide">
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 &quot;Use previous version of Korean IME&quot;.
如果您遇到任何问题,您可能需要启用&quot;使用上一个版本的韩语IME&quot;。
Open Setting in Windows 11 and go to:
Windows 11中的打开设置转到
Time &amp; Language &gt; Language &amp; Region &gt; Korean &gt; Language Options &gt; Keyboard - Microsoft IME &gt; Compatibility,
时间和语言&gt; 语言和区域 &gt; 韩国语言选项 &gt; 键盘-微软IME &gt; 兼容性
and enable &quot;Use previous version of Microsoft IME&quot;.
并启用&quot;使用之前版本的 Microsoft IME&quot;。
</system:String>
<system:String x:Key="KoreanImeOpenLink">Open Language and Region System Settings</system:String>
<system:String x:Key="KoreanImeOpenLinkToolTip">Opens the Korean IME setting location. Go to Korean &gt; Language Options &gt; Keyboard - Microsoft IME &gt; Compatibility</system:String>
<system:String x:Key="KoreanImeOpenLink">打开语言和区域系统设置</system:String>
<system:String x:Key="KoreanImeOpenLinkToolTip">打开韩语输入法设置位置。转到韩语&gt; 语言选项 &gt; 键盘-微软输入法 &gt; 兼容性</system:String>
<system:String x:Key="KoreanImeOpenLinkButton">打开</system:String>
<system:String x:Key="KoreanImeRegistry">Use Previous Korean IME</system:String>
<system:String x:Key="KoreanImeRegistryTooltip">You can change the Previous Korean IME settings directly from here</system:String>
<system:String x:Key="homePage">Home Page</system:String>
<system:String x:Key="homePageToolTip">Show home page results when query text is empty.</system:String>
<system:String x:Key="historyResultsForHomePage">Show History Results in Home Page</system:String>
<system:String x:Key="historyResultsCountForHomePage">Maximum History Results Shown in Home Page</system:String>
<system:String x:Key="homeToggleBoxToolTip">This can only be edited if plugin supports Home feature and Home Page is enabled.</system:String>
<system:String x:Key="KoreanImeRegistry">使用以前的韩语输入法</system:String>
<system:String x:Key="KoreanImeRegistryTooltip">您可以直接从这里更改前韩语输入法设置</system:String>
<system:String x:Key="homePage">首页</system:String>
<system:String x:Key="homePageToolTip">当查询文本为空时显示主页结果。</system:String>
<system:String x:Key="historyResultsForHomePage">在主页中显示历史记录</system:String>
<system:String x:Key="historyResultsCountForHomePage">在主页显示的最大历史结果数</system:String>
<system:String x:Key="homeToggleBoxToolTip">这只能在插件支持主页功能和主页启用时进行编辑。</system:String>
<!-- Setting Plugin -->
<system:String x:Key="searchplugin">搜索插件</system:String>
@ -152,13 +152,13 @@
<system:String x:Key="currentActionKeywords">当前触发关键字</system:String>
<system:String x:Key="newActionKeyword">新触发关键字</system:String>
<system:String x:Key="actionKeywordsTooltip">更改触发关键字</system:String>
<system:String x:Key="pluginSearchDelayTime">Plugin search delay time</system:String>
<system:String x:Key="pluginSearchDelayTimeTooltip">Change Plugin Search Delay Time</system:String>
<system:String x:Key="FilterComboboxLabel">Advanced Settings:</system:String>
<system:String x:Key="pluginSearchDelayTime">插件搜索延迟时间</system:String>
<system:String x:Key="pluginSearchDelayTimeTooltip">更改插件搜索延迟时间</system:String>
<system:String x:Key="FilterComboboxLabel">高级设置:</system:String>
<system:String x:Key="DisplayModeOnOff">启用</system:String>
<system:String x:Key="DisplayModePriority">优先级</system:String>
<system:String x:Key="DisplayModeSearchDelay">Search Delay</system:String>
<system:String x:Key="DisplayModeHomeOnOff">Home Page</system:String>
<system:String x:Key="DisplayModeSearchDelay">延迟搜索</system:String>
<system:String x:Key="DisplayModeHomeOnOff">首页</system:String>
<system:String x:Key="currentPriority">当前优先级</system:String>
<system:String x:Key="newPriority">新优先级</system:String>
<system:String x:Key="priority">优先级</system:String>
@ -170,10 +170,10 @@
<system:String x:Key="plugin_query_version">版本</system:String>
<system:String x:Key="plugin_query_web">官方网站</system:String>
<system:String x:Key="plugin_uninstall">卸载</system:String>
<system:String x:Key="failedToRemovePluginSettingsTitle">Fail to remove plugin settings</system:String>
<system:String x:Key="failedToRemovePluginSettingsMessage">Plugins: {0} - Fail to remove plugin settings files, please remove them manually</system:String>
<system:String x:Key="failedToRemovePluginCacheTitle">Fail to remove plugin cache</system:String>
<system:String x:Key="failedToRemovePluginCacheMessage">Plugins: {0} - Fail to remove plugin cache files, please remove them manually</system:String>
<system:String x:Key="failedToRemovePluginSettingsTitle">移除插件设置失败</system:String>
<system:String x:Key="failedToRemovePluginSettingsMessage">插件:{0} - 移除插件设置文件失败,请手动删除</system:String>
<system:String x:Key="failedToRemovePluginCacheTitle">移除插件缓存失败</system:String>
<system:String x:Key="failedToRemovePluginCacheMessage">插件:{0} - 移除插件设置文件失败,请手动删除</system:String>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">插件商店</system:String>
@ -210,9 +210,9 @@
<system:String x:Key="resultItemFont">结果标题字体</system:String>
<system:String x:Key="resultSubItemFont">结果字幕字体</system:String>
<system:String x:Key="resetCustomize">重置</system:String>
<system:String x:Key="resetCustomizeToolTip">Reset to the recommended font and size settings.</system:String>
<system:String x:Key="ImportThemeSize">Import Theme Size</system:String>
<system:String x:Key="ImportThemeSizeToolTip">If a size value intended by the theme designer is available, it will be retrieved and applied.</system:String>
<system:String x:Key="resetCustomizeToolTip">重置为推荐字体和大小设置。</system:String>
<system:String x:Key="ImportThemeSize">导入主题尺寸</system:String>
<system:String x:Key="ImportThemeSizeToolTip">如果主题设计器想要的大小值可用,它将被检索和应用。</system:String>
<system:String x:Key="CustomizeToolTip">自定义</system:String>
<system:String x:Key="windowMode">窗口模式</system:String>
<system:String x:Key="opacity">透明度</system:String>
@ -239,21 +239,21 @@
<system:String x:Key="AnimationSpeedCustom">自定义</system:String>
<system:String x:Key="Clock">时钟</system:String>
<system:String x:Key="Date">日期</system:String>
<system:String x:Key="BackdropType">Backdrop Type</system:String>
<system:String x:Key="BackdropInfo">The backdrop effect is not applied in the preview.</system:String>
<system:String x:Key="BackdropTypeDisabledToolTip">Backdrop supported starting from Windows 11 build 22000 and above</system:String>
<system:String x:Key="BackdropType">返回类型</system:String>
<system:String x:Key="BackdropInfo">预览中没有应用背景效果。</system:String>
<system:String x:Key="BackdropTypeDisabledToolTip">自 Windows 11 Build 22000 起支持背景效果</system:String>
<system:String x:Key="BackdropTypesNone">无</system:String>
<system:String x:Key="BackdropTypesAcrylic">Acrylic</system:String>
<system:String x:Key="BackdropTypesMica">Mica</system:String>
<system:String x:Key="BackdropTypesMicaAlt">Mica Alt</system:String>
<system:String x:Key="TypeIsDarkToolTip">This theme supports two (light/dark) modes.</system:String>
<system:String x:Key="BackdropTypesAcrylic">亚克力</system:String>
<system:String x:Key="BackdropTypesMica">云母</system:String>
<system:String x:Key="BackdropTypesMicaAlt">云母平替</system:String>
<system:String x:Key="TypeIsDarkToolTip">该主题支持两种(浅色/深色)模式。</system:String>
<system:String x:Key="TypeHasBlurToolTip">该主题支持模糊透明背景。</system:String>
<system:String x:Key="ShowPlaceholder">Show placeholder</system:String>
<system:String x:Key="ShowPlaceholderTip">Display placeholder when query is empty</system:String>
<system:String x:Key="PlaceholderText">Placeholder text</system:String>
<system:String x:Key="PlaceholderTextTip">Change placeholder text. Input empty will use: {0}</system:String>
<system:String x:Key="KeepMaxResults">Fixed Window Size</system:String>
<system:String x:Key="KeepMaxResultsToolTip">The window size is not adjustable by dragging.</system:String>
<system:String x:Key="ShowPlaceholder">显示占位符</system:String>
<system:String x:Key="ShowPlaceholderTip">当查询为空时显示占位符</system:String>
<system:String x:Key="PlaceholderText">占位符文本</system:String>
<system:String x:Key="PlaceholderTextTip">更改占位符文本。输入空将使用:{0}</system:String>
<system:String x:Key="KeepMaxResults">固定窗口大小</system:String>
<system:String x:Key="KeepMaxResultsToolTip">窗口高度不能通过拖动来调整。</system:String>
<!-- Setting Hotkey -->
<system:String x:Key="hotkey">热键</system:String>
@ -313,9 +313,9 @@
<system:String x:Key="useGlyphUI">使用 Segoe Fluent 图标</system:String>
<system:String x:Key="useGlyphUIEffect">在支持时在选项中显示 Segoe Fluent 图标</system:String>
<system:String x:Key="flowlauncherPressHotkey">按下按键</system:String>
<system:String x:Key="showBadges">Show Result Badges</system:String>
<system:String x:Key="showBadgesToolTip">For supported plugins, badges are displayed to help distinguish them more easily.</system:String>
<system:String x:Key="showBadgesGlobalOnly">Show Result Badges for Global Query Only</system:String>
<system:String x:Key="showBadges">显示结果徽章</system:String>
<system:String x:Key="showBadgesToolTip">对于支持的插件,将显示徽章以帮助更容易区分它们。</system:String>
<system:String x:Key="showBadgesGlobalOnly">仅在全局查询下显示结果徽章</system:String>
<!-- Setting Proxy -->
<system:String x:Key="proxy">HTTP 代理</system:String>
@ -356,22 +356,23 @@
<system:String x:Key="logfolder">日志目录</system:String>
<system:String x:Key="clearlogfolder">清除日志</system:String>
<system:String x:Key="clearlogfolderMessage">你确定要删除所有的日志吗?</system:String>
<system:String x:Key="cachefolder">Cache Folder</system:String>
<system:String x:Key="clearcachefolder">Clear Caches</system:String>
<system:String x:Key="clearcachefolderMessage">Are you sure you want to delete all caches?</system:String>
<system:String x:Key="clearfolderfailMessage">Failed to clear part of folders and files. Please see log file for more information</system:String>
<system:String x:Key="cachefolder">缓存文件夹</system:String>
<system:String x:Key="clearcachefolder">清除缓存</system:String>
<system:String x:Key="clearcachefolderMessage">您确定要删除所有缓存吗?</system:String>
<system:String x:Key="clearfolderfailMessage">无法清除部分文件夹和文件。请查看日志文件以获取更多信息</system:String>
<system:String x:Key="welcomewindow">向导</system:String>
<system:String x:Key="userdatapath">用户数据位置</system:String>
<system:String x:Key="userdatapathToolTip">用户设置和已安装的插件保存在用户数据文件夹中。此位置可能因是否处于便携模式而异。</system:String>
<system:String x:Key="userdatapathButton">打开文件夹</system:String>
<system:String x:Key="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>
<system:String x:Key="settingWindowFontTitle">Setting Window Font</system:String>
<system:String x:Key="advanced">高级</system:String>
<system:String x:Key="logLevel">日志等级</system:String>
<system:String x:Key="LogLevelDEBUG">调试</system:String>
<system:String x:Key="LogLevelINFO">信息</system:String>
<system:String x:Key="settingWindowFontTitle">设置窗口字体</system:String>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">默认文件管理器</system:String>
<system:String x:Key="fileManager_learnMore">Learn more</system:String>
<system:String x:Key="fileManager_learnMore">了解更多</system:String>
<system:String x:Key="fileManager_tips">请指定您使用的文件管理器的文件位置并根据需要添加参数。“%d”表示要打开的目录路径由文件夹字段的参数和打开特定目录的命令使用。“%f”表示要打开的文件路径由文件字段的参数和打开特定文件的命令使用。</system:String>
<system:String x:Key="fileManager_tips2">例如如果文件管理器使用诸如“totalcmd.exe /A c:\windows”之类的命令来打开 c:\windows 目录,则文件管理器路径将为 totalcmd.exe文件夹参数将为 /A &quot;%d&quot;。某些文件管理器(如 QTTabBar可能只需要提供路径在本例中使用“%d”作为文件管理器路径其余字段留空。</system:String>
<system:String x:Key="fileManager_name">文件管理器</system:String>
@ -379,8 +380,8 @@
<system:String x:Key="fileManager_path">文件管理器路径</system:String>
<system:String x:Key="fileManager_directory_arg">文件夹路径参数</system:String>
<system:String x:Key="fileManager_file_arg">选中文件路径参数</system:String>
<system:String x:Key="fileManagerPathNotFound">The file manager '{0}' could not be located at '{1}'. Would you like to continue?</system:String>
<system:String x:Key="fileManagerPathError">File Manager Path Error</system:String>
<system:String x:Key="fileManagerPathNotFound">文件管理器 '{0}' 不能在 '{1}'中定位。您想要继续吗?</system:String>
<system:String x:Key="fileManagerPathError">文件管理器路径错误</system:String>
<!-- DefaultBrowser Setting Dialog -->
<system:String x:Key="defaultBrowserTitle">默认浏览器</system:String>
@ -388,7 +389,7 @@
<system:String x:Key="defaultBrowser_name">浏览器</system:String>
<system:String x:Key="defaultBrowser_profile_name">浏览器名称</system:String>
<system:String x:Key="defaultBrowser_path">浏览器路径</system:String>
<system:String x:Key="defaultBrowser_newWindow">新窗</system:String>
<system:String x:Key="defaultBrowser_newWindow">新窗</system:String>
<system:String x:Key="defaultBrowser_newTab">新标签</system:String>
<system:String x:Key="defaultBrowser_parameter">隐身模式</system:String>
@ -405,19 +406,19 @@
<system:String x:Key="cannotFindSpecifiedPlugin">找不到指定的插件</system:String>
<system:String x:Key="newActionKeywordsCannotBeEmpty">新触发关键字不能为空</system:String>
<system:String x:Key="newActionKeywordsHasBeenAssigned">此触发关键字已经被指派给其他插件了,请换一个关键字</system:String>
<system:String x:Key="newActionKeywordsSameAsOld">This new Action Keyword is the same as old, please choose a different one</system:String>
<system:String x:Key="newActionKeywordsSameAsOld">此触发关键字已经被指派给其他插件了,请换一个关键字</system:String>
<system:String x:Key="success">成功</system:String>
<system:String x:Key="completedSuccessfully">成功完成</system:String>
<system:String x:Key="failedToCopy">Failed to copy</system:String>
<system:String x:Key="actionkeyword_tips">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.</system:String>
<system:String x:Key="failedToCopy">复制失败</system:String>
<system:String x:Key="actionkeyword_tips">请输入您希望用来启动插件的动作关键字,并使用空格进行分隔。若不想指定任何关键字,可直接输入*,此时插件将在未输入动作关键字的情况下被触发</system:String>
<!-- Search Delay Settings Dialog -->
<system:String x:Key="searchDelayTimeTitle">Search Delay Time Setting</system:String>
<system:String x:Key="searchDelayTimeTips">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.</system:String>
<system:String x:Key="searchDelayTimeTitle">搜索延迟时间设置</system:String>
<system:String x:Key="searchDelayTimeTips">请输入您希望插件使用的搜索延迟时间(单位:毫秒)。若不想指定,可留空,此时插件将采用默认的搜索延迟时间。</system:String>
<!-- Search Delay Settings Dialog -->
<system:String x:Key="homeTitle">Home Page</system:String>
<system:String x:Key="homeTips">Enable the plugin home page state if you like to show the plugin results when query is empty.</system:String>
<system:String x:Key="homeTitle">首页</system:String>
<system:String x:Key="homeTips">如果您想在查询为空时显示插件的结果,请启用插件主页状态。</system:String>
<!-- Custom Query Hotkey Dialog -->
<system:String x:Key="customeQueryHotkeyTitle">自定义查询热键</system:String>
@ -468,17 +469,17 @@
<system:String x:Key="reportWindow_report_succeed">发送成功</system:String>
<system:String x:Key="reportWindow_report_failed">发送失败</system:String>
<system:String x:Key="reportWindow_flowlauncher_got_an_error">Flow Launcher 出错啦</system:String>
<system:String x:Key="reportWindow_please_open_issue">Please open new issue in</system:String>
<system:String x:Key="reportWindow_upload_log">1. Upload log file: {0}</system:String>
<system:String x:Key="reportWindow_copy_below">2. Copy below exception message</system:String>
<system:String x:Key="reportWindow_please_open_issue">请打开新的问题在</system:String>
<system:String x:Key="reportWindow_upload_log">1. 上传日志文件:{0}</system:String>
<system:String x:Key="reportWindow_copy_below">2. 复制下面的异常消息</system:String>
<!-- File Open Error -->
<system:String x:Key="fileManagerNotFoundTitle">File Manager Error</system:String>
<system:String x:Key="fileManagerNotFoundTitle">文件管理器错误</system:String>
<system:String x:Key="fileManagerNotFound">
The specified file manager could not be found. Please check the Custom File Manager setting under Settings &gt; General.
找不到指定的文件管理器。请在“设置 &gt; 通用”下检查自定义文件管理器设置。
</system:String>
<system:String x:Key="errorTitle">错误</system:String>
<system:String x:Key="folderOpenError">An error occurred while opening the folder. {0}</system:String>
<system:String x:Key="folderOpenError">打开文件夹时发生错误。{0}</system:String>
<!-- General Notice -->
<system:String x:Key="pleaseWait">请稍等...</system:String>

View file

@ -364,6 +364,7 @@
<system:String x:Key="userdatapath">User Data Location</system:String>
<system:String x:Key="userdatapathToolTip">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.</system:String>
<system:String x:Key="userdatapathButton">Open Folder</system:String>
<system:String x:Key="advanced">Advanced</system:String>
<system:String x:Key="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>

View file

@ -64,10 +64,6 @@
Key="R"
Command="{Binding ReQueryCommand}"
Modifiers="Ctrl" />
<KeyBinding
Key="H"
Command="{Binding LoadHistoryCommand}"
Modifiers="Ctrl" />
<KeyBinding
Key="OemCloseBrackets"
Command="{Binding IncreaseWidthCommand}"
@ -191,6 +187,10 @@
Key="{Binding SettingWindowHotkey, Converter={StaticResource StringToKeyBindingConverter}, ConverterParameter='key'}"
Command="{Binding OpenSettingCommand}"
Modifiers="{Binding SettingWindowHotkey, Converter={StaticResource StringToKeyBindingConverter}, ConverterParameter='modifiers'}" />
<KeyBinding
Key="{Binding OpenHistoryHotkey, Converter={StaticResource StringToKeyBindingConverter}, ConverterParameter='key'}"
Command="{Binding LoadHistoryCommand}"
Modifiers="{Binding OpenHistoryHotkey, Converter={StaticResource StringToKeyBindingConverter}, ConverterParameter='modifiers'}" />
<KeyBinding
Key="{Binding OpenContextMenuHotkey, Converter={StaticResource StringToKeyBindingConverter}, ConverterParameter='key'}"
Command="{Binding LoadContextMenuCommand}"
@ -359,7 +359,7 @@
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=ResultListBox, Path=Items.Count}" Value="0" />
<Condition Binding="{Binding ElementName=ContextMenu, Path=Visibility}" Value="Collapsed" />
<Condition Binding="{Binding ElementName=ResultContextMenu, Path=Visibility}" Value="Collapsed" />
<Condition Binding="{Binding ElementName=History, Path=Visibility}" Value="Collapsed" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
@ -373,7 +373,7 @@
<DataTrigger Binding="{Binding ElementName=ResultListBox, Path=Visibility}" Value="Visible">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=ContextMenu, Path=Visibility}" Value="Visible">
<DataTrigger Binding="{Binding ElementName=ResultContextMenu, Path=Visibility}" Value="Visible">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=History, Path=Visibility}" Value="Visible">
@ -419,7 +419,7 @@
</ContentControl>
<ContentControl>
<flowlauncher:ResultListBox
x:Name="ContextMenu"
x:Name="ResultContextMenu"
DataContext="{Binding ContextMenu}"
LeftClickResultCommand="{Binding LeftClickResultCommand}"
RightClickResultCommand="{Binding RightClickResultCommand}" />

View file

@ -101,7 +101,7 @@ namespace Flow.Launcher
private void ThemeManager_ActualApplicationThemeChanged(ModernWpf.ThemeManager sender, object args)
{
_theme.RefreshFrameAsync();
_ = _theme.RefreshFrameAsync();
}
private void OnSourceInitialized(object sender, EventArgs e)
@ -295,14 +295,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
@ -465,7 +465,55 @@ namespace Flow.Launcher
private void OnMouseDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left) DragMove();
// When the window is maximized via Snap,
// dragging attempts will first switch the window from Maximized to Normal state,
// and adjust the drag position accordingly.
if (e.ChangedButton == MouseButton.Left)
{
try
{
if (WindowState == WindowState.Maximized)
{
// Calculate ratio based on maximized window dimensions
double maxWidth = ActualWidth;
double maxHeight = ActualHeight;
var mousePos = e.GetPosition(this);
double xRatio = mousePos.X / maxWidth;
double yRatio = mousePos.Y / maxHeight;
// Current monitor information
var screen = Screen.FromHandle(new WindowInteropHelper(this).Handle);
var workingArea = screen.WorkingArea;
var screenLeftTop = Win32Helper.TransformPixelsToDIP(this, workingArea.X, workingArea.Y);
// Switch to Normal state
WindowState = WindowState.Normal;
Application.Current?.Dispatcher.Invoke(new Action(() =>
{
double normalWidth = Width;
double normalHeight = Height;
// Apply ratio based on the difference between maximized and normal window sizes
Left = screenLeftTop.X + (maxWidth - normalWidth) * xRatio;
Top = screenLeftTop.Y + (maxHeight - normalHeight) * yRatio;
if (Mouse.LeftButton == MouseButtonState.Pressed)
{
DragMove();
}
}), DispatcherPriority.ApplicationIdle);
}
else
{
DragMove();
}
}
catch (InvalidOperationException)
{
// Ignored - can occur if drag operation is already in progress
}
}
}
#endregion
@ -490,56 +538,76 @@ namespace Flow.Launcher
#region Window WndProc
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == Win32Helper.WM_ENTERSIZEMOVE)
switch (msg)
{
_initialWidth = (int)Width;
_initialHeight = (int)Height;
handled = true;
}
else if (msg == Win32Helper.WM_EXITSIZEMOVE)
{
if (_initialHeight != (int)Height)
{
if (!_settings.KeepMaxResults)
case Win32Helper.WM_ENTERSIZEMOVE:
_initialWidth = (int)Width;
_initialHeight = (int)Height;
handled = true;
break;
case Win32Helper.WM_EXITSIZEMOVE:
//Prevent updating the number of results when the window height is below the height of a single result item.
//This situation occurs not only when the user manually resizes the window, but also when the window is released from a side snap, as the OS automatically adjusts the window height.
//(Without this check, releasing from a snap can cause the window height to hit the minimum, resulting in only 2 results being shown.)
if (_initialHeight != (int)Height && Height > (_settings.WindowHeightSize + _settings.ItemHeightSize))
{
// Get shadow margin
var shadowMargin = 0;
var (_, useDropShadowEffect) = _theme.GetActualValue();
if (useDropShadowEffect)
if (!_settings.KeepMaxResults)
{
shadowMargin = 32;
// Get shadow margin
var shadowMargin = 0;
var (_, useDropShadowEffect) = _theme.GetActualValue();
if (useDropShadowEffect)
{
shadowMargin = 32;
}
// Calculate max results to show
var itemCount = (Height - (_settings.WindowHeightSize + 14) - shadowMargin) / _settings.ItemHeightSize;
if (itemCount < 2)
{
_settings.MaxResultsToShow = 2;
}
else
{
_settings.MaxResultsToShow = Convert.ToInt32(Math.Truncate(itemCount));
}
}
// Calculate max results to show
var itemCount = (Height - (_settings.WindowHeightSize + 14) - shadowMargin) / _settings.ItemHeightSize;
if (itemCount < 2)
{
_settings.MaxResultsToShow = 2;
}
else
{
_settings.MaxResultsToShow = Convert.ToInt32(Math.Truncate(itemCount));
}
SizeToContent = SizeToContent.Height;
}
else
{
// Update height when exiting maximized snap state.
SizeToContent = SizeToContent.Height;
}
SizeToContent = SizeToContent.Height;
}
if (_initialWidth != (int)Width)
{
if (!_settings.KeepMaxResults)
if (_initialWidth != (int)Width)
{
// Update width
_viewModel.MainWindowWidth = Width;
if (!_settings.KeepMaxResults)
{
// Update width
_viewModel.MainWindowWidth = Width;
}
SizeToContent = SizeToContent.Height;
}
handled = true;
break;
case Win32Helper.WM_NCLBUTTONDBLCLK: // Block the double click in frame
SizeToContent = SizeToContent.Height;
}
handled = true;
handled = true;
break;
case Win32Helper.WM_SYSCOMMAND: // Block Maximize/Minimize by Win+Up and Win+Down Arrow
var command = wParam.ToInt32() & 0xFFF0;
if (command == Win32Helper.SC_MAXIMIZE || command == Win32Helper.SC_MINIMIZE)
{
SizeToContent = SizeToContent.Height;
handled = true;
}
break;
}
return IntPtr.Zero;
@ -1016,7 +1084,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;
}
@ -1031,20 +1099,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;

View file

@ -160,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;
@ -188,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;

View file

@ -251,7 +251,7 @@ namespace Flow.Launcher
Http.GetStreamAsync(url, token);
public Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath, Action<double> reportProgress = null,
CancellationToken token = default) =>Http.DownloadAsync(url, filePath, reportProgress, token);
CancellationToken token = default) => Http.DownloadAsync(url, filePath, reportProgress, token);
public void AddActionKeyword(string pluginId, string newActionKeyword) =>
PluginManager.AddActionKeyword(pluginId, newActionKeyword);
@ -399,13 +399,27 @@ namespace Flow.Launcher
var path = browserInfo.Path == "*" ? "" : browserInfo.Path;
if (browserInfo.OpenInTab)
try
{
uri.AbsoluteUri.OpenInBrowserTab(path, inPrivate ?? browserInfo.EnablePrivate, browserInfo.PrivateArg);
if (browserInfo.OpenInTab)
{
uri.AbsoluteUri.OpenInBrowserTab(path, inPrivate ?? browserInfo.EnablePrivate, browserInfo.PrivateArg);
}
else
{
uri.AbsoluteUri.OpenInBrowserWindow(path, inPrivate ?? browserInfo.EnablePrivate, browserInfo.PrivateArg);
}
}
else
catch (Exception e)
{
uri.AbsoluteUri.OpenInBrowserWindow(path, inPrivate ?? browserInfo.EnablePrivate, browserInfo.PrivateArg);
var tabOrWindow = browserInfo.OpenInTab ? "tab" : "window";
LogException(ClassName, $"Failed to open URL in browser {tabOrWindow}: {path}, {inPrivate ?? browserInfo.EnablePrivate}, {browserInfo.PrivateArg}", e);
ShowMsgBox(
GetTranslation("browserOpenError"),
GetTranslation("errorTitle"),
MessageBoxButton.OK,
MessageBoxImage.Error
);
}
}
else

View file

@ -2407,6 +2407,79 @@
</Setter.Value>
</Setter>
</Style>
<!-- Explorer Plugin Expander -->
<Style x:Key="ExpanderHeaderRightArrowStyle" TargetType="ToggleButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border x:Name="RootBorder" Background="Transparent" Padding="16,15,16,15">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ContentPresenter
Grid.Column="0"
VerticalAlignment="Center"
HorizontalAlignment="Left"
RecognizesAccessKey="True"
SnapsToDevicePixels="True"
Content="{TemplateBinding Content}"
Margin="8 0 0 0"
ContentTemplate="{TemplateBinding ContentTemplate}" />
<Grid Grid.Column="1"
Width="20" Height="20"
Margin="8 0 4 0"
VerticalAlignment="Center"
HorizontalAlignment="Right"
Background="Transparent"
RenderTransformOrigin="0.5,0.5"
x:Name="ChevronGrid">
<Grid.RenderTransform>
<RotateTransform Angle="0"/>
</Grid.RenderTransform>
<Ellipse
x:Name="circle"
Width="19"
Height="19"
Stroke="Transparent"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
<Path
x:Name="arrow"
Data="M 1,1.5 L 4.5,5 L 8,1.5"
Stroke="#666"
StrokeThickness="1"
SnapsToDevicePixels="False"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="arrow" Property="Data" Value="M 1,4.5 L 4.5,1 L 8,4.5" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="RootBorder" Property="Background" Value="{DynamicResource CustomExpanderHover}" />
<Setter TargetName="circle" Property="Stroke" Value="Transparent" />
<Setter TargetName="arrow" Property="Stroke" Value="{DynamicResource Color05B}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="circle" Property="Stroke" Value="Transparent" />
<Setter TargetName="circle" Property="StrokeThickness" Value="1.5" />
<Setter TargetName="arrow" Property="Stroke" Value="{DynamicResource Color17B}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ExpanderStyle1" TargetType="{x:Type Expander}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
<Setter Property="Background" Value="Transparent" />

View file

@ -137,7 +137,7 @@
</cc:Card>
<cc:ExCard
Title="Advanced"
Title="{DynamicResource advanced}"
Margin="0 14 0 0"
Icon="&#xE8B7;">
<StackPanel>
@ -156,7 +156,7 @@
Icon="&#xf259;"
Type="Inside">
<StackPanel Orientation="Horizontal">
<Button Command="{Binding ResetSettingWindowFontCommand}" Content="Reset" />
<Button Command="{Binding ResetSettingWindowFontCommand}" Content="{DynamicResource commonReset}" />
<ComboBox
Margin="12 8 0 8"
HorizontalAlignment="Stretch"

View file

@ -154,7 +154,7 @@
Title="{DynamicResource AlwaysPreview}"
Margin="0 14 0 0"
Icon="&#xe8a1;"
Sub="{Binding AlwaysPreviewToolTip}">
Sub="{DynamicResource AlwaysPreviewToolTip}">
<ui:ToggleSwitch
IsOn="{Binding Settings.AlwaysPreview}"
OffContent="{DynamicResource disable}"

View file

@ -89,7 +89,10 @@
Title="{DynamicResource ToggleHistoryHotkey}"
Icon="&#xf738;"
Type="Inside">
<cc:HotkeyDisplay Keys="Ctrl+H" />
<flowlauncher:HotkeyControl
DefaultHotkey="Ctrl+H"
Type="OpenHistoryHotkey"
ValidateKeyGesture="False" />
</cc:Card>
<cc:Card
Title="{DynamicResource CopyFilePathHotkey}"

View file

@ -374,7 +374,7 @@
IsHitTestVisible="False"
Visibility="Visible" />
</ContentControl>
<Border x:Name="ContextMenu" Visibility="Collapsed" />
<Border x:Name="ResultContextMenu" Visibility="Collapsed" />
<Border x:Name="History" Visibility="Collapsed" />
</Grid>
</Border>

View file

@ -108,6 +108,10 @@
<Style x:Key="BasePendingLineStyle" TargetType="{x:Type Line}">
<Setter Property="Stroke" Value="{StaticResource SystemAccentColorLight1Brush}" />
</Style>
<Style
x:Key="PendingLineStyle"
BasedOn="{StaticResource BasePendingLineStyle}"
TargetType="{x:Type Line}" />
<Style x:Key="BaseClockPanelPosition" TargetType="{x:Type Canvas}" />
@ -479,7 +483,7 @@
<MultiDataTrigger.Conditions>
<!--
<Condition Binding="{Binding ElementName=ResultListBox, Path=Visibility}" Value="Collapsed" />
<Condition Binding="{Binding ElementName=ContextMenu, Path=Visibility}" Value="Collapsed" />-->
<Condition Binding="{Binding ElementName=ResultContextMenu, Path=Visibility}" Value="Collapsed" />-->
<Condition Binding="{Binding ElementName=History, Path=Visibility}" Value="Collapsed" />
<Condition Binding="{Binding ElementName=ResultListBox, Path=Items.Count}" Value="0" />
</MultiDataTrigger.Conditions>

View file

@ -137,6 +137,9 @@ namespace Flow.Launcher.ViewModel
case nameof(Settings.SettingWindowHotkey):
OnPropertyChanged(nameof(SettingWindowHotkey));
break;
case nameof(Settings.OpenHistoryHotkey):
OnPropertyChanged(nameof(OpenHistoryHotkey));
break;
}
};
@ -213,7 +216,26 @@ namespace Flow.Launcher.ViewModel
while (channelReader.TryRead(out var item))
{
if (!item.Token.IsCancellationRequested)
{
// Indicate if to clear existing results so to show only ones from plugins with action keywords
var query = item.Query;
var currentIsHomeQuery = query.IsHomeQuery;
var shouldClearExistingResults = ShouldClearExistingResultsForQuery(query, currentIsHomeQuery);
_lastQuery = item.Query;
_previousIsHomeQuery = currentIsHomeQuery;
// If the queue already has the item, we need to pass the shouldClearExistingResults flag
if (queue.TryGetValue(item.ID, out var existingItem))
{
item.ShouldClearExistingResults = shouldClearExistingResults || existingItem.ShouldClearExistingResults;
}
else
{
item.ShouldClearExistingResults = shouldClearExistingResults;
}
queue[item.ID] = item;
}
}
UpdateResultView(queue.Values);
@ -265,6 +287,8 @@ namespace Flow.Launcher.ViewModel
if (token.IsCancellationRequested) return;
App.API.LogDebug(ClassName, $"Update results for plugin <{pair.Metadata.Name}>");
if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(resultsCopy, pair.Metadata, e.Query,
token)))
{
@ -886,6 +910,7 @@ namespace Flow.Launcher.ViewModel
public string SelectPrevPageHotkey => VerifyOrSetDefaultHotkey(Settings.SelectPrevPageHotkey, "");
public string OpenContextMenuHotkey => VerifyOrSetDefaultHotkey(Settings.OpenContextMenuHotkey, "Ctrl+O");
public string SettingWindowHotkey => VerifyOrSetDefaultHotkey(Settings.SettingWindowHotkey, "Ctrl+I");
public string OpenHistoryHotkey => VerifyOrSetDefaultHotkey(Settings.OpenHistoryHotkey, "Ctrl+H");
public string CycleHistoryUpHotkey => VerifyOrSetDefaultHotkey(Settings.CycleHistoryUpHotkey, "Alt+Up");
public string CycleHistoryDownHotkey => VerifyOrSetDefaultHotkey(Settings.CycleHistoryDownHotkey, "Alt+Down");
@ -1258,7 +1283,7 @@ namespace Flow.Launcher.ViewModel
App.API.LogDebug(ClassName, $"Start query with ActionKeyword <{query.ActionKeyword}> and RawQuery <{query.RawQuery}>");
var currentIsHomeQuery = query.RawQuery == string.Empty;
var currentIsHomeQuery = query.IsHomeQuery;
_updateSource?.Dispose();
@ -1432,13 +1457,8 @@ namespace Flow.Launcher.ViewModel
App.API.LogDebug(ClassName, $"Update results for plugin <{plugin.Metadata.Name}>");
// Indicate if to clear existing results so to show only ones from plugins with action keywords
var shouldClearExistingResults = ShouldClearExistingResultsForQuery(query, currentIsHomeQuery);
_lastQuery = query;
_previousIsHomeQuery = currentIsHomeQuery;
if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(resultsCopy, plugin.Metadata, query,
token, reSelect, shouldClearExistingResults)))
token, reSelect)))
{
App.API.LogError(ClassName, "Unable to add item to Result Update Queue");
}
@ -1455,13 +1475,8 @@ namespace Flow.Launcher.ViewModel
App.API.LogDebug(ClassName, $"Update results for history");
// Indicate if to clear existing results so to show only ones from plugins with action keywords
var shouldClearExistingResults = ShouldClearExistingResultsForQuery(query, currentIsHomeQuery);
_lastQuery = query;
_previousIsHomeQuery = currentIsHomeQuery;
if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(results, _historyMetadata, query,
token, reSelect, shouldClearExistingResults)))
token, reSelect)))
{
App.API.LogError(ClassName, "Unable to add item to Result Update Queue");
}
@ -1861,6 +1876,7 @@ namespace Flow.Launcher.ViewModel
{
if (!resultsForUpdates.Any())
return;
CancellationToken token;
try

View file

@ -10,7 +10,7 @@ namespace Flow.Launcher.ViewModel
Query Query,
CancellationToken Token,
bool ReSelectFirstResult = true,
bool shouldClearExistingResults = false)
bool ShouldClearExistingResults = false)
{
public string ID { get; } = Metadata.ID;
}

View file

@ -17,6 +17,8 @@ namespace Flow.Launcher.ViewModel
{
#region Private Fields
private readonly string ClassName = nameof(ResultsViewModel);
public ResultCollection Results { get; }
private readonly object _collectionLock = new();
@ -187,11 +189,9 @@ namespace Flow.Launcher.ViewModel
/// </summary>
public void AddResults(ICollection<ResultsForUpdate> resultsForUpdates, CancellationToken token, bool reselect = true)
{
// Since NewResults may need to clear existing results, do not check token cancellation after this point
var newResults = NewResults(resultsForUpdates);
if (token.IsCancellationRequested)
return;
UpdateResults(newResults, reselect, token);
}
@ -240,16 +240,20 @@ namespace Flow.Launcher.ViewModel
private List<ResultViewModel> NewResults(ICollection<ResultsForUpdate> resultsForUpdates)
{
if (!resultsForUpdates.Any())
{
App.API.LogDebug(ClassName, "No results for updates, returning existing results");
return Results;
}
var newResults = resultsForUpdates.SelectMany(u => u.Results, (u, r) => new ResultViewModel(r, _settings));
if (resultsForUpdates.Any(x => x.shouldClearExistingResults))
if (resultsForUpdates.Any(x => x.ShouldClearExistingResults))
{
App.API.LogDebug("NewResults", $"Existing results are cleared for query");
App.API.LogDebug(ClassName, $"Existing results are cleared for query");
return newResults.OrderByDescending(rv => rv.Result.Score).ToList();
}
App.API.LogDebug(ClassName, $"Keeping existing results for {resultsForUpdates.Count} queries");
return Results.Where(r => r?.Result != null && resultsForUpdates.All(u => u.ID != r.Result.PluginID))
.Concat(newResults)
.OrderByDescending(rv => rv.Result.Score)
@ -293,8 +297,6 @@ namespace Flow.Launcher.ViewModel
{
private long editTime = 0;
private CancellationToken _token;
public event NotifyCollectionChangedEventHandler CollectionChanged;
protected void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
@ -302,12 +304,12 @@ namespace Flow.Launcher.ViewModel
CollectionChanged?.Invoke(this, e);
}
public void BulkAddAll(List<ResultViewModel> resultViews)
private void BulkAddAll(List<ResultViewModel> resultViews, CancellationToken token = default)
{
AddRange(resultViews);
// can return because the list will be cleared next time updated, which include a reset event
if (_token.IsCancellationRequested)
if (token.IsCancellationRequested)
return;
// manually update event
@ -315,12 +317,12 @@ namespace Flow.Launcher.ViewModel
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
private void AddAll(List<ResultViewModel> Items)
private void AddAll(List<ResultViewModel> Items, CancellationToken token = default)
{
for (int i = 0; i < Items.Count; i++)
{
var item = Items[i];
if (_token.IsCancellationRequested)
if (token.IsCancellationRequested)
return;
Add(item);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, i));
@ -342,21 +344,30 @@ namespace Flow.Launcher.ViewModel
/// <param name="newItems"></param>
public void Update(List<ResultViewModel> newItems, CancellationToken token = default)
{
_token = token;
if (Count == 0 && newItems.Count == 0 || _token.IsCancellationRequested)
// Since NewResults may need to clear existing results, so we cannot check token cancellation here
if (Count == 0 && newItems.Count == 0)
return;
if (editTime < 10 || newItems.Count < 30)
{
if (Count != 0) RemoveAll(newItems.Count);
AddAll(newItems);
// After results are removed, we need to check the token cancellation
// so that we will not add new items from the cancelled queries
if (token.IsCancellationRequested) return;
AddAll(newItems, token);
editTime++;
return;
}
else
{
Clear();
BulkAddAll(newItems);
// After results are removed, we need to check the token cancellation
// so that we will not add new items from the cancelled queries
if (token.IsCancellationRequested) return;
BulkAddAll(newItems, token);
if (Capacity > 8000 && newItems.Count < 3000)
{
Capacity = newItems.Count;

View file

@ -1,7 +1,9 @@
using System.Collections.Generic;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System;
using System.Threading.Tasks;
using Flow.Launcher.Plugin.BrowserBookmark.Models;
using Microsoft.Data.Sqlite;
@ -43,16 +45,23 @@ public abstract class ChromiumBookmarkLoader : IBookmarkLoader
catch (Exception ex)
{
Main._context.API.LogException(ClassName, $"Failed to register bookmark file monitoring: {bookmarkPath}", ex);
continue;
}
var source = name + (Path.GetFileName(profile) == "Default" ? "" : $" ({Path.GetFileName(profile)})");
var profileBookmarks = LoadBookmarksFromFile(bookmarkPath, source);
// Load favicons after loading bookmarks
var faviconDbPath = Path.Combine(profile, "Favicons");
if (File.Exists(faviconDbPath))
if (Main._settings.EnableFavicons)
{
LoadFaviconsFromDb(faviconDbPath, profileBookmarks);
var faviconDbPath = Path.Combine(profile, "Favicons");
if (File.Exists(faviconDbPath))
{
Main._context.API.StopwatchLogInfo(ClassName, $"Load {profileBookmarks.Count} favicons cost", () =>
{
LoadFaviconsFromDb(faviconDbPath, profileBookmarks);
});
}
}
bookmarks.AddRange(profileBookmarks);
@ -148,19 +157,24 @@ public abstract class ChromiumBookmarkLoader : IBookmarkLoader
try
{
using var connection = new SqliteConnection($"Data Source={tempDbPath}");
connection.Open();
// Since some bookmarks may have same favicon id, we need to record them to avoid duplicates
var savedPaths = new ConcurrentDictionary<string, bool>();
foreach (var bookmark in bookmarks)
// Get favicons based on bookmarks concurrently
Parallel.ForEach(bookmarks, bookmark =>
{
// Use read-only connection to avoid locking issues
var connection = new SqliteConnection($"Data Source={tempDbPath};Mode=ReadOnly");
connection.Open();
try
{
var url = bookmark.Url;
if (string.IsNullOrEmpty(url)) continue;
if (string.IsNullOrEmpty(url)) return;
// Extract domain from URL
if (!Uri.TryCreate(url, UriKind.Absolute, out Uri uri))
continue;
return;
var domain = uri.Host;
@ -178,16 +192,21 @@ public abstract class ChromiumBookmarkLoader : IBookmarkLoader
using var reader = cmd.ExecuteReader();
if (!reader.Read() || reader.IsDBNull(1))
continue;
return;
var iconId = reader.GetInt64(0).ToString();
var imageData = (byte[])reader["image_data"];
if (imageData is not { Length: > 0 })
continue;
return;
var faviconPath = Path.Combine(_faviconCacheDir, $"chromium_{domain}_{iconId}.png");
SaveBitmapData(imageData, faviconPath);
// Filter out duplicate favicons
if (savedPaths.TryAdd(faviconPath, true))
{
SaveBitmapData(imageData, faviconPath);
}
bookmark.FaviconPath = faviconPath;
}
@ -195,11 +214,14 @@ public abstract class ChromiumBookmarkLoader : IBookmarkLoader
{
Main._context.API.LogException(ClassName, $"Failed to extract bookmark favicon: {bookmark.Url}", ex);
}
}
// https://github.com/dotnet/efcore/issues/26580
SqliteConnection.ClearPool(connection);
connection.Close();
finally
{
// https://github.com/dotnet/efcore/issues/26580
SqliteConnection.ClearPool(connection);
connection.Close();
connection.Dispose();
}
});
}
catch (Exception ex)
{

View file

@ -1,7 +1,9 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Flow.Launcher.Plugin.BrowserBookmark.Models;
using Microsoft.Data.Sqlite;
@ -30,8 +32,6 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
ORDER BY moz_places.visit_count DESC
""";
private const string DbPathFormat = "Data Source={0}";
protected List<Bookmark> GetBookmarksFromPath(string placesPath)
{
// Variable to store bookmark list
@ -41,30 +41,32 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
if (string.IsNullOrEmpty(placesPath) || !File.Exists(placesPath))
return bookmarks;
// Try to register file monitoring
try
{
Main.RegisterBookmarkFile(placesPath);
}
catch (Exception ex)
{
Main._context.API.LogException(ClassName, $"Failed to register Firefox bookmark file monitoring: {placesPath}", ex);
return bookmarks;
}
var tempDbPath = Path.Combine(_faviconCacheDir, $"tempplaces_{Guid.NewGuid()}.sqlite");
try
{
// Try to register file monitoring
try
{
Main.RegisterBookmarkFile(placesPath);
}
catch (Exception ex)
{
Main._context.API.LogException(ClassName, $"Failed to register Firefox bookmark file monitoring: {placesPath}", ex);
}
// Use a copy to avoid lock issues with the original file
File.Copy(placesPath, tempDbPath, true);
// Connect to database and execute query
string dbPath = string.Format(DbPathFormat, tempDbPath);
using var dbConnection = new SqliteConnection(dbPath);
// Create the connection string and init the connection
using var dbConnection = new SqliteConnection($"Data Source={tempDbPath};Mode=ReadOnly");
// Open connection to the database file and execute the query
dbConnection.Open();
var reader = new SqliteCommand(QueryAllBookmarks, dbConnection).ExecuteReader();
// Create bookmark list
// Get results in List<Bookmark> format
bookmarks = reader
.Select(
x => new Bookmark(
@ -75,12 +77,20 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
)
.ToList();
// Path to favicon database
var faviconDbPath = Path.Combine(Path.GetDirectoryName(placesPath), "favicons.sqlite");
if (File.Exists(faviconDbPath))
// Load favicons after loading bookmarks
if (Main._settings.EnableFavicons)
{
LoadFaviconsFromDb(faviconDbPath, bookmarks);
var faviconDbPath = Path.Combine(Path.GetDirectoryName(placesPath), "favicons.sqlite");
if (File.Exists(faviconDbPath))
{
Main._context.API.StopwatchLogInfo(ClassName, $"Load {bookmarks.Count} favicons cost", () =>
{
LoadFaviconsFromDb(faviconDbPath, bookmarks);
});
}
}
// Close the connection so that we can delete the temporary file
// https://github.com/dotnet/efcore/issues/26580
SqliteConnection.ClearPool(dbConnection);
dbConnection.Close();
@ -93,7 +103,10 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
// Delete temporary file
try
{
File.Delete(tempDbPath);
if (File.Exists(tempDbPath))
{
File.Delete(tempDbPath);
}
}
catch (Exception ex)
{
@ -103,34 +116,52 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
return bookmarks;
}
private void LoadFaviconsFromDb(string faviconDbPath, List<Bookmark> bookmarks)
private void LoadFaviconsFromDb(string dbPath, List<Bookmark> bookmarks)
{
// Use a copy to avoid lock issues with the original file
var tempDbPath = Path.Combine(_faviconCacheDir, $"tempfavicons_{Guid.NewGuid()}.sqlite");
try
{
// Use a copy to avoid lock issues with the original file
File.Copy(faviconDbPath, tempDbPath, true);
var defaultIconPath = Path.Combine(
Path.GetDirectoryName(typeof(FirefoxBookmarkLoaderBase).Assembly.Location),
"bookmark.png");
string dbPath = string.Format(DbPathFormat, tempDbPath);
using var connection = new SqliteConnection(dbPath);
connection.Open();
// Get favicons based on bookmark URLs
foreach (var bookmark in bookmarks)
File.Copy(dbPath, tempDbPath, true);
}
catch (Exception ex)
{
try
{
if (File.Exists(tempDbPath))
{
File.Delete(tempDbPath);
}
}
catch (Exception ex1)
{
Main._context.API.LogException(ClassName, $"Failed to delete temporary favicon DB: {tempDbPath}", ex1);
}
Main._context.API.LogException(ClassName, $"Failed to copy favicon DB: {dbPath}", ex);
return;
}
try
{
// Since some bookmarks may have same favicon id, we need to record them to avoid duplicates
var savedPaths = new ConcurrentDictionary<string, bool>();
// Get favicons based on bookmarks concurrently
Parallel.ForEach(bookmarks, bookmark =>
{
// Use read-only connection to avoid locking issues
var connection = new SqliteConnection($"Data Source={tempDbPath};Mode=ReadOnly");
connection.Open();
try
{
if (string.IsNullOrEmpty(bookmark.Url))
continue;
return;
// Extract domain from URL
if (!Uri.TryCreate(bookmark.Url, UriKind.Absolute, out Uri uri))
continue;
return;
var domain = uri.Host;
@ -150,12 +181,12 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
using var reader = cmd.ExecuteReader();
if (!reader.Read() || reader.IsDBNull(0))
continue;
return;
var imageData = (byte[])reader["data"];
if (imageData is not { Length: > 0 })
continue;
return;
string faviconPath;
if (IsSvgData(imageData))
@ -166,7 +197,12 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
{
faviconPath = Path.Combine(_faviconCacheDir, $"firefox_{domain}.png");
}
SaveBitmapData(imageData, faviconPath);
// Filter out duplicate favicons
if (savedPaths.TryAdd(faviconPath, true))
{
SaveBitmapData(imageData, faviconPath);
}
bookmark.FaviconPath = faviconPath;
}
@ -174,15 +210,18 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
{
Main._context.API.LogException(ClassName, $"Failed to extract Firefox favicon: {bookmark.Url}", ex);
}
}
// https://github.com/dotnet/efcore/issues/26580
SqliteConnection.ClearPool(connection);
connection.Close();
finally
{
// https://github.com/dotnet/efcore/issues/26580
SqliteConnection.ClearPool(connection);
connection.Close();
connection.Dispose();
}
});
}
catch (Exception ex)
{
Main._context.API.LogException(ClassName, $"Failed to load Firefox favicon DB: {faviconDbPath}", ex);
Main._context.API.LogException(ClassName, $"Failed to load Firefox favicon DB: {tempDbPath}", ex);
}
// Delete temporary file
@ -231,6 +270,7 @@ public class FirefoxBookmarkLoader : FirefoxBookmarkLoaderBase
/// <summary>
/// Path to places.sqlite
/// </summary>
/// <remarks></remarks>
private static string PlacesPath
{
get
@ -256,12 +296,50 @@ public class FirefoxBookmarkLoader : FirefoxBookmarkLoaderBase
var indexOfDefaultProfileAttributePath = lines.IndexOf("Path=" + defaultProfileFolderName);
/*
Current profiles.ini structure example as of Firefox version 69.0.1
[Install736426B0AF4A39CB]
Default=Profiles/7789f565.default-release <== this is the default profile this plugin will get the bookmarks from. When opened Firefox will load the default profile
Locked=1
[Profile2]
Name=newblahprofile
IsRelative=0
Path=C:\t6h2yuq8.newblahprofile <== Note this is a custom location path for the profile user can set, we need to cater for this in code.
[Profile1]
Name=default
IsRelative=1
Path=Profiles/cydum7q4.default
Default=1
[Profile0]
Name=default-release
IsRelative=1
Path=Profiles/7789f565.default-release
[General]
StartWithLastProfile=1
Version=2
*/
// Seen in the example above, the IsRelative attribute is always above the Path attribute
var relativePath = Path.Combine(defaultProfileFolderName, "places.sqlite");
var absoluePath = Path.Combine(profileFolderPath, relativePath);
// If the index is out of range, it means that the default profile is in a custom location or the file is malformed
// If the profile is in a custom location, we need to check
if (indexOfDefaultProfileAttributePath - 1 < 0 ||
indexOfDefaultProfileAttributePath - 1 >= lines.Count)
{
return Directory.Exists(absoluePath) ? absoluePath : relativePath;
}
var relativeAttribute = lines[indexOfDefaultProfileAttributePath - 1];
return relativeAttribute == "0" // See above, the profile is located in a custom location, path is not relative, so IsRelative=0
? defaultProfileFolderName + @"\places.sqlite"
: Path.Combine(profileFolderPath, defaultProfileFolderName) + @"\places.sqlite";
? relativePath : absoluePath;
}
}
}

View file

@ -27,4 +27,6 @@
<system:String x:Key="flowlauncher_plugin_browserbookmark_browserEngine">Browser Engine</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_guideMessage01">If you are not using Chrome, Firefox or Edge, or you are using their portable version, you need to add bookmarks data directory and select correct browser engine to make this plugin work.</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_guideMessage02">For example: Brave's engine is Chromium; and its default bookmarks data location is: "%LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData". For Firefox engine, the bookmarks directory is the userdata folder contains the places.sqlite file.</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_enable_favicons">Load favicons (can be time consuming during startup)</system:String>
</ResourceDictionary>

View file

@ -1,14 +1,14 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Channels;
using System.Threading.Tasks;
using System.Threading;
using System.Windows.Controls;
using Flow.Launcher.Plugin.BrowserBookmark.Commands;
using Flow.Launcher.Plugin.BrowserBookmark.Models;
using Flow.Launcher.Plugin.BrowserBookmark.Views;
using System.IO;
using System.Threading.Channels;
using System.Threading.Tasks;
using System.Threading;
using Flow.Launcher.Plugin.SharedCommands;
namespace Flow.Launcher.Plugin.BrowserBookmark;
@ -21,9 +21,9 @@ public class Main : ISettingProvider, IPlugin, IReloadable, IPluginI18n, IContex
internal static PluginInitContext _context;
private static List<Bookmark> _cachedBookmarks = new();
internal static Settings _settings;
private static Settings _settings;
private static List<Bookmark> _cachedBookmarks = new();
private static bool _initialized = false;

View file

@ -8,6 +8,8 @@ public class Settings : BaseModel
public string BrowserPath { get; set; }
public bool EnableFavicons { get; set; } = false;
public bool LoadChromeBookmark { get; set; } = true;
public bool LoadFirefoxBookmark { get; set; } = true;
public bool LoadEdgeBookmark { get; set; } = true;

View file

@ -12,6 +12,7 @@
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel
Grid.Row="0"
@ -91,5 +92,12 @@
Content="{DynamicResource flowlauncher_plugin_browserbookmark_removeBrowserBookmark}" />
</StackPanel>
</StackPanel>
<CheckBox
Grid.Row="2"
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Content="{DynamicResource flowlauncher_plugin_browserbookmark_enable_favicons}"
IsChecked="{Binding Settings.EnableFavicons}" />
</Grid>
</UserControl>

View file

@ -201,10 +201,10 @@ namespace Flow.Launcher.Plugin.Explorer
{
if (Context.API.ShowMsgBox(
string.Format(Context.API.GetTranslation("plugin_explorer_delete_folder_link"), record.FullPath),
string.Empty,
MessageBoxButton.YesNo,
Context.API.GetTranslation("plugin_explorer_deletefilefolder"),
MessageBoxButton.OKCancel,
MessageBoxImage.Warning)
== MessageBoxResult.No)
== MessageBoxResult.Cancel)
return false;
if (isFile)

View file

@ -31,6 +31,7 @@
<system:String x:Key="plugin_explorer_previewpanel_display_file_size_checkbox">الحجم</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_creation_checkbox">تاريخ الإنشاء</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_modification_checkbox">تاريخ التعديل</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_age_checkbox">File Age</system:String>
<system:String x:Key="plugin_explorer_previewpanel_file_info_label">عرض معلومات الملف</system:String>
<system:String x:Key="plugin_explorer_previewpanel_date_and_time_format_label">تنسيق التاريخ والوقت</system:String>
<system:String x:Key="plugin_explorer_everything_sort_option">خيارات الترتيب:</system:String>
@ -164,4 +165,12 @@
<system:String x:Key="plugin_explorer_native_context_menu_display_context_menu">عرض قائمة السياق الأصلية (تجريبي)</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_include_patterns_guide">أدناه يمكنك تحديد العناصر التي تريد تضمينها في قائمة السياق، يمكن أن تكون جزئية (على سبيل المثال 'pen wit') أو كاملة ('فتح بواسطة').</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_exclude_patterns_guide">يمكنك أدناه تحديد العناصر التي تريد استبعادها من قائمة الضغط الأيمن، يمكن أن تكون جزئية (على سبيل المثال، 'pen wit') أو كاملة ('Open with').</system:String>
<!-- Preview Info -->
<system:String x:Key="Today">Today</system:String>
<system:String x:Key="DaysAgo">{0} days ago</system:String>
<system:String x:Key="OneMonthAgo">1 month ago</system:String>
<system:String x:Key="MonthsAgo">{0} months ago</system:String>
<system:String x:Key="OneYearAgo">1 year ago</system:String>
<system:String x:Key="YearsAgo">{0} years ago</system:String>
</ResourceDictionary>

View file

@ -31,6 +31,7 @@
<system:String x:Key="plugin_explorer_previewpanel_display_file_size_checkbox">Velikost</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_creation_checkbox">Datum vytvoření</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_modification_checkbox">Datum změny</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_age_checkbox">File Age</system:String>
<system:String x:Key="plugin_explorer_previewpanel_file_info_label">Display File Info</system:String>
<system:String x:Key="plugin_explorer_previewpanel_date_and_time_format_label">Date and time format</system:String>
<system:String x:Key="plugin_explorer_everything_sort_option">Možnosti řazení:</system:String>
@ -164,4 +165,12 @@
<system:String x:Key="plugin_explorer_native_context_menu_display_context_menu">Display native context menu (experimental)</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_include_patterns_guide">Below you can specify items you want to include in the context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_exclude_patterns_guide">Below you can specify items you want to exclude from context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<!-- Preview Info -->
<system:String x:Key="Today">Today</system:String>
<system:String x:Key="DaysAgo">{0} days ago</system:String>
<system:String x:Key="OneMonthAgo">1 month ago</system:String>
<system:String x:Key="MonthsAgo">{0} months ago</system:String>
<system:String x:Key="OneYearAgo">1 year ago</system:String>
<system:String x:Key="YearsAgo">{0} years ago</system:String>
</ResourceDictionary>

View file

@ -31,6 +31,7 @@
<system:String x:Key="plugin_explorer_previewpanel_display_file_size_checkbox">Size</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_creation_checkbox">Date Created</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_modification_checkbox">Date Modified</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_age_checkbox">File Age</system:String>
<system:String x:Key="plugin_explorer_previewpanel_file_info_label">Display File Info</system:String>
<system:String x:Key="plugin_explorer_previewpanel_date_and_time_format_label">Date and time format</system:String>
<system:String x:Key="plugin_explorer_everything_sort_option">Sort Option:</system:String>
@ -164,4 +165,12 @@
<system:String x:Key="plugin_explorer_native_context_menu_display_context_menu">Display native context menu (experimental)</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_include_patterns_guide">Below you can specify items you want to include in the context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_exclude_patterns_guide">Below you can specify items you want to exclude from context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<!-- Preview Info -->
<system:String x:Key="Today">Today</system:String>
<system:String x:Key="DaysAgo">{0} days ago</system:String>
<system:String x:Key="OneMonthAgo">1 month ago</system:String>
<system:String x:Key="MonthsAgo">{0} months ago</system:String>
<system:String x:Key="OneYearAgo">1 year ago</system:String>
<system:String x:Key="YearsAgo">{0} years ago</system:String>
</ResourceDictionary>

View file

@ -31,6 +31,7 @@
<system:String x:Key="plugin_explorer_previewpanel_display_file_size_checkbox">Größe</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_creation_checkbox">Erstellungsdatum</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_modification_checkbox">Änderungsdatum</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_age_checkbox">File Age</system:String>
<system:String x:Key="plugin_explorer_previewpanel_file_info_label">Datei-Info anzeigen</system:String>
<system:String x:Key="plugin_explorer_previewpanel_date_and_time_format_label">Datums- und Zeitformat</system:String>
<system:String x:Key="plugin_explorer_everything_sort_option">Sortieroption:</system:String>
@ -164,4 +165,12 @@
<system:String x:Key="plugin_explorer_native_context_menu_display_context_menu">Natives Kontextmenü anzeigen (experimentell)</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_include_patterns_guide">Unten können Sie die Elemente angeben, die Sie in das Kontextmenü aufnehmen möchten. Diese können partiell (z. B. „Stift mit“) oder vollständig („Öffnen mit“) sein.</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_exclude_patterns_guide">Unten können Sie die Elemente angeben, die Sie aus dem Kontextmenü ausschließen möchten. Diese können partiell (z. B. „Stift mit“) oder vollständig („Öffnen mit“) sein.</system:String>
<!-- Preview Info -->
<system:String x:Key="Today">Today</system:String>
<system:String x:Key="DaysAgo">{0} days ago</system:String>
<system:String x:Key="OneMonthAgo">1 month ago</system:String>
<system:String x:Key="MonthsAgo">{0} months ago</system:String>
<system:String x:Key="OneYearAgo">1 year ago</system:String>
<system:String x:Key="YearsAgo">{0} years ago</system:String>
</ResourceDictionary>

View file

@ -166,6 +166,9 @@
<system:String x:Key="flowlauncher_plugin_everything_enable_content_search">Do you want to enable content search for Everything?</system:String>
<system:String x:Key="flowlauncher_plugin_everything_enable_content_search_tips">It can be very slow without index (which is only supported in Everything v1.5+)</system:String>
<system:String x:Key="flowlauncher_plugin_everything_not_found">Unable to find Everything.exe</system:String>
<system:String x:Key="flowlauncher_plugin_everything_install_issue">Failed to install Everything, please install it manually</system:String>
<!-- Native Context Menu -->
<system:String x:Key="plugin_explorer_native_context_menu_header">Native Context Menu</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_display_context_menu">Display native context menu (experimental)</system:String>

View file

@ -31,6 +31,7 @@
<system:String x:Key="plugin_explorer_previewpanel_display_file_size_checkbox">Size</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_creation_checkbox">Fecha de creación</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_modification_checkbox">Fecha de modificación</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_age_checkbox">File Age</system:String>
<system:String x:Key="plugin_explorer_previewpanel_file_info_label">Display File Info</system:String>
<system:String x:Key="plugin_explorer_previewpanel_date_and_time_format_label">Date and time format</system:String>
<system:String x:Key="plugin_explorer_everything_sort_option">Sort Option:</system:String>
@ -164,4 +165,12 @@
<system:String x:Key="plugin_explorer_native_context_menu_display_context_menu">Display native context menu (experimental)</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_include_patterns_guide">Below you can specify items you want to include in the context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_exclude_patterns_guide">Below you can specify items you want to exclude from context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<!-- Preview Info -->
<system:String x:Key="Today">Today</system:String>
<system:String x:Key="DaysAgo">{0} days ago</system:String>
<system:String x:Key="OneMonthAgo">1 month ago</system:String>
<system:String x:Key="MonthsAgo">{0} months ago</system:String>
<system:String x:Key="OneYearAgo">1 year ago</system:String>
<system:String x:Key="YearsAgo">{0} years ago</system:String>
</ResourceDictionary>

View file

@ -31,6 +31,7 @@
<system:String x:Key="plugin_explorer_previewpanel_display_file_size_checkbox">Tamaño</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_creation_checkbox">Fecha de creación</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_modification_checkbox">Fecha de modificación</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_age_checkbox">Edad del archivo</system:String>
<system:String x:Key="plugin_explorer_previewpanel_file_info_label">Mostrar información del archivo</system:String>
<system:String x:Key="plugin_explorer_previewpanel_date_and_time_format_label">Formato de fecha y hora</system:String>
<system:String x:Key="plugin_explorer_everything_sort_option">Ordenar por:</system:String>
@ -164,4 +165,12 @@
<system:String x:Key="plugin_explorer_native_context_menu_display_context_menu">Mostrar menú contextual nativo (experimental)</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_include_patterns_guide">En el siguiente cuadro puede especificar los elementos que desea incluir en el menú contextual, puede describirlos de forma parcial (p. ej., 'brir co') o completa ('Abrir con').</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_exclude_patterns_guide">En el siguiente cuadro puede especificar los elementos que desea excluir en el menú contextual, puede describirlos de forma parcial (p. ej., 'brir co') o completa ('Abrir con').</system:String>
<!-- Preview Info -->
<system:String x:Key="Today">Hoy</system:String>
<system:String x:Key="DaysAgo">Hace {0} días</system:String>
<system:String x:Key="OneMonthAgo">Hace 1 mes</system:String>
<system:String x:Key="MonthsAgo">Hace {0} meses</system:String>
<system:String x:Key="OneYearAgo">Hace 1 año</system:String>
<system:String x:Key="YearsAgo">Hace {0} años</system:String>
</ResourceDictionary>

View file

@ -31,6 +31,7 @@
<system:String x:Key="plugin_explorer_previewpanel_display_file_size_checkbox">Taille</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_creation_checkbox">Date de création</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_modification_checkbox">Date de modification</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_age_checkbox">Âge du fichier</system:String>
<system:String x:Key="plugin_explorer_previewpanel_file_info_label">Afficher les informations du fichier</system:String>
<system:String x:Key="plugin_explorer_previewpanel_date_and_time_format_label">Format de la date et de l'heure</system:String>
<system:String x:Key="plugin_explorer_everything_sort_option">Option de tri :</system:String>
@ -164,4 +165,12 @@
<system:String x:Key="plugin_explorer_native_context_menu_display_context_menu">Afficher le menu contextuel natif (expérimental)</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_include_patterns_guide">Ci-dessous, vous pouvez spécifier les éléments que vous souhaitez inclure dans le menu contextuel. Ils peuvent être partiels ('pen wit') ou complets ('Ouvrir avec').</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_exclude_patterns_guide">Vous pouvez spécifier ci-dessous les éléments que vous souhaitez exclure du menu contextuel. Ces éléments peuvent être partiels (par exemple, &quot;pen wit&quot;) ou complets (&quot;Ouvrir avec&quot;).</system:String>
<!-- Preview Info -->
<system:String x:Key="Today">Aujourdhui</system:String>
<system:String x:Key="DaysAgo">Il y a {0} jours</system:String>
<system:String x:Key="OneMonthAgo">il y a 1 mois</system:String>
<system:String x:Key="MonthsAgo">Il y a {0} mois</system:String>
<system:String x:Key="OneYearAgo">il y a 1 an</system:String>
<system:String x:Key="YearsAgo">Il y a {0} ans</system:String>
</ResourceDictionary>

View file

@ -31,6 +31,7 @@
<system:String x:Key="plugin_explorer_previewpanel_display_file_size_checkbox">גודל</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_creation_checkbox">תאריך יצירה</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_modification_checkbox">תאריך שינוי</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_age_checkbox">גיל הקובץ</system:String>
<system:String x:Key="plugin_explorer_previewpanel_file_info_label">הצגת מידע על קובץ</system:String>
<system:String x:Key="plugin_explorer_previewpanel_date_and_time_format_label">תבנית תאריך ושעה</system:String>
<system:String x:Key="plugin_explorer_everything_sort_option">אפשרות מיון:</system:String>
@ -164,4 +165,12 @@
<system:String x:Key="plugin_explorer_native_context_menu_display_context_menu">הצג תפריט הקשר מקורי (ניסיוני)</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_include_patterns_guide">כאן תוכל להגדיר פריטים שברצונך לכלול בתפריט ההקשר, הם יכולים להיות חלקיים (למשל 'pen wit') או שלמים ('Open with').</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_exclude_patterns_guide">כאן תוכל להגדיר פריטים שברצונך להחריג מתפריט ההקשר, הם יכולים להיות חלקיים (למשל 'pen wit') או שלמים ('Open with').</system:String>
<!-- Preview Info -->
<system:String x:Key="Today">היום</system:String>
<system:String x:Key="DaysAgo">לפני {0} ימים</system:String>
<system:String x:Key="OneMonthAgo">לפני חודש אחד</system:String>
<system:String x:Key="MonthsAgo">לפני {0} חודשים</system:String>
<system:String x:Key="OneYearAgo">לפני שנה אחת</system:String>
<system:String x:Key="YearsAgo">לפני {0} שנים</system:String>
</ResourceDictionary>

View file

@ -31,6 +31,7 @@
<system:String x:Key="plugin_explorer_previewpanel_display_file_size_checkbox">Dimensioni</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_creation_checkbox">Data di creazione</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_modification_checkbox">Data della modifica</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_age_checkbox">File Age</system:String>
<system:String x:Key="plugin_explorer_previewpanel_file_info_label">Visualizza Informazioni File</system:String>
<system:String x:Key="plugin_explorer_previewpanel_date_and_time_format_label">Formato data e ora</system:String>
<system:String x:Key="plugin_explorer_everything_sort_option">Opzioni di ordinamento:</system:String>
@ -164,4 +165,12 @@
<system:String x:Key="plugin_explorer_native_context_menu_display_context_menu">Visualizza il menu contestuale nativo (sperimentale)</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_include_patterns_guide">Sotto si può specificare elementi che si vuole includere nel menu contestuale, che possono essere parziali (es 'pri co') o completi ('Apri con').</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_exclude_patterns_guide">Below you can specify items you want to exclude from context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<!-- Preview Info -->
<system:String x:Key="Today">Today</system:String>
<system:String x:Key="DaysAgo">{0} days ago</system:String>
<system:String x:Key="OneMonthAgo">1 month ago</system:String>
<system:String x:Key="MonthsAgo">{0} months ago</system:String>
<system:String x:Key="OneYearAgo">1 year ago</system:String>
<system:String x:Key="YearsAgo">{0} years ago</system:String>
</ResourceDictionary>

View file

@ -31,6 +31,7 @@
<system:String x:Key="plugin_explorer_previewpanel_display_file_size_checkbox">サイズ</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_creation_checkbox">作成日時</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_modification_checkbox">更新日時</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_age_checkbox">File Age</system:String>
<system:String x:Key="plugin_explorer_previewpanel_file_info_label">ファイル情報の表示</system:String>
<system:String x:Key="plugin_explorer_previewpanel_date_and_time_format_label">日付と時刻の形式</system:String>
<system:String x:Key="plugin_explorer_everything_sort_option">Sort Option:</system:String>
@ -164,4 +165,12 @@
<system:String x:Key="plugin_explorer_native_context_menu_display_context_menu">Display native context menu (experimental)</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_include_patterns_guide">Below you can specify items you want to include in the context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_exclude_patterns_guide">Below you can specify items you want to exclude from context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<!-- Preview Info -->
<system:String x:Key="Today">Today</system:String>
<system:String x:Key="DaysAgo">{0} days ago</system:String>
<system:String x:Key="OneMonthAgo">1 month ago</system:String>
<system:String x:Key="MonthsAgo">{0} months ago</system:String>
<system:String x:Key="OneYearAgo">1 year ago</system:String>
<system:String x:Key="YearsAgo">{0} years ago</system:String>
</ResourceDictionary>

View file

@ -31,6 +31,7 @@
<system:String x:Key="plugin_explorer_previewpanel_display_file_size_checkbox">크기</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_creation_checkbox">만든 날짜</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_modification_checkbox">수정한 날짜</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_age_checkbox">File Age</system:String>
<system:String x:Key="plugin_explorer_previewpanel_file_info_label">파일 정보 표시</system:String>
<system:String x:Key="plugin_explorer_previewpanel_date_and_time_format_label">시간과 날짜 형식</system:String>
<system:String x:Key="plugin_explorer_everything_sort_option">정렬 옵션:</system:String>
@ -80,8 +81,8 @@
<!-- Context menu items -->
<system:String x:Key="plugin_explorer_copypath">경로 복사</system:String>
<system:String x:Key="plugin_explorer_copypath_subtitle">이 항목의 경로를 클립보드에 복사</system:String>
<system:String x:Key="plugin_explorer_copyname">Copy name</system:String>
<system:String x:Key="plugin_explorer_copyname_subtitle">Copy name of current item to clipboard</system:String>
<system:String x:Key="plugin_explorer_copyname">이름 복사</system:String>
<system:String x:Key="plugin_explorer_copyname_subtitle">이 항목의 이름을 클립보드에 복사</system:String>
<system:String x:Key="plugin_explorer_copyfilefolder">복사하기</system:String>
<system:String x:Key="plugin_explorer_copyfile_subtitle">이 파일을 클립보드에 복사</system:String>
<system:String x:Key="plugin_explorer_copyfolder_subtitle">이 파일을 클립보드에 복사</system:String>
@ -164,4 +165,12 @@
<system:String x:Key="plugin_explorer_native_context_menu_display_context_menu">Display native context menu (experimental)</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_include_patterns_guide">Below you can specify items you want to include in the context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_exclude_patterns_guide">Below you can specify items you want to exclude from context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<!-- Preview Info -->
<system:String x:Key="Today">Today</system:String>
<system:String x:Key="DaysAgo">{0} days ago</system:String>
<system:String x:Key="OneMonthAgo">1 month ago</system:String>
<system:String x:Key="MonthsAgo">{0} months ago</system:String>
<system:String x:Key="OneYearAgo">1 year ago</system:String>
<system:String x:Key="YearsAgo">{0} years ago</system:String>
</ResourceDictionary>

View file

@ -31,6 +31,7 @@
<system:String x:Key="plugin_explorer_previewpanel_display_file_size_checkbox">Størrelse</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_creation_checkbox">Dato opprettet</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_modification_checkbox">Dato endret</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_age_checkbox">File Age</system:String>
<system:String x:Key="plugin_explorer_previewpanel_file_info_label">Vis filinfo</system:String>
<system:String x:Key="plugin_explorer_previewpanel_date_and_time_format_label">Dato- og klokkeslettformat</system:String>
<system:String x:Key="plugin_explorer_everything_sort_option">Alternativ for sortering:</system:String>
@ -164,4 +165,12 @@
<system:String x:Key="plugin_explorer_native_context_menu_display_context_menu">Vis opprinnelig hurtigmeny (eksperimentell)</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_include_patterns_guide">Nedenfor kan du spesifisere elementer du vil inkludere i hurtigtmenyen, de kan være delvise (f.eks. 'pne me') eller komplette ('Åpne med').</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_exclude_patterns_guide">Nedenfor kan du spesifisere elementer du vil ekskludere fra hurtigtmenyen, de kan være delvise (f.eks. 'pne me') eller komplette ('Åpne med').</system:String>
<!-- Preview Info -->
<system:String x:Key="Today">Today</system:String>
<system:String x:Key="DaysAgo">{0} days ago</system:String>
<system:String x:Key="OneMonthAgo">1 month ago</system:String>
<system:String x:Key="MonthsAgo">{0} months ago</system:String>
<system:String x:Key="OneYearAgo">1 year ago</system:String>
<system:String x:Key="YearsAgo">{0} years ago</system:String>
</ResourceDictionary>

View file

@ -31,6 +31,7 @@
<system:String x:Key="plugin_explorer_previewpanel_display_file_size_checkbox">Grootte</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_creation_checkbox">Datum aangemaakt</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_modification_checkbox">Datum gewijzigd</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_age_checkbox">File Age</system:String>
<system:String x:Key="plugin_explorer_previewpanel_file_info_label">Bestandsinformatie weergeven</system:String>
<system:String x:Key="plugin_explorer_previewpanel_date_and_time_format_label">Formaat voor datum en tijd</system:String>
<system:String x:Key="plugin_explorer_everything_sort_option">Sort Option:</system:String>
@ -164,4 +165,12 @@
<system:String x:Key="plugin_explorer_native_context_menu_display_context_menu">Display native context menu (experimental)</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_include_patterns_guide">Below you can specify items you want to include in the context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_exclude_patterns_guide">Below you can specify items you want to exclude from context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<!-- Preview Info -->
<system:String x:Key="Today">Today</system:String>
<system:String x:Key="DaysAgo">{0} days ago</system:String>
<system:String x:Key="OneMonthAgo">1 month ago</system:String>
<system:String x:Key="MonthsAgo">{0} months ago</system:String>
<system:String x:Key="OneYearAgo">1 year ago</system:String>
<system:String x:Key="YearsAgo">{0} years ago</system:String>
</ResourceDictionary>

View file

@ -31,6 +31,7 @@
<system:String x:Key="plugin_explorer_previewpanel_display_file_size_checkbox">Rozmiar</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_creation_checkbox">Data utworzenia</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_modification_checkbox">Data modyfikacji</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_age_checkbox">File Age</system:String>
<system:String x:Key="plugin_explorer_previewpanel_file_info_label">Wyświetl informacje o pliku</system:String>
<system:String x:Key="plugin_explorer_previewpanel_date_and_time_format_label">Format daty i czasu</system:String>
<system:String x:Key="plugin_explorer_everything_sort_option">Opcje sortowania:</system:String>
@ -164,4 +165,12 @@
<system:String x:Key="plugin_explorer_native_context_menu_display_context_menu">Wyświetl natywne menu kontekstowe (eksperymentalne)</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_include_patterns_guide">Poniżej możesz określić elementy, które chcesz uwzględnić w menu kontekstowym. Mogą być one częściowe (np. &quot;otw w&quot;) lub pełne (&quot;Otwórz za pomocą&quot;).</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_exclude_patterns_guide">Poniżej możesz określić elementy, które chcesz wykluczyć z menu kontekstowego. Mogą być one częściowe (np. &quot;otw w&quot;) lub pełne (&quot;Otwórz za pomocą&quot;).</system:String>
<!-- Preview Info -->
<system:String x:Key="Today">Today</system:String>
<system:String x:Key="DaysAgo">{0} days ago</system:String>
<system:String x:Key="OneMonthAgo">1 month ago</system:String>
<system:String x:Key="MonthsAgo">{0} months ago</system:String>
<system:String x:Key="OneYearAgo">1 year ago</system:String>
<system:String x:Key="YearsAgo">{0} years ago</system:String>
</ResourceDictionary>

View file

@ -31,6 +31,7 @@
<system:String x:Key="plugin_explorer_previewpanel_display_file_size_checkbox">Tamanho</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_creation_checkbox">Date Created</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_modification_checkbox">Date Modified</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_age_checkbox">File Age</system:String>
<system:String x:Key="plugin_explorer_previewpanel_file_info_label">Display File Info</system:String>
<system:String x:Key="plugin_explorer_previewpanel_date_and_time_format_label">Date and time format</system:String>
<system:String x:Key="plugin_explorer_everything_sort_option">Sort Option:</system:String>
@ -164,4 +165,12 @@
<system:String x:Key="plugin_explorer_native_context_menu_display_context_menu">Display native context menu (experimental)</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_include_patterns_guide">Below you can specify items you want to include in the context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_exclude_patterns_guide">Below you can specify items you want to exclude from context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<!-- Preview Info -->
<system:String x:Key="Today">Today</system:String>
<system:String x:Key="DaysAgo">{0} days ago</system:String>
<system:String x:Key="OneMonthAgo">1 month ago</system:String>
<system:String x:Key="MonthsAgo">{0} months ago</system:String>
<system:String x:Key="OneYearAgo">1 year ago</system:String>
<system:String x:Key="YearsAgo">{0} years ago</system:String>
</ResourceDictionary>

View file

@ -31,6 +31,7 @@
<system:String x:Key="plugin_explorer_previewpanel_display_file_size_checkbox">Tamanho</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_creation_checkbox">Data de criação</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_modification_checkbox">Data de modificação</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_age_checkbox">Antiguidade</system:String>
<system:String x:Key="plugin_explorer_previewpanel_file_info_label">Mostrar informações do ficheiro</system:String>
<system:String x:Key="plugin_explorer_previewpanel_date_and_time_format_label">Formato de data e de hora</system:String>
<system:String x:Key="plugin_explorer_everything_sort_option">Ordenação:</system:String>
@ -164,4 +165,12 @@
<system:String x:Key="plugin_explorer_native_context_menu_display_context_menu">Mostrar menu de contexto nativo (experimental)</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_include_patterns_guide">Aqui pode especificar os itens a incluir no menu de contexto. Podem ser parciais (ex.: 'brir co') ou completos ('Abrir com').</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_exclude_patterns_guide">Aqui pode especificar os itens a excluir do menu de contexto. Podem ser parciais (ex.: 'brir co') ou completos ('Abrir com').</system:String>
<!-- Preview Info -->
<system:String x:Key="Today">Hoje</system:String>
<system:String x:Key="DaysAgo">Há {0} dias</system:String>
<system:String x:Key="OneMonthAgo">Há 1 mês</system:String>
<system:String x:Key="MonthsAgo">Há {0} meses</system:String>
<system:String x:Key="OneYearAgo">Há 1 ano</system:String>
<system:String x:Key="YearsAgo">Há {0} anos</system:String>
</ResourceDictionary>

View file

@ -31,6 +31,7 @@
<system:String x:Key="plugin_explorer_previewpanel_display_file_size_checkbox">Размер</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_creation_checkbox">Date Created</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_modification_checkbox">Date Modified</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_age_checkbox">File Age</system:String>
<system:String x:Key="plugin_explorer_previewpanel_file_info_label">Display File Info</system:String>
<system:String x:Key="plugin_explorer_previewpanel_date_and_time_format_label">Date and time format</system:String>
<system:String x:Key="plugin_explorer_everything_sort_option">Sort Option:</system:String>
@ -164,4 +165,12 @@
<system:String x:Key="plugin_explorer_native_context_menu_display_context_menu">Display native context menu (experimental)</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_include_patterns_guide">Below you can specify items you want to include in the context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_exclude_patterns_guide">Below you can specify items you want to exclude from context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<!-- Preview Info -->
<system:String x:Key="Today">Today</system:String>
<system:String x:Key="DaysAgo">{0} days ago</system:String>
<system:String x:Key="OneMonthAgo">1 month ago</system:String>
<system:String x:Key="MonthsAgo">{0} months ago</system:String>
<system:String x:Key="OneYearAgo">1 year ago</system:String>
<system:String x:Key="YearsAgo">{0} years ago</system:String>
</ResourceDictionary>

View file

@ -31,6 +31,7 @@
<system:String x:Key="plugin_explorer_previewpanel_display_file_size_checkbox">Veľkosť</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_creation_checkbox">Dátum vytvorenia</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_modification_checkbox">Dátum úpravy</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_age_checkbox">Čas od vytvorenia</system:String>
<system:String x:Key="plugin_explorer_previewpanel_file_info_label">Zobraziť informácie o súbore</system:String>
<system:String x:Key="plugin_explorer_previewpanel_date_and_time_format_label">Formát dátumu a času</system:String>
<system:String x:Key="plugin_explorer_everything_sort_option">Zoradenie:</system:String>
@ -164,4 +165,12 @@
<system:String x:Key="plugin_explorer_native_context_menu_display_context_menu">Zobraziť natívnu kontextovú ponuku (experimentálne)</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_include_patterns_guide">Nižšie môžete určiť položky, ktoré chcete zahrnúť do kontextovej ponuky, môžu byť čiastočné (napr. &quot;tvoriť v program&quot;) alebo úplné (&quot;Otvoriť v programe&quot;).</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_exclude_patterns_guide">Nižšie môžete určiť položky, ktoré chcete vylúčiť z kontextovej ponuky, môžu byť čiastočné (napr. &quot;tvoriť v program&quot;) alebo úplné (&quot;Otvoriť v programe&quot;).</system:String>
<!-- Preview Info -->
<system:String x:Key="Today">Dnes</system:String>
<system:String x:Key="DaysAgo">pred {0} dňami</system:String>
<system:String x:Key="OneMonthAgo">pred mesiacom</system:String>
<system:String x:Key="MonthsAgo">pred {0} mesiacmi</system:String>
<system:String x:Key="OneYearAgo">pred rokom</system:String>
<system:String x:Key="YearsAgo">pred {0} rokmi</system:String>
</ResourceDictionary>

View file

@ -31,6 +31,7 @@
<system:String x:Key="plugin_explorer_previewpanel_display_file_size_checkbox">Size</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_creation_checkbox">Date Created</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_modification_checkbox">Date Modified</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_age_checkbox">File Age</system:String>
<system:String x:Key="plugin_explorer_previewpanel_file_info_label">Display File Info</system:String>
<system:String x:Key="plugin_explorer_previewpanel_date_and_time_format_label">Date and time format</system:String>
<system:String x:Key="plugin_explorer_everything_sort_option">Sort Option:</system:String>
@ -164,4 +165,12 @@
<system:String x:Key="plugin_explorer_native_context_menu_display_context_menu">Display native context menu (experimental)</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_include_patterns_guide">Below you can specify items you want to include in the context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_exclude_patterns_guide">Below you can specify items you want to exclude from context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<!-- Preview Info -->
<system:String x:Key="Today">Today</system:String>
<system:String x:Key="DaysAgo">{0} days ago</system:String>
<system:String x:Key="OneMonthAgo">1 month ago</system:String>
<system:String x:Key="MonthsAgo">{0} months ago</system:String>
<system:String x:Key="OneYearAgo">1 year ago</system:String>
<system:String x:Key="YearsAgo">{0} years ago</system:String>
</ResourceDictionary>

View file

@ -31,6 +31,7 @@
<system:String x:Key="plugin_explorer_previewpanel_display_file_size_checkbox">Boyut</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_creation_checkbox">Oluşturma Tarihi</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_modification_checkbox">Değiştirme Tarihi</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_age_checkbox">File Age</system:String>
<system:String x:Key="plugin_explorer_previewpanel_file_info_label">Dosya Özelliklerini Göster</system:String>
<system:String x:Key="plugin_explorer_previewpanel_date_and_time_format_label">Tarih ve saat biçimi</system:String>
<system:String x:Key="plugin_explorer_everything_sort_option">Sıralama Seçeneği:</system:String>
@ -164,4 +165,12 @@
<system:String x:Key="plugin_explorer_native_context_menu_display_context_menu">Display native context menu (experimental)</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_include_patterns_guide">Below you can specify items you want to include in the context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_exclude_patterns_guide">Below you can specify items you want to exclude from context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<!-- Preview Info -->
<system:String x:Key="Today">Today</system:String>
<system:String x:Key="DaysAgo">{0} days ago</system:String>
<system:String x:Key="OneMonthAgo">1 month ago</system:String>
<system:String x:Key="MonthsAgo">{0} months ago</system:String>
<system:String x:Key="OneYearAgo">1 year ago</system:String>
<system:String x:Key="YearsAgo">{0} years ago</system:String>
</ResourceDictionary>

View file

@ -31,6 +31,7 @@
<system:String x:Key="plugin_explorer_previewpanel_display_file_size_checkbox">Розмір</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_creation_checkbox">Дата створення</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_modification_checkbox">Дата останньої зміни</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_age_checkbox">File Age</system:String>
<system:String x:Key="plugin_explorer_previewpanel_file_info_label">Показати інформацію про файл</system:String>
<system:String x:Key="plugin_explorer_previewpanel_date_and_time_format_label">Формат дати й часу</system:String>
<system:String x:Key="plugin_explorer_everything_sort_option">Варіант сортування:</system:String>
@ -164,4 +165,12 @@
<system:String x:Key="plugin_explorer_native_context_menu_display_context_menu">Відображати рідне контекстне меню (експериментально)</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_include_patterns_guide">Нижче ви можете вказати елементи, які хочете включити до контекстного меню, вони можуть бути частковими (наприклад, «шир пера») або повними («Відкрити за допомогою»).</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_exclude_patterns_guide">Below you can specify items you want to exclude from context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<!-- Preview Info -->
<system:String x:Key="Today">Today</system:String>
<system:String x:Key="DaysAgo">{0} days ago</system:String>
<system:String x:Key="OneMonthAgo">1 month ago</system:String>
<system:String x:Key="MonthsAgo">{0} months ago</system:String>
<system:String x:Key="OneYearAgo">1 year ago</system:String>
<system:String x:Key="YearsAgo">{0} years ago</system:String>
</ResourceDictionary>

View file

@ -31,6 +31,7 @@
<system:String x:Key="plugin_explorer_previewpanel_display_file_size_checkbox">Kích thước</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_creation_checkbox">Date Created</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_modification_checkbox">Date Modified</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_age_checkbox">File Age</system:String>
<system:String x:Key="plugin_explorer_previewpanel_file_info_label">Hiển thị thông tin tệp</system:String>
<system:String x:Key="plugin_explorer_previewpanel_date_and_time_format_label">Định dạng ngày và giờ</system:String>
<system:String x:Key="plugin_explorer_everything_sort_option">Tùy Chọn Sắp Xếp</system:String>
@ -164,4 +165,12 @@
<system:String x:Key="plugin_explorer_native_context_menu_display_context_menu">Display native context menu (experimental)</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_include_patterns_guide">Below you can specify items you want to include in the context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_exclude_patterns_guide">Below you can specify items you want to exclude from context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<!-- Preview Info -->
<system:String x:Key="Today">Today</system:String>
<system:String x:Key="DaysAgo">{0} days ago</system:String>
<system:String x:Key="OneMonthAgo">1 month ago</system:String>
<system:String x:Key="MonthsAgo">{0} months ago</system:String>
<system:String x:Key="OneYearAgo">1 year ago</system:String>
<system:String x:Key="YearsAgo">{0} years ago</system:String>
</ResourceDictionary>

View file

@ -31,6 +31,7 @@
<system:String x:Key="plugin_explorer_previewpanel_display_file_size_checkbox">大小</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_creation_checkbox">创建日期</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_modification_checkbox">修改日期</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_age_checkbox">文件时间</system:String>
<system:String x:Key="plugin_explorer_previewpanel_file_info_label">显示文件信息</system:String>
<system:String x:Key="plugin_explorer_previewpanel_date_and_time_format_label">日期和时间格式</system:String>
<system:String x:Key="plugin_explorer_everything_sort_option">排序选项</system:String>
@ -80,8 +81,8 @@
<!-- Context menu items -->
<system:String x:Key="plugin_explorer_copypath">复制路径</system:String>
<system:String x:Key="plugin_explorer_copypath_subtitle">复制当前结果的路径到剪贴板</system:String>
<system:String x:Key="plugin_explorer_copyname">Copy name</system:String>
<system:String x:Key="plugin_explorer_copyname_subtitle">Copy name of current item to clipboard</system:String>
<system:String x:Key="plugin_explorer_copyname">复制名称</system:String>
<system:String x:Key="plugin_explorer_copyname_subtitle">复制当前文件的名称到剪贴板</system:String>
<system:String x:Key="plugin_explorer_copyfilefolder">复制</system:String>
<system:String x:Key="plugin_explorer_copyfile_subtitle">复制当前文件到剪贴板</system:String>
<system:String x:Key="plugin_explorer_copyfolder_subtitle">复制当前文件夹到剪贴板</system:String>
@ -164,4 +165,12 @@
<system:String x:Key="plugin_explorer_native_context_menu_display_context_menu">显示本机上下文菜单(实验性)</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_include_patterns_guide">您可以在下面指定想要包含在上下文菜单中的项目它们可以是部分的例如“pen wit”或完整的“打开方式”。</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_exclude_patterns_guide">您可以在下面指定要从上下文菜单中排除的项目它们可以是部分的例如“pen wit”或完整的“打开方式”。</system:String>
<!-- Preview Info -->
<system:String x:Key="Today">今天</system:String>
<system:String x:Key="DaysAgo">{0}天前</system:String>
<system:String x:Key="OneMonthAgo">1个月前</system:String>
<system:String x:Key="MonthsAgo">{0}个月前</system:String>
<system:String x:Key="OneYearAgo">1年前</system:String>
<system:String x:Key="YearsAgo">{0}年前</system:String>
</ResourceDictionary>

View file

@ -31,6 +31,7 @@
<system:String x:Key="plugin_explorer_previewpanel_display_file_size_checkbox">大小</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_creation_checkbox">創建日期</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_modification_checkbox">修改日期</system:String>
<system:String x:Key="plugin_explorer_previewpanel_display_file_age_checkbox">File Age</system:String>
<system:String x:Key="plugin_explorer_previewpanel_file_info_label">Display File Info</system:String>
<system:String x:Key="plugin_explorer_previewpanel_date_and_time_format_label">Date and time format</system:String>
<system:String x:Key="plugin_explorer_everything_sort_option">Sort Option:</system:String>
@ -164,4 +165,12 @@
<system:String x:Key="plugin_explorer_native_context_menu_display_context_menu">Display native context menu (experimental)</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_include_patterns_guide">Below you can specify items you want to include in the context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<system:String x:Key="plugin_explorer_native_context_menu_exclude_patterns_guide">Below you can specify items you want to exclude from context menu, they can be partial (e.g. 'pen wit') or complete ('Open with').</system:String>
<!-- Preview Info -->
<system:String x:Key="Today">Today</system:String>
<system:String x:Key="DaysAgo">{0} days ago</system:String>
<system:String x:Key="OneMonthAgo">1 month ago</system:String>
<system:String x:Key="MonthsAgo">{0} months ago</system:String>
<system:String x:Key="OneYearAgo">1 year ago</system:String>
<system:String x:Key="YearsAgo">{0} years ago</system:String>
</ResourceDictionary>

View file

@ -11,6 +11,8 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
{
public class EverythingSearchManager : IIndexProvider, IContentIndexProvider, IPathIndexProvider
{
private static readonly string ClassName = nameof(EverythingSearchManager);
private Settings Settings { get; }
public EverythingSearchManager(Settings settings)
@ -42,19 +44,32 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
private async ValueTask<bool> ClickToInstallEverythingAsync(ActionContext _)
{
var installedPath = await EverythingDownloadHelper.PromptDownloadIfNotInstallAsync(Settings.EverythingInstalledPath, Main.Context.API);
if (installedPath == null)
try
{
Main.Context.API.ShowMsgError("Unable to find Everything.exe");
var installedPath = await EverythingDownloadHelper.PromptDownloadIfNotInstallAsync(Settings.EverythingInstalledPath, Main.Context.API);
if (installedPath == null)
{
Main.Context.API.ShowMsgError(Main.Context.API.GetTranslation("flowlauncher_plugin_everything_not_found"));
Main.Context.API.LogError(ClassName, "Unable to find Everything.exe");
return false;
}
Settings.EverythingInstalledPath = installedPath;
Process.Start(installedPath, "-startup");
return true;
}
// Sometimes Everything installation will fail because of permission issues or file not found issues
// Just let the user know that Everything is not installed properly and ask them to install it manually
catch (Exception e)
{
Main.Context.API.ShowMsgError(Main.Context.API.GetTranslation("flowlauncher_plugin_everything_install_issue"));
Main.Context.API.LogException(ClassName, "Failed to install Everything", e);
return false;
}
Settings.EverythingInstalledPath = installedPath;
Process.Start(installedPath, "-startup");
return true;
}
public async IAsyncEnumerable<SearchResult> SearchAsync(string search, [EnumeratorCancellation] CancellationToken token)

View file

@ -1,4 +1,5 @@
using System.ComponentModel;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Windows;
@ -11,28 +12,32 @@ using DragEventArgs = System.Windows.DragEventArgs;
namespace Flow.Launcher.Plugin.Explorer.Views
{
/// <summary>
/// Interaction logic for ExplorerSettings.xaml
/// </summary>
public partial class ExplorerSettings
{
private readonly SettingsViewModel viewModel;
private readonly SettingsViewModel _viewModel;
private readonly List<Expander> _expanders;
public ExplorerSettings(SettingsViewModel viewModel)
{
_viewModel = viewModel;
DataContext = viewModel;
InitializeComponent();
this.viewModel = viewModel;
DataContext = viewModel;
ActionKeywordModel.Init(viewModel.Settings);
lbxAccessLinks.Items.SortDescriptions.Add(new SortDescription("Path", ListSortDirection.Ascending));
lbxExcludedPaths.Items.SortDescriptions.Add(new SortDescription("Path", ListSortDirection.Ascending));
_expanders = new List<Expander>
{
GeneralSettingsExpander,
ContextMenuExpander,
PreviewPanelExpander,
EverythingExpander,
ActionKeywordsExpander,
QuickAccessExpander,
ExcludedPathsExpander
};
}
private void AccessLinkDragDrop(string containerName, DragEventArgs e)
@ -51,7 +56,7 @@ namespace Flow.Launcher.Plugin.Explorer.Views
{
Path = s
};
viewModel.AppendLink(containerName, newFolderLink);
_viewModel.AppendLink(containerName, newFolderLink);
}
}
}
@ -76,8 +81,8 @@ namespace Flow.Launcher.Plugin.Explorer.Views
{
if (tbFastSortWarning is not null)
{
tbFastSortWarning.Visibility = viewModel.FastSortWarningVisibility;
tbFastSortWarning.Text = viewModel.SortOptionWarningMessage;
tbFastSortWarning.Visibility = _viewModel.FastSortWarningVisibility;
tbFastSortWarning.Text = _viewModel.SortOptionWarningMessage;
}
}
private void LbxAccessLinks_OnDrop(object sender, DragEventArgs e)
@ -93,5 +98,32 @@ namespace Flow.Launcher.Plugin.Explorer.Views
{
e.Handled = e.Text.ToCharArray().Any(c => !char.IsDigit(c));
}
private void Expander_Expanded(object sender, RoutedEventArgs e)
{
if (sender is Expander expandedExpander)
{
// Ensure _expanders is not null and contains items
if (_expanders == null || !_expanders.Any()) return;
foreach (var expander in _expanders)
{
if (expander != null && expander != expandedExpander && expander.IsExpanded)
{
expander.IsExpanded = false;
}
}
}
}
private void lbxAccessLinks_Loaded(object sender, RoutedEventArgs e)
{
lbxAccessLinks.Items.SortDescriptions.Add(new SortDescription("Path", ListSortDirection.Ascending));
}
private void lbxExcludedPaths_Loaded(object sender, RoutedEventArgs e)
{
lbxExcludedPaths.Items.SortDescriptions.Add(new SortDescription("Path", ListSortDirection.Ascending));
}
}
}

View file

@ -13,8 +13,8 @@
<system:String x:Key="plugin_pluginsmanager_installing_plugin">正在安装插件</system:String>
<system:String x:Key="plugin_pluginsmanager_install_from_web">下载与安装 {0}</system:String>
<system:String x:Key="plugin_pluginsmanager_uninstall_title">插件卸载</system:String>
<system:String x:Key="plugin_pluginsmanager_keep_plugin_settings_title">Keep plugin settings</system:String>
<system:String x:Key="plugin_pluginsmanager_keep_plugin_settings_subtitle">Do you want to keep the settings of the plugin for the next usage?</system:String>
<system:String x:Key="plugin_pluginsmanager_keep_plugin_settings_title">保留插件设置</system:String>
<system:String x:Key="plugin_pluginsmanager_keep_plugin_settings_subtitle">你想要保留插件设置以便下一次的使用吗?</system:String>
<system:String x:Key="plugin_pluginsmanager_install_success_restart">插件安装成功。正在重新启动 Flow Launcher请稍候...</system:String>
<system:String x:Key="plugin_pluginsmanager_install_errormetadatafile">安装失败无法从新插件中找到plugin.json元数据文件</system:String>
<system:String x:Key="plugin_pluginsmanager_install_error_duplicate">错误:具有相同或更高版本的 {0} 的插件已经存在。</system:String>

View file

@ -316,61 +316,75 @@ namespace Flow.Launcher.Plugin.PluginsManager
var downloadToFilePath = Path.Combine(Path.GetTempPath(),
$"{x.Name}-{x.NewVersion}.zip");
_ = Task.Run(async delegate
_ = Task.Run(async () =>
{
using var cts = new CancellationTokenSource();
try
{
using var cts = new CancellationTokenSource();
if (!x.PluginNewUserPlugin.IsFromLocalInstallPath)
{
await DownloadFileAsync(
$"{Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin")} {x.PluginNewUserPlugin.Name}",
x.PluginNewUserPlugin.UrlDownload, downloadToFilePath, cts);
}
else
{
downloadToFilePath = x.PluginNewUserPlugin.LocalInstallPath;
}
// check if user cancelled download before installing plugin
if (cts.IsCancellationRequested)
{
return;
}
else
{
await Context.API.UpdatePluginAsync(x.PluginExistingMetadata, x.PluginNewUserPlugin,
downloadToFilePath);
if (Settings.AutoRestartAfterChanging)
if (!x.PluginNewUserPlugin.IsFromLocalInstallPath)
{
Context.API.ShowMsg(
Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
string.Format(
Context.API.GetTranslation(
"plugin_pluginsmanager_update_success_restart"),
x.Name));
Context.API.RestartApp();
await DownloadFileAsync(
$"{Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin")} {x.PluginNewUserPlugin.Name}",
x.PluginNewUserPlugin.UrlDownload, downloadToFilePath, cts);
}
else
{
Context.API.ShowMsg(
Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
string.Format(
Context.API.GetTranslation(
"plugin_pluginsmanager_update_success_no_restart"),
x.Name));
downloadToFilePath = x.PluginNewUserPlugin.LocalInstallPath;
}
// check if user cancelled download before installing plugin
if (cts.IsCancellationRequested)
{
return;
}
else
{
await Context.API.UpdatePluginAsync(x.PluginExistingMetadata, x.PluginNewUserPlugin,
downloadToFilePath);
if (Settings.AutoRestartAfterChanging)
{
Context.API.ShowMsg(
Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
string.Format(
Context.API.GetTranslation(
"plugin_pluginsmanager_update_success_restart"),
x.Name));
Context.API.RestartApp();
}
else
{
Context.API.ShowMsg(
Context.API.GetTranslation("plugin_pluginsmanager_update_title"),
string.Format(
Context.API.GetTranslation(
"plugin_pluginsmanager_update_success_no_restart"),
x.Name));
}
}
}
}).ContinueWith(t =>
{
Context.API.LogException(ClassName, $"Update failed for {x.Name}",
t.Exception.InnerException);
Context.API.ShowMsg(
Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
string.Format(
Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"),
x.Name));
}, token, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default);
catch (HttpRequestException e)
{
// show error message
Context.API.ShowMsgError(
string.Format(Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin"), x.Name),
Context.API.GetTranslation("plugin_pluginsmanager_download_error"));
Context.API.LogException(ClassName, "An error occurred while downloading plugin", e);
return;
}
catch (Exception e)
{
// show error message
Context.API.LogException(ClassName, $"Update failed for {x.Name}", e);
Context.API.ShowMsgError(
Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
string.Format(
Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"),
x.Name));
return;
}
});
return true;
},
@ -436,7 +450,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
catch (Exception ex)
{
Context.API.LogException(ClassName, $"Update failed for {plugin.Name}", ex.InnerException);
Context.API.ShowMsg(
Context.API.ShowMsgError(
Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
string.Format(
Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"),

View file

@ -8,7 +8,7 @@
<system:String x:Key="flowlauncher_plugin_processkiller_kill_all_count">{0} Prozesse beenden</system:String>
<system:String x:Key="flowlauncher_plugin_processkiller_kill_instances">Alle Instanzen beenden</system:String>
<system:String x:Key="flowlauncher_plugin_processkiller_show_window_title">Show title for processes with visible windows</system:String>
<system:String x:Key="flowlauncher_plugin_processkiller_put_visible_window_process_top">Put processes with visible windows on the top</system:String>
<system:String x:Key="flowlauncher_plugin_processkiller_show_window_title">Titel für Prozesse mit sichtbaren Fenstern zeigen</system:String>
<system:String x:Key="flowlauncher_plugin_processkiller_put_visible_window_process_top">Prozesse mit sichtbaren Fenstern ganz oben setzen</system:String>
</ResourceDictionary>

View file

@ -8,7 +8,7 @@
<system:String x:Key="flowlauncher_plugin_processkiller_kill_all_count">杀死 {0} 进程</system:String>
<system:String x:Key="flowlauncher_plugin_processkiller_kill_instances">杀死所有实例</system:String>
<system:String x:Key="flowlauncher_plugin_processkiller_show_window_title">Show title for processes with visible windows</system:String>
<system:String x:Key="flowlauncher_plugin_processkiller_put_visible_window_process_top">Put processes with visible windows on the top</system:String>
<system:String x:Key="flowlauncher_plugin_processkiller_show_window_title">显示带有可见窗口的进程标题</system:String>
<system:String x:Key="flowlauncher_plugin_processkiller_put_visible_window_process_top">在顶部放置带有可见窗口的进程</system:String>
</ResourceDictionary>

View file

@ -46,8 +46,8 @@
<system:String x:Key="flowlauncher_plugin_program_pls_select_program_source">Por favor, seleccione la ruta del programa</system:String>
<system:String x:Key="flowlauncher_plugin_program_delete_program_source">¿Está seguro de que desea eliminar las fuentes del programa seleccionadas?</system:String>
<system:String x:Key="flowlauncher_plugin_program_delete_program_source_select_not_user_added">Please select program sources that are not added by you</system:String>
<system:String x:Key="flowlauncher_plugin_program_delete_program_source_select_user_added">Please select program sources that are added by you</system:String>
<system:String x:Key="flowlauncher_plugin_program_delete_program_source_select_not_user_added">Por favor, seleccione las fuentes del programa que no han sido añadidas por usted</system:String>
<system:String x:Key="flowlauncher_plugin_program_delete_program_source_select_user_added">Por favor, seleccione las fuentes del programa que han sido añadidas por usted</system:String>
<system:String x:Key="flowlauncher_plugin_program_duplicate_program_source">Ya existe otra fuente de programa con la misma ubicación.</system:String>
<system:String x:Key="flowlauncher_plugin_program_edit_program_source_title">Fuente de Programa</system:String>

View file

@ -34,8 +34,8 @@
<system:String x:Key="flowlauncher_plugin_program_enable_hideuninstallers_tooltip">隐藏具有常见卸载程序名称的程序,例如 unins000.exe</system:String>
<system:String x:Key="flowlauncher_plugin_program_enable_description">启用程序描述</system:String>
<system:String x:Key="flowlauncher_plugin_program_enable_description_tooltip">Flow 将搜索程序描述</system:String>
<system:String x:Key="flowlauncher_plugin_program_enable_hideduplicatedwindowsapp">Hide duplicated apps</system:String>
<system:String x:Key="flowlauncher_plugin_program_enable_hideduplicatedwindowsapp_tooltip">Hide duplicated Win32 programs that are already in the UWP list</system:String>
<system:String x:Key="flowlauncher_plugin_program_enable_hideduplicatedwindowsapp">隐藏重复的应用</system:String>
<system:String x:Key="flowlauncher_plugin_program_enable_hideduplicatedwindowsapp_tooltip">隐藏已经在UWP列表中重复的Win32程序</system:String>
<system:String x:Key="flowlauncher_plugin_program_suffixes_header">后缀</system:String>
<system:String x:Key="flowlauncher_plugin_program_max_depth_header">最大深度</system:String>
@ -46,8 +46,8 @@
<system:String x:Key="flowlauncher_plugin_program_pls_select_program_source">请先选择一项</system:String>
<system:String x:Key="flowlauncher_plugin_program_delete_program_source">您确定要删除选定的程序源吗?</system:String>
<system:String x:Key="flowlauncher_plugin_program_delete_program_source_select_not_user_added">Please select program sources that are not added by you</system:String>
<system:String x:Key="flowlauncher_plugin_program_delete_program_source_select_user_added">Please select program sources that are added by you</system:String>
<system:String x:Key="flowlauncher_plugin_program_delete_program_source_select_not_user_added">请选择没有被您添加的程序源</system:String>
<system:String x:Key="flowlauncher_plugin_program_delete_program_source_select_user_added">请选择由您添加的程序源</system:String>
<system:String x:Key="flowlauncher_plugin_program_duplicate_program_source">相同位置存在另一个程序源。</system:String>
<system:String x:Key="flowlauncher_plugin_program_edit_program_source_title">程序源</system:String>
@ -76,7 +76,7 @@
<system:String x:Key="flowlauncher_plugin_program_run_as_different_user">以其他用户身份运行</system:String>
<system:String x:Key="flowlauncher_plugin_program_run_as_administrator">以管理员身份运行</system:String>
<system:String x:Key="flowlauncher_plugin_program_open_containing_folder">打开文件所在文件夹</system:String>
<system:String x:Key="flowlauncher_plugin_program_disable_program">Hide</system:String>
<system:String x:Key="flowlauncher_plugin_program_disable_program">隐藏</system:String>
<system:String x:Key="flowlauncher_plugin_program_open_target_folder">打开目标文件夹</system:String>
<system:String x:Key="flowlauncher_plugin_program_plugin_name">程序</system:String>

View file

@ -8,9 +8,8 @@ using Windows.Win32.Storage.FileSystem;
namespace Flow.Launcher.Plugin.Program.Programs
{
class ShellLinkHelper
public class ShellLinkHelper
{
// Reference : http://www.pinvoke.net/default.aspx/Interfaces.IShellLinkW
[ComImport(), Guid("00021401-0000-0000-C000-000000000046")]
public class ShellLink
@ -28,7 +27,9 @@ namespace Flow.Launcher.Plugin.Program.Programs
const int STGM_READ = 0;
((IPersistFile)link).Load(path, STGM_READ);
var hwnd = new HWND(IntPtr.Zero);
((IShellLinkW)link).Resolve(hwnd, 0);
// Use SLR_NO_UI to avoid showing any UI during resolution, like Problem with Shortcut dialogs
// https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ishelllinka-resolve
((IShellLinkW)link).Resolve(hwnd, (uint)SLR_FLAGS.SLR_NO_UI);
const int MAX_PATH = 260;
Span<char> buffer = stackalloc char[MAX_PATH];
@ -79,6 +80,6 @@ namespace Flow.Launcher.Plugin.Program.Programs
Marshal.ReleaseComObject(link);
return target;
}
}
}
}

View file

@ -9,7 +9,7 @@
<system:String x:Key="flowlauncher_plugin_cmd_use_windows_terminal">Use Windows Terminal</system:String>
<system:String x:Key="flowlauncher_plugin_cmd_run_as_different_user">다른 유저 권한으로 실행</system:String>
<system:String x:Key="flowlauncher_plugin_cmd_plugin_name">쉘</system:String>
<system:String x:Key="flowlauncher_plugin_cmd_plugin_description">Allows to execute system commands from Flow Launcher</system:String>
<system:String x:Key="flowlauncher_plugin_cmd_plugin_description">Flow Launcher를 통해 시스템 명령어를 실행할 수 있습니다</system:String>
<system:String x:Key="flowlauncher_plugin_cmd_cmd_has_been_executed_times">이 명령은 {0}회 실행되었습니다.</system:String>
<system:String x:Key="flowlauncher_plugin_cmd_execute_through_shell">쉘을 통해 명령 실행</system:String>
<system:String x:Key="flowlauncher_plugin_cmd_run_as_administrator">관리자 권한으로 실행</system:String>

View file

@ -6,7 +6,7 @@
<system:String x:Key="flowlauncher_plugin_cmd_press_any_key_to_close">按下任意键以关闭此窗口...</system:String>
<system:String x:Key="flowlauncher_plugin_cmd_leave_cmd_open">执行后不关闭命令窗口</system:String>
<system:String x:Key="flowlauncher_plugin_cmd_always_run_as_administrator">始终以管理员身份运行</system:String>
<system:String x:Key="flowlauncher_plugin_cmd_use_windows_terminal">Use Windows Terminal</system:String>
<system:String x:Key="flowlauncher_plugin_cmd_use_windows_terminal">使用 Windows 终端</system:String>
<system:String x:Key="flowlauncher_plugin_cmd_run_as_different_user">以其他用户身份运行</system:String>
<system:String x:Key="flowlauncher_plugin_cmd_plugin_name">命令行</system:String>
<system:String x:Key="flowlauncher_plugin_cmd_plugin_description">允许从 Flow Launcher 中执行系统命令</system:String>

View file

@ -201,94 +201,101 @@ namespace Flow.Launcher.Plugin.Shell
switch (_settings.Shell)
{
case Shell.Cmd:
{
if (_settings.UseWindowsTerminal)
{
info.FileName = "wt.exe";
info.ArgumentList.Add("cmd");
}
else
{
info.FileName = "cmd.exe";
}
if (_settings.UseWindowsTerminal)
{
info.FileName = "wt.exe";
info.ArgumentList.Add("cmd");
}
else
{
info.FileName = "cmd.exe";
}
info.ArgumentList.Add($"{(_settings.LeaveShellOpen ? "/k" : "/c")} {command} {(_settings.CloseShellAfterPress ? $"&& echo {Context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")} && pause > nul /c" : "")}");
break;
}
info.ArgumentList.Add($"{(_settings.LeaveShellOpen ? "/k" : "/c")} {command} {(_settings.CloseShellAfterPress ? $"&& echo {Context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")} && pause > nul /c" : "")}");
break;
}
case Shell.Powershell:
{
if (_settings.UseWindowsTerminal)
{
info.FileName = "wt.exe";
info.ArgumentList.Add("powershell");
// Using just a ; doesn't work with wt, as it's used to create a new tab for the terminal window
// \\ must be escaped for it to work properly, or breaking it into multiple arguments
var addedCharacter = _settings.UseWindowsTerminal ? "\\" : "";
if (_settings.UseWindowsTerminal)
{
info.FileName = "wt.exe";
info.ArgumentList.Add("powershell");
}
else
{
info.FileName = "powershell.exe";
}
if (_settings.LeaveShellOpen)
{
info.ArgumentList.Add("-NoExit");
info.ArgumentList.Add(command);
}
else
{
info.ArgumentList.Add("-Command");
info.ArgumentList.Add($"{command}{addedCharacter}; {(_settings.CloseShellAfterPress ? $"Write-Host '{Context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")}'{addedCharacter}; [System.Console]::ReadKey(){addedCharacter}; exit" : "")}");
}
break;
}
else
{
info.FileName = "powershell.exe";
}
if (_settings.LeaveShellOpen)
{
info.ArgumentList.Add("-NoExit");
info.ArgumentList.Add(command);
}
else
{
info.ArgumentList.Add("-Command");
info.ArgumentList.Add($"{command}\\; {(_settings.CloseShellAfterPress ? $"Write-Host '{Context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")}'\\; [System.Console]::ReadKey()\\; exit" : "")}");
}
break;
}
case Shell.Pwsh:
{
if (_settings.UseWindowsTerminal)
{
info.FileName = "wt.exe";
info.ArgumentList.Add("pwsh");
// Using just a ; doesn't work with wt, as it's used to create a new tab for the terminal window
// \\ must be escaped for it to work properly, or breaking it into multiple arguments
var addedCharacter = _settings.UseWindowsTerminal ? "\\" : "";
if (_settings.UseWindowsTerminal)
{
info.FileName = "wt.exe";
info.ArgumentList.Add("pwsh");
}
else
{
info.FileName = "pwsh.exe";
}
if (_settings.LeaveShellOpen)
{
info.ArgumentList.Add("-NoExit");
}
info.ArgumentList.Add("-Command");
info.ArgumentList.Add($"{command}{addedCharacter}; {(_settings.CloseShellAfterPress ? $"Write-Host '{Context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")}'{addedCharacter}; [System.Console]::ReadKey(){addedCharacter}; exit" : "")}");
break;
}
else
{
info.FileName = "pwsh.exe";
}
if (_settings.LeaveShellOpen)
{
info.ArgumentList.Add("-NoExit");
}
info.ArgumentList.Add("-Command");
info.ArgumentList.Add($"{command}\\; {(_settings.CloseShellAfterPress ? $"Write-Host '{Context.API.GetTranslation("flowlauncher_plugin_cmd_press_any_key_to_close")}'\\; [System.Console]::ReadKey()\\; exit" : "")}");
break;
}
case Shell.RunCommand:
{
var parts = command.Split(new[]
{
' '
}, 2);
if (parts.Length == 2)
{
var filename = parts[0];
if (ExistInPath(filename))
var parts = command.Split(new[]
{
var arguments = parts[1];
info.FileName = filename;
info.ArgumentList.Add(arguments);
' '
}, 2);
if (parts.Length == 2)
{
var filename = parts[0];
if (ExistInPath(filename))
{
var arguments = parts[1];
info.FileName = filename;
info.ArgumentList.Add(arguments);
}
else
{
info.FileName = command;
}
}
else
{
info.FileName = command;
}
}
else
{
info.FileName = command;
info.UseShellExecute = true;
break;
}
info.UseShellExecute = true;
break;
}
default:
throw new NotImplementedException();
}

Some files were not shown because too many files have changed in this diff Show more