Merge branch 'dev' into plugin_settings_cache_path

This commit is contained in:
Jack Ye 2025-03-21 07:31:12 +08:00 committed by GitHub
commit c87b731efd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 1147 additions and 983 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

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

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

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

View file

@ -17,7 +17,7 @@
<core:LocalizationConverter x:Key="LocalizationConverter" />
</UserControl.Resources>
<Grid Margin="70,14,0,14">
<Grid Margin="{StaticResource SettingPanelMargin}">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
@ -30,7 +30,7 @@
<TextBlock
Grid.Row="0"
Grid.Column="0"
Margin="0,0,10,0"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
VerticalAlignment="Center"
FontSize="14"
Text="{DynamicResource flowlauncher_plugin_calculator_output_decimal_seperator}" />
@ -39,8 +39,9 @@
Grid.Row="0"
Grid.Column="1"
MaxWidth="300"
Margin="10,5,0,5"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
ItemsSource="{Binding Source={ui:EnumBindingSource {x:Type calculator:DecimalSeparator}}}"
SelectedItem="{Binding Settings.DecimalSeparator}">
<ComboBox.ItemTemplate>
@ -53,7 +54,7 @@
<TextBlock
Grid.Row="1"
Grid.Column="0"
Margin="0,0,10,0"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
VerticalAlignment="Center"
FontSize="14"
Text="{DynamicResource flowlauncher_plugin_calculator_max_decimal_places}" />
@ -61,8 +62,9 @@
x:Name="MaxDecimalPlaces"
Grid.Row="1"
Grid.Column="1"
Margin="10,5,0,5"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
ItemsSource="{Binding MaxDecimalPlacesRange}"
SelectedItem="{Binding Settings.MaxDecimalPlaces}" />

View file

@ -7,7 +7,7 @@
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<Grid Margin="70 15 18 15">
<Grid Margin="{StaticResource SettingPanelMargin}">
<Grid.ColumnDefinitions />
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
@ -15,13 +15,12 @@
</Grid.RowDefinitions>
<CheckBox
Grid.Row="0"
Padding="8 0 0 0"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
Content="{DynamicResource plugin_pluginsmanager_plugin_settings_unknown_source}"
IsChecked="{Binding WarnFromUnknownSource}" />
<CheckBox
Grid.Row="1"
Margin="0 10 0 0"
Padding="8 0 0 0"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
Content="{DynamicResource plugin_pluginsmanager_plugin_settings_auto_restart}"
IsChecked="{Binding AutoRestartAfterChanging}" />
</Grid>

View file

@ -10,124 +10,109 @@
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</UserControl.Resources>
<Grid Margin="0">
<Grid Margin="{StaticResource SettingPanelMargin}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<DockPanel
Margin="70 10 0 8"
HorizontalAlignment="Stretch"
LastChildFill="True">
<DockPanel HorizontalAlignment="Stretch" LastChildFill="True">
<TextBlock
MinWidth="120"
Margin="0 5 10 0"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
VerticalAlignment="Center"
Text="{DynamicResource flowlauncher_plugin_program_index_source}" />
<WrapPanel
Width="Auto"
Margin="0 0 14 0"
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
HorizontalAlignment="Right"
DockPanel.Dock="Right">
<CheckBox
Name="UWPEnabled"
Margin="12 0 12 0"
Margin="{StaticResource SettingPanelItemRightMargin}"
Content="{DynamicResource flowlauncher_plugin_program_index_uwp}"
IsChecked="{Binding EnableUWP}"
ToolTip="{DynamicResource flowlauncher_plugin_program_index_uwp_tooltip}"
Visibility="{Binding ShowUWPCheckbox, Converter={StaticResource BooleanToVisibilityConverter}}" />
<CheckBox
Name="StartMenuEnabled"
Margin="12 0 12 0"
Margin="{StaticResource SettingPanelItemRightMargin}"
Content="{DynamicResource flowlauncher_plugin_program_index_start}"
IsChecked="{Binding EnableStartMenuSource}"
ToolTip="{DynamicResource flowlauncher_plugin_program_index_start_tooltip}" />
<CheckBox
Name="RegistryEnabled"
Margin="12 0 12 0"
Margin="{StaticResource SettingPanelItemRightMargin}"
Content="{DynamicResource flowlauncher_plugin_program_index_registry}"
IsChecked="{Binding EnableRegistrySource}"
ToolTip="{DynamicResource flowlauncher_plugin_program_index_registry_tooltip}" />
<CheckBox
Name="PATHEnabled"
Margin="12 0 12 0"
Content="{DynamicResource flowlauncher_plugin_program_index_PATH}"
IsChecked="{Binding EnablePATHSource}"
ToolTip="{DynamicResource flowlauncher_plugin_program_index_PATH_tooltip}" />
</WrapPanel>
</DockPanel>
<StackPanel
Grid.Row="1"
HorizontalAlignment="Stretch"
Orientation="Vertical">
<Separator
Height="1"
BorderBrush="{DynamicResource Color03B}"
BorderThickness="1" />
<DockPanel
Margin="70 10 0 8"
HorizontalAlignment="Stretch"
LastChildFill="True">
<Separator Style="{StaticResource SettingPanelSeparatorStyle}" />
<DockPanel HorizontalAlignment="Stretch" LastChildFill="True">
<TextBlock
MinWidth="120"
Margin="0 5 10 0"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
VerticalAlignment="Center"
Text="{DynamicResource flowlauncher_plugin_program_index_option}" />
<WrapPanel
Width="Auto"
Margin="0 0 14 0"
HorizontalAlignment="Right"
DockPanel.Dock="Right">
<CheckBox
Margin="12 0 12 0"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
Content="{DynamicResource flowlauncher_plugin_program_enable_hidelnkpath}"
IsChecked="{Binding HideAppsPath}"
ToolTip="{DynamicResource flowlauncher_plugin_program_enable_hidelnkpath_tooltip}" />
<CheckBox
Margin="12 0 12 0"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
Content="{DynamicResource flowlauncher_plugin_program_enable_hideuninstallers}"
IsChecked="{Binding HideUninstallers}"
ToolTip="{DynamicResource flowlauncher_plugin_program_enable_hideuninstallers_tooltip}" />
<CheckBox
Margin="12 0 12 0"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
Content="{DynamicResource flowlauncher_plugin_program_enable_description}"
IsChecked="{Binding EnableDescription}"
ToolTip="{DynamicResource flowlauncher_plugin_program_enable_description_tooltip}" />
<CheckBox
Margin="12 0 12 0"
Content="{DynamicResource flowlauncher_plugin_program_enable_hideduplicatedwindowsapp}"
IsChecked="{Binding HideDuplicatedWindowsApp}"
ToolTip="{DynamicResource flowlauncher_plugin_program_enable_hideduplicatedwindowsapp_tooltip}" />
</WrapPanel>
</DockPanel>
<Separator
Height="1"
BorderBrush="{DynamicResource Color03B}"
BorderThickness="1" />
<Separator Style="{StaticResource SettingPanelSeparatorStyle}" />
<StackPanel
Margin="60 0 0 2"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Orientation="Horizontal">
<Button
x:Name="btnLoadAllProgramSource"
MinWidth="120"
Margin="10 10 5 10"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
HorizontalAlignment="Right"
Click="btnLoadAllProgramSource_OnClick"
Content="{DynamicResource flowlauncher_plugin_program_all_programs}" />
<Button
x:Name="btnProgramSuffixes"
MinWidth="120"
Margin="5 10 5 10"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
HorizontalAlignment="Right"
Click="BtnProgramSuffixes_OnClick"
Content="{DynamicResource flowlauncher_plugin_program_suffixes}" />
<Button
x:Name="btnReindex"
MinWidth="120"
Margin="5 10 5 10"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
HorizontalAlignment="Right"
Click="btnReindex_Click"
Content="{DynamicResource flowlauncher_plugin_program_reindex}" />
@ -140,12 +125,13 @@
x:Name="progressBarIndexing"
Width="80"
Height="20"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
IsIndeterminate="True"
Maximum="100"
Minimum="0" />
<TextBlock
Height="20"
Margin="10 0 0 0"
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
HorizontalAlignment="Center"
Text="{DynamicResource flowlauncher_plugin_program_indexing}" />
</StackPanel>
@ -154,7 +140,7 @@
<ListView
x:Name="programSourceView"
Grid.Row="2"
Margin="70 0 20 0"
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
AllowDrop="True"
BorderBrush="DarkGray"
BorderThickness="1"
@ -203,27 +189,24 @@
</GridView>
</ListView.View>
</ListView>
<DockPanel
Grid.Row="3"
Grid.RowSpan="1"
Margin="0 0 20 0">
<DockPanel Grid.Row="3">
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<Button
x:Name="btnProgramSourceStatus"
MinWidth="100"
Margin="10"
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
Click="btnProgramSourceStatus_OnClick"
Content="{DynamicResource flowlauncher_plugin_program_disable}" />
<Button
x:Name="btnEditProgramSource"
MinWidth="100"
Margin="10"
Margin="{StaticResource SettingPanelItemLeftTopBottomMargin}"
Click="btnEditProgramSource_OnClick"
Content="{DynamicResource flowlauncher_plugin_program_edit}" />
<Button
x:Name="btnAddProgramSource"
MinWidth="100"
Margin="10 10 0 10"
Margin="{StaticResource SettingPanelItemLeftTopBottomMargin}"
Click="btnAddProgramSource_OnClick"
Content="{DynamicResource flowlauncher_plugin_program_add}" />
</StackPanel>

View file

@ -8,7 +8,7 @@
d:DesignWidth="300"
Loaded="CMDSetting_OnLoaded"
mc:Ignorable="d">
<Grid Margin="60,10,10,20" VerticalAlignment="Top">
<Grid Margin="{StaticResource SettingPanelMargin}" VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
@ -21,37 +21,37 @@
<CheckBox
x:Name="ReplaceWinR"
Grid.Row="0"
Margin="10,10,5,5"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
HorizontalAlignment="Left"
Content="{DynamicResource flowlauncher_plugin_cmd_relace_winr}" />
<CheckBox
x:Name="CloseShellAfterPress"
Grid.Row="1"
Margin="10,5,5,5"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
HorizontalAlignment="Left"
Content="{DynamicResource flowlauncher_plugin_cmd_close_cmd_after_press}" />
<CheckBox
x:Name="LeaveShellOpen"
Grid.Row="2"
Margin="10,5,5,5"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
HorizontalAlignment="Left"
Content="{DynamicResource flowlauncher_plugin_cmd_leave_cmd_open}" />
<CheckBox
x:Name="AlwaysRunAsAdministrator"
Grid.Row="3"
Margin="10,5,5,5"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
HorizontalAlignment="Left"
Content="{DynamicResource flowlauncher_plugin_cmd_always_run_as_administrator}" />
<CheckBox
x:Name="UseWindowsTerminal"
Grid.Row="4"
Margin="10,5,5,5"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
HorizontalAlignment="Left"
Content="{DynamicResource flowlauncher_plugin_cmd_use_windows_terminal}" />
<ComboBox
x:Name="ShellComboBox"
Grid.Row="5"
Margin="10,5,5,5"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
HorizontalAlignment="Left">
<ComboBoxItem>CMD</ComboBoxItem>
<ComboBoxItem>PowerShell</ComboBoxItem>
@ -61,11 +61,11 @@
<StackPanel Grid.Row="6" Orientation="Horizontal">
<CheckBox
x:Name="ShowOnlyMostUsedCMDs"
Margin="10,5,5,5"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
Content="{DynamicResource flowlauncher_plugin_cmd_history}" />
<ComboBox
x:Name="ShowOnlyMostUsedCMDsNumber"
Margin="10,5,5,5"
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
HorizontalAlignment="Left" />
</StackPanel>
</Grid>

View file

@ -9,7 +9,8 @@
d:DesignHeight="300"
d:DesignWidth="300"
mc:Ignorable="d">
<Grid Margin="70 18 18 18">
<Grid Margin="{StaticResource SettingPanelMargin}">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
@ -18,7 +19,7 @@
<ListView
x:Name="lbxCommands"
Grid.Row="0"
Margin="0"
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
BorderBrush="DarkGray"
BorderThickness="1"
ItemsSource="{Binding Settings.Commands}"
@ -57,11 +58,12 @@
<StackPanel
Grid.Row="1"
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
HorizontalAlignment="Right"
Orientation="Horizontal">
<Button
Width="100"
Margin="10"
Margin="{StaticResource SettingPanelItemLeftMargin}"
Click="OnEditCommandKeywordClick"
Content="{DynamicResource flowlauncher_plugin_sys_edit}" />
</StackPanel>

View file

@ -19,7 +19,7 @@
<system:String x:Key="flowlauncher_plugin_websearch_action_keyword">Action Keyword</system:String>
<system:String x:Key="flowlauncher_plugin_websearch_url">URL</system:String>
<system:String x:Key="flowlauncher_plugin_websearch_search">Search</system:String>
<system:String x:Key="flowlauncher_plugin_websearch_enable_suggestion">Use Search Query Autocomplete:</system:String>
<system:String x:Key="flowlauncher_plugin_websearch_enable_suggestion">Use Search Query Autocomplete</system:String>
<system:String x:Key="flowlauncher_plugin_websearch_enable_suggestion_provider">Autocomplete Data from:</system:String>
<system:String x:Key="flowlauncher_plugin_websearch_pls_select_web_search">Please select a web search</system:String>
<system:String x:Key="flowlauncher_plugin_websearch_delete_warning">Are you sure you want to delete {0}?</system:String>

View file

@ -9,6 +9,7 @@
d:DesignHeight="300"
d:DesignWidth="500"
mc:Ignorable="d">
<UserControl.Resources>
<Style x:Key="BrowserPathBoxStyle" TargetType="TextBox">
<Setter Property="Height" Value="28" />
@ -35,16 +36,19 @@
</DockPanel>
</DataTemplate>
</UserControl.Resources>
<Grid Margin="0,4,0,0">
<Grid Margin="{StaticResource SettingPanelMargin}">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="56" />
<RowDefinition Height="50" />
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListView
x:Name="SearchSourcesListView"
Grid.Row="0"
Margin="18,18,18,0"
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
BorderBrush="DarkGray"
BorderThickness="1"
GridViewColumnHeader.Click="SortByColumn"
@ -60,7 +64,7 @@
<Image
Width="20"
Height="20"
Margin="6,0,0,0"
Margin="6 0 0 0"
Source="{Binding Path=IconPath}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
@ -69,11 +73,11 @@
<GridViewColumn
Width="130"
DisplayMemberBinding="{Binding ActionKeyword}"
Header="{DynamicResource flowlauncher_plugin_websearch_action_keyword}"/>
Header="{DynamicResource flowlauncher_plugin_websearch_action_keyword}" />
<GridViewColumn
Width="350"
Width="239"
DisplayMemberBinding="{Binding Title}"
Header="{DynamicResource flowlauncher_plugin_websearch_title}"/>
Header="{DynamicResource flowlauncher_plugin_websearch_title}" />
<GridViewColumn Width="140" Header="{DynamicResource flowlauncher_plugin_websearch_enable}">
<GridViewColumn.CellTemplate>
<DataTemplate>
@ -95,59 +99,57 @@
</GridView>
</ListView.View>
</ListView>
<StackPanel
Grid.Row="1"
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
HorizontalAlignment="Right"
Orientation="Horizontal">
<Button
Width="100"
Margin="10"
Margin="{StaticResource SettingPanelItemLeftMargin}"
Click="OnDeleteSearchSearchClick"
Content="{DynamicResource flowlauncher_plugin_websearch_delete}" />
<Button
Width="100"
Margin="10"
Margin="{StaticResource SettingPanelItemLeftMargin}"
Click="OnEditSearchSourceClick"
Content="{DynamicResource flowlauncher_plugin_websearch_edit}" />
<Button
Width="100"
Margin="10,10,18,10"
Margin="{StaticResource SettingPanelItemLeftMargin}"
Click="OnAddSearchSearchClick"
Content="{DynamicResource flowlauncher_plugin_websearch_add}" />
</StackPanel>
<Border
Grid.Row="2"
Margin="0,0,0,0"
HorizontalAlignment="Stretch"
BorderBrush="{DynamicResource Color03B}"
BorderThickness="0,1,0,0">
<DockPanel HorizontalAlignment="Right">
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal">
<Label
Margin="14,0,10,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Content="{DynamicResource flowlauncher_plugin_websearch_enable_suggestion_provider}" />
<ComboBox
Height="30"
Margin="0,0,20,0"
VerticalAlignment="Center"
FontSize="11"
IsEnabled="{Binding ElementName=EnableSuggestion, Path=IsChecked}"
ItemsSource="{Binding Settings.Suggestions}"
SelectedItem="{Binding Settings.SelectedSuggestion}" />
<Label
Margin="0,0,10,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Content="{DynamicResource flowlauncher_plugin_websearch_enable_suggestion}" />
<CheckBox
Name="EnableSuggestion"
Margin="0,0,8,0"
IsChecked="{Binding Settings.EnableSuggestion}" />
</StackPanel>
<!-- Not sure why binding IsEnabled directly to Settings.EnableWebSearchSuggestion is not working -->
</DockPanel>
</Border>
<Separator Grid.Row="2" Style="{StaticResource SettingPanelSeparatorStyle}" />
<DockPanel
Grid.Row="3"
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
HorizontalAlignment="Right">
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal">
<Label
HorizontalAlignment="Right"
VerticalAlignment="Center"
Content="{DynamicResource flowlauncher_plugin_websearch_enable_suggestion_provider}" />
<ComboBox
Height="30"
Margin="{StaticResource SettingPanelItemLeftMargin}"
VerticalAlignment="Center"
FontSize="11"
IsEnabled="{Binding ElementName=EnableSuggestion, Path=IsChecked}"
ItemsSource="{Binding Settings.Suggestions}"
SelectedItem="{Binding Settings.SelectedSuggestion}" />
<CheckBox
Name="EnableSuggestion"
Margin="{StaticResource SettingPanelItemLeftMargin}"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Content="{DynamicResource flowlauncher_plugin_websearch_enable_suggestion}"
IsChecked="{Binding Settings.EnableSuggestion}" />
</StackPanel>
<!-- Not sure why binding IsEnabled directly to Settings.EnableWebSearchSuggestion is not working -->
</DockPanel>
</Grid>
</UserControl>