Merge branch 'dev' into processkiller_orderby_windowtitle

This commit is contained in:
Jack Ye 2025-03-26 14:20:13 +08:00 committed by GitHub
commit 0ddaea3317
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
230 changed files with 7185 additions and 4671 deletions

View file

@ -1,18 +1,14 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Forms;
using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Plugin;
using CheckBox = System.Windows.Controls.CheckBox;
using ComboBox = System.Windows.Controls.ComboBox;
using Control = System.Windows.Controls.Control;
using Orientation = System.Windows.Controls.Orientation;
using TextBox = System.Windows.Controls.TextBox;
using UserControl = System.Windows.Controls.UserControl;
#nullable enable
namespace Flow.Launcher.Core.Plugin
{
@ -23,51 +19,72 @@ namespace Flow.Launcher.Core.Plugin
public required string SettingPath { get; init; }
public Dictionary<string, FrameworkElement> SettingControls { get; } = new();
public IReadOnlyDictionary<string, object> Inner => Settings;
protected ConcurrentDictionary<string, object> Settings { get; set; }
public IReadOnlyDictionary<string, object?> Inner => Settings;
protected ConcurrentDictionary<string, object?> Settings { get; set; } = null!;
public required IPublicAPI API { get; init; }
private JsonStorage<ConcurrentDictionary<string, object>> _storage;
private JsonStorage<ConcurrentDictionary<string, object?>> _storage = null!;
// maybe move to resource?
private static readonly Thickness settingControlMargin = new(0, 9, 18, 9);
private static readonly Thickness settingCheckboxMargin = new(0, 9, 9, 9);
private static readonly Thickness settingPanelMargin = new(0, 0, 0, 0);
private static readonly Thickness settingTextBlockMargin = new(70, 9, 18, 9);
private static readonly Thickness settingLabelPanelMargin = new(70, 9, 18, 9);
private static readonly Thickness settingLabelMargin = new(0, 0, 0, 0);
private static readonly Thickness settingDescMargin = new(0, 2, 0, 0);
private static readonly Thickness settingSepMargin = new(0, 0, 0, 2);
private static readonly Thickness SettingPanelMargin = (Thickness)Application.Current.FindResource("SettingPanelMargin");
private static readonly Thickness SettingPanelItemLeftMargin = (Thickness)Application.Current.FindResource("SettingPanelItemLeftMargin");
private static readonly Thickness SettingPanelItemTopBottomMargin = (Thickness)Application.Current.FindResource("SettingPanelItemTopBottomMargin");
private static readonly Thickness SettingPanelItemLeftTopBottomMargin = (Thickness)Application.Current.FindResource("SettingPanelItemLeftTopBottomMargin");
private static readonly double SettingPanelTextBoxMinWidth = (double)Application.Current.FindResource("SettingPanelTextBoxMinWidth");
private static readonly double SettingPanelPathTextBoxWidth = (double)Application.Current.FindResource("SettingPanelPathTextBoxWidth");
private static readonly double SettingPanelAreaTextBoxMinHeight = (double)Application.Current.FindResource("SettingPanelAreaTextBoxMinHeight");
public async Task InitializeAsync()
{
_storage = new JsonStorage<ConcurrentDictionary<string, object>>(SettingPath);
Settings = await _storage.LoadAsync();
if (Configuration == null)
if (Settings == null)
{
return;
_storage = new JsonStorage<ConcurrentDictionary<string, object?>>(SettingPath);
Settings = await _storage.LoadAsync();
// Because value type of settings dictionary is object which causes them to be JsonElement when loading from json files,
// we need to convert it to the correct type
foreach (var (key, value) in Settings)
{
if (value is not JsonElement jsonElement) continue;
Settings[key] = jsonElement.ValueKind switch
{
JsonValueKind.String => jsonElement.GetString() ?? value,
JsonValueKind.True => jsonElement.GetBoolean(),
JsonValueKind.False => jsonElement.GetBoolean(),
JsonValueKind.Null => null,
_ => value
};
}
}
if (Configuration == null) return;
foreach (var (type, attributes) in Configuration.Body)
{
if (attributes.Name == null)
{
continue;
}
// Skip if the setting does not have attributes or name
if (attributes?.Name == null) continue;
if (!Settings.ContainsKey(attributes.Name))
// Skip if the setting does not have attributes or name
if (!NeedSaveInSettings(type)) continue;
// If need save in settings, we need to make sure the setting exists in the settings file
if (Settings.ContainsKey(attributes.Name)) continue;
if (type == "checkbox")
{
// If can parse the default value to bool, use it, otherwise use false
Settings[attributes.Name] = bool.TryParse(attributes.DefaultValue, out var value) && value;
}
else
{
Settings[attributes.Name] = attributes.DefaultValue;
}
}
}
public void UpdateSettings(IReadOnlyDictionary<string, object> settings)
{
if (settings == null || settings.Count == 0)
return;
if (settings == null || settings.Count == 0) return;
foreach (var (key, value) in settings)
{
@ -78,19 +95,23 @@ namespace Flow.Launcher.Core.Plugin
switch (control)
{
case TextBox textBox:
textBox.Dispatcher.Invoke(() => textBox.Text = value as string ?? string.Empty);
var text = value as string ?? string.Empty;
textBox.Dispatcher.Invoke(() => textBox.Text = text);
break;
case PasswordBox passwordBox:
passwordBox.Dispatcher.Invoke(() => passwordBox.Password = value as string ?? string.Empty);
var password = value as string ?? string.Empty;
passwordBox.Dispatcher.Invoke(() => passwordBox.Password = password);
break;
case ComboBox comboBox:
comboBox.Dispatcher.Invoke(() => comboBox.SelectedItem = value);
break;
case CheckBox checkBox:
checkBox.Dispatcher.Invoke(() =>
checkBox.IsChecked = value is bool isChecked
? isChecked
: bool.Parse(value as string ?? string.Empty));
var isChecked = value is bool boolValue
? boolValue
// If can parse the default value to bool, use it, otherwise use false
: value is string stringValue && bool.TryParse(stringValue, out var boolValueFromString)
&& boolValueFromString;
checkBox.Dispatcher.Invoke(() =>checkBox.IsChecked = isChecked);
break;
}
}
@ -108,7 +129,7 @@ namespace Flow.Launcher.Core.Plugin
{
_storage.Save();
}
public bool NeedCreateSettingPanel()
{
// If there are no settings or the settings configuration is empty, return null
@ -118,329 +139,350 @@ namespace Flow.Launcher.Core.Plugin
public Control CreateSettingPanel()
{
// No need to check if NeedCreateSettingPanel is true because CreateSettingPanel will only be called if it's true
// if (!NeedCreateSettingPanel()) return null;
var settingWindow = new UserControl();
var mainPanel = new Grid { Margin = settingPanelMargin, VerticalAlignment = VerticalAlignment.Center };
ColumnDefinition gridCol1 = new ColumnDefinition();
ColumnDefinition gridCol2 = new ColumnDefinition();
gridCol1.Width = new GridLength(70, GridUnitType.Star);
gridCol2.Width = new GridLength(30, GridUnitType.Star);
mainPanel.ColumnDefinitions.Add(gridCol1);
mainPanel.ColumnDefinitions.Add(gridCol2);
settingWindow.Content = mainPanel;
int rowCount = 0;
foreach (var (type, attribute) in Configuration.Body)
// Create main grid with two columns (Column 1: Auto, Column 2: *)
var mainPanel = new Grid { Margin = SettingPanelMargin, VerticalAlignment = VerticalAlignment.Center };
mainPanel.ColumnDefinitions.Add(new ColumnDefinition()
{
Separator sep = new Separator();
sep.VerticalAlignment = VerticalAlignment.Top;
sep.Margin = settingSepMargin;
sep.SetResourceReference(Separator.BackgroundProperty, "Color03B"); /* for theme change */
var panel = new StackPanel
Width = new GridLength(0, GridUnitType.Auto)
});
mainPanel.ColumnDefinitions.Add(new ColumnDefinition()
{
Width = new GridLength(1, GridUnitType.Star)
});
// Iterate over each setting and create one row for it
var rowCount = 0;
foreach (var (type, attributes) in Configuration!.Body)
{
// Skip if the setting does not have attributes or name
if (attributes?.Name == null) continue;
// Add a new row to the main grid
mainPanel.RowDefinitions.Add(new RowDefinition()
{
Orientation = Orientation.Vertical,
VerticalAlignment = VerticalAlignment.Center,
Margin = settingLabelPanelMargin
};
RowDefinition gridRow = new RowDefinition();
mainPanel.RowDefinitions.Add(gridRow);
var name = new TextBlock()
{
Text = attribute.Label,
VerticalAlignment = VerticalAlignment.Center,
Margin = settingLabelMargin,
TextWrapping = TextWrapping.WrapWithOverflow
};
var desc = new TextBlock()
{
Text = attribute.Description,
FontSize = 12,
VerticalAlignment = VerticalAlignment.Center,
Margin = settingDescMargin,
TextWrapping = TextWrapping.WrapWithOverflow
};
desc.SetResourceReference(TextBlock.ForegroundProperty, "Color04B");
if (attribute.Description == null) /* if no description, hide */
desc.Visibility = Visibility.Collapsed;
if (type != "textBlock") /* if textBlock, hide desc */
{
panel.Children.Add(name);
panel.Children.Add(desc);
}
Grid.SetColumn(panel, 0);
Grid.SetRow(panel, rowCount);
Height = new GridLength(0, GridUnitType.Auto)
});
// State controls for column 0 and 1
StackPanel? panel = null;
FrameworkElement contentControl;
// If the type is textBlock, separator, or checkbox, we do not need to create a panel
if (type != "textBlock" && type != "separator" && type != "checkbox")
{
// Create a panel to hold the label and description
panel = new StackPanel
{
Margin = SettingPanelItemTopBottomMargin,
Orientation = Orientation.Vertical,
VerticalAlignment = VerticalAlignment.Center
};
// Create a text block for name
var name = new TextBlock()
{
Text = attributes.Label,
VerticalAlignment = VerticalAlignment.Center,
TextWrapping = TextWrapping.WrapWithOverflow
};
// Create a text block for description
TextBlock? desc = null;
if (attributes.Description != null)
{
desc = new TextBlock()
{
Text = attributes.Description,
VerticalAlignment = VerticalAlignment.Center,
TextWrapping = TextWrapping.WrapWithOverflow
};
desc.SetResourceReference(TextBlock.StyleProperty, "SettingPanelTextBlockDescriptionStyle"); // for theme change
}
// Add the name and description to the panel
panel.Children.Add(name);
if (desc != null) panel.Children.Add(desc);
}
switch (type)
{
case "textBlock":
{
contentControl = new TextBlock
{
Text = attribute.Description.Replace("\\r\\n", "\r\n"),
Margin = settingTextBlockMargin,
Padding = new Thickness(0, 0, 0, 0),
HorizontalAlignment = System.Windows.HorizontalAlignment.Left,
TextAlignment = TextAlignment.Left,
TextWrapping = TextWrapping.Wrap
};
contentControl = new TextBlock
{
Text = attributes.Description?.Replace("\\r\\n", "\r\n") ?? string.Empty,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemTopBottomMargin,
TextAlignment = TextAlignment.Left,
TextWrapping = TextWrapping.Wrap
};
Grid.SetColumn(contentControl, 0);
Grid.SetColumnSpan(contentControl, 2);
Grid.SetRow(contentControl, rowCount);
if (rowCount != 0)
mainPanel.Children.Add(sep);
Grid.SetRow(sep, rowCount);
Grid.SetColumn(sep, 0);
Grid.SetColumnSpan(sep, 2);
break;
}
break;
}
case "input":
{
var textBox = new TextBox()
{
Text = Settings[attribute.Name] as string ?? string.Empty,
Margin = settingControlMargin,
HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
ToolTip = attribute.Description
};
var textBox = new TextBox()
{
MinWidth = SettingPanelTextBoxMinWidth,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemLeftTopBottomMargin,
Text = Settings[attributes.Name] as string ?? string.Empty,
ToolTip = attributes.Description
};
textBox.TextChanged += (_, _) =>
{
Settings[attribute.Name] = textBox.Text;
};
textBox.TextChanged += (_, _) =>
{
Settings[attributes.Name] = textBox.Text;
};
contentControl = textBox;
Grid.SetColumn(contentControl, 1);
Grid.SetRow(contentControl, rowCount);
if (rowCount != 0)
mainPanel.Children.Add(sep);
contentControl = textBox;
Grid.SetRow(sep, rowCount);
Grid.SetColumn(sep, 0);
Grid.SetColumnSpan(sep, 2);
break;
}
break;
}
case "inputWithFileBtn":
case "inputWithFolderBtn":
{
var textBox = new TextBox()
{
Margin = new Thickness(10, 0, 0, 0),
Text = Settings[attribute.Name] as string ?? string.Empty,
HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
ToolTip = attribute.Description
};
textBox.TextChanged += (_, _) =>
{
Settings[attribute.Name] = textBox.Text;
};
var Btn = new System.Windows.Controls.Button()
{
Margin = new Thickness(10, 0, 0, 0), Content = "Browse"
};
Btn.Click += (_, _) =>
{
using CommonDialog dialog = type switch
var textBox = new TextBox()
{
"inputWithFolderBtn" => new FolderBrowserDialog(),
_ => new OpenFileDialog(),
Width = SettingPanelPathTextBoxWidth,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemLeftMargin,
Text = Settings[attributes.Name] as string ?? string.Empty,
ToolTip = attributes.Description
};
if (dialog.ShowDialog() != DialogResult.OK) return;
var path = dialog switch
textBox.TextChanged += (_, _) =>
{
FolderBrowserDialog folderDialog => folderDialog.SelectedPath,
OpenFileDialog fileDialog => fileDialog.FileName,
Settings[attributes.Name] = textBox.Text;
};
textBox.Text = path;
Settings[attribute.Name] = path;
};
var dockPanel = new DockPanel() { Margin = settingControlMargin };
var Btn = new Button()
{
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemLeftMargin,
Content = API.GetTranslation("select")
};
DockPanel.SetDock(Btn, Dock.Right);
dockPanel.Children.Add(Btn);
dockPanel.Children.Add(textBox);
contentControl = dockPanel;
Grid.SetColumn(contentControl, 1);
Grid.SetRow(contentControl, rowCount);
if (rowCount != 0)
mainPanel.Children.Add(sep);
Btn.Click += (_, _) =>
{
using System.Windows.Forms.CommonDialog dialog = type switch
{
"inputWithFolderBtn" => new System.Windows.Forms.FolderBrowserDialog(),
_ => new System.Windows.Forms.OpenFileDialog(),
};
Grid.SetRow(sep, rowCount);
Grid.SetColumn(sep, 0);
Grid.SetColumnSpan(sep, 2);
if (dialog.ShowDialog() != System.Windows.Forms.DialogResult.OK)
{
return;
}
break;
}
var path = dialog switch
{
System.Windows.Forms.FolderBrowserDialog folderDialog => folderDialog.SelectedPath,
System.Windows.Forms.OpenFileDialog fileDialog => fileDialog.FileName,
_ => throw new System.NotImplementedException()
};
textBox.Text = path;
Settings[attributes.Name] = path;
};
var stackPanel = new StackPanel()
{
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemTopBottomMargin,
Orientation = Orientation.Horizontal
};
// Create a stack panel to wrap the button and text box
stackPanel.Children.Add(textBox);
stackPanel.Children.Add(Btn);
contentControl = stackPanel;
break;
}
case "textarea":
{
var textBox = new TextBox()
{
Height = 120,
Margin = settingControlMargin,
VerticalAlignment = VerticalAlignment.Center,
TextWrapping = TextWrapping.WrapWithOverflow,
AcceptsReturn = true,
HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
Text = Settings[attribute.Name] as string ?? string.Empty,
ToolTip = attribute.Description
};
var textBox = new TextBox()
{
MinHeight = SettingPanelAreaTextBoxMinHeight,
HorizontalAlignment = HorizontalAlignment.Stretch,
VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemLeftTopBottomMargin,
TextWrapping = TextWrapping.WrapWithOverflow,
AcceptsReturn = true,
Text = Settings[attributes.Name] as string ?? string.Empty,
ToolTip = attributes.Description
};
textBox.TextChanged += (sender, _) =>
{
Settings[attribute.Name] = ((TextBox)sender).Text;
};
textBox.TextChanged += (sender, _) =>
{
Settings[attributes.Name] = ((TextBox)sender).Text;
};
contentControl = textBox;
Grid.SetColumn(contentControl, 1);
Grid.SetRow(contentControl, rowCount);
if (rowCount != 0)
mainPanel.Children.Add(sep);
contentControl = textBox;
Grid.SetRow(sep, rowCount);
Grid.SetColumn(sep, 0);
Grid.SetColumnSpan(sep, 2);
break;
}
break;
}
case "passwordBox":
{
var passwordBox = new PasswordBox()
{
Margin = settingControlMargin,
Password = Settings[attribute.Name] as string ?? string.Empty,
PasswordChar = attribute.passwordChar == default ? '*' : attribute.passwordChar,
HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
ToolTip = attribute.Description
};
var passwordBox = new PasswordBox()
{
MinWidth = SettingPanelTextBoxMinWidth,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemLeftTopBottomMargin,
Password = Settings[attributes.Name] as string ?? string.Empty,
PasswordChar = attributes.passwordChar == default ? '*' : attributes.passwordChar,
ToolTip = attributes.Description,
};
passwordBox.PasswordChanged += (sender, _) =>
{
Settings[attribute.Name] = ((PasswordBox)sender).Password;
};
passwordBox.PasswordChanged += (sender, _) =>
{
Settings[attributes.Name] = ((PasswordBox)sender).Password;
};
contentControl = passwordBox;
Grid.SetColumn(contentControl, 1);
Grid.SetRow(contentControl, rowCount);
if (rowCount != 0)
mainPanel.Children.Add(sep);
contentControl = passwordBox;
Grid.SetRow(sep, rowCount);
Grid.SetColumn(sep, 0);
Grid.SetColumnSpan(sep, 2);
break;
}
break;
}
case "dropdown":
{
var comboBox = new System.Windows.Controls.ComboBox()
{
ItemsSource = attribute.Options,
SelectedItem = Settings[attribute.Name],
Margin = settingControlMargin,
HorizontalAlignment = System.Windows.HorizontalAlignment.Right,
ToolTip = attribute.Description
};
var comboBox = new ComboBox()
{
ItemsSource = attributes.Options,
SelectedItem = Settings[attributes.Name],
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemLeftTopBottomMargin,
ToolTip = attributes.Description
};
comboBox.SelectionChanged += (sender, _) =>
{
Settings[attribute.Name] = (string)((System.Windows.Controls.ComboBox)sender).SelectedItem;
};
comboBox.SelectionChanged += (sender, _) =>
{
Settings[attributes.Name] = (string)((ComboBox)sender).SelectedItem;
};
contentControl = comboBox;
Grid.SetColumn(contentControl, 1);
Grid.SetRow(contentControl, rowCount);
if (rowCount != 0)
mainPanel.Children.Add(sep);
contentControl = comboBox;
Grid.SetRow(sep, rowCount);
Grid.SetColumn(sep, 0);
Grid.SetColumnSpan(sep, 2);
break;
}
break;
}
case "checkbox":
var checkBox = new CheckBox
{
IsChecked =
Settings[attribute.Name] is bool isChecked
// If can parse the default value to bool, use it, otherwise use false
var defaultValue = bool.TryParse(attributes.DefaultValue, out var value) && value;
var checkBox = new CheckBox
{
IsChecked =
Settings[attributes.Name] is bool isChecked
? isChecked
: bool.Parse(attribute.DefaultValue),
Margin = settingCheckboxMargin,
HorizontalAlignment = System.Windows.HorizontalAlignment.Right,
ToolTip = attribute.Description
};
: defaultValue,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemTopBottomMargin,
Content = attributes.Label,
ToolTip = attributes.Description
};
checkBox.Click += (sender, _) =>
{
Settings[attribute.Name] = ((CheckBox)sender).IsChecked;
};
checkBox.Click += (sender, _) =>
{
Settings[attributes.Name] = ((CheckBox)sender).IsChecked ?? defaultValue;
};
contentControl = checkBox;
Grid.SetColumn(contentControl, 1);
Grid.SetRow(contentControl, rowCount);
if (rowCount != 0)
mainPanel.Children.Add(sep);
contentControl = checkBox;
Grid.SetRow(sep, rowCount);
Grid.SetColumn(sep, 0);
Grid.SetColumnSpan(sep, 2);
break;
break;
}
case "hyperlink":
var hyperlink = new Hyperlink { ToolTip = attribute.Description, NavigateUri = attribute.url };
var linkbtn = new System.Windows.Controls.Button
{
HorizontalAlignment = System.Windows.HorizontalAlignment.Right,
Margin = settingControlMargin
};
var hyperlink = new Hyperlink
{
ToolTip = attributes.Description,
NavigateUri = attributes.url
};
linkbtn.Content = attribute.urlLabel;
hyperlink.Inlines.Add(attributes.urlLabel);
hyperlink.RequestNavigate += (sender, e) =>
{
API.OpenUrl(e.Uri);
e.Handled = true;
};
contentControl = linkbtn;
Grid.SetColumn(contentControl, 1);
Grid.SetRow(contentControl, rowCount);
if (rowCount != 0)
mainPanel.Children.Add(sep);
var textBlock = new TextBlock()
{
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
Margin = SettingPanelItemLeftTopBottomMargin,
TextAlignment = TextAlignment.Left,
TextWrapping = TextWrapping.Wrap
};
textBlock.Inlines.Add(hyperlink);
Grid.SetRow(sep, rowCount);
Grid.SetColumn(sep, 0);
Grid.SetColumnSpan(sep, 2);
contentControl = textBlock;
break;
break;
}
case "separator":
{
var sep = new Separator();
sep.SetResourceReference(Separator.StyleProperty, "SettingPanelSeparatorStyle");
contentControl = sep;
break;
}
default:
continue;
}
if (type != "textBlock")
SettingControls[attribute.Name] = contentControl;
// If type is textBlock or separator, we just add the content control to the main grid
if (panel == null)
{
// Add the content control to the column 0, row rowCount and columnSpan 2 of the main grid
mainPanel.Children.Add(contentControl);
Grid.SetColumn(contentControl, 0);
Grid.SetColumnSpan(contentControl, 2);
Grid.SetRow(contentControl, rowCount);
}
else
{
// Add the panel to the column 0 and row rowCount of the main grid
mainPanel.Children.Add(panel);
Grid.SetColumn(panel, 0);
Grid.SetRow(panel, rowCount);
// Add the content control to the column 1 and row rowCount of the main grid
mainPanel.Children.Add(contentControl);
Grid.SetColumn(contentControl, 1);
Grid.SetRow(contentControl, rowCount);
}
// Add into SettingControls for settings storage if need
if (NeedSaveInSettings(type)) SettingControls[attributes.Name] = contentControl;
mainPanel.Children.Add(panel);
mainPanel.Children.Add(contentControl);
rowCount++;
}
return settingWindow;
// Wrap the main grid in a user control
return new UserControl()
{
Content = mainPanel
};
}
private static bool NeedSaveInSettings(string type)
{
return type != "textBlock" && type != "separator" && type != "hyperlink";
}
}
}

View file

@ -205,9 +205,6 @@ namespace Flow.Launcher.Core.Plugin
}
}
InternationalizationManager.Instance.AddPluginLanguageDirectories(GetPluginsForInterface<IPluginI18n>());
InternationalizationManager.Instance.ChangeLanguage(Ioc.Default.GetRequiredService<Settings>().Language);
if (failedPlugins.Any())
{
var failed = string.Join(",", failedPlugins.Select(x => x.Metadata.Name));
@ -231,7 +228,6 @@ namespace Flow.Launcher.Core.Plugin
if (!NonGlobalPlugins.ContainsKey(query.ActionKeyword))
return GlobalPlugins;
var plugin = NonGlobalPlugins[query.ActionKeyword];
return new List<PluginPair>
{
@ -367,7 +363,16 @@ namespace Flow.Launcher.Core.Plugin
NonGlobalPlugins[newActionKeyword] = plugin;
}
// Update action keywords and action keyword in plugin metadata
plugin.Metadata.ActionKeywords.Add(newActionKeyword);
if (plugin.Metadata.ActionKeywords.Count > 0)
{
plugin.Metadata.ActionKeyword = plugin.Metadata.ActionKeywords[0];
}
else
{
plugin.Metadata.ActionKeyword = string.Empty;
}
}
/// <summary>
@ -388,16 +393,15 @@ namespace Flow.Launcher.Core.Plugin
if (oldActionkeyword != Query.GlobalPluginWildcardSign)
NonGlobalPlugins.Remove(oldActionkeyword);
// Update action keywords and action keyword in plugin metadata
plugin.Metadata.ActionKeywords.Remove(oldActionkeyword);
}
public static void ReplaceActionKeyword(string id, string oldActionKeyword, string newActionKeyword)
{
if (oldActionKeyword != newActionKeyword)
if (plugin.Metadata.ActionKeywords.Count > 0)
{
AddActionKeyword(id, newActionKeyword);
RemoveActionKeyword(id, oldActionKeyword);
plugin.Metadata.ActionKeyword = plugin.Metadata.ActionKeywords[0];
}
else
{
plugin.Metadata.ActionKeyword = string.Empty;
}
}

View file

@ -67,9 +67,9 @@ namespace Flow.Launcher.Core.Resource
return DefaultLanguageCode;
}
internal void AddPluginLanguageDirectories(IEnumerable<PluginPair> plugins)
private void AddPluginLanguageDirectories()
{
foreach (var plugin in plugins)
foreach (var plugin in PluginManager.GetPluginsForInterface<IPluginI18n>())
{
var location = Assembly.GetAssembly(plugin.Plugin.GetType()).Location;
var dir = Path.GetDirectoryName(location);
@ -96,6 +96,32 @@ namespace Flow.Launcher.Core.Resource
_oldResources.Clear();
}
/// <summary>
/// Initialize language. Will change app language and plugin language based on settings.
/// </summary>
public async Task InitializeLanguageAsync()
{
// Get actual language
var languageCode = _settings.Language;
if (languageCode == Constant.SystemLanguageCode)
{
languageCode = SystemLanguageCode;
}
// Get language by language code and change language
var language = GetLanguageByLanguageCode(languageCode);
// Add plugin language directories first so that we can load language files from plugins
AddPluginLanguageDirectories();
// Change language
await ChangeLanguageAsync(language);
}
/// <summary>
/// Change language during runtime. Will change app language and plugin language & save settings.
/// </summary>
/// <param name="languageCode"></param>
public void ChangeLanguage(string languageCode)
{
languageCode = languageCode.NonNull();
@ -110,7 +136,12 @@ namespace Flow.Launcher.Core.Resource
// Get language by language code and change language
var language = GetLanguageByLanguageCode(languageCode);
ChangeLanguage(language, isSystem);
// Change language
_ = ChangeLanguageAsync(language);
// Save settings
_settings.Language = isSystem ? Constant.SystemLanguageCode : language.LanguageCode;
}
private Language GetLanguageByLanguageCode(string languageCode)
@ -128,26 +159,22 @@ namespace Flow.Launcher.Core.Resource
}
}
private void ChangeLanguage(Language language, bool isSystem)
private async Task ChangeLanguageAsync(Language language)
{
language = language.NonNull();
// Remove old language files and load language
RemoveOldLanguageFiles();
if (language != AvailableLanguages.English)
{
LoadLanguage(language);
}
// Culture of main thread
// Use CreateSpecificCulture to preserve possible user-override settings in Windows, if Flow's language culture is the same as Windows's
CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture(language.LanguageCode);
CultureInfo.CurrentUICulture = CultureInfo.CurrentCulture;
// Raise event after culture is set
_settings.Language = isSystem ? Constant.SystemLanguageCode : language.LanguageCode;
_ = Task.Run(() =>
{
UpdatePluginMetadataTranslations();
});
// Raise event for plugins after culture is set
await Task.Run(UpdatePluginMetadataTranslations);
}
public bool PromptShouldUsePinyin(string languageCodeToSet)

View file

@ -3,21 +3,29 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Effects;
using System.Windows.Shell;
using System.Windows.Threading;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Microsoft.Win32;
namespace Flow.Launcher.Core.Resource
{
public class Theme
{
#region Properties & Fields
public bool BlurEnabled { get; set; }
private const string ThemeMetadataNamePrefix = "Name:";
private const string ThemeMetadataIsDarkPrefix = "IsDark:";
private const string ThemeMetadataHasBlurPrefix = "HasBlur:";
@ -31,14 +39,12 @@ namespace Flow.Launcher.Core.Resource
private string _oldTheme;
private const string Folder = Constant.Themes;
private const string Extension = ".xaml";
private string DirectoryPath => Path.Combine(Constant.ProgramDirectory, Folder);
private string UserDirectoryPath => Path.Combine(DataLocation.DataDirectory(), Folder);
private static string DirectoryPath => Path.Combine(Constant.ProgramDirectory, Folder);
private static string UserDirectoryPath => Path.Combine(DataLocation.DataDirectory(), Folder);
public string CurrentTheme => _settings.Theme;
#endregion
public bool BlurEnabled { get; set; }
private double mainWindowWidth;
#region Constructor
public Theme(IPublicAPI publicAPI, Settings settings)
{
@ -50,20 +56,32 @@ namespace Flow.Launcher.Core.Resource
MakeSureThemeDirectoriesExist();
var dicts = Application.Current.Resources.MergedDictionaries;
_oldResource = dicts.First(d =>
_oldResource = dicts.FirstOrDefault(d =>
{
if (d.Source == null)
return false;
if (d.Source == null) return false;
var p = d.Source.AbsolutePath;
var dir = Path.GetDirectoryName(p).NonNull();
var info = new DirectoryInfo(dir);
var f = info.Name;
var e = Path.GetExtension(p);
var found = f == Folder && e == Extension;
return found;
return p.Contains(Folder) && Path.GetExtension(p) == Extension;
});
_oldTheme = Path.GetFileNameWithoutExtension(_oldResource.Source.AbsolutePath);
if (_oldResource != null)
{
_oldTheme = Path.GetFileNameWithoutExtension(_oldResource.Source.AbsolutePath);
}
else
{
Log.Error("Current theme resource not found. Initializing with default theme.");
_oldTheme = Constant.DefaultTheme;
};
}
#endregion
#region Theme Resources
public string GetCurrentTheme()
{
return _settings.Theme;
}
private void MakeSureThemeDirectoriesExist()
@ -81,68 +99,154 @@ namespace Flow.Launcher.Core.Resource
}
}
public bool ChangeTheme(string theme)
{
const string defaultTheme = Constant.DefaultTheme;
string path = GetThemePath(theme);
try
{
if (string.IsNullOrEmpty(path))
throw new DirectoryNotFoundException("Theme path can't be found <{path}>");
// reload all resources even if the theme itself hasn't changed in order to pickup changes
// to things like fonts
UpdateResourceDictionary(GetResourceDictionary(theme));
_settings.Theme = theme;
//always allow re-loading default theme, in case of failure of switching to a new theme from default theme
if (_oldTheme != theme || theme == defaultTheme)
{
_oldTheme = Path.GetFileNameWithoutExtension(_oldResource.Source.AbsolutePath);
}
BlurEnabled = Win32Helper.IsBlurTheme();
if (_settings.UseDropShadowEffect && !BlurEnabled)
AddDropShadowEffectToCurrentTheme();
Win32Helper.SetBlurForWindow(Application.Current.MainWindow, BlurEnabled);
}
catch (DirectoryNotFoundException)
{
Log.Error($"|Theme.ChangeTheme|Theme <{theme}> path can't be found");
if (theme != defaultTheme)
{
_api.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_path_not_exists"), theme));
ChangeTheme(defaultTheme);
}
return false;
}
catch (XamlParseException)
{
Log.Error($"|Theme.ChangeTheme|Theme <{theme}> fail to parse");
if (theme != defaultTheme)
{
_api.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_parse_error"), theme));
ChangeTheme(defaultTheme);
}
return false;
}
return true;
}
private void UpdateResourceDictionary(ResourceDictionary dictionaryToUpdate)
{
var dicts = Application.Current.Resources.MergedDictionaries;
// Add new resources
if (!Application.Current.Resources.MergedDictionaries.Contains(dictionaryToUpdate))
{
Application.Current.Resources.MergedDictionaries.Add(dictionaryToUpdate);
}
// Remove old resources
if (_oldResource != null && _oldResource != dictionaryToUpdate &&
Application.Current.Resources.MergedDictionaries.Contains(_oldResource))
{
Application.Current.Resources.MergedDictionaries.Remove(_oldResource);
}
dicts.Remove(_oldResource);
dicts.Add(dictionaryToUpdate);
_oldResource = dictionaryToUpdate;
}
/// <summary>
/// Updates only the font settings and refreshes the UI.
/// </summary>
public void UpdateFonts()
{
try
{
// Load a ResourceDictionary for the specified theme.
var themeName = GetCurrentTheme();
var dict = GetThemeResourceDictionary(themeName);
// Apply font settings to the theme resource.
ApplyFontSettings(dict);
UpdateResourceDictionary(dict);
// Must apply blur and drop shadow effects
_ = RefreshFrameAsync();
}
catch (Exception e)
{
Log.Exception("Error occurred while updating theme fonts", e);
}
}
/// <summary>
/// Loads and applies font settings to the theme resource.
/// </summary>
private void ApplyFontSettings(ResourceDictionary dict)
{
if (dict["QueryBoxStyle"] is Style queryBoxStyle &&
dict["QuerySuggestionBoxStyle"] is Style querySuggestionBoxStyle)
{
var fontFamily = new FontFamily(_settings.QueryBoxFont);
var fontStyle = FontHelper.GetFontStyleFromInvariantStringOrNormal(_settings.QueryBoxFontStyle);
var fontWeight = FontHelper.GetFontWeightFromInvariantStringOrNormal(_settings.QueryBoxFontWeight);
var fontStretch = FontHelper.GetFontStretchFromInvariantStringOrNormal(_settings.QueryBoxFontStretch);
SetFontProperties(queryBoxStyle, fontFamily, fontStyle, fontWeight, fontStretch, true);
SetFontProperties(querySuggestionBoxStyle, fontFamily, fontStyle, fontWeight, fontStretch, false);
}
if (dict["ItemTitleStyle"] is Style resultItemStyle &&
dict["ItemTitleSelectedStyle"] is Style resultItemSelectedStyle &&
dict["ItemHotkeyStyle"] is Style resultHotkeyItemStyle &&
dict["ItemHotkeySelectedStyle"] is Style resultHotkeyItemSelectedStyle)
{
var fontFamily = new FontFamily(_settings.ResultFont);
var fontStyle = FontHelper.GetFontStyleFromInvariantStringOrNormal(_settings.ResultFontStyle);
var fontWeight = FontHelper.GetFontWeightFromInvariantStringOrNormal(_settings.ResultFontWeight);
var fontStretch = FontHelper.GetFontStretchFromInvariantStringOrNormal(_settings.ResultFontStretch);
SetFontProperties(resultItemStyle, fontFamily, fontStyle, fontWeight, fontStretch, false);
SetFontProperties(resultItemSelectedStyle, fontFamily, fontStyle, fontWeight, fontStretch, false);
SetFontProperties(resultHotkeyItemStyle, fontFamily, fontStyle, fontWeight, fontStretch, false);
SetFontProperties(resultHotkeyItemSelectedStyle, fontFamily, fontStyle, fontWeight, fontStretch, false);
}
if (dict["ItemSubTitleStyle"] is Style resultSubItemStyle &&
dict["ItemSubTitleSelectedStyle"] is Style resultSubItemSelectedStyle)
{
var fontFamily = new FontFamily(_settings.ResultSubFont);
var fontStyle = FontHelper.GetFontStyleFromInvariantStringOrNormal(_settings.ResultSubFontStyle);
var fontWeight = FontHelper.GetFontWeightFromInvariantStringOrNormal(_settings.ResultSubFontWeight);
var fontStretch = FontHelper.GetFontStretchFromInvariantStringOrNormal(_settings.ResultSubFontStretch);
SetFontProperties(resultSubItemStyle, fontFamily, fontStyle, fontWeight, fontStretch, false);
SetFontProperties(resultSubItemSelectedStyle, fontFamily, fontStyle, fontWeight, fontStretch, false);
}
}
/// <summary>
/// Applies font properties to a Style.
/// </summary>
private static void SetFontProperties(Style style, FontFamily fontFamily, FontStyle fontStyle, FontWeight fontWeight, FontStretch fontStretch, bool isTextBox)
{
// Remove existing font-related setters
if (isTextBox)
{
// First, find the setters to remove and store them in a list
var settersToRemove = style.Setters
.OfType<Setter>()
.Where(setter =>
setter.Property == Control.FontFamilyProperty ||
setter.Property == Control.FontStyleProperty ||
setter.Property == Control.FontWeightProperty ||
setter.Property == Control.FontStretchProperty)
.ToList();
// Remove each found setter one by one
foreach (var setter in settersToRemove)
{
style.Setters.Remove(setter);
}
// Add New font setter
style.Setters.Add(new Setter(Control.FontFamilyProperty, fontFamily));
style.Setters.Add(new Setter(Control.FontStyleProperty, fontStyle));
style.Setters.Add(new Setter(Control.FontWeightProperty, fontWeight));
style.Setters.Add(new Setter(Control.FontStretchProperty, fontStretch));
// Set caret brush (retain existing logic)
var caretBrushPropertyValue = style.Setters.OfType<Setter>().Any(x => x.Property.Name == "CaretBrush");
var foregroundPropertyValue = style.Setters.OfType<Setter>().Where(x => x.Property.Name == "Foreground")
.Select(x => x.Value).FirstOrDefault();
if (!caretBrushPropertyValue && foregroundPropertyValue != null)
style.Setters.Add(new Setter(TextBoxBase.CaretBrushProperty, foregroundPropertyValue));
}
else
{
var settersToRemove = style.Setters
.OfType<Setter>()
.Where(setter =>
setter.Property == TextBlock.FontFamilyProperty ||
setter.Property == TextBlock.FontStyleProperty ||
setter.Property == TextBlock.FontWeightProperty ||
setter.Property == TextBlock.FontStretchProperty)
.ToList();
foreach (var setter in settersToRemove)
{
style.Setters.Remove(setter);
}
style.Setters.Add(new Setter(TextBlock.FontFamilyProperty, fontFamily));
style.Setters.Add(new Setter(TextBlock.FontStyleProperty, fontStyle));
style.Setters.Add(new Setter(TextBlock.FontWeightProperty, fontWeight));
style.Setters.Add(new Setter(TextBlock.FontStretchProperty, fontStretch));
}
}
private ResourceDictionary GetThemeResourceDictionary(string theme)
{
var uri = GetThemePath(theme);
@ -154,9 +258,7 @@ namespace Flow.Launcher.Core.Resource
return dict;
}
private ResourceDictionary CurrentThemeResourceDictionary() => GetThemeResourceDictionary(_settings.Theme);
public ResourceDictionary GetResourceDictionary(string theme)
private ResourceDictionary GetResourceDictionary(string theme)
{
var dict = GetThemeResourceDictionary(theme);
@ -168,22 +270,22 @@ namespace Flow.Launcher.Core.Resource
var fontWeight = FontHelper.GetFontWeightFromInvariantStringOrNormal(_settings.QueryBoxFontWeight);
var fontStretch = FontHelper.GetFontStretchFromInvariantStringOrNormal(_settings.QueryBoxFontStretch);
queryBoxStyle.Setters.Add(new Setter(TextBox.FontFamilyProperty, fontFamily));
queryBoxStyle.Setters.Add(new Setter(TextBox.FontStyleProperty, fontStyle));
queryBoxStyle.Setters.Add(new Setter(TextBox.FontWeightProperty, fontWeight));
queryBoxStyle.Setters.Add(new Setter(TextBox.FontStretchProperty, fontStretch));
queryBoxStyle.Setters.Add(new Setter(Control.FontFamilyProperty, fontFamily));
queryBoxStyle.Setters.Add(new Setter(Control.FontStyleProperty, fontStyle));
queryBoxStyle.Setters.Add(new Setter(Control.FontWeightProperty, fontWeight));
queryBoxStyle.Setters.Add(new Setter(Control.FontStretchProperty, fontStretch));
var caretBrushPropertyValue = queryBoxStyle.Setters.OfType<Setter>().Any(x => x.Property.Name == "CaretBrush");
var foregroundPropertyValue = queryBoxStyle.Setters.OfType<Setter>().Where(x => x.Property.Name == "Foreground")
.Select(x => x.Value).FirstOrDefault();
if (!caretBrushPropertyValue && foregroundPropertyValue != null) //otherwise BaseQueryBoxStyle will handle styling
queryBoxStyle.Setters.Add(new Setter(TextBox.CaretBrushProperty, foregroundPropertyValue));
queryBoxStyle.Setters.Add(new Setter(TextBoxBase.CaretBrushProperty, foregroundPropertyValue));
// Query suggestion box's font style is aligned with query box
querySuggestionBoxStyle.Setters.Add(new Setter(TextBox.FontFamilyProperty, fontFamily));
querySuggestionBoxStyle.Setters.Add(new Setter(TextBox.FontStyleProperty, fontStyle));
querySuggestionBoxStyle.Setters.Add(new Setter(TextBox.FontWeightProperty, fontWeight));
querySuggestionBoxStyle.Setters.Add(new Setter(TextBox.FontStretchProperty, fontStretch));
querySuggestionBoxStyle.Setters.Add(new Setter(Control.FontFamilyProperty, fontFamily));
querySuggestionBoxStyle.Setters.Add(new Setter(Control.FontStyleProperty, fontStyle));
querySuggestionBoxStyle.Setters.Add(new Setter(Control.FontWeightProperty, fontWeight));
querySuggestionBoxStyle.Setters.Add(new Setter(Control.FontStretchProperty, fontStretch));
}
if (dict["ItemTitleStyle"] is Style resultItemStyle &&
@ -213,36 +315,20 @@ namespace Flow.Launcher.Core.Resource
Setter[] setters = { fontFamily, fontStyle, fontWeight, fontStretch };
Array.ForEach(
new[] { resultSubItemStyle,resultSubItemSelectedStyle}, o
new[] { resultSubItemStyle, resultSubItemSelectedStyle }, o
=> Array.ForEach(setters, p => o.Setters.Add(p)));
}
/* Ignore Theme Window Width and use setting */
var windowStyle = dict["WindowStyle"] as Style;
var width = _settings.WindowSize;
windowStyle.Setters.Add(new Setter(Window.WidthProperty, width));
mainWindowWidth = (double)width;
windowStyle.Setters.Add(new Setter(FrameworkElement.WidthProperty, width));
return dict;
}
private ResourceDictionary GetCurrentResourceDictionary( )
private ResourceDictionary GetCurrentResourceDictionary()
{
return GetResourceDictionary(_settings.Theme);
}
public List<ThemeData> LoadAvailableThemes()
{
List<ThemeData> themes = new List<ThemeData>();
foreach (var themeDirectory in _themeDirectories)
{
var filePaths = Directory
.GetFiles(themeDirectory)
.Where(filePath => filePath.EndsWith(Extension) && !filePath.EndsWith("Base.xaml"))
.Select(GetThemeDataFromPath);
themes.AddRange(filePaths);
}
return themes.OrderBy(o => o.Name).ToList();
return GetResourceDictionary(GetCurrentTheme());
}
private ThemeData GetThemeDataFromPath(string path)
@ -264,15 +350,15 @@ namespace Flow.Launcher.Core.Resource
{
if (line.StartsWith(ThemeMetadataNamePrefix, StringComparison.OrdinalIgnoreCase))
{
name = line.Remove(0, ThemeMetadataNamePrefix.Length).Trim();
name = line[ThemeMetadataNamePrefix.Length..].Trim();
}
else if (line.StartsWith(ThemeMetadataIsDarkPrefix, StringComparison.OrdinalIgnoreCase))
{
isDark = bool.Parse(line.Remove(0, ThemeMetadataIsDarkPrefix.Length).Trim());
isDark = bool.Parse(line[ThemeMetadataIsDarkPrefix.Length..].Trim());
}
else if (line.StartsWith(ThemeMetadataHasBlurPrefix, StringComparison.OrdinalIgnoreCase))
{
hasBlur = bool.Parse(line.Remove(0, ThemeMetadataHasBlurPrefix.Length).Trim());
hasBlur = bool.Parse(line[ThemeMetadataHasBlurPrefix.Length..].Trim());
}
}
@ -293,6 +379,82 @@ namespace Flow.Launcher.Core.Resource
return string.Empty;
}
#endregion
#region Load & Change
public List<ThemeData> LoadAvailableThemes()
{
List<ThemeData> themes = new List<ThemeData>();
foreach (var themeDirectory in _themeDirectories)
{
var filePaths = Directory
.GetFiles(themeDirectory)
.Where(filePath => filePath.EndsWith(Extension) && !filePath.EndsWith("Base.xaml"))
.Select(GetThemeDataFromPath);
themes.AddRange(filePaths);
}
return themes.OrderBy(o => o.Name).ToList();
}
public bool ChangeTheme(string theme = null)
{
if (string.IsNullOrEmpty(theme))
theme = GetCurrentTheme();
string path = GetThemePath(theme);
try
{
if (string.IsNullOrEmpty(path))
throw new DirectoryNotFoundException($"Theme path can't be found <{path}>");
// Retrieve theme resource always use the resource with font settings applied.
var resourceDict = GetResourceDictionary(theme);
UpdateResourceDictionary(resourceDict);
_settings.Theme = theme;
//always allow re-loading default theme, in case of failure of switching to a new theme from default theme
if (_oldTheme != theme || theme == Constant.DefaultTheme)
{
_oldTheme = Path.GetFileNameWithoutExtension(_oldResource.Source.AbsolutePath);
}
BlurEnabled = IsBlurTheme();
// Can only apply blur but here also apply drop shadow effect to avoid possible drop shadow effect issues
_ = RefreshFrameAsync();
return true;
}
catch (DirectoryNotFoundException)
{
Log.Error($"|Theme.ChangeTheme|Theme <{theme}> path can't be found");
if (theme != Constant.DefaultTheme)
{
_api.ShowMsgBox(string.Format(_api.GetTranslation("theme_load_failure_path_not_exists"), theme));
ChangeTheme(Constant.DefaultTheme);
}
return false;
}
catch (XamlParseException)
{
Log.Error($"|Theme.ChangeTheme|Theme <{theme}> fail to parse");
if (theme != Constant.DefaultTheme)
{
_api.ShowMsgBox(string.Format(_api.GetTranslation("theme_load_failure_parse_error"), theme));
ChangeTheme(Constant.DefaultTheme);
}
return false;
}
}
#endregion
#region Shadow Effect
public void AddDropShadowEffectToCurrentTheme()
{
var dict = GetCurrentResourceDictionary();
@ -311,8 +473,7 @@ namespace Flow.Launcher.Core.Resource
}
};
var marginSetter = windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == Border.MarginProperty) as Setter;
if (marginSetter == null)
if (windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == Border.MarginProperty) is not Setter marginSetter)
{
var margin = new Thickness(ShadowExtraMargin, 12, ShadowExtraMargin, ShadowExtraMargin);
marginSetter = new Setter()
@ -347,14 +508,12 @@ namespace Flow.Launcher.Core.Resource
var dict = GetCurrentResourceDictionary();
var windowBorderStyle = dict["WindowBorderStyle"] as Style;
var effectSetter = windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == Border.EffectProperty) as Setter;
var marginSetter = windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == Border.MarginProperty) as Setter;
if (effectSetter != null)
if (windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == Border.EffectProperty) is Setter effectSetter)
{
windowBorderStyle.Setters.Remove(effectSetter);
}
if (marginSetter != null)
if (windowBorderStyle.Setters.FirstOrDefault(setterBase => setterBase is Setter setter && setter.Property == Border.MarginProperty) is Setter marginSetter)
{
var currentMargin = (Thickness)marginSetter.Value;
var newMargin = new Thickness(
@ -395,6 +554,340 @@ namespace Flow.Launcher.Core.Resource
}
}
#endregion
#region Blur Handling
/// <summary>
/// Refreshes the frame to apply the current theme settings.
/// </summary>
public async Task RefreshFrameAsync()
{
await Application.Current.Dispatcher.InvokeAsync(() =>
{
// Get the actual backdrop type and drop shadow effect settings
var (backdropType, useDropShadowEffect) = GetActualValue();
// Remove OS minimizing/maximizing animation
// Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_TRANSITIONS_FORCEDISABLED, 3);
// The timing of adding the shadow effect should vary depending on whether the theme is transparent.
if (BlurEnabled)
{
AutoDropShadow(useDropShadowEffect);
}
SetBlurForWindow(GetCurrentTheme(), backdropType);
if (!BlurEnabled)
{
AutoDropShadow(useDropShadowEffect);
}
}, DispatcherPriority.Normal);
}
/// <summary>
/// Sets the blur for a window via SetWindowCompositionAttribute
/// </summary>
public async Task SetBlurForWindowAsync()
{
await Application.Current.Dispatcher.InvokeAsync(() =>
{
// Get the actual backdrop type and drop shadow effect settings
var (backdropType, _) = GetActualValue();
SetBlurForWindow(GetCurrentTheme(), backdropType);
}, DispatcherPriority.Normal);
}
/// <summary>
/// Gets the actual backdrop type and drop shadow effect settings based on the current theme status.
/// </summary>
public (BackdropTypes BackdropType, bool UseDropShadowEffect) GetActualValue()
{
var backdropType = _settings.BackdropType;
var useDropShadowEffect = _settings.UseDropShadowEffect;
// When changed non-blur theme, change to backdrop to none
if (!BlurEnabled)
{
backdropType = BackdropTypes.None;
}
// Dropshadow on and control disabled.(user can't change dropshadow with blur theme)
if (BlurEnabled)
{
useDropShadowEffect = true;
}
return (backdropType, useDropShadowEffect);
}
private void SetBlurForWindow(string theme, BackdropTypes backdropType)
{
var dict = GetResourceDictionary(theme);
if (dict == null) return;
var windowBorderStyle = dict.Contains("WindowBorderStyle") ? dict["WindowBorderStyle"] as Style : null;
if (windowBorderStyle == null) return;
var mainWindow = Application.Current.MainWindow;
if (mainWindow == null) return;
// Check if the theme supports blur
bool hasBlur = dict.Contains("ThemeBlurEnabled") && dict["ThemeBlurEnabled"] is bool b && b;
if (BlurEnabled && hasBlur && Win32Helper.IsBackdropSupported())
{
// If the BackdropType is Mica or MicaAlt, set the windowborderstyle's background to transparent
if (backdropType == BackdropTypes.Mica || backdropType == BackdropTypes.MicaAlt)
{
windowBorderStyle.Setters.Remove(windowBorderStyle.Setters.OfType<Setter>().FirstOrDefault(x => x.Property.Name == "Background"));
windowBorderStyle.Setters.Add(new Setter(Border.BackgroundProperty, new SolidColorBrush(Color.FromArgb(1, 0, 0, 0))));
}
else if (backdropType == BackdropTypes.Acrylic)
{
windowBorderStyle.Setters.Remove(windowBorderStyle.Setters.OfType<Setter>().FirstOrDefault(x => x.Property.Name == "Background"));
windowBorderStyle.Setters.Add(new Setter(Border.BackgroundProperty, new SolidColorBrush(Colors.Transparent)));
}
// Apply the blur effect
Win32Helper.DWMSetBackdropForWindow(mainWindow, backdropType);
ColorizeWindow(theme, backdropType);
}
else
{
// Apply default style when Blur is disabled
Win32Helper.DWMSetBackdropForWindow(mainWindow, BackdropTypes.None);
ColorizeWindow(theme, backdropType);
}
UpdateResourceDictionary(dict);
}
private void AutoDropShadow(bool useDropShadowEffect)
{
SetWindowCornerPreference("Default");
RemoveDropShadowEffectFromCurrentTheme();
if (useDropShadowEffect)
{
if (BlurEnabled && Win32Helper.IsBackdropSupported())
{
SetWindowCornerPreference("Round");
}
else
{
SetWindowCornerPreference("Default");
AddDropShadowEffectToCurrentTheme();
}
}
else
{
if (BlurEnabled && Win32Helper.IsBackdropSupported())
{
SetWindowCornerPreference("Default");
}
else
{
RemoveDropShadowEffectFromCurrentTheme();
}
}
}
private static void SetWindowCornerPreference(string cornerType)
{
Window mainWindow = Application.Current.MainWindow;
if (mainWindow == null)
return;
Win32Helper.DWMSetCornerPreferenceForWindow(mainWindow, cornerType);
}
// Get Background Color from WindowBorderStyle when there not color for BG.
// for theme has not "LightBG" or "DarkBG" case.
private Color GetWindowBorderStyleBackground(string theme)
{
var Resources = GetThemeResourceDictionary(theme);
var windowBorderStyle = (Style)Resources["WindowBorderStyle"];
var backgroundSetter = windowBorderStyle.Setters
.OfType<Setter>()
.FirstOrDefault(s => s.Property == Border.BackgroundProperty);
if (backgroundSetter != null)
{
// Background's Value is DynamicColor Case
var backgroundValue = backgroundSetter.Value;
if (backgroundValue is SolidColorBrush solidColorBrush)
{
return solidColorBrush.Color; // Return SolidColorBrush's Color
}
else if (backgroundValue is DynamicResourceExtension dynamicResource)
{
// When DynamicResource Extension it is, Key is resource's name.
var resourceKey = backgroundSetter.Value.ToString();
// find key in resource and return color.
if (Resources.Contains(resourceKey))
{
var colorResource = Resources[resourceKey];
if (colorResource is SolidColorBrush colorBrush)
{
return colorBrush.Color;
}
else if (colorResource is Color color)
{
return color;
}
}
}
}
return Colors.Transparent; // Default is transparent
}
private void ApplyPreviewBackground(Color? bgColor = null)
{
if (bgColor == null) return;
// Copy the existing WindowBorderStyle
var previewStyle = new Style(typeof(Border));
if (Application.Current.Resources.Contains("WindowBorderStyle"))
{
if (Application.Current.Resources["WindowBorderStyle"] is Style originalStyle)
{
foreach (var setter in originalStyle.Setters.OfType<Setter>())
{
previewStyle.Setters.Add(new Setter(setter.Property, setter.Value));
}
}
}
// Apply background color (remove transparency in color)
// WPF does not allow the use of an acrylic brush within the window's internal area,
// so transparency effects are not applied to the preview.
Color backgroundColor = Color.FromRgb(bgColor.Value.R, bgColor.Value.G, bgColor.Value.B);
previewStyle.Setters.Add(new Setter(Border.BackgroundProperty, new SolidColorBrush(backgroundColor)));
// The blur theme keeps the corner round fixed (applying DWM code to modify it causes rendering issues).
// The non-blur theme retains the previously set WindowBorderStyle.
if (BlurEnabled)
{
previewStyle.Setters.Add(new Setter(Border.CornerRadiusProperty, new CornerRadius(5)));
previewStyle.Setters.Add(new Setter(Border.BorderThicknessProperty, new Thickness(1)));
}
Application.Current.Resources["PreviewWindowBorderStyle"] = previewStyle;
}
private void ColorizeWindow(string theme, BackdropTypes backdropType)
{
var dict = GetThemeResourceDictionary(theme);
if (dict == null) return;
var mainWindow = Application.Current.MainWindow;
if (mainWindow == null) return;
// Check if the theme supports blur
bool hasBlur = dict.Contains("ThemeBlurEnabled") && dict["ThemeBlurEnabled"] is bool b && b;
// SystemBG value check (Auto, Light, Dark)
string systemBG = dict.Contains("SystemBG") ? dict["SystemBG"] as string : "Auto"; // 기본값 Auto
// Check the user's ColorScheme setting
string colorScheme = _settings.ColorScheme;
// Check system dark mode setting (read AppsUseLightTheme value)
int themeValue = (int)Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", "AppsUseLightTheme", 1);
bool isSystemDark = themeValue == 0;
// Final decision on whether to use dark mode
bool useDarkMode = false;
// If systemBG is not "Auto", prioritize it over ColorScheme and set the mode based on systemBG value
if (systemBG == "Dark")
{
useDarkMode = true; // Dark
}
else if (systemBG == "Light")
{
useDarkMode = false; // Light
}
else if (systemBG == "Auto")
{
// If systemBG is "Auto", decide based on ColorScheme
if (colorScheme == "Dark")
useDarkMode = true;
else if (colorScheme == "Light")
useDarkMode = false;
else
useDarkMode = isSystemDark; // Auto (based on system setting)
}
// Apply DWM Dark Mode
Win32Helper.DWMSetDarkModeForWindow(mainWindow, useDarkMode);
Color LightBG;
Color DarkBG;
// Retrieve LightBG value (fallback to WindowBorderStyle background color if not found)
try
{
LightBG = dict.Contains("LightBG") ? (Color)dict["LightBG"] : GetWindowBorderStyleBackground(theme);
}
catch (Exception)
{
LightBG = GetWindowBorderStyleBackground(theme);
}
// Retrieve DarkBG value (fallback to LightBG if not found)
try
{
DarkBG = dict.Contains("DarkBG") ? (Color)dict["DarkBG"] : LightBG;
}
catch (Exception)
{
DarkBG = LightBG;
}
// Select background color based on ColorScheme and SystemBG
Color selectedBG = useDarkMode ? DarkBG : LightBG;
ApplyPreviewBackground(selectedBG);
bool isBlurAvailable = hasBlur && Win32Helper.IsBackdropSupported(); // Windows 11 미만이면 hasBlur를 강제 false
if (!isBlurAvailable)
{
mainWindow.Background = Brushes.Transparent;
}
else
{
// Only set the background to transparent if the theme supports blur
if (backdropType == BackdropTypes.Mica || backdropType == BackdropTypes.MicaAlt)
{
mainWindow.Background = new SolidColorBrush(Color.FromArgb(1, 0, 0, 0));
}
else
{
mainWindow.Background = new SolidColorBrush(selectedBG);
}
}
}
private static bool IsBlurTheme()
{
if (!Win32Helper.IsBackdropSupported()) // Windows 11 미만이면 무조건 false
return false;
var resource = Application.Current.TryFindResource("ThemeBlurEnabled");
return resource is bool b && b;
}
#endregion
#region Classes
public record ThemeData(string FileNameWithoutExtension, string Name, bool? IsDark = null, bool? HasBlur = null);
#endregion
}
}

View file

@ -32,6 +32,7 @@ namespace Flow.Launcher.Infrastructure
public static readonly string MissingImgIcon = Path.Combine(ImagesDirectory, "app_missing_img.png");
public static readonly string LoadingImgIcon = Path.Combine(ImagesDirectory, "loading.png");
public static readonly string ImageIcon = Path.Combine(ImagesDirectory, "image.png");
public static readonly string HistoryIcon = Path.Combine(ImagesDirectory, "history.png");
public static string PythonPath;
public static string NodePath;

View file

@ -0,0 +1,123 @@
using System.Collections.Generic;
using System;
using System.Runtime.InteropServices;
using System.Windows;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.Graphics.Gdi;
using Windows.Win32.UI.WindowsAndMessaging;
namespace Flow.Launcher.Infrastructure;
/// <summary>
/// Contains full information about a display monitor.
/// Codes are edited from: <see href="https://github.com/Jack251970/DesktopWidgets3">.
/// </summary>
internal class MonitorInfo
{
/// <summary>
/// Gets the display monitors (including invisible pseudo-monitors associated with the mirroring drivers).
/// </summary>
/// <returns>A list of display monitors</returns>
public static unsafe IList<MonitorInfo> GetDisplayMonitors()
{
var monitorCount = PInvoke.GetSystemMetrics(SYSTEM_METRICS_INDEX.SM_CMONITORS);
var list = new List<MonitorInfo>(monitorCount);
var callback = new MONITORENUMPROC((HMONITOR monitor, HDC deviceContext, RECT* rect, LPARAM data) =>
{
list.Add(new MonitorInfo(monitor, rect));
return true;
});
var dwData = new LPARAM();
var hdc = new HDC();
bool ok = PInvoke.EnumDisplayMonitors(hdc, (RECT?)null, callback, dwData);
if (!ok)
{
Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
}
return list;
}
/// <summary>
/// Gets the display monitor that is nearest to a given window.
/// </summary>
/// <param name="hwnd">Window handle</param>
/// <returns>The display monitor that is nearest to a given window, or null if no monitor is found.</returns>
public static unsafe MonitorInfo GetNearestDisplayMonitor(HWND hwnd)
{
var nearestMonitor = PInvoke.MonitorFromWindow(hwnd, MONITOR_FROM_FLAGS.MONITOR_DEFAULTTONEAREST);
MonitorInfo nearestMonitorInfo = null;
var callback = new MONITORENUMPROC((HMONITOR monitor, HDC deviceContext, RECT* rect, LPARAM data) =>
{
if (monitor == nearestMonitor)
{
nearestMonitorInfo = new MonitorInfo(monitor, rect);
return false;
}
return true;
});
var dwData = new LPARAM();
var hdc = new HDC();
bool ok = PInvoke.EnumDisplayMonitors(hdc, (RECT?)null, callback, dwData);
if (!ok)
{
Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
}
return nearestMonitorInfo;
}
private readonly HMONITOR _monitor;
internal unsafe MonitorInfo(HMONITOR monitor, RECT* rect)
{
RectMonitor =
new Rect(new Point(rect->left, rect->top),
new Point(rect->right, rect->bottom));
_monitor = monitor;
var info = new MONITORINFOEXW() { monitorInfo = new MONITORINFO() { cbSize = (uint)sizeof(MONITORINFOEXW) } };
GetMonitorInfo(monitor, ref info);
RectWork =
new Rect(new Point(info.monitorInfo.rcWork.left, info.monitorInfo.rcWork.top),
new Point(info.monitorInfo.rcWork.right, info.monitorInfo.rcWork.bottom));
Name = new string(info.szDevice.AsSpan()).Replace("\0", "").Trim();
}
/// <summary>
/// Gets the name of the display.
/// </summary>
public string Name { get; }
/// <summary>
/// Gets the display monitor rectangle, expressed in virtual-screen coordinates.
/// </summary>
/// <remarks>
/// <note>If the monitor is not the primary display monitor, some of the rectangle's coordinates may be negative values.</note>
/// </remarks>
public Rect RectMonitor { get; }
/// <summary>
/// Gets the work area rectangle of the display monitor, expressed in virtual-screen coordinates.
/// </summary>
/// <remarks>
/// <note>If the monitor is not the primary display monitor, some of the rectangle's coordinates may be negative values.</note>
/// </remarks>
public Rect RectWork { get; }
/// <summary>
/// Gets if the monitor is the the primary display monitor.
/// </summary>
public bool IsPrimary => _monitor == PInvoke.MonitorFromWindow(new(IntPtr.Zero), MONITOR_FROM_FLAGS.MONITOR_DEFAULTTOPRIMARY);
/// <inheritdoc />
public override string ToString() => $"{Name} {RectMonitor.Width}x{RectMonitor.Height}";
private static unsafe bool GetMonitorInfo(HMONITOR hMonitor, ref MONITORINFOEXW lpmi)
{
fixed (MONITORINFOEXW* lpmiLocal = &lpmi)
{
var lpmiBase = (MONITORINFO*)lpmiLocal;
var __result = PInvoke.GetMonitorInfo(hMonitor, lpmiBase);
return __result;
}
}
}

View file

@ -16,4 +16,46 @@ WM_KEYUP
WM_SYSKEYDOWN
WM_SYSKEYUP
EnumWindows
EnumWindows
DwmSetWindowAttribute
DWM_SYSTEMBACKDROP_TYPE
DWM_WINDOW_CORNER_PREFERENCE
MAX_PATH
SystemParametersInfo
SetForegroundWindow
GetWindowLong
GetForegroundWindow
GetDesktopWindow
GetShellWindow
GetWindowRect
GetClassName
FindWindowEx
WINDOW_STYLE
SetLastError
WINDOW_EX_STYLE
GetSystemMetrics
EnumDisplayMonitors
MonitorFromWindow
GetMonitorInfo
MONITORINFOEXW
WM_ENTERSIZEMOVE
WM_EXITSIZEMOVE
GetKeyboardLayout
GetWindowThreadProcessId
ActivateKeyboardLayout
GetKeyboardLayoutList
PostMessage
WM_INPUTLANGCHANGEREQUEST
INPUTLANGCHANGE_FORWARD
LOCALE_TRANSIENT_KEYBOARD1
LOCALE_TRANSIENT_KEYBOARD2
LOCALE_TRANSIENT_KEYBOARD3
LOCALE_TRANSIENT_KEYBOARD4

View file

@ -0,0 +1,25 @@
using System.Runtime.InteropServices;
using Windows.Win32.Foundation;
using Windows.Win32.UI.WindowsAndMessaging;
namespace Windows.Win32;
// Edited from: https://github.com/files-community/Files
internal static partial class PInvoke
{
[DllImport("User32", EntryPoint = "SetWindowLongW", ExactSpelling = true)]
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);
// NOTE:
// CsWin32 doesn't generate SetWindowLong on other than x86 and vice versa.
// For more info, visit https://github.com/microsoft/CsWin32/issues/882
public static unsafe nint SetWindowLongPtr(HWND hWnd, WINDOW_LONG_PTR_INDEX nIndex, nint dwNewLong)
{
return sizeof(nint) is 4
? _SetWindowLong(hWnd, (int)nIndex, (int)dwNewLong)
: _SetWindowLongPtr(hWnd, (int)nIndex, dwNewLong);
}
}

View file

@ -76,6 +76,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
}
}
public bool UseDropShadowEffect { get; set; } = true;
public BackdropTypes BackdropType{ get; set; } = BackdropTypes.None;
/* Appearance Settings. It should be separated from the setting later.*/
public double WindowHeightSize { get; set; } = 42;
@ -430,4 +431,12 @@ namespace Flow.Launcher.Infrastructure.UserSettings
Fast,
Custom
}
public enum BackdropTypes
{
None,
Acrylic,
Mica,
MicaAlt
}
}

View file

@ -1,7 +1,18 @@
using System;
using System.ComponentModel;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Windows.Interop;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
using Flow.Launcher.Infrastructure.UserSettings;
using Microsoft.Win32;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.Graphics.Dwm;
using Windows.Win32.UI.Input.KeyboardAndMouse;
using Windows.Win32.UI.WindowsAndMessaging;
using Point = System.Windows.Point;
namespace Flow.Launcher.Infrastructure
{
@ -9,93 +20,473 @@ namespace Flow.Launcher.Infrastructure
{
#region Blur Handling
/*
Found on https://github.com/riverar/sample-win10-aeroglass
*/
private enum AccentState
public static bool IsBackdropSupported()
{
ACCENT_DISABLED = 0,
ACCENT_ENABLE_GRADIENT = 1,
ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
ACCENT_ENABLE_BLURBEHIND = 3,
ACCENT_INVALID_STATE = 4
// Mica and Acrylic only supported Windows 11 22000+
return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
Environment.OSVersion.Version.Build >= 22000;
}
[StructLayout(LayoutKind.Sequential)]
private struct AccentPolicy
public static unsafe bool DWMSetCloakForWindow(Window window, bool cloak)
{
public AccentState AccentState;
public int AccentFlags;
public int GradientColor;
public int AnimationId;
var cloaked = cloak ? 1 : 0;
return PInvoke.DwmSetWindowAttribute(
GetWindowHandle(window),
DWMWINDOWATTRIBUTE.DWMWA_CLOAK,
&cloaked,
(uint)Marshal.SizeOf<int>()).Succeeded;
}
[StructLayout(LayoutKind.Sequential)]
private struct WindowCompositionAttributeData
public static unsafe bool DWMSetBackdropForWindow(Window window, BackdropTypes backdrop)
{
public WindowCompositionAttribute Attribute;
public IntPtr Data;
public int SizeOfData;
var backdropType = backdrop switch
{
BackdropTypes.Acrylic => DWM_SYSTEMBACKDROP_TYPE.DWMSBT_TRANSIENTWINDOW,
BackdropTypes.Mica => DWM_SYSTEMBACKDROP_TYPE.DWMSBT_MAINWINDOW,
BackdropTypes.MicaAlt => DWM_SYSTEMBACKDROP_TYPE.DWMSBT_TABBEDWINDOW,
_ => DWM_SYSTEMBACKDROP_TYPE.DWMSBT_AUTO
};
return PInvoke.DwmSetWindowAttribute(
GetWindowHandle(window),
DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE,
&backdropType,
(uint)Marshal.SizeOf<int>()).Succeeded;
}
private enum WindowCompositionAttribute
public static unsafe bool DWMSetDarkModeForWindow(Window window, bool useDarkMode)
{
WCA_ACCENT_POLICY = 19
}
var darkMode = useDarkMode ? 1 : 0;
[DllImport("user32.dll")]
private static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data);
return PInvoke.DwmSetWindowAttribute(
GetWindowHandle(window),
DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE,
&darkMode,
(uint)Marshal.SizeOf<int>()).Succeeded;
}
/// <summary>
/// Checks if the blur theme is enabled
///
/// </summary>
public static bool IsBlurTheme()
/// <param name="window"></param>
/// <param name="cornerType">DoNotRound, Round, RoundSmall, Default</param>
/// <returns></returns>
public static unsafe bool DWMSetCornerPreferenceForWindow(Window window, string cornerType)
{
if (Environment.OSVersion.Version >= new Version(6, 2))
var preference = cornerType switch
{
var resource = Application.Current.TryFindResource("ThemeBlurEnabled");
"DoNotRound" => DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_DONOTROUND,
"Round" => DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_ROUND,
"RoundSmall" => DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_ROUNDSMALL,
"Default" => DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_DEFAULT,
_ => throw new InvalidOperationException("Invalid corner type")
};
if (resource is bool b)
return b;
return PInvoke.DwmSetWindowAttribute(
GetWindowHandle(window),
DWMWINDOWATTRIBUTE.DWMWA_WINDOW_CORNER_PREFERENCE,
&preference,
(uint)Marshal.SizeOf<int>()).Succeeded;
}
#endregion
#region Wallpaper
public static unsafe string GetWallpaperPath()
{
var wallpaperPtr = stackalloc char[(int)PInvoke.MAX_PATH];
PInvoke.SystemParametersInfo(SYSTEM_PARAMETERS_INFO_ACTION.SPI_GETDESKWALLPAPER, PInvoke.MAX_PATH,
wallpaperPtr,
0);
var wallpaper = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(wallpaperPtr);
return wallpaper.ToString();
}
#endregion
#region Window Foreground
public static nint GetForegroundWindow()
{
return PInvoke.GetForegroundWindow().Value;
}
public static bool SetForegroundWindow(Window window)
{
return PInvoke.SetForegroundWindow(GetWindowHandle(window));
}
public static bool SetForegroundWindow(nint handle)
{
return PInvoke.SetForegroundWindow(new(handle));
}
#endregion
#region Task Switching
/// <summary>
/// Hide windows in the Alt+Tab window list
/// </summary>
/// <param name="window">To hide a window</param>
public static void HideFromAltTab(Window window)
{
var hwnd = GetWindowHandle(window);
var exStyle = GetWindowStyle(hwnd, WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE);
// Add TOOLWINDOW style, remove APPWINDOW style
var newExStyle = ((uint)exStyle | (uint)WINDOW_EX_STYLE.WS_EX_TOOLWINDOW) & ~(uint)WINDOW_EX_STYLE.WS_EX_APPWINDOW;
SetWindowStyle(hwnd, WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE, (int)newExStyle);
}
/// <summary>
/// Restore window display in the Alt+Tab window list.
/// </summary>
/// <param name="window">To restore the displayed window</param>
public static void ShowInAltTab(Window window)
{
var hwnd = GetWindowHandle(window);
var exStyle = GetWindowStyle(hwnd, WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE);
// Remove the TOOLWINDOW style and add the APPWINDOW style.
var newExStyle = ((uint)exStyle & ~(uint)WINDOW_EX_STYLE.WS_EX_TOOLWINDOW) | (uint)WINDOW_EX_STYLE.WS_EX_APPWINDOW;
SetWindowStyle(GetWindowHandle(window), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE, (int)newExStyle);
}
/// <summary>
/// Disable windows toolbar's control box
/// This will also disable system menu with Alt+Space hotkey
/// </summary>
public static void DisableControlBox(Window window)
{
var hwnd = GetWindowHandle(window);
var style = GetWindowStyle(hwnd, WINDOW_LONG_PTR_INDEX.GWL_STYLE);
style &= ~(int)WINDOW_STYLE.WS_SYSMENU;
SetWindowStyle(hwnd, WINDOW_LONG_PTR_INDEX.GWL_STYLE, style);
}
private static int GetWindowStyle(HWND hWnd, WINDOW_LONG_PTR_INDEX nIndex)
{
var style = PInvoke.GetWindowLong(hWnd, nIndex);
if (style == 0 && Marshal.GetLastPInvokeError() != 0)
{
throw new Win32Exception(Marshal.GetLastPInvokeError());
}
return style;
}
private static nint SetWindowStyle(HWND hWnd, WINDOW_LONG_PTR_INDEX nIndex, int dwNewLong)
{
PInvoke.SetLastError(WIN32_ERROR.NO_ERROR); // Clear any existing error
var result = PInvoke.SetWindowLongPtr(hWnd, nIndex, dwNewLong);
if (result == 0 && Marshal.GetLastPInvokeError() != 0)
{
throw new Win32Exception(Marshal.GetLastPInvokeError());
}
return result;
}
#endregion
#region Window Fullscreen
private const string WINDOW_CLASS_CONSOLE = "ConsoleWindowClass";
private const string WINDOW_CLASS_WINTAB = "Flip3D";
private const string WINDOW_CLASS_PROGMAN = "Progman";
private const string WINDOW_CLASS_WORKERW = "WorkerW";
private static HWND _hwnd_shell;
private static HWND HWND_SHELL =>
_hwnd_shell != HWND.Null ? _hwnd_shell : _hwnd_shell = PInvoke.GetShellWindow();
private static HWND _hwnd_desktop;
private static HWND HWND_DESKTOP =>
_hwnd_desktop != HWND.Null ? _hwnd_desktop : _hwnd_desktop = PInvoke.GetDesktopWindow();
public static unsafe bool IsForegroundWindowFullscreen()
{
// Get current active window
var hWnd = PInvoke.GetForegroundWindow();
if (hWnd.Equals(HWND.Null))
{
return false;
}
return false;
// If current active window is desktop or shell, exit early
if (hWnd.Equals(HWND_DESKTOP) || hWnd.Equals(HWND_SHELL))
{
return false;
}
string windowClass;
const int capacity = 256;
Span<char> buffer = stackalloc char[capacity];
int validLength;
fixed (char* pBuffer = buffer)
{
validLength = PInvoke.GetClassName(hWnd, pBuffer, capacity);
}
windowClass = buffer[..validLength].ToString();
// For Win+Tab (Flip3D)
if (windowClass == WINDOW_CLASS_WINTAB)
{
return false;
}
PInvoke.GetWindowRect(hWnd, out var appBounds);
// For console (ConsoleWindowClass), we have to check for negative dimensions
if (windowClass == WINDOW_CLASS_CONSOLE)
{
return appBounds.top < 0 && appBounds.bottom < 0;
}
// For desktop (Progman or WorkerW, depends on the system), we have to check
if (windowClass is WINDOW_CLASS_PROGMAN or WINDOW_CLASS_WORKERW)
{
var hWndDesktop = PInvoke.FindWindowEx(hWnd, HWND.Null, "SHELLDLL_DefView", null);
hWndDesktop = PInvoke.FindWindowEx(hWndDesktop, HWND.Null, "SysListView32", "FolderView");
if (hWndDesktop.Value != IntPtr.Zero)
{
return false;
}
}
var monitorInfo = MonitorInfo.GetNearestDisplayMonitor(hWnd);
return (appBounds.bottom - appBounds.top) == monitorInfo.RectMonitor.Height &&
(appBounds.right - appBounds.left) == monitorInfo.RectMonitor.Width;
}
#endregion
#region Pixel to DIP
/// <summary>
/// Transforms pixels to Device Independent Pixels used by WPF
/// </summary>
/// <param name="visual">current window, required to get presentation source</param>
/// <param name="unitX">horizontal position in pixels</param>
/// <param name="unitY">vertical position in pixels</param>
/// <returns>point containing device independent pixels</returns>
public static Point TransformPixelsToDIP(Visual visual, double unitX, double unitY)
{
Matrix matrix;
var source = PresentationSource.FromVisual(visual);
if (source is not null)
{
matrix = source.CompositionTarget.TransformFromDevice;
}
else
{
using var src = new HwndSource(new HwndSourceParameters());
matrix = src.CompositionTarget.TransformFromDevice;
}
return new Point((int)(matrix.M11 * unitX), (int)(matrix.M22 * unitY));
}
#endregion
#region WndProc
public const int WM_ENTERSIZEMOVE = (int)PInvoke.WM_ENTERSIZEMOVE;
public const int WM_EXITSIZEMOVE = (int)PInvoke.WM_EXITSIZEMOVE;
#endregion
#region Window Handle
internal static HWND GetWindowHandle(Window window, bool ensure = false)
{
var windowHelper = new WindowInteropHelper(window);
if (ensure)
{
windowHelper.EnsureHandle();
}
return new(windowHelper.Handle);
}
#endregion
#region Keyboard Layout
private const string UserProfileRegistryPath = @"Control Panel\International\User Profile";
// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/70feba9f-294e-491e-b6eb-56532684c37f
private const string EnglishLanguageTag = "en";
private static readonly string[] ImeLanguageTags =
{
"zh", // Chinese
"ja", // Japanese
"ko", // Korean
};
private const uint KeyboardLayoutLoWord = 0xFFFF;
// Store the previous keyboard layout
private static HKL _previousLayout;
/// <summary>
/// Switches the keyboard layout to English if available.
/// </summary>
/// <param name="backupPrevious">If true, the current keyboard layout will be stored for later restoration.</param>
/// <exception cref="Win32Exception">Thrown when there's an error getting the window thread process ID.</exception>
public static unsafe void SwitchToEnglishKeyboardLayout(bool backupPrevious)
{
// Find an installed English layout
var enHKL = FindEnglishKeyboardLayout();
// No installed English layout found
if (enHKL == HKL.Null) return;
// Get the current foreground window
var hwnd = PInvoke.GetForegroundWindow();
if (hwnd == HWND.Null) return;
// Get the current foreground window thread ID
var threadId = PInvoke.GetWindowThreadProcessId(hwnd);
if (threadId == 0) throw new Win32Exception(Marshal.GetLastWin32Error());
// If the current layout has an IME mode, disable it without switching to another layout.
// This is needed because for languages with IME mode, Flow Launcher just temporarily disables
// the IME mode instead of switching to another layout.
var currentLayout = PInvoke.GetKeyboardLayout(threadId);
var currentLangId = (uint)currentLayout.Value & KeyboardLayoutLoWord;
foreach (var langTag in ImeLanguageTags)
{
if (GetLanguageTag(currentLangId).StartsWith(langTag, StringComparison.OrdinalIgnoreCase))
{
return;
}
}
// Backup current keyboard layout
if (backupPrevious) _previousLayout = currentLayout;
// Switch to English layout
PInvoke.ActivateKeyboardLayout(enHKL, 0);
}
/// <summary>
/// Sets the blur for a window via SetWindowCompositionAttribute
/// Restores the previously backed-up keyboard layout.
/// If it wasn't backed up or has already been restored, this method does nothing.
/// </summary>
public static void SetBlurForWindow(Window w, bool blur)
public static void RestorePreviousKeyboardLayout()
{
SetWindowAccent(w, blur ? AccentState.ACCENT_ENABLE_BLURBEHIND : AccentState.ACCENT_DISABLED);
if (_previousLayout == HKL.Null) return;
var hwnd = PInvoke.GetForegroundWindow();
if (hwnd == HWND.Null) return;
PInvoke.PostMessage(
hwnd,
PInvoke.WM_INPUTLANGCHANGEREQUEST,
PInvoke.INPUTLANGCHANGE_FORWARD,
_previousLayout.Value
);
_previousLayout = HKL.Null;
}
private static void SetWindowAccent(Window w, AccentState state)
/// <summary>
/// Finds an installed English keyboard layout.
/// </summary>
/// <returns></returns>
/// <exception cref="Win32Exception"></exception>
private static unsafe HKL FindEnglishKeyboardLayout()
{
var windowHelper = new WindowInteropHelper(w);
// Get the number of keyboard layouts
int count = PInvoke.GetKeyboardLayoutList(0, null);
if (count <= 0) return HKL.Null;
windowHelper.EnsureHandle();
var accent = new AccentPolicy { AccentState = state };
var accentStructSize = Marshal.SizeOf(accent);
var accentPtr = Marshal.AllocHGlobal(accentStructSize);
Marshal.StructureToPtr(accent, accentPtr, false);
var data = new WindowCompositionAttributeData
// Get all keyboard layouts
var handles = new HKL[count];
fixed (HKL* h = handles)
{
Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY,
SizeOfData = accentStructSize,
Data = accentPtr
};
var result = PInvoke.GetKeyboardLayoutList(count, h);
if (result == 0) throw new Win32Exception(Marshal.GetLastWin32Error());
}
SetWindowCompositionAttribute(windowHelper.Handle, ref data);
// Look for any English keyboard layout
foreach (var hkl in handles)
{
// The lower word contains the language identifier
var langId = (uint)hkl.Value & KeyboardLayoutLoWord;
var langTag = GetLanguageTag(langId);
Marshal.FreeHGlobal(accentPtr);
// Check if it's an English layout
if (langTag.StartsWith(EnglishLanguageTag, StringComparison.OrdinalIgnoreCase))
{
return hkl;
}
}
return HKL.Null;
}
/// <summary>
/// Returns the
/// <see href="https://learn.microsoft.com/globalization/locale/standard-locale-names">
/// BCP 47 language tag
/// </see>
/// of the current input language.
/// </summary>
/// <remarks>
/// Edited from: https://github.com/dotnet/winforms
/// </remarks>
private static string GetLanguageTag(uint langId)
{
// We need to convert the language identifier to a language tag, because they are deprecated and may have a
// transient value.
// https://learn.microsoft.com/globalization/locale/other-locale-names#lcid
// https://learn.microsoft.com/windows/win32/winmsg/wm-inputlangchange#remarks
//
// It turns out that the LCIDToLocaleName API, which is used inside CultureInfo, may return incorrect
// language tags for transient language identifiers. For example, it returns "nqo-GN" and "jv-Java-ID"
// instead of the "nqo" and "jv-Java" (as seen in the Get-WinUserLanguageList PowerShell cmdlet).
//
// Try to extract proper language tag from registry as a workaround approved by a Windows team.
// https://github.com/dotnet/winforms/pull/8573#issuecomment-1542600949
//
// NOTE: this logic may break in future versions of Windows since it is not documented.
if (langId is PInvoke.LOCALE_TRANSIENT_KEYBOARD1
or PInvoke.LOCALE_TRANSIENT_KEYBOARD2
or PInvoke.LOCALE_TRANSIENT_KEYBOARD3
or PInvoke.LOCALE_TRANSIENT_KEYBOARD4)
{
using var key = Registry.CurrentUser.OpenSubKey(UserProfileRegistryPath);
if (key?.GetValue("Languages") is string[] languages)
{
foreach (string language in languages)
{
using var subKey = key.OpenSubKey(language);
if (subKey?.GetValue("TransientLangId") is int transientLangId
&& transientLangId == langId)
{
return language;
}
}
}
}
return CultureInfo.GetCultureInfo((int)langId).Name;
}
#endregion
}
}

View file

@ -66,7 +66,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Fody" Version="6.5.4">
<PackageReference Include="Fody" Version="6.5.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View file

@ -152,7 +152,6 @@ namespace Flow.Launcher.Plugin
/// <param name="callback"></param>
public void RemoveGlobalKeyboardCallback(Func<int, int, SpecialKeyState, bool> callback);
/// <summary>
/// Fuzzy Search the string with the given query. This is the core search mechanism Flow uses
/// </summary>
@ -191,14 +190,15 @@ namespace Flow.Launcher.Plugin
Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath, Action<double> reportProgress = null, CancellationToken token = default);
/// <summary>
/// Add ActionKeyword for specific plugin
/// Add ActionKeyword and update action keyword metadata for specific plugin
/// Before adding, please check if action keyword is already assigned by <see cref="ActionKeywordAssigned"/>
/// </summary>
/// <param name="pluginId">ID for plugin that needs to add action keyword</param>
/// <param name="newActionKeyword">The actionkeyword that is supposed to be added</param>
void AddActionKeyword(string pluginId, string newActionKeyword);
/// <summary>
/// Remove ActionKeyword for specific plugin
/// Remove ActionKeyword and update action keyword metadata for specific plugin
/// </summary>
/// <param name="pluginId">ID for plugin that needs to remove action keyword</param>
/// <param name="oldActionKeyword">The actionkeyword that is supposed to be removed</param>

View file

@ -34,6 +34,8 @@ namespace Flow.Launcher.Plugin
public List<string> ActionKeywords { get; set; }
public bool HideActionKeywordPanel { get; set; }
public string IcoPath { get; set;}
public override string ToString()

View file

@ -39,10 +39,9 @@ namespace Flow.Launcher.Plugin
public const string TermSeparator = " ";
/// <summary>
/// User can set multiple action keywords seperated by ';'
/// User can set multiple action keywords seperated by whitespace
/// </summary>
public const string ActionKeywordSeparator = ";";
public const string ActionKeywordSeparator = TermSeparator;
/// <summary>
/// Wildcard action keyword. Plugins using this value will be queried on every search.

View file

@ -3,6 +3,8 @@ using Flow.Launcher.Core.Resource;
using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;
using Flow.Launcher.Core;
using System.Linq;
using System.Collections.Generic;
namespace Flow.Launcher
{
@ -32,14 +34,37 @@ namespace Flow.Launcher
private void btnDone_OnClick(object sender, RoutedEventArgs _)
{
var oldActionKeyword = plugin.Metadata.ActionKeywords[0];
var newActionKeyword = tbAction.Text.Trim();
newActionKeyword = newActionKeyword.Length > 0 ? newActionKeyword : "*";
if (!PluginViewModel.IsActionKeywordRegistered(newActionKeyword))
var oldActionKeywords = plugin.Metadata.ActionKeywords;
var newActionKeywords = tbAction.Text.Split(Query.ActionKeywordSeparator).ToList();
newActionKeywords.RemoveAll(string.IsNullOrEmpty);
newActionKeywords = newActionKeywords.Distinct().ToList();
newActionKeywords = newActionKeywords.Count > 0 ? newActionKeywords : new() { Query.GlobalPluginWildcardSign };
var addedActionKeywords = newActionKeywords.Except(oldActionKeywords).ToList();
var removedActionKeywords = oldActionKeywords.Except(newActionKeywords).ToList();
if (!addedActionKeywords.Any(App.API.ActionKeywordAssigned))
{
pluginViewModel.ChangeActionKeyword(newActionKeyword, oldActionKeyword);
Close();
if (oldActionKeywords.Count != newActionKeywords.Count)
{
ReplaceActionKeyword(plugin.Metadata.ID, removedActionKeywords, addedActionKeywords);
return;
}
var sortedOldActionKeywords = oldActionKeywords.OrderBy(s => s).ToList();
var sortedNewActionKeywords = newActionKeywords.OrderBy(s => s).ToList();
if (sortedOldActionKeywords.SequenceEqual(sortedNewActionKeywords))
{
// User just changes the sequence of action keywords
var msg = translater.GetTranslation("newActionKeywordsSameAsOld");
MessageBoxEx.Show(msg);
}
else
{
ReplaceActionKeyword(plugin.Metadata.ID, removedActionKeywords, addedActionKeywords);
}
}
else
{
@ -47,5 +72,21 @@ namespace Flow.Launcher
App.API.ShowMsgBox(msg);
}
}
private void ReplaceActionKeyword(string id, IReadOnlyList<string> removedActionKeywords, IReadOnlyList<string> addedActionKeywords)
{
foreach (var actionKeyword in removedActionKeywords)
{
App.API.RemoveActionKeyword(id, actionKeyword);
}
foreach (var actionKeyword in addedActionKeywords)
{
App.API.AddActionKeyword(id, actionKeyword);
}
// Update action keywords text and close window
pluginViewModel.OnActionKeywordsChanged();
Close();
}
}
}

View file

@ -4,7 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="http://schemas.modernwpf.com/2019"
ShutdownMode="OnMainWindowClose"
Startup="OnStartupAsync">
Startup="OnStartup">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>

View file

@ -27,11 +27,26 @@ namespace Flow.Launcher
{
public partial class App : IDisposable, ISingleInstanceApp
{
#region Public Properties
public static IPublicAPI API { get; private set; }
private const string Unique = "Flow.Launcher_Unique_Application_Mutex";
#endregion
#region Private Fields
private static bool _disposed;
private MainWindow _mainWindow;
private readonly MainViewModel _mainVM;
private readonly Settings _settings;
// To prevent two disposals running at the same time.
private static readonly object _disposingLock = new();
#endregion
#region Constructor
public App()
{
// Initialize settings
@ -64,6 +79,7 @@ namespace Flow.Launcher
.AddSingleton<IPublicAPI, PublicAPIInstance>()
.AddSingleton<MainViewModel>()
.AddSingleton<Theme>()
.AddSingleton<WelcomeViewModel>()
).Build();
Ioc.Default.ConfigureServices(host.Services);
}
@ -78,37 +94,47 @@ namespace Flow.Launcher
{
API = Ioc.Default.GetRequiredService<IPublicAPI>();
_settings.Initialize();
_mainVM = Ioc.Default.GetRequiredService<MainViewModel>();
}
catch (Exception e)
{
ShowErrorMsgBoxAndFailFast("Cannot initialize api and settings, please open new issue in Flow.Launcher", e);
return;
}
// Local function
static void ShowErrorMsgBoxAndFailFast(string message, Exception e)
{
// Firstly show users the message
MessageBox.Show(e.ToString(), message, MessageBoxButton.OK, MessageBoxImage.Error);
// Flow cannot construct its App instance, so ensure Flow crashes w/ the exception info.
Environment.FailFast(message, e);
}
}
private static void ShowErrorMsgBoxAndFailFast(string message, Exception e)
{
// Firstly show users the message
MessageBox.Show(e.ToString(), message, MessageBoxButton.OK, MessageBoxImage.Error);
#endregion
// Flow cannot construct its App instance, so ensure Flow crashes w/ the exception info.
Environment.FailFast(message, e);
}
#region Main
[STAThread]
public static void Main()
{
if (SingleInstance<App>.InitializeAsFirstInstance(Unique))
if (SingleInstance<App>.InitializeAsFirstInstance())
{
using (var application = new App())
{
application.InitializeComponent();
application.Run();
}
using var application = new App();
application.InitializeComponent();
application.Run();
}
}
private async void OnStartupAsync(object sender, StartupEventArgs e)
#endregion
#region App Events
#pragma warning disable VSTHRD100 // Avoid async void methods
private async void OnStartup(object sender, StartupEventArgs e)
{
await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
{
@ -126,29 +152,33 @@ namespace Flow.Launcher
AbstractPluginEnvironment.PreStartPluginExecutablePathUpdate(_settings);
// TODO: Clean InternationalizationManager.Instance and InternationalizationManager.Instance.GetTranslation in future
InternationalizationManager.Instance.ChangeLanguage(_settings.Language);
PluginManager.LoadPlugins(_settings.PluginSettings);
// Register ResultsUpdated event after all plugins are loaded
Ioc.Default.GetRequiredService<MainViewModel>().RegisterResultsUpdatedEvent();
Http.Proxy = _settings.Proxy;
await PluginManager.InitializePluginsAsync();
// Change language after all plugins are initialized because we need to update plugin title based on their api
// TODO: Clean InternationalizationManager.Instance and InternationalizationManager.Instance.GetTranslation in future
await Ioc.Default.GetRequiredService<Internationalization>().InitializeLanguageAsync();
await imageLoadertask;
var mainVM = Ioc.Default.GetRequiredService<MainViewModel>();
var window = new MainWindow(_settings, mainVM);
_mainWindow = new MainWindow();
Log.Info($"|App.OnStartup|Dependencies Info:{ErrorReporting.DependenciesInfo()}");
Current.MainWindow = window;
Current.MainWindow = _mainWindow;
Current.MainWindow.Title = Constant.FlowLauncher;
HotKeyMapper.Initialize();
// main windows needs initialized before theme change because of blur settings
// TODO: Clean ThemeManager.Instance in future
ThemeManager.Instance.ChangeTheme(_settings.Theme);
Ioc.Default.GetRequiredService<Theme>().ChangeTheme();
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
@ -158,11 +188,12 @@ namespace Flow.Launcher
AutoUpdates();
API.SaveAppAllSettings();
Log.Info(
"|App.OnStartup|End Flow Launcher startup ---------------------------------------------------- ");
Log.Info("|App.OnStartup|End Flow Launcher startup ----------------------------------------------------");
});
}
#pragma warning restore VSTHRD100 // Avoid async void methods
private void AutoStartup()
{
// we try to enable auto-startup on first launch, or reenable if it was removed
@ -185,13 +216,11 @@ namespace Flow.Launcher
// but if it fails (permissions, etc) then don't keep retrying
// this also gives the user a visual indication in the Settings widget
_settings.StartFlowLauncherOnSystemStartup = false;
Notification.Show(InternationalizationManager.Instance.GetTranslation("setAutoStartFailed"),
e.Message);
API.ShowMsg(API.GetTranslation("setAutoStartFailed"), e.Message);
}
}
}
//[Conditional("RELEASE")]
private void AutoUpdates()
{
_ = Task.Run(async () =>
@ -209,11 +238,29 @@ namespace Flow.Launcher
});
}
#endregion
#region Register Events
private void RegisterExitEvents()
{
AppDomain.CurrentDomain.ProcessExit += (s, e) => Dispose();
Current.Exit += (s, e) => Dispose();
Current.SessionEnding += (s, e) => Dispose();
AppDomain.CurrentDomain.ProcessExit += (s, e) =>
{
Log.Info("|App.RegisterExitEvents|Process Exit");
Dispose();
};
Current.Exit += (s, e) =>
{
Log.Info("|App.RegisterExitEvents|Application Exit");
Dispose();
};
Current.SessionEnding += (s, e) =>
{
Log.Info("|App.RegisterExitEvents|Session Ending");
Dispose();
};
}
/// <summary>
@ -234,20 +281,60 @@ namespace Flow.Launcher
AppDomain.CurrentDomain.UnhandledException += ErrorReporting.UnhandledExceptionHandle;
}
public void Dispose()
#endregion
#region IDisposable
protected virtual void Dispose(bool disposing)
{
// if sessionending is called, exit proverbially be called when log off / shutdown
// but if sessionending is not called, exit won't be called when log off / shutdown
if (!_disposed)
// Prevent two disposes at the same time.
lock (_disposingLock)
{
API.SaveAppAllSettings();
if (!disposing)
{
return;
}
if (_disposed)
{
return;
}
_disposed = true;
}
Stopwatch.Normal("|App.Dispose|Dispose cost", () =>
{
Log.Info("|App.Dispose|Begin Flow Launcher dispose ----------------------------------------------------");
if (disposing)
{
// Dispose needs to be called on the main Windows thread,
// since some resources owned by the thread need to be disposed.
_mainWindow?.Dispatcher.Invoke(_mainWindow.Dispose);
_mainVM?.Dispose();
}
Log.Info("|App.Dispose|End Flow Launcher dispose ----------------------------------------------------");
});
}
public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
#endregion
#region ISingleInstanceApp
public void OnSecondAppStarted()
{
Ioc.Default.GetRequiredService<MainViewModel>().Show();
}
#endregion
}
}

View file

@ -58,9 +58,9 @@
</Button>
</Grid>
</StackPanel>
<StackPanel Margin="26,0,26,0">
<StackPanel Margin="26 0 26 0">
<TextBlock
Margin="0,0,0,12"
Margin="0 0 0 12"
FontSize="20"
FontWeight="SemiBold"
Text="{DynamicResource customeQueryHotkeyTitle}"
@ -72,10 +72,10 @@
TextWrapping="WrapWithOverflow" />
<Image
Width="478"
Margin="0,20,0,0"
Margin="0 20 0 0"
Source="/Images/illustration_01.png" />
<Grid Width="478" Margin="0,20,0,0">
<Grid Width="478" Margin="0 20 0 0">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
@ -99,12 +99,12 @@
Grid.Row="0"
Grid.Column="1"
Grid.ColumnSpan="2"
Margin="10,0,10,0"
Margin="10 0 10 0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
HorizontalContentAlignment="Left"
HotkeySettings="{Binding Settings}"
DefaultHotkey="" />
DefaultHotkey=""
Type="CustomQueryHotkey" />
<TextBlock
Grid.Row="1"
Grid.Column="0"
@ -124,8 +124,8 @@
x:Name="btnTestActionKeyword"
Grid.Row="1"
Grid.Column="2"
Margin="0,0,10,0"
Padding="10,5,10,5"
Margin="0 0 10 0"
Padding="10 5 10 5"
Click="BtnTestActionKeyword_OnClick"
Content="{DynamicResource preview}" />
</Grid>
@ -133,21 +133,21 @@
</StackPanel>
<Border
Grid.Row="1"
Margin="0,14,0,0"
Margin="0 14 0 0"
Background="{DynamicResource PopupButtonAreaBGColor}"
BorderBrush="{DynamicResource PopupButtonAreaBorderColor}"
BorderThickness="0,1,0,0">
BorderThickness="0 1 0 0">
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<Button
x:Name="btnCancel"
MinWidth="140"
Margin="10,0,5,0"
Margin="10 0 5 0"
Click="BtnCancel_OnClick"
Content="{DynamicResource cancel}" />
<Button
x:Name="btnAdd"
MinWidth="140"
Margin="5,0,10,0"
Margin="5 0 10 0"
Click="btnAdd_OnClick"
Style="{StaticResource AccentButtonStyle}">
<TextBlock x:Name="lblAdd" Text="{DynamicResource done}" />

View file

@ -85,7 +85,7 @@
<ItemGroup>
<PackageReference Include="ChefKeys" Version="0.1.2" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="Fody" Version="6.5.4">
<PackageReference Include="Fody" Version="6.5.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
@ -94,10 +94,6 @@
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.106">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<!-- ModernWpfUI v0.9.5 introduced WinRT changes that causes Notification platform unavailable error on some machines -->
<!-- https://github.com/Flow-Launcher/Flow.Launcher/issues/1772#issuecomment-1502440801 -->
<PackageReference Include="ModernWpfUI" Version="0.9.4" />

View file

@ -1,66 +0,0 @@
using System;
using System.Windows;
using System.Windows.Interop;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.Graphics.Dwm;
using Windows.Win32.UI.Controls;
namespace Flow.Launcher.Helper;
public class DwmDropShadow
{
/// <summary>
/// Drops a standard shadow to a WPF Window, even if the window isborderless. Only works with DWM (Vista and Seven).
/// This method is much more efficient than setting AllowsTransparency to true and using the DropShadow effect,
/// as AllowsTransparency involves a huge permormance issue (hardware acceleration is turned off for all the window).
/// </summary>
/// <param name="window">Window to which the shadow will be applied</param>
public static void DropShadowToWindow(Window window)
{
if (!DropShadow(window))
{
window.SourceInitialized += window_SourceInitialized;
}
}
private static void window_SourceInitialized(object sender, EventArgs e) //fixed typo
{
Window window = (Window)sender;
DropShadow(window);
window.SourceInitialized -= window_SourceInitialized;
}
/// <summary>
/// The actual method that makes API calls to drop the shadow to the window
/// </summary>
/// <param name="window">Window to which the shadow will be applied</param>
/// <returns>True if the method succeeded, false if not</returns>
private static unsafe bool DropShadow(Window window)
{
try
{
WindowInteropHelper helper = new WindowInteropHelper(window);
int val = 2;
var ret1 = PInvoke.DwmSetWindowAttribute(new (helper.Handle), DWMWINDOWATTRIBUTE.DWMWA_NCRENDERING_POLICY, &val, 4);
if (ret1 == HRESULT.S_OK)
{
var m = new MARGINS { cyBottomHeight = 0, cxLeftWidth = 0, cxRightWidth = 0, cyTopHeight = 0 };
var ret2 = PInvoke.DwmExtendFrameIntoClientArea(new(helper.Handle), &m);
return ret2 == HRESULT.S_OK;
}
return false;
}
catch (Exception)
{
// Probably dwmapi.dll not found (incompatible OS)
return false;
}
}
}

View file

@ -8,10 +8,10 @@ using System.Windows;
// modified to allow single instace restart
namespace Flow.Launcher.Helper
{
public interface ISingleInstanceApp
{
void OnSecondAppStarted();
}
public interface ISingleInstanceApp
{
void OnSecondAppStarted();
}
/// <summary>
/// This class checks to make sure that only one instance of
@ -24,9 +24,7 @@ namespace Flow.Launcher.Helper
/// running as Administrator, can activate it with command line arguments.
/// For most apps, this will not be much of an issue.
/// </remarks>
public static class SingleInstance<TApplication>
where TApplication: Application , ISingleInstanceApp
public static class SingleInstance<TApplication> where TApplication : Application, ISingleInstanceApp
{
#region Private Fields
@ -39,11 +37,12 @@ namespace Flow.Launcher.Helper
/// Suffix to the channel name.
/// </summary>
private const string ChannelNameSuffix = "SingeInstanceIPCChannel";
private const string InstanceMutexName = "Flow.Launcher_Unique_Application_Mutex";
/// <summary>
/// Application mutex.
/// </summary>
internal static Mutex singleInstanceMutex;
internal static Mutex SingleInstanceMutex { get; set; }
#endregion
@ -54,24 +53,23 @@ namespace Flow.Launcher.Helper
/// If not, activates the first instance.
/// </summary>
/// <returns>True if this is the first instance of the application.</returns>
public static bool InitializeAsFirstInstance( string uniqueName )
public static bool InitializeAsFirstInstance()
{
// Build unique application Id and the IPC channel name.
string applicationIdentifier = uniqueName + Environment.UserName;
string applicationIdentifier = InstanceMutexName + Environment.UserName;
string channelName = String.Concat(applicationIdentifier, Delimiter, ChannelNameSuffix);
string channelName = string.Concat(applicationIdentifier, Delimiter, ChannelNameSuffix);
// Create mutex based on unique application Id to check if this is the first instance of the application.
bool firstInstance;
singleInstanceMutex = new Mutex(true, applicationIdentifier, out firstInstance);
SingleInstanceMutex = new Mutex(true, applicationIdentifier, out var firstInstance);
if (firstInstance)
{
_ = CreateRemoteService(channelName);
_ = CreateRemoteServiceAsync(channelName);
return true;
}
else
{
_ = SignalFirstInstance(channelName);
_ = SignalFirstInstanceAsync(channelName);
return false;
}
}
@ -81,7 +79,7 @@ namespace Flow.Launcher.Helper
/// </summary>
public static void Cleanup()
{
singleInstanceMutex?.ReleaseMutex();
SingleInstanceMutex?.ReleaseMutex();
}
#endregion
@ -93,22 +91,19 @@ namespace Flow.Launcher.Helper
/// Once receives signal from client, will activate first instance.
/// </summary>
/// <param name="channelName">Application's IPC channel name.</param>
private static async Task CreateRemoteService(string channelName)
private static async Task CreateRemoteServiceAsync(string channelName)
{
using (NamedPipeServerStream pipeServer = new NamedPipeServerStream(channelName, PipeDirection.In))
using NamedPipeServerStream pipeServer = new NamedPipeServerStream(channelName, PipeDirection.In);
while (true)
{
while(true)
{
// Wait for connection to the pipe
await pipeServer.WaitForConnectionAsync();
if (Application.Current != null)
{
// Do an asynchronous call to ActivateFirstInstance function
Application.Current.Dispatcher.Invoke(ActivateFirstInstance);
}
// Disconect client
pipeServer.Disconnect();
}
// Wait for connection to the pipe
await pipeServer.WaitForConnectionAsync();
// Do an asynchronous call to ActivateFirstInstance function
Application.Current?.Dispatcher.Invoke(ActivateFirstInstance);
// Disconect client
pipeServer.Disconnect();
}
}
@ -119,25 +114,13 @@ namespace Flow.Launcher.Helper
/// <param name="args">
/// Command line arguments for the second instance, passed to the first instance to take appropriate action.
/// </param>
private static async Task SignalFirstInstance(string channelName)
private static async Task SignalFirstInstanceAsync(string channelName)
{
// Create a client pipe connected to server
using (NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", channelName, PipeDirection.Out))
{
// Connect to the available pipe
await pipeClient.ConnectAsync(0);
}
}
using NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", channelName, PipeDirection.Out);
/// <summary>
/// Callback for activating first instance of the application.
/// </summary>
/// <param name="arg">Callback argument.</param>
/// <returns>Always null.</returns>
private static object ActivateFirstInstanceCallback(object o)
{
ActivateFirstInstance();
return null;
// Connect to the available pipe
await pipeClient.ConnectAsync(0);
}
/// <summary>

View file

@ -2,19 +2,16 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Flow.Launcher.Infrastructure;
using Microsoft.Win32;
using Windows.Win32;
using Windows.Win32.UI.WindowsAndMessaging;
namespace Flow.Launcher.Helper;
public static class WallpaperPathRetrieval
{
private static readonly int MAX_PATH = 260;
private static readonly int MAX_CACHE_SIZE = 3;
private static readonly Dictionary<(string, DateTime), ImageBrush> wallpaperCache = new();
@ -29,7 +26,7 @@ public static class WallpaperPathRetrieval
try
{
var wallpaperPath = GetWallpaperPath();
var wallpaperPath = Win32Helper.GetWallpaperPath();
if (wallpaperPath is not null && File.Exists(wallpaperPath))
{
// Since the wallpaper file name can be the same (TranscodedWallpaper),
@ -78,17 +75,6 @@ public static class WallpaperPathRetrieval
}
}
private static unsafe string GetWallpaperPath()
{
var wallpaperPtr = stackalloc char[MAX_PATH];
PInvoke.SystemParametersInfo(SYSTEM_PARAMETERS_INFO_ACTION.SPI_GETDESKWALLPAPER, (uint)MAX_PATH,
wallpaperPtr,
0);
var wallpaper = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(wallpaperPtr);
return wallpaper.ToString();
}
private static Color GetWallpaperColor()
{
RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Colors", true);

View file

@ -1,211 +0,0 @@
using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Interop;
using System.Windows.Media;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.UI.WindowsAndMessaging;
using Point = System.Windows.Point;
namespace Flow.Launcher.Helper;
public class WindowsInteropHelper
{
private static HWND _hwnd_shell;
private static HWND _hwnd_desktop;
//Accessors for shell and desktop handlers
//Will set the variables once and then will return them
private static HWND HWND_SHELL
{
get
{
return _hwnd_shell != HWND.Null ? _hwnd_shell : _hwnd_shell = PInvoke.GetShellWindow();
}
}
private static HWND HWND_DESKTOP
{
get
{
return _hwnd_desktop != HWND.Null ? _hwnd_desktop : _hwnd_desktop = PInvoke.GetDesktopWindow();
}
}
const string WINDOW_CLASS_CONSOLE = "ConsoleWindowClass";
const string WINDOW_CLASS_WINTAB = "Flip3D";
const string WINDOW_CLASS_PROGMAN = "Progman";
const string WINDOW_CLASS_WORKERW = "WorkerW";
public unsafe static bool IsWindowFullscreen()
{
//get current active window
var hWnd = PInvoke.GetForegroundWindow();
if (hWnd.Equals(HWND.Null))
{
return false;
}
//if current active window is desktop or shell, exit early
if (hWnd.Equals(HWND_DESKTOP) || hWnd.Equals(HWND_SHELL))
{
return false;
}
string windowClass;
const int capacity = 256;
Span<char> buffer = stackalloc char[capacity];
int validLength;
fixed (char* pBuffer = buffer)
{
validLength = PInvoke.GetClassName(hWnd, pBuffer, capacity);
}
windowClass = buffer[..validLength].ToString();
//for Win+Tab (Flip3D)
if (windowClass == WINDOW_CLASS_WINTAB)
{
return false;
}
PInvoke.GetWindowRect(hWnd, out var appBounds);
//for console (ConsoleWindowClass), we have to check for negative dimensions
if (windowClass == WINDOW_CLASS_CONSOLE)
{
return appBounds.top < 0 && appBounds.bottom < 0;
}
//for desktop (Progman or WorkerW, depends on the system), we have to check
if (windowClass is WINDOW_CLASS_PROGMAN or WINDOW_CLASS_WORKERW)
{
var hWndDesktop = PInvoke.FindWindowEx(hWnd, HWND.Null, "SHELLDLL_DefView", null);
hWndDesktop = PInvoke.FindWindowEx(hWndDesktop, HWND.Null, "SysListView32", "FolderView");
if (hWndDesktop.Value != (IntPtr.Zero))
{
return false;
}
}
Rectangle screenBounds = Screen.FromHandle(hWnd).Bounds;
return (appBounds.bottom - appBounds.top) == screenBounds.Height &&
(appBounds.right - appBounds.left) == screenBounds.Width;
}
/// <summary>
/// disable windows toolbar's control box
/// this will also disable system menu with Alt+Space hotkey
/// </summary>
public static void DisableControlBox(Window win)
{
var hwnd = new HWND(new WindowInteropHelper(win).Handle);
var style = PInvoke.GetWindowLong(hwnd, WINDOW_LONG_PTR_INDEX.GWL_STYLE);
if (style == 0)
{
throw new Win32Exception(Marshal.GetLastPInvokeError());
}
style &= ~(int)WINDOW_STYLE.WS_SYSMENU;
var previousStyle = PInvoke.SetWindowLong(hwnd, WINDOW_LONG_PTR_INDEX.GWL_STYLE,
style);
if (previousStyle == 0)
{
throw new Win32Exception(Marshal.GetLastPInvokeError());
}
}
/// <summary>
/// Transforms pixels to Device Independent Pixels used by WPF
/// </summary>
/// <param name="visual">current window, required to get presentation source</param>
/// <param name="unitX">horizontal position in pixels</param>
/// <param name="unitY">vertical position in pixels</param>
/// <returns>point containing device independent pixels</returns>
public static Point TransformPixelsToDIP(Visual visual, double unitX, double unitY)
{
Matrix matrix;
var source = PresentationSource.FromVisual(visual);
if (source is not null)
{
matrix = source.CompositionTarget.TransformFromDevice;
}
else
{
using var src = new HwndSource(new HwndSourceParameters());
matrix = src.CompositionTarget.TransformFromDevice;
}
return new Point((int)(matrix.M11 * unitX), (int)(matrix.M22 * unitY));
}
#region Alt Tab
private static int SetWindowLong(HWND hWnd, WINDOW_LONG_PTR_INDEX nIndex, int dwNewLong)
{
PInvoke.SetLastError(WIN32_ERROR.NO_ERROR); // Clear any existing error
var result = PInvoke.SetWindowLong(hWnd, nIndex, dwNewLong);
if (result == 0 && Marshal.GetLastPInvokeError() != 0)
{
throw new Win32Exception(Marshal.GetLastPInvokeError());
}
return result;
}
/// <summary>
/// Hide windows in the Alt+Tab window list
/// </summary>
/// <param name="window">To hide a window</param>
public static void HideFromAltTab(Window window)
{
var exStyle = GetCurrentWindowStyle(window);
// Add TOOLWINDOW style, remove APPWINDOW style
var newExStyle = ((uint)exStyle | (uint)WINDOW_EX_STYLE.WS_EX_TOOLWINDOW) & ~(uint)WINDOW_EX_STYLE.WS_EX_APPWINDOW;
SetWindowLong(new(new WindowInteropHelper(window).Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE, (int)newExStyle);
}
/// <summary>
/// Restore window display in the Alt+Tab window list.
/// </summary>
/// <param name="window">To restore the displayed window</param>
public static void ShowInAltTab(Window window)
{
var exStyle = GetCurrentWindowStyle(window);
// Remove the TOOLWINDOW style and add the APPWINDOW style.
var newExStyle = ((uint)exStyle & ~(uint)WINDOW_EX_STYLE.WS_EX_TOOLWINDOW) | (uint)WINDOW_EX_STYLE.WS_EX_APPWINDOW;
SetWindowLong(new(new WindowInteropHelper(window).Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE, (int)newExStyle);
}
/// <summary>
/// To obtain the current overridden style of a window.
/// </summary>
/// <param name="window">To obtain the style dialog window</param>
/// <returns>current extension style value</returns>
private static int GetCurrentWindowStyle(Window window)
{
var style = PInvoke.GetWindowLong(new(new WindowInteropHelper(window).Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE);
if (style == 0 && Marshal.GetLastPInvokeError() != 0)
{
throw new Win32Exception(Marshal.GetLastPInvokeError());
}
return style;
}
#endregion
}

View file

@ -4,25 +4,16 @@ using System.Collections.ObjectModel;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher
{
public partial class HotkeyControl
{
public IHotkeySettings HotkeySettings {
get { return (IHotkeySettings)GetValue(HotkeySettingsProperty); }
set { SetValue(HotkeySettingsProperty, value); }
}
public static readonly DependencyProperty HotkeySettingsProperty = DependencyProperty.Register(
nameof(HotkeySettings),
typeof(IHotkeySettings),
typeof(HotkeyControl),
new PropertyMetadata()
);
public string WindowTitle {
get { return (string)GetValue(WindowTitleProperty); }
set { SetValue(WindowTitleProperty, value); }
@ -71,8 +62,7 @@ namespace Flow.Launcher
return;
}
hotkeyControl.SetKeysToDisplay(new HotkeyModel(hotkeyControl.Hotkey));
hotkeyControl.CurrentHotkey = new HotkeyModel(hotkeyControl.Hotkey);
hotkeyControl.RefreshHotkeyInterface(hotkeyControl.Hotkey);
}
@ -90,17 +80,132 @@ namespace Flow.Launcher
}
public static readonly DependencyProperty HotkeyProperty = DependencyProperty.Register(
nameof(Hotkey),
typeof(string),
public static readonly DependencyProperty TypeProperty = DependencyProperty.Register(
nameof(Type),
typeof(HotkeyType),
typeof(HotkeyControl),
new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnHotkeyChanged)
new FrameworkPropertyMetadata(HotkeyType.None, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnHotkeyChanged)
);
public HotkeyType Type
{
get { return (HotkeyType)GetValue(TypeProperty); }
set { SetValue(TypeProperty, value); }
}
public enum HotkeyType
{
None,
// Custom query hotkeys
CustomQueryHotkey,
// Settings hotkeys
Hotkey,
PreviewHotkey,
OpenContextMenuHotkey,
SettingWindowHotkey,
CycleHistoryUpHotkey,
CycleHistoryDownHotkey,
SelectPrevPageHotkey,
SelectNextPageHotkey,
AutoCompleteHotkey,
AutoCompleteHotkey2,
SelectPrevItemHotkey,
SelectPrevItemHotkey2,
SelectNextItemHotkey,
SelectNextItemHotkey2
}
// We can initialize settings in static field because it has been constructed in App constuctor
// and it will not construct settings instances twice
private static readonly Settings _settings = Ioc.Default.GetRequiredService<Settings>();
private string hotkey = string.Empty;
public string Hotkey
{
get { return (string)GetValue(HotkeyProperty); }
set { SetValue(HotkeyProperty, value); }
get
{
return Type switch
{
// Custom query hotkeys
HotkeyType.CustomQueryHotkey => hotkey,
// Settings hotkeys
HotkeyType.Hotkey => _settings.Hotkey,
HotkeyType.PreviewHotkey => _settings.PreviewHotkey,
HotkeyType.OpenContextMenuHotkey => _settings.OpenContextMenuHotkey,
HotkeyType.SettingWindowHotkey => _settings.SettingWindowHotkey,
HotkeyType.CycleHistoryUpHotkey => _settings.CycleHistoryUpHotkey,
HotkeyType.CycleHistoryDownHotkey => _settings.CycleHistoryDownHotkey,
HotkeyType.SelectPrevPageHotkey => _settings.SelectPrevPageHotkey,
HotkeyType.SelectNextPageHotkey => _settings.SelectNextPageHotkey,
HotkeyType.AutoCompleteHotkey => _settings.AutoCompleteHotkey,
HotkeyType.AutoCompleteHotkey2 => _settings.AutoCompleteHotkey2,
HotkeyType.SelectPrevItemHotkey => _settings.SelectPrevItemHotkey,
HotkeyType.SelectPrevItemHotkey2 => _settings.SelectPrevItemHotkey2,
HotkeyType.SelectNextItemHotkey => _settings.SelectNextItemHotkey,
HotkeyType.SelectNextItemHotkey2 => _settings.SelectNextItemHotkey2,
_ => throw new System.NotImplementedException("Hotkey type not set")
};
}
set
{
switch (Type)
{
// Custom query hotkeys
case HotkeyType.CustomQueryHotkey:
// We just need to store it in a local field
// because we will save to settings in other place
hotkey = value;
break;
// Settings hotkeys
case HotkeyType.Hotkey:
_settings.Hotkey = value;
break;
case HotkeyType.PreviewHotkey:
_settings.PreviewHotkey = value;
break;
case HotkeyType.OpenContextMenuHotkey:
_settings.OpenContextMenuHotkey = value;
break;
case HotkeyType.SettingWindowHotkey:
_settings.SettingWindowHotkey = value;
break;
case HotkeyType.CycleHistoryUpHotkey:
_settings.CycleHistoryUpHotkey = value;
break;
case HotkeyType.CycleHistoryDownHotkey:
_settings.CycleHistoryDownHotkey = value;
break;
case HotkeyType.SelectPrevPageHotkey:
_settings.SelectPrevPageHotkey = value;
break;
case HotkeyType.SelectNextPageHotkey:
_settings.SelectNextPageHotkey = value;
break;
case HotkeyType.AutoCompleteHotkey:
_settings.AutoCompleteHotkey = value;
break;
case HotkeyType.AutoCompleteHotkey2:
_settings.AutoCompleteHotkey2 = value;
break;
case HotkeyType.SelectPrevItemHotkey:
_settings.SelectPrevItemHotkey = value;
break;
case HotkeyType.SelectNextItemHotkey:
_settings.SelectNextItemHotkey = value;
break;
case HotkeyType.SelectPrevItemHotkey2:
_settings.SelectPrevItemHotkey2 = value;
break;
case HotkeyType.SelectNextItemHotkey2:
_settings.SelectNextItemHotkey2 = value;
break;
default:
throw new System.NotImplementedException("Hotkey type not set");
}
// After setting the hotkey, we need to refresh the interface
RefreshHotkeyInterface(Hotkey);
}
}
public HotkeyControl()
@ -108,7 +213,15 @@ namespace Flow.Launcher
InitializeComponent();
HotkeyList.ItemsSource = KeysToDisplay;
SetKeysToDisplay(CurrentHotkey);
// We should not call RefreshHotkeyInterface here because DependencyProperty is not set yet
// And it will be called in OnHotkeyChanged event or Hotkey setter later
}
private void RefreshHotkeyInterface(string hotkey)
{
SetKeysToDisplay(new HotkeyModel(hotkey));
CurrentHotkey = new HotkeyModel(hotkey);
}
private static bool CheckHotkeyAvailability(HotkeyModel hotkey, bool validateKeyGesture) =>
@ -133,7 +246,7 @@ namespace Flow.Launcher
HotKeyMapper.RemoveHotkey(Hotkey);
}
var dialog = new HotkeyControlDialog(Hotkey, DefaultHotkey, HotkeySettings, WindowTitle);
var dialog = new HotkeyControlDialog(Hotkey, DefaultHotkey, WindowTitle);
await dialog.ShowAsync();
switch (dialog.ResultType)
{

View file

@ -4,9 +4,11 @@ using System.Linq;
using System.Windows;
using System.Windows.Input;
using ChefKeys;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using ModernWpf.Controls;
@ -16,7 +18,7 @@ namespace Flow.Launcher;
public partial class HotkeyControlDialog : ContentDialog
{
private IHotkeySettings _hotkeySettings;
private static readonly IHotkeySettings _hotkeySettings = Ioc.Default.GetRequiredService<Settings>();
private Action? _overwriteOtherHotkey;
private string DefaultHotkey { get; }
public string WindowTitle { get; }
@ -36,7 +38,7 @@ public partial class HotkeyControlDialog : ContentDialog
private static bool isOpenFlowHotkey;
public HotkeyControlDialog(string hotkey, string defaultHotkey, IHotkeySettings hotkeySettings, string windowTitle = "")
public HotkeyControlDialog(string hotkey, string defaultHotkey, string windowTitle = "")
{
WindowTitle = windowTitle switch
{
@ -45,7 +47,6 @@ public partial class HotkeyControlDialog : ContentDialog
};
DefaultHotkey = defaultHotkey;
CurrentHotkey = new HotkeyModel(hotkey);
_hotkeySettings = hotkeySettings;
SetKeysToDisplay(CurrentHotkey);
InitializeComponent();

View file

@ -13,6 +13,7 @@
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">فشل في تسجيل مفتاح التشغيل السريع &quot;{0}&quot;. قد يكون المفتاح مستخدمًا من قبل برنامج آخر. قم بتغيير المفتاح، أو قم بإغلاق البرنامج الآخر.</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="MessageBoxTitle">Flow Launcher</system:String>
<system:String x:Key="couldnotStartCmd">تعذر بدء {0}</system:String>
<system:String x:Key="invalidFlowLauncherPluginFileFormat">تنسيق ملف إضافة Flow Launcher غير صالح</system:String>
@ -44,6 +45,8 @@
<system:String x:Key="portableMode">وضع المحمول</system:String>
<system:String x:Key="portableModeToolTIp">تخزين جميع الإعدادات وبيانات المستخدم في مجلد واحد (مفيد عند استخدام الأقراص القابلة للإزالة أو الخدمات السحابية).</system:String>
<system:String x:Key="startFlowLauncherOnSystemStartup">تشغيل Flow Launcher عند بدء تشغيل النظام</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="setAutoStartFailed">خطأ في إعداد التشغيل عند بدء التشغيل</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">إخفاء Flow Launcher عند فقدان التركيز</system:String>
<system:String x:Key="dontPromptUpdateMsg">عدم عرض إشعارات الإصدار الجديد</system:String>
@ -126,7 +129,8 @@
<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>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">متجر الإضافات</system:String>
@ -143,8 +147,6 @@
<system:String x:Key="LabelNewToolTip">تم تحديث هذه الإضافة في آخر 7 أيام</system:String>
<system:String x:Key="LabelUpdateToolTip">يتوفر تحديث جديد</system:String>
<!-- Setting Theme -->
<system:String x:Key="theme">السمة</system:String>
<system:String x:Key="appearance">المظهر</system:String>
@ -194,7 +196,6 @@
<system:String x:Key="TypeIsDarkToolTip">هذه السمة تدعم الوضعين (فاتح/داكن).</system:String>
<system:String x:Key="TypeHasBlurToolTip">هذه السمة تدعم الخلفية الضبابية الشفافة.</system:String>
<!-- Setting Hotkey -->
<system:String x:Key="hotkey">مفتاح الاختصار</system:String>
<system:String x:Key="hotkeys">مفاتيح الاختصار</system:String>
@ -297,6 +298,9 @@
<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>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">اختر مدير الملفات</system:String>
@ -367,6 +371,7 @@
<system:String x:Key="commonOK">حسناً</system:String>
<system:String x:Key="commonYes">نعم</system:String>
<system:String x:Key="commonNo">لا</system:String>
<system:String x:Key="commonBackground">الخلفية</system:String>
<!-- Crash Reporter -->
<system:String x:Key="reportWindow_version">الإصدار</system:String>
@ -383,6 +388,9 @@
<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>
<!-- General Notice -->
<system:String x:Key="pleaseWait">يرجى الانتظار...</system:String>

View file

@ -13,6 +13,7 @@
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">Nepodařilo se zaregistrovat hotkey &quot;{0}&quot;. Klávesová zkratka může být používána jiným programem. Změňte na jinou klávesu nebo ukončíte jiný program.</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="MessageBoxTitle">Flow Launcher</system:String>
<system:String x:Key="couldnotStartCmd">Nepodařilo se spustit {0}</system:String>
<system:String x:Key="invalidFlowLauncherPluginFileFormat">Neplatný typ souboru pluginu aplikace Flow Launcher</system:String>
@ -44,6 +45,8 @@
<system:String x:Key="portableMode">Přenosný režim</system:String>
<system:String x:Key="portableModeToolTIp">Ukládat všechna nastavení a uživatelská data v jedné složce (Užitečné při užití s přenosnými zařízeními).</system:String>
<system:String x:Key="startFlowLauncherOnSystemStartup">Spustit Flow Launcher při spuštění systému</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="setAutoStartFailed">Při nastavování spouštění došlo k chybě</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">Skrýt Flow Launcher při vykliknutí</system:String>
<system:String x:Key="dontPromptUpdateMsg">Nezobrazovat oznámení o nové verzi</system:String>
@ -126,7 +129,8 @@
<system:String x:Key="plugin_query_version">Verze</system:String>
<system:String x:Key="plugin_query_web">Webová stránka</system:String>
<system:String x:Key="plugin_uninstall">Odinstalovat</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>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">Obchod s pluginy</system:String>
@ -143,8 +147,6 @@
<system:String x:Key="LabelNewToolTip">Tento plugin byl aktualizován během posledních 7 dní</system:String>
<system:String x:Key="LabelUpdateToolTip">Nová aktualizace je k dispozici</system:String>
<!-- Setting Theme -->
<system:String x:Key="theme">Motiv</system:String>
<system:String x:Key="appearance">Vzhled</system:String>
@ -194,7 +196,6 @@
<system:String x:Key="TypeIsDarkToolTip">This theme supports two(light/dark) modes.</system:String>
<system:String x:Key="TypeHasBlurToolTip">This theme supports Blur Transparent Background.</system:String>
<!-- Setting Hotkey -->
<system:String x:Key="hotkey">Klávesová zkratka</system:String>
<system:String x:Key="hotkeys">Klávesové zkratky</system:String>
@ -297,6 +298,9 @@
<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="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">Vybrat správce souborů</system:String>
@ -367,6 +371,7 @@ Pokud před zkratku při zadávání přidáte znak &quot;@&quot;, bude odpovíd
<system:String x:Key="commonOK">Dobře</system:String>
<system:String x:Key="commonYes">Yes</system:String>
<system:String x:Key="commonNo">No</system:String>
<system:String x:Key="commonBackground">Pozadí</system:String>
<!-- Crash Reporter -->
<system:String x:Key="reportWindow_version">Verze</system:String>
@ -383,6 +388,9 @@ Pokud před zkratku při zadávání přidáte znak &quot;@&quot;, bude odpovíd
<system:String x:Key="reportWindow_report_succeed">Hlášení bylo úspěšně odesláno</system:String>
<system:String x:Key="reportWindow_report_failed">Nepodařilo se odeslat hlášení</system:String>
<system:String x:Key="reportWindow_flowlauncher_got_an_error">Flow Launcher zaznamenal chybu</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>
<!-- General Notice -->
<system:String x:Key="pleaseWait">Počkejte prosím...</system:String>

View file

@ -13,6 +13,7 @@
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">Failed to register hotkey &quot;{0}&quot;. The hotkey may be in use by another program. Change to a different hotkey, or exit another program.</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="MessageBoxTitle">Flow Launcher</system:String>
<system:String x:Key="couldnotStartCmd">Kunne ikke starte {0}</system:String>
<system:String x:Key="invalidFlowLauncherPluginFileFormat">Ugyldigt Flow Launcher plugin filformat</system:String>
@ -44,6 +45,8 @@
<system:String x:Key="portableMode">Portable Mode</system:String>
<system:String x:Key="portableModeToolTIp">Store all settings and user data in one folder (Useful when used with removable drives or cloud services).</system:String>
<system:String x:Key="startFlowLauncherOnSystemStartup">Start Flow Launcher ved system start</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="setAutoStartFailed">Error setting launch on startup</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">Skjul Flow Launcher ved mistet fokus</system:String>
<system:String x:Key="dontPromptUpdateMsg">Vis ikke notifikationer om nye versioner</system:String>
@ -126,7 +129,8 @@
<system:String x:Key="plugin_query_version">Version</system:String>
<system:String x:Key="plugin_query_web">Website</system:String>
<system:String x:Key="plugin_uninstall">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>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">Plugin Store</system:String>
@ -143,8 +147,6 @@
<system:String x:Key="LabelNewToolTip">This plugin has been updated within the last 7 days</system:String>
<system:String x:Key="LabelUpdateToolTip">New Update is Available</system:String>
<!-- Setting Theme -->
<system:String x:Key="theme">Tema</system:String>
<system:String x:Key="appearance">Appearance</system:String>
@ -194,7 +196,6 @@
<system:String x:Key="TypeIsDarkToolTip">This theme supports two(light/dark) modes.</system:String>
<system:String x:Key="TypeHasBlurToolTip">This theme supports Blur Transparent Background.</system:String>
<!-- Setting Hotkey -->
<system:String x:Key="hotkey">Genvejstast</system:String>
<system:String x:Key="hotkeys">Genvejstast</system:String>
@ -297,6 +298,9 @@
<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="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">Select File Manager</system:String>
@ -367,6 +371,7 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
<system:String x:Key="commonOK">OK</system:String>
<system:String x:Key="commonYes">Yes</system:String>
<system:String x:Key="commonNo">No</system:String>
<system:String x:Key="commonBackground">Background</system:String>
<!-- Crash Reporter -->
<system:String x:Key="reportWindow_version">Version</system:String>
@ -383,6 +388,9 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
<system:String x:Key="reportWindow_report_succeed">Rapport sendt korrekt</system:String>
<system:String x:Key="reportWindow_report_failed">Kunne ikke sende rapport</system:String>
<system:String x:Key="reportWindow_flowlauncher_got_an_error">Flow Launcher fik en fejl</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>
<!-- General Notice -->
<system:String x:Key="pleaseWait">Please wait...</system:String>

View file

@ -13,6 +13,7 @@
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">Hotkey &quot;{0}&quot; konnte nicht registriert werden. Der Hotkey ist möglicherweise von einem anderen Programm in Verwendung. Wechseln Sie zu einem anderen Hotkey oder beenden Sie das andere Programm.</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="MessageBoxTitle">Flow Launcher</system:String>
<system:String x:Key="couldnotStartCmd">Konnte nicht gestartet werden {0}</system:String>
<system:String x:Key="invalidFlowLauncherPluginFileFormat">Flow Launcher Plug-in-Dateiformat ungültig</system:String>
@ -44,6 +45,8 @@
<system:String x:Key="portableMode">Portabler Modus</system:String>
<system:String x:Key="portableModeToolTIp">Speichern Sie alle Einstellungen und Benutzerdaten in einem Ordner (nützlich bei Verwendung von Wechsellaufwerken oder Cloud-Diensten).</system:String>
<system:String x:Key="startFlowLauncherOnSystemStartup">Flow Launcher bei Systemstart starten</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="setAutoStartFailed">Fehler bei Einstellungsstart bei Start</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">Flow Launcher ausblenden, wenn Fokus verloren geht</system:String>
<system:String x:Key="dontPromptUpdateMsg">Versionsbenachrichtigungen nicht zeigen</system:String>
@ -126,7 +129,8 @@
<system:String x:Key="plugin_query_version">Version</system:String>
<system:String x:Key="plugin_query_web">Website</system:String>
<system:String x:Key="plugin_uninstall">Deinstallieren</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>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">Plug-in-Store</system:String>
@ -143,8 +147,6 @@
<system:String x:Key="LabelNewToolTip">Dieses Plug-in ist innerhalb der letzten 7 Tage aktualisiert worden</system:String>
<system:String x:Key="LabelUpdateToolTip">Neues Update ist verfügbar</system:String>
<!-- Setting Theme -->
<system:String x:Key="theme">Theme</system:String>
<system:String x:Key="appearance">Erscheinungsbild</system:String>
@ -194,7 +196,6 @@
<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>
<!-- Setting Hotkey -->
<system:String x:Key="hotkey">Hotkey</system:String>
<system:String x:Key="hotkeys">Hotkeys</system:String>
@ -297,6 +298,9 @@
<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="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">Dateimanager auswählen</system:String>
@ -367,6 +371,7 @@ Wenn Sie bei der Eingabe eines Shortcuts ein '@'-Präfix hinzufügen, stimmt die
<system:String x:Key="commonOK">OK</system:String>
<system:String x:Key="commonYes">Ja</system:String>
<system:String x:Key="commonNo">Nein</system:String>
<system:String x:Key="commonBackground">Hintergrund</system:String>
<!-- Crash Reporter -->
<system:String x:Key="reportWindow_version">Version</system:String>
@ -383,6 +388,9 @@ Wenn Sie bei der Eingabe eines Shortcuts ein '@'-Präfix hinzufügen, stimmt die
<system:String x:Key="reportWindow_report_succeed">Bericht erfolgreich gesendet</system:String>
<system:String x:Key="reportWindow_report_failed">Bericht konnte nicht gesendet werden</system:String>
<system:String x:Key="reportWindow_flowlauncher_got_an_error">Flow Launcher hat einen Fehler</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>
<!-- General Notice -->
<system:String x:Key="pleaseWait">Bitte warten Sie ...</system:String>

View file

@ -104,6 +104,11 @@
<system:String x:Key="AlwaysPreview">Always Preview</system:String>
<system:String x:Key="AlwaysPreviewToolTip">Always open preview panel when Flow activates. Press {0} to toggle preview.</system:String>
<system:String x:Key="shadowEffectNotAllowed">Shadow effect is not allowed while current theme has blur effect enabled</system:String>
<system:String x:Key="BackdropType">Backdrop Type</system:String>
<system:String x:Key="BackdropTypesNone">None</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>
<!-- Setting Plugin -->
<system:String x:Key="searchplugin">Search Plugin</system:String>
@ -337,9 +342,10 @@
<system:String x:Key="cannotFindSpecifiedPlugin">Can't find specified plugin</system:String>
<system:String x:Key="newActionKeywordsCannotBeEmpty">New Action Keyword can't be empty</system:String>
<system:String x:Key="newActionKeywordsHasBeenAssigned">This new Action Keyword is already assigned to another plugin, please choose a different one</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="success">Success</system:String>
<system:String x:Key="completedSuccessfully">Completed successfully</system:String>
<system:String x:Key="actionkeyword_tips">Enter the action keyword you like to use to start the plugin. 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="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>
<!-- Custom Query Hotkey Dialog -->
<system:String x:Key="customeQueryHotkeyTitle">Custom Query Hotkey</system:String>

View file

@ -13,6 +13,7 @@
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">Failed to register hotkey &quot;{0}&quot;. The hotkey may be in use by another program. Change to a different hotkey, or exit another program.</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="MessageBoxTitle">Flow Launcher</system:String>
<system:String x:Key="couldnotStartCmd">No se pudo iniciar {0}</system:String>
<system:String x:Key="invalidFlowLauncherPluginFileFormat">Formato de archivo de plugin Flow Launcher inválido</system:String>
@ -44,6 +45,8 @@
<system:String x:Key="portableMode">Modo portable</system:String>
<system:String x:Key="portableModeToolTIp">Almacena todos los ajustes y datos de usuario en una sola carpeta (útil cuando se utiliza con unidades extraíbles o servicios en la nube).</system:String>
<system:String x:Key="startFlowLauncherOnSystemStartup">Iniciar Flow Launcher al arrancar el sistema</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="setAutoStartFailed">Error setting launch on startup</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">Ocultar Flow Launcher cuando se pierde el enfoque</system:String>
<system:String x:Key="dontPromptUpdateMsg">No mostrar notificaciones de nuevas versiones</system:String>
@ -126,7 +129,8 @@
<system:String x:Key="plugin_query_version">Versión</system:String>
<system:String x:Key="plugin_query_web">Sitio web</system:String>
<system:String x:Key="plugin_uninstall">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>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">Tienda de Plugins</system:String>
@ -143,8 +147,6 @@
<system:String x:Key="LabelNewToolTip">This plugin has been updated within the last 7 days</system:String>
<system:String x:Key="LabelUpdateToolTip">New Update is Available</system:String>
<!-- Setting Theme -->
<system:String x:Key="theme">Tema</system:String>
<system:String x:Key="appearance">Appearance</system:String>
@ -194,7 +196,6 @@
<system:String x:Key="TypeIsDarkToolTip">This theme supports two(light/dark) modes.</system:String>
<system:String x:Key="TypeHasBlurToolTip">This theme supports Blur Transparent Background.</system:String>
<!-- Setting Hotkey -->
<system:String x:Key="hotkey">Tecla Rápida</system:String>
<system:String x:Key="hotkeys">Tecla Rápida</system:String>
@ -297,6 +298,9 @@
<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="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">Seleccionar Gestor de Archivos</system:String>
@ -367,6 +371,7 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
<system:String x:Key="commonOK">OK</system:String>
<system:String x:Key="commonYes">Yes</system:String>
<system:String x:Key="commonNo">No</system:String>
<system:String x:Key="commonBackground">Background</system:String>
<!-- Crash Reporter -->
<system:String x:Key="reportWindow_version">Versión</system:String>
@ -383,6 +388,9 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
<system:String x:Key="reportWindow_report_succeed">Informe enviado correctamente</system:String>
<system:String x:Key="reportWindow_report_failed">Error al enviar el informe</system:String>
<system:String x:Key="reportWindow_flowlauncher_got_an_error">Flow Launcher ha tenido un error</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>
<!-- General Notice -->
<system:String x:Key="pleaseWait">Por favor espere...</system:String>

View file

@ -13,6 +13,7 @@
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">No se ha podido registrar el atajo de teclado &quot;{0}&quot;. El atajo de teclado puede estar siendo utilizado por otro programa. Seleccione un atajo de teclado diferente o salga del otro programa.</system:String>
<system:String x:Key="unregisterHotkeyFailed">No se ha podido anular el registro de la tecla de acceso rápido «{0}». Inténtelo de nuevo o consulte el registro para obtener más detalles</system:String>
<system:String x:Key="MessageBoxTitle">Flow Launcher</system:String>
<system:String x:Key="couldnotStartCmd">No se ha podido iniciar {0}</system:String>
<system:String x:Key="invalidFlowLauncherPluginFileFormat">Formato de archivo del complemento de Flow Launcher no válido</system:String>
@ -44,6 +45,8 @@
<system:String x:Key="portableMode">Modo Portable</system:String>
<system:String x:Key="portableModeToolTIp">Guarda toda la configuración y datos de usuario en una carpeta (Útil cuando se utiliza con unidades extraíbles o servicios en la nube).</system:String>
<system:String x:Key="startFlowLauncherOnSystemStartup">Cargar Flow Launcher al iniciar el sistema</system:String>
<system:String x:Key="useLogonTaskForStartup">Usar la tarea de inicio de sesión en lugar de la entrada de inicio para una experiencia de inicio más rápida</system:String>
<system:String x:Key="useLogonTaskForStartupTooltip">Después de la desinstalación, es necesario eliminar manualmente la tarea (Flow.Launcher Startup) mediante el Programador de Tareas</system:String>
<system:String x:Key="setAutoStartFailed">Error de configuración de arranque al iniciar</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">Ocultar Flow Launcher cuando se pierde el foco</system:String>
<system:String x:Key="dontPromptUpdateMsg">No mostrar notificaciones de nuevas versiones</system:String>
@ -126,7 +129,8 @@
<system:String x:Key="plugin_query_version">Versión</system:String>
<system:String x:Key="plugin_query_web">Sitio web</system:String>
<system:String x:Key="plugin_uninstall">Desinstalar</system:String>
<system:String x:Key="failedToRemovePluginSettingsTitle">Fallo al eliminar la configuración del complemento</system:String>
<system:String x:Key="failedToRemovePluginSettingsMessage">Complementos: {0} - Fallo al eliminar los archivos de configuración del complemento, por favor elimínelos manualmente</system:String>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">Tienda complementos</system:String>
@ -143,8 +147,6 @@
<system:String x:Key="LabelNewToolTip">Este complemento ha sido actualizado en los últimos 7 días</system:String>
<system:String x:Key="LabelUpdateToolTip">Nueva actualización disponible</system:String>
<!-- Setting Theme -->
<system:String x:Key="theme">Tema</system:String>
<system:String x:Key="appearance">Apariencia</system:String>
@ -194,7 +196,6 @@
<system:String x:Key="TypeIsDarkToolTip">Este tema soporta dos modos (claro/oscuro).</system:String>
<system:String x:Key="TypeHasBlurToolTip">Este tema soporta fondo transparente desenfocado.</system:String>
<!-- Setting Hotkey -->
<system:String x:Key="hotkey">Atajo de teclado</system:String>
<system:String x:Key="hotkeys">Atajos de teclado</system:String>
@ -297,6 +298,9 @@
<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="logLevel">Nivel de registro</system:String>
<system:String x:Key="LogLevelDEBUG">Depurar</system:String>
<system:String x:Key="LogLevelINFO">Información</system:String>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">Seleccionar administrador de archivos</system:String>
@ -367,6 +371,7 @@ Si añade un prefijo &quot;@&quot; al introducir un acceso directo, éste coinci
<system:String x:Key="commonOK">Aceptar</system:String>
<system:String x:Key="commonYes">Si</system:String>
<system:String x:Key="commonNo">No</system:String>
<system:String x:Key="commonBackground">Fondo</system:String>
<!-- Crash Reporter -->
<system:String x:Key="reportWindow_version">Versión</system:String>
@ -383,6 +388,9 @@ Si añade un prefijo &quot;@&quot; al introducir un acceso directo, éste coinci
<system:String x:Key="reportWindow_report_succeed">Informe enviado correctamente</system:String>
<system:String x:Key="reportWindow_report_failed">No se ha podido enviar el informe</system:String>
<system:String x:Key="reportWindow_flowlauncher_got_an_error">Flow Launcher ha tenido un error</system:String>
<system:String x:Key="reportWindow_please_open_issue">Por favor, abra un nuevo tema en</system:String>
<system:String x:Key="reportWindow_upload_log">1. Subir archivo de registro: {0}</system:String>
<system:String x:Key="reportWindow_copy_below">2. Copiar el siguiente mensaje de excepción</system:String>
<!-- General Notice -->
<system:String x:Key="pleaseWait">Por favor espere...</system:String>

View file

@ -13,6 +13,7 @@
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">Échec lors de l'enregistrement du raccourci : {0}</system:String>
<system:String x:Key="unregisterHotkeyFailed">Échec de la réinitialisation du raccourci &quot;{0}&quot;. Veuillez réessayer ou consulter le journal pour plus de détails</system:String>
<system:String x:Key="MessageBoxTitle">Flow Launcher</system:String>
<system:String x:Key="couldnotStartCmd">Impossible de lancer {0}</system:String>
<system:String x:Key="invalidFlowLauncherPluginFileFormat">Le format de fichier n'est pas un plugin Flow Launcher valide</system:String>
@ -44,6 +45,8 @@
<system:String x:Key="portableMode">Mode Portable</system:String>
<system:String x:Key="portableModeToolTIp">Stocker tous les paramètres et données utilisateur dans un seul dossier (Pratique en cas d'utilisation de disques amovibles ou de services cloud).</system:String>
<system:String x:Key="startFlowLauncherOnSystemStartup">Lancer Flow Launcher au démarrage du système</system:String>
<system:String x:Key="useLogonTaskForStartup">Utilisez la tâche de connexion au lieu de l'entrée de démarrage pour une expérience de démarrage plus rapide</system:String>
<system:String x:Key="useLogonTaskForStartupTooltip">Après une désinstallation, vous devez supprimer manuellement cette tâche (Flow.Launcher Startup) via le planificateur de tâches</system:String>
<system:String x:Key="setAutoStartFailed">Erreur lors de la configuration du lancement au démarrage</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">Cacher Flow Launcher lors de la perte de focus</system:String>
<system:String x:Key="dontPromptUpdateMsg">Ne pas afficher le message de mise à jour pour les nouvelles versions</system:String>
@ -126,7 +129,8 @@
<system:String x:Key="plugin_query_version">Version</system:String>
<system:String x:Key="plugin_query_web">Site Web</system:String>
<system:String x:Key="plugin_uninstall">Désinstaller</system:String>
<system:String x:Key="failedToRemovePluginSettingsTitle">Échec de la suppression des paramètres du plugin</system:String>
<system:String x:Key="failedToRemovePluginSettingsMessage">Plugins : {0} - Échec de la suppression des fichiers de configuration des plugins, veuillez les supprimer manuellement</system:String>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">Magasin des Plugins</system:String>
@ -143,8 +147,6 @@
<system:String x:Key="LabelNewToolTip">Cette extension a été mis à jour au cours des 7 derniers jours</system:String>
<system:String x:Key="LabelUpdateToolTip">Une nouvelle mise à jour est disponible</system:String>
<!-- Setting Theme -->
<system:String x:Key="theme">Thèmes</system:String>
<system:String x:Key="appearance">Apparence</system:String>
@ -194,7 +196,6 @@
<system:String x:Key="TypeIsDarkToolTip">Ce thème prend en charge deux modes (clair/sombre).</system:String>
<system:String x:Key="TypeHasBlurToolTip">Ce thème prend en charge l'arrière-plan flou et transparent.</system:String>
<!-- Setting Hotkey -->
<system:String x:Key="hotkey">Raccourcis</system:String>
<system:String x:Key="hotkeys">Raccourcis</system:String>
@ -296,6 +297,9 @@
<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="logLevel">Niveau de journalisation</system:String>
<system:String x:Key="LogLevelDEBUG">Débogage</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">Sélectionner le gestionnaire de fichiers</system:String>
@ -326,7 +330,7 @@
<system:String x:Key="oldActionKeywords">Ancien mot-clé d'action</system:String>
<system:String x:Key="newActionKeywords">Nouveau mot-clé d'action</system:String>
<system:String x:Key="cancel">Annuler</system:String>
<system:String x:Key="done">Termin</system:String>
<system:String x:Key="done">Terminé</system:String>
<system:String x:Key="cannotFindSpecifiedPlugin">Impossible de trouver le module spécifi</system:String>
<system:String x:Key="newActionKeywordsCannotBeEmpty">Le nouveau mot-clé d'action doit être spécifi</system:String>
<system:String x:Key="newActionKeywordsHasBeenAssigned">Le nouveau mot-clé d'action a été assigné à un autre module, veuillez en choisir un autre</system:String>
@ -366,6 +370,7 @@ Si vous ajoutez un préfixe &quot;@&quot; lors de la saisie d'un raccourci, celu
<system:String x:Key="commonOK">Ok</system:String>
<system:String x:Key="commonYes">Oui</system:String>
<system:String x:Key="commonNo">Non</system:String>
<system:String x:Key="commonBackground">Arrière-plan</system:String>
<!-- Crash Reporter -->
<system:String x:Key="reportWindow_version">Version</system:String>
@ -382,6 +387,9 @@ Si vous ajoutez un préfixe &quot;@&quot; lors de la saisie d'un raccourci, celu
<system:String x:Key="reportWindow_report_succeed">Signalement envoy</system:String>
<system:String x:Key="reportWindow_report_failed">Échec de l'envoi du signalement</system:String>
<system:String x:Key="reportWindow_flowlauncher_got_an_error">Flow Launcher a rencontré une erreur</system:String>
<system:String x:Key="reportWindow_please_open_issue">Veuillez ouvrir un nouveau ticket dans</system:String>
<system:String x:Key="reportWindow_upload_log">1. Télécharger le fichier journal : {0}</system:String>
<system:String x:Key="reportWindow_copy_below">2. Copiez le message dexception ci-dessous</system:String>
<!-- General Notice -->
<system:String x:Key="pleaseWait">Veuillez patienter...</system:String>

View file

@ -2,9 +2,9 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:system="clr-namespace:System;assembly=mscorlib">
<!-- Startup -->
<system:String x:Key="runtimePluginInstalledChooseRuntimePrompt">
Flow detected you have installed {0} plugins, which will require {1} to run. Would you like to download {1}?
Flow זיהה שהתקנת את התוסף {0}, אשר דורש את {1} כדי לפעול. האם תרצה להוריד את {1}?
{2}{2}
Click no if it's already installed, and you will be prompted to select the folder that contains the {1} executable
אם זה כבר מותקן, לחץ על 'לא' ותתבקש לבחור את התיקיה המכילה את קובץ ההפעלה {1}
</system:String>
<system:String x:Key="runtimePluginChooseRuntimeExecutable">אנא בחר את קובץ ההפעלה {0}</system:String>
<system:String x:Key="runtimePluginUnableToSetExecutablePath">לא ניתן להגדיר נתיב הפעלה {0}, אנא נסה שוב בהגדרות Flow (גלול עד למטה).</system:String>
@ -13,13 +13,14 @@
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">רישום מקש הקיצור &quot;{0}&quot; נכשל. ייתכן שמקש הקיצור נמצא בשימוש על ידי תוכנה אחרת. שנה למקש קיצור אחר, או צא מהתוכנה האחרת.</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>
<system:String x:Key="setAsTopMostInThisQuery">הגדר כגבוה ביותר בשאילתה זו</system:String>
<system:String x:Key="cancelTopMostInThisQuery">בטל העלאה בשאילתה זו</system:String>
<system:String x:Key="executeQuery">בצע שאילתה: {0}</system:String>
<system:String x:Key="lastExecuteTime">Last execution time: {0}</system:String>
<system:String x:Key="lastExecuteTime">זמן ביצוע אחרון: {0}</system:String>
<system:String x:Key="iconTrayOpen">פתח</system:String>
<system:String x:Key="iconTraySettings">הגדרות</system:String>
<system:String x:Key="iconTrayAbout">אודות</system:String>
@ -28,15 +29,15 @@
<system:String x:Key="copy">העתק</system:String>
<system:String x:Key="cut">גזור</system:String>
<system:String x:Key="paste">הדבק</system:String>
<system:String x:Key="undo">Undo</system:String>
<system:String x:Key="undo">בטל</system:String>
<system:String x:Key="selectAll">בחר הכל</system:String>
<system:String x:Key="fileTitle">קובץ</system:String>
<system:String x:Key="folderTitle">תיקייה</system:String>
<system:String x:Key="textTitle">טקסט</system:String>
<system:String x:Key="GameMode">מצב משחק</system:String>
<system:String x:Key="GameModeToolTip">השהה את השימוש במקשי קיצור.</system:String>
<system:String x:Key="PositionReset">Position Reset</system:String>
<system:String x:Key="PositionResetToolTip">Reset search window position</system:String>
<system:String x:Key="PositionReset">איפוס מיקום</system:String>
<system:String x:Key="PositionResetToolTip">אפס את מיקום חלון החיפוש</system:String>
<!-- Setting General -->
<system:String x:Key="flowlauncher_settings">הגדרות</system:String>
@ -44,6 +45,8 @@
<system:String x:Key="portableMode">מצב נייד</system:String>
<system:String x:Key="portableModeToolTIp">אחסן את כל ההגדרות ונתוני המשתמש בתיקייה אחת (שימושי בשימוש עם כוננים נשלפים או שירותי ענן).</system:String>
<system:String x:Key="startFlowLauncherOnSystemStartup">הפעל את Flow Launcher בעת הפעלת Window</system:String>
<system:String x:Key="useLogonTaskForStartup">השתמש במשימת כניסה במקום בכניסה בעת האתחול, לחוויית הפעלה מהירה יותר</system:String>
<system:String x:Key="useLogonTaskForStartupTooltip">לאחר הסרת ההתקנה, עליך להסיר ידנית משימה זו (Flow.Launcher Startup) דרך מתזמן המשימות</system:String>
<system:String x:Key="setAutoStartFailed">שגיאה בהגדרת ההפעלה בעת הפעלת windows</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">הסתר את Flow Launcher כאשר הוא אינו החלון הפעיל</system:String>
<system:String x:Key="dontPromptUpdateMsg">אל תציג התראות על גרסה חדשה</system:String>
@ -60,179 +63,177 @@
<system:String x:Key="SearchWindowAlignRightTop">ימין עליון</system:String>
<system:String x:Key="SearchWindowAlignCustom">Custom Position</system:String>
<system:String x:Key="language">שפה</system:String>
<system:String x:Key="lastQueryMode">Last Query Style</system:String>
<system:String x:Key="lastQueryModeToolTip">Show/Hide previous results when Flow Launcher is reactivated.</system:String>
<system:String x:Key="LastQueryPreserved">Preserve Last Query</system:String>
<system:String x:Key="LastQuerySelected">Select last Query</system:String>
<system:String x:Key="LastQueryEmpty">Empty last Query</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="KeepMaxResults">Fixed Window Height</system:String>
<system:String x:Key="KeepMaxResultsToolTip">The window height is not adjustable by dragging.</system:String>
<system:String x:Key="maxShowResults">Maximum results shown</system:String>
<system:String x:Key="maxShowResultsToolTip">You can also quickly adjust this by using CTRL+Plus and CTRL+Minus.</system:String>
<system:String x:Key="ignoreHotkeysOnFullscreen">Ignore hotkeys in fullscreen mode</system:String>
<system:String x:Key="ignoreHotkeysOnFullscreenToolTip">Disable Flow Launcher activation when a full screen application is active (Recommended for games).</system:String>
<system:String x:Key="defaultFileManager">Default File Manager</system:String>
<system:String x:Key="defaultFileManagerToolTip">Select the file manager to use when opening the folder.</system:String>
<system:String x:Key="defaultBrowser">Default Web Browser</system:String>
<system:String x:Key="defaultBrowserToolTip">Setting for New Tab, New Window, Private Mode.</system:String>
<system:String x:Key="pythonFilePath">Python Path</system:String>
<system:String x:Key="nodeFilePath">Node.js Path</system:String>
<system:String x:Key="selectNodeExecutable">Please select the Node.js executable</system:String>
<system:String x:Key="selectPythonExecutable">Please select pythonw.exe</system:String>
<system:String x:Key="typingStartEn">Always Start Typing in English Mode</system:String>
<system:String x:Key="typingStartEnTooltip">Temporarily change your input method to English mode when activating Flow.</system:String>
<system:String x:Key="lastQueryMode">סגנון שאילתה אחרונה</system:String>
<system:String x:Key="lastQueryModeToolTip">הצג/הסתר תוצאות קודמות כאשר Flow Launcher מופעל מחדש.</system:String>
<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">שמור מילת מפתח לפעולה האחרונה</system:String>
<system:String x:Key="LastQueryActionKeywordSelected">בחר מילת מפתח לפעולה האחרונה</system:String>
<system:String x:Key="KeepMaxResults">גובה חלון קבוע</system:String>
<system:String x:Key="KeepMaxResultsToolTip">גובה החלון אינו ניתן להתאמה באמצעות גרירה.</system:String>
<system:String x:Key="maxShowResults">כמות תוצאות מרבית</system:String>
<system:String x:Key="maxShowResultsToolTip">ניתן גם להתאים במהירות באמצעות CTRL+פלוס ו-CTRL+מינוס.</system:String>
<system:String x:Key="ignoreHotkeysOnFullscreen">התעלם מקיצורי מקשים במצב מסך מלא</system:String>
<system:String x:Key="ignoreHotkeysOnFullscreenToolTip">השבת את הפעלת Flow Launcher כאשר יישום מסך מלא פעיל (מומלץ למשחקים).</system:String>
<system:String x:Key="defaultFileManager">מנהל הקבצים המוגדר כברירת מחדל</system:String>
<system:String x:Key="defaultFileManagerToolTip">בחר את מנהל הקבצים לשימוש בעת פתיחת תיקיה.</system:String>
<system:String x:Key="defaultBrowser">דפדפן ברירת מחדל</system:String>
<system:String x:Key="defaultBrowserToolTip">הגדרה ללשונית חדשה, חלון חדש, מצב פרטי.</system:String>
<system:String x:Key="pythonFilePath">נתיב Python</system:String>
<system:String x:Key="nodeFilePath">נתיב Node.js</system:String>
<system:String x:Key="selectNodeExecutable">בחר את קובץ ההפעלה של Node.js</system:String>
<system:String x:Key="selectPythonExecutable">בחר את pythonw.exe</system:String>
<system:String x:Key="typingStartEn">תמיד התחל להקליד במצב אנגלית</system:String>
<system:String x:Key="typingStartEnTooltip">שנה זמנית את שיטת הקלט שלך למצב אנגלית בעת הפעלת Flow.</system:String>
<system:String x:Key="autoUpdates">עדכון אוטומטי</system:String>
<system:String x:Key="select">בחר</system:String>
<system:String x:Key="hideOnStartup">Hide Flow Launcher on startup</system:String>
<system:String x:Key="hideOnStartupToolTip">Flow Launcher search window is hidden in the tray after starting up.</system:String>
<system:String x:Key="hideNotifyIcon">Hide tray icon</system:String>
<system:String x:Key="hideNotifyIconToolTip">When the icon is hidden from the tray, the Settings menu can be opened by right-clicking on the search window.</system:String>
<system:String x:Key="querySearchPrecision">Query Search Precision</system:String>
<system:String x:Key="querySearchPrecisionToolTip">Changes minimum match score required for results.</system:String>
<system:String x:Key="hideOnStartup">הסתר את Flow Launcher בהפעלת המחשב</system:String>
<system:String x:Key="hideOnStartupToolTip">חלון החיפוש של Flow Launcher מוסתר במגש לאחר ההפעלה.</system:String>
<system:String x:Key="hideNotifyIcon">הסתר אייקון מגש</system:String>
<system:String x:Key="hideNotifyIconToolTip">כאשר האייקון מוסתר מהמגש, ניתן לפתוח את תפריט ההגדרות על ידי לחיצה ימנית על חלון החיפוש.</system:String>
<system:String x:Key="querySearchPrecision">דיוק חיפוש שאילתה</system:String>
<system:String x:Key="querySearchPrecisionToolTip">משנה את ציון ההתאמה המינימלי הנדרש לתוצאות.</system:String>
<system:String x:Key="SearchPrecisionNone">ללא</system:String>
<system:String x:Key="SearchPrecisionLow">נמוך</system:String>
<system:String x:Key="SearchPrecisionRegular">Regular</system:String>
<system:String x:Key="ShouldUsePinyin">Search with 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="AlwaysPreview">Always Preview</system:String>
<system:String x:Key="AlwaysPreviewToolTip">Always open preview panel when Flow activates. Press {0} to toggle preview.</system:String>
<system:String x:Key="shadowEffectNotAllowed">Shadow effect is not allowed while current theme has blur effect enabled</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>
<!-- Setting Plugin -->
<system:String x:Key="searchplugin">Search Plugin</system:String>
<system:String x:Key="searchpluginToolTip">Ctrl+F to search plugins</system:String>
<system:String x:Key="searchplugin_Noresult_Title">No results found</system:String>
<system:String x:Key="searchplugin">חפש תוסף</system:String>
<system:String x:Key="searchpluginToolTip">Ctrl+F לחיפוש תוסף</system:String>
<system:String x:Key="searchplugin_Noresult_Title">לא נמצאו תוצאות</system:String>
<system:String x:Key="searchplugin_Noresult_Subtitle">Please try a different search.</system:String>
<system:String x:Key="plugin">Plugin</system:String>
<system:String x:Key="plugin">תוסף</system:String>
<system:String x:Key="plugins">תוספים</system:String>
<system:String x:Key="browserMorePlugins">מצא תוספים נוספים</system:String>
<system:String x:Key="enable">On</system:String>
<system:String x:Key="disable">Off</system:String>
<system:String x:Key="actionKeywordsTitle">Action keyword Setting</system:String>
<system:String x:Key="actionKeywords">Action keyword</system:String>
<system:String x:Key="currentActionKeywords">Current action keyword</system:String>
<system:String x:Key="newActionKeyword">New action keyword</system:String>
<system:String x:Key="actionKeywordsTooltip">Change Action Keywords</system:String>
<system:String x:Key="currentPriority">Current Priority</system:String>
<system:String x:Key="newPriority">New Priority</system:String>
<system:String x:Key="priority">Priority</system:String>
<system:String x:Key="priorityToolTip">Change Plugin Results Priority</system:String>
<system:String x:Key="pluginDirectory">Plugin Directory</system:String>
<system:String x:Key="enable">פועל</system:String>
<system:String x:Key="disable">כבוי</system:String>
<system:String x:Key="actionKeywordsTitle">הגדרת מילת מפתח לפעולה</system:String>
<system:String x:Key="actionKeywords">מילת מפתח לפעולה</system:String>
<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="currentPriority">עדיפות נוכחית</system:String>
<system:String x:Key="newPriority">עדיפות חדשה</system:String>
<system:String x:Key="priority">עדיפות</system:String>
<system:String x:Key="priorityToolTip">שנה עדיפות תוצאות תוסף</system:String>
<system:String x:Key="pluginDirectory">ספריית תוספים</system:String>
<system:String x:Key="author">מאת</system:String>
<system:String x:Key="plugin_init_time">Init time:</system:String>
<system:String x:Key="plugin_query_time">Query time:</system:String>
<system:String x:Key="plugin_init_time">זמן פתיחה:</system:String>
<system:String x:Key="plugin_query_time">זמן שאילתא:</system:String>
<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">נכשל בהסרת הגדרות התוסף</system:String>
<system:String x:Key="failedToRemovePluginSettingsMessage">תוספים: {0} - נכשל בהסרת קבצי הגדרות התוסף, יש להסירם ידנית</system:String>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">חנות תוספים</system:String>
<system:String x:Key="pluginStore_NewRelease">שחרור חדש</system:String>
<system:String x:Key="pluginStore_RecentlyUpdated">Recently Updated</system:String>
<system:String x:Key="pluginStore_RecentlyUpdated">עודכן לאחרונה</system:String>
<system:String x:Key="pluginStore_None">תוספים</system:String>
<system:String x:Key="pluginStore_Installed">מותקן</system:String>
<system:String x:Key="refresh">רענן</system:String>
<system:String x:Key="installbtn">התקן</system:String>
<system:String x:Key="uninstallbtn">הסר התקנה</system:String>
<system:String x:Key="updatebtn">עדכון</system:String>
<system:String x:Key="LabelInstalledToolTip">Plugin already installed</system:String>
<system:String x:Key="LabelInstalledToolTip">התוסף כבר מותקן</system:String>
<system:String x:Key="LabelNew">גרסה חדשה</system:String>
<system:String x:Key="LabelNewToolTip">This plugin has been updated within the last 7 days</system:String>
<system:String x:Key="LabelUpdateToolTip">New Update is Available</system:String>
<system:String x:Key="LabelNewToolTip">תוסף זה עודכן במהלך 7 הימים האחרונים</system:String>
<system:String x:Key="LabelUpdateToolTip">עדכון חדש זמין</system:String>
<!-- Setting Theme -->
<system:String x:Key="theme">ערכת נושא</system:String>
<system:String x:Key="appearance">Appearance</system:String>
<system:String x:Key="appearance">מראה</system:String>
<system:String x:Key="browserMoreThemes">גלריית ערכות נושא</system:String>
<system:String x:Key="howToCreateTheme">How to create a theme</system:String>
<system:String x:Key="hiThere">Hi There</system:String>
<system:String x:Key="SampleTitleExplorer">Explorer</system:String>
<system:String x:Key="SampleSubTitleExplorer">Search for files, folders and file contents</system:String>
<system:String x:Key="SampleTitleWebSearch">WebSearch</system:String>
<system:String x:Key="howToCreateTheme">איך ליצור ערכת נושא</system:String>
<system:String x:Key="hiThere">שלום</system:String>
<system:String x:Key="SampleTitleExplorer">סייר</system:String>
<system:String x:Key="SampleSubTitleExplorer">חפש קבצים, תיקיות ובתוכן הקבצים</system:String>
<system:String x:Key="SampleTitleWebSearch">חיפוש באינטרנט</system:String>
<system:String x:Key="SampleSubTitleWebSearch">Search the web with different search engine support</system:String>
<system:String x:Key="SampleTitleProgram">Program</system:String>
<system:String x:Key="SampleSubTitleProgram">Launch programs as admin or a different user</system:String>
<system:String x:Key="SampleTitleProgram">תוכנה</system:String>
<system:String x:Key="SampleSubTitleProgram">הפעל תוכנות כמנהל או כמשתמש אחר</system:String>
<system:String x:Key="SampleTitleProcessKiller">ProcessKiller</system:String>
<system:String x:Key="SampleSubTitleProcessKiller">Terminate unwanted processes</system:String>
<system:String x:Key="SearchBarHeight">Search Bar Height</system:String>
<system:String x:Key="ItemHeight">Item Height</system:String>
<system:String x:Key="queryBoxFont">Query Box Font</system:String>
<system:String x:Key="resultItemFont">Result Title Font</system:String>
<system:String x:Key="resultSubItemFont">Result Subtitle Font</system:String>
<system:String x:Key="SampleSubTitleProcessKiller">הפסקת תהליכים לא רצויים</system:String>
<system:String x:Key="SearchBarHeight">גובה סרגל החיפוש</system:String>
<system:String x:Key="ItemHeight">גובה פריט</system:String>
<system:String x:Key="queryBoxFont">גופן תיבת שאילתות</system:String>
<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="CustomizeToolTip">Customize</system:String>
<system:String x:Key="windowMode">Window Mode</system:String>
<system:String x:Key="opacity">Opacity</system:String>
<system:String x:Key="theme_load_failure_path_not_exists">Theme {0} not exists, fallback to default theme</system:String>
<system:String x:Key="theme_load_failure_parse_error">Fail to load theme {0}, fallback to default theme</system:String>
<system:String x:Key="ThemeFolder">Theme Folder</system:String>
<system:String x:Key="OpenThemeFolder">Open Theme Folder</system:String>
<system:String x:Key="ColorScheme">Color Scheme</system:String>
<system:String x:Key="ColorSchemeSystem">System Default</system:String>
<system:String x:Key="CustomizeToolTip">התאם אישית</system:String>
<system:String x:Key="windowMode">מצב חלון</system:String>
<system:String x:Key="opacity">שקיפות</system:String>
<system:String x:Key="theme_load_failure_path_not_exists">ערכת הנושא {0} אינה קיימת, חוזר לערכת ברירת המחדל</system:String>
<system:String x:Key="theme_load_failure_parse_error">נכשל בטעינת העיצוב {0}, חוזר לערכת ברירת המחדל</system:String>
<system:String x:Key="ThemeFolder">תיקיית ערכת נושא</system:String>
<system:String x:Key="OpenThemeFolder">פתח תיקיית ערכת נושא</system:String>
<system:String x:Key="ColorScheme">ערכת צבעים</system:String>
<system:String x:Key="ColorSchemeSystem">ברירת המחדל של המערכת</system:String>
<system:String x:Key="ColorSchemeLight">בהיר</system:String>
<system:String x:Key="ColorSchemeDark">כהה</system:String>
<system:String x:Key="SoundEffect">Sound Effect</system:String>
<system:String x:Key="SoundEffectTip">Play a small sound when the search window opens</system:String>
<system:String x:Key="SoundEffectVolume">Sound Effect Volume</system:String>
<system:String x:Key="SoundEffectVolumeTip">Adjust the volume of the sound effect</system:String>
<system:String x:Key="SoundEffectWarning">Windows Media Player is unavailable and is required for Flow's volume adjustment. Please check your installation if you need to adjust volume.</system:String>
<system:String x:Key="Animation">Animation</system:String>
<system:String x:Key="AnimationTip">Use Animation in UI</system:String>
<system:String x:Key="AnimationSpeed">Animation Speed</system:String>
<system:String x:Key="AnimationSpeedTip">The speed of the UI animation</system:String>
<system:String x:Key="AnimationSpeedSlow">Slow</system:String>
<system:String x:Key="AnimationSpeedMedium">Medium</system:String>
<system:String x:Key="AnimationSpeedFast">Fast</system:String>
<system:String x:Key="AnimationSpeedCustom">Custom</system:String>
<system:String x:Key="Clock">Clock</system:String>
<system:String x:Key="Date">Date</system:String>
<system:String x:Key="TypeIsDarkToolTip">This theme supports two(light/dark) modes.</system:String>
<system:String x:Key="TypeHasBlurToolTip">This theme supports Blur Transparent Background.</system:String>
<system:String x:Key="SoundEffect">אפקט צליל</system:String>
<system:String x:Key="SoundEffectTip">השמע צליל קטן כאשר חלון החיפוש נפתח</system:String>
<system:String x:Key="SoundEffectVolume">עוצמת אפקט הקול</system:String>
<system:String x:Key="SoundEffectVolumeTip">התאם את עוצמת אפקט הקול</system:String>
<system:String x:Key="SoundEffectWarning">Windows Media Player אינו זמין, והוא נדרש להתאמת עוצמת הקול של Flow. אנא בדוק את ההתקנה שלך אם אתה צריך להתאים את עוצמת הקול.</system:String>
<system:String x:Key="Animation">אנימציה</system:String>
<system:String x:Key="AnimationTip">השתמש באנימציה בממשק המשתמש</system:String>
<system:String x:Key="AnimationSpeed">מהירות אנימציה</system:String>
<system:String x:Key="AnimationSpeedTip">מהירות האנימציה של ממשק המשתמש</system:String>
<system:String x:Key="AnimationSpeedSlow">איטי</system:String>
<system:String x:Key="AnimationSpeedMedium">בינוני</system:String>
<system:String x:Key="AnimationSpeedFast">מהיר</system:String>
<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="TypeIsDarkToolTip">ערכת נושא זאת תומך בשני מצבים (בהיר/כהה).</system:String>
<system:String x:Key="TypeHasBlurToolTip">ערכת נושא זו תומכת בטשטוש רקע שקוף.</system:String>
<!-- Setting Hotkey -->
<system:String x:Key="hotkey">מקש קיצור</system:String>
<system:String x:Key="hotkeys">מקשי קיצור</system:String>
<system:String x:Key="flowlauncherHotkey">פתח את Flow Launcher</system:String>
<system:String x:Key="flowlauncherHotkeyToolTip">Enter shortcut to show/hide Flow Launcher.</system:String>
<system:String x:Key="previewHotkey">Toggle Preview</system:String>
<system:String x:Key="previewHotkeyToolTip">Enter shortcut to show/hide preview in search window.</system:String>
<system:String x:Key="hotkeyPresets">Hotkey Presets</system:String>
<system:String x:Key="hotkeyPresetsToolTip">List of currently registered hotkeys</system:String>
<system:String x:Key="openResultModifiers">Open Result Modifier Key</system:String>
<system:String x:Key="openResultModifiersToolTip">Select a modifier key to open selected result via keyboard.</system:String>
<system:String x:Key="flowlauncherHotkeyToolTip">הזן קיצור דרך להצגה/הסתרה של Flow Launcher.</system:String>
<system:String x:Key="previewHotkey">הצג/הסתר תצוגה מקדימה</system:String>
<system:String x:Key="previewHotkeyToolTip">הזן קיצור דרך להצגה/הסתרה של התצוגה המקדימה בחלון החיפוש.</system:String>
<system:String x:Key="hotkeyPresets">קיצורי דרך מוגדרים</system:String>
<system:String x:Key="hotkeyPresetsToolTip">רשימת קיצורי הדרך הרשומים כעת</system:String>
<system:String x:Key="openResultModifiers">מקש משני לפתיחת תוצאה</system:String>
<system:String x:Key="openResultModifiersToolTip">בחר מקש משני לפתיחת התוצאה שנבחרה דרך המקלדת.</system:String>
<system:String x:Key="showOpenResultHotkey">הצג מקש קיצור</system:String>
<system:String x:Key="showOpenResultHotkeyToolTip">Show result selection hotkey with results.</system:String>
<system:String x:Key="autoCompleteHotkey">Auto Complete</system:String>
<system:String x:Key="autoCompleteHotkeyToolTip">Runs autocomplete for the selected items.</system:String>
<system:String x:Key="SelectNextItemHotkey">Select Next Item</system:String>
<system:String x:Key="SelectPrevItemHotkey">Select Previous Item</system:String>
<system:String x:Key="showOpenResultHotkeyToolTip">הצג מקש קיצור לבחירת תוצאה עם התוצאות.</system:String>
<system:String x:Key="autoCompleteHotkey">השלמה אוטומטית</system:String>
<system:String x:Key="autoCompleteHotkeyToolTip">מבצע השלמה אוטומטית לפריטים שנבחרו.</system:String>
<system:String x:Key="SelectNextItemHotkey">בחר את הפריט הבא</system:String>
<system:String x:Key="SelectPrevItemHotkey">בחר את הפריט הקודם</system:String>
<system:String x:Key="SelectNextPageHotkey">הדף הבא</system:String>
<system:String x:Key="SelectPrevPageHotkey">הדף הקודם</system:String>
<system:String x:Key="CycleHistoryUpHotkey">Cycle Previous Query</system:String>
<system:String x:Key="CycleHistoryDownHotkey">Cycle Next Query</system:String>
<system:String x:Key="OpenContextMenuHotkey">Open Context Menu</system:String>
<system:String x:Key="OpenNativeContextMenuHotkey">Open Native Context Menu</system:String>
<system:String x:Key="SettingWindowHotkey">Open Setting Window</system:String>
<system:String x:Key="CycleHistoryUpHotkey">עבור לשאילתה הקודמת</system:String>
<system:String x:Key="CycleHistoryDownHotkey">עבור לשאילתה הבאה</system:String>
<system:String x:Key="OpenContextMenuHotkey">פתח תפריט הקשר</system:String>
<system:String x:Key="OpenNativeContextMenuHotkey">פתח תפריט הקשר מקומי</system:String>
<system:String x:Key="SettingWindowHotkey">פתח חלון הגדרות</system:String>
<system:String x:Key="CopyFilePathHotkey">העתק את נתיב הקובץ</system:String>
<system:String x:Key="ToggleGameModeHotkey">Toggle Game Mode</system:String>
<system:String x:Key="ToggleHistoryHotkey">Toggle History</system:String>
<system:String x:Key="OpenContainFolderHotkey">Open Containing Folder</system:String>
<system:String x:Key="ToggleGameModeHotkey">הפעל או כבה מצב משחק</system:String>
<system:String x:Key="ToggleHistoryHotkey">הפעל או כבה היסטוריה</system:String>
<system:String x:Key="OpenContainFolderHotkey">פתח תיקייה מכילה</system:String>
<system:String x:Key="RunAsAdminHotkey">הרץ כמנהל</system:String>
<system:String x:Key="RequeryHotkey">Refresh Search Results</system:String>
<system:String x:Key="ReloadPluginHotkey">Reload Plugins Data</system:String>
<system:String x:Key="QuickWidthHotkey">Quick Adjust Window Width</system:String>
<system:String x:Key="QuickHeightHotkey">Quick Adjust Window Height</system:String>
<system:String x:Key="ReloadPluginHotkeyToolTip">Use when require plugins to reload and update their existing data.</system:String>
<system:String x:Key="AdditionalHotkeyToolTip">You can add one more hotkey for this function.</system:String>
<system:String x:Key="customQueryHotkey">Custom Query Hotkeys</system:String>
<system:String x:Key="customQueryShortcut">Custom Query Shortcuts</system:String>
<system:String x:Key="builtinShortcuts">Built-in Shortcuts</system:String>
<system:String x:Key="RequeryHotkey">רענן תוצאות חיפוש</system:String>
<system:String x:Key="ReloadPluginHotkey">טען מחדש נתוני תוספים</system:String>
<system:String x:Key="QuickWidthHotkey">כוונון מהיר של רוחב החלון</system:String>
<system:String x:Key="QuickHeightHotkey">כוונון מהיר של גובה החלון</system:String>
<system:String x:Key="ReloadPluginHotkeyToolTip">השתמש כאשר יש צורך בטעינה מחדש של תוספים ובעדכון הנתונים שלהם.</system:String>
<system:String x:Key="AdditionalHotkeyToolTip">באפשרותך להוסיף מקש קיצור נוסף לפעולה זו.</system:String>
<system:String x:Key="customQueryHotkey">מקשי קיצור לשאילתות מותאמות אישית</system:String>
<system:String x:Key="customQueryShortcut">קיצורי דרך לשאילתות מותאמות אישית</system:String>
<system:String x:Key="builtinShortcuts">קיצורי דרך מובנים</system:String>
<system:String x:Key="customQuery">שאילתה</system:String>
<system:String x:Key="customShortcut">קיצור דרך</system:String>
<system:String x:Key="customShortcutExpansion">הרחבה</system:String>
@ -242,33 +243,33 @@
<system:String x:Key="add">הוסף</system:String>
<system:String x:Key="none">ללא</system:String>
<system:String x:Key="pleaseSelectAnItem">אנא בחר פריט</system:String>
<system:String x:Key="deleteCustomHotkeyWarning">Are you sure you want to delete {0} plugin hotkey?</system:String>
<system:String x:Key="deleteCustomShortcutWarning">Are you sure you want to delete shortcut: {0} with expansion {1}?</system:String>
<system:String x:Key="shortcut_clipboard_description">Get text from clipboard.</system:String>
<system:String x:Key="shortcut_active_explorer_path">Get path from active explorer.</system:String>
<system:String x:Key="queryWindowShadowEffect">Query window shadow effect</system:String>
<system:String x:Key="shadowEffectCPUUsage">Shadow effect has a substantial usage of GPU. Not recommended if your computer performance is limited.</system:String>
<system:String x:Key="windowWidthSize">Window Width Size</system:String>
<system:String x:Key="windowWidthSizeToolTip">You can also quickly adjust this by using Ctrl+[ and Ctrl+].</system:String>
<system:String x:Key="useGlyphUI">Use Segoe Fluent Icons</system:String>
<system:String x:Key="useGlyphUIEffect">Use Segoe Fluent Icons for query results where supported</system:String>
<system:String x:Key="flowlauncherPressHotkey">Press Key</system:String>
<system:String x:Key="deleteCustomHotkeyWarning">האם אתה בטוח שברצונך למחוק את מקש הקיצור של התוסף {0}?</system:String>
<system:String x:Key="deleteCustomShortcutWarning">האם אתה בטוח שברצונך למחוק את הקיצור: {0} עם ההרחבה {1}?</system:String>
<system:String x:Key="shortcut_clipboard_description">קבל טקסט מהלוח.</system:String>
<system:String x:Key="shortcut_active_explorer_path">קבל נתיב מסייר הקבצים הפעיל.</system:String>
<system:String x:Key="queryWindowShadowEffect">אפקט צל לחלון השאילתה</system:String>
<system:String x:Key="shadowEffectCPUUsage">לאפקט הצל יש שימוש ניכר ב-GPU. לא מומלץ אם ביצועי המחשב שלך מוגבלים.</system:String>
<system:String x:Key="windowWidthSize">רוחב החלון</system:String>
<system:String x:Key="windowWidthSizeToolTip">ניתן גם להתאים במהירות באמצעות Ctrl+[ ו-Ctrl+]</system:String>
<system:String x:Key="useGlyphUI">השתמש ב-Segoe Fluent Icons</system:String>
<system:String x:Key="useGlyphUIEffect">השתמש ב-Segoe Fluent Icons לתוצאות חיפוש כאשר נתמך</system:String>
<system:String x:Key="flowlauncherPressHotkey">הקש על מקש</system:String>
<!-- Setting Proxy -->
<system:String x:Key="proxy">HTTP Proxy</system:String>
<system:String x:Key="enableProxy">Enable HTTP Proxy</system:String>
<system:String x:Key="server">HTTP Server</system:String>
<system:String x:Key="enableProxy">הפעל HTTP Proxy</system:String>
<system:String x:Key="server">שרת HTTP</system:String>
<system:String x:Key="port">Port</system:String>
<system:String x:Key="userName">שם משתמש</system:String>
<system:String x:Key="password">סיסמא</system:String>
<system:String x:Key="testProxy">Test Proxy</system:String>
<system:String x:Key="testProxy">בדוק Proxy</system:String>
<system:String x:Key="save">שמור</system:String>
<system:String x:Key="serverCantBeEmpty">Server field can't be empty</system:String>
<system:String x:Key="portCantBeEmpty">Port field can't be empty</system:String>
<system:String x:Key="invalidPortFormat">Invalid port format</system:String>
<system:String x:Key="saveProxySuccessfully">Proxy configuration saved successfully</system:String>
<system:String x:Key="proxyIsCorrect">Proxy configured correctly</system:String>
<system:String x:Key="proxyConnectFailed">Proxy connection failed</system:String>
<system:String x:Key="serverCantBeEmpty">שדה השרת לא יכול להיות ריק</system:String>
<system:String x:Key="portCantBeEmpty">שדה ה-Port לא יכול להיות ריק</system:String>
<system:String x:Key="invalidPortFormat">פורמט ה-Port לא תקין</system:String>
<system:String x:Key="saveProxySuccessfully">תצורת ה-Proxy נשמרה בהצלחה</system:String>
<system:String x:Key="proxyIsCorrect">ה-Proxy הוגדר בהצלחה</system:String>
<system:String x:Key="proxyConnectFailed">החיבור ל- Proxy נכשל</system:String>
<!-- Setting About -->
<system:String x:Key="about">אודות</system:String>
@ -277,182 +278,189 @@
<system:String x:Key="docs">תיעוד</system:String>
<system:String x:Key="version">גרסה</system:String>
<system:String x:Key="icons">סמלים</system:String>
<system:String x:Key="about_activate_times">You have activated Flow Launcher {0} times</system:String>
<system:String x:Key="checkUpdates">Check for Updates</system:String>
<system:String x:Key="BecomeASponsor">Become A Sponsor</system:String>
<system:String x:Key="newVersionTips">New version {0} is available, would you like to restart Flow Launcher to use the update?</system:String>
<system:String x:Key="about_activate_times">הפעלת את Flow Launcher {0} פעמים</system:String>
<system:String x:Key="checkUpdates">בדוק עדכונים</system:String>
<system:String x:Key="BecomeASponsor">תן חסות</system:String>
<system:String x:Key="newVersionTips">גרסה חדשה {0} זמינה, האם ברצונך להפעיל מחדש את Flow Launcher כדי להשתמש בעדכון?</system:String>
<system:String x:Key="checkUpdatesFailed">בדיקת העדכונים נכשלה, אנא בדוק את הגדרות החיבור ואת הגדרות ה-Proxy שלך לכתובת api.github.com.</system:String>
<system:String x:Key="downloadUpdatesFailed">
Download updates failed, please check your connection and proxy settings to github-cloud.s3.amazonaws.com,
or go to https://github.com/Flow-Launcher/Flow.Launcher/releases to download updates manually.
הורדת העדכונים נכשלה, אנא בדוק את הגדרות החיבור ואת ה-proxy שלך אל github-cloud.s3.amazonaws.com,
או עבור אל https://github.com/Flow-Launcher/Flow.Launcher/releases כדי להוריד עדכונים באופן ידני.
</system:String>
<system:String x:Key="releaseNotes">Release Notes</system:String>
<system:String x:Key="documentation">Usage Tips</system:String>
<system:String x:Key="releaseNotes">הערות שחרור</system:String>
<system:String x:Key="documentation">טיפים לשימוש</system:String>
<system:String x:Key="devtool">DevTools</system:String>
<system:String x:Key="settingfolder">Setting Folder</system:String>
<system:String x:Key="logfolder">Log Folder</system:String>
<system:String x:Key="clearlogfolder">Clear Logs</system:String>
<system:String x:Key="clearlogfolderMessage">Are you sure you want to delete all logs?</system:String>
<system:String x:Key="settingfolder">תיקיית ההגדרות</system:String>
<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="welcomewindow">אשף</system:String>
<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="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>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">Select File Manager</system:String>
<system:String x:Key="fileManager_tips">Please specify the file location of the file manager you using and add arguments as required. The &quot;%d&quot; represents the directory path to open for, used by the Arg for Folder field and for commands opening specific directories. The &quot;%f&quot; represents the file path to open for, used by the Arg for File field and for commands opening specific files.</system:String>
<system:String x:Key="fileManager_tips2">For example, if the file manager uses a command such as &quot;totalcmd.exe /A c:\windows&quot; to open the c:\windows directory, the File Manager Path will be totalcmd.exe, and the Arg For Folder will be /A &quot;%d&quot;. Certain file managers like QTTabBar may just require a path to be supplied, in this instance use &quot;%d&quot; as the File Manager Path and leave the rest of the fileds blank.</system:String>
<system:String x:Key="fileManagerWindow">בחר מנהל קבצים</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>
<system:String x:Key="fileManager_profile_name">שם פרופיל</system:String>
<system:String x:Key="fileManager_path">File Manager Path</system:String>
<system:String x:Key="fileManager_directory_arg">Arg For Folder</system:String>
<system:String x:Key="fileManager_file_arg">Arg For File</system:String>
<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>
<!-- DefaultBrowser Setting Dialog -->
<system:String x:Key="defaultBrowserTitle">Default Web Browser</system:String>
<system:String x:Key="defaultBrowser_tips">The default setting follows the OS default browser setting. If specified separately, flow uses that browser.</system:String>
<system:String x:Key="defaultBrowser_name">Browser</system:String>
<system:String x:Key="defaultBrowser_profile_name">Browser Name</system:String>
<system:String x:Key="defaultBrowser_path">Browser Path</system:String>
<system:String x:Key="defaultBrowserTitle">דפדפן ברירת מחדל</system:String>
<system:String x:Key="defaultBrowser_tips">ההגדרה המוגדרת כברירת מחדל עוקבת אחר הדפדפן המוגדר כברירת מחדל במערכת ההפעלה. אם צוין דפדפן אחר, Flow Launcher ישתמש בו.</system:String>
<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_newTab">כרטיסייה חדשה</system:String>
<system:String x:Key="defaultBrowser_parameter">מצב פרטיות</system:String>
<!-- Priority Setting Dialog -->
<system:String x:Key="changePriorityWindow">Change Priority</system:String>
<system:String x:Key="priority_tips">Greater the number, the higher the result will be ranked. Try setting it as 5. If you want the results to be lower than any other plugin's, provide a negative number</system:String>
<system:String x:Key="invalidPriority">Please provide an valid integer for Priority!</system:String>
<system:String x:Key="changePriorityWindow">שנה עדיפות</system:String>
<system:String x:Key="priority_tips">ככל שהמספר גבוה יותר, התוצאה תדורג גבוה יותר ברשימת החיפוש. נסה להגדיר את הערך ל-5. אם ברצונך שהתוצאות יופיעו אחרי תוצאות של כל תוסף אחר, הזן מספר שלילי.</system:String>
<system:String x:Key="invalidPriority">אנא הזן מספר שלם תקף עבור העדיפות!</system:String>
<!-- Action Keyword Setting Dialog -->
<system:String x:Key="oldActionKeywords">Old Action Keyword</system:String>
<system:String x:Key="newActionKeywords">New Action Keyword</system:String>
<system:String x:Key="oldActionKeywords">מילת פעולה ישנה</system:String>
<system:String x:Key="newActionKeywords">מילת פעולה חדשה</system:String>
<system:String x:Key="cancel">ביטול</system:String>
<system:String x:Key="done">בוצע</system:String>
<system:String x:Key="cannotFindSpecifiedPlugin">Can't find specified plugin</system:String>
<system:String x:Key="newActionKeywordsCannotBeEmpty">New Action Keyword can't be empty</system:String>
<system:String x:Key="newActionKeywordsHasBeenAssigned">This new Action Keyword is already assigned to another plugin, please choose a different one</system:String>
<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="success">הצליח</system:String>
<system:String x:Key="completedSuccessfully">הושלם בהצלחה</system:String>
<system:String x:Key="actionkeyword_tips">Enter the action keyword you like to use to start the plugin. 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="actionkeyword_tips">הזן את מילת הפעולה שברצונך להשתמש בה להפעלת התוסף. השתמש ב-* אם אינך רוצה לציין מילה כלשהי, והתוסף יופעל ללא צורך במילת פעולה.</system:String>
<!-- Custom Query Hotkey Dialog -->
<system:String x:Key="customeQueryHotkeyTitle">Custom Query Hotkey</system:String>
<system:String x:Key="customeQueryHotkeyTips">Press a custom hotkey to open Flow Launcher and input the specified query automatically.</system:String>
<system:String x:Key="customeQueryHotkeyTitle">מקש קיצור לשאילתה מותאמת אישית</system:String>
<system:String x:Key="customeQueryHotkeyTips">הקש על מקש קיצור מותאם אישית כדי לפתוח את Flow Launcher ולהזין את השאילתה שצוינה באופן אוטומטי.</system:String>
<system:String x:Key="preview">תצוגה מקדימה</system:String>
<system:String x:Key="hotkeyIsNotUnavailable">Hotkey is unavailable, please select a new hotkey</system:String>
<system:String x:Key="invalidPluginHotkey">Invalid plugin hotkey</system:String>
<system:String x:Key="hotkeyIsNotUnavailable">מקש הקיצור אינו זמין, אנא בחר מקש קיצור חדש</system:String>
<system:String x:Key="invalidPluginHotkey">מקש קיצור לא חוקי לתוסף</system:String>
<system:String x:Key="update">עדכון</system:String>
<system:String x:Key="hotkeyRegTitle">Binding Hotkey</system:String>
<system:String x:Key="hotkeyUnavailable">Current hotkey is unavailable.</system:String>
<system:String x:Key="hotkeyUnavailableUneditable">This hotkey is reserved for &quot;{0}&quot; and can't be used. Please choose another hotkey.</system:String>
<system:String x:Key="hotkeyUnavailableEditable">This hotkey is already in use by &quot;{0}&quot;. If you press &quot;Overwrite&quot;, it will be removed from &quot;{0}&quot;.</system:String>
<system:String x:Key="hotkeyRegGuide">Press the keys you want to use for this function.</system:String>
<system:String x:Key="hotkeyRegTitle">שיוך מקש קיצור</system:String>
<system:String x:Key="hotkeyUnavailable">מקש הקיצור הנוכחי אינו זמין.</system:String>
<system:String x:Key="hotkeyUnavailableUneditable">מקש קיצור זה שמור עבור &quot;{0}&quot; ואינו ניתן לשימוש. אנא בחר מקש קיצור אחר.</system:String>
<system:String x:Key="hotkeyUnavailableEditable">מקש קיצור זה כבר נמצא בשימוש על ידי &quot;{0}&quot;. אם תלחץ על &quot;החלף&quot;, הוא יוסר מ-&quot;{0}&quot;.</system:String>
<system:String x:Key="hotkeyRegGuide">הקש על המקשים שברצונך להשתמש בהם עבור פעולה זו.</system:String>
<!-- Custom Query Shortcut Dialog -->
<system:String x:Key="customeQueryShortcutTitle">Custom Query Shortcut</system:String>
<system:String x:Key="customeQueryShortcutTips">Enter a shortcut that automatically expands to the specified query.</system:String>
<system:String x:Key="customeQueryShortcutGuide" xml:space="preserve">A shortcut is expanded when it exactly matches the query.
<system:String x:Key="customeQueryShortcutTitle">קיצור דרך לשאילתה מותאמת אישית</system:String>
<system:String x:Key="customeQueryShortcutTips">הזן קיצור דרך שיוחלף אוטומטית בשאילתה שצוינה.</system:String>
<system:String x:Key="customeQueryShortcutGuide" xml:space="preserve">קיצור דרך מוחלף כאשר הוא תואם בדיוק לשאילתה.
If you add an '@' prefix while inputting a shortcut, it matches any position in the query. Builtin shortcuts match any position in a query.
אם תוסיף תחילית '@' בעת הזנת קיצור דרך, הוא יתאים לכל מיקום בשאילתה. קיצורי דרך מובנים מתאימים לכל מיקום בשאילתה.
</system:String>
<system:String x:Key="duplicateShortcut">Shortcut already exists, please enter a new Shortcut or edit the existing one.</system:String>
<system:String x:Key="emptyShortcut">Shortcut and/or its expansion is empty.</system:String>
<system:String x:Key="duplicateShortcut">קיצור דרך כבר קיים, אנא הזן קיצור דרך חדש או ערוך את הקיים.</system:String>
<system:String x:Key="emptyShortcut">קיצור הדרך ו/או ההרחבה שלו ריקים.</system:String>
<!-- Common Action -->
<system:String x:Key="commonSave">שמור</system:String>
<system:String x:Key="commonOverwrite">Overwrite</system:String>
<system:String x:Key="commonOverwrite">שכתב</system:String>
<system:String x:Key="commonCancel">ביטול</system:String>
<system:String x:Key="commonReset">אפס</system:String>
<system:String x:Key="commonDelete">מחק</system:String>
<system:String x:Key="commonOK">אישור</system:String>
<system:String x:Key="commonYes">כן</system:String>
<system:String x:Key="commonNo">לא</system:String>
<system:String x:Key="commonBackground">רקע</system:String>
<!-- Crash Reporter -->
<system:String x:Key="reportWindow_version">גרסה</system:String>
<system:String x:Key="reportWindow_time">זמן</system:String>
<system:String x:Key="reportWindow_reproduce">Please tell us how application crashed so we can fix it</system:String>
<system:String x:Key="reportWindow_reproduce">אנא תאר כיצד האפליקציה קרסה כדי שנוכל לתקן זאת</system:String>
<system:String x:Key="reportWindow_send_report">שלח דיווח</system:String>
<system:String x:Key="reportWindow_cancel">ביטול</system:String>
<system:String x:Key="reportWindow_general">כללי</system:String>
<system:String x:Key="reportWindow_exceptions">חריגים</system:String>
<system:String x:Key="reportWindow_exception_type">Exception Type</system:String>
<system:String x:Key="reportWindow_exception_type">סוג החריגה</system:String>
<system:String x:Key="reportWindow_source">מקור</system:String>
<system:String x:Key="reportWindow_stack_trace">Stack Trace</system:String>
<system:String x:Key="reportWindow_stack_trace">מעקב מחסנית</system:String>
<system:String x:Key="reportWindow_sending">שולח</system:String>
<system:String x:Key="reportWindow_report_succeed">Report sent successfully</system:String>
<system:String x:Key="reportWindow_report_failed">Failed to send report</system:String>
<system:String x:Key="reportWindow_flowlauncher_got_an_error">Flow Launcher got an error</system:String>
<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">אנא פתח דיווח חדש ב</system:String>
<system:String x:Key="reportWindow_upload_log">1. העלה קובץ יומן: {0}</system:String>
<system:String x:Key="reportWindow_copy_below">2. העתק את הודעת החריגה למטה</system:String>
<!-- General Notice -->
<system:String x:Key="pleaseWait">אנא המתן...</system:String>
<!-- Update -->
<system:String x:Key="update_flowlauncher_update_check">Checking for new update</system:String>
<system:String x:Key="update_flowlauncher_already_on_latest">You already have the latest Flow Launcher version</system:String>
<system:String x:Key="update_flowlauncher_update_check">בודק עדכון חדש</system:String>
<system:String x:Key="update_flowlauncher_already_on_latest">כבר מותקנת אצלך הגרסה העדכנית של Flow Launcher</system:String>
<system:String x:Key="update_flowlauncher_update_found">עדכון נמצא</system:String>
<system:String x:Key="update_flowlauncher_updating">מעדכן...</system:String>
<system:String x:Key="update_flowlauncher_fail_moving_portable_user_profile_data">
Flow Launcher was not able to move your user profile data to the new update version.
Please manually move your profile data folder from {0} to {1}
Flow Launcher לא הצליח להעביר את נתוני פרופיל המשתמש שלך לגרסת העדכון החדשה.
אנא העבר ידנית את תיקיית נתוני הפרופיל שלך מ-{0} אל-{1}
</system:String>
<system:String x:Key="update_flowlauncher_new_update">עדכון חדש</system:String>
<system:String x:Key="update_flowlauncher_update_new_version_available">New Flow Launcher release {0} is now available</system:String>
<system:String x:Key="update_flowlauncher_update_error">An error occurred while trying to install software updates</system:String>
<system:String x:Key="update_flowlauncher_update_new_version_available">גרסה חדשה {0} של Flow Launcher זמינה כעת</system:String>
<system:String x:Key="update_flowlauncher_update_error">אירעה שגיאה במהלך ניסיון התקנת עדכוני התוכנה</system:String>
<system:String x:Key="update_flowlauncher_update">עדכון</system:String>
<system:String x:Key="update_flowlauncher_update_cancel">ביטול</system:String>
<system:String x:Key="update_flowlauncher_fail">העדכון נכשל</system:String>
<system:String x:Key="update_flowlauncher_check_connection">Check your connection and try updating proxy settings to github-cloud.s3.amazonaws.com.</system:String>
<system:String x:Key="update_flowlauncher_update_restart_flowlauncher_tip">This upgrade will restart Flow Launcher</system:String>
<system:String x:Key="update_flowlauncher_update_update_files">Following files will be updated</system:String>
<system:String x:Key="update_flowlauncher_check_connection">בדוק את החיבור שלך ונסה לעדכן את הגדרות הפרוקסי ל-github-cloud.s3.amazonaws.com.</system:String>
<system:String x:Key="update_flowlauncher_update_restart_flowlauncher_tip">שדרוג זה יאתחל את Flow Launcher</system:String>
<system:String x:Key="update_flowlauncher_update_update_files">הקבצים הבאים יעודכנו</system:String>
<system:String x:Key="update_flowlauncher_update_files">עדכן קבצים</system:String>
<system:String x:Key="update_flowlauncher_update_update_description">Update description</system:String>
<system:String x:Key="update_flowlauncher_update_update_description">עדכן תיאור</system:String>
<!-- Welcome Window -->
<system:String x:Key="Skip">דלג</system:String>
<system:String x:Key="Welcome_Page1_Title">Welcome to Flow Launcher</system:String>
<system:String x:Key="Welcome_Page1_Text01">Hello, this is the first time you are running Flow Launcher!</system:String>
<system:String x:Key="Welcome_Page1_Text02">Before starting, this wizard will assist in setting up Flow Launcher. You can skip this if you wish. Please choose a language</system:String>
<system:String x:Key="Welcome_Page2_Title">Search and run all files and applications on your PC</system:String>
<system:String x:Key="Welcome_Page2_Text01">Search everything from applications, files, bookmarks, YouTube, Twitter and more. All from the comfort of your keyboard without ever touching the mouse.</system:String>
<system:String x:Key="Welcome_Page2_Text02">Flow Launcher starts with the hotkey below, go ahead and try it out now. To change it, click on the input and press the desired hotkey on the keyboard.</system:String>
<system:String x:Key="Welcome_Page1_Title">ברוך הבא אל Flow Launcher</system:String>
<system:String x:Key="Welcome_Page1_Text01">שלום, זו הפעם הראשונה שבה Flow Launcher מופעל!</system:String>
<system:String x:Key="Welcome_Page1_Text02">לפני שתתחיל, אשף זה יסייע בהגדרת Flow Launcher. אתה יכול לדלג על שלב זה. בחר שפה</system:String>
<system:String x:Key="Welcome_Page2_Title">חפש והפעל את כל הקבצים והיישומים במחשב שלך</system:String>
<system:String x:Key="Welcome_Page2_Text01">חפש הכל מיישומים, קבצים, סימניות, YouTube, ועד טוויטר ועוד. הכל מהנוחות של המקלדת מבלי לגעת בעכבר.</system:String>
<system:String x:Key="Welcome_Page2_Text02">ניתן להפעיל את Flow Launcherבקיצור המקש שלמטה, קדימה נסה אותו כעת! כדי לשנות אותו, לחץ על מקש הקיצור הרצוי במקלדת.</system:String>
<system:String x:Key="Welcome_Page3_Title">מקשי קיצור</system:String>
<system:String x:Key="Welcome_Page4_Title">Action Keyword and Commands</system:String>
<system:String x:Key="Welcome_Page4_Text01">Search the web, launch applications or run various functions through Flow Launcher plugins. Certain functions start with an action keyword, and if necessary, they can be used without action keywords. Try the queries below in Flow Launcher.</system:String>
<system:String x:Key="Welcome_Page5_Title">Let's Start Flow Launcher</system:String>
<system:String x:Key="Welcome_Page5_Text01">Finished. Enjoy Flow Launcher. Don't forget the hotkey to start :)</system:String>
<system:String x:Key="Welcome_Page4_Title">מילת מפתח ופקודות פעולה</system:String>
<system:String x:Key="Welcome_Page4_Text01">חפש באינטרנט, הפעל אפליקציות או הפעל פונקציות שונות באמצעות תוספים של Flow Launcher. פונקציות מסוימות מתחילות במילת מפתח פעולה, ובמידת הצורך, ניתן להשתמש בהן ללא מילות מפתח פעולה. נסה את השאילתות למטה ב-Flow Launcher.</system:String>
<system:String x:Key="Welcome_Page5_Title">בואו נתחיל עם Flow Launcher</system:String>
<system:String x:Key="Welcome_Page5_Text01">סיימנו. תהנה מ-Flow Launcher. אל תשכח את מקש הקיצור כדי להתחיל :)</system:String>
<!-- General Guide & Hotkey -->
<system:String x:Key="HotkeyUpDownDesc">Back / Context Menu</system:String>
<system:String x:Key="HotkeyLeftRightDesc">Item Navigation</system:String>
<system:String x:Key="HotkeyShiftEnterDesc">Open Context Menu</system:String>
<system:String x:Key="HotkeyCtrlEnterDesc">Open Containing Folder</system:String>
<system:String x:Key="HotkeyCtrlShiftEnterDesc">Run as Admin / Open Folder in Default File Manager</system:String>
<system:String x:Key="HotkeyCtrlHDesc">Query History</system:String>
<system:String x:Key="HotkeyESCDesc">Back to Result in Context Menu</system:String>
<system:String x:Key="HotkeyTabDesc">Autocomplete</system:String>
<system:String x:Key="HotkeyRunDesc">Open / Run Selected Item</system:String>
<system:String x:Key="HotkeyCtrlIDesc">Open Setting Window</system:String>
<system:String x:Key="HotkeyF5Desc">Reload Plugin Data</system:String>
<system:String x:Key="HotkeyUpDownDesc">חזור / תפריט הקשר</system:String>
<system:String x:Key="HotkeyLeftRightDesc">ניווט בין פריטים</system:String>
<system:String x:Key="HotkeyShiftEnterDesc">פתח תפריט הקשר</system:String>
<system:String x:Key="HotkeyCtrlEnterDesc">פתח תיקייה מכילה</system:String>
<system:String x:Key="HotkeyCtrlShiftEnterDesc">הפעל כמנהל / פתח תיקייה במנהל הקבצים ברירת מחדל</system:String>
<system:String x:Key="HotkeyCtrlHDesc">היסטוריית שאילתות</system:String>
<system:String x:Key="HotkeyESCDesc">חזור לתוצאה בתפריט הקשר</system:String>
<system:String x:Key="HotkeyTabDesc">השלמה אוטומטית</system:String>
<system:String x:Key="HotkeyRunDesc">פתח / הפעל פריט נבחר</system:String>
<system:String x:Key="HotkeyCtrlIDesc">פתח חלון הגדרות</system:String>
<system:String x:Key="HotkeyF5Desc">טען מחדש נתוני תוסף</system:String>
<system:String x:Key="HotkeySelectFirstResult">Select first result</system:String>
<system:String x:Key="HotkeySelectLastResult">Select last result</system:String>
<system:String x:Key="HotkeyRequery">Run current query again</system:String>
<system:String x:Key="HotkeyOpenResult">Open result</system:String>
<system:String x:Key="HotkeyOpenResultN">Open result #{0}</system:String>
<system:String x:Key="HotkeySelectFirstResult">בחר בתוצאה הראשונה</system:String>
<system:String x:Key="HotkeySelectLastResult">בחר בתוצאה האחרונה</system:String>
<system:String x:Key="HotkeyRequery">הפעל מחדש את השאילתה הנוכחית</system:String>
<system:String x:Key="HotkeyOpenResult">פתח תוצאה</system:String>
<system:String x:Key="HotkeyOpenResultN">פתח תוצאה #{0}</system:String>
<system:String x:Key="RecommendWeather">Weather</system:String>
<system:String x:Key="RecommendWeatherDesc">Weather in Google Result</system:String>
<system:String x:Key="RecommendWeather">מזג אוויר</system:String>
<system:String x:Key="RecommendWeatherDesc">מזג אוויר מתוצאות Google</system:String>
<system:String x:Key="RecommendShell">&gt; ping 8.8.8.8</system:String>
<system:String x:Key="RecommendShellDesc">Shell Command</system:String>
<system:String x:Key="RecommendShellDesc">פקודת Shell</system:String>
<system:String x:Key="RecommendBluetooth">s Bluetooth</system:String>
<system:String x:Key="RecommendBluetoothDesc">Bluetooth in Windows Settings</system:String>
<system:String x:Key="RecommendBluetoothDesc">Bluetooth בהגדרות Windows</system:String>
<system:String x:Key="RecommendAcronyms">sn</system:String>
<system:String x:Key="RecommendAcronymsDesc">Sticky Notes</system:String>
<system:String x:Key="RecommendAcronymsDesc">פתקים נדבקים</system:String>
<!-- Preview Area -->
<system:String x:Key="FileSize">File Size</system:String>
<system:String x:Key="Created">Created</system:String>
<system:String x:Key="LastModified">Last Modified</system:String>
<system:String x:Key="FileSize">גודל קובץ</system:String>
<system:String x:Key="Created">נוצר</system:String>
<system:String x:Key="LastModified">תאריך שינוי אחרון</system:String>
</ResourceDictionary>

View file

@ -13,6 +13,7 @@
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">Registrazione del tasto di scelta rapida &quot;{0}&quot; non riuscita. Il tasto di scelta rapida potrebbe essere in uso da un altro programma. Passa a un altro tasto di scelta rapida o esci da un altro programma.</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="MessageBoxTitle">Flow Launcher</system:String>
<system:String x:Key="couldnotStartCmd">Avvio fallito {0}</system:String>
<system:String x:Key="invalidFlowLauncherPluginFileFormat">Formato file plugin non valido</system:String>
@ -44,6 +45,8 @@
<system:String x:Key="portableMode">Modalità portatile</system:String>
<system:String x:Key="portableModeToolTIp">Memorizzare tutte le impostazioni e i dati dell'utente in un'unica cartella (utile se utilizzato con unità rimovibili o servizi cloud).</system:String>
<system:String x:Key="startFlowLauncherOnSystemStartup">Avvia Wow all'avvio di Windows</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="setAutoStartFailed">Errore nell'impostazione del lancio all'avvio</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">Nascondi Flow Launcher quando perde il focus</system:String>
<system:String x:Key="dontPromptUpdateMsg">Non mostrare le notifiche per una nuova versione</system:String>
@ -126,7 +129,8 @@
<system:String x:Key="plugin_query_version">Versione</system:String>
<system:String x:Key="plugin_query_web">Sito Web</system:String>
<system:String x:Key="plugin_uninstall">Disinstalla</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>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">Negozio dei Plugin</system:String>
@ -143,8 +147,6 @@
<system:String x:Key="LabelNewToolTip">Questo plugin è stato aggiornato negli ultimi 7 giorni</system:String>
<system:String x:Key="LabelUpdateToolTip">Nuovo aggiornamento disponibile</system:String>
<!-- Setting Theme -->
<system:String x:Key="theme">Tema</system:String>
<system:String x:Key="appearance">Aspetto</system:String>
@ -194,7 +196,6 @@
<system:String x:Key="TypeIsDarkToolTip">Questo tema supporta due (chiaro/scuro) varianti.</system:String>
<system:String x:Key="TypeHasBlurToolTip">Questo tema supporta lo sfondo trasparente blurrato.</system:String>
<!-- Setting Hotkey -->
<system:String x:Key="hotkey">Tasti scelta rapida</system:String>
<system:String x:Key="hotkeys">Tasti scelta rapida</system:String>
@ -297,6 +298,9 @@
<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="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">Seleziona Gestore File</system:String>
@ -367,6 +371,7 @@ Se si aggiunge un prefisso '@' mentre si inserisce una scorciatoia, corrisponde
<system:String x:Key="commonOK">OK</system:String>
<system:String x:Key="commonYes">Sì</system:String>
<system:String x:Key="commonNo">No</system:String>
<system:String x:Key="commonBackground">Sfondo</system:String>
<!-- Crash Reporter -->
<system:String x:Key="reportWindow_version">Versione</system:String>
@ -383,6 +388,9 @@ Se si aggiunge un prefisso '@' mentre si inserisce una scorciatoia, corrisponde
<system:String x:Key="reportWindow_report_succeed">Rapporto inviato correttamente</system:String>
<system:String x:Key="reportWindow_report_failed">Invio rapporto fallito</system:String>
<system:String x:Key="reportWindow_flowlauncher_got_an_error">Flow Launcher ha riportato un errore</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>
<!-- General Notice -->
<system:String x:Key="pleaseWait">Attendere prego...</system:String>

View file

@ -13,6 +13,7 @@
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">ホットキー &quot;{0}&quot; の登録に失敗しました。このホットキーは別のプログラムで使用されている可能性があります。別のホットキーに変更するか、このホットキーを使用しているプログラムを終了してください。</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="MessageBoxTitle">Flow Launcher</system:String>
<system:String x:Key="couldnotStartCmd">{0}の起動に失敗しました</system:String>
<system:String x:Key="invalidFlowLauncherPluginFileFormat">Flow Launcherプラグインの形式が正しくありません</system:String>
@ -44,6 +45,8 @@
<system:String x:Key="portableMode">ポータブルモード</system:String>
<system:String x:Key="portableModeToolTIp">すべての設定とユーザーデータを1つのフォルダに保存します(リムーバブルドライブやクラウドサービスで使用する場合に便利です)。</system:String>
<system:String x:Key="startFlowLauncherOnSystemStartup">スタートアップ時にFlow Launcherを起動する</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="setAutoStartFailed">Error setting launch on startup</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">フォーカスを失った時にFlow Launcherを隠す</system:String>
<system:String x:Key="dontPromptUpdateMsg">最新版が入手可能であっても、アップグレードメッセージを表示しない</system:String>
@ -126,7 +129,8 @@
<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>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">プラグインストア</system:String>
@ -143,8 +147,6 @@
<system:String x:Key="LabelNewToolTip">This plugin has been updated within the last 7 days</system:String>
<system:String x:Key="LabelUpdateToolTip">新しいアップデートが利用可能です</system:String>
<!-- Setting Theme -->
<system:String x:Key="theme">テーマ</system:String>
<system:String x:Key="appearance">外観</system:String>
@ -194,7 +196,6 @@
<system:String x:Key="TypeIsDarkToolTip">This theme supports two(light/dark) modes.</system:String>
<system:String x:Key="TypeHasBlurToolTip">This theme supports Blur Transparent Background.</system:String>
<!-- Setting Hotkey -->
<system:String x:Key="hotkey">ホットキー</system:String>
<system:String x:Key="hotkeys">ホットキー</system:String>
@ -297,6 +298,9 @@
<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="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">Select File Manager</system:String>
@ -367,6 +371,7 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
<system:String x:Key="commonOK">Update</system:String>
<system:String x:Key="commonYes">Yes</system:String>
<system:String x:Key="commonNo">No</system:String>
<system:String x:Key="commonBackground">バックグラウンド</system:String>
<!-- Crash Reporter -->
<system:String x:Key="reportWindow_version">バージョン</system:String>
@ -383,6 +388,9 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
<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>
<!-- General Notice -->
<system:String x:Key="pleaseWait">Please wait...</system:String>

View file

@ -13,6 +13,7 @@
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">Failed to register hotkey &quot;{0}&quot;. The hotkey may be in use by another program. Change to a different hotkey, or exit another program.</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="MessageBoxTitle">Flow Launcher</system:String>
<system:String x:Key="couldnotStartCmd">{0}을 실행할 수 없습니다.</system:String>
<system:String x:Key="invalidFlowLauncherPluginFileFormat">Flow Launcher 플러그인 파일 형식이 유효하지 않습니다.</system:String>
@ -44,6 +45,8 @@
<system:String x:Key="portableMode">포터블 모드</system:String>
<system:String x:Key="portableModeToolTIp">모든 설정이 폴더안에 들어갑니다. USB 드라이브나 클라우드로 사용 가능합니다.</system:String>
<system:String x:Key="startFlowLauncherOnSystemStartup">시스템 시작 시 Flow Launcher 실행</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="setAutoStartFailed">Error setting launch on startup</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">포커스 잃으면 Flow Launcher 숨김</system:String>
<system:String x:Key="dontPromptUpdateMsg">새 버전 알림 끄기</system:String>
@ -126,7 +129,8 @@
<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>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">플러그인 스토어</system:String>
@ -143,8 +147,6 @@
<system:String x:Key="LabelNewToolTip">이 플러그인은 최근 7일 사이 업데이트 되었습니다</system:String>
<system:String x:Key="LabelUpdateToolTip">새 업데이트 설치 가능</system:String>
<!-- Setting Theme -->
<system:String x:Key="theme">테마</system:String>
<system:String x:Key="appearance">외관</system:String>
@ -194,7 +196,6 @@
<system:String x:Key="TypeIsDarkToolTip">This theme supports two(light/dark) modes.</system:String>
<system:String x:Key="TypeHasBlurToolTip">This theme supports Blur Transparent Background.</system:String>
<!-- Setting Hotkey -->
<system:String x:Key="hotkey">단축키</system:String>
<system:String x:Key="hotkeys">단축키</system:String>
@ -297,6 +298,9 @@
<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>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">파일관리자 선택</system:String>
@ -367,6 +371,7 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
<system:String x:Key="commonOK">확인</system:String>
<system:String x:Key="commonYes">Yes</system:String>
<system:String x:Key="commonNo">No</system:String>
<system:String x:Key="commonBackground">배경</system:String>
<!-- Crash Reporter -->
<system:String x:Key="reportWindow_version">버전</system:String>
@ -383,6 +388,9 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
<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>
<!-- General Notice -->
<system:String x:Key="pleaseWait">잠시 기다려주세요...</system:String>

View file

@ -13,6 +13,7 @@
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">Kan ikke registrere hurtigtasten &quot;{0}&quot;. Hurtigtasten kan være i bruk av et annet program. Endre til en annen hurtigtast, eller avslutt et annet program.</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="MessageBoxTitle">Flow Launcher</system:String>
<system:String x:Key="couldnotStartCmd">Kunne ikke starte {0}</system:String>
<system:String x:Key="invalidFlowLauncherPluginFileFormat">Ugyldig Flow Launcher programtillegg filformat</system:String>
@ -44,6 +45,8 @@
<system:String x:Key="portableMode">Portabel modus</system:String>
<system:String x:Key="portableModeToolTIp">Lagre alle innstillinger og brukerdata i en mappe (nyttig når man bruker flyttbare stasjoner eller skytjenester).</system:String>
<system:String x:Key="startFlowLauncherOnSystemStartup">Start Flow Launcher ved systemoppstart</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="setAutoStartFailed">Feil ved å sette kjør ved oppstart</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">Skjul Flow Launcher når fokus forsvinner</system:String>
<system:String x:Key="dontPromptUpdateMsg">Ikke vis varsler om nye versjoner</system:String>
@ -126,7 +129,8 @@
<system:String x:Key="plugin_query_version">Versjon</system:String>
<system:String x:Key="plugin_query_web">Nettsted</system:String>
<system:String x:Key="plugin_uninstall">Avinstaller</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>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">Programtillegg butikk</system:String>
@ -143,8 +147,6 @@
<system:String x:Key="LabelNewToolTip">Dette programtillegget er oppdatert i løpet av de siste 7 dagene</system:String>
<system:String x:Key="LabelUpdateToolTip">Ny oppdatering er tilgjengelig</system:String>
<!-- Setting Theme -->
<system:String x:Key="theme">Drakt</system:String>
<system:String x:Key="appearance">Utseende</system:String>
@ -194,7 +196,6 @@
<system:String x:Key="TypeIsDarkToolTip">Dette temaet støtter to (lys/mørk) moduser.</system:String>
<system:String x:Key="TypeHasBlurToolTip">Dette temaet støtter uskarp gjennomsiktig bakgrunn.</system:String>
<!-- Setting Hotkey -->
<system:String x:Key="hotkey">Hurtigtast</system:String>
<system:String x:Key="hotkeys">Hurtigtaster</system:String>
@ -297,6 +298,9 @@
<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="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">Velg filbehandler</system:String>
@ -367,6 +371,7 @@ Hvis du legger til et @-prefiks mens du legger inn en snarvei, samsvarer det med
<system:String x:Key="commonOK">OK</system:String>
<system:String x:Key="commonYes">Ja</system:String>
<system:String x:Key="commonNo">Nei</system:String>
<system:String x:Key="commonBackground">Bakgrunn</system:String>
<!-- Crash Reporter -->
<system:String x:Key="reportWindow_version">Versjon</system:String>
@ -383,6 +388,9 @@ Hvis du legger til et @-prefiks mens du legger inn en snarvei, samsvarer det med
<system:String x:Key="reportWindow_report_succeed">Rapporten ble sendt</system:String>
<system:String x:Key="reportWindow_report_failed">Kunne ikke sende rapport</system:String>
<system:String x:Key="reportWindow_flowlauncher_got_an_error">Flow Launcher fikk en feil</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>
<!-- General Notice -->
<system:String x:Key="pleaseWait">Vennligst vent...</system:String>

View file

@ -13,6 +13,7 @@
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">Sneltoets &quot;{0}&quot; registreren. De sneltoets kan in gebruik zijn door een ander programma. Verander naar een andere sneltoets of sluit een ander programma.</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="MessageBoxTitle">Flow Launcher</system:String>
<system:String x:Key="couldnotStartCmd">Kan {0} niet starten</system:String>
<system:String x:Key="invalidFlowLauncherPluginFileFormat">Ongeldige Flow Launcher plugin bestandsextensie</system:String>
@ -44,6 +45,8 @@
<system:String x:Key="portableMode">Draagbare Modus</system:String>
<system:String x:Key="portableModeToolTIp">Alle instellingen en gebruikersgegevens opslaan in één map (Nuttig bij het gebruik van verwijderbare schijven of cloud services).</system:String>
<system:String x:Key="startFlowLauncherOnSystemStartup">Start Flow Launcher als systeem opstart</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="setAutoStartFailed">Fout bij het instellen van uitvoeren bij opstarten</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">Verberg Flow Launcher als focus verloren is</system:String>
<system:String x:Key="dontPromptUpdateMsg">Laat geen nieuwe versie notificaties zien</system:String>
@ -126,7 +129,8 @@
<system:String x:Key="plugin_query_version">Versie</system:String>
<system:String x:Key="plugin_query_web">Website</system:String>
<system:String x:Key="plugin_uninstall">Verwijderen</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>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">Plugin Winkel</system:String>
@ -143,8 +147,6 @@
<system:String x:Key="LabelNewToolTip">Deze plug-in is in de laatste 7 dagen bijgewerkt</system:String>
<system:String x:Key="LabelUpdateToolTip">Nieuwe update beschikbaar</system:String>
<!-- Setting Theme -->
<system:String x:Key="theme">Thema</system:String>
<system:String x:Key="appearance">Uiterlijk</system:String>
@ -194,7 +196,6 @@
<system:String x:Key="TypeIsDarkToolTip">Dit thema ondersteunt twee (licht/donker) modi.</system:String>
<system:String x:Key="TypeHasBlurToolTip">This theme supports Blur Transparent Background.</system:String>
<!-- Setting Hotkey -->
<system:String x:Key="hotkey">Sneltoets</system:String>
<system:String x:Key="hotkeys">Sneltoets</system:String>
@ -297,6 +298,9 @@
<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="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">Bestandsbeheerder selecteren</system:String>
@ -367,6 +371,7 @@ Als u een '@' voorvoegsel toevoegt tijdens het invoeren van een snelkoppeling, m
<system:String x:Key="commonOK">OK</system:String>
<system:String x:Key="commonYes">Yes</system:String>
<system:String x:Key="commonNo">No</system:String>
<system:String x:Key="commonBackground">Background</system:String>
<!-- Crash Reporter -->
<system:String x:Key="reportWindow_version">Versie</system:String>
@ -383,6 +388,9 @@ Als u een '@' voorvoegsel toevoegt tijdens het invoeren van een snelkoppeling, m
<system:String x:Key="reportWindow_report_succeed">Rapport succesvol verzonden</system:String>
<system:String x:Key="reportWindow_report_failed">Verzenden van rapport mislukt</system:String>
<system:String x:Key="reportWindow_flowlauncher_got_an_error">Flow Launcher heeft een error</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>
<!-- General Notice -->
<system:String x:Key="pleaseWait">Please wait...</system:String>

View file

@ -6,13 +6,14 @@
{2}{2}
Kliknij &quot;nie&quot;, jeśli jest już zainstalowany. Zostaniesz wtedy poproszony o wybranie folderu zawierającego plik wykonywalny {1}
</system:String>
<system:String x:Key="runtimePluginChooseRuntimeExecutable">Proszę wybrać plik wykonywalny {0}</system:String>
<system:String x:Key="runtimePluginUnableToSetExecutablePath">Nie można ustawić ścieżki pliku wykonywalnego {0}, proszę spróbować z poziomu ustawień Flow (przewiń na dół strony).</system:String>
<system:String x:Key="runtimePluginChooseRuntimeExecutable">Wybierz plik wykonywalny {0}</system:String>
<system:String x:Key="runtimePluginUnableToSetExecutablePath">Nie można ustawić ścieżki do pliku wykonywalnego {0}. Spróbuj ponownie w ustawieniach Flow (przewiń na sam dół).</system:String>
<system:String x:Key="failedToInitializePluginsTitle">Nie udało się zainicjować wtyczek</system:String>
<system:String x:Key="failedToInitializePluginsMessage">Wtyczki: {0} - nie udało się załadować i zostaną wyłączone, proszę skontaktować się z twórcą wtyczki w celu uzyskania pomocy</system:String>
<system:String x:Key="failedToInitializePluginsMessage">Wtyczki: {0} nie udało się ich wczytać i zostaną wyłączone. Skontaktuj się z twórcą wtyczki, aby uzyskać pomoc</system:String>
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">Nie udało się zarejestrować skrótu klawiszowego &quot;{0}&quot;. Klucz skrótu może być używany przez inny program. Zmień skrót klawiszowy lub wyjdź z innego programu.</system:String>
<system:String x:Key="registerHotkeyFailed">Nie udało się zarejestrować skrótu klawiszowego „{0}”. Skrót może być używany przez inny program. Zmień skrót na inny lub zamknij program, który go używa.</system:String>
<system:String x:Key="unregisterHotkeyFailed">Nie udało się wyrejestrować skrótu „{0}”. Spróbuj ponownie lub sprawdź szczegóły w dzienniku</system:String>
<system:String x:Key="MessageBoxTitle">Flow Launcher</system:String>
<system:String x:Key="couldnotStartCmd">Nie udało się uruchomić: {0}</system:String>
<system:String x:Key="invalidFlowLauncherPluginFileFormat">Niepoprawny format pliku wtyczki</system:String>
@ -44,6 +45,8 @@ Kliknij &quot;nie&quot;, jeśli jest już zainstalowany. Zostaniesz wtedy popros
<system:String x:Key="portableMode">Tryb przenośny</system:String>
<system:String x:Key="portableModeToolTIp">Przechowuj wszystkie ustawienia i dane użytkownika w jednym folderze (Przydatne, gdy używane na dyskach wymiennych lub usługach chmurowych).</system:String>
<system:String x:Key="startFlowLauncherOnSystemStartup">Uruchamiaj Flow Launcher przy starcie systemu</system:String>
<system:String x:Key="useLogonTaskForStartup">Użyj zadania logowania zamiast wpisu autostartu, aby przyspieszyć uruchamianie</system:String>
<system:String x:Key="useLogonTaskForStartupTooltip">Po odinstalowaniu musisz ręcznie usunąć to zadanie (Flow.Launcher Startup) za pomocą Harmonogramu zadań</system:String>
<system:String x:Key="setAutoStartFailed">Błąd uruchamiania ustawień przy starcie</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">Ukryj okno Flow Launcher kiedy przestanie ono być aktywne</system:String>
<system:String x:Key="dontPromptUpdateMsg">Nie pokazuj powiadomienia o nowej wersji</system:String>
@ -65,8 +68,8 @@ Kliknij &quot;nie&quot;, jeśli jest już zainstalowany. Zostaniesz wtedy popros
<system:String x:Key="LastQueryPreserved">Zachowaj ostatnie zapytanie</system:String>
<system:String x:Key="LastQuerySelected">Wybierz ostatnie zapytanie</system:String>
<system:String x:Key="LastQueryEmpty">Puste ostatnie zapytanie</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">Zachowaj ostatnie słowo kluczowe akcji</system:String>
<system:String x:Key="LastQueryActionKeywordSelected">Wybierz ostatnie słowo kluczowe akcji</system:String>
<system:String x:Key="KeepMaxResults">Stała wysokość okna</system:String>
<system:String x:Key="KeepMaxResultsToolTip">Wysokość okna nie jest regulowana poprzez przeciąganie.</system:String>
<system:String x:Key="maxShowResults">Maksymalna liczba wyników</system:String>
@ -126,7 +129,8 @@ Kliknij &quot;nie&quot;, jeśli jest już zainstalowany. Zostaniesz wtedy popros
<system:String x:Key="plugin_query_version">Wersja</system:String>
<system:String x:Key="plugin_query_web">Strona</system:String>
<system:String x:Key="plugin_uninstall">Odinstalowywanie</system:String>
<system:String x:Key="failedToRemovePluginSettingsTitle">Nie udało się usunąć ustawień wtyczki</system:String>
<system:String x:Key="failedToRemovePluginSettingsMessage">Wtyczki: {0} nie udało się usunąć plików ustawień wtyczek, usuń je ręcznie</system:String>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">Sklep z wtyczkami</system:String>
@ -143,8 +147,6 @@ Kliknij &quot;nie&quot;, jeśli jest już zainstalowany. Zostaniesz wtedy popros
<system:String x:Key="LabelNewToolTip">Ta wtyczka została zaktualizowana w ciągu ostatnich 7 dni</system:String>
<system:String x:Key="LabelUpdateToolTip">Dostępna jest nowa aktualizacja</system:String>
<!-- Setting Theme -->
<system:String x:Key="theme">Skórka</system:String>
<system:String x:Key="appearance">Wygląd</system:String>
@ -194,7 +196,6 @@ Kliknij &quot;nie&quot;, jeśli jest już zainstalowany. Zostaniesz wtedy popros
<system:String x:Key="TypeIsDarkToolTip">Ten motyw obsługuje dwa tryby (jasny/ciemny).</system:String>
<system:String x:Key="TypeHasBlurToolTip">Ten motyw obsługuje rozmyte przezroczyste tło.</system:String>
<!-- Setting Hotkey -->
<system:String x:Key="hotkey">Skrót klawiszowy</system:String>
<system:String x:Key="hotkeys">Skrót klawiszowy</system:String>
@ -297,6 +298,9 @@ 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="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">Wybierz menedżer plików</system:String>
@ -367,6 +371,7 @@ Jeśli dodasz prefiks '@' podczas wprowadzania skrótu, będzie on pasował do d
<system:String x:Key="commonOK">Aktualizuj</system:String>
<system:String x:Key="commonYes">Tak</system:String>
<system:String x:Key="commonNo">Nie</system:String>
<system:String x:Key="commonBackground">Tło</system:String>
<!-- Crash Reporter -->
<system:String x:Key="reportWindow_version">Wersja</system:String>
@ -383,6 +388,9 @@ Jeśli dodasz prefiks '@' podczas wprowadzania skrótu, będzie on pasował do d
<system:String x:Key="reportWindow_report_succeed">Raport wysłany pomyślnie</system:String>
<system:String x:Key="reportWindow_report_failed">Nie udało się wysłać raportu</system:String>
<system:String x:Key="reportWindow_flowlauncher_got_an_error">W programie Flow Launcher wystąpił błąd</system:String>
<system:String x:Key="reportWindow_please_open_issue">Otwórz nowe zgłoszenie w</system:String>
<system:String x:Key="reportWindow_upload_log">1. Prześlij plik dziennika: {0}</system:String>
<system:String x:Key="reportWindow_copy_below">2. Skopiuj poniższą wiadomość wyjątku</system:String>
<!-- General Notice -->
<system:String x:Key="pleaseWait">Proszę czekać...</system:String>
@ -413,8 +421,8 @@ Jeśli dodasz prefiks '@' podczas wprowadzania skrótu, będzie on pasował do d
<system:String x:Key="Welcome_Page1_Title">Witamy w Flow Launcher</system:String>
<system:String x:Key="Welcome_Page1_Text01">Witaj, po raz pierwszy uruchamiasz Flow Launcher!</system:String>
<system:String x:Key="Welcome_Page1_Text02">Przed rozpoczęciem ten kreator pomoże skonfigurować Flow Launcher. Jeśli chcesz, możesz to pominąć. Proszę wybierz język</system:String>
<system:String x:Key="Welcome_Page2_Title">Wyszukiwanie i uruchamianie wszystkich plików i aplikacji na PC</system:String>
<system:String x:Key="Welcome_Page2_Text01">Przeszukuj wszystko, od aplikacji, plików, zakładek, YouTube, X i nie tylko. Wszystko to z komfortowej klawiatury, bez konieczności dotykania myszy.</system:String>
<system:String x:Key="Welcome_Page2_Title">Wyszukuj i uruchamiaj pliki oraz aplikacje na komputerze</system:String>
<system:String x:Key="Welcome_Page2_Text01">Wyszukuj wszystko aplikacje, pliki, zakładki, YouTube, Twitter i nie tylko. Wszystko wygodnie z klawiatury, bez używania myszy.</system:String>
<system:String x:Key="Welcome_Page2_Text02">Flow Launcher uruchamia się za pomocą poniższego skrótu klawiszowego, śmiało i wypróbuj go teraz. Aby to zmienić, kliknij dane wejściowe i naciśnij żądany klawisz skrótu na klawiaturze.</system:String>
<system:String x:Key="Welcome_Page3_Title">Skróty klawiszowe</system:String>
<system:String x:Key="Welcome_Page4_Title">Słowo kluczowe akcji i polecenia</system:String>
@ -425,7 +433,7 @@ Jeśli dodasz prefiks '@' podczas wprowadzania skrótu, będzie on pasował do d
<!-- General Guide & Hotkey -->
<system:String x:Key="HotkeyUpDownDesc">Powrót / Menu kontekstowe</system:String>
<system:String x:Key="HotkeyLeftRightDesc">Nawigacja pozycji</system:String>
<system:String x:Key="HotkeyLeftRightDesc">Nawigacja po elementach</system:String>
<system:String x:Key="HotkeyShiftEnterDesc">Otwórz menu kontekstowe</system:String>
<system:String x:Key="HotkeyCtrlEnterDesc">Otwórz folder zawierający</system:String>
<system:String x:Key="HotkeyCtrlShiftEnterDesc">Uruchom jako administrator / Otwórz folder w domyślnym menedżerze plików</system:String>

View file

@ -13,6 +13,7 @@
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">Falha em registrar a tecla de atalho &quot;{0}&quot;. A combinação pode estar em uso por outro programa. Mude para uma tecla de atalho diferente, ou encerre o outro programa.</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="MessageBoxTitle">Flow Launcher</system:String>
<system:String x:Key="couldnotStartCmd">Não foi possível iniciar {0}</system:String>
<system:String x:Key="invalidFlowLauncherPluginFileFormat">Formato de plugin Flow Launcher inválido</system:String>
@ -44,6 +45,8 @@
<system:String x:Key="portableMode">Modo Portátil</system:String>
<system:String x:Key="portableModeToolTIp">Armazene todas as configurações e dados do usuário em uma pasta (útil quando usado com unidades removíveis ou serviços em nuvem).</system:String>
<system:String x:Key="startFlowLauncherOnSystemStartup">Iniciar Flow Launcher com inicialização do sistema</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="setAutoStartFailed">Erro ao ativar início com o sistema</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">Esconder Flow Launcher quando foco for perdido</system:String>
<system:String x:Key="dontPromptUpdateMsg">Não mostrar notificações de novas versões</system:String>
@ -126,7 +129,8 @@
<system:String x:Key="plugin_query_version">Versão</system:String>
<system:String x:Key="plugin_query_web">Site</system:String>
<system:String x:Key="plugin_uninstall">Desinstalar</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>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">Loja de Plugins</system:String>
@ -143,8 +147,6 @@
<system:String x:Key="LabelNewToolTip">Este plugin foi atualizado nos últimos 7 dias</system:String>
<system:String x:Key="LabelUpdateToolTip">Nova Atualização Disponível</system:String>
<!-- Setting Theme -->
<system:String x:Key="theme">Tema</system:String>
<system:String x:Key="appearance">Aparência</system:String>
@ -194,7 +196,6 @@
<system:String x:Key="TypeIsDarkToolTip">This theme supports two(light/dark) modes.</system:String>
<system:String x:Key="TypeHasBlurToolTip">This theme supports Blur Transparent Background.</system:String>
<!-- Setting Hotkey -->
<system:String x:Key="hotkey">Atalho</system:String>
<system:String x:Key="hotkeys">Atalho</system:String>
@ -297,6 +298,9 @@
<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="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">Selecione o Gerenciador de Arquivos</system:String>
@ -367,6 +371,7 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
<system:String x:Key="commonOK">OK</system:String>
<system:String x:Key="commonYes">Yes</system:String>
<system:String x:Key="commonNo">No</system:String>
<system:String x:Key="commonBackground">Plano de fundo</system:String>
<!-- Crash Reporter -->
<system:String x:Key="reportWindow_version">Versão</system:String>
@ -383,6 +388,9 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
<system:String x:Key="reportWindow_report_succeed">Relatório enviado com sucesso</system:String>
<system:String x:Key="reportWindow_report_failed">Falha ao enviar relatório</system:String>
<system:String x:Key="reportWindow_flowlauncher_got_an_error">Flow Launcher apresentou um erro</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>
<!-- General Notice -->
<system:String x:Key="pleaseWait">Por favor, aguarde...</system:String>

View file

@ -2,17 +2,18 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:system="clr-namespace:System;assembly=mscorlib">
<!-- Startup -->
<system:String x:Key="runtimePluginInstalledChooseRuntimePrompt">
Flow Launcher detetou que tem instalados {0} plugins e que necessitam de {1} para serem executados. Gostaria de descarregar {1}?
{2}{2}
Clique &quot;Não&quot; se já tiver instalado e, de seguida, ser-lhe-á solicitada a pasta que contém o executável {1}.
Flow Launcher detetou que tem instalou os plugins {0}, que necessitam de {1} para serem executados. Gostaria de descarregar {1}?
{2}{2}
Clique &quot;Não&quot; se já tiver instalado e, de seguida, ser-lhe-á solicitada a pasta que contém o executável {1}.
</system:String>
<system:String x:Key="runtimePluginChooseRuntimeExecutable">Por favor, selecione o executável {0}</system:String>
<system:String x:Key="runtimePluginUnableToSetExecutablePath">Não foi possível definir o caminho do executável {0}. Experimente definir o caminho nas definições (desloque até ao fundo).</system:String>
<system:String x:Key="failedToInitializePluginsTitle">Falha ao iniciar os plugins</system:String>
<system:String x:Key="failedToInitializePluginsMessage">Plugins: {0} - não foi possível iniciar e serão desativados. Contacte o criador dos plugin para obter ajuda.</system:String>
<system:String x:Key="failedToInitializePluginsMessage">Plugin: {0} - não foi possível iniciar e será desativado. Contacte o criador do plugin para obter ajuda.</system:String>
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">Falha ao registar a tecla de atalho &quot;{0}&quot;. A tecla de atalho pode estar a ser usada por outra aplicação. Utilize uma tecla de atalho diferente ou feche o outro programa.</system:String>
<system:String x:Key="unregisterHotkeyFailed">Falha ao cancelar a atribuição da tecla de atalho &quot;{0}&quot;. Tente novamente ou consulte o registo para mais detalhes.</system:String>
<system:String x:Key="MessageBoxTitle">Flow Launcher</system:String>
<system:String x:Key="couldnotStartCmd">Não foi possível iniciar {0}</system:String>
<system:String x:Key="invalidFlowLauncherPluginFileFormat">Formato do ficheiro inválido como plugin</system:String>
@ -44,6 +45,8 @@ Clique &quot;Não&quot; se já tiver instalado e, de seguida, ser-lhe-á solicit
<system:String x:Key="portableMode">Modo portátil</system:String>
<system:String x:Key="portableModeToolTIp">Guardar todas as definições e dados do utilizador numa pasta (indicado se utilizar discos amovíveis ou serviços cloud)</system:String>
<system:String x:Key="startFlowLauncherOnSystemStartup">Iniciar Flow Launcher ao arrancar o sistema</system:String>
<system:String x:Key="useLogonTaskForStartup">Utilizar tarefa de arranque em vez de uma entrada de arranque para uma experiência mais rápida</system:String>
<system:String x:Key="useLogonTaskForStartupTooltip">Se desinstalar a aplicação, tem que remover manualmente a tarefa (Flow.Launcher Startup) no agendamento de tarefas</system:String>
<system:String x:Key="setAutoStartFailed">Erro ao definir para iniciar ao arrancar</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">Ocultar Flow Launcher ao perder o foco</system:String>
<system:String x:Key="dontPromptUpdateMsg">Não notificar acerca de novas versões</system:String>
@ -126,7 +129,8 @@ Clique &quot;Não&quot; se já tiver instalado e, de seguida, ser-lhe-á solicit
<system:String x:Key="plugin_query_version">Versão</system:String>
<system:String x:Key="plugin_query_web">Site</system:String>
<system:String x:Key="plugin_uninstall">Desinstalar</system:String>
<system:String x:Key="failedToRemovePluginSettingsTitle">Falha ao remover as definições do plugin</system:String>
<system:String x:Key="failedToRemovePluginSettingsMessage">Plugin: {0} - Falha ao remover o ficheiro de definições do plugin. Experimente remover manualmente.</system:String>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">Loja de plugins</system:String>
@ -143,8 +147,6 @@ Clique &quot;Não&quot; se já tiver instalado e, de seguida, ser-lhe-á solicit
<system:String x:Key="LabelNewToolTip">Este plugin foi atualizado nos últimos 7 dias</system:String>
<system:String x:Key="LabelUpdateToolTip">Atualização disponível</system:String>
<!-- Setting Theme -->
<system:String x:Key="theme">Tema</system:String>
<system:String x:Key="appearance">Aparência</system:String>
@ -194,7 +196,6 @@ Clique &quot;Não&quot; se já tiver instalado e, de seguida, ser-lhe-á solicit
<system:String x:Key="TypeIsDarkToolTip">Este tema tem suporte a dois modos (claro/escuro).</system:String>
<system:String x:Key="TypeHasBlurToolTip">Este tema tem suporte a fundo transparente desfocado.</system:String>
<!-- Setting Hotkey -->
<system:String x:Key="hotkey">Tecla de atalho</system:String>
<system:String x:Key="hotkeys">Teclas de atalho</system:String>
@ -296,6 +297,9 @@ Clique &quot;Não&quot; se já tiver instalado e, de seguida, ser-lhe-á solicit
<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="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">Selecione o gestor de ficheiros</system:String>
@ -366,6 +370,7 @@ Se adicionar o prefixo '@' durante a introdução do atalho, será utilizada qua
<system:String x:Key="commonOK">OK</system:String>
<system:String x:Key="commonYes">Sim</system:String>
<system:String x:Key="commonNo">Não</system:String>
<system:String x:Key="commonBackground">Fundo</system:String>
<!-- Crash Reporter -->
<system:String x:Key="reportWindow_version">Versão</system:String>
@ -382,6 +387,9 @@ Se adicionar o prefixo '@' durante a introdução do atalho, será utilizada qua
<system:String x:Key="reportWindow_report_succeed">Relatório enviado com sucesso</system:String>
<system:String x:Key="reportWindow_report_failed">Falha ao enviar o relatório</system:String>
<system:String x:Key="reportWindow_flowlauncher_got_an_error">Ocorreu um erro</system:String>
<system:String x:Key="reportWindow_please_open_issue">Abra um relatório de erro em</system:String>
<system:String x:Key="reportWindow_upload_log">1. Carregue o ficheiro de registos: {0}</system:String>
<system:String x:Key="reportWindow_copy_below">2. Copie a mensagem abaixo</system:String>
<!-- General Notice -->
<system:String x:Key="pleaseWait">Por favor aguarde...</system:String>

View file

@ -13,6 +13,7 @@
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">Не удалось зарегистрировать сочетание клавиш &quot;{0}&quot;. Возможно, оно используется другой программой. Измените сочетание клавиш или закройте другую программу.</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="MessageBoxTitle">Flow Launcher</system:String>
<system:String x:Key="couldnotStartCmd">Не удалось запустить {0}</system:String>
<system:String x:Key="invalidFlowLauncherPluginFileFormat">Недопустимый формат файла плагина Flow Launcher</system:String>
@ -44,6 +45,8 @@
<system:String x:Key="portableMode">Портативный режим</system:String>
<system:String x:Key="portableModeToolTIp">Храните все настройки и данные пользователя в одной папке (полезно при использовании со съёмными дисками или облачными сервисами).</system:String>
<system:String x:Key="startFlowLauncherOnSystemStartup">Запускать Flow Launcher при запуске системы</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="setAutoStartFailed">Ошибка настройки запуска при запуске</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">Скрывать Flow Launcher, если потерян фокуc</system:String>
<system:String x:Key="dontPromptUpdateMsg">Не отображать сообщение об обновлении, когда доступна новая версия</system:String>
@ -126,7 +129,8 @@
<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>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">Магазин плагинов</system:String>
@ -143,8 +147,6 @@
<system:String x:Key="LabelNewToolTip">Этот плагин был обновлён за последние 7 дней</system:String>
<system:String x:Key="LabelUpdateToolTip">Доступно новое обновление</system:String>
<!-- Setting Theme -->
<system:String x:Key="theme">Тема</system:String>
<system:String x:Key="appearance">Внешний вид</system:String>
@ -194,7 +196,6 @@
<system:String x:Key="TypeIsDarkToolTip">This theme supports two(light/dark) modes.</system:String>
<system:String x:Key="TypeHasBlurToolTip">This theme supports Blur Transparent Background.</system:String>
<!-- Setting Hotkey -->
<system:String x:Key="hotkey">Горячая клавиша</system:String>
<system:String x:Key="hotkeys">Горячая клавиша</system:String>
@ -297,6 +298,9 @@
<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="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">Выбор менеджера файлов</system:String>
@ -367,6 +371,7 @@
<system:String x:Key="commonOK">OK</system:String>
<system:String x:Key="commonYes">Yes</system:String>
<system:String x:Key="commonNo">No</system:String>
<system:String x:Key="commonBackground">Фон</system:String>
<!-- Crash Reporter -->
<system:String x:Key="reportWindow_version">Версия</system:String>
@ -383,6 +388,9 @@
<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>
<!-- General Notice -->
<system:String x:Key="pleaseWait">Пожалуйста, подождите...</system:String>

View file

@ -13,6 +13,7 @@
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">Nepodarilo sa zaregistrovať klávesovú skratku &quot;{0}&quot;. Klávesová skratka môže byť používaná iným programom. Zmeňte klávesovú skratku na inú alebo ukončite iný program.</system:String>
<system:String x:Key="unregisterHotkeyFailed">Nepodarilo sa registrovať klávesovú skratku &quot;{0}&quot;. Skúste to znova alebo si pozrite podrobnosti v denníku</system:String>
<system:String x:Key="MessageBoxTitle">Flow Launcher</system:String>
<system:String x:Key="couldnotStartCmd">Nepodarilo sa spustiť {0}</system:String>
<system:String x:Key="invalidFlowLauncherPluginFileFormat">Neplatný formát súboru pre plugin Flow Launchera</system:String>
@ -44,6 +45,8 @@
<system:String x:Key="portableMode">Prenosný režim</system:String>
<system:String x:Key="portableModeToolTIp">Uloží všetky nastavenia a používateľské údaje do jedného priečinka (Užitočné pri vymeniteľných diskoch a cloudových službách).</system:String>
<system:String x:Key="startFlowLauncherOnSystemStartup">Spustiť Flow Launcher pri spustení systému</system:String>
<system:String x:Key="useLogonTaskForStartup">Pre rýchlejšie spustenie použiť úlohu pri prihlásení namiesto položky po spustení</system:String>
<system:String x:Key="useLogonTaskForStartupTooltip">Po odinštalovaní musíte úlohu manuálne odstrániť (Flow.Launcher Startup) cez Plánovač úloh</system:String>
<system:String x:Key="setAutoStartFailed">Chybné nastavenie spustenia pri spustení</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">Schovať Flow Launcher po strate fokusu</system:String>
<system:String x:Key="dontPromptUpdateMsg">Nezobrazovať upozornenia na novú verziu</system:String>
@ -126,7 +129,8 @@
<system:String x:Key="plugin_query_version">Verzia</system:String>
<system:String x:Key="plugin_query_web">Webstránka</system:String>
<system:String x:Key="plugin_uninstall">Odinštalovať</system:String>
<system:String x:Key="failedToRemovePluginSettingsTitle">Nepodarilo sa odstrániť nastavenia pluginu</system:String>
<system:String x:Key="failedToRemovePluginSettingsMessage">Pluginy: {0} Nepodarilo sa odstrániť súbory s nastaveniami pluginu, odstráňte ich manuálne</system:String>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">Repozitár pluginov</system:String>
@ -143,8 +147,6 @@
<system:String x:Key="LabelNewToolTip">Tento plugin bol aktualizovaný za posledných 7 dní</system:String>
<system:String x:Key="LabelUpdateToolTip">K dispozícii je nová aktualizácia</system:String>
<!-- Setting Theme -->
<system:String x:Key="theme">Motív</system:String>
<system:String x:Key="appearance">Vzhľad</system:String>
@ -194,7 +196,6 @@
<system:String x:Key="TypeIsDarkToolTip">Tento motív podporuje 2 režimy (svetlý/tmavý).</system:String>
<system:String x:Key="TypeHasBlurToolTip">Tento motív podporuje rozostrenie priehľadného pozadia.</system:String>
<!-- Setting Hotkey -->
<system:String x:Key="hotkey">Klávesové skratky</system:String>
<system:String x:Key="hotkeys">Klávesové skratky</system:String>
@ -297,6 +298,9 @@
<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="logLevel">Úroveň logovania</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">Vyberte správcu súborov</system:String>
@ -367,6 +371,7 @@ Ak pri zadávaní skratky pred ňu pridáte &quot;@&quot;, bude sa zhodovať s
<system:String x:Key="commonOK">Aktualizovať</system:String>
<system:String x:Key="commonYes">Áno</system:String>
<system:String x:Key="commonNo">Nie</system:String>
<system:String x:Key="commonBackground">Pozadie</system:String>
<!-- Crash Reporter -->
<system:String x:Key="reportWindow_version">Verzia</system:String>
@ -383,6 +388,9 @@ Ak pri zadávaní skratky pred ňu pridáte &quot;@&quot;, bude sa zhodovať s
<system:String x:Key="reportWindow_report_succeed">Hlásenie bolo úspešne odoslané</system:String>
<system:String x:Key="reportWindow_report_failed">Odoslanie hlásenia zlyhalo</system:String>
<system:String x:Key="reportWindow_flowlauncher_got_an_error">Flow Launcher zaznamenal chybu</system:String>
<system:String x:Key="reportWindow_please_open_issue">Prosím, otvorte nové issue na</system:String>
<system:String x:Key="reportWindow_upload_log">1. Nahrajte súbor logu: {0}</system:String>
<system:String x:Key="reportWindow_copy_below">2. Skopírujte nižšie uvedenú správu o výnimke</system:String>
<!-- General Notice -->
<system:String x:Key="pleaseWait">Čakajte, prosím...</system:String>

View file

@ -13,6 +13,7 @@
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">Failed to register hotkey &quot;{0}&quot;. The hotkey may be in use by another program. Change to a different hotkey, or exit another program.</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="MessageBoxTitle">Flow Launcher</system:String>
<system:String x:Key="couldnotStartCmd">Neuspešno pokretanje {0}</system:String>
<system:String x:Key="invalidFlowLauncherPluginFileFormat">Nepravilni Flow Launcher plugin format datoteke</system:String>
@ -44,6 +45,8 @@
<system:String x:Key="portableMode">Portable Mode</system:String>
<system:String x:Key="portableModeToolTIp">Store all settings and user data in one folder (Useful when used with removable drives or cloud services).</system:String>
<system:String x:Key="startFlowLauncherOnSystemStartup">Pokreni Flow Launcher pri podizanju sistema</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="setAutoStartFailed">Error setting launch on startup</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">Sakri Flow Launcher kada se izgubi fokus</system:String>
<system:String x:Key="dontPromptUpdateMsg">Ne prikazuj obaveštenje o novoj verziji</system:String>
@ -126,7 +129,8 @@
<system:String x:Key="plugin_query_version">Verzija</system:String>
<system:String x:Key="plugin_query_web">Website</system:String>
<system:String x:Key="plugin_uninstall">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>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">Plugin Store</system:String>
@ -143,8 +147,6 @@
<system:String x:Key="LabelNewToolTip">This plugin has been updated within the last 7 days</system:String>
<system:String x:Key="LabelUpdateToolTip">New Update is Available</system:String>
<!-- Setting Theme -->
<system:String x:Key="theme">Tema</system:String>
<system:String x:Key="appearance">Appearance</system:String>
@ -194,7 +196,6 @@
<system:String x:Key="TypeIsDarkToolTip">This theme supports two(light/dark) modes.</system:String>
<system:String x:Key="TypeHasBlurToolTip">This theme supports Blur Transparent Background.</system:String>
<!-- Setting Hotkey -->
<system:String x:Key="hotkey">Prečica</system:String>
<system:String x:Key="hotkeys">Prečica</system:String>
@ -297,6 +298,9 @@
<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="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">Select File Manager</system:String>
@ -367,6 +371,7 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
<system:String x:Key="commonOK">OK</system:String>
<system:String x:Key="commonYes">Yes</system:String>
<system:String x:Key="commonNo">No</system:String>
<system:String x:Key="commonBackground">Background</system:String>
<!-- Crash Reporter -->
<system:String x:Key="reportWindow_version">Verzija</system:String>
@ -383,6 +388,9 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
<system:String x:Key="reportWindow_report_succeed">Izveštaj uspešno poslat</system:String>
<system:String x:Key="reportWindow_report_failed">Izveštaj neuspešno poslat</system:String>
<system:String x:Key="reportWindow_flowlauncher_got_an_error">Flow Launcher je dobio grešku</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>
<!-- General Notice -->
<system:String x:Key="pleaseWait">Please wait...</system:String>

View file

@ -13,6 +13,7 @@
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">&quot;{0}&quot; kısayolunu atama başarısız oldu. Kısayolu başka bir program kullanıyorsa kapatmayı deneyin veya kısayolu değiştirin.</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="MessageBoxTitle">Flow Launcher</system:String>
<system:String x:Key="couldnotStartCmd">{0} başlatılamıyor</system:String>
<system:String x:Key="invalidFlowLauncherPluginFileFormat">Geçersiz Flow Launcher eklenti dosyası formatı</system:String>
@ -44,6 +45,8 @@
<system:String x:Key="portableMode">Taşınabilir Mod</system:String>
<system:String x:Key="portableModeToolTIp">Tüm ayarları ve kullanıcı verilerini tek bir klasörde saklayın (Çıkarılabilir sürücüler veya bulut hizmetleri ile kullanıldığında kullanışlıdır).</system:String>
<system:String x:Key="startFlowLauncherOnSystemStartup">Sistem ile Başlat</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="setAutoStartFailed">Sistemle başlatma ayarı başarısız oldu</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">Odak Pencereden Ayrıldığında Gizle</system:String>
<system:String x:Key="dontPromptUpdateMsg">Güncelleme bildirimlerini gösterme</system:String>
@ -126,7 +129,8 @@
<system:String x:Key="plugin_query_version">Sürüm</system:String>
<system:String x:Key="plugin_query_web">İnternet Sitesi</system:String>
<system:String x:Key="plugin_uninstall">Kaldır</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>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">Eklenti Mağazası</system:String>
@ -143,8 +147,6 @@
<system:String x:Key="LabelNewToolTip">Bu eklenti son 7 gün içerisinde güncellenmiş.</system:String>
<system:String x:Key="LabelUpdateToolTip">Yeni Bir Güncelleme Mevcut</system:String>
<!-- Setting Theme -->
<system:String x:Key="theme">Temalar</system:String>
<system:String x:Key="appearance">Görünüm</system:String>
@ -194,7 +196,6 @@
<system:String x:Key="TypeIsDarkToolTip">This theme supports two(light/dark) modes.</system:String>
<system:String x:Key="TypeHasBlurToolTip">This theme supports Blur Transparent Background.</system:String>
<!-- Setting Hotkey -->
<system:String x:Key="hotkey">Kısayol Tuşu</system:String>
<system:String x:Key="hotkeys">Kısayol Tuşu</system:String>
@ -297,6 +298,9 @@
<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="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">Dosya Yöneticisi Seçenekleri</system:String>
@ -365,6 +369,7 @@
<system:String x:Key="commonOK">Güncelle</system:String>
<system:String x:Key="commonYes">Yes</system:String>
<system:String x:Key="commonNo">No</system:String>
<system:String x:Key="commonBackground">Arka plan</system:String>
<!-- Crash Reporter -->
<system:String x:Key="reportWindow_version">Sürüm</system:String>
@ -381,6 +386,9 @@
<system:String x:Key="reportWindow_report_succeed">Hata raporu başarıyla gönderildi</system:String>
<system:String x:Key="reportWindow_report_failed">Hata raporu gönderimi başarısız oldu</system:String>
<system:String x:Key="reportWindow_flowlauncher_got_an_error">Flow Launcher'da bir hata oluştu</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>
<!-- General Notice -->
<system:String x:Key="pleaseWait">Lütfen bekleyin...</system:String>

View file

@ -13,6 +13,7 @@
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">Не вдалося зареєструвати гарячу клавішу &quot;{0}&quot;. Можливо, гаряча клавіша використовується іншою програмою. Змініть її на іншу гарячу клавішу або вийдіть з програми, де вона використовується.</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="MessageBoxTitle">Flow Launcher</system:String>
<system:String x:Key="couldnotStartCmd">Не вдалося запустити {0}</system:String>
<system:String x:Key="invalidFlowLauncherPluginFileFormat">Невірний формат файлу плагіна Flow Launcher</system:String>
@ -44,6 +45,8 @@
<system:String x:Key="portableMode">Портативний режим</system:String>
<system:String x:Key="portableModeToolTIp">Зберігати всі налаштування і дані користувача в одній теці (буде корисно при видаленні дисків або хмарних сервісах).</system:String>
<system:String x:Key="startFlowLauncherOnSystemStartup">Запускати Flow Launcher при запуску системи</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="setAutoStartFailed">Помилка запуску налаштування під час запуску</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">Сховати Flow Launcher, якщо втрачено фокус</system:String>
<system:String x:Key="dontPromptUpdateMsg">Не повідомляти про доступні нові версії</system:String>
@ -126,7 +129,8 @@
<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>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">Магазин плагінів</system:String>
@ -143,8 +147,6 @@
<system:String x:Key="LabelNewToolTip">Цей плагін було оновлено протягом останніх 7 днів</system:String>
<system:String x:Key="LabelUpdateToolTip">Доступне нове оновлення</system:String>
<!-- Setting Theme -->
<system:String x:Key="theme">Тема</system:String>
<system:String x:Key="appearance">Зовнішній вигляд</system:String>
@ -194,7 +196,6 @@
<system:String x:Key="TypeIsDarkToolTip">This theme supports two(light/dark) modes.</system:String>
<system:String x:Key="TypeHasBlurToolTip">Ця тема підтримує розмитий прозорий фон.</system:String>
<!-- Setting Hotkey -->
<system:String x:Key="hotkey">Гаряча клавіша</system:String>
<system:String x:Key="hotkeys">Гарячі клавіші</system:String>
@ -297,6 +298,9 @@
<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>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">Виберіть файловий менеджер</system:String>
@ -367,6 +371,7 @@
<system:String x:Key="commonOK">Добре</system:String>
<system:String x:Key="commonYes">Так</system:String>
<system:String x:Key="commonNo">Ні</system:String>
<system:String x:Key="commonBackground">Тло</system:String>
<!-- Crash Reporter -->
<system:String x:Key="reportWindow_version">Версія</system:String>
@ -383,6 +388,9 @@
<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>
<!-- General Notice -->
<system:String x:Key="pleaseWait">Будь ласка, зачекайте...</system:String>

View file

@ -13,6 +13,7 @@
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">Không thể đăng ký phím nóng &quot;{0}&quot;. Phím nóng có thể được sử dụng bởi một chương trình khác. Chuyển sang phím nóng khác hoặc thoát khỏi chương trình khác.</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="MessageBoxTitle">Flow Launcher</system:String>
<system:String x:Key="couldnotStartCmd">Không thể khởi động {0}</system:String>
<system:String x:Key="invalidFlowLauncherPluginFileFormat">Định dạng tệp plugin Flow Launcher không chính xác</system:String>
@ -44,6 +45,8 @@
<system:String x:Key="portableMode">Chế độ Portabler</system:String>
<system:String x:Key="portableModeToolTIp">Lưu trữ tất cả cài đặt và dữ liệu người dùng trong một thư mục (hữu ích khi sử dụng với thiết bị lưu trữ di động hoặc dịch vụ đám mây).</system:String>
<system:String x:Key="startFlowLauncherOnSystemStartup">Khởi động Flow Launcher khi khởi động hệ thống</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="setAutoStartFailed">Không lưu được tính năng tự khởi động khi khởi động hệ thống</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">Ẩn Flow Launcher khi mất tiêu điểm</system:String>
<system:String x:Key="dontPromptUpdateMsg">Không hiển thị thông báo khi có phiên bản mới</system:String>
@ -126,7 +129,8 @@
<system:String x:Key="plugin_query_version">Phiên bản</system:String>
<system:String x:Key="plugin_query_web">Trang web</system:String>
<system:String x:Key="plugin_uninstall">Gỡ cài đặt</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>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">Tải tiện ích mở rộng</system:String>
@ -143,8 +147,6 @@
<system:String x:Key="LabelNewToolTip">Plugin này đã được cập nhật trong vòng 7 ngày qua</system:String>
<system:String x:Key="LabelUpdateToolTip">Đã có bản cập nhật mới</system:String>
<!-- Setting Theme -->
<system:String x:Key="theme">Giao Diện</system:String>
<system:String x:Key="appearance">Giao diện</system:String>
@ -194,7 +196,6 @@
<system:String x:Key="TypeIsDarkToolTip">This theme supports two(light/dark) modes.</system:String>
<system:String x:Key="TypeHasBlurToolTip">This theme supports Blur Transparent Background.</system:String>
<!-- Setting Hotkey -->
<system:String x:Key="hotkey">Phím tắt</system:String>
<system:String x:Key="hotkeys">Phím tắt</system:String>
@ -299,6 +300,9 @@
<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="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">Chọn trình quản lý tệp</system:String>
@ -371,6 +375,7 @@
<system:String x:Key="commonOK">OK</system:String>
<system:String x:Key="commonYes">Có</system:String>
<system:String x:Key="commonNo">Không</system:String>
<system:String x:Key="commonBackground">Nền</system:String>
<!-- Crash Reporter -->
<system:String x:Key="reportWindow_version">Phiên bản</system:String>
@ -387,6 +392,9 @@
<system:String x:Key="reportWindow_report_succeed">Đã gửi báo cáo thành công</system:String>
<system:String x:Key="reportWindow_report_failed">Báo cáo lỗi</system:String>
<system:String x:Key="reportWindow_flowlauncher_got_an_error">Trình khởi chạy luồng có lỗi</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>
<!-- General Notice -->
<system:String x:Key="pleaseWait">Cảnh báo nhỏ...</system:String>

View file

@ -13,6 +13,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="MessageBoxTitle">Flow Launcher</system:String>
<system:String x:Key="couldnotStartCmd">启动命令 {0} 失败</system:String>
<system:String x:Key="invalidFlowLauncherPluginFileFormat">无效的 Flow Launcher 插件文件格式</system:String>
@ -44,6 +45,8 @@
<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="setAutoStartFailed">设置开机自启时出错</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">失去焦点时自动隐藏 Flow Launcher</system:String>
<system:String x:Key="dontPromptUpdateMsg">不显示新版本提示</system:String>
@ -126,7 +129,8 @@
<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>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">插件商店</system:String>
@ -143,8 +147,6 @@
<system:String x:Key="LabelNewToolTip">此插件在过去7天内有更新</system:String>
<system:String x:Key="LabelUpdateToolTip">有可用的更新</system:String>
<!-- Setting Theme -->
<system:String x:Key="theme">主题</system:String>
<system:String x:Key="appearance">外观</system:String>
@ -194,7 +196,6 @@
<system:String x:Key="TypeIsDarkToolTip">该主题支持两种(浅色/深色)模式。</system:String>
<system:String x:Key="TypeHasBlurToolTip">该主题支持模糊透明背景。</system:String>
<!-- Setting Hotkey -->
<system:String x:Key="hotkey">热键</system:String>
<system:String x:Key="hotkeys">热键</system:String>
@ -297,6 +298,9 @@
<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>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">默认文件管理器</system:String>
@ -367,6 +371,7 @@
<system:String x:Key="commonOK">更新</system:String>
<system:String x:Key="commonYes">是</system:String>
<system:String x:Key="commonNo">否</system:String>
<system:String x:Key="commonBackground">背景</system:String>
<!-- Crash Reporter -->
<system:String x:Key="reportWindow_version">版本</system:String>
@ -383,6 +388,9 @@
<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>
<!-- General Notice -->
<system:String x:Key="pleaseWait">请稍等...</system:String>

View file

@ -13,6 +13,7 @@
<!-- MainWindow -->
<system:String x:Key="registerHotkeyFailed">Failed to register hotkey &quot;{0}&quot;. The hotkey may be in use by another program. Change to a different hotkey, or exit another program.</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="MessageBoxTitle">Flow Launcher</system:String>
<system:String x:Key="couldnotStartCmd">啟動命令 {0} 失敗</system:String>
<system:String x:Key="invalidFlowLauncherPluginFileFormat">無效的 Flow Launcher 外掛格式</system:String>
@ -44,6 +45,8 @@
<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="setAutoStartFailed">Error setting launch on startup</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">失去焦點時自動隱藏 Flow Launcher</system:String>
<system:String x:Key="dontPromptUpdateMsg">不顯示新版本提示</system:String>
@ -126,7 +129,8 @@
<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>
<!-- Setting Plugin Store -->
<system:String x:Key="pluginStore">插件商店</system:String>
@ -143,8 +147,6 @@
<system:String x:Key="LabelNewToolTip">This plugin has been updated within the last 7 days</system:String>
<system:String x:Key="LabelUpdateToolTip">New Update is Available</system:String>
<!-- Setting Theme -->
<system:String x:Key="theme">主題</system:String>
<system:String x:Key="appearance">外觀</system:String>
@ -194,7 +196,6 @@
<system:String x:Key="TypeIsDarkToolTip">This theme supports two(light/dark) modes.</system:String>
<system:String x:Key="TypeHasBlurToolTip">This theme supports Blur Transparent Background.</system:String>
<!-- Setting Hotkey -->
<system:String x:Key="hotkey">快捷鍵</system:String>
<system:String x:Key="hotkeys">快捷鍵</system:String>
@ -297,6 +298,9 @@
<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="logLevel">Log Level</system:String>
<system:String x:Key="LogLevelDEBUG">Debug</system:String>
<system:String x:Key="LogLevelINFO">Info</system:String>
<!-- FileManager Setting Dialog -->
<system:String x:Key="fileManagerWindow">選擇檔案管理器</system:String>
@ -367,6 +371,7 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
<system:String x:Key="commonOK">更新</system:String>
<system:String x:Key="commonYes">Yes</system:String>
<system:String x:Key="commonNo">No</system:String>
<system:String x:Key="commonBackground">背景</system:String>
<!-- Crash Reporter -->
<system:String x:Key="reportWindow_version">版本</system:String>
@ -383,6 +388,9 @@ If you add an '@' prefix while inputting a shortcut, it matches any position in
<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>
<!-- General Notice -->
<system:String x:Key="pleaseWait">請稍後...</system:String>

View file

@ -17,20 +17,21 @@
AllowDrop="True"
AllowsTransparency="True"
Background="Transparent"
Closed="OnClosed"
Closing="OnClosing"
Deactivated="OnDeactivated"
Icon="Images/app.png"
SourceInitialized="OnSourceInitialized"
Initialized="OnInitialized"
Left="{Binding Settings.WindowLeft, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Loaded="OnLoaded"
LocationChanged="OnLocationChanged"
Opacity="{Binding MainWindowOpacity, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
PreviewKeyDown="OnKeyDown"
PreviewKeyUp="OnKeyUp"
PreviewMouseMove="OnPreviewMouseMove"
ResizeMode="CanResize"
ShowInTaskbar="False"
SizeToContent="Height"
SourceInitialized="OnSourceInitialized"
Topmost="True"
Visibility="{Binding MainWindowVisibility, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
WindowStartupLocation="Manual"
@ -215,7 +216,7 @@
<Border MouseDown="OnMouseDown" Style="{DynamicResource WindowBorderStyle}">
<StackPanel Orientation="Vertical">
<Grid>
<Grid x:Name="QueryBoxArea">
<Border MinHeight="30" Style="{DynamicResource QueryBoxBgStyle}">
<Grid>
<TextBox
@ -240,14 +241,14 @@
FontSize="{Binding QueryBoxFontSize, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
InputMethod.PreferredImeConversionMode="{Binding StartWithEnglishMode, Converter={StaticResource BoolToIMEConversionModeConverter}}"
InputMethod.PreferredImeState="{Binding StartWithEnglishMode, Converter={StaticResource BoolToIMEStateConverter}}"
PreviewDragOver="OnPreviewDragOver"
PreviewDragOver="QueryTextBox_OnPreviewDragOver"
PreviewKeyUp="QueryTextBox_KeyUp"
Style="{DynamicResource QueryBoxStyle}"
Text="{Binding QueryText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Visibility="Visible"
WindowChrome.IsHitTestVisibleInChrome="True">
<TextBox.CommandBindings>
<CommandBinding Command="ApplicationCommands.Copy" Executed="OnCopy" />
<CommandBinding Command="ApplicationCommands.Copy" Executed="QueryTextBox_OnCopy" />
</TextBox.CommandBindings>
<TextBox.ContextMenu>
<ContextMenu MinWidth="160">
@ -331,7 +332,6 @@
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
StrokeThickness="2"
Style="{DynamicResource PendingLineStyle}"
Visibility="{Binding ProgressBarVisibility, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
X1="-100"
X2="0"
@ -339,7 +339,7 @@
Y2="0" />
</Grid>
<Grid ClipToBounds="True">
<Grid x:Name="MiddleSeparatorArea" ClipToBounds="True">
<ContentControl>
<ContentControl.Style>
<Style TargetType="ContentControl">
@ -377,9 +377,9 @@
HorizontalAlignment="Stretch"
Style="{DynamicResource SeparatorStyle}" />
</ContentControl>
</Grid>
<Border Style="{DynamicResource WindowRadius}">
<Border x:Name="ResultPreviewAreaBoarder" Style="{DynamicResource WindowRadius}">
<Border.Clip>
<MultiBinding Converter="{StaticResource BorderClipConverter}">
<Binding Path="ActualWidth" RelativeSource="{RelativeSource Self}" />
@ -387,12 +387,14 @@
<Binding Path="CornerRadius" RelativeSource="{RelativeSource Self}" />
</MultiBinding>
</Border.Clip>
<Grid>
<Grid x:Name="ResultPreviewArea">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MinWidth="80" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="0.85*" MinWidth="244" />
</Grid.ColumnDefinitions>
<StackPanel
x:Name="ResultArea"
Grid.Column="0"
@ -419,7 +421,9 @@
RightClickResultCommand="{Binding RightClickResultCommand}" />
</ContentControl>
</StackPanel>
<GridSplitter
x:Name="PreviewMiddleSeparator"
Grid.Column="1"
Margin="0"
HorizontalAlignment="Center"
@ -433,6 +437,7 @@
</ControlTemplate>
</GridSplitter.Template>
</GridSplitter>
<Grid
x:Name="Preview"
Grid.Column="2"
@ -442,7 +447,7 @@
<Border
MinHeight="380"
d:DataContext="{d:DesignInstance vm:ResultViewModel}"
DataContext="{Binding SelectedItem, ElementName=ResultListBox}"
DataContext="{Binding PreviewSelectedItem, Mode=OneWay}"
Visibility="{Binding ShowDefaultPreview}">
<Grid
Margin="0 0 10 5"
@ -519,7 +524,7 @@
MaxHeight="{Binding ElementName=ResultListBox, Path=ActualHeight}"
Padding="0 0 10 10"
d:DataContext="{d:DesignInstance vm:ResultViewModel}"
DataContext="{Binding SelectedItem, ElementName=ResultListBox}"
DataContext="{Binding PreviewSelectedItem, Mode=OneWay}"
Visibility="{Binding ShowCustomizedPreview}">
<ContentControl Content="{Binding Result.PreviewPanel.Value}" />
</Border>

File diff suppressed because it is too large Load diff

View file

@ -1,10 +1,9 @@
using System;
using System;
using System.IO;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media.Animation;
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Image;
@ -12,14 +11,14 @@ namespace Flow.Launcher
{
public partial class Msg : Window
{
Storyboard fadeOutStoryboard = new Storyboard();
private readonly Storyboard fadeOutStoryboard = new();
private bool closing;
public Msg()
{
InitializeComponent();
var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position);
var dipWorkingArea = WindowsInteropHelper.TransformPixelsToDIP(this,
var dipWorkingArea = Win32Helper.TransformPixelsToDIP(this,
screen.WorkingArea.Width,
screen.WorkingArea.Height);
Left = dipWorkingArea.X - Width;
@ -82,13 +81,13 @@ namespace Flow.Launcher
Show();
await Dispatcher.InvokeAsync(async () =>
{
if (!closing)
{
closing = true;
await Dispatcher.InvokeAsync(fadeOutStoryboard.Begin);
}
});
{
if (!closing)
{
closing = true;
await Dispatcher.InvokeAsync(fadeOutStoryboard.Begin);
}
});
}
}
}

View file

@ -1,20 +0,0 @@
DwmSetWindowAttribute
DwmExtendFrameIntoClientArea
SystemParametersInfo
SetForegroundWindow
GetWindowLong
SetWindowLong
GetForegroundWindow
GetDesktopWindow
GetShellWindow
GetWindowRect
GetClassName
FindWindowEx
WINDOW_STYLE
WM_ENTERSIZEMOVE
WM_EXITSIZEMOVE
SetLastError
WINDOW_EX_STYLE

View file

@ -0,0 +1,130 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string"/>
<xsd:attribute name="type" type="xsd:string"/>
<xsd:attribute name="mimetype" type="xsd:string"/>
<xsd:attribute ref="xml:space"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string"/>
<xsd:attribute name="name" type="xsd:string"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
<xsd:attribute ref="xml:space"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<data name="app" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\app.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="dev" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Images\dev.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="gamemode" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Images\gamemode.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

View file

@ -1,46 +1,48 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using CommunityToolkit.Mvvm.DependencyInjection;
using Squirrel;
using Flow.Launcher.Core;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Http;
using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.Image;
using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;
using Flow.Launcher.Plugin.SharedModels;
using Flow.Launcher.Plugin.SharedCommands;
using System.Threading;
using System.IO;
using Flow.Launcher.Infrastructure.Http;
using JetBrains.Annotations;
using System.Runtime.CompilerServices;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.Storage;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Collections.Specialized;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedModels;
using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.ViewModel;
using JetBrains.Annotations;
using Flow.Launcher.Core.Resource;
namespace Flow.Launcher
{
public class PublicAPIInstance : IPublicAPI
{
private readonly Settings _settings;
private readonly Internationalization _translater;
private readonly MainViewModel _mainVM;
#region Constructor
public PublicAPIInstance(Settings settings, MainViewModel mainVM)
public PublicAPIInstance(Settings settings, Internationalization translater, MainViewModel mainVM)
{
_settings = settings;
_translater = translater;
_mainVM = mainVM;
GlobalHotkey.hookedKeyboardCallback = KListener_hookedKeyboardCallback;
WebRequest.RegisterPrefix("data", new DataWebRequestFactory());
@ -153,17 +155,17 @@ namespace Flow.Launcher
public void StopLoadingBar() => _mainVM.ProgressBarVisibility = Visibility.Collapsed;
public string GetTranslation(string key) => InternationalizationManager.Instance.GetTranslation(key);
public string GetTranslation(string key) => _translater.GetTranslation(key);
public List<PluginPair> GetAllPlugins() => PluginManager.AllPlugins.ToList();
public MatchResult FuzzySearch(string query, string stringToCompare) =>
StringMatcher.FuzzySearch(query, stringToCompare);
public Task<string> HttpGetStringAsync(string url, CancellationToken token = default) => Http.GetAsync(url);
public Task<string> HttpGetStringAsync(string url, CancellationToken token = default) => Http.GetAsync(url, token);
public Task<Stream> HttpGetStreamAsync(string url, CancellationToken token = default) =>
Http.GetStreamAsync(url);
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);
@ -329,7 +331,6 @@ namespace Flow.Launcher
return _mainVM.GameModeStatus;
}
private readonly List<Func<int, int, SpecialKeyState, bool>> _globalKeyboardHandlers = new();
public void RegisterGlobalKeyboardCallback(Func<int, int, SpecialKeyState, bool> callback) => _globalKeyboardHandlers.Add(callback);

View file

@ -11,30 +11,33 @@
mc:Ignorable="d">
<Border
Width="Auto"
Height="52"
Height="Auto"
Margin="0"
Padding="0"
BorderThickness="0 1 0 0"
CornerRadius="0"
Style="{DynamicResource SettingGroupBox}"
Visibility="{Binding ActionKeywordsVisibility}">
<DockPanel Margin="22 0 18 0" VerticalAlignment="Center">
<DockPanel Margin="{StaticResource SettingPanelMargin}">
<TextBlock
Margin="48 0 10 0"
Margin="{StaticResource SettingPanelItemRightMargin}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
DockPanel.Dock="Left"
Style="{StaticResource Glyph}">
&#xe819;
</TextBlock>
<TextBlock
Margin="{StaticResource SettingPanelItemRightMargin}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
DockPanel.Dock="Left"
Style="{DynamicResource SettingTitleLabel}"
Text="{DynamicResource actionKeywords}" />
<!-- Here Margin="0 -4.5 0 -4.5" is to remove redundant top bottom margin from Margin="{StaticResource SettingPanelMargin}" -->
<Button
Width="100"
Height="34"
Margin="5 0 0 0"
Margin="0 -4.5 0 -4.5"
HorizontalAlignment="Right"
Command="{Binding SetActionKeywordsCommand}"
Content="{Binding ActionKeywordsText}"

View file

@ -5585,4 +5585,31 @@
</Setter.Value>
</Setter>
</Style>
<!-- Settings Panel -->
<Thickness x:Key="SettingPanelMargin">70,13.5,18,13.5</Thickness>
<Thickness x:Key="SettingPanelItemLeftMargin">9,0,0,0</Thickness>
<Thickness x:Key="SettingPanelItemRightMargin">0,0,9,0</Thickness>
<Thickness x:Key="SettingPanelItemTopBottomMargin">0,4.5,0,4.5</Thickness>
<Thickness x:Key="SettingPanelItemLeftTopBottomMargin">9,4.5,0,4.5</Thickness>
<Thickness x:Key="SettingPanelItemRightTopBottomMargin">0,4.5,9,4.5</Thickness>
<Style x:Key="SettingPanelSeparatorStyle" TargetType="Separator">
<Setter Property="Margin" Value="-70 13.5 -18 13.5" />
<Setter Property="Height" Value="1" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Background" Value="{DynamicResource Color03B}" />
</Style>
<system:Double x:Key="SettingPanelTextBoxMinWidth">180</system:Double>
<system:Double x:Key="SettingPanelPathTextBoxWidth">240</system:Double>
<system:Double x:Key="SettingPanelAreaTextBoxMinHeight">150</system:Double>
<Style x:Key="SettingPanelTextBlockDescriptionStyle" TargetType="TextBlock">
<Setter Property="FontSize" Value="12" />
<Setter Property="Margin" Value="0 2 0 0" />
<Setter Property="Foreground" Value="{DynamicResource Color04B}" />
</Style>
</ResourceDictionary>

View file

@ -7,17 +7,17 @@
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<SolidColorBrush x:Key="SystemThemeBorder" Color="#3f3f3f" />
<SolidColorBrush x:Key="QuerySuggestionBoxForeground" Color="#4d4d4d" />
<SolidColorBrush x:Key="QuerySuggestionBoxForeground" Color="#33FFFFFF" />
<SolidColorBrush x:Key="QuerySelectionBrush" Color="#4a5459" />
<SolidColorBrush x:Key="SubTitleForeground" Color="#7b7b7b" />
<SolidColorBrush x:Key="SubTitleSelectedForeground" Color="#7b7b7b" />
<SolidColorBrush x:Key="SearchIconForeground" Color="#4d4d4d" />
<SolidColorBrush x:Key="SeparatorForeground" Color="#14ffffff" />
<SolidColorBrush x:Key="SubTitleForeground" Color="#33FFFFFF" />
<SolidColorBrush x:Key="SubTitleSelectedForeground" Color="#33FFFFFF" />
<SolidColorBrush x:Key="SearchIconForeground" Color="#33FFFFFF" />
<SolidColorBrush x:Key="SeparatorForeground" Color="#24FFFFFF" />
<SolidColorBrush x:Key="ThumbColor" Color="#9a9a9a" />
<SolidColorBrush x:Key="InlineHighlight" Color="#0078d7" />
<SolidColorBrush x:Key="HotkeyForeground" Color="#7b7b7b" />
<SolidColorBrush x:Key="HotkeySelectedForeground" Color="#7b7b7b" />
<SolidColorBrush x:Key="ClockDateForeground" Color="#4d4d4d" />
<SolidColorBrush x:Key="HotkeyForeground" Color="#33FFFFFF" />
<SolidColorBrush x:Key="HotkeySelectedForeground" Color="#33FFFFFF" />
<SolidColorBrush x:Key="ClockDateForeground" Color="#26FFFFFF" />
<Color x:Key="ItemSelectedBackgroundColorBrush">#198F8F8F</Color>

View file

@ -7,18 +7,18 @@
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<SolidColorBrush x:Key="SystemThemeBorder" Color="#aaaaaa" />
<SolidColorBrush x:Key="QuerySuggestionBoxForeground" Color="#d8d2d0" />
<SolidColorBrush x:Key="QuerySuggestionBoxForeground" Color="#51000000" />
<SolidColorBrush x:Key="QuerySelectionBrush" Color="#0a68d8" />
<SolidColorBrush x:Key="SubTitleForeground" Color="#818181" />
<SolidColorBrush x:Key="SubTitleSelectedForeground" Color="#72767d" />
<SolidColorBrush x:Key="SearchIconForeground" Color="#d3d3d3" />
<SolidColorBrush x:Key="SeparatorForeground" Color="#14000000" />
<SolidColorBrush x:Key="SearchIconForeground" Color="#20000000" />
<SolidColorBrush x:Key="SeparatorForeground" Color="#20000000" />
<SolidColorBrush x:Key="ThumbColor" Color="#868686" />
<SolidColorBrush x:Key="InlineHighlight" Color="#0078d7" />
<SolidColorBrush x:Key="HotkeyForeground" Color="#acacac" />
<SolidColorBrush x:Key="HotkeySelectedForeground" Color="#acacac" />
<SolidColorBrush x:Key="ClockDateForeground" Color="#d3d3d3" />
<Color x:Key="ItemSelectedBackgroundColorBrush">#198F8F8F</Color>
<SolidColorBrush x:Key="HotkeyForeground" Color="#51000000" />
<SolidColorBrush x:Key="HotkeySelectedForeground" Color="#51000000" />
<SolidColorBrush x:Key="ClockDateForeground" Color="#44000000" />
<Color x:Key="ItemSelectedBackgroundColorBrush">#0C000000</Color>
<SolidColorBrush x:Key="Color00B" Color="#fbfbfb" />
<SolidColorBrush x:Key="Color01B" Color="#f3f3f3" />

View file

@ -1,8 +1,9 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Windows.Navigation;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Core.Resource;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.ViewModel;
namespace Flow.Launcher.Resources.Pages
{
@ -10,10 +11,10 @@ namespace Flow.Launcher.Resources.Pages
{
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (e.ExtraData is Settings settings)
Settings = settings;
else
throw new ArgumentException("Unexpected Navigation Parameter for Settings");
Settings = Ioc.Default.GetRequiredService<Settings>();
// Sometimes the navigation is not triggered by button click,
// so we need to reset the page number
Ioc.Default.GetRequiredService<WelcomeViewModel>().PageNum = 1;
InitializeComponent();
}
private Internationalization _translater => InternationalizationManager.Instance;
@ -37,4 +38,4 @@ namespace Flow.Launcher.Resources.Pages
}
}
}
}

View file

@ -114,8 +114,7 @@
Margin="0,8,0,0"
ChangeHotkey="{Binding SetTogglingHotkeyCommand}"
DefaultHotkey="Alt+Space"
Hotkey="{Binding Settings.Hotkey}"
HotkeySettings="{Binding Settings}"
Type="Hotkey"
ValidateKeyGesture="True"
WindowTitle="{DynamicResource flowlauncherHotkey}" />
</StackPanel>

View file

@ -1,11 +1,11 @@
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.UserSettings;
using System;
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.ViewModel;
using System.Windows.Media;
using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Resources.Pages
{
@ -15,11 +15,10 @@ namespace Flow.Launcher.Resources.Pages
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (e.ExtraData is Settings settings)
Settings = settings;
else
throw new ArgumentException("Unexpected Parameter setting.");
Settings = Ioc.Default.GetRequiredService<Settings>();
// Sometimes the navigation is not triggered by button click,
// so we need to reset the page number
Ioc.Default.GetRequiredService<WelcomeViewModel>().PageNum = 2;
InitializeComponent();
}

View file

@ -1,6 +1,7 @@
using System;
using System.Windows.Navigation;
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.ViewModel;
namespace Flow.Launcher.Resources.Pages
{
@ -8,10 +9,10 @@ namespace Flow.Launcher.Resources.Pages
{
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (e.ExtraData is Settings settings)
Settings = settings;
else if(Settings is null)
throw new ArgumentException("Unexpected Navigation Parameter for Settings");
Settings = Ioc.Default.GetRequiredService<Settings>();
// Sometimes the navigation is not triggered by button click,
// so we need to reset the page number
Ioc.Default.GetRequiredService<WelcomeViewModel>().PageNum = 3;
InitializeComponent();
}

View file

@ -1,5 +1,6 @@
using Flow.Launcher.Infrastructure.UserSettings;
using System;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.ViewModel;
using System.Windows.Navigation;
namespace Flow.Launcher.Resources.Pages
@ -8,10 +9,10 @@ namespace Flow.Launcher.Resources.Pages
{
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (e.ExtraData is Settings settings)
Settings = settings;
else
throw new ArgumentException("Unexpected Navigation Parameter for Settings");
Settings = Ioc.Default.GetRequiredService<Settings>();
// Sometimes the navigation is not triggered by button click,
// so we need to reset the page number
Ioc.Default.GetRequiredService<WelcomeViewModel>().PageNum = 4;
InitializeComponent();
}

View file

@ -1,9 +1,10 @@
using System;
using System.Windows;
using System.Windows;
using System.Windows.Navigation;
using Flow.Launcher.Infrastructure.UserSettings;
using Microsoft.Win32;
using Flow.Launcher.Infrastructure;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.ViewModel;
namespace Flow.Launcher.Resources.Pages
{
@ -15,10 +16,10 @@ namespace Flow.Launcher.Resources.Pages
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (e.ExtraData is Settings settings)
Settings = settings;
else
throw new ArgumentException("Unexpected Navigation Parameter for Settings");
Settings = Ioc.Default.GetRequiredService<Settings>();
// Sometimes the navigation is not triggered by button click,
// so we need to reset the page number
Ioc.Default.GetRequiredService<WelcomeViewModel>().PageNum = 5;
InitializeComponent();
}

View file

@ -80,7 +80,7 @@ public partial class SettingsPaneAboutViewModel : BaseModel
[RelayCommand]
private void OpenWelcomeWindow()
{
var window = new WelcomeWindow(_settings);
var window = new WelcomeWindow();
window.ShowDialog();
}

View file

@ -5,6 +5,7 @@ using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows.Media;
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Helper;
@ -13,7 +14,6 @@ using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;
using ModernWpf;
using ThemeManager = Flow.Launcher.Core.Resource.ThemeManager;
using ThemeManagerForColorSchemeSwitch = ModernWpf.ThemeManager;
namespace Flow.Launcher.SettingPages.ViewModels;
@ -22,45 +22,68 @@ public partial class SettingsPaneThemeViewModel : BaseModel
{
private const string DefaultFont = "Segoe UI";
public Settings Settings { get; }
private readonly Theme _theme = Ioc.Default.GetRequiredService<Theme>();
public static string LinkHowToCreateTheme => @"https://flowlauncher.com/docs/#/how-to-create-a-theme";
public static string LinkThemeGallery => "https://github.com/Flow-Launcher/Flow.Launcher/discussions/1438";
private List<Theme.ThemeData> _themes;
public List<Theme.ThemeData> Themes => _themes ??= _theme.LoadAvailableThemes();
private Theme.ThemeData _selectedTheme;
public Theme.ThemeData SelectedTheme
{
get => _selectedTheme ??= Themes.Find(v => v.FileNameWithoutExtension == Settings.Theme);
get => _selectedTheme ??= Themes.Find(v => v.FileNameWithoutExtension == _theme.GetCurrentTheme());
set
{
_selectedTheme = value;
ThemeManager.Instance.ChangeTheme(value.FileNameWithoutExtension);
_theme.ChangeTheme(value.FileNameWithoutExtension);
if (ThemeManager.Instance.BlurEnabled && Settings.UseDropShadowEffect)
DropShadowEffect = false;
// Update UI state
OnPropertyChanged(nameof(BackdropType));
OnPropertyChanged(nameof(IsBackdropEnabled));
OnPropertyChanged(nameof(IsDropShadowEnabled));
OnPropertyChanged(nameof(DropShadowEffect));
_ = _theme.RefreshFrameAsync();
}
}
public bool IsBackdropEnabled
{
get
{
if (!Win32Helper.IsBackdropSupported()) return false;
return SelectedTheme?.HasBlur ?? false;
}
}
public bool IsDropShadowEnabled => !_theme.BlurEnabled;
public bool DropShadowEffect
{
get => Settings.UseDropShadowEffect;
set
{
if (ThemeManager.Instance.BlurEnabled && value)
if (_theme.BlurEnabled)
{
App.API.ShowMsgBox(InternationalizationManager.Instance.GetTranslation("shadowEffectNotAllowed"));
// Always DropShadowEffect = true with blur theme
Settings.UseDropShadowEffect = true;
return;
}
// User can change shadow with non-blur theme.
if (value)
{
ThemeManager.Instance.AddDropShadowEffectToCurrentTheme();
_theme.AddDropShadowEffectToCurrentTheme();
}
else
{
ThemeManager.Instance.RemoveDropShadowEffectFromCurrentTheme();
_theme.RemoveDropShadowEffectFromCurrentTheme();
}
Settings.UseDropShadowEffect = value;
OnPropertyChanged(nameof(DropShadowEffect));
}
}
@ -94,12 +117,25 @@ public partial class SettingsPaneThemeViewModel : BaseModel
set => Settings.ResultSubItemFontSize = value;
}
private List<Theme.ThemeData> _themes;
public List<Theme.ThemeData> Themes => _themes ??= ThemeManager.Instance.LoadAvailableThemes();
public class ColorSchemeData : DropdownDataGeneric<ColorSchemes> { }
public List<ColorSchemeData> ColorSchemes { get; } = DropdownDataGeneric<ColorSchemes>.GetValues<ColorSchemeData>("ColorScheme");
public string ColorScheme
{
get => Settings.ColorScheme;
set
{
ThemeManagerForColorSchemeSwitch.Current.ApplicationTheme = value switch
{
Constant.Light => ApplicationTheme.Light,
Constant.Dark => ApplicationTheme.Dark,
Constant.System => null,
_ => ThemeManagerForColorSchemeSwitch.Current.ApplicationTheme
};
Settings.ColorScheme = value;
_ = _theme.RefreshFrameAsync();
}
}
public List<string> TimeFormatList { get; } = new()
{
@ -174,6 +210,33 @@ public partial class SettingsPaneThemeViewModel : BaseModel
public class AnimationSpeedData : DropdownDataGeneric<AnimationSpeeds> { }
public List<AnimationSpeedData> AnimationSpeeds { get; } = DropdownDataGeneric<AnimationSpeeds>.GetValues<AnimationSpeedData>("AnimationSpeed");
public class BackdropTypeData : DropdownDataGeneric<BackdropTypes> { }
public List<BackdropTypeData> BackdropTypesList { get; } =
DropdownDataGeneric<BackdropTypes>.GetValues<BackdropTypeData>("BackdropTypes");
public BackdropTypes BackdropType
{
get => Enum.IsDefined(typeof(BackdropTypes), Settings.BackdropType)
? Settings.BackdropType
: BackdropTypes.None;
set
{
if (!Enum.IsDefined(typeof(BackdropTypes), value))
{
value = BackdropTypes.None;
}
Settings.BackdropType = value;
// Can only apply blur because drop shadow effect is not supported with backdrop
// So drop shadow effect has been disabled
_ = _theme.SetBlurForWindowAsync();
OnPropertyChanged(nameof(IsDropShadowEnabled));
}
}
public bool UseSound
{
get => Settings.UseSound;
@ -219,37 +282,37 @@ public partial class SettingsPaneThemeViewModel : BaseModel
{
var results = new List<Result>
{
new Result
new()
{
Title = InternationalizationManager.Instance.GetTranslation("SampleTitleExplorer"),
SubTitle = InternationalizationManager.Instance.GetTranslation("SampleSubTitleExplorer"),
Title = App.API.GetTranslation("SampleTitleExplorer"),
SubTitle = App.API.GetTranslation("SampleSubTitleExplorer"),
IcoPath = Path.Combine(
Constant.ProgramDirectory,
@"Plugins\Flow.Launcher.Plugin.Explorer\Images\explorer.png"
)
},
new Result
new()
{
Title = InternationalizationManager.Instance.GetTranslation("SampleTitleWebSearch"),
SubTitle = InternationalizationManager.Instance.GetTranslation("SampleSubTitleWebSearch"),
Title = App.API.GetTranslation("SampleTitleWebSearch"),
SubTitle = App.API.GetTranslation("SampleSubTitleWebSearch"),
IcoPath = Path.Combine(
Constant.ProgramDirectory,
@"Plugins\Flow.Launcher.Plugin.WebSearch\Images\web_search.png"
)
},
new Result
new()
{
Title = InternationalizationManager.Instance.GetTranslation("SampleTitleProgram"),
SubTitle = InternationalizationManager.Instance.GetTranslation("SampleSubTitleProgram"),
Title = App.API.GetTranslation("SampleTitleProgram"),
SubTitle = App.API.GetTranslation("SampleSubTitleProgram"),
IcoPath = Path.Combine(
Constant.ProgramDirectory,
@"Plugins\Flow.Launcher.Plugin.Program\Images\program.png"
)
},
new Result
new()
{
Title = InternationalizationManager.Instance.GetTranslation("SampleTitleProcessKiller"),
SubTitle = InternationalizationManager.Instance.GetTranslation("SampleSubTitleProcessKiller"),
Title = App.API.GetTranslation("SampleTitleProcessKiller"),
SubTitle = App.API.GetTranslation("SampleSubTitleProcessKiller"),
IcoPath = Path.Combine(
Constant.ProgramDirectory,
@"Plugins\Flow.Launcher.Plugin.ProcessKiller\Images\app.png"
@ -281,7 +344,7 @@ public partial class SettingsPaneThemeViewModel : BaseModel
set
{
Settings.QueryBoxFont = value.ToString();
ThemeManager.Instance.ChangeTheme(Settings.Theme);
_theme.UpdateFonts();
}
}
@ -303,7 +366,7 @@ public partial class SettingsPaneThemeViewModel : BaseModel
Settings.QueryBoxFontStretch = value.Stretch.ToString();
Settings.QueryBoxFontWeight = value.Weight.ToString();
Settings.QueryBoxFontStyle = value.Style.ToString();
ThemeManager.Instance.ChangeTheme(Settings.Theme);
_theme.UpdateFonts();
}
}
@ -325,7 +388,7 @@ public partial class SettingsPaneThemeViewModel : BaseModel
set
{
Settings.ResultFont = value.ToString();
ThemeManager.Instance.ChangeTheme(Settings.Theme);
_theme.UpdateFonts();
}
}
@ -347,7 +410,7 @@ public partial class SettingsPaneThemeViewModel : BaseModel
Settings.ResultFontStretch = value.Stretch.ToString();
Settings.ResultFontWeight = value.Weight.ToString();
Settings.ResultFontStyle = value.Style.ToString();
ThemeManager.Instance.ChangeTheme(Settings.Theme);
_theme.UpdateFonts();
}
}
@ -355,9 +418,9 @@ public partial class SettingsPaneThemeViewModel : BaseModel
{
get
{
if (Fonts.SystemFontFamilies.Count(o =>
if (Fonts.SystemFontFamilies.Any(o =>
o.FamilyNames.Values != null &&
o.FamilyNames.Values.Contains(Settings.ResultSubFont)) > 0)
o.FamilyNames.Values.Contains(Settings.ResultSubFont)))
{
var font = new FontFamily(Settings.ResultSubFont);
return font;
@ -371,7 +434,7 @@ public partial class SettingsPaneThemeViewModel : BaseModel
set
{
Settings.ResultSubFont = value.ToString();
ThemeManager.Instance.ChangeTheme(Settings.Theme);
_theme.UpdateFonts();
}
}
@ -392,34 +455,23 @@ public partial class SettingsPaneThemeViewModel : BaseModel
Settings.ResultSubFontStretch = value.Stretch.ToString();
Settings.ResultSubFontWeight = value.Weight.ToString();
Settings.ResultSubFontStyle = value.Style.ToString();
ThemeManager.Instance.ChangeTheme(Settings.Theme);
_theme.UpdateFonts();
}
}
public string ThemeImage => Constant.QueryTextBoxIconImagePath;
public SettingsPaneThemeViewModel(Settings settings)
{
Settings = settings;
}
[RelayCommand]
private void OpenThemesFolder()
{
App.API.OpenDirectory(Path.Combine(DataLocation.DataDirectory(), Constant.Themes));
}
public void UpdateColorScheme()
{
ThemeManagerForColorSchemeSwitch.Current.ApplicationTheme = Settings.ColorScheme switch
{
Constant.Light => ApplicationTheme.Light,
Constant.Dark => ApplicationTheme.Dark,
Constant.System => null,
_ => ThemeManagerForColorSchemeSwitch.Current.ApplicationTheme
};
}
public SettingsPaneThemeViewModel(Settings settings)
{
Settings = settings;
}
[RelayCommand]
public void Reset()
{

View file

@ -1,6 +1,8 @@
using System;
using System.Windows.Navigation;
using System.Windows.Navigation;
using Flow.Launcher.Core;
using Flow.Launcher.SettingPages.ViewModels;
using Flow.Launcher.Infrastructure.UserSettings;
using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.SettingPages.Views;
@ -12,8 +14,8 @@ public partial class SettingsPaneAbout
{
if (!IsInitialized)
{
if (e.ExtraData is not SettingWindow.PaneData { Settings: { } settings, Updater: { } updater })
throw new ArgumentException("Settings are required for SettingsPaneAbout.");
var settings = Ioc.Default.GetRequiredService<Settings>();
var updater = Ioc.Default.GetRequiredService<Updater>();
_viewModel = new SettingsPaneAboutViewModel(settings, updater);
DataContext = _viewModel;
InitializeComponent();

View file

@ -1,5 +1,7 @@
using System;
using System.Windows.Navigation;
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core;
using Flow.Launcher.Core.Configuration;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.SettingPages.ViewModels;
@ -13,8 +15,9 @@ public partial class SettingsPaneGeneral
{
if (!IsInitialized)
{
if (e.ExtraData is not SettingWindow.PaneData { Settings: { } settings, Updater: {} updater, Portable: {} portable })
throw new ArgumentException("Settings, Updater and Portable are required for SettingsPaneGeneral.");
var settings = Ioc.Default.GetRequiredService<Settings>();
var updater = Ioc.Default.GetRequiredService<Updater>();
var portable = Ioc.Default.GetRequiredService<Portable>();
_viewModel = new SettingsPaneGeneralViewModel(settings, updater, portable);
DataContext = _viewModel;
InitializeComponent();

View file

@ -34,8 +34,7 @@
<flowlauncher:HotkeyControl
ChangeHotkey="{Binding SetTogglingHotkeyCommand}"
DefaultHotkey="Alt+Space"
Hotkey="{Binding Settings.Hotkey}"
HotkeySettings="{Binding Settings}"
Type="Hotkey"
ValidateKeyGesture="True"
WindowTitle="{DynamicResource flowlauncherHotkey}" />
</cc:Card>
@ -46,8 +45,7 @@
Sub="{DynamicResource previewHotkeyToolTip}">
<flowlauncher:HotkeyControl
DefaultHotkey="F1"
Hotkey="{Binding Settings.PreviewHotkey}"
HotkeySettings="{Binding Settings}"
Type="PreviewHotkey"
ValidateKeyGesture="False"
WindowTitle="{DynamicResource previewHotkey}" />
</cc:Card>
@ -105,8 +103,7 @@
Type="Inside">
<flowlauncher:HotkeyControl
DefaultHotkey="Ctrl+I"
Hotkey="{Binding Settings.OpenContextMenuHotkey}"
HotkeySettings="{Binding Settings}"
Type="OpenContextMenuHotkey"
ValidateKeyGesture="False" />
</cc:Card>
<cc:Card
@ -127,8 +124,7 @@
Type="Inside">
<flowlauncher:HotkeyControl
DefaultHotkey="Ctrl+I"
Hotkey="{Binding Settings.SettingWindowHotkey}"
HotkeySettings="{Binding Settings}"
Type="SettingWindowHotkey"
ValidateKeyGesture="False" />
</cc:Card>
<cc:Card
@ -149,8 +145,7 @@
Type="Inside">
<flowlauncher:HotkeyControl
DefaultHotkey="Alt+Up"
Hotkey="{Binding Settings.CycleHistoryUpHotkey}"
HotkeySettings="{Binding Settings}"
Type="CycleHistoryUpHotkey"
ValidateKeyGesture="False" />
</cc:Card>
<cc:Card
@ -159,8 +154,7 @@
Type="Inside">
<flowlauncher:HotkeyControl
DefaultHotkey="Alt+Down"
Hotkey="{Binding Settings.CycleHistoryDownHotkey}"
HotkeySettings="{Binding Settings}"
Type="CycleHistoryDownHotkey"
ValidateKeyGesture="False" />
</cc:Card>
<cc:Card
@ -176,8 +170,7 @@
Type="Inside">
<flowlauncher:HotkeyControl
DefaultHotkey=""
Hotkey="{Binding Settings.SelectPrevPageHotkey}"
HotkeySettings="{Binding Settings}"
Type="SelectPrevPageHotkey"
ValidateKeyGesture="False" />
</cc:Card>
<cc:Card
@ -186,8 +179,7 @@
Type="Inside">
<flowlauncher:HotkeyControl
DefaultHotkey=""
Hotkey="{Binding Settings.SelectNextPageHotkey}"
HotkeySettings="{Binding Settings}"
Type="SelectNextPageHotkey"
ValidateKeyGesture="False" />
</cc:Card>
@ -221,8 +213,7 @@
<cc:ExCard.SideContent>
<flowlauncher:HotkeyControl
DefaultHotkey="Ctrl+Tab"
Hotkey="{Binding Settings.AutoCompleteHotkey}"
HotkeySettings="{Binding Settings}"
Type="AutoCompleteHotkey"
ValidateKeyGesture="False" />
</cc:ExCard.SideContent>
<cc:Card
@ -231,8 +222,7 @@
Type="InsideFit">
<flowlauncher:HotkeyControl
DefaultHotkey=""
Hotkey="{Binding Settings.AutoCompleteHotkey2}"
HotkeySettings="{Binding Settings}"
Type="AutoCompleteHotkey2"
ValidateKeyGesture="False" />
</cc:Card>
</cc:ExCard>
@ -244,8 +234,7 @@
<cc:ExCard.SideContent>
<flowlauncher:HotkeyControl
DefaultHotkey="Shift+Tab"
Hotkey="{Binding Settings.SelectPrevItemHotkey}"
HotkeySettings="{Binding Settings}"
Type="SelectPrevItemHotkey"
ValidateKeyGesture="False" />
</cc:ExCard.SideContent>
<cc:Card
@ -254,8 +243,7 @@
Type="InsideFit">
<flowlauncher:HotkeyControl
DefaultHotkey=""
Hotkey="{Binding Settings.SelectPrevItemHotkey2}"
HotkeySettings="{Binding Settings}"
Type="SelectPrevItemHotkey2"
ValidateKeyGesture="False" />
</cc:Card>
</cc:ExCard>
@ -267,8 +255,7 @@
<cc:ExCard.SideContent>
<flowlauncher:HotkeyControl
DefaultHotkey="Tab"
Hotkey="{Binding Settings.SelectNextItemHotkey}"
HotkeySettings="{Binding Settings}"
Type="SelectNextItemHotkey"
ValidateKeyGesture="False" />
</cc:ExCard.SideContent>
<cc:Card
@ -277,8 +264,7 @@
Type="InsideFit">
<flowlauncher:HotkeyControl
DefaultHotkey=""
Hotkey="{Binding Settings.SelectNextItemHotkey2}"
HotkeySettings="{Binding Settings}"
Type="SelectNextItemHotkey2"
ValidateKeyGesture="False" />
</cc:Card>
</cc:ExCard>

View file

@ -1,6 +1,7 @@
using System;
using System.Windows.Navigation;
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.SettingPages.ViewModels;
using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher.SettingPages.Views;
@ -12,8 +13,7 @@ public partial class SettingsPaneHotkey
{
if (!IsInitialized)
{
if (e.ExtraData is not SettingWindow.PaneData { Settings: { } settings })
throw new ArgumentException("Settings are required for SettingsPaneHotkey.");
var settings = Ioc.Default.GetRequiredService<Settings>();
_viewModel = new SettingsPaneHotkeyViewModel(settings);
DataContext = _viewModel;
InitializeComponent();

View file

@ -1,10 +1,11 @@
using System;
using System.ComponentModel;
using System.ComponentModel;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.SettingPages.ViewModels;
using Flow.Launcher.ViewModel;
using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher.SettingPages.Views;
@ -16,8 +17,7 @@ public partial class SettingsPanePluginStore
{
if (!IsInitialized)
{
if (e.ExtraData is not SettingWindow.PaneData { Settings: { } settings })
throw new ArgumentException($"Settings are required for {nameof(SettingsPanePluginStore)}.");
var settings = Ioc.Default.GetRequiredService<Settings>();
_viewModel = new SettingsPanePluginStoreViewModel();
DataContext = _viewModel;
InitializeComponent();

View file

@ -1,7 +1,8 @@
using System;
using System.Windows.Input;
using System.Windows.Input;
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.SettingPages.ViewModels;
using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher.SettingPages.Views;
@ -13,8 +14,7 @@ public partial class SettingsPanePlugins
{
if (!IsInitialized)
{
if (e.ExtraData is not SettingWindow.PaneData { Settings: { } settings })
throw new ArgumentException("Settings are required for SettingsPaneHotkey.");
var settings = Ioc.Default.GetRequiredService<Settings>();
_viewModel = new SettingsPanePluginsViewModel(settings);
DataContext = _viewModel;
InitializeComponent();

View file

@ -1,6 +1,8 @@
using System;
using System.Windows.Navigation;
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core;
using Flow.Launcher.SettingPages.ViewModels;
using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher.SettingPages.Views;
@ -12,8 +14,8 @@ public partial class SettingsPaneProxy
{
if (!IsInitialized)
{
if (e.ExtraData is not SettingWindow.PaneData { Settings: { } settings, Updater: { } updater })
throw new ArgumentException($"Settings are required for {nameof(SettingsPaneProxy)}.");
var settings = Ioc.Default.GetRequiredService<Settings>();
var updater = Ioc.Default.GetRequiredService<Updater>();
_viewModel = new SettingsPaneProxyViewModel(settings, updater);
DataContext = _viewModel;
InitializeComponent();

View file

@ -303,7 +303,7 @@
Width="400"
Margin="40 30 0 30"
SnapsToDevicePixels="True"
Style="{DynamicResource WindowBorderStyle}">
Style="{DynamicResource PreviewWindowBorderStyle}">
<Border BorderThickness="0" Style="{DynamicResource WindowRadius}">
<Grid>
<Grid.RowDefinitions>
@ -370,17 +370,6 @@
</DockPanel>
</Border>
</Grid>
<!-- Drop shadow effect -->
<cc:Card
Title="{DynamicResource queryWindowShadowEffect}"
Margin="0 8 0 0"
Icon="&#xeb91;"
Sub="{DynamicResource shadowEffectCPUUsage}">
<ui:ToggleSwitch
IsOn="{Binding DropShadowEffect}"
OffContent="{DynamicResource disable}"
OnContent="{DynamicResource enable}" />
</cc:Card>
<!-- Theme -->
<cc:ExCard
@ -469,12 +458,46 @@
</ListBox.Template>
</ListBox>
</cc:ExCard>
<cc:CardGroup Margin="0 10 0 0">
<!-- Backdrop effect -->
<cc:Card
Title="{DynamicResource BackdropType}"
Margin="0 0 0 0"
Icon="&#xeb42;">
<ComboBox
MinWidth="160"
VerticalAlignment="Center"
DisplayMemberPath="Display"
FontSize="14"
IsEnabled="{Binding IsBackdropEnabled}"
ItemsSource="{Binding BackdropTypesList}"
SelectedValue="{Binding BackdropType, Mode=TwoWay}"
SelectedValuePath="Value" />
<!-- ✅ 추가 -->
</cc:Card>
<!-- Drop shadow effect -->
<cc:Card
Title="{DynamicResource queryWindowShadowEffect}"
Margin="0 0 0 0"
Icon="&#xeb91;">
<ui:ToggleSwitch
IsEnabled="{Binding IsDropShadowEnabled}"
IsOn="{Binding DropShadowEffect}"
OffContent="{DynamicResource disable}"
OnContent="{DynamicResource enable}" />
</cc:Card>
</cc:CardGroup>
<cc:HyperLink
Margin="10"
HorizontalAlignment="Right"
Text="{DynamicResource browserMoreThemes}"
Uri="{Binding LinkThemeGallery}" />
<!-- Fixed Height -->
<cc:CardGroup Margin="0 20 0 0">
<cc:Card
@ -667,9 +690,8 @@
DisplayMemberPath="Display"
FontSize="14"
ItemsSource="{Binding ColorSchemes}"
SelectedValue="{Binding Settings.ColorScheme}"
SelectedValuePath="Value"
SelectionChanged="Selector_OnSelectionChanged" />
SelectedValue="{Binding ColorScheme, Mode=TwoWay}"
SelectedValuePath="Value" />
</cc:Card>
<!-- Theme folder -->

View file

@ -1,10 +1,8 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Navigation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.SettingPages.ViewModels;
using Page = ModernWpf.Controls.Page;
using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher.SettingPages.Views;
@ -16,8 +14,7 @@ public partial class SettingsPaneTheme : Page
{
if (!IsInitialized)
{
if (e.ExtraData is not SettingWindow.PaneData { Settings: { } settings })
throw new ArgumentException($"Settings are required for {nameof(SettingsPaneTheme)}.");
var settings = Ioc.Default.GetRequiredService<Settings>();
_viewModel = new SettingsPaneThemeViewModel(settings);
DataContext = _viewModel;
InitializeComponent();
@ -25,9 +22,4 @@ public partial class SettingsPaneTheme : Page
base.OnNavigatedTo(e);
}
private void Selector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
_viewModel.UpdateColorScheme();
}
}

View file

@ -4,9 +4,7 @@ using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Interop;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core;
using Flow.Launcher.Core.Configuration;
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.SettingPages.Views;
@ -18,8 +16,6 @@ namespace Flow.Launcher;
public partial class SettingWindow
{
private readonly Updater _updater;
private readonly IPortable _portable;
private readonly IPublicAPI _api;
private readonly Settings _settings;
private readonly SettingWindowViewModel _viewModel;
@ -30,8 +26,6 @@ public partial class SettingWindow
_settings = Ioc.Default.GetRequiredService<Settings>();
DataContext = viewModel;
_viewModel = viewModel;
_updater = Ioc.Default.GetRequiredService<Updater>();
_portable = Ioc.Default.GetRequiredService<Portable>();
_api = Ioc.Default.GetRequiredService<IPublicAPI>();
InitializePosition();
InitializeComponent();
@ -98,13 +92,13 @@ public partial class SettingWindow
{
if (WindowState == WindowState.Maximized)
{
MaximizeButton.Visibility = Visibility.Collapsed;
MaximizeButton.Visibility = Visibility.Hidden;
RestoreButton.Visibility = Visibility.Visible;
}
else
{
MaximizeButton.Visibility = Visibility.Visible;
RestoreButton.Visibility = Visibility.Collapsed;
RestoreButton.Visibility = Visibility.Hidden;
}
}
@ -149,8 +143,8 @@ public partial class SettingWindow
private double WindowLeft()
{
var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position);
var dip1 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.X, 0);
var dip2 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.Width, 0);
var dip1 = Win32Helper.TransformPixelsToDIP(this, screen.WorkingArea.X, 0);
var dip2 = Win32Helper.TransformPixelsToDIP(this, screen.WorkingArea.Width, 0);
var left = (dip2.X - ActualWidth) / 2 + dip1.X;
return left;
}
@ -158,18 +152,17 @@ public partial class SettingWindow
private double WindowTop()
{
var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position);
var dip1 = WindowsInteropHelper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Y);
var dip2 = WindowsInteropHelper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Height);
var dip1 = Win32Helper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Y);
var dip2 = Win32Helper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Height);
var top = (dip2.Y - ActualHeight) / 2 + dip1.Y - 20;
return top;
}
private void NavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
var paneData = new PaneData(_settings, _updater, _portable);
if (args.IsSettingsSelected)
{
ContentFrame.Navigate(typeof(SettingsPaneGeneral), paneData);
ContentFrame.Navigate(typeof(SettingsPaneGeneral));
}
else
{
@ -191,7 +184,7 @@ public partial class SettingWindow
nameof(About) => typeof(SettingsPaneAbout),
_ => typeof(SettingsPaneGeneral)
};
ContentFrame.Navigate(pageType, paneData);
ContentFrame.Navigate(pageType);
}
}
@ -211,6 +204,4 @@ public partial class SettingWindow
{
NavView.SelectedItem ??= NavView.MenuItems[0]; /* Set First Page */
}
public record PaneData(Settings Settings, Updater Updater, IPortable Portable);
}

View file

@ -27,7 +27,6 @@
<Style x:Key="BaseQueryBoxStyle" TargetType="{x:Type TextBox}">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="FontSize" Value="28" />
<Setter Property="FontWeight" Value="Regular" />
<Setter Property="Margin" Value="16 7 0 7" />
<Setter Property="Padding" Value="0 0 68 0" />
<Setter Property="Background" Value="Transparent" />
@ -107,7 +106,7 @@
</Style>
<Style x:Key="BasePendingLineStyle" TargetType="{x:Type Line}">
<Setter Property="Stroke" Value="Blue" />
<Setter Property="Stroke" Value="{StaticResource SystemAccentColorLight1Brush}" />
</Style>
<Style x:Key="BaseClockPanelPosition" TargetType="{x:Type Canvas}" />
@ -165,29 +164,6 @@
BasedOn="{StaticResource BaseClockPanel}"
TargetType="{x:Type StackPanel}">
<Setter Property="Orientation" Value="Vertical" />
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=QueryTextBox, UpdateSourceTrigger=PropertyChanged, Path=Text.Length}" Value="0" />
<Condition Binding="{Binding ElementName=ContextMenu, Path=Visibility}" Value="Collapsed" />
<Condition Binding="{Binding ElementName=History, Path=Visibility}" Value="Collapsed" />
</MultiDataTrigger.Conditions>
<Setter Property="Visibility" Value="Visible" />
<MultiDataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="Opacity"
From="0.0"
To="1"
Duration="0:0:0.25" />
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
</MultiDataTrigger>
</Style.Triggers>
</Style>
<!-- Item Style -->
@ -204,12 +180,10 @@
<Style x:Key="BaseItemTitleStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="#FFFFF8" />
<Setter Property="FontSize" Value="16" />
<Setter Property="FontWeight" Value="Medium" />
</Style>
<Style x:Key="BaseItemSubTitleStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="#D9D9D4" />
<Setter Property="FontSize" Value="13" />
<Setter Property="FontWeight" Value="Normal" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=SubTitle, UpdateSourceTrigger=PropertyChanged, Path=Text.Length}" Value="0">
<Setter Property="Height" Value="0" />
@ -241,7 +215,6 @@
<Style x:Key="BaseItemTitleSelectedStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="#FFFFF8" />
<Setter Property="FontSize" Value="16" />
<Setter Property="FontWeight" Value="Normal" />
</Style>
<Style x:Key="BaseItemSubTitleSelectedStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="#D9D9D4" />
@ -417,6 +390,7 @@
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=History, Path=Visibility}" Value="Collapsed" />
<Condition Binding="{Binding ElementName=ResultListBox, Path=Items.Count}" Value="0" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
@ -458,12 +432,12 @@
</DataTrigger>
</Style.Triggers>
</Style>
<Style
x:Key="PreviewBorderStyle"
BasedOn="{StaticResource BasePreviewBorderStyle}"
TargetType="{x:Type Border}">
<Setter Property="BorderBrush" Value="Gray" />
</Style>
<Style x:Key="PreviewArea" TargetType="{x:Type Grid}">
@ -473,8 +447,8 @@
<MultiDataTrigger.Conditions>
<!--
<Condition Binding="{Binding ElementName=ResultListBox, Path=Visibility}" Value="Collapsed" />
<Condition Binding="{Binding ElementName=ContextMenu, Path=Visibility}" Value="Collapsed" />
<Condition Binding="{Binding ElementName=History, Path=Visibility}" Value="Collapsed" />-->
<Condition Binding="{Binding ElementName=ContextMenu, 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>
<MultiDataTrigger.Setters>
@ -557,6 +531,14 @@
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
<Style x:Key="PreviewWindowBorderStyle" TargetType="{x:Type Border}">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Background" Value="#2F2F2F" />
<Setter Property="Padding" Value="0 0 0 0" />
<Setter Property="CornerRadius" Value="5" />
<Setter Property="UseLayoutRounding" Value="True" />
<Setter Property="SnapsToDevicePixels" Value="True" />
</Style>
<!-- Style for old version themes -->
<Style
x:Key="PreviewItemTitleStyle"

View file

@ -12,6 +12,9 @@
</ResourceDictionary.MergedDictionaries>
<system:Boolean x:Key="ThemeBlurEnabled">True</system:Boolean>
<system:String x:Key="SystemBG">Dark</system:String>
<Color x:Key="LightBG">#C7000000</Color>
<Color x:Key="DarkBG">#C7000000</Color>
<Style x:Key="WindowRadius" TargetType="{x:Type Border}">
<Setter Property="CornerRadius" Value="0" />
@ -51,7 +54,6 @@
</Setter.Value>
</Setter>
</Style>
<Style
x:Key="SeparatorStyle"
BasedOn="{StaticResource BaseSeparatorStyle}"
@ -139,8 +141,8 @@
BasedOn="{StaticResource BaseSearchIconStyle}"
TargetType="{x:Type Path}">
<Setter Property="Fill" Value="#ffffff" />
<Setter Property="Width" Value="32" />
<Setter Property="Height" Value="32" />
<Setter Property="Width" Value="30" />
<Setter Property="Height" Value="30" />
<Setter Property="Opacity" Value="0.2" />
</Style>
<Style x:Key="ItemHotkeyStyle" TargetType="{x:Type TextBlock}">

View file

@ -10,8 +10,11 @@
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Themes/Base.xaml" />
</ResourceDictionary.MergedDictionaries>
<system:Boolean x:Key="ThemeBlurEnabled">True</system:Boolean>
<system:String x:Key="SystemBG">Dark</system:String>
<Color x:Key="LightBG">#B0000000</Color>
<Color x:Key="DarkBG">#B6000000</Color>
<Style x:Key="WindowRadius" TargetType="{x:Type Border}">
<Setter Property="CornerRadius" Value="0" />
</Style>
@ -135,8 +138,8 @@
BasedOn="{StaticResource BaseSearchIconStyle}"
TargetType="{x:Type Path}">
<Setter Property="Fill" Value="#ffffff" />
<Setter Property="Width" Value="32" />
<Setter Property="Height" Value="32" />
<Setter Property="Width" Value="30" />
<Setter Property="Height" Value="30" />
<Setter Property="Opacity" Value="0.5" />
</Style>
<Style x:Key="ItemHotkeyStyle" TargetType="{x:Type TextBlock}">

View file

@ -10,14 +10,24 @@
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Themes/Base.xaml" />
</ResourceDictionary.MergedDictionaries>
<system:Boolean x:Key="ThemeBlurEnabled">True</system:Boolean>
<system:String x:Key="SystemBG">Light</system:String>
<Color x:Key="LightBG">#BFFAFAFA</Color>
<Color x:Key="DarkBG">#BFFAFAFA</Color>
<Style
x:Key="ItemGlyph"
BasedOn="{StaticResource BaseGlyphStyle}"
TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="#FF000000" />
</Style>
<Style x:Key="ItemGlyphSelectedStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="#FF000000" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="Width" Value="25" />
<Setter Property="Height" Value="25" />
<Setter Property="FontSize" Value="25" />
</Style>
<Style x:Key="WindowRadius" TargetType="{x:Type Border}">
<Setter Property="CornerRadius" Value="0" />
</Style>
@ -33,7 +43,9 @@
<Style
x:Key="QuerySuggestionBoxStyle"
BasedOn="{StaticResource BaseQuerySuggestionBoxStyle}"
TargetType="{x:Type TextBox}" />
TargetType="{x:Type TextBox}">
<Setter Property="Foreground" Value="#39000000" />
</Style>
<Style
x:Key="WindowBorderStyle"
@ -76,7 +88,7 @@
x:Key="ItemSubTitleStyle"
BasedOn="{StaticResource BaseItemSubTitleStyle}"
TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="#818181" />
<Setter Property="Foreground" Value="#85000000" />
</Style>
<Style
x:Key="ItemTitleSelectedStyle"
@ -88,18 +100,18 @@
x:Key="ItemSubTitleSelectedStyle"
BasedOn="{StaticResource BaseItemSubTitleSelectedStyle}"
TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="#72767d" />
<Setter Property="Foreground" Value="#85000000" />
</Style>
<SolidColorBrush
x:Key="ItemSelectedBackgroundColor"
Opacity="0.5"
Color="#ccd0d4" />
Opacity="0.6"
Color="#33000000" />
<Style
x:Key="SeparatorStyle"
BasedOn="{StaticResource BaseSeparatorStyle}"
TargetType="{x:Type Rectangle}">
<Setter Property="Fill" Value="#c6c6c6" />
<Setter Property="Fill" Value="#22000000" />
<Setter Property="Height" Value="1" />
<Setter Property="Margin" Value="12 0 12 8" />
</Style>
@ -112,7 +124,7 @@
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border
Background="#bebebe"
Background="#3C000000"
BorderBrush="Transparent"
BorderThickness="0"
CornerRadius="2"
@ -132,8 +144,8 @@
BasedOn="{StaticResource BaseSearchIconStyle}"
TargetType="{x:Type Path}">
<Setter Property="Fill" Value="#000000" />
<Setter Property="Width" Value="32" />
<Setter Property="Height" Value="32" />
<Setter Property="Width" Value="30" />
<Setter Property="Height" Value="30" />
<Setter Property="Opacity" Value="0.2" />
</Style>
<Style x:Key="ItemHotkeyStyle" TargetType="{x:Type TextBlock}">

View file

@ -1,7 +1,7 @@
<!--
Name: Circle
IsDark: True
HasBlur: False
HasBlur: True
-->
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
@ -12,6 +12,10 @@
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Themes/Base.xaml" />
</ResourceDictionary.MergedDictionaries>
<system:Boolean x:Key="ThemeBlurEnabled">True</system:Boolean>
<system:String x:Key="SystemBG">Auto</system:String>
<Color x:Key="LightBG">#E5E6E6E6</Color>
<Color x:Key="DarkBG">#DF1F1F1F</Color>
<Style
x:Key="ItemGlyph"
BasedOn="{StaticResource BaseGlyphStyle}"
@ -23,7 +27,7 @@
BasedOn="{StaticResource BaseQueryBoxStyle}"
TargetType="{x:Type TextBox}">
<Setter Property="Padding" Value="0 4 50 0" />
<Setter Property="Foreground" Value="{m:DynamicColor SystemControlPageTextBaseHighBrush}" />
<Setter Property="Foreground" Value="{m:DynamicColor SystemControlHighlightBaseHighBrush}" />
<Setter Property="FontSize" Value="18" />
<Setter Property="Height" Value="38" />
</Style>
@ -75,7 +79,7 @@
x:Key="SeparatorStyle"
BasedOn="{StaticResource BaseSeparatorStyle}"
TargetType="{x:Type Rectangle}">
<Setter Property="Fill" Value="{m:DynamicColor SystemControlBackgroundChromeMediumBrush}" />
<Setter Property="Fill" Value="{DynamicResource SeparatorForeground}" />
<Setter Property="Height" Value="1" />
<Setter Property="Margin" Value="0 0 0 8" />
</Style>

View file

@ -29,7 +29,9 @@
<Style
x:Key="WindowBorderStyle"
BasedOn="{StaticResource BaseWindowBorderStyle}"
TargetType="{x:Type Border}" />
TargetType="{x:Type Border}">
<Setter Property="Background" Value="#2F2F2F" />
</Style>
<Style
x:Key="WindowStyle"
@ -89,7 +91,7 @@
TargetType="{x:Type Rectangle}">
<Setter Property="Fill" Value="#3b3b3b" />
<Setter Property="Height" Value="1" />
<Setter Property="Margin" Value="8,0,8,8" />
<Setter Property="Margin" Value="8 0 8 8" />
</Style>
<Style
x:Key="PreviewBorderStyle"

View file

@ -2,46 +2,45 @@
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Themes/Base.xaml" />
</ResourceDictionary.MergedDictionaries>
<Thickness x:Key="ResultMargin">0 0 0 0</Thickness>
<Thickness x:Key="ResultMargin">0 0 0 4</Thickness>
<Style
x:Key="ItemGlyph"
BasedOn="{StaticResource BaseGlyphStyle}"
TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="#0e172c" />
<Setter Property="Foreground" Value="#ffffff" />
</Style>
<Style
x:Key="QueryBoxStyle"
BasedOn="{StaticResource BaseQueryBoxStyle}"
TargetType="{x:Type TextBox}">
<Setter Property="Foreground" Value="#0E172C" />
<Setter Property="CaretBrush" Value="#0E172C" />
<Setter Property="SelectionBrush" Value="#a786df" />
<Setter Property="Foreground" Value="#cc1081" />
<Setter Property="CaretBrush" Value="#cc1081" />
<Setter Property="SelectionBrush" Value="#e564b1" />
</Style>
<Style
x:Key="QuerySuggestionBoxStyle"
BasedOn="{StaticResource BaseQuerySuggestionBoxStyle}"
TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="#E9819F" />
<Setter Property="Background" Value="#1f1d1f" />
<Setter Property="Foreground" Value="#71114b" />
</Style>
<Style
x:Key="WindowBorderStyle"
BasedOn="{StaticResource BaseWindowBorderStyle}"
TargetType="{x:Type Border}">
<Setter Property="CornerRadius" Value="8" />
<Setter Property="Background" Value="#fec7d7" />
<Setter Property="BorderThickness" Value="3" />
<Setter Property="BorderBrush" Value="#0e172c" />
<Setter Property="Background" Value="#1f1d1f" />
<Setter Property="BorderThickness" Value="2" />
<Setter Property="BorderBrush" Value="#000000" />
</Style>
<Style
x:Key="SeparatorStyle"
BasedOn="{StaticResource BaseSeparatorStyle}"
TargetType="{x:Type Rectangle}">
<Setter Property="Fill" Value="#0e172c" />
<Setter Property="Height" Value="3" />
<Setter Property="Margin" Value="0 0 0 0" />
<Setter Property="Fill" Value="#000000" />
<Setter Property="Height" Value="1" />
<Setter Property="Margin" Value="12 0 12 4" />
</Style>
<Style
x:Key="WindowStyle"
@ -51,33 +50,34 @@
x:Key="PendingLineStyle"
BasedOn="{StaticResource BasePendingLineStyle}"
TargetType="{x:Type Line}">
<Setter Property="Stroke" Value="#a786df" />
<Setter Property="Stroke" Value="#cc1081" />
</Style>
<Style
x:Key="ItemTitleStyle"
BasedOn="{StaticResource BaseItemTitleStyle}"
TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="#0e172c" />
<Setter Property="Foreground" Value="#f5f5f5" />
</Style>
<Style
x:Key="ItemSubTitleStyle"
BasedOn="{StaticResource BaseItemSubTitleStyle}"
TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="#0e172c" />
<Setter Property="Foreground" Value="#c2c2c2" />
<Setter Property="Opacity" Value="0.5" />
</Style>
<Style
x:Key="ItemTitleSelectedStyle"
BasedOn="{StaticResource BaseItemTitleSelectedStyle}"
TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="#fffffe" />
<Setter Property="Foreground" Value="#f5f5f5" />
</Style>
<Style
x:Key="ItemSubTitleSelectedStyle"
BasedOn="{StaticResource BaseItemSubTitleSelectedStyle}"
TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="#fffffe" />
<Setter Property="Foreground" Value="#ed92c9" />
</Style>
<SolidColorBrush x:Key="ItemSelectedBackgroundColor">#0e172c</SolidColorBrush>
<SolidColorBrush x:Key="ItemSelectedBackgroundColor">#cc1081</SolidColorBrush>
<Style
x:Key="ThumbStyle"
BasedOn="{StaticResource BaseThumbStyle}"
@ -86,7 +86,7 @@
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border
Background="#E9819F"
Background="#e564b1"
BorderBrush="Transparent"
BorderThickness="0"
CornerRadius="2"
@ -109,56 +109,53 @@
<Setter Property="HorizontalAlignment" Value="Right" />
</Style>
<Style x:Key="SearchIconStyle" TargetType="{x:Type Path}">
<Setter Property="Fill" Value="#E9819F" />
<Setter Property="Fill" Value="#cc1081" />
<Setter Property="Width" Value="28" />
<Setter Property="Height" Value="28" />
</Style>
<Style x:Key="ItemHotkeyStyle" TargetType="{x:Type TextBlock}">
<Setter Property="FontSize" Value="11" />
<Setter Property="Foreground" Value="#E9819F" />
<Setter Property="FontSize" Value="14" />
<Setter Property="Foreground" Value="#ed92c9" />
</Style>
<Style x:Key="ItemHotkeySelectedStyle" TargetType="{x:Type TextBlock}">
<Setter Property="FontSize" Value="11" />
<Setter Property="Foreground" Value="#E9819F" />
<Setter Property="FontSize" Value="14" />
<Setter Property="Foreground" Value="#ed92c9" />
</Style>
<Style
x:Key="ClockBox"
BasedOn="{StaticResource BaseClockBox}"
TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="#E9819F" />
<Setter Property="Foreground" Value="#71114b" />
</Style>
<Style
x:Key="DateBox"
BasedOn="{StaticResource BaseDateBox}"
TargetType="{x:Type TextBlock}">
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Foreground" Value="#E9819F" />
<Setter Property="Foreground" Value="#71114b" />
</Style>
<Style
x:Key="PreviewBorderStyle"
BasedOn="{StaticResource BasePreviewBorderStyle}"
TargetType="{x:Type Border}">
<Setter Property="Margin" Value="0 0 10 0" />
<Setter Property="Width" Value="5" />
<Setter Property="BorderThickness" Value="3 0 0 0" />
<Setter Property="BorderBrush" Value="#0e172c" />
<Setter Property="BorderBrush" Value="#000000" />
</Style>
<Style
x:Key="PreviewItemTitleStyle"
BasedOn="{StaticResource BasePreviewItemTitleStyle}"
TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="#0E172C" />
<Setter Property="Foreground" Value="#f5f5f5" />
</Style>
<Style
x:Key="PreviewItemSubTitleStyle"
BasedOn="{StaticResource BasePreviewItemSubTitleStyle}"
TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="#0E172C" />
<Setter Property="Foreground" Value="#c2c2c2" />
</Style>
<Style
x:Key="PreviewGlyph"
BasedOn="{StaticResource BasePreviewGlyph}"
TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="#0E172C" />
<Setter Property="Foreground" Value="#ffffff" />
</Style>
</ResourceDictionary>

View file

@ -32,7 +32,7 @@
x:Key="QueryBoxStyle"
BasedOn="{StaticResource BaseQueryBoxStyle}"
TargetType="{x:Type TextBox}">
<Setter Property="Padding" Value="0,4,50,0" />
<Setter Property="Padding" Value="0 4 50 0" />
<Setter Property="CaretBrush" Value="#fa7941" />
<Setter Property="Foreground" Value="#ffffff" />
<Setter Property="FontSize" Value="18" />
@ -43,7 +43,7 @@
x:Key="QuerySuggestionBoxStyle"
BasedOn="{StaticResource BaseQuerySuggestionBoxStyle}"
TargetType="{x:Type TextBox}">
<Setter Property="Padding" Value="0,4,50,0" />
<Setter Property="Padding" Value="0 4 50 0" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Height" Value="38" />
<Setter Property="FontSize" Value="18" />
@ -56,15 +56,7 @@
TargetType="{x:Type Border}">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="BorderBrush" Value="#e2e2e2" />
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Offset="0.0" Color="#383838" />
<GradientStop Offset="0.9" Color="#2e2e2e" />
<GradientStop Offset="1.0" Color="#2e2e2e" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="#2e2e2e" />
<Setter Property="CornerRadius" Value="8" />
<Setter Property="UseLayoutRounding" Value="True" />
</Style>
@ -96,7 +88,7 @@
TargetType="{x:Type Rectangle}">
<Setter Property="Fill" Value="#3b3b3b" />
<Setter Property="Height" Value="1" />
<Setter Property="Margin" Value="0,0,0,8" />
<Setter Property="Margin" Value="0 0 0 8" />
</Style>
<Style x:Key="HighlightStyle" />
<Style
@ -147,7 +139,7 @@
<Setter Property="Background" Value="Transparent" />
<Setter Property="Width" Value="32" />
<Setter Property="Height" Value="32" />
<Setter Property="Margin" Value="0,8,8,0" />
<Setter Property="Margin" Value="0 8 8 0" />
<Setter Property="HorizontalAlignment" Value="Right" />
</Style>
@ -174,7 +166,7 @@
x:Key="ClockPanel"
BasedOn="{StaticResource ClockPanel}"
TargetType="{x:Type StackPanel}">
<Setter Property="Margin" Value="0,0,54,2" />
<Setter Property="Margin" Value="0 0 54 2" />
</Style>
<Style
x:Key="ClockBox"

View file

@ -11,6 +11,10 @@
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Themes/Base.xaml" />
</ResourceDictionary.MergedDictionaries>
<system:Boolean x:Key="ThemeBlurEnabled">False</system:Boolean>
<system:String x:Key="SystemBG">Auto</system:String>
<Color x:Key="LightBG">#FFFAFAFA</Color>
<Color x:Key="DarkBG">#FF202020</Color>
<Thickness x:Key="ResultMargin">0 0 0 8</Thickness>
<Style
x:Key="ItemGlyph"
@ -175,13 +179,13 @@
x:Key="ClockBox"
BasedOn="{StaticResource BaseClockBox}"
TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="{DynamicResource ClockDateForeground}" />
<Setter Property="Foreground" Value="{DynamicResource SystemControlBackgroundBaseLowBrush}" />
</Style>
<Style
x:Key="DateBox"
BasedOn="{StaticResource BaseDateBox}"
TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="{DynamicResource ClockDateForeground}" />
<Setter Property="Foreground" Value="{DynamicResource SystemControlBackgroundBaseLowBrush}" />
</Style>
<Style
x:Key="PreviewBorderStyle"

View file

@ -1,7 +1,7 @@
<!--
Name: Windows 11
IsDark: True
HasBlur: False
HasBlur: True
-->
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
@ -12,6 +12,10 @@
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Themes/Base.xaml" />
</ResourceDictionary.MergedDictionaries>
<system:Boolean x:Key="ThemeBlurEnabled">True</system:Boolean>
<system:String x:Key="SystemBG">Auto</system:String>
<Color x:Key="LightBG">#BFFAFAFA</Color>
<Color x:Key="DarkBG">#DD202020</Color>
<Style
x:Key="BulletStyle"
BasedOn="{StaticResource BaseBulletStyle}"

File diff suppressed because it is too large Load diff

View file

@ -43,7 +43,6 @@ namespace Flow.Launcher.ViewModel
}
}
private async void LoadIconAsync()
{
Image = await ImageLoader.LoadAsync(PluginPair.Metadata.IcoPath);
@ -100,7 +99,7 @@ namespace Flow.Launcher.ViewModel
: null;
private ImageSource _image = ImageLoader.MissingImage;
public Visibility ActionKeywordsVisibility => PluginPair.Metadata.ActionKeywords.Count == 1 ? Visibility.Visible : Visibility.Collapsed;
public Visibility ActionKeywordsVisibility => PluginPair.Metadata.HideActionKeywordPanel ? Visibility.Collapsed : Visibility.Visible;
public string InitilizaTime => PluginPair.Metadata.InitTime + "ms";
public string QueryTime => PluginPair.Metadata.AvgQueryTime + "ms";
public string Version => InternationalizationManager.Instance.GetTranslation("plugin_query_version") + " " + PluginPair.Metadata.Version;
@ -109,9 +108,8 @@ namespace Flow.Launcher.ViewModel
public int Priority => PluginPair.Metadata.Priority;
public Infrastructure.UserSettings.Plugin PluginSettingsObject { get; set; }
public void ChangeActionKeyword(string newActionKeyword, string oldActionKeyword)
public void OnActionKeywordsChanged()
{
PluginManager.ReplaceActionKeyword(PluginPair.Metadata.ID, oldActionKeyword, newActionKeyword);
OnPropertyChanged(nameof(ActionKeywordsText));
}
@ -150,8 +148,6 @@ namespace Flow.Launcher.ViewModel
App.API.ShowMainWindow();
}
public static bool IsActionKeywordRegistered(string newActionKeyword) => PluginManager.ActionKeywordRegistered(newActionKeyword);
[RelayCommand]
private void SetActionKeywords()
{

View file

@ -1,4 +1,7 @@
using System;
using System.Collections.Generic;
using System.Drawing.Text;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
@ -6,25 +9,20 @@ using Flow.Launcher.Infrastructure.Image;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using System.IO;
using System.Drawing.Text;
using System.Collections.Generic;
namespace Flow.Launcher.ViewModel
{
public class ResultViewModel : BaseModel
{
private static PrivateFontCollection fontCollection = new();
private static Dictionary<string, string> fonts = new();
private static readonly PrivateFontCollection FontCollection = new();
private static readonly Dictionary<string, string> Fonts = new();
public ResultViewModel(Result result, Settings settings)
{
Settings = settings;
if (result == null)
{
return;
}
if (result == null) return;
Result = result;
if (Result.Glyph is { FontFamily: not null } glyph)
@ -39,20 +37,20 @@ namespace Flow.Launcher.ViewModel
fontFamilyPath = Path.Combine(Result.PluginDirectory, fontFamilyPath);
}
if (fonts.ContainsKey(fontFamilyPath))
if (Fonts.TryGetValue(fontFamilyPath, out var value))
{
Glyph = glyph with
{
FontFamily = fonts[fontFamilyPath]
FontFamily = value
};
}
else
{
fontCollection.AddFontFile(fontFamilyPath);
fonts[fontFamilyPath] = $"{Path.GetDirectoryName(fontFamilyPath)}/#{fontCollection.Families[^1].Name}";
FontCollection.AddFontFile(fontFamilyPath);
Fonts[fontFamilyPath] = $"{Path.GetDirectoryName(fontFamilyPath)}/#{FontCollection.Families[^1].Name}";
Glyph = glyph with
{
FontFamily = fonts[fontFamilyPath]
FontFamily = Fonts[fontFamilyPath]
};
}
}
@ -61,7 +59,6 @@ namespace Flow.Launcher.ViewModel
Glyph = glyph;
}
}
}
public Settings Settings { get; }
@ -95,14 +92,10 @@ namespace Flow.Launcher.ViewModel
get
{
if (PreviewImageAvailable)
{
return Visibility.Visible;
}
else
{
// Fall back to icon
return ShowIcon;
}
// Fall back to icon
return ShowIcon;
}
}
@ -111,9 +104,8 @@ namespace Flow.Launcher.ViewModel
get
{
if (Result.RoundedIcon)
{
return IconXY / 2;
}
return IconXY;
}
@ -148,31 +140,40 @@ namespace Flow.Launcher.ViewModel
? Result.SubTitle
: Result.SubTitleToolTip;
private volatile bool ImageLoaded;
private volatile bool PreviewImageLoaded;
private volatile bool _imageLoaded;
private volatile bool _previewImageLoaded;
private ImageSource image = ImageLoader.LoadingImage;
private ImageSource previewImage = ImageLoader.LoadingImage;
private ImageSource _image = ImageLoader.LoadingImage;
private ImageSource _previewImage = ImageLoader.LoadingImage;
public ImageSource Image
{
get
{
if (!ImageLoaded)
if (!_imageLoaded)
{
ImageLoaded = true;
_imageLoaded = true;
_ = LoadImageAsync();
}
return image;
return _image;
}
private set => image = value;
private set => _image = value;
}
public ImageSource PreviewImage
{
get => previewImage;
private set => previewImage = value;
get
{
if (!_previewImageLoaded)
{
_previewImageLoaded = true;
_ = LoadPreviewImageAsync();
}
return _previewImage;
}
private set => _previewImage = value;
}
/// <summary>
@ -188,8 +189,7 @@ namespace Flow.Launcher.ViewModel
{
try
{
var image = icon();
return image;
return icon();
}
catch (Exception e)
{
@ -208,7 +208,7 @@ namespace Flow.Launcher.ViewModel
var iconDelegate = Result.Icon;
if (ImageLoader.TryGetValue(imagePath, false, out ImageSource img))
{
image = img;
_image = img;
}
else
{
@ -223,7 +223,7 @@ namespace Flow.Launcher.ViewModel
var iconDelegate = Result.Preview.PreviewDelegate ?? Result.Icon;
if (ImageLoader.TryGetValue(imagePath, true, out ImageSource img))
{
previewImage = img;
_previewImage = img;
}
else
{
@ -234,13 +234,10 @@ namespace Flow.Launcher.ViewModel
public void LoadPreviewImage()
{
if (ShowDefaultPreview == Visibility.Visible)
if (ShowDefaultPreview == Visibility.Visible && !_previewImageLoaded && ShowPreviewImage == Visibility.Visible)
{
if (!PreviewImageLoaded && ShowPreviewImage == Visibility.Visible)
{
PreviewImageLoaded = true;
_ = LoadPreviewImageAsync();
}
_previewImageLoaded = true;
_ = LoadPreviewImageAsync();
}
}

View file

@ -1,6 +1,4 @@
using System;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
@ -10,6 +8,8 @@ using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
namespace Flow.Launcher.ViewModel
{
@ -28,6 +28,7 @@ namespace Flow.Launcher.ViewModel
Results = new ResultCollection();
BindingOperations.EnableCollectionSynchronization(Results, _collectionLock);
}
public ResultsViewModel(Settings settings) : this()
{
_settings = settings;
@ -219,7 +220,6 @@ namespace Flow.Launcher.ViewModel
if (newRawResults.Count == 0)
return Results;
var newResults = newRawResults.Select(r => new ResultViewModel(r, _settings));
return Results.Where(r => r.Result.PluginID != resultId)
@ -241,6 +241,7 @@ namespace Flow.Launcher.ViewModel
#endregion
#region FormattedText Dependency Property
public static readonly DependencyProperty FormattedTextProperty = DependencyProperty.RegisterAttached(
"FormattedText",
typeof(Inline),
@ -259,8 +260,7 @@ namespace Flow.Launcher.ViewModel
private static void FormattedTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var textBlock = d as TextBlock;
if (textBlock == null) return;
if (d is not TextBlock textBlock) return;
var inline = (Inline)e.NewValue;
@ -269,6 +269,7 @@ namespace Flow.Launcher.ViewModel
textBlock.Inlines.Add(inline);
}
#endregion
public class ResultCollection : List<ResultViewModel>, INotifyCollectionChanged
@ -279,7 +280,6 @@ namespace Flow.Launcher.ViewModel
public event NotifyCollectionChangedEventHandler CollectionChanged;
protected void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
CollectionChanged?.Invoke(this, e);
@ -297,6 +297,7 @@ namespace Flow.Launcher.ViewModel
// wpf use DirectX / double buffered already, so just reset all won't cause ui flickering
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
private void AddAll(List<ResultViewModel> Items)
{
for (int i = 0; i < Items.Count; i++)
@ -308,6 +309,7 @@ namespace Flow.Launcher.ViewModel
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, i));
}
}
public void RemoveAll(int Capacity = 512)
{
Clear();

View file

@ -0,0 +1,68 @@
using Flow.Launcher.Plugin;
namespace Flow.Launcher.ViewModel
{
public partial class WelcomeViewModel : BaseModel
{
public const int MaxPageNum = 5;
public string PageDisplay => $"{PageNum}/5";
private int _pageNum = 1;
public int PageNum
{
get => _pageNum;
set
{
if (_pageNum != value)
{
_pageNum = value;
OnPropertyChanged();
UpdateView();
}
}
}
private bool _backEnabled = false;
public bool BackEnabled
{
get => _backEnabled;
set
{
_backEnabled = value;
OnPropertyChanged();
}
}
private bool _nextEnabled = true;
public bool NextEnabled
{
get => _nextEnabled;
set
{
_nextEnabled = value;
OnPropertyChanged();
}
}
private void UpdateView()
{
OnPropertyChanged(nameof(PageDisplay));
if (PageNum == 1)
{
BackEnabled = false;
NextEnabled = true;
}
else if (PageNum == MaxPageNum)
{
BackEnabled = true;
NextEnabled = false;
}
else
{
BackEnabled = true;
NextEnabled = true;
}
}
}
}

View file

@ -6,6 +6,7 @@
xmlns:local="clr-namespace:Flow.Launcher"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.modernwpf.com/2019"
xmlns:vm="clr-namespace:Flow.Launcher.ViewModel"
Name="FlowWelcomeWindow"
Title="{DynamicResource Welcome_Page1_Title}"
Width="550"
@ -14,8 +15,10 @@
MinHeight="650"
MaxWidth="550"
MaxHeight="650"
d:DataContext="{d:DesignInstance Type=vm:WelcomeViewModel}"
Activated="OnActivated"
Background="{DynamicResource Color00B}"
Closed="Window_Closed"
Foreground="{DynamicResource PopupTextColor}"
MouseDown="window_MouseDown"
WindowStartupLocation="CenterScreen"
@ -41,12 +44,12 @@
Grid.Column="0"
Width="16"
Height="16"
Margin="10,4,4,4"
Margin="10 4 4 4"
RenderOptions.BitmapScalingMode="HighQuality"
Source="/Images/app.png" />
<TextBlock
Grid.Column="1"
Margin="4,0,0,0"
Margin="4 0 0 0"
VerticalAlignment="Center"
FontSize="12"
Foreground="{DynamicResource Color05B}"
@ -95,7 +98,7 @@
Grid.Row="1"
Background="{DynamicResource Color00B}"
BorderBrush="{DynamicResource PopupButtonAreaBorderColor}"
BorderThickness="0,1,0,0">
BorderThickness="0 1 0 0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="130" />
@ -109,11 +112,11 @@
VerticalAlignment="Center">
<TextBlock
Name="PageNavigation"
Margin="0,2,0,0"
Margin="0 2 0 0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="14"
Text="{Binding PageDisplay, Mode=OneWay, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"
Text="{Binding PageDisplay, Mode=OneWay}"
TextAlignment="Center" />
</StackPanel>
@ -122,25 +125,26 @@
Grid.Column="0"
Width="100"
Height="40"
Margin="20,5,0,5"
Margin="20 5 0 5"
Click="BtnCancel_OnClick"
Content="{DynamicResource Skip}"
DockPanel.Dock="Right"
FontSize="14" />
<DockPanel
Grid.Column="2"
Margin="0,0,20,0"
Margin="0 0 20 0"
VerticalAlignment="Stretch">
<Button
x:Name="NextButton"
Width="40"
Height="40"
Margin="8,5,0,5"
Margin="8 5 0 5"
Click="ForwardButton_Click"
Content="&#xe76c;"
DockPanel.Dock="Right"
FontFamily="/Resources/#Segoe Fluent Icons"
FontSize="18" />
FontSize="18"
IsEnabled="{Binding NextEnabled, Mode=OneWay}" />
<Button
x:Name="BackButton"
Width="40"
@ -149,7 +153,8 @@
Content="&#xe76b;"
DockPanel.Dock="Right"
FontFamily="/Resources/#Segoe Fluent Icons"
FontSize="18" />
FontSize="18"
IsEnabled="{Binding BackEnabled, Mode=OneWay}" />
<StackPanel />
</DockPanel>

View file

@ -2,75 +2,57 @@
using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Resources.Pages;
using ModernWpf.Media.Animation;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.ViewModel;
using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher
{
public partial class WelcomeWindow : Window
{
private readonly Settings settings;
private readonly WelcomeViewModel _viewModel;
public WelcomeWindow(Settings settings)
{
InitializeComponent();
BackButton.IsEnabled = false;
this.settings = settings;
}
private NavigationTransitionInfo _transitionInfo = new SlideNavigationTransitionInfo()
private readonly NavigationTransitionInfo _forwardTransitionInfo = new SlideNavigationTransitionInfo()
{
Effect = SlideNavigationTransitionEffect.FromRight
};
private NavigationTransitionInfo _backTransitionInfo = new SlideNavigationTransitionInfo()
private readonly NavigationTransitionInfo _backTransitionInfo = new SlideNavigationTransitionInfo()
{
Effect = SlideNavigationTransitionEffect.FromLeft
};
private int pageNum = 1;
private int MaxPage = 5;
public string PageDisplay => $"{pageNum}/5";
private void UpdateView()
public WelcomeWindow()
{
PageNavigation.Text = PageDisplay;
if (pageNum == 1)
{
BackButton.IsEnabled = false;
NextButton.IsEnabled = true;
}
else if (pageNum == MaxPage)
{
BackButton.IsEnabled = true;
NextButton.IsEnabled = false;
}
else
{
BackButton.IsEnabled = true;
NextButton.IsEnabled = true;
}
_viewModel = Ioc.Default.GetRequiredService<WelcomeViewModel>();
DataContext = _viewModel;
InitializeComponent();
}
private void ForwardButton_Click(object sender, RoutedEventArgs e)
{
pageNum++;
UpdateView();
ContentFrame.Navigate(PageTypeSelector(pageNum), settings, _transitionInfo);
if (_viewModel.PageNum < WelcomeViewModel.MaxPageNum)
{
_viewModel.PageNum++;
ContentFrame.Navigate(PageTypeSelector(_viewModel.PageNum), null, _forwardTransitionInfo);
}
else
{
_viewModel.NextEnabled = false;
}
}
private void BackwardButton_Click(object sender, RoutedEventArgs e)
{
if (pageNum > 1)
if (_viewModel.PageNum > 1)
{
pageNum--;
UpdateView();
ContentFrame.Navigate(PageTypeSelector(pageNum), settings, _backTransitionInfo);
_viewModel.PageNum--;
ContentFrame.Navigate(PageTypeSelector(_viewModel.PageNum), null, _backTransitionInfo);
}
else
{
BackButton.IsEnabled = false;
_viewModel.BackEnabled = false;
}
}
@ -109,7 +91,13 @@ namespace Flow.Launcher
private void ContentFrame_Loaded(object sender, RoutedEventArgs e)
{
ContentFrame.Navigate(PageTypeSelector(1), settings); /* Set First Page */
ContentFrame.Navigate(PageTypeSelector(1)); /* Set First Page */
}
private void Window_Closed(object sender, EventArgs e)
{
// Save settings when window is closed
Ioc.Default.GetRequiredService<Settings>().Save();
}
}
}

View file

@ -2,27 +2,27 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:system="clr-namespace:System;assembly=mscorlib">
<!-- Plugin Info -->
<system:String x:Key="flowlauncher_plugin_browserbookmark_plugin_name">Browser Bookmarks</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_plugin_description">Search your browser bookmarks</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_plugin_name">סימניות דפדפן</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_plugin_description">חפש בסימניות הדפדפן שלך</system:String>
<!-- Settings -->
<system:String x:Key="flowlauncher_plugin_browserbookmark_bookmarkDataSetting">Bookmark Data</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_settings_openBookmarks">Open bookmarks in:</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_settings_newWindow">New window</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_settings_newTab">New tab</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_settings_setBrowserFromPath">Set browser from path:</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_settings_choose">Choose</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_copyurl_title">Copy url</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_copyurl_subtitle">Copy the bookmark's url to clipboard</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_loadBrowserFrom">Load Browser From:</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_browserName">Browser Name</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_browserBookmarkDataDirectory">Data Directory Path</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_bookmarkDataSetting">נתוני סימניות</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_settings_openBookmarks">פתח סימניות ב:</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_settings_newWindow">חלון חדש</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_settings_newTab">לשונית חדשה</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_settings_setBrowserFromPath">הגדר דפדפן מנתיב:</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_settings_choose">בחר</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_copyurl_title">העתק כתובת</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_copyurl_subtitle">העתק את כתובת הסימנייה ללוח</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_loadBrowserFrom">טען דפדפן מ:</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_browserName">שם הדפדפן</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_browserBookmarkDataDirectory">נתיב ספריית הנתונים</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_addBrowserBookmark">הוסף</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_editBrowserBookmark">ערוך</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_removeBrowserBookmark">מחק</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_browseBrowserBookmark">Browse</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_others">Others</system:String>
<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: &quot;%LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData&quot;. For Firefox engine, the bookmarks directory is the userdata folder contains the places.sqlite file.</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_browseBrowserBookmark">עיין</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_others">אחרים</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_browserEngine">מנוע דפדפן</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_guideMessage01">אם אינך משתמש ב-Chrome, Firefox או Edge, או שאתה משתמש בגרסה הניידת שלהם, עליך להוסיף את ספריית נתוני הסימניות ולבחור את מנוע הדפדפן המתאים כדי שהתוסף יעבוד.</system:String>
<system:String x:Key="flowlauncher_plugin_browserbookmark_guideMessage02">לדוגמה: המנוע של Brave הוא Chromium, ומיקום ברירת המחדל של נתוני הסימניות שלו הוא: %LOCALAPPDATA%\BraveSoftware\Brave-Browser\UserData. עבור מנוע Firefox, ספריית הסימניות היא תיקיית המשתמש שמכילה את הקובץ places.sqlite.</system:String>
</ResourceDictionary>

View file

@ -8,77 +8,87 @@
d:DesignWidth="500"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
mc:Ignorable="d">
<Grid Margin="60,0,10,0">
<Grid Margin="{StaticResource SettingPanelMargin}">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Margin="0,10,0,10" Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock Margin="10" Text="{DynamicResource flowlauncher_plugin_browserbookmark_loadBrowserFrom}" />
<CheckBox
Margin="0,0,15,0"
Content="Chrome"
IsChecked="{Binding LoadChromeBookmark}" />
<CheckBox
Margin="0,0,15,0"
Content="Edge"
IsChecked="{Binding LoadEdgeBookmark}" />
<CheckBox
Margin="0,0,15,0"
Content="Firefox"
IsChecked="{Binding LoadFirefoxBookmark}" />
<StackPanel
Grid.Row="0"
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
Orientation="Horizontal">
<TextBlock
Margin="{StaticResource SettingPanelItemRightMargin}"
VerticalAlignment="Center"
Text="{DynamicResource flowlauncher_plugin_browserbookmark_loadBrowserFrom}" />
<CheckBox
Margin="{StaticResource SettingPanelItemRightMargin}"
Content="Chrome"
IsChecked="{Binding LoadChromeBookmark}" />
<CheckBox
Margin="{StaticResource SettingPanelItemRightMargin}"
Content="Edge"
IsChecked="{Binding LoadEdgeBookmark}" />
<CheckBox
Margin="{StaticResource SettingPanelItemRightMargin}"
Content="Firefox"
IsChecked="{Binding LoadFirefoxBookmark}" />
<Button
Margin="{StaticResource SettingPanelItemRightMargin}"
Click="Others_Click"
Content="{DynamicResource flowlauncher_plugin_browserbookmark_others}" />
</StackPanel>
<StackPanel
Name="CustomBrowsersList"
Grid.Row="1"
Visibility="Collapsed">
<ListView
Name="CustomBrowsers"
Height="auto"
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
BorderBrush="DarkGray"
BorderThickness="1"
ItemsSource="{Binding Settings.CustomChromiumBrowsers}"
MouseDoubleClick="MouseDoubleClickOnSelectedCustomBrowser"
SelectedItem="{Binding SelectedCustomBrowser}"
Style="{StaticResource {x:Static GridView.GridViewStyleKey}}">
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Name, Mode=OneWay}" Header="{DynamicResource flowlauncher_plugin_browserbookmark_browserName}" />
<GridViewColumn DisplayMemberBinding="{Binding DataDirectoryPath, Mode=OneWay}" Header="{DynamicResource flowlauncher_plugin_browserbookmark_browserBookmarkDataDirectory}" />
<GridViewColumn DisplayMemberBinding="{Binding BrowserType, Mode=OneWay}" Header="{DynamicResource flowlauncher_plugin_browserbookmark_browserEngine}" />
</GridView>
</ListView.View>
</ListView>
<StackPanel
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
HorizontalAlignment="Right"
Orientation="Horizontal">
<Button
Margin="0,0,15,0"
Click="Others_Click"
Content="{DynamicResource flowlauncher_plugin_browserbookmark_others}" />
</StackPanel>
<StackPanel Name="CustomBrowsersList" Visibility="Collapsed">
<ListView
Name="CustomBrowsers"
Height="auto"
Margin="10"
BorderBrush="DarkGray"
BorderThickness="1"
ItemsSource="{Binding Settings.CustomChromiumBrowsers}"
MouseDoubleClick="MouseDoubleClickOnSelectedCustomBrowser"
SelectedItem="{Binding SelectedCustomBrowser}"
Style="{StaticResource {x:Static GridView.GridViewStyleKey}}">
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Name, Mode=OneWay}" Header="{DynamicResource flowlauncher_plugin_browserbookmark_browserName}" />
<GridViewColumn DisplayMemberBinding="{Binding DataDirectoryPath, Mode=OneWay}" Header="{DynamicResource flowlauncher_plugin_browserbookmark_browserBookmarkDataDirectory}" />
<GridViewColumn DisplayMemberBinding="{Binding BrowserType, Mode=OneWay}" Header="{DynamicResource flowlauncher_plugin_browserbookmark_browserEngine}" />
</GridView>
</ListView.View>
</ListView>
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<Button
MinWidth="130"
Margin="10"
Click="NewCustomBrowser"
Content="{DynamicResource flowlauncher_plugin_browserbookmark_addBrowserBookmark}" />
<Button
MinWidth="130"
Margin="10"
Click="EditCustomBrowser"
Content="{DynamicResource flowlauncher_plugin_browserbookmark_editBrowserBookmark}">
<Button.Style>
<Style BasedOn="{StaticResource DefaultButtonStyle}" TargetType="Button">
<Setter Property="IsEnabled" Value="true" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=CustomBrowsers, Path=SelectedItems.Count}" Value="0">
<Setter Property="IsEnabled" Value="false" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<Button
MinWidth="120"
Margin="10"
Click="DeleteCustomBrowser"
Content="{DynamicResource flowlauncher_plugin_browserbookmark_removeBrowserBookmark}" />
</StackPanel>
Width="100"
Click="NewCustomBrowser"
Content="{DynamicResource flowlauncher_plugin_browserbookmark_addBrowserBookmark}" />
<Button
Width="100"
Margin="{StaticResource SettingPanelItemLeftMargin}"
Click="EditCustomBrowser"
Content="{DynamicResource flowlauncher_plugin_browserbookmark_editBrowserBookmark}">
<Button.Style>
<Style BasedOn="{StaticResource DefaultButtonStyle}" TargetType="Button">
<Setter Property="IsEnabled" Value="true" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=CustomBrowsers, Path=SelectedItems.Count}" Value="0">
<Setter Property="IsEnabled" Value="false" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<Button
Width="100"
Margin="{StaticResource SettingPanelItemLeftMargin}"
Click="DeleteCustomBrowser"
Content="{DynamicResource flowlauncher_plugin_browserbookmark_removeBrowserBookmark}" />
</StackPanel>
</StackPanel>
</Grid>

View file

@ -43,6 +43,7 @@
<ItemGroup>
<ProjectReference Include="..\..\Flow.Launcher.Core\Flow.Launcher.Core.csproj" />
<ProjectReference Include="..\..\Flow.Launcher.Plugin\Flow.Launcher.Plugin.csproj" />
</ItemGroup>
<ItemGroup>

View file

@ -1,15 +1,15 @@
<?xml version="1.0"?>
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:system="clr-namespace:System;assembly=mscorlib">
<system:String x:Key="flowlauncher_plugin_caculator_plugin_name">Calculator</system:String>
<system:String x:Key="flowlauncher_plugin_caculator_plugin_description">Allows to do mathematical calculations.(Try 5*3-2 in Flow Launcher)</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_not_a_number">Not a number (NaN)</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_expression_not_complete">Expression wrong or incomplete (Did you forget some parentheses?)</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_copy_number_to_clipboard">Copy this number to the clipboard</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_output_decimal_seperator">Decimal separator</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_output_decimal_seperator_help">The decimal separator to be used in the output.</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_decimal_seperator_use_system_locale">Use system locale</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_decimal_seperator_comma">Comma (,)</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_decimal_seperator_dot">Dot (.)</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_max_decimal_places">Max. decimal places</system:String>
<system:String x:Key="flowlauncher_plugin_caculator_plugin_name">מחשבון</system:String>
<system:String x:Key="flowlauncher_plugin_caculator_plugin_description">מאפשר לבצע חישובים מתמטיים. (נסה 5*3-2 ב-Flow Launcher)</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_not_a_number">לא מספר (NaN)</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_expression_not_complete">הביטוי שגוי או לא שלם (האם שכחת סוגריים?)</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_copy_number_to_clipboard">העתק מספר זה ללוח</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_output_decimal_seperator">מפריד עשרוני</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_output_decimal_seperator_help">מפריד עשרוני שישמש בתוצאה.</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_decimal_seperator_use_system_locale">השתמש בהגדרת מערכת</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_decimal_seperator_comma">פסיק (,)</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_decimal_seperator_dot">נקודה (.)</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_max_decimal_places">מספר מקסימלי של מקומות עשרוניים</system:String>
</ResourceDictionary>

View file

@ -155,16 +155,16 @@ namespace Flow.Launcher.Plugin.Calculator
return value.ToString(numberFormatInfo);
}
private string GetDecimalSeparator()
private static string GetDecimalSeparator()
{
string systemDecimalSeperator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
switch (_settings.DecimalSeparator)
string systemDecimalSeparator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
return _settings.DecimalSeparator switch
{
case DecimalSeparator.UseSystemLocale: return systemDecimalSeperator;
case DecimalSeparator.Dot: return dot;
case DecimalSeparator.Comma: return comma;
default: return systemDecimalSeperator;
}
DecimalSeparator.UseSystemLocale => systemDecimalSeparator,
DecimalSeparator.Dot => dot,
DecimalSeparator.Comma => comma,
_ => systemDecimalSeparator,
};
}
private bool IsBracketComplete(string query)

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