Skip to content

Commit b8acead

Browse files
authored
Merge branch 'dev' into httpspref
2 parents 001dad9 + eb261f5 commit b8acead

File tree

12 files changed

+388
-35
lines changed

12 files changed

+388
-35
lines changed

Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,12 @@ private void CustomHotkeyEdit()
8989
if (window.ShowDialog() is not true) return;
9090

9191
var index = Settings.CustomPluginHotkeys.IndexOf(settingItem);
92-
Settings.CustomPluginHotkeys[index] = new CustomPluginHotkey(window.Hotkey, window.ActionKeyword);
93-
HotKeyMapper.RemoveHotkey(settingItem.Hotkey); // remove origin hotkey
94-
HotKeyMapper.SetCustomQueryHotkey(Settings.CustomPluginHotkeys[index]); // set new hotkey
92+
if (index >= 0 && index < Settings.CustomPluginHotkeys.Count)
93+
{
94+
Settings.CustomPluginHotkeys[index] = new CustomPluginHotkey(window.Hotkey, window.ActionKeyword);
95+
HotKeyMapper.RemoveHotkey(settingItem.Hotkey); // remove origin hotkey
96+
HotKeyMapper.SetCustomQueryHotkey(Settings.CustomPluginHotkeys[index]); // set new hotkey
97+
}
9598
}
9699

97100
[RelayCommand]
@@ -150,7 +153,10 @@ private void CustomShortcutEdit()
150153
if (window.ShowDialog() is not true) return;
151154

152155
var index = Settings.CustomShortcuts.IndexOf(settingItem);
153-
Settings.CustomShortcuts[index] = new CustomShortcutModel(window.Key, window.Value);
156+
if (index >= 0 && index < Settings.CustomShortcuts.Count)
157+
{
158+
Settings.CustomShortcuts[index] = new CustomShortcutModel(window.Key, window.Value);
159+
}
154160
}
155161

156162
[RelayCommand]
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System;
2+
using System.Globalization;
3+
using System.Windows;
4+
using System.Windows.Data;
5+
6+
namespace Flow.Launcher.Plugin.Url.Converters;
7+
8+
[ValueConversion(typeof(bool), typeof(Visibility))]
9+
public class BoolToVisibilityConverter : IValueConverter
10+
{
11+
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
12+
{
13+
if (value is not bool)
14+
throw new ArgumentException("value should be boolean", nameof(value));
15+
16+
return (bool)value ? Visibility.Visible : Visibility.Collapsed;
17+
}
18+
19+
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
20+
{
21+
throw new InvalidOperationException();
22+
}
23+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System;
2+
using System.Globalization;
3+
using System.Windows.Data;
4+
5+
namespace Flow.Launcher.Plugin.Url.Converters;
6+
7+
[ValueConversion(typeof(bool), typeof(bool))]
8+
public class InverseBoolConverter : IValueConverter
9+
{
10+
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
11+
{
12+
if (value is not bool)
13+
throw new ArgumentException("value should be boolean", nameof(value));
14+
15+
return !(bool)value;
16+
}
17+
18+
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
19+
{
20+
if (value is not bool)
21+
throw new ArgumentException("value should be boolean", nameof(value));
22+
23+
return !(bool)value;
24+
}
25+
}
Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
1-
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
2-
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
3-
xmlns:system="clr-namespace:System;assembly=mscorlib">
1+
<ResourceDictionary
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:system="clr-namespace:System;assembly=mscorlib">
45

5-
<system:String x:Key="flowlauncher_plugin_url_open_search_in">Open search in:</system:String>
6-
<system:String x:Key="flowlauncher_plugin_new_window">New Window</system:String>
7-
<system:String x:Key="flowlauncher_plugin_new_tab">New Tab</system:String>
8-
96
<system:String x:Key="flowlauncher_plugin_url_open_url">Open url:{0}</system:String>
107
<system:String x:Key="flowlauncher_plugin_url_cannot_open_url">Can't open url:{0}</system:String>
118

129
<system:String x:Key="flowlauncher_plugin_url_plugin_name">URL</system:String>
1310
<system:String x:Key="flowlauncher_plugin_url_plugin_description">Open the typed URL from Flow Launcher</system:String>
1411

15-
<system:String x:Key="flowlauncher_plugin_url_plugin_set_tip">Please set your browser path:</system:String>
1612
<system:String x:Key="flowlauncher_plugin_url_plugin_choose">Choose</system:String>
1713
<system:String x:Key="flowlauncher_plugin_url_plugin_filter">Application(*.exe)|*.exe|All files|*.*</system:String>
18-
14+
15+
<system:String x:Key="flowlauncher_plugin_url_use_custom_browser">Use custom instead of Flow's default web browser</system:String>
16+
<system:String x:Key="flowlauncher_plugin_url_browser_path">Browser path</system:String>
17+
18+
<system:String x:Key="flowlauncher_plugin_url_new_tab">New tab</system:String>
19+
<system:String x:Key="flowlauncher_plugin_url_new_window">New window</system:String>
20+
21+
<system:String x:Key="flowlauncher_plugin_url_private_mode">Private mode</system:String>
22+
1923
<system:String x:Key="flowlauncher_plugin_url_usehttps">Prefer https over http</system:String>
2024
</ResourceDictionary>

Plugins/Flow.Launcher.Plugin.Url/Main.cs

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22
using System.Collections.Generic;
33
using System.Text.RegularExpressions;
44
using System.Windows.Controls;
5+
using Flow.Launcher.Plugin.SharedCommands;
56

67
namespace Flow.Launcher.Plugin.Url
78
{
89
public class Main : IPlugin, IPluginI18n, ISettingProvider
910
{
1011
//based on https://gist.github.com/dperini/729294
11-
private const string urlPattern = "^" +
12+
private const string UrlPattern = "^" +
1213
// protocol identifier
1314
"(?:(?:https?|ftp)://|)" +
1415
// user:pass authentication
@@ -40,18 +41,18 @@ public class Main : IPlugin, IPluginI18n, ISettingProvider
4041
// resource path
4142
"(?:/\\S*)?" +
4243
"$";
43-
Regex reg = new Regex(urlPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
44+
private readonly Regex UrlRegex = new(UrlPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
4445
internal static PluginInitContext Context { get; private set; }
45-
private Settings _settings;
46-
46+
internal static Settings Settings { get; private set; }
47+
4748
public List<Result> Query(Query query)
4849
{
4950
var raw = query.Search;
5051
if (IsURL(raw))
5152
{
52-
return new List<Result>
53-
{
54-
new Result
53+
return
54+
[
55+
new()
5556
{
5657
Title = raw,
5758
SubTitle = Localize.flowlauncher_plugin_url_open_url(raw),
@@ -65,8 +66,22 @@ public List<Result> Query(Query query)
6566
}
6667
try
6768
{
68-
Context.API.OpenUrl(raw);
69-
69+
if (Settings.UseCustomBrowser)
70+
{
71+
if (Settings.OpenInNewBrowserWindow)
72+
{
73+
SearchWeb.OpenInBrowserWindow(raw, Settings.BrowserPath, Settings.OpenInPrivateMode, Settings.PrivateModeArgument);
74+
}
75+
else
76+
{
77+
SearchWeb.OpenInBrowserTab(raw, Settings.BrowserPath, Settings.OpenInPrivateMode, Settings.PrivateModeArgument);
78+
}
79+
}
80+
else
81+
{
82+
Context.API.OpenWebUrl(raw);
83+
}
84+
7085
return true;
7186
}
7287
catch(Exception)
@@ -76,9 +91,10 @@ public List<Result> Query(Query query)
7691
}
7792
}
7893
}
79-
};
94+
];
8095
}
81-
return new List<Result>(0);
96+
97+
return [];
8298
}
8399

84100
private string GetHttpPreference()
@@ -90,7 +106,7 @@ public bool IsURL(string raw)
90106
{
91107
raw = raw.ToLower();
92108

93-
if (reg.Match(raw).Value == raw) return true;
109+
if (UrlRegex.Match(raw).Value == raw) return true;
94110

95111
if (raw == "localhost" || raw.StartsWith("localhost:") ||
96112
raw == "http://localhost" || raw.StartsWith("http://localhost:") ||
@@ -106,8 +122,8 @@ public bool IsURL(string raw)
106122
public void Init(PluginInitContext context)
107123
{
108124
Context = context;
109-
110-
_settings = context.API.LoadSettingJsonStorage<Settings>();
125+
126+
Settings = context.API.LoadSettingJsonStorage<Settings>();
111127
}
112128

113129
public string GetTranslatedPluginTitle()
Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,53 @@
11
namespace Flow.Launcher.Plugin.Url
22
{
3-
public class Settings
3+
public class Settings : BaseModel
44
{
5-
public string BrowserPath { get; set; }
5+
private bool _useCustomBrowser = false;
6+
public bool UseCustomBrowser
7+
{
8+
get => _useCustomBrowser;
9+
set
10+
{
11+
if (_useCustomBrowser != value)
12+
{
13+
_useCustomBrowser = value;
14+
OnPropertyChanged();
15+
}
16+
}
17+
}
18+
19+
private string _browserPath = string.Empty;
20+
public string BrowserPath
21+
{
22+
get => _browserPath;
23+
set
24+
{
25+
if (_browserPath != value)
26+
{
27+
_browserPath = value;
28+
OnPropertyChanged();
29+
}
30+
}
31+
}
32+
33+
private bool _openInNewBrowserWindow = true;
34+
public bool OpenInNewBrowserWindow
35+
{
36+
get => _openInNewBrowserWindow;
37+
set
38+
{
39+
if (_openInNewBrowserWindow != value)
40+
{
41+
_openInNewBrowserWindow = value;
42+
OnPropertyChanged();
43+
}
44+
}
45+
}
46+
47+
public bool OpenInPrivateMode { get; set; } = false;
48+
49+
public string PrivateModeArgument { get; set; } = string.Empty;
650

7-
public bool OpenInNewBrowserWindow { get; set; } = true;
851
public bool AlwaysOpenWithHttps { get; set; } = false;
952
}
1053
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<UserControl
2+
x:Class="Flow.Launcher.Plugin.Url.SettingsControl"
3+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5+
xmlns:converters="clr-namespace:Flow.Launcher.Plugin.Url.Converters"
6+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
7+
xmlns:local="clr-namespace:Flow.Launcher.Plugin.Url"
8+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
9+
d:DesignHeight="450"
10+
d:DesignWidth="800"
11+
DataContext="{Binding RelativeSource={RelativeSource Self}}"
12+
mc:Ignorable="d">
13+
<UserControl.Resources>
14+
<converters:InverseBoolConverter x:Key="InverseBoolConverter" />
15+
<converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
16+
</UserControl.Resources>
17+
18+
<Grid Margin="{StaticResource SettingPanelMargin}">
19+
<Grid.RowDefinitions>
20+
<RowDefinition Height="auto" />
21+
<RowDefinition Height="auto" />
22+
</Grid.RowDefinitions>
23+
24+
<CheckBox
25+
Grid.Row="0"
26+
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
27+
HorizontalAlignment="Left"
28+
VerticalAlignment="Center"
29+
Content="{DynamicResource flowlauncher_plugin_url_use_custom_browser}"
30+
IsChecked="{Binding Settings.UseCustomBrowser, Mode=TwoWay}" />
31+
32+
<Grid
33+
Grid.Row="1"
34+
HorizontalAlignment="Left"
35+
Visibility="{Binding Settings.UseCustomBrowser, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}">
36+
<Grid.RowDefinitions>
37+
<RowDefinition Height="auto" />
38+
<RowDefinition Height="auto" />
39+
<RowDefinition Height="auto" />
40+
</Grid.RowDefinitions>
41+
<Grid.ColumnDefinitions>
42+
<ColumnDefinition Width="Auto" />
43+
<ColumnDefinition Width="*" />
44+
</Grid.ColumnDefinitions>
45+
46+
<TextBlock
47+
Grid.Row="0"
48+
Grid.Column="0"
49+
Margin="{StaticResource SettingPanelItemRightTopBottomMargin}"
50+
VerticalAlignment="Center"
51+
FontSize="14"
52+
Text="{DynamicResource flowlauncher_plugin_url_browser_path}" />
53+
<Grid
54+
Grid.Row="0"
55+
Grid.Column="1"
56+
Margin="{StaticResource SettingPanelItemLeftTopBottomMargin}">
57+
<Grid.ColumnDefinitions>
58+
<ColumnDefinition Width="*" />
59+
<ColumnDefinition Width="Auto" />
60+
</Grid.ColumnDefinitions>
61+
62+
<TextBox
63+
Grid.Column="0"
64+
HorizontalAlignment="Stretch"
65+
VerticalAlignment="Center"
66+
IsReadOnly="True"
67+
Text="{Binding Settings.BrowserPath, Mode=OneWay}" />
68+
<Button
69+
Grid.Column="1"
70+
Margin="{StaticResource SettingPanelItemLeftMargin}"
71+
HorizontalAlignment="Left"
72+
VerticalAlignment="Center"
73+
Click="SelectBrowserPath"
74+
Content="{DynamicResource flowlauncher_plugin_url_plugin_choose}" />
75+
</Grid>
76+
77+
<StackPanel
78+
Grid.Row="1"
79+
Grid.Column="1"
80+
Margin="{StaticResource SettingPanelItemLeftTopBottomMargin}"
81+
Orientation="Horizontal">
82+
<RadioButton Content="{DynamicResource flowlauncher_plugin_url_new_tab}" IsChecked="{Binding Settings.OpenInNewBrowserWindow, Converter={StaticResource InverseBoolConverter}, Mode=TwoWay}" />
83+
<RadioButton Content="{DynamicResource flowlauncher_plugin_url_new_window}" IsChecked="{Binding Settings.OpenInNewBrowserWindow, Mode=TwoWay}" />
84+
</StackPanel>
85+
86+
<TextBlock
87+
Grid.Row="2"
88+
Grid.Column="0"
89+
Margin="{StaticResource SettingPanelItemTopBottomMargin}"
90+
VerticalAlignment="Center"
91+
FontSize="14"
92+
Text="{DynamicResource flowlauncher_plugin_url_private_mode}" />
93+
<Grid
94+
Grid.Row="2"
95+
Grid.Column="1"
96+
Margin="{StaticResource SettingPanelItemLeftTopBottomMargin}">
97+
<Grid.ColumnDefinitions>
98+
<ColumnDefinition Width="*" />
99+
<ColumnDefinition Width="Auto" />
100+
</Grid.ColumnDefinitions>
101+
102+
<TextBox
103+
Grid.Column="0"
104+
HorizontalAlignment="Stretch"
105+
VerticalAlignment="Center"
106+
Text="{Binding Settings.PrivateModeArgument, Mode=TwoWay}" />
107+
<CheckBox
108+
Grid.Column="1"
109+
Margin="{StaticResource SettingPanelItemLeftMargin}"
110+
HorizontalAlignment="Left"
111+
VerticalAlignment="Center"
112+
Content=""
113+
IsChecked="{Binding Settings.OpenInPrivateMode, Mode=TwoWay}" />
114+
</Grid>
115+
</Grid>
116+
</Grid>
117+
</UserControl>

0 commit comments

Comments
 (0)