mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Merge branch 'dev' into localize-missing-python-js-dialog
This commit is contained in:
commit
a3c7b2b40f
24 changed files with 763 additions and 124 deletions
|
|
@ -72,4 +72,8 @@ changes:
|
|||
# Sum all the line removed in the PR
|
||||
deletions: {{ branch.diff.files_metadata | map(attr='deletions') | sum }}
|
||||
# Calculate the ratio of new code
|
||||
ratio: {{ (changes.additions / (changes.additions + changes.deletions)) * 100 | round(2) }}
|
||||
ratio: {{ (changes.additions / (changes.additions + changes.deletions)) * 100 | round(2) }}
|
||||
|
||||
has:
|
||||
screenshot_link: {{ pr.description | includes(regex=r/!\[.*\]\(.*(jpg|svg|png|gif|psd).*\)/) }}
|
||||
image_uploaded: {{ pr.description | includes(regex=r/<img.*src.*(jpg|svg|png|gif|psd).*>/) }}
|
||||
1
.github/actions/spelling/expect.txt
vendored
1
.github/actions/spelling/expect.txt
vendored
|
|
@ -98,6 +98,7 @@ Português
|
|||
Português (Brasil)
|
||||
Italiano
|
||||
Slovenský
|
||||
quicklook
|
||||
Tiếng Việt
|
||||
Droplex
|
||||
Preinstalled
|
||||
|
|
|
|||
19
.github/workflows/pr_assignee.yml
vendored
Normal file
19
.github/workflows/pr_assignee.yml
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
name: Assign PR to creator
|
||||
|
||||
# Due to GitHub token limitation, only able to assign org members not authors from forks.
|
||||
# https://github.com/thomaseizinger/assign-pr-creator-action/issues/3
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened]
|
||||
branches-ignore:
|
||||
- l10n_dev
|
||||
|
||||
jobs:
|
||||
automation:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Assign PR to creator
|
||||
uses: thomaseizinger/assign-pr-creator-action@v1.0.0
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
19
.github/workflows/pr_milestone.yml
vendored
Normal file
19
.github/workflows/pr_milestone.yml
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
name: Set Milestone
|
||||
|
||||
# Assigns the earliest created milestone that matches the below glob pattern.
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
automation:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: set-milestone
|
||||
uses: andrefcdias/add-to-milestone@v1.3.0
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
milestone: "+([0-9]).+([0-9]).+([0-9])"
|
||||
use-expression: true
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
using Flow.Launcher.Core.ExternalPlugins;
|
||||
using Flow.Launcher.Core.ExternalPlugins;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
|
|
@ -91,6 +91,48 @@ namespace Flow.Launcher.Core.Plugin
|
|||
}).ToArray());
|
||||
}
|
||||
|
||||
public static async Task OpenExternalPreviewAsync(string path, bool sendFailToast = true)
|
||||
{
|
||||
await Task.WhenAll(AllPlugins.Select(plugin => plugin.Plugin switch
|
||||
{
|
||||
IAsyncExternalPreview p => p.OpenPreviewAsync(path, sendFailToast),
|
||||
_ => Task.CompletedTask,
|
||||
}).ToArray());
|
||||
}
|
||||
|
||||
public static async Task CloseExternalPreviewAsync()
|
||||
{
|
||||
await Task.WhenAll(AllPlugins.Select(plugin => plugin.Plugin switch
|
||||
{
|
||||
IAsyncExternalPreview p => p.ClosePreviewAsync(),
|
||||
_ => Task.CompletedTask,
|
||||
}).ToArray());
|
||||
}
|
||||
|
||||
public static async Task SwitchExternalPreviewAsync(string path, bool sendFailToast = true)
|
||||
{
|
||||
await Task.WhenAll(AllPlugins.Select(plugin => plugin.Plugin switch
|
||||
{
|
||||
IAsyncExternalPreview p => p.SwitchPreviewAsync(path, sendFailToast),
|
||||
_ => Task.CompletedTask,
|
||||
}).ToArray());
|
||||
}
|
||||
|
||||
public static bool UseExternalPreview()
|
||||
{
|
||||
return GetPluginsForInterface<IAsyncExternalPreview>().Any(x => !x.Metadata.Disabled);
|
||||
}
|
||||
|
||||
public static bool AllowAlwaysPreview()
|
||||
{
|
||||
var plugin = GetPluginsForInterface<IAsyncExternalPreview>().FirstOrDefault(x => !x.Metadata.Disabled);
|
||||
|
||||
if (plugin is null)
|
||||
return false;
|
||||
|
||||
return ((IAsyncExternalPreview)plugin.Plugin).AllowAlwaysPreview();
|
||||
}
|
||||
|
||||
static PluginManager()
|
||||
{
|
||||
// validate user directory
|
||||
|
|
|
|||
|
|
@ -185,7 +185,9 @@ namespace Flow.Launcher.Infrastructure.UserSettings
|
|||
/// when false Alphabet static service will always return empty results
|
||||
/// </summary>
|
||||
public bool ShouldUsePinyin { get; set; } = false;
|
||||
|
||||
public bool AlwaysPreview { get; set; } = false;
|
||||
|
||||
public bool AlwaysStartEn { get; set; } = false;
|
||||
|
||||
private SearchPrecisionScore _querySearchPrecision = SearchPrecisionScore.Regular;
|
||||
|
|
|
|||
40
Flow.Launcher.Plugin/Interfaces/IAsyncExternalPreview.cs
Normal file
40
Flow.Launcher.Plugin/Interfaces/IAsyncExternalPreview.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
using System.Threading.Tasks;
|
||||
|
||||
namespace Flow.Launcher.Plugin
|
||||
{
|
||||
/// <summary>
|
||||
/// This interface is for plugins that wish to provide file preview (external preview)
|
||||
/// via a third party app instead of the default preview.
|
||||
/// </summary>
|
||||
public interface IAsyncExternalPreview : IFeatures
|
||||
{
|
||||
/// <summary>
|
||||
/// Method for opening/showing the preview.
|
||||
/// </summary>
|
||||
/// <param name="path">The file path to open the preview for</param>
|
||||
/// <param name="sendFailToast">Whether to send a toast message notification on failure for the user</param>
|
||||
public Task OpenPreviewAsync(string path, bool sendFailToast = true);
|
||||
|
||||
/// <summary>
|
||||
/// Method for closing/hiding the preview.
|
||||
/// </summary>
|
||||
public Task ClosePreviewAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Method for switching the preview to the next file result.
|
||||
/// This requires the external preview be already open/showing
|
||||
/// </summary>
|
||||
/// <param name="path">The file path to switch the preview for</param>
|
||||
/// <param name="sendFailToast">Whether to send a toast message notification on failure for the user</param>
|
||||
public Task SwitchPreviewAsync(string path, bool sendFailToast = true);
|
||||
|
||||
/// <summary>
|
||||
/// Allows the preview plugin to override the AlwaysPreview setting. Typically useful if plugin's preview does not
|
||||
/// fully work well with being shown together when the query window appears with results.
|
||||
/// When AlwaysPreview setting is on and this is set to false, the preview will not be shown when query
|
||||
/// window appears with results, instead the internal preview will be shown.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool AllowAlwaysPreview();
|
||||
}
|
||||
}
|
||||
|
|
@ -270,12 +270,12 @@ namespace Flow.Launcher.Plugin
|
|||
/// <summary>
|
||||
/// Full image used for preview panel
|
||||
/// </summary>
|
||||
public string PreviewImagePath { get; set; }
|
||||
public string PreviewImagePath { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the preview image should occupy the full width of the preview panel.
|
||||
/// </summary>
|
||||
public bool IsMedia { get; set; }
|
||||
public bool IsMedia { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Result description text that is shown at the bottom of the preview panel.
|
||||
|
|
@ -283,12 +283,17 @@ namespace Flow.Launcher.Plugin
|
|||
/// <remarks>
|
||||
/// When a value is not set, the <see cref="SubTitle"/> will be used.
|
||||
/// </remarks>
|
||||
public string Description { get; set; }
|
||||
public string Description { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate to get the preview panel's image
|
||||
/// </summary>
|
||||
public IconDelegate PreviewDelegate { get; set; }
|
||||
public IconDelegate PreviewDelegate { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// File path of the result. For third-party programs providing external preview.
|
||||
/// </summary>
|
||||
public string FilePath { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// Default instance of <see cref="PreviewInfo"/>
|
||||
|
|
@ -299,6 +304,7 @@ namespace Flow.Launcher.Plugin
|
|||
Description = null,
|
||||
IsMedia = false,
|
||||
PreviewDelegate = null,
|
||||
FilePath = null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
BIN
Flow.Launcher/Images/Error.png
Normal file
BIN
Flow.Launcher/Images/Error.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.9 KiB |
BIN
Flow.Launcher/Images/Exclamation.png
Normal file
BIN
Flow.Launcher/Images/Exclamation.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
BIN
Flow.Launcher/Images/Information.png
Normal file
BIN
Flow.Launcher/Images/Information.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.7 KiB |
BIN
Flow.Launcher/Images/Question.png
Normal file
BIN
Flow.Launcher/Images/Question.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.1 KiB |
|
|
@ -189,6 +189,8 @@
|
|||
<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>
|
||||
|
||||
|
||||
<!-- Setting Hotkey -->
|
||||
|
|
@ -213,6 +215,7 @@
|
|||
<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="CopyFilePathHotkey">Copy File Path</system:String>
|
||||
<system:String x:Key="ToggleGameModeHotkey">Toggle Game Mode</system:String>
|
||||
|
|
@ -357,6 +360,9 @@
|
|||
<system:String x:Key="commonCancel">Cancel</system:String>
|
||||
<system:String x:Key="commonReset">Reset</system:String>
|
||||
<system:String x:Key="commonDelete">Delete</system:String>
|
||||
<system:String x:Key="commonOK">OK</system:String>
|
||||
<system:String x:Key="commonYes">Yes</system:String>
|
||||
<system:String x:Key="commonNo">No</system:String>
|
||||
|
||||
<!-- Crash Reporter -->
|
||||
<system:String x:Key="reportWindow_version">Version</system:String>
|
||||
|
|
|
|||
|
|
@ -427,7 +427,7 @@
|
|||
VerticalAlignment="Stretch"
|
||||
Background="Transparent"
|
||||
ShowsPreview="True"
|
||||
Visibility="{Binding PreviewVisible, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
Visibility="{Binding InternalPreviewVisible, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<GridSplitter.Template>
|
||||
<ControlTemplate TargetType="{x:Type GridSplitter}">
|
||||
<Border Style="{DynamicResource PreviewBorderStyle}" />
|
||||
|
|
@ -439,7 +439,7 @@
|
|||
Grid.Column="2"
|
||||
VerticalAlignment="Stretch"
|
||||
Style="{DynamicResource PreviewArea}"
|
||||
Visibility="{Binding PreviewVisible, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
Visibility="{Binding InternalPreviewVisible, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<Border
|
||||
MinHeight="380"
|
||||
d:DataContext="{d:DesignInstance vm:ResultViewModel}"
|
||||
|
|
|
|||
|
|
@ -630,7 +630,7 @@ namespace Flow.Launcher
|
|||
if (_settings.UseAnimation)
|
||||
await Task.Delay(100);
|
||||
|
||||
if (_settings.HideWhenDeactivated)
|
||||
if (_settings.HideWhenDeactivated && !_viewModel.ExternalPreviewVisible)
|
||||
{
|
||||
_viewModel.Hide();
|
||||
}
|
||||
|
|
|
|||
142
Flow.Launcher/MessageBoxEx.xaml
Normal file
142
Flow.Launcher/MessageBoxEx.xaml
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
<Window
|
||||
x:Class="Flow.Launcher.MessageBoxEx"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Flow.Launcher"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
x:Name="MessageBoxWindow"
|
||||
Width="420"
|
||||
Height="Auto"
|
||||
Background="{DynamicResource PopuBGColor}"
|
||||
Foreground="{DynamicResource PopupTextColor}"
|
||||
ResizeMode="NoResize"
|
||||
SizeToContent="Height"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
mc:Ignorable="d">
|
||||
<WindowChrome.WindowChrome>
|
||||
<WindowChrome CaptionHeight="32" ResizeBorderThickness="{x:Static SystemParameters.WindowResizeBorderThickness}" />
|
||||
</WindowChrome.WindowChrome>
|
||||
<Window.InputBindings>
|
||||
<KeyBinding Key="Escape" Command="Close" />
|
||||
</Window.InputBindings>
|
||||
<Window.CommandBindings>
|
||||
<CommandBinding Command="Close" Executed="cmdEsc_OnPress" />
|
||||
</Window.CommandBindings>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
<RowDefinition MinHeight="68" />
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Grid.Row="0">
|
||||
<StackPanel>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button
|
||||
Grid.Column="4"
|
||||
Click="Button_Cancel"
|
||||
Style="{StaticResource TitleBarCloseButtonStyle}">
|
||||
<Path
|
||||
Width="46"
|
||||
Height="32"
|
||||
Data="M 18,11 27,20 M 18,20 27,11"
|
||||
Stroke="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type Button}}}"
|
||||
StrokeThickness="1">
|
||||
<Path.Style>
|
||||
<Style TargetType="Path">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Path=IsActive, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" Value="False">
|
||||
<Setter Property="Opacity" Value="0.5" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Path.Style>
|
||||
</Path>
|
||||
</Button>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="1" Margin="30 0 30 24">
|
||||
<Grid Grid.Column="0" Margin="0 0 0 12">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image
|
||||
Name="Img"
|
||||
Grid.Column="0"
|
||||
Width="18"
|
||||
Height="18"
|
||||
Margin="0 0 0 0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
RenderOptions.BitmapScalingMode="Fant"
|
||||
Stretch="UniformToFill"
|
||||
Visibility="Collapsed" />
|
||||
<TextBlock
|
||||
x:Name="TitleTextBlock"
|
||||
Grid.Column="1"
|
||||
MaxWidth="400"
|
||||
Margin="10 0 26 0"
|
||||
VerticalAlignment="Center"
|
||||
FontFamily="Segoe UI"
|
||||
FontSize="20"
|
||||
FontWeight="SemiBold"
|
||||
TextAlignment="Left"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
<TextBlock
|
||||
x:Name="DescTextBlock"
|
||||
Grid.Column="1"
|
||||
MaxWidth="400"
|
||||
Margin="0 0 26 0"
|
||||
HorizontalAlignment="Stretch"
|
||||
FontSize="14"
|
||||
TextAlignment="Left"
|
||||
TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
<Border
|
||||
Grid.Row="2"
|
||||
Margin="0 0 0 0"
|
||||
Background="{DynamicResource PopupButtonAreaBGColor}"
|
||||
BorderBrush="{DynamicResource PopupButtonAreaBorderColor}"
|
||||
BorderThickness="0 1 0 0">
|
||||
<WrapPanel
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Orientation="Horizontal">
|
||||
<Button
|
||||
x:Name="btnCancel"
|
||||
MinWidth="140"
|
||||
Margin="5 0 5 0"
|
||||
Click="Button_Click"
|
||||
Content="{DynamicResource commonCancel}" />
|
||||
<Button
|
||||
x:Name="btnNo"
|
||||
MinWidth="140"
|
||||
Margin="5 0 5 0"
|
||||
Click="Button_Click"
|
||||
Content="{DynamicResource commonNo}" />
|
||||
<Button
|
||||
x:Name="btnOk"
|
||||
MinWidth="140"
|
||||
Margin="5 0 5 0"
|
||||
Click="Button_Click"
|
||||
Content="{DynamicResource commonOK}" />
|
||||
<Button
|
||||
x:Name="btnYes"
|
||||
MinWidth="140"
|
||||
Margin="5 0 5 0"
|
||||
Click="Button_Click"
|
||||
Content="{DynamicResource commonYes}" />
|
||||
</WrapPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Window>
|
||||
192
Flow.Launcher/MessageBoxEx.xaml.cs
Normal file
192
Flow.Launcher/MessageBoxEx.xaml.cs
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using Flow.Launcher.Core.Resource;
|
||||
using Flow.Launcher.Infrastructure;
|
||||
using Flow.Launcher.Infrastructure.Image;
|
||||
using YamlDotNet.Core.Tokens;
|
||||
|
||||
namespace Flow.Launcher
|
||||
{
|
||||
public partial class MessageBoxEx : Window
|
||||
{
|
||||
public MessageBoxEx()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public enum MessageBoxType
|
||||
{
|
||||
ConfirmationWithYesNo = 0,
|
||||
ConfirmationWithYesNoCancel,
|
||||
YesNo,
|
||||
Information,
|
||||
Error,
|
||||
Warning
|
||||
}
|
||||
|
||||
public enum MessageBoxImage
|
||||
{
|
||||
Warning = 0,
|
||||
Question,
|
||||
Information,
|
||||
Error,
|
||||
None
|
||||
}
|
||||
|
||||
static MessageBoxEx msgBox;
|
||||
static MessageBoxResult _result = MessageBoxResult.No;
|
||||
|
||||
|
||||
/// 1 parameter
|
||||
public static MessageBoxResult Show(string msg)
|
||||
{
|
||||
return Show(string.Empty, msg, MessageBoxButton.OK, MessageBoxImage.None);
|
||||
}
|
||||
|
||||
// 2 parameter
|
||||
public static MessageBoxResult Show(string caption, string text)
|
||||
{
|
||||
return Show(caption, text, MessageBoxButton.OK, MessageBoxImage.None);
|
||||
}
|
||||
|
||||
/// 3 parameter
|
||||
public static MessageBoxResult Show(string caption, string msg, MessageBoxType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case MessageBoxType.ConfirmationWithYesNo:
|
||||
return Show(caption, msg, MessageBoxButton.YesNo,
|
||||
MessageBoxImage.Question);
|
||||
case MessageBoxType.YesNo:
|
||||
return Show(caption, msg, MessageBoxButton.YesNo,
|
||||
MessageBoxImage.Question);
|
||||
case MessageBoxType.ConfirmationWithYesNoCancel:
|
||||
return Show(caption, msg, MessageBoxButton.YesNoCancel,
|
||||
MessageBoxImage.Question);
|
||||
case MessageBoxType.Information:
|
||||
return Show(caption, msg, MessageBoxButton.OK,
|
||||
MessageBoxImage.Information);
|
||||
case MessageBoxType.Error:
|
||||
return Show(caption, msg, MessageBoxButton.OK,
|
||||
MessageBoxImage.Error);
|
||||
case MessageBoxType.Warning:
|
||||
return Show(caption, msg, MessageBoxButton.OK,
|
||||
MessageBoxImage.Warning);
|
||||
default:
|
||||
return MessageBoxResult.No;
|
||||
}
|
||||
}
|
||||
|
||||
// 4 parameter, Final Display Message.
|
||||
public static MessageBoxResult Show(string caption, string text, MessageBoxButton button, MessageBoxImage image)
|
||||
{
|
||||
msgBox = new MessageBoxEx();
|
||||
msgBox.TitleTextBlock.Text = text;
|
||||
msgBox.DescTextBlock.Text = caption;
|
||||
msgBox.Title = text;
|
||||
SetVisibilityOfButtons(button);
|
||||
SetImageOfMessageBox(image);
|
||||
msgBox.ShowDialog();
|
||||
return _result;
|
||||
}
|
||||
private void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender == btnOk)
|
||||
_result = MessageBoxResult.OK;
|
||||
else if (sender == btnYes)
|
||||
_result = MessageBoxResult.Yes;
|
||||
else if (sender == btnNo)
|
||||
_result = MessageBoxResult.No;
|
||||
else if (sender == btnCancel)
|
||||
_result = MessageBoxResult.Cancel;
|
||||
else
|
||||
_result = MessageBoxResult.None;
|
||||
msgBox.Close();
|
||||
msgBox = null;
|
||||
}
|
||||
|
||||
private static void SetVisibilityOfButtons(MessageBoxButton button)
|
||||
{
|
||||
switch (button)
|
||||
{
|
||||
case MessageBoxButton.OK:
|
||||
msgBox.btnCancel.Visibility = Visibility.Collapsed;
|
||||
msgBox.btnNo.Visibility = Visibility.Collapsed;
|
||||
msgBox.btnYes.Visibility = Visibility.Collapsed;
|
||||
msgBox.btnOk.Focus();
|
||||
break;
|
||||
case MessageBoxButton.OKCancel:
|
||||
msgBox.btnNo.Visibility = Visibility.Collapsed;
|
||||
msgBox.btnYes.Visibility = Visibility.Collapsed;
|
||||
msgBox.btnCancel.Focus();
|
||||
break;
|
||||
case MessageBoxButton.YesNo:
|
||||
msgBox.btnOk.Visibility = Visibility.Collapsed;
|
||||
msgBox.btnCancel.Visibility = Visibility.Collapsed;
|
||||
msgBox.btnNo.Focus();
|
||||
break;
|
||||
case MessageBoxButton.YesNoCancel:
|
||||
msgBox.btnOk.Visibility = Visibility.Collapsed;
|
||||
msgBox.btnCancel.Focus();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
private static void SetImageOfMessageBox(MessageBoxImage image)
|
||||
{
|
||||
switch (image)
|
||||
{
|
||||
case MessageBoxImage.Warning:
|
||||
msgBox.SetImage("Warning.png");
|
||||
msgBox.Img.Visibility = Visibility.Visible;
|
||||
break;
|
||||
case MessageBoxImage.Question:
|
||||
msgBox.SetImage("Question.png");
|
||||
msgBox.Img.Visibility = Visibility.Visible;
|
||||
break;
|
||||
case MessageBoxImage.Information:
|
||||
msgBox.SetImage("Information.png");
|
||||
msgBox.Img.Visibility = Visibility.Visible;
|
||||
break;
|
||||
case MessageBoxImage.Error:
|
||||
msgBox.SetImage("Error.png");
|
||||
msgBox.Img.Visibility = Visibility.Visible;
|
||||
break;
|
||||
default:
|
||||
msgBox.Img.Visibility = Visibility.Collapsed;
|
||||
break;
|
||||
}
|
||||
}
|
||||
private void SetImage(string imageName)
|
||||
{
|
||||
string uri = Constant.ProgramDirectory + "/Images/" + imageName;
|
||||
var uriSource = new Uri(uri, UriKind.RelativeOrAbsolute);
|
||||
Img.Source = new BitmapImage(uriSource);
|
||||
}
|
||||
private void cmdEsc_OnPress(object sender, ExecutedRoutedEventArgs e)
|
||||
{
|
||||
DialogResult = false;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Button_Cancel(object sender, RoutedEventArgs e)
|
||||
{
|
||||
msgBox.Close();
|
||||
msgBox = null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,8 @@
|
|||
<converters:TextConverter x:Key="TextConverter" />
|
||||
<core:TranslationConverter x:Key="TranslationConverter" />
|
||||
|
||||
<!-- Icon for Theme Type Label -->
|
||||
<Geometry x:Key="circle_half_stroke_solid">F1 M512,512z M0,0z M448,256C448,150,362,64,256,64L256,448C362,448,448,362,448,256z M0,256A256,256,0,1,1,512,256A256,256,0,1,1,0,256z</Geometry>
|
||||
<Style x:Key="StoreItemFocusVisualStyleKey">
|
||||
<Setter Property="Control.Template">
|
||||
<Setter.Value>
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ using Flow.Launcher.Core.Resource;
|
|||
using Flow.Launcher.Infrastructure;
|
||||
using Flow.Launcher.Infrastructure.UserSettings;
|
||||
using Flow.Launcher.Plugin;
|
||||
using static Flow.Launcher.MessageBoxEx;
|
||||
|
||||
namespace Flow.Launcher.SettingPages.ViewModels;
|
||||
|
||||
|
|
@ -62,10 +63,10 @@ public partial class SettingsPaneAboutViewModel : BaseModel
|
|||
[RelayCommand]
|
||||
private void AskClearLogFolderConfirmation()
|
||||
{
|
||||
var confirmResult = MessageBox.Show(
|
||||
var confirmResult = MessageBoxEx.Show(
|
||||
InternationalizationManager.Instance.GetTranslation("clearlogfolderMessage"),
|
||||
InternationalizationManager.Instance.GetTranslation("clearlogfolder"),
|
||||
MessageBoxButton.YesNo
|
||||
MessageBoxType.YesNo
|
||||
);
|
||||
|
||||
if (confirmResult == MessageBoxResult.Yes)
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
xmlns:cc="clr-namespace:Flow.Launcher.Resources.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:flowlauncher="clr-namespace:Flow.Launcher"
|
||||
xmlns:userSettings="clr-namespace:Flow.Launcher.Infrastructure.UserSettings;assembly=Flow.Launcher.Infrastructure"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="http://schemas.modernwpf.com/2019"
|
||||
xmlns:userSettings="clr-namespace:Flow.Launcher.Infrastructure.UserSettings;assembly=Flow.Launcher.Infrastructure"
|
||||
xmlns:viewModels="clr-namespace:Flow.Launcher.SettingPages.ViewModels"
|
||||
Title="Hotkey"
|
||||
d:DataContext="{d:DesignInstance viewModels:SettingsPaneHotkeyViewModel}"
|
||||
|
|
@ -33,9 +33,9 @@
|
|||
Sub="{DynamicResource flowlauncherHotkeyToolTip}">
|
||||
<flowlauncher:HotkeyControl
|
||||
ChangeHotkey="{Binding SetTogglingHotkeyCommand}"
|
||||
HotkeySettings="{Binding Settings}"
|
||||
DefaultHotkey="Alt+Space"
|
||||
Hotkey="{Binding Settings.Hotkey}"
|
||||
HotkeySettings="{Binding Settings}"
|
||||
ValidateKeyGesture="True"
|
||||
WindowTitle="{DynamicResource flowlauncherHotkey}" />
|
||||
</cc:Card>
|
||||
|
|
@ -45,17 +45,15 @@
|
|||
Icon=""
|
||||
Sub="{DynamicResource previewHotkeyToolTip}">
|
||||
<flowlauncher:HotkeyControl
|
||||
HotkeySettings="{Binding Settings}"
|
||||
DefaultHotkey="F1"
|
||||
Hotkey="{Binding Settings.PreviewHotkey}"
|
||||
HotkeySettings="{Binding Settings}"
|
||||
ValidateKeyGesture="False"
|
||||
WindowTitle="{DynamicResource previewHotkey}" />
|
||||
</cc:Card>
|
||||
|
||||
<cc:CardGroup Margin="0 12 0 0">
|
||||
<cc:Card
|
||||
Title="{DynamicResource openResultModifiers}"
|
||||
Sub="{DynamicResource openResultModifiersToolTip}">
|
||||
<cc:Card Title="{DynamicResource openResultModifiers}" Sub="{DynamicResource openResultModifiersToolTip}">
|
||||
<ComboBox
|
||||
Width="120"
|
||||
FontSize="14"
|
||||
|
|
@ -106,9 +104,9 @@
|
|||
Icon=""
|
||||
Type="Inside">
|
||||
<flowlauncher:HotkeyControl
|
||||
HotkeySettings="{Binding Settings}"
|
||||
DefaultHotkey="Ctrl+I"
|
||||
Hotkey="{Binding Settings.OpenContextMenuHotkey}"
|
||||
HotkeySettings="{Binding Settings}"
|
||||
ValidateKeyGesture="False" />
|
||||
</cc:Card>
|
||||
<cc:Card
|
||||
|
|
@ -117,15 +115,20 @@
|
|||
Type="Inside">
|
||||
<cc:HotkeyDisplay Keys="Shift+Enter" />
|
||||
</cc:Card>
|
||||
|
||||
<cc:Card
|
||||
Title="{DynamicResource OpenNativeContextMenuHotkey}"
|
||||
Icon=""
|
||||
Type="Inside">
|
||||
<cc:HotkeyDisplay Keys="Alt+Enter" />
|
||||
</cc:Card>
|
||||
<cc:Card
|
||||
Title="{DynamicResource SettingWindowHotkey}"
|
||||
Icon=""
|
||||
Type="Inside">
|
||||
<flowlauncher:HotkeyControl
|
||||
HotkeySettings="{Binding Settings}"
|
||||
DefaultHotkey="Ctrl+I"
|
||||
Hotkey="{Binding Settings.SettingWindowHotkey}"
|
||||
HotkeySettings="{Binding Settings}"
|
||||
ValidateKeyGesture="False" />
|
||||
</cc:Card>
|
||||
<cc:Card
|
||||
|
|
@ -172,9 +175,9 @@
|
|||
Icon=""
|
||||
Type="Inside">
|
||||
<flowlauncher:HotkeyControl
|
||||
HotkeySettings="{Binding Settings}"
|
||||
DefaultHotkey=""
|
||||
Hotkey="{Binding Settings.SelectPrevPageHotkey}"
|
||||
HotkeySettings="{Binding Settings}"
|
||||
ValidateKeyGesture="False" />
|
||||
</cc:Card>
|
||||
<cc:Card
|
||||
|
|
@ -182,9 +185,9 @@
|
|||
Icon=""
|
||||
Type="Inside">
|
||||
<flowlauncher:HotkeyControl
|
||||
HotkeySettings="{Binding Settings}"
|
||||
DefaultHotkey=""
|
||||
Hotkey="{Binding Settings.SelectNextPageHotkey}"
|
||||
HotkeySettings="{Binding Settings}"
|
||||
ValidateKeyGesture="False" />
|
||||
</cc:Card>
|
||||
|
||||
|
|
@ -217,9 +220,9 @@
|
|||
Sub="{DynamicResource autoCompleteHotkeyToolTip}">
|
||||
<cc:ExCard.SideContent>
|
||||
<flowlauncher:HotkeyControl
|
||||
HotkeySettings="{Binding Settings}"
|
||||
DefaultHotkey="Ctrl+Tab"
|
||||
Hotkey="{Binding Settings.AutoCompleteHotkey}"
|
||||
HotkeySettings="{Binding Settings}"
|
||||
ValidateKeyGesture="False" />
|
||||
</cc:ExCard.SideContent>
|
||||
<cc:Card
|
||||
|
|
@ -227,9 +230,9 @@
|
|||
Sub="{DynamicResource AdditionalHotkeyToolTip}"
|
||||
Type="InsideFit">
|
||||
<flowlauncher:HotkeyControl
|
||||
HotkeySettings="{Binding Settings}"
|
||||
DefaultHotkey=""
|
||||
Hotkey="{Binding Settings.AutoCompleteHotkey2}"
|
||||
HotkeySettings="{Binding Settings}"
|
||||
ValidateKeyGesture="False" />
|
||||
</cc:Card>
|
||||
</cc:ExCard>
|
||||
|
|
@ -240,9 +243,9 @@
|
|||
Icon="">
|
||||
<cc:ExCard.SideContent>
|
||||
<flowlauncher:HotkeyControl
|
||||
HotkeySettings="{Binding Settings}"
|
||||
DefaultHotkey="Shift+Tab"
|
||||
Hotkey="{Binding Settings.SelectPrevItemHotkey}"
|
||||
HotkeySettings="{Binding Settings}"
|
||||
ValidateKeyGesture="False" />
|
||||
</cc:ExCard.SideContent>
|
||||
<cc:Card
|
||||
|
|
@ -250,9 +253,9 @@
|
|||
Sub="{DynamicResource AdditionalHotkeyToolTip}"
|
||||
Type="InsideFit">
|
||||
<flowlauncher:HotkeyControl
|
||||
HotkeySettings="{Binding Settings}"
|
||||
DefaultHotkey=""
|
||||
Hotkey="{Binding Settings.SelectPrevItemHotkey2}"
|
||||
HotkeySettings="{Binding Settings}"
|
||||
ValidateKeyGesture="False" />
|
||||
</cc:Card>
|
||||
</cc:ExCard>
|
||||
|
|
@ -263,9 +266,9 @@
|
|||
Icon="">
|
||||
<cc:ExCard.SideContent>
|
||||
<flowlauncher:HotkeyControl
|
||||
HotkeySettings="{Binding Settings}"
|
||||
DefaultHotkey="Tab"
|
||||
Hotkey="{Binding Settings.SelectNextItemHotkey}"
|
||||
HotkeySettings="{Binding Settings}"
|
||||
ValidateKeyGesture="False" />
|
||||
</cc:ExCard.SideContent>
|
||||
<cc:Card
|
||||
|
|
@ -273,9 +276,9 @@
|
|||
Sub="{DynamicResource AdditionalHotkeyToolTip}"
|
||||
Type="InsideFit">
|
||||
<flowlauncher:HotkeyControl
|
||||
HotkeySettings="{Binding Settings}"
|
||||
DefaultHotkey=""
|
||||
Hotkey="{Binding Settings.SelectNextItemHotkey2}"
|
||||
HotkeySettings="{Binding Settings}"
|
||||
ValidateKeyGesture="False" />
|
||||
</cc:Card>
|
||||
</cc:ExCard>
|
||||
|
|
@ -435,8 +438,7 @@
|
|||
<GridViewColumn Width="430" Header="{DynamicResource builtinShortcutDescription}">
|
||||
<GridViewColumn.CellTemplate>
|
||||
<DataTemplate DataType="{x:Type userSettings:BuiltinShortcutModel}">
|
||||
<TextBlock
|
||||
Text="{Binding Description, Converter={StaticResource TranslationConverter}}" />
|
||||
<TextBlock Text="{Binding Description, Converter={StaticResource TranslationConverter}}" />
|
||||
</DataTemplate>
|
||||
</GridViewColumn.CellTemplate>
|
||||
</GridViewColumn>
|
||||
|
|
|
|||
|
|
@ -390,17 +390,21 @@
|
|||
Icon="">
|
||||
<cc:ExCard.SideContent>
|
||||
<StackPanel VerticalAlignment="Center" Orientation="Horizontal">
|
||||
<ui:FontIcon
|
||||
Margin="0 2 8 0"
|
||||
<ui:PathIcon
|
||||
Width="12"
|
||||
Margin="0 1 8 0"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="12"
|
||||
Glyph=""
|
||||
Data="{DynamicResource circle_half_stroke_solid}"
|
||||
ToolTip="{DynamicResource TypeIsDarkToolTip}"
|
||||
ToolTipService.InitialShowDelay="0"
|
||||
Visibility="{Binding SelectedTheme.IsDark, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
<ui:FontIcon
|
||||
Margin="0 2 8 0"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="12"
|
||||
Glyph=""
|
||||
ToolTip="{DynamicResource TypeHasBlurToolTip}"
|
||||
ToolTipService.InitialShowDelay="0"
|
||||
Visibility="{Binding SelectedTheme.HasBlur, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
<TextBlock Text="{Binding SelectedTheme.Name}" />
|
||||
</StackPanel>
|
||||
|
|
@ -433,17 +437,21 @@
|
|||
VerticalAlignment="Center"
|
||||
Text="{Binding Name}"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:FontIcon
|
||||
<ui:PathIcon
|
||||
Width="12"
|
||||
Margin="8 1 0 0"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="12"
|
||||
Glyph=""
|
||||
Data="{DynamicResource circle_half_stroke_solid}"
|
||||
ToolTip="{DynamicResource TypeIsDarkToolTip}"
|
||||
ToolTipService.InitialShowDelay="0"
|
||||
Visibility="{Binding IsDark, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
<ui:FontIcon
|
||||
Margin="8 1 0 0"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="12"
|
||||
Glyph=""
|
||||
ToolTip="{DynamicResource TypeHasBlurToolTip}"
|
||||
ToolTipService.InitialShowDelay="0"
|
||||
Visibility="{Binding HasBlur, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
|
|
@ -407,6 +407,10 @@ namespace Flow.Launcher.ViewModel
|
|||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region BasicCommands
|
||||
|
||||
[RelayCommand]
|
||||
private void OpenSetting()
|
||||
{
|
||||
|
|
@ -581,56 +585,6 @@ namespace Flow.Launcher.ViewModel
|
|||
Settings.MaxResultsToShow -= 1;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public void TogglePreview()
|
||||
{
|
||||
if (!PreviewVisible)
|
||||
{
|
||||
ShowPreview();
|
||||
}
|
||||
else
|
||||
{
|
||||
HidePreview();
|
||||
}
|
||||
|
||||
ContextMenu.IsPreviewOn = PreviewVisible;
|
||||
History.IsPreviewOn = PreviewVisible;
|
||||
Results.IsPreviewOn = PreviewVisible;
|
||||
}
|
||||
|
||||
private void ShowPreview()
|
||||
{
|
||||
ResultAreaColumn = 1;
|
||||
PreviewVisible = true;
|
||||
Results.SelectedItem?.LoadPreviewImage();
|
||||
}
|
||||
|
||||
private void HidePreview()
|
||||
{
|
||||
ResultAreaColumn = 3;
|
||||
PreviewVisible = false;
|
||||
}
|
||||
|
||||
public void ResetPreview()
|
||||
{
|
||||
if (Settings.AlwaysPreview == true)
|
||||
{
|
||||
ShowPreview();
|
||||
}
|
||||
else
|
||||
{
|
||||
HidePreview();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdatePreview()
|
||||
{
|
||||
if (PreviewVisible)
|
||||
{
|
||||
Results.SelectedItem?.LoadPreviewImage();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// we need move cursor to end when we manually changed query
|
||||
/// but we don't want to move cursor to end when query is updated from TextBox
|
||||
|
|
@ -805,10 +759,186 @@ namespace Flow.Launcher.ViewModel
|
|||
public string Image => Constant.QueryTextBoxIconImagePath;
|
||||
|
||||
public bool StartWithEnglishMode => Settings.AlwaysStartEn;
|
||||
|
||||
#endregion
|
||||
|
||||
public bool PreviewVisible { get; set; } = false;
|
||||
#region Preview
|
||||
|
||||
public int ResultAreaColumn { get; set; } = 1;
|
||||
public bool InternalPreviewVisible
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ResultAreaColumn == ResultAreaColumnPreviewShown)
|
||||
return true;
|
||||
|
||||
if (ResultAreaColumn == ResultAreaColumnPreviewHidden)
|
||||
return false;
|
||||
#if DEBUG
|
||||
throw new NotImplementedException("ResultAreaColumn should match ResultAreaColumnPreviewShown/ResultAreaColumnPreviewHidden value");
|
||||
#else
|
||||
Log.Error("MainViewModel", "ResultAreaColumnPreviewHidden/ResultAreaColumnPreviewShown int value not implemented", "InternalPreviewVisible");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly int ResultAreaColumnPreviewShown = 1;
|
||||
|
||||
private static readonly int ResultAreaColumnPreviewHidden = 3;
|
||||
|
||||
public int ResultAreaColumn { get; set; } = ResultAreaColumnPreviewShown;
|
||||
|
||||
// This is not a reliable indicator of whether external preview is visible due to the
|
||||
// ability of manually closing/exiting the external preview program which, does not inform flow that
|
||||
// preview is no longer available.
|
||||
public bool ExternalPreviewVisible { get; set; } = false;
|
||||
|
||||
private void ShowPreview()
|
||||
{
|
||||
var useExternalPreview = PluginManager.UseExternalPreview();
|
||||
|
||||
switch (useExternalPreview)
|
||||
{
|
||||
case true
|
||||
when CanExternalPreviewSelectedResult(out var path):
|
||||
// Internal preview may still be on when user switches to external
|
||||
if (InternalPreviewVisible)
|
||||
HideInternalPreview();
|
||||
OpenExternalPreview(path);
|
||||
break;
|
||||
|
||||
case true
|
||||
when !CanExternalPreviewSelectedResult(out var _):
|
||||
if (ExternalPreviewVisible)
|
||||
CloseExternalPreview();
|
||||
ShowInternalPreview();
|
||||
break;
|
||||
|
||||
case false:
|
||||
ShowInternalPreview();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void HidePreview()
|
||||
{
|
||||
if (PluginManager.UseExternalPreview())
|
||||
CloseExternalPreview();
|
||||
|
||||
if (InternalPreviewVisible)
|
||||
HideInternalPreview();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void TogglePreview()
|
||||
{
|
||||
if (InternalPreviewVisible || ExternalPreviewVisible)
|
||||
{
|
||||
HidePreview();
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowPreview();
|
||||
}
|
||||
}
|
||||
|
||||
private void ToggleInternalPreview()
|
||||
{
|
||||
if (!InternalPreviewVisible)
|
||||
{
|
||||
ShowInternalPreview();
|
||||
}
|
||||
else
|
||||
{
|
||||
HideInternalPreview();
|
||||
}
|
||||
}
|
||||
|
||||
private void OpenExternalPreview(string path, bool sendFailToast = true)
|
||||
{
|
||||
_ = PluginManager.OpenExternalPreviewAsync(path, sendFailToast).ConfigureAwait(false);
|
||||
ExternalPreviewVisible = true;
|
||||
}
|
||||
|
||||
private void CloseExternalPreview()
|
||||
{
|
||||
_ = PluginManager.CloseExternalPreviewAsync().ConfigureAwait(false);
|
||||
ExternalPreviewVisible = false;
|
||||
}
|
||||
|
||||
private void SwitchExternalPreview(string path, bool sendFailToast = true)
|
||||
{
|
||||
_ = PluginManager.SwitchExternalPreviewAsync(path,sendFailToast).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private void ShowInternalPreview()
|
||||
{
|
||||
ResultAreaColumn = ResultAreaColumnPreviewShown;
|
||||
Results.SelectedItem?.LoadPreviewImage();
|
||||
}
|
||||
|
||||
private void HideInternalPreview()
|
||||
{
|
||||
ResultAreaColumn = ResultAreaColumnPreviewHidden;
|
||||
}
|
||||
|
||||
public void ResetPreview()
|
||||
{
|
||||
switch (Settings.AlwaysPreview)
|
||||
{
|
||||
case true
|
||||
when PluginManager.AllowAlwaysPreview() && CanExternalPreviewSelectedResult(out var path):
|
||||
OpenExternalPreview(path);
|
||||
break;
|
||||
|
||||
case true:
|
||||
ShowInternalPreview();
|
||||
break;
|
||||
|
||||
case false:
|
||||
HidePreview();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdatePreview()
|
||||
{
|
||||
switch (PluginManager.UseExternalPreview())
|
||||
{
|
||||
case true
|
||||
when CanExternalPreviewSelectedResult(out var path):
|
||||
if (ExternalPreviewVisible)
|
||||
{
|
||||
SwitchExternalPreview(path, false);
|
||||
}
|
||||
else if (InternalPreviewVisible)
|
||||
{
|
||||
HideInternalPreview();
|
||||
OpenExternalPreview(path);
|
||||
}
|
||||
break;
|
||||
|
||||
case true
|
||||
when !CanExternalPreviewSelectedResult(out var _):
|
||||
if (ExternalPreviewVisible)
|
||||
{
|
||||
CloseExternalPreview();
|
||||
ShowInternalPreview();
|
||||
}
|
||||
break;
|
||||
|
||||
case false
|
||||
when InternalPreviewVisible:
|
||||
Results.SelectedItem?.LoadPreviewImage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private bool CanExternalPreviewSelectedResult(out string path)
|
||||
{
|
||||
path = Results.SelectedItem?.Result?.Preview.FilePath;
|
||||
return !string.IsNullOrEmpty(path);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
|
@ -1232,6 +1362,9 @@ namespace Flow.Launcher.ViewModel
|
|||
lastContextMenuResult = new Result();
|
||||
lastContextMenuResults = new List<Result>();
|
||||
|
||||
if (ExternalPreviewVisible)
|
||||
CloseExternalPreview();
|
||||
|
||||
if (!SelectedIsFromQueryResults())
|
||||
{
|
||||
SelectedResults = Results;
|
||||
|
|
|
|||
|
|
@ -222,34 +222,7 @@ namespace Flow.Launcher.Plugin.Explorer
|
|||
if (record.Type is ResultType.Volume)
|
||||
return false;
|
||||
|
||||
var screenWithMouseCursor = System.Windows.Forms.Screen.FromPoint(System.Windows.Forms.Cursor.Position);
|
||||
var xOfScreenCenter = screenWithMouseCursor.WorkingArea.Left + screenWithMouseCursor.WorkingArea.Width / 2;
|
||||
var yOfScreenCenter = screenWithMouseCursor.WorkingArea.Top + screenWithMouseCursor.WorkingArea.Height / 2;
|
||||
var showPosition = new System.Drawing.Point(xOfScreenCenter, yOfScreenCenter);
|
||||
|
||||
switch (record.Type)
|
||||
{
|
||||
case ResultType.File:
|
||||
{
|
||||
var fileInfos = new FileInfo[]
|
||||
{
|
||||
new(record.FullPath)
|
||||
};
|
||||
|
||||
new Peter.ShellContextMenu().ShowContextMenu(fileInfos, showPosition);
|
||||
break;
|
||||
}
|
||||
case ResultType.Folder:
|
||||
{
|
||||
var directoryInfos = new DirectoryInfo[]
|
||||
{
|
||||
new(record.FullPath)
|
||||
};
|
||||
|
||||
new Peter.ShellContextMenu().ShowContextMenu(directoryInfos, showPosition);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ResultManager.ShowNativeContextMenu(record.FullPath, record.Type);
|
||||
|
||||
return false;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ using System.Windows.Input;
|
|||
using Path = System.IO.Path;
|
||||
using System.Windows.Controls;
|
||||
using Flow.Launcher.Plugin.Explorer.Views;
|
||||
using Peter;
|
||||
|
||||
namespace Flow.Launcher.Plugin.Explorer.Search
|
||||
{
|
||||
|
|
@ -70,6 +71,27 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
};
|
||||
}
|
||||
|
||||
internal static void ShowNativeContextMenu(string path, ResultType type)
|
||||
{
|
||||
var screenWithMouseCursor = System.Windows.Forms.Screen.FromPoint(System.Windows.Forms.Cursor.Position);
|
||||
var xOfScreenCenter = screenWithMouseCursor.WorkingArea.Left + screenWithMouseCursor.WorkingArea.Width / 2;
|
||||
var yOfScreenCenter = screenWithMouseCursor.WorkingArea.Top + screenWithMouseCursor.WorkingArea.Height / 2;
|
||||
var showPosition = new System.Drawing.Point(xOfScreenCenter, yOfScreenCenter);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ResultType.File:
|
||||
var fileInfo = new FileInfo[] { new(path) };
|
||||
new ShellContextMenu().ShowContextMenu(fileInfo, showPosition);
|
||||
break;
|
||||
|
||||
case ResultType.Folder:
|
||||
var folderInfo = new System.IO.DirectoryInfo[] { new(path) };
|
||||
new ShellContextMenu().ShowContextMenu(folderInfo, showPosition);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
internal static Result CreateFolderResult(string title, string subtitle, string path, Query query, int score = 0, bool windowsIndexed = false)
|
||||
{
|
||||
return new Result
|
||||
|
|
@ -80,8 +102,17 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
AutoCompleteText = GetAutoCompleteText(title, query, path, ResultType.Folder),
|
||||
TitleHighlightData = StringMatcher.FuzzySearch(query.Search, title).MatchData,
|
||||
CopyText = path,
|
||||
Preview = new Result.PreviewInfo
|
||||
{
|
||||
FilePath = path,
|
||||
},
|
||||
Action = c =>
|
||||
{
|
||||
if (c.SpecialKeyState.ToModifierKeys() == ModifierKeys.Alt)
|
||||
{
|
||||
ShowNativeContextMenu(path, ResultType.Folder);
|
||||
return false;
|
||||
}
|
||||
// open folder
|
||||
if (c.SpecialKeyState.ToModifierKeys() == (ModifierKeys.Control | ModifierKeys.Shift))
|
||||
{
|
||||
|
|
@ -165,6 +196,10 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
Score = 500,
|
||||
ProgressBar = progressValue,
|
||||
ProgressBarColor = progressBarColor,
|
||||
Preview = new Result.PreviewInfo
|
||||
{
|
||||
FilePath = path,
|
||||
},
|
||||
Action = _ =>
|
||||
{
|
||||
OpenFolder(path);
|
||||
|
|
@ -218,8 +253,13 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
IcoPath = folderPath,
|
||||
Score = 500,
|
||||
CopyText = folderPath,
|
||||
Action = _ =>
|
||||
Action = c =>
|
||||
{
|
||||
if (c.SpecialKeyState.ToModifierKeys() == ModifierKeys.Alt)
|
||||
{
|
||||
ShowNativeContextMenu(folderPath, ResultType.Folder);
|
||||
return false;
|
||||
}
|
||||
OpenFolder(folderPath);
|
||||
return true;
|
||||
},
|
||||
|
|
@ -229,10 +269,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
|
||||
internal static Result CreateFileResult(string filePath, Query query, int score = 0, bool windowsIndexed = false)
|
||||
{
|
||||
Result.PreviewInfo preview = IsMedia(Path.GetExtension(filePath))
|
||||
? new Result.PreviewInfo { IsMedia = true, PreviewImagePath = filePath, }
|
||||
: Result.PreviewInfo.Default;
|
||||
|
||||
bool isMedia = IsMedia(Path.GetExtension(filePath));
|
||||
var title = Path.GetFileName(filePath);
|
||||
|
||||
|
||||
|
|
@ -243,7 +280,12 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
Title = title,
|
||||
SubTitle = Path.GetDirectoryName(filePath),
|
||||
IcoPath = filePath,
|
||||
Preview = preview,
|
||||
Preview = new Result.PreviewInfo
|
||||
{
|
||||
IsMedia = isMedia,
|
||||
PreviewImagePath = isMedia ? filePath : null,
|
||||
FilePath = filePath,
|
||||
},
|
||||
AutoCompleteText = GetAutoCompleteText(title, query, filePath, ResultType.File),
|
||||
TitleHighlightData = StringMatcher.FuzzySearch(query.Search, title).MatchData,
|
||||
Score = score,
|
||||
|
|
@ -251,6 +293,11 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
PreviewPanel = new Lazy<UserControl>(() => new PreviewPanel(Settings, filePath)),
|
||||
Action = c =>
|
||||
{
|
||||
if (c.SpecialKeyState.ToModifierKeys() == ModifierKeys.Alt)
|
||||
{
|
||||
ShowNativeContextMenu(filePath, ResultType.File);
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
if (c.SpecialKeyState.ToModifierKeys() == (ModifierKeys.Control | ModifierKeys.Shift))
|
||||
|
|
|
|||
Loading…
Reference in a new issue