mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Merge Dev
This commit is contained in:
commit
2887a17ceb
14 changed files with 420 additions and 290 deletions
19
Flow.Launcher/Converters/DateTimeFormatToNowConverter.cs
Normal file
19
Flow.Launcher/Converters/DateTimeFormatToNowConverter.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Flow.Launcher.Converters
|
||||
{
|
||||
public class DateTimeFormatToNowConverter : IValueConverter
|
||||
{
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return value is not string format ? null : DateTime.Now.ToString(format);
|
||||
}
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -250,13 +250,15 @@
|
|||
IsHitTestVisible="False"
|
||||
Style="{DynamicResource ClockPanel}">
|
||||
<TextBlock
|
||||
Style="{DynamicResource DateBox}"
|
||||
Text="{Binding DateText}"
|
||||
Visibility="{Binding Settings.UseDate, Converter={StaticResource BooleanToVisibilityConverter}}" />
|
||||
<TextBlock
|
||||
x:Name="ClockBox"
|
||||
Style="{DynamicResource ClockBox}"
|
||||
Text="{Binding ClockText}"
|
||||
Visibility="{Binding Settings.UseClock, Converter={StaticResource BooleanToVisibilityConverter}}" />
|
||||
<TextBlock
|
||||
x:Name="DateBox"
|
||||
Style="{DynamicResource DateBox}"
|
||||
Text="{Binding DateText}"
|
||||
Visibility="{Binding Settings.UseDate, Converter={StaticResource BooleanToVisibilityConverter}}" />
|
||||
</StackPanel>
|
||||
|
||||
<Canvas Style="{DynamicResource SearchIconPosition}">
|
||||
|
|
|
|||
|
|
@ -30,6 +30,10 @@ using System.Windows.Data;
|
|||
using ModernWpf.Controls;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms.Design.Behavior;
|
||||
using System.Security.Cryptography;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.VisualBasic.Devices;
|
||||
using Microsoft.FSharp.Data.UnitSystems.SI.UnitNames;
|
||||
|
||||
namespace Flow.Launcher
|
||||
{
|
||||
|
|
@ -105,7 +109,6 @@ namespace Flow.Launcher
|
|||
// since the default main window visibility is visible
|
||||
// so we need set focus during startup
|
||||
QueryTextBox.Focus();
|
||||
|
||||
_viewModel.PropertyChanged += (o, e) =>
|
||||
{
|
||||
switch (e.PropertyName)
|
||||
|
|
@ -243,7 +246,9 @@ namespace Flow.Launcher
|
|||
Icon = Properties.Resources.app,
|
||||
Visible = !_settings.HideNotifyIcon
|
||||
};
|
||||
|
||||
contextMenu = new ContextMenu();
|
||||
|
||||
var openIcon = new FontIcon { Glyph = "\ue71e" };
|
||||
var open = new MenuItem
|
||||
{
|
||||
|
|
@ -280,9 +285,11 @@ namespace Flow.Launcher
|
|||
positionreset.Click += (o, e) => PositionReset();
|
||||
settings.Click += (o, e) => App.API.OpenSettingDialog();
|
||||
exit.Click += (o, e) => Close();
|
||||
contextMenu.Items.Add(open);
|
||||
|
||||
gamemode.ToolTip = InternationalizationManager.Instance.GetTranslation("GameModeToolTip");
|
||||
positionreset.ToolTip = InternationalizationManager.Instance.GetTranslation("PositionResetToolTip");
|
||||
|
||||
contextMenu.Items.Add(open);
|
||||
contextMenu.Items.Add(gamemode);
|
||||
contextMenu.Items.Add(positionreset);
|
||||
contextMenu.Items.Add(settings);
|
||||
|
|
@ -359,11 +366,14 @@ namespace Flow.Launcher
|
|||
|
||||
_animating = true;
|
||||
UpdatePosition();
|
||||
Storyboard sb = new Storyboard();
|
||||
|
||||
Storyboard windowsb = new Storyboard();
|
||||
Storyboard clocksb = new Storyboard();
|
||||
Storyboard iconsb = new Storyboard();
|
||||
CircleEase easing = new CircleEase(); // or whatever easing class you want
|
||||
CircleEase easing = new CircleEase();
|
||||
easing.EasingMode = EasingMode.EaseInOut;
|
||||
var da = new DoubleAnimation
|
||||
|
||||
var WindowOpacity = new DoubleAnimation
|
||||
{
|
||||
From = 0,
|
||||
To = 1,
|
||||
|
|
@ -371,33 +381,76 @@ namespace Flow.Launcher
|
|||
FillBehavior = FillBehavior.Stop
|
||||
};
|
||||
|
||||
var da2 = new DoubleAnimation
|
||||
var WindowMotion = new DoubleAnimation
|
||||
{
|
||||
From = Top + 10,
|
||||
To = Top,
|
||||
Duration = TimeSpan.FromSeconds(0.25),
|
||||
FillBehavior = FillBehavior.Stop
|
||||
};
|
||||
var da3 = new DoubleAnimation
|
||||
{
|
||||
var IconMotion = new DoubleAnimation
|
||||
{
|
||||
From = 12,
|
||||
To = 0,
|
||||
EasingFunction = easing,
|
||||
Duration = TimeSpan.FromSeconds(0.36),
|
||||
FillBehavior = FillBehavior.Stop
|
||||
};
|
||||
Storyboard.SetTarget(da, this);
|
||||
Storyboard.SetTargetProperty(da, new PropertyPath(Window.OpacityProperty));
|
||||
Storyboard.SetTargetProperty(da2, new PropertyPath(Window.TopProperty));
|
||||
Storyboard.SetTargetProperty(da3, new PropertyPath(TopProperty));
|
||||
sb.Children.Add(da);
|
||||
sb.Children.Add(da2);
|
||||
iconsb.Children.Add(da3);
|
||||
sb.Completed += (_, _) => _animating = false;
|
||||
};
|
||||
|
||||
var ClockOpacity = new DoubleAnimation
|
||||
{
|
||||
From = 0,
|
||||
To = 1,
|
||||
EasingFunction = easing,
|
||||
Duration = TimeSpan.FromSeconds(0.36),
|
||||
FillBehavior = FillBehavior.Stop
|
||||
};
|
||||
double TargetIconOpacity = SearchIcon.Opacity; // Animation Target Opacity from Style
|
||||
var IconOpacity = new DoubleAnimation
|
||||
{
|
||||
From = 0,
|
||||
To = TargetIconOpacity,
|
||||
EasingFunction = easing,
|
||||
Duration = TimeSpan.FromSeconds(0.36),
|
||||
FillBehavior = FillBehavior.Stop
|
||||
};
|
||||
|
||||
double right = ClockPanel.Margin.Right;
|
||||
var thicknessAnimation = new ThicknessAnimation
|
||||
{
|
||||
From = new Thickness(0, 12, right, 0),
|
||||
To = new Thickness(0, 0, right, 0),
|
||||
EasingFunction = easing,
|
||||
Duration = TimeSpan.FromSeconds(0.36),
|
||||
FillBehavior = FillBehavior.Stop
|
||||
};
|
||||
|
||||
Storyboard.SetTargetProperty(ClockOpacity, new PropertyPath(OpacityProperty));
|
||||
Storyboard.SetTargetName(thicknessAnimation, "ClockPanel");
|
||||
Storyboard.SetTargetProperty(thicknessAnimation, new PropertyPath(MarginProperty));
|
||||
Storyboard.SetTarget(WindowOpacity, this);
|
||||
Storyboard.SetTargetProperty(WindowOpacity, new PropertyPath(Window.OpacityProperty));
|
||||
Storyboard.SetTargetProperty(WindowMotion, new PropertyPath(Window.TopProperty));
|
||||
Storyboard.SetTargetProperty(IconMotion, new PropertyPath(TopProperty));
|
||||
Storyboard.SetTargetProperty(IconOpacity, new PropertyPath(OpacityProperty));
|
||||
|
||||
clocksb.Children.Add(thicknessAnimation);
|
||||
clocksb.Children.Add(ClockOpacity);
|
||||
windowsb.Children.Add(WindowOpacity);
|
||||
windowsb.Children.Add(WindowMotion);
|
||||
iconsb.Children.Add(IconMotion);
|
||||
iconsb.Children.Add(IconOpacity);
|
||||
|
||||
windowsb.Completed += (_, _) => _animating = false;
|
||||
_settings.WindowLeft = Left;
|
||||
_settings.WindowTop = Top;
|
||||
|
||||
if (QueryTextBox.Text.Length == 0)
|
||||
{
|
||||
clocksb.Begin(ClockPanel);
|
||||
}
|
||||
iconsb.Begin(SearchIcon);
|
||||
sb.Begin(FlowMainWindow);
|
||||
windowsb.Begin(FlowMainWindow);
|
||||
}
|
||||
|
||||
private void OnMouseDown(object sender, MouseButtonEventArgs e)
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
</Window.CommandBindings>
|
||||
|
||||
<Window.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
|
||||
<converters:BorderClipConverter x:Key="BorderClipConverter" />
|
||||
<converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
|
||||
<converters:TextConverter x:Key="TextConverter" />
|
||||
|
|
@ -1815,13 +1816,25 @@
|
|||
</Grid.RowDefinitions>
|
||||
<Border Grid.Row="0">
|
||||
<TextBox
|
||||
x:Name="QueryTextBox"
|
||||
IsReadOnly="True"
|
||||
Style="{DynamicResource QueryBoxStyle}"
|
||||
Text="{DynamicResource hiThere}" />
|
||||
</Border>
|
||||
<StackPanel x:Name="ClockPanel" Style="{DynamicResource ClockPanel}">
|
||||
<TextBlock x:Name="DateBox" Style="{DynamicResource DateBox}" />
|
||||
<TextBlock x:Name="ClockBox" Style="{DynamicResource ClockBox}" />
|
||||
<StackPanel
|
||||
x:Name="ClockPanel"
|
||||
IsHitTestVisible="False"
|
||||
Style="{DynamicResource ClockPanel}">
|
||||
<TextBlock
|
||||
x:Name="ClockBox"
|
||||
Style="{DynamicResource ClockBox}"
|
||||
Text="{Binding ClockText}"
|
||||
Visibility="{Binding Settings.UseClock, Converter={StaticResource BooleanToVisibilityConverter}}" />
|
||||
<TextBlock
|
||||
x:Name="DateBox"
|
||||
Style="{DynamicResource DateBox}"
|
||||
Text="{Binding DateText}"
|
||||
Visibility="{Binding Settings.UseDate, Converter={StaticResource BooleanToVisibilityConverter}}" />
|
||||
</StackPanel>
|
||||
<Canvas Style="{DynamicResource SearchIconPosition}">
|
||||
<Path
|
||||
|
|
@ -2162,6 +2175,12 @@
|
|||
Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
Orientation="Horizontal">
|
||||
<TextBlock
|
||||
Margin="0,0,10,0"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="14"
|
||||
Foreground="{DynamicResource Color04B}"
|
||||
Text="{Binding ClockText}" />
|
||||
<ComboBox
|
||||
x:Name="TimeFormat"
|
||||
Grid.Column="2"
|
||||
|
|
@ -2170,14 +2189,12 @@
|
|||
VerticalAlignment="Center"
|
||||
FontSize="14"
|
||||
ItemsSource="{Binding TimeFormatList}"
|
||||
SelectedValue="{Binding Settings.TimeFormat}"
|
||||
SelectionChanged="PreviewClockAndDate" />
|
||||
SelectedItem="{Binding TimeFormat}" />
|
||||
<ui:ToggleSwitch
|
||||
IsOn="{Binding UseClock, Mode=TwoWay}"
|
||||
OffContent="{DynamicResource disable}"
|
||||
OnContent="{DynamicResource enable}"
|
||||
Style="{DynamicResource SideToggleSwitch}"
|
||||
Toggled="PreviewClockAndDate" />
|
||||
Style="{DynamicResource SideToggleSwitch}" />
|
||||
</StackPanel>
|
||||
<TextBlock Style="{StaticResource Glyph}">
|
||||

|
||||
|
|
@ -2200,6 +2217,12 @@
|
|||
Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
Orientation="Horizontal">
|
||||
<TextBlock
|
||||
Margin="0,0,10,0"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="14"
|
||||
Foreground="{DynamicResource Color04B}"
|
||||
Text="{Binding DateText}" />
|
||||
<ComboBox
|
||||
x:Name="DateFormat"
|
||||
Grid.Column="2"
|
||||
|
|
@ -2208,14 +2231,12 @@
|
|||
VerticalAlignment="Center"
|
||||
FontSize="14"
|
||||
ItemsSource="{Binding DateFormatList}"
|
||||
SelectedValue="{Binding Settings.DateFormat}"
|
||||
SelectionChanged="PreviewClockAndDate" />
|
||||
SelectedItem="{Binding DateFormat}" />
|
||||
<ui:ToggleSwitch
|
||||
IsOn="{Binding UseDate, Mode=TwoWay}"
|
||||
OffContent="{DynamicResource disable}"
|
||||
OnContent="{DynamicResource enable}"
|
||||
Style="{DynamicResource SideToggleSwitch}"
|
||||
Toggled="PreviewClockAndDate" />
|
||||
Style="{DynamicResource SideToggleSwitch}" />
|
||||
</StackPanel>
|
||||
<TextBlock Style="{StaticResource Glyph}">
|
||||

|
||||
|
|
|
|||
|
|
@ -10,17 +10,14 @@ using Flow.Launcher.ViewModel;
|
|||
using ModernWpf;
|
||||
using ModernWpf.Controls;
|
||||
using System;
|
||||
using System.Drawing.Printing;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Navigation;
|
||||
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window;
|
||||
using Button = System.Windows.Controls.Button;
|
||||
using Control = System.Windows.Controls.Control;
|
||||
using KeyEventArgs = System.Windows.Input.KeyEventArgs;
|
||||
|
|
@ -44,6 +41,7 @@ namespace Flow.Launcher
|
|||
API = api;
|
||||
InitializePosition();
|
||||
InitializeComponent();
|
||||
|
||||
}
|
||||
|
||||
#region General
|
||||
|
|
@ -64,7 +62,6 @@ namespace Flow.Launcher
|
|||
pluginStoreView.Filter = PluginStoreFilter;
|
||||
|
||||
InitializePosition();
|
||||
ClockDisplay();
|
||||
}
|
||||
|
||||
private void OnSelectPythonDirectoryClick(object sender, RoutedEventArgs e)
|
||||
|
|
@ -514,34 +511,6 @@ namespace Flow.Launcher
|
|||
}
|
||||
}
|
||||
|
||||
private void PreviewClockAndDate(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ClockDisplay();
|
||||
}
|
||||
|
||||
public void ClockDisplay()
|
||||
{
|
||||
if (settings.UseClock)
|
||||
{
|
||||
ClockBox.Visibility = Visibility.Visible;
|
||||
ClockBox.Text = DateTime.Now.ToString(settings.TimeFormat);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClockBox.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
|
||||
if (settings.UseDate)
|
||||
{
|
||||
DateBox.Visibility = Visibility.Visible;
|
||||
DateBox.Text = DateTime.Now.ToString(settings.DateFormat);
|
||||
}
|
||||
else
|
||||
{
|
||||
DateBox.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
|
||||
public void InitializePosition()
|
||||
{
|
||||
if (settings.SettingWindowTop >= 0 && settings.SettingWindowLeft >= 0)
|
||||
|
|
@ -556,6 +525,7 @@ namespace Flow.Launcher
|
|||
}
|
||||
WindowState = settings.SettingWindowState;
|
||||
}
|
||||
|
||||
public double WindowLeft()
|
||||
{
|
||||
var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position);
|
||||
|
|
|
|||
|
|
@ -100,29 +100,39 @@
|
|||
<Setter Property="Stroke" Value="Blue" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="BaseClockPosition" TargetType="{x:Type Canvas}" />
|
||||
<Style x:Key="BaseClockPanelPosition" TargetType="{x:Type Canvas}" />
|
||||
|
||||
<Style x:Key="BaseClockPanel" TargetType="{x:Type StackPanel}">
|
||||
<Setter Property="Orientation" Value="Horizontal" />
|
||||
<Setter Property="HorizontalAlignment" Value="Right" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="Height" Value="Auto" />
|
||||
<Setter Property="Margin" Value="0,0,14,0" />
|
||||
<Setter Property="Margin" Value="0,0,66,0" />
|
||||
<Setter Property="Visibility" Value="Collapsed" />
|
||||
</Style>
|
||||
<Style x:Key="BaseClockBox" TargetType="{x:Type TextBlock}">
|
||||
<Setter Property="FontSize" Value="22" />
|
||||
<Setter Property="FontSize" Value="20" />
|
||||
<Setter Property="Foreground" Value="#8f8f8f" />
|
||||
<Setter Property="HorizontalAlignment" Value="Right" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="Margin" Value="0,0,2,0" />
|
||||
<Setter Property="Margin" Value="0,0,0,0" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding ElementName=DateBox, Path=Visibility}" Value="Visible">
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
<Style x:Key="BaseDateBox" TargetType="{x:Type TextBlock}">
|
||||
<Setter Property="FontSize" Value="16" />
|
||||
<Setter Property="FontSize" Value="18" />
|
||||
<Setter Property="Foreground" Value="#8f8f8f" />
|
||||
<Setter Property="HorizontalAlignment" Value="Right" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="Margin" Value="0,0,10,0" />
|
||||
<Setter Property="Margin" Value="0,0,0,0" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding ElementName=ClockBox, Path=Visibility}" Value="Visible">
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<Style
|
||||
|
|
@ -141,8 +151,8 @@
|
|||
x:Key="ClockPanel"
|
||||
BasedOn="{StaticResource BaseClockPanel}"
|
||||
TargetType="{x:Type StackPanel}">
|
||||
<Setter Property="Margin" Value="0,0,66,0" />
|
||||
<Setter Property="Visibility" Value="Visible" />
|
||||
<Setter Property="Orientation" Value="Vertical" />
|
||||
<Setter Property="Visibility" Value="Collapsed" />
|
||||
<Style.Triggers>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
|
|
@ -150,30 +160,19 @@
|
|||
<Condition Binding="{Binding ElementName=ContextMenu, Path=Visibility}" Value="Collapsed" />
|
||||
<Condition Binding="{Binding ElementName=History, Path=Visibility}" Value="Collapsed" />
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Visibility" Value="Visible" />
|
||||
<MultiDataTrigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
From="0.0"
|
||||
To="1.0"
|
||||
Duration="0:0:0.2" />
|
||||
To="1"
|
||||
Duration="0:0:0.25" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</MultiDataTrigger.EnterActions>
|
||||
<MultiDataTrigger.ExitActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
To="0.0"
|
||||
Duration="0:0:0.2" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</MultiDataTrigger.ExitActions>
|
||||
|
||||
</MultiDataTrigger>
|
||||
|
||||
</Style.Triggers>
|
||||
|
||||
</Style>
|
||||
|
|
@ -397,6 +396,12 @@
|
|||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="HorizontalAlignment" Value="Right" />
|
||||
</Style>
|
||||
<Style
|
||||
x:Key="ClockPanelPosition"
|
||||
BasedOn="{StaticResource BaseClockPanelPosition}"
|
||||
TargetType="{x:Type Canvas}">
|
||||
<Setter Property="Margin" Value="0,2,66,0" />
|
||||
</Style>
|
||||
<Style
|
||||
x:Key="ItemHotkeyStyle"
|
||||
BasedOn="{StaticResource BaseItemHotkeyStyle}"
|
||||
|
|
|
|||
|
|
@ -96,18 +96,31 @@
|
|||
BasedOn="{StaticResource BaseClockBox}"
|
||||
TargetType="{x:Type TextBlock}">
|
||||
<Setter Property="Foreground" Value="#2C5595" />
|
||||
<Setter Property="FontSize" Value="18" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding ElementName=DateBox, Path=Visibility}" Value="Visible">
|
||||
<Setter Property="FontSize" Value="18" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
<Style
|
||||
x:Key="DateBox"
|
||||
BasedOn="{StaticResource BaseDateBox}"
|
||||
TargetType="{x:Type TextBlock}">
|
||||
<Setter Property="Margin" Value="10,0,0,0" />
|
||||
<Setter Property="FontSize" Value="18" />
|
||||
<Setter Property="Foreground" Value="#2C5595" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding ElementName=ClockBox, Path=Visibility}" Value="Visible">
|
||||
<Setter Property="FontSize" Value="18" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
<Style
|
||||
x:Key="ClockPanel"
|
||||
BasedOn="{StaticResource BaseClockPanel}"
|
||||
BasedOn="{StaticResource ClockPanel}"
|
||||
TargetType="{x:Type StackPanel}">
|
||||
<Setter Property="Margin" Value="0,0,22,0" />
|
||||
<Setter Property="Visibility" Value="Visible" />
|
||||
<Setter Property="Orientation" Value="Horizontal" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
|
|
@ -123,6 +123,7 @@
|
|||
x:Key="DateBox"
|
||||
BasedOn="{StaticResource BaseDateBox}"
|
||||
TargetType="{x:Type TextBlock}">
|
||||
<Setter Property="FontWeight" Value="Bold" />
|
||||
<Setter Property="Foreground" Value="#71114b" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
|
|
@ -159,12 +159,12 @@
|
|||
x:Key="ClockBox"
|
||||
BasedOn="{StaticResource BaseClockBox}"
|
||||
TargetType="{x:Type TextBlock}">
|
||||
<Setter Property="Foreground" Value="#b2b2b2" />
|
||||
<Setter Property="Foreground" Value="#818181" />
|
||||
</Style>
|
||||
<Style
|
||||
x:Key="DateBox"
|
||||
BasedOn="{StaticResource BaseDateBox}"
|
||||
TargetType="{x:Type TextBlock}">
|
||||
<Setter Property="Foreground" Value="#b2b2b2" />
|
||||
<Setter Property="Foreground" Value="#818181" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
|
|
|
|||
|
|
@ -175,6 +175,7 @@
|
|||
BasedOn="{StaticResource BaseClockBox}"
|
||||
TargetType="{x:Type TextBlock}">
|
||||
<Setter Property="Foreground" Value="#acacac" />
|
||||
<Setter Property="FontSize" Value="22" />
|
||||
</Style>
|
||||
<Style
|
||||
x:Key="DateBox"
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ using ISavable = Flow.Launcher.Plugin.ISavable;
|
|||
using System.IO;
|
||||
using System.Collections.Specialized;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Flow.Launcher.ViewModel
|
||||
{
|
||||
|
|
@ -77,7 +78,6 @@ namespace Flow.Launcher.ViewModel
|
|||
_userSelectedRecord = _userSelectedRecordStorage.Load();
|
||||
_topMostRecord = _topMostRecordStorage.Load();
|
||||
|
||||
InitializeKeyCommands();
|
||||
|
||||
ContextMenu = new ResultsViewModel(Settings)
|
||||
{
|
||||
|
|
@ -167,160 +167,164 @@ namespace Flow.Launcher.ViewModel
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void InitializeKeyCommands()
|
||||
[RelayCommand]
|
||||
private async Task ReloadPluginDataAsync()
|
||||
{
|
||||
EscCommand = new RelayCommand(_ =>
|
||||
Hide();
|
||||
|
||||
await PluginManager.ReloadDataAsync().ConfigureAwait(false);
|
||||
Notification.Show(InternationalizationManager.Instance.GetTranslation("success"), InternationalizationManager.Instance.GetTranslation("completedSuccessfully"));
|
||||
}
|
||||
[RelayCommand]
|
||||
private void LoadHistory()
|
||||
{
|
||||
if (SelectedIsFromQueryResults())
|
||||
{
|
||||
if (!SelectedIsFromQueryResults())
|
||||
{
|
||||
SelectedResults = Results;
|
||||
}
|
||||
else
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
});
|
||||
|
||||
ClearQueryCommand = new RelayCommand(_ =>
|
||||
SelectedResults = History;
|
||||
History.SelectedIndex = _history.Items.Count - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!string.IsNullOrEmpty(QueryText))
|
||||
{
|
||||
ChangeQueryText(string.Empty);
|
||||
|
||||
// Push Event to UI SystemQuery has changed
|
||||
//OnPropertyChanged(nameof(SystemQueryText));
|
||||
}
|
||||
});
|
||||
|
||||
SelectNextItemCommand = new RelayCommand(_ => { SelectedResults.SelectNextResult(); });
|
||||
|
||||
SelectPrevItemCommand = new RelayCommand(_ => { SelectedResults.SelectPrevResult(); });
|
||||
|
||||
SelectNextPageCommand = new RelayCommand(_ => { SelectedResults.SelectNextPage(); });
|
||||
|
||||
SelectPrevPageCommand = new RelayCommand(_ => { SelectedResults.SelectPrevPage(); });
|
||||
|
||||
SelectFirstResultCommand = new RelayCommand(_ => SelectedResults.SelectFirstResult());
|
||||
|
||||
StartHelpCommand = new RelayCommand(_ =>
|
||||
SelectedResults = Results;
|
||||
}
|
||||
}
|
||||
[RelayCommand]
|
||||
private void LoadContextMenu()
|
||||
{
|
||||
if (SelectedIsFromQueryResults())
|
||||
{
|
||||
PluginManager.API.OpenUrl("https://github.com/Flow-Launcher/Flow.Launcher/wiki/Flow-Launcher/");
|
||||
});
|
||||
OpenSettingCommand = new RelayCommand(_ => { App.API.OpenSettingDialog(); });
|
||||
OpenResultCommand = new AsyncRelayCommand(async _ =>
|
||||
// When switch to ContextMenu from QueryResults, but no item being chosen, should do nothing
|
||||
// i.e. Shift+Enter/Ctrl+O right after Alt + Space should do nothing
|
||||
if (SelectedResults.SelectedItem != null)
|
||||
SelectedResults = ContextMenu;
|
||||
}
|
||||
else
|
||||
{
|
||||
var results = SelectedResults;
|
||||
SelectedResults = Results;
|
||||
}
|
||||
}
|
||||
[RelayCommand]
|
||||
private void Backspace(object index)
|
||||
{
|
||||
var query = QueryBuilder.Build(QueryText.Trim(), PluginManager.NonGlobalPlugins);
|
||||
|
||||
var result = results.SelectedItem?.Result;
|
||||
if (result == null)
|
||||
// GetPreviousExistingDirectory does not require trailing '\', otherwise will return empty string
|
||||
var path = FilesFolders.GetPreviousExistingDirectory((_) => true, query.Search.TrimEnd('\\'));
|
||||
|
||||
var actionKeyword = string.IsNullOrEmpty(query.ActionKeyword) ? string.Empty : $"{query.ActionKeyword} ";
|
||||
|
||||
ChangeQueryText($"{actionKeyword}{path}");
|
||||
}
|
||||
[RelayCommand]
|
||||
private void AutocompleteQuery()
|
||||
{
|
||||
var result = SelectedResults.SelectedItem?.Result;
|
||||
if (result != null && SelectedIsFromQueryResults()) // SelectedItem returns null if selection is empty.
|
||||
{
|
||||
var autoCompleteText = result.Title;
|
||||
|
||||
if (!string.IsNullOrEmpty(result.AutoCompleteText))
|
||||
{
|
||||
return;
|
||||
autoCompleteText = result.AutoCompleteText;
|
||||
}
|
||||
var hideWindow = await result.ExecuteAsync(new ActionContext
|
||||
else if (!string.IsNullOrEmpty(SelectedResults.SelectedItem?.QuerySuggestionText))
|
||||
{
|
||||
autoCompleteText = SelectedResults.SelectedItem.QuerySuggestionText;
|
||||
}
|
||||
|
||||
var specialKeyState = GlobalHotkey.CheckModifiers();
|
||||
if (specialKeyState.ShiftPressed)
|
||||
{
|
||||
autoCompleteText = result.SubTitle;
|
||||
}
|
||||
|
||||
ChangeQueryText(autoCompleteText);
|
||||
}
|
||||
}
|
||||
[RelayCommand]
|
||||
private async Task OpenResultAsync(string index)
|
||||
{
|
||||
var results = SelectedResults;
|
||||
if (index is not null)
|
||||
{
|
||||
results.SelectedIndex = int.Parse(index);
|
||||
}
|
||||
var result = results.SelectedItem?.Result;
|
||||
if (result == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var hideWindow = await result.ExecuteAsync(new ActionContext
|
||||
{
|
||||
SpecialKeyState = GlobalHotkey.CheckModifiers()
|
||||
}).ConfigureAwait(false);
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (hideWindow)
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
|
||||
if (SelectedIsFromQueryResults())
|
||||
{
|
||||
_userSelectedRecord.Add(result);
|
||||
_history.Add(result.OriginQuery.RawQuery);
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectedResults = Results;
|
||||
}
|
||||
});
|
||||
|
||||
AutocompleteQueryCommand = new RelayCommand(_ =>
|
||||
{
|
||||
var result = SelectedResults.SelectedItem?.Result;
|
||||
if (result != null && SelectedIsFromQueryResults()) // SelectedItem returns null if selection is empty.
|
||||
{
|
||||
var autoCompleteText = result.Title;
|
||||
|
||||
if (!string.IsNullOrEmpty(result.AutoCompleteText))
|
||||
{
|
||||
autoCompleteText = result.AutoCompleteText;
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(SelectedResults.SelectedItem?.QuerySuggestionText))
|
||||
{
|
||||
autoCompleteText = SelectedResults.SelectedItem.QuerySuggestionText;
|
||||
}
|
||||
|
||||
var specialKeyState = GlobalHotkey.CheckModifiers();
|
||||
if (specialKeyState.ShiftPressed)
|
||||
{
|
||||
autoCompleteText = result.SubTitle;
|
||||
}
|
||||
|
||||
ChangeQueryText(autoCompleteText);
|
||||
}
|
||||
});
|
||||
|
||||
BackspaceCommand = new RelayCommand(index =>
|
||||
{
|
||||
var query = QueryBuilder.Build(QueryText.Trim(), PluginManager.NonGlobalPlugins);
|
||||
|
||||
// GetPreviousExistingDirectory does not require trailing '\', otherwise will return empty string
|
||||
var path = FilesFolders.GetPreviousExistingDirectory((_) => true, query.Search.TrimEnd('\\'));
|
||||
|
||||
var actionKeyword = string.IsNullOrEmpty(query.ActionKeyword) ? string.Empty : $"{query.ActionKeyword} ";
|
||||
|
||||
ChangeQueryText($"{actionKeyword}{path}");
|
||||
});
|
||||
|
||||
LoadContextMenuCommand = new RelayCommand(_ =>
|
||||
{
|
||||
if (SelectedIsFromQueryResults())
|
||||
{
|
||||
// When switch to ContextMenu from QueryResults, but no item being chosen, should do nothing
|
||||
// i.e. Shift+Enter/Ctrl+O right after Alt + Space should do nothing
|
||||
if (SelectedResults.SelectedItem != null)
|
||||
SelectedResults = ContextMenu;
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectedResults = Results;
|
||||
}
|
||||
});
|
||||
|
||||
LoadHistoryCommand = new RelayCommand(_ =>
|
||||
{
|
||||
if (SelectedIsFromQueryResults())
|
||||
{
|
||||
SelectedResults = History;
|
||||
History.SelectedIndex = _history.Items.Count - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectedResults = Results;
|
||||
}
|
||||
});
|
||||
|
||||
ReloadPluginDataCommand = new RelayCommand(_ =>
|
||||
if (hideWindow)
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
|
||||
_ = PluginManager
|
||||
.ReloadDataAsync()
|
||||
.ContinueWith(_ =>
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
Notification.Show(
|
||||
InternationalizationManager.Instance.GetTranslation("success"),
|
||||
InternationalizationManager.Instance.GetTranslation("completedSuccessfully")
|
||||
);
|
||||
}), TaskScheduler.Default)
|
||||
.ConfigureAwait(false);
|
||||
});
|
||||
if (SelectedIsFromQueryResults())
|
||||
{
|
||||
_userSelectedRecord.Add(result);
|
||||
_history.Add(result.OriginQuery.RawQuery);
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectedResults = Results;
|
||||
}
|
||||
}
|
||||
[RelayCommand]
|
||||
private void OpenSetting()
|
||||
{
|
||||
App.API.OpenSettingDialog();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void SelectHelp()
|
||||
{
|
||||
PluginManager.API.OpenUrl("https://www.flowlauncher.com/docs/#/usage-tips");
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void SelectFirstResult()
|
||||
{
|
||||
SelectedResults.SelectFirstResult();
|
||||
}
|
||||
[RelayCommand]
|
||||
private void SelectPrevPage()
|
||||
{
|
||||
SelectedResults.SelectPrevPage();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void SelectNextPage()
|
||||
{
|
||||
SelectedResults.SelectNextPage();
|
||||
}
|
||||
[RelayCommand]
|
||||
private void SelectPrevItem()
|
||||
{
|
||||
SelectedResults.SelectPrevResult();
|
||||
}
|
||||
[RelayCommand]
|
||||
private void SelectNextItem()
|
||||
{
|
||||
SelectedResults.SelectNextResult();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void Esc()
|
||||
{
|
||||
if (!SelectedIsFromQueryResults())
|
||||
{
|
||||
SelectedResults = Results;
|
||||
}
|
||||
else
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
@ -328,9 +332,10 @@ namespace Flow.Launcher.ViewModel
|
|||
#region ViewModel Properties
|
||||
|
||||
public Settings Settings { get; }
|
||||
public object ClockText { get; private set; }
|
||||
public string ClockText { get; private set; }
|
||||
public string DateText { get; private set; }
|
||||
|
||||
public CultureInfo cultureInfo => new CultureInfo(Settings.Language);
|
||||
private async Task RegisterClockAndDateUpdateAsync()
|
||||
{
|
||||
var timer = new PeriodicTimer(TimeSpan.FromSeconds(1));
|
||||
|
|
@ -338,9 +343,9 @@ namespace Flow.Launcher.ViewModel
|
|||
while (await timer.WaitForNextTickAsync().ConfigureAwait(false))
|
||||
{
|
||||
if (Settings.UseClock)
|
||||
ClockText = DateTime.Now.ToString(Settings.TimeFormat);
|
||||
ClockText = DateTime.Now.ToString(Settings.TimeFormat, cultureInfo);
|
||||
if (Settings.UseDate)
|
||||
DateText = DateTime.Now.ToString(Settings.DateFormat);
|
||||
DateText = DateTime.Now.ToString(Settings.DateFormat, cultureInfo);
|
||||
}
|
||||
}
|
||||
public ResultsViewModel Results { get; private set; }
|
||||
|
|
@ -416,6 +421,7 @@ namespace Flow.Launcher.ViewModel
|
|||
/// but we don't want to move cursor to end when query is updated from TextBox
|
||||
/// </summary>
|
||||
/// <param name="queryText"></param>
|
||||
/// <param name="reQuery">Force query even when Query Text doesn't change</param>
|
||||
public void ChangeQueryText(string queryText, bool reQuery = false)
|
||||
{
|
||||
if (QueryText != queryText)
|
||||
|
|
@ -494,25 +500,6 @@ namespace Flow.Launcher.ViewModel
|
|||
|
||||
public string PluginIconPath { get; set; } = null;
|
||||
|
||||
public ICommand EscCommand { get; set; }
|
||||
public ICommand BackspaceCommand { get; set; }
|
||||
public ICommand SelectNextItemCommand { get; set; }
|
||||
public ICommand SelectPrevItemCommand { get; set; }
|
||||
public ICommand SelectNextPageCommand { get; set; }
|
||||
public ICommand SelectPrevPageCommand { get; set; }
|
||||
public ICommand SelectFirstResultCommand { get; set; }
|
||||
public ICommand StartHelpCommand { get; set; }
|
||||
public ICommand LoadContextMenuCommand { get; set; }
|
||||
public ICommand LoadHistoryCommand { get; set; }
|
||||
public ICommand OpenResultCommand { get; set; }
|
||||
public ICommand OpenSettingCommand { get; set; }
|
||||
public ICommand ReloadPluginDataCommand { get; set; }
|
||||
public ICommand ClearQueryCommand { get; private set; }
|
||||
|
||||
public ICommand CopyToClipboard { get; set; }
|
||||
|
||||
public ICommand AutocompleteQueryCommand { get; set; }
|
||||
|
||||
public string OpenResultCommandModifiers { get; private set; }
|
||||
|
||||
public string Image => Constant.QueryTextBoxIconImagePath;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ using Flow.Launcher.Plugin;
|
|||
using Flow.Launcher.Plugin.SharedModels;
|
||||
using System.Collections.ObjectModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Flow.Launcher.ViewModel
|
||||
{
|
||||
|
|
@ -46,6 +47,18 @@ namespace Flow.Launcher.ViewModel
|
|||
case nameof(Settings.WindowSize):
|
||||
OnPropertyChanged(nameof(WindowWidthSize));
|
||||
break;
|
||||
case nameof(Settings.UseDate):
|
||||
case nameof(Settings.DateFormat):
|
||||
OnPropertyChanged(nameof(DateText));
|
||||
break;
|
||||
case nameof(Settings.UseClock):
|
||||
case nameof(Settings.TimeFormat):
|
||||
OnPropertyChanged(nameof(ClockText));
|
||||
break;
|
||||
case nameof(Settings.Language):
|
||||
OnPropertyChanged(nameof(ClockText));
|
||||
OnPropertyChanged(nameof(DateText));
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -56,7 +69,7 @@ namespace Flow.Launcher.ViewModel
|
|||
{
|
||||
await _updater.UpdateAppAsync(App.API, false);
|
||||
}
|
||||
|
||||
|
||||
public bool AutoUpdates
|
||||
{
|
||||
get => Settings.AutoUpdates;
|
||||
|
|
@ -71,6 +84,8 @@ namespace Flow.Launcher.ViewModel
|
|||
}
|
||||
}
|
||||
|
||||
public CultureInfo cultureInfo => new CultureInfo(Settings.Language);
|
||||
|
||||
public bool StartFlowLauncherOnSystemStartup
|
||||
{
|
||||
get => Settings.StartFlowLauncherOnSystemStartup;
|
||||
|
|
@ -157,7 +172,10 @@ namespace Flow.Launcher.ViewModel
|
|||
{
|
||||
var key = $"LastQuery{e}";
|
||||
var display = _translater.GetTranslation(key);
|
||||
var m = new LastQueryMode { Display = display, Value = e, };
|
||||
var m = new LastQueryMode
|
||||
{
|
||||
Display = display, Value = e,
|
||||
};
|
||||
modes.Add(m);
|
||||
}
|
||||
return modes;
|
||||
|
|
@ -302,11 +320,11 @@ namespace Flow.Launcher.ViewModel
|
|||
}
|
||||
}
|
||||
|
||||
private IList<PluginStoreItemViewModel> LabelMaker(IList<UserPlugin> list)
|
||||
private IList<PluginStoreItemViewModel> LabelMaker(IList<UserPlugin> list)
|
||||
{
|
||||
return list.Select(p=>new PluginStoreItemViewModel(p))
|
||||
return list.Select(p => new PluginStoreItemViewModel(p))
|
||||
.OrderByDescending(p => p.Category == PluginStoreItemViewModel.NewRelease)
|
||||
.ThenByDescending(p=>p.Category == PluginStoreItemViewModel.RecentlyUpdated)
|
||||
.ThenByDescending(p => p.Category == PluginStoreItemViewModel.RecentlyUpdated)
|
||||
.ThenByDescending(p => p.Category == PluginStoreItemViewModel.None)
|
||||
.ThenByDescending(p => p.Category == PluginStoreItemViewModel.Installed)
|
||||
.ToList();
|
||||
|
|
@ -340,15 +358,14 @@ namespace Flow.Launcher.ViewModel
|
|||
|
||||
internal void DisplayPluginQuery(string queryToDisplay, PluginPair plugin, int actionKeywordPosition = 0)
|
||||
{
|
||||
var actionKeyword = plugin.Metadata.ActionKeywords.Count == 0
|
||||
? string.Empty
|
||||
var actionKeyword = plugin.Metadata.ActionKeywords.Count == 0
|
||||
? string.Empty
|
||||
: plugin.Metadata.ActionKeywords[actionKeywordPosition];
|
||||
|
||||
|
||||
App.API.ChangeQuery($"{actionKeyword} {queryToDisplay}");
|
||||
App.API.ShowMainWindow();
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region theme
|
||||
|
|
@ -413,8 +430,7 @@ namespace Flow.Launcher.ViewModel
|
|||
var display = _translater.GetTranslation(key);
|
||||
var m = new ColorScheme
|
||||
{
|
||||
Display = display,
|
||||
Value = e,
|
||||
Display = display, Value = e,
|
||||
};
|
||||
modes.Add(m);
|
||||
}
|
||||
|
|
@ -422,8 +438,6 @@ namespace Flow.Launcher.ViewModel
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class SearchWindowPosition
|
||||
{
|
||||
public string Display { get; set; }
|
||||
|
|
@ -440,32 +454,63 @@ namespace Flow.Launcher.ViewModel
|
|||
{
|
||||
var key = $"SearchWindowPosition{e}";
|
||||
var display = _translater.GetTranslation(key);
|
||||
var m = new SearchWindowPosition { Display = display, Value = e, };
|
||||
var m = new SearchWindowPosition
|
||||
{
|
||||
Display = display, Value = e,
|
||||
};
|
||||
modes.Add(m);
|
||||
}
|
||||
return modes;
|
||||
}
|
||||
}
|
||||
|
||||
public List<string> TimeFormatList { get; set; } = new List<string>()
|
||||
public List<string> TimeFormatList { get; } = new()
|
||||
{
|
||||
"h:mm",
|
||||
"hh:mm",
|
||||
"H:mm",
|
||||
"HH:mm",
|
||||
"tt h:mm",
|
||||
"tt hh:mm",
|
||||
"h:mm tt",
|
||||
"hh:mm tt"
|
||||
};
|
||||
|
||||
public List<string> DateFormatList { get; set; } = new List<string>()
|
||||
public List<string> DateFormatList { get; } = new()
|
||||
{
|
||||
"MM'/'dd dddd",
|
||||
"MM'/'dd ddd",
|
||||
"MM'/'dd",
|
||||
"MM'-'dd",
|
||||
"MMMM', 'dd",
|
||||
"dd'/'MM",
|
||||
"dd'-'MM",
|
||||
"ddd MM'/'dd",
|
||||
"dddd MM'/'dd",
|
||||
"dddd"
|
||||
"dddd",
|
||||
"ddd dd'/'MM",
|
||||
"dddd dd'/'MM",
|
||||
"dddd dd', 'MMMM",
|
||||
"dd', 'MMMM"
|
||||
};
|
||||
|
||||
public string TimeFormat
|
||||
{
|
||||
get { return Settings.TimeFormat; }
|
||||
set { Settings.TimeFormat = value; }
|
||||
}
|
||||
|
||||
public string DateFormat
|
||||
{
|
||||
get { return Settings.DateFormat; }
|
||||
set { Settings.DateFormat = value; }
|
||||
}
|
||||
|
||||
public string ClockText => DateTime.Now.ToString(TimeFormat, cultureInfo);
|
||||
|
||||
public string DateText => DateTime.Now.ToString(DateFormat, cultureInfo);
|
||||
|
||||
|
||||
public double WindowWidthSize
|
||||
{
|
||||
get => Settings.WindowSize;
|
||||
|
|
@ -707,7 +752,7 @@ namespace Flow.Launcher.ViewModel
|
|||
|
||||
string deleteWarning = string.Format(
|
||||
InternationalizationManager.Instance.GetTranslation("deleteCustomShortcutWarning"),
|
||||
item?.Key, item?.Value);
|
||||
item.Key, item.Value);
|
||||
if (MessageBox.Show(deleteWarning, InternationalizationManager.Instance.GetTranslation("delete"),
|
||||
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
|
||||
{
|
||||
|
|
@ -773,34 +818,37 @@ namespace Flow.Launcher.ViewModel
|
|||
}
|
||||
}
|
||||
public string ActivatedTimes => string.Format(_translater.GetTranslation("about_activate_times"), Settings.ActivateTimes);
|
||||
|
||||
|
||||
public string CheckLogFolder
|
||||
{
|
||||
get
|
||||
get
|
||||
{
|
||||
var dirInfo = new DirectoryInfo(Path.Combine(DataLocation.DataDirectory(), Constant.Logs, Constant.Version));
|
||||
long size = dirInfo.EnumerateFiles("*", SearchOption.AllDirectories).Sum(file => file.Length);
|
||||
|
||||
return _translater.GetTranslation("clearlogfolder") + " (" + FormatBytes(size) + ")" ;
|
||||
|
||||
return _translater.GetTranslation("clearlogfolder") + " (" + FormatBytes(size) + ")";
|
||||
}
|
||||
}
|
||||
|
||||
internal void ClearLogFolder()
|
||||
{
|
||||
var directory = new DirectoryInfo(
|
||||
Path.Combine(
|
||||
DataLocation.DataDirectory(),
|
||||
Constant.Logs,
|
||||
Constant.Version));
|
||||
Path.Combine(
|
||||
DataLocation.DataDirectory(),
|
||||
Constant.Logs,
|
||||
Constant.Version));
|
||||
|
||||
directory.EnumerateFiles()
|
||||
.ToList()
|
||||
.ForEach(x => x.Delete());
|
||||
.ToList()
|
||||
.ForEach(x => x.Delete());
|
||||
}
|
||||
internal string FormatBytes(long bytes)
|
||||
{
|
||||
const int scale = 1024;
|
||||
string[] orders = new string[] { "GB", "MB", "KB", "Bytes" };
|
||||
string[] orders = new string[]
|
||||
{
|
||||
"GB", "MB", "KB", "Bytes"
|
||||
};
|
||||
long max = (long)Math.Pow(scale, orders.Length - 1);
|
||||
|
||||
foreach (string order in orders)
|
||||
|
|
@ -812,6 +860,7 @@ namespace Flow.Launcher.ViewModel
|
|||
}
|
||||
return "0 Bytes";
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,8 +97,8 @@ namespace Flow.Launcher.Plugin.Program.Programs
|
|||
}
|
||||
|
||||
// To initialize the app description
|
||||
public String description = String.Empty;
|
||||
|
||||
public string description = string.Empty;
|
||||
public string arguments = string.Empty;
|
||||
|
||||
// Retrieve the target path using Shell Link
|
||||
public string retrieveTargetPath(string path)
|
||||
|
|
@ -122,13 +122,16 @@ namespace Flow.Launcher.Plugin.Program.Programs
|
|||
buffer = new StringBuilder(MAX_PATH);
|
||||
((IShellLinkW)link).GetDescription(buffer, MAX_PATH);
|
||||
description = buffer.ToString();
|
||||
|
||||
buffer.Clear();
|
||||
((IShellLinkW)link).GetArguments(buffer, MAX_PATH);
|
||||
arguments = buffer.ToString();
|
||||
}
|
||||
|
||||
// To release unmanaged memory
|
||||
Marshal.ReleaseComObject(link);
|
||||
|
||||
return target;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,11 +26,11 @@ namespace Flow.Launcher.Plugin.Program.Programs
|
|||
public string UniqueIdentifier { get => _uid; set => _uid = value == null ? string.Empty : value.ToLowerInvariant(); } // For path comparison
|
||||
public string IcoPath { get; set; }
|
||||
/// <summary>
|
||||
/// Path of the file. It's the path of .lnk or .url for .lnk and .url.
|
||||
/// Path of the file. It's the path of .lnk and .url for .lnk and .url files.
|
||||
/// </summary>
|
||||
public string FullPath { get; set; }
|
||||
/// <summary>
|
||||
/// Path of the excutable for .lnk, or the URL for .url.
|
||||
/// Path of the excutable for .lnk, or the URL for .url. Arguments are included if any.
|
||||
/// </summary>
|
||||
public string LnkResolvedPath { get; set; }
|
||||
/// <summary>
|
||||
|
|
@ -185,7 +185,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
|
|||
{
|
||||
var info = new ProcessStartInfo
|
||||
{
|
||||
FileName = ExecutablePath,
|
||||
FileName = FullPath,
|
||||
WorkingDirectory = ParentDirectory,
|
||||
Verb = "runas",
|
||||
UseShellExecute = true
|
||||
|
|
@ -275,6 +275,12 @@ namespace Flow.Launcher.Plugin.Program.Programs
|
|||
program.LnkResolvedPath = Path.GetFullPath(target);
|
||||
program.ExecutableName = Path.GetFileName(target);
|
||||
|
||||
var args = _helper.arguments;
|
||||
if(!string.IsNullOrEmpty(args))
|
||||
{
|
||||
program.LnkResolvedPath += " " + args;
|
||||
}
|
||||
|
||||
var description = _helper.description;
|
||||
if (!string.IsNullOrEmpty(description))
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue