mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Merge pull request #3586 from 01Dri/rename-quick-access-links
Enhancement: Rename Quick Access Links
This commit is contained in:
commit
b8afbd7332
10 changed files with 473 additions and 101 deletions
|
|
@ -75,7 +75,9 @@ namespace Flow.Launcher.Plugin.Explorer
|
|||
{
|
||||
Settings.QuickAccessLinks.Add(new AccessLink
|
||||
{
|
||||
Path = record.FullPath, Type = record.Type
|
||||
Name = record.FullPath.GetPathName(),
|
||||
Path = record.FullPath,
|
||||
Type = record.Type
|
||||
});
|
||||
|
||||
Context.API.ShowMsg(Context.API.GetTranslation("plugin_explorer_addfilefoldersuccess"),
|
||||
|
|
|
|||
21
Plugins/Flow.Launcher.Plugin.Explorer/Helper/PathHelper.cs
Normal file
21
Plugins/Flow.Launcher.Plugin.Explorer/Helper/PathHelper.cs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Flow.Launcher.Plugin.Explorer.Search;
|
||||
|
||||
namespace Flow.Launcher.Plugin.Explorer.Helper;
|
||||
|
||||
public static class PathHelper
|
||||
{
|
||||
public static string GetPathName(this string selectedPath)
|
||||
{
|
||||
if (string.IsNullOrEmpty(selectedPath)) return string.Empty;
|
||||
var path = selectedPath.EndsWith(Constants.DirectorySeparator) ? selectedPath[0..^1] : selectedPath;
|
||||
|
||||
if (path.EndsWith(':'))
|
||||
return path[0..^1] + " Drive";
|
||||
|
||||
return path.Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.None)
|
||||
.Last();
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
<!-- Dialogues -->
|
||||
<system:String x:Key="plugin_explorer_make_selection_warning">Please make a selection first</system:String>
|
||||
<system:String x:Key="plugin_explorer_quick_access_link_no_folder_selected">Please select a folder path.</system:String>
|
||||
<system:String x:Key="plugin_explorer_quick_access_link_path_already_exists">Please choose a different name or folder path.</system:String>
|
||||
<system:String x:Key="plugin_explorer_select_folder_link_warning">Please select a folder link</system:String>
|
||||
<system:String x:Key="plugin_explorer_delete_folder_link">Are you sure you want to delete {0}?</system:String>
|
||||
<system:String x:Key="plugin_explorer_deletefileconfirm">Are you sure you want to permanently delete this file?</system:String>
|
||||
|
|
@ -27,6 +29,7 @@
|
|||
<system:String x:Key="plugin_explorer_add">Add</system:String>
|
||||
<system:String x:Key="plugin_explorer_generalsetting_header">General Setting</system:String>
|
||||
<system:String x:Key="plugin_explorer_manageactionkeywords_header">Customise Action Keywords</system:String>
|
||||
<system:String x:Key="plugin_explorer_manage_quick_access_links_header">Customise Quick Access</system:String>
|
||||
<system:String x:Key="plugin_explorer_quickaccesslinks_header">Quick Access Links</system:String>
|
||||
<system:String x:Key="plugin_explorer_everything_setting_header">Everything Setting</system:String>
|
||||
<system:String x:Key="plugin_explorer_previewpanel_setting_header">Preview Panel</system:String>
|
||||
|
|
@ -92,6 +95,7 @@
|
|||
<system:String x:Key="plugin_explorer_deletefile_subtitle">Permanently delete current file</system:String>
|
||||
<system:String x:Key="plugin_explorer_deletefolder_subtitle">Permanently delete current folder</system:String>
|
||||
<system:String x:Key="plugin_explorer_path">Path:</system:String>
|
||||
<system:String x:Key="plugin_explorer_name">Name:</system:String>
|
||||
<system:String x:Key="plugin_explorer_deletefilefolder_subtitle">Delete the selected</system:String>
|
||||
<system:String x:Key="plugin_explorer_runasdifferentuser">Run as different user</system:String>
|
||||
<system:String x:Key="plugin_explorer_runasdifferentuser_subtitle">Run the selected using a different user account</system:String>
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ namespace Flow.Launcher.Plugin.Explorer
|
|||
Context = context;
|
||||
|
||||
Settings = context.API.LoadSettingJsonStorage<Settings>();
|
||||
FillQuickAccessLinkNames();
|
||||
|
||||
viewModel = new SettingsViewModel(context, Settings);
|
||||
|
||||
|
|
@ -95,5 +96,17 @@ namespace Flow.Launcher.Plugin.Explorer
|
|||
{
|
||||
return Context.API.GetTranslation("plugin_explorer_plugin_description");
|
||||
}
|
||||
|
||||
private void FillQuickAccessLinkNames()
|
||||
{
|
||||
// Legacy version does not have names for quick access links, so we fill them with the path name.
|
||||
foreach (var link in Settings.QuickAccessLinks)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(link.Name))
|
||||
{
|
||||
link.Name = link.Path.GetPathName();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,4 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks
|
||||
namespace Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks
|
||||
{
|
||||
public class AccessLink
|
||||
{
|
||||
|
|
@ -10,20 +6,6 @@ namespace Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks
|
|||
|
||||
public ResultType Type { get; set; } = ResultType.Folder;
|
||||
|
||||
[JsonIgnore]
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
var path = Path.EndsWith(Constants.DirectorySeparator) ? Path[0..^1] : Path;
|
||||
|
||||
if (path.EndsWith(':'))
|
||||
return path[0..^1] + " Drive";
|
||||
|
||||
return path.Split(new[] { System.IO.Path.DirectorySeparatorChar }, StringSplitOptions.None)
|
||||
.Last();
|
||||
}
|
||||
}
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ using System.Linq;
|
|||
using System.Windows;
|
||||
using System.Windows.Forms;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Flow.Launcher.Plugin.Explorer.Helper;
|
||||
using Flow.Launcher.Plugin.Explorer.Search;
|
||||
using Flow.Launcher.Plugin.Explorer.Search.Everything;
|
||||
using Flow.Launcher.Plugin.Explorer.Search.Everything.Exceptions;
|
||||
|
|
@ -328,14 +329,10 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
|
|||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void EditLink(object commandParameter)
|
||||
private void EditIndexSearchExcludePaths()
|
||||
{
|
||||
var (selectedLink, collection) = commandParameter switch
|
||||
{
|
||||
"QuickAccessLink" => (SelectedQuickAccessLink, Settings.QuickAccessLinks),
|
||||
"IndexSearchExcludedPaths" => (SelectedIndexSearchExcludedPath, Settings.IndexSearchExcludedSubdirectoryPaths),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(commandParameter))
|
||||
};
|
||||
var selectedLink = SelectedIndexSearchExcludedPath;
|
||||
var collection = Settings.IndexSearchExcludedSubdirectoryPaths;
|
||||
|
||||
if (selectedLink is null)
|
||||
{
|
||||
|
|
@ -354,28 +351,18 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
|
|||
collection.Remove(selectedLink);
|
||||
collection.Add(new AccessLink
|
||||
{
|
||||
Path = path, Type = selectedLink.Type,
|
||||
Path = path, Type = selectedLink.Type, Name = path.GetPathName()
|
||||
});
|
||||
}
|
||||
|
||||
private void ShowUnselectedMessage()
|
||||
{
|
||||
var warning = Context.API.GetTranslation("plugin_explorer_make_selection_warning");
|
||||
Context.API.ShowMsgBox(warning);
|
||||
Save();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void AddLink(object commandParameter)
|
||||
private void AddIndexSearchExcludePaths()
|
||||
{
|
||||
var container = commandParameter switch
|
||||
{
|
||||
"QuickAccessLink" => Settings.QuickAccessLinks,
|
||||
"IndexSearchExcludedPaths" => Settings.IndexSearchExcludedSubdirectoryPaths,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(commandParameter))
|
||||
};
|
||||
|
||||
ArgumentNullException.ThrowIfNull(container);
|
||||
var container = Settings.IndexSearchExcludedSubdirectoryPaths;
|
||||
|
||||
if (container is null) return;
|
||||
|
||||
var folderBrowserDialog = new FolderBrowserDialog();
|
||||
|
||||
if (folderBrowserDialog.ShowDialog() != DialogResult.OK)
|
||||
|
|
@ -383,16 +370,47 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
|
|||
|
||||
var newAccessLink = new AccessLink
|
||||
{
|
||||
Name = folderBrowserDialog.SelectedPath.GetPathName(),
|
||||
Path = folderBrowserDialog.SelectedPath
|
||||
};
|
||||
|
||||
container.Add(newAccessLink);
|
||||
Save();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void RemoveLink(object obj)
|
||||
private void EditQuickAccessLink()
|
||||
{
|
||||
if (obj is not string container) return;
|
||||
var selectedLink = SelectedQuickAccessLink;
|
||||
var collection = Settings.QuickAccessLinks;
|
||||
|
||||
if (selectedLink is null)
|
||||
{
|
||||
ShowUnselectedMessage();
|
||||
return;
|
||||
}
|
||||
|
||||
var quickAccessLinkSettings = new QuickAccessLinkSettings(collection, SelectedQuickAccessLink);
|
||||
if (quickAccessLinkSettings.ShowDialog() == true)
|
||||
{
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void AddQuickAccessLink()
|
||||
{
|
||||
var quickAccessLinkSettings = new QuickAccessLinkSettings(Settings.QuickAccessLinks);
|
||||
if (quickAccessLinkSettings.ShowDialog() == true)
|
||||
{
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void RemoveLink(object commandParameter)
|
||||
{
|
||||
if (commandParameter is not string container) return;
|
||||
|
||||
switch (container)
|
||||
{
|
||||
|
|
@ -407,10 +425,16 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
|
|||
}
|
||||
Save();
|
||||
}
|
||||
|
||||
private void ShowUnselectedMessage()
|
||||
{
|
||||
var warning = Context.API.GetTranslation("plugin_explorer_make_selection_warning");
|
||||
Context.API.ShowMsgBox(warning);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private string? PromptUserSelectPath(ResultType type, string? initialDirectory = null)
|
||||
private static string? PromptUserSelectPath(ResultType type, string? initialDirectory = null)
|
||||
{
|
||||
string? path = null;
|
||||
|
||||
|
|
|
|||
|
|
@ -92,41 +92,43 @@
|
|||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Expander">
|
||||
<Border
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
SnapsToDevicePixels="true">
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
SnapsToDevicePixels="true">
|
||||
<DockPanel>
|
||||
<ToggleButton
|
||||
x:Name="HeaderSite"
|
||||
MinWidth="0"
|
||||
MinHeight="0"
|
||||
Margin="0"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
Content="{TemplateBinding Header}"
|
||||
ContentTemplate="{TemplateBinding HeaderTemplate}"
|
||||
ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}"
|
||||
DockPanel.Dock="Top"
|
||||
FocusVisualStyle="{StaticResource ExpanderHeaderFocusVisual}"
|
||||
FontFamily="{TemplateBinding FontFamily}"
|
||||
FontSize="{TemplateBinding FontSize}"
|
||||
FontStretch="{TemplateBinding FontStretch}"
|
||||
FontStyle="{TemplateBinding FontStyle}"
|
||||
FontWeight="{TemplateBinding FontWeight}"
|
||||
Foreground="{TemplateBinding Foreground}"
|
||||
IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
Style="{StaticResource ExpanderHeaderRightArrowStyle}" />
|
||||
<Border x:Name="ContentPresenterBorder" BorderThickness="0,1,0,0"
|
||||
BorderBrush="{DynamicResource Color03B}">
|
||||
x:Name="HeaderSite"
|
||||
MinWidth="0"
|
||||
MinHeight="0"
|
||||
Margin="0"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
Content="{TemplateBinding Header}"
|
||||
ContentTemplate="{TemplateBinding HeaderTemplate}"
|
||||
ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}"
|
||||
DockPanel.Dock="Top"
|
||||
FocusVisualStyle="{StaticResource ExpanderHeaderFocusVisual}"
|
||||
FontFamily="{TemplateBinding FontFamily}"
|
||||
FontSize="{TemplateBinding FontSize}"
|
||||
FontStretch="{TemplateBinding FontStretch}"
|
||||
FontStyle="{TemplateBinding FontStyle}"
|
||||
FontWeight="{TemplateBinding FontWeight}"
|
||||
Foreground="{TemplateBinding Foreground}"
|
||||
IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
Style="{StaticResource ExpanderHeaderRightArrowStyle}" />
|
||||
<Border
|
||||
x:Name="ContentPresenterBorder"
|
||||
BorderBrush="{DynamicResource Color03B}"
|
||||
BorderThickness="0 1 0 0">
|
||||
<ContentPresenter
|
||||
x:Name="ExpandSite"
|
||||
Margin="{TemplateBinding Padding}"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
DockPanel.Dock="Bottom"
|
||||
Focusable="false" />
|
||||
x:Name="ExpandSite"
|
||||
Margin="{TemplateBinding Padding}"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
DockPanel.Dock="Bottom"
|
||||
Focusable="false" />
|
||||
<Border.LayoutTransform>
|
||||
<ScaleTransform ScaleY="0" />
|
||||
</Border.LayoutTransform>
|
||||
|
|
@ -141,13 +143,17 @@
|
|||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="ContentPresenterBorder"
|
||||
Storyboard.TargetProperty="(Border.LayoutTransform).(ScaleTransform.ScaleY)"
|
||||
From="0.0" To="1.0" Duration="0:0:0" />
|
||||
Storyboard.TargetName="ContentPresenterBorder"
|
||||
Storyboard.TargetProperty="(Border.LayoutTransform).(ScaleTransform.ScaleY)"
|
||||
From="0.0"
|
||||
To="1.0"
|
||||
Duration="0:0:0" />
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="ContentPresenterBorder"
|
||||
Storyboard.TargetProperty="(Border.Opacity)"
|
||||
From="0.0" To="1.0" Duration="0:0:0" />
|
||||
Storyboard.TargetName="ContentPresenterBorder"
|
||||
Storyboard.TargetProperty="(Border.Opacity)"
|
||||
From="0.0"
|
||||
To="1.0"
|
||||
Duration="0:0:0" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.EnterActions>
|
||||
|
|
@ -155,13 +161,17 @@
|
|||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="ContentPresenterBorder"
|
||||
Storyboard.TargetProperty="(Border.LayoutTransform).(ScaleTransform.ScaleY)"
|
||||
From="1.0" To="0.0" Duration="0:0:0" />
|
||||
Storyboard.TargetName="ContentPresenterBorder"
|
||||
Storyboard.TargetProperty="(Border.LayoutTransform).(ScaleTransform.ScaleY)"
|
||||
From="1.0"
|
||||
To="0.0"
|
||||
Duration="0:0:0" />
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="ContentPresenterBorder"
|
||||
Storyboard.TargetProperty="(Border.Opacity)"
|
||||
From="1.0" To="0.0" Duration="0:0:0" />
|
||||
Storyboard.TargetName="ContentPresenterBorder"
|
||||
Storyboard.TargetProperty="(Border.Opacity)"
|
||||
From="1.0"
|
||||
To="0.0"
|
||||
Duration="0:0:0" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.ExitActions>
|
||||
|
|
@ -734,10 +744,29 @@
|
|||
BorderThickness="1"
|
||||
DragEnter="lbxAccessLinks_DragEnter"
|
||||
Drop="LbxAccessLinks_OnDrop"
|
||||
ItemTemplate="{StaticResource ListViewTemplateAccessLinks}"
|
||||
ItemsSource="{Binding Settings.QuickAccessLinks}"
|
||||
Loaded="lbxAccessLinks_Loaded"
|
||||
SelectedItem="{Binding SelectedQuickAccessLink}" />
|
||||
SelectedItem="{Binding SelectedQuickAccessLink}"
|
||||
SizeChanged="lbxAccessLinks_SizeChanged">
|
||||
<ListView.View>
|
||||
<GridView>
|
||||
<GridViewColumn Width="600" Header="{DynamicResource plugin_explorer_name}">
|
||||
<GridViewColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Name}" />
|
||||
</DataTemplate>
|
||||
</GridViewColumn.CellTemplate>
|
||||
</GridViewColumn>
|
||||
<GridViewColumn Width="900" Header="{DynamicResource plugin_explorer_path}">
|
||||
<GridViewColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Path}" TextTrimming="CharacterEllipsis" />
|
||||
</DataTemplate>
|
||||
</GridViewColumn.CellTemplate>
|
||||
</GridViewColumn>
|
||||
</GridView>
|
||||
</ListView.View>
|
||||
</ListView>
|
||||
</Border>
|
||||
|
||||
<StackPanel
|
||||
|
|
@ -755,14 +784,12 @@
|
|||
<Button
|
||||
MinWidth="100"
|
||||
Margin="{StaticResource SettingPanelItemLeftMargin}"
|
||||
Command="{Binding EditLinkCommand}"
|
||||
CommandParameter="QuickAccessLink"
|
||||
Command="{Binding EditQuickAccessLinkCommand}"
|
||||
Content="{DynamicResource plugin_explorer_edit}" />
|
||||
<Button
|
||||
MinWidth="100"
|
||||
Margin="{StaticResource SettingPanelItemLeftMargin}"
|
||||
Command="{Binding AddLinkCommand}"
|
||||
CommandParameter="QuickAccessLink"
|
||||
Command="{Binding AddQuickAccessLinkCommand}"
|
||||
Content="{DynamicResource plugin_explorer_add}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
|
@ -822,14 +849,12 @@
|
|||
<Button
|
||||
MinWidth="100"
|
||||
Margin="{StaticResource SettingPanelItemLeftMargin}"
|
||||
Command="{Binding EditLinkCommand}"
|
||||
CommandParameter="IndexSearchExcludedPaths"
|
||||
Command="{Binding EditIndexSearchExcludePathsCommand}"
|
||||
Content="{DynamicResource plugin_explorer_edit}" />
|
||||
<Button
|
||||
MinWidth="100"
|
||||
Margin="{StaticResource SettingPanelItemLeftMargin}"
|
||||
Command="{Binding AddLinkCommand}"
|
||||
CommandParameter="IndexSearchExcludedPaths"
|
||||
Command="{Binding AddIndexSearchExcludePathsCommand}"
|
||||
Content="{DynamicResource plugin_explorer_add}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
|
|
|||
|
|
@ -125,5 +125,22 @@ namespace Flow.Launcher.Plugin.Explorer.Views
|
|||
{
|
||||
lbxExcludedPaths.Items.SortDescriptions.Add(new SortDescription("Path", ListSortDirection.Ascending));
|
||||
}
|
||||
|
||||
private void lbxAccessLinks_SizeChanged(object sender, SizeChangedEventArgs e)
|
||||
{
|
||||
if (sender is not ListView listView) return;
|
||||
if (listView.View is not GridView gView) return;
|
||||
|
||||
var workingWidth =
|
||||
listView.ActualWidth - SystemParameters.VerticalScrollBarWidth; // take into account vertical scrollbar
|
||||
|
||||
if (workingWidth <= 0) return;
|
||||
|
||||
var col1 = 0.4;
|
||||
var col2 = 0.6;
|
||||
|
||||
gView.Columns[0].Width = workingWidth * col1;
|
||||
gView.Columns[1].Width = workingWidth * col2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,137 @@
|
|||
<Window x:Class="Flow.Launcher.Plugin.Explorer.Views.QuickAccessLinkSettings"
|
||||
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.Plugin.Explorer.Views"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
Title="{DynamicResource plugin_explorer_manage_quick_access_links_header}"
|
||||
Width="Auto"
|
||||
Height="255"
|
||||
Background="{DynamicResource PopuBGColor}"
|
||||
DataContext="{Binding RelativeSource={RelativeSource Self}}"
|
||||
Foreground="{DynamicResource PopupTextColor}"
|
||||
ResizeMode="NoResize"
|
||||
SizeToContent="Width"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
mc:Ignorable="d">
|
||||
<WindowChrome.WindowChrome>
|
||||
<WindowChrome CaptionHeight="32" ResizeBorderThickness="{x:Static SystemParameters.WindowResizeBorderThickness}" />
|
||||
</WindowChrome.WindowChrome>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="80" />
|
||||
</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="BtnCancel_OnClick"
|
||||
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 Margin="26 0 26 0">
|
||||
<StackPanel Margin="0 0 0 12">
|
||||
<TextBlock
|
||||
Margin="0 0 0 0"
|
||||
FontSize="20"
|
||||
FontWeight="SemiBold"
|
||||
Text="{DynamicResource plugin_explorer_manage_quick_access_links_header}"
|
||||
TextAlignment="Left" />
|
||||
</StackPanel>
|
||||
<StackPanel Margin="0 10 0 0" Orientation="Horizontal">
|
||||
<TextBlock
|
||||
MinWidth="150"
|
||||
Margin="0 10 15 10"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="14"
|
||||
Text="{DynamicResource plugin_explorer_name}" />
|
||||
<TextBox
|
||||
Margin="10 0 0 0"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="12"
|
||||
Width="250"
|
||||
Text="{Binding SelectedName, Mode=TwoWay}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Margin="0 10 0 0" Orientation="Horizontal">
|
||||
<TextBlock
|
||||
MinWidth="150"
|
||||
Margin="0 10 15 10"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="14"
|
||||
Text="{DynamicResource plugin_explorer_path}" />
|
||||
|
||||
|
||||
<TextBox
|
||||
Margin="10 0 0 0"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="12"
|
||||
Width="250"
|
||||
Text="{Binding SelectedPath, Mode=TwoWay}"
|
||||
IsReadOnly="True" />
|
||||
<Button
|
||||
Width="80"
|
||||
Height="Auto"
|
||||
Margin="10 0 0 0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Content="{DynamicResource select}"
|
||||
Click="SelectPath_OnClick" />
|
||||
</StackPanel>
|
||||
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
<Border
|
||||
Grid.Row="1"
|
||||
Background="{DynamicResource PopupButtonAreaBGColor}"
|
||||
BorderBrush="{DynamicResource PopupButtonAreaBorderColor}"
|
||||
BorderThickness="0 1 0 0">
|
||||
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
|
||||
<Button
|
||||
x:Name="btnCancel"
|
||||
Width="145"
|
||||
Height="30"
|
||||
Margin="0 0 5 0"
|
||||
Click="BtnCancel_OnClick"
|
||||
Content="{DynamicResource cancel}" />
|
||||
<Button
|
||||
Name="DownButton"
|
||||
Width="145"
|
||||
Height="30"
|
||||
Margin="5 0 0 0"
|
||||
Click="OnDoneButtonClick"
|
||||
Style="{StaticResource AccentButtonStyle}">
|
||||
<TextBlock x:Name="lblAdd" Text="{DynamicResource done}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Forms;
|
||||
using Flow.Launcher.Plugin.Explorer.Helper;
|
||||
using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks;
|
||||
|
||||
namespace Flow.Launcher.Plugin.Explorer.Views;
|
||||
|
||||
public partial class QuickAccessLinkSettings : INotifyPropertyChanged
|
||||
{
|
||||
private string _selectedPath;
|
||||
public string SelectedPath
|
||||
{
|
||||
get => _selectedPath;
|
||||
set
|
||||
{
|
||||
if (_selectedPath != value)
|
||||
{
|
||||
_selectedPath = value;
|
||||
OnPropertyChanged();
|
||||
if (string.IsNullOrEmpty(_selectedName))
|
||||
{
|
||||
SelectedName = _selectedPath.GetPathName();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string _selectedName;
|
||||
public string SelectedName
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.IsNullOrEmpty(_selectedName) ? _selectedPath.GetPathName() : _selectedName;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_selectedName != value)
|
||||
{
|
||||
_selectedName = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsEdit { get; }
|
||||
private AccessLink SelectedAccessLink { get; }
|
||||
|
||||
public ObservableCollection<AccessLink> QuickAccessLinks { get; }
|
||||
|
||||
public QuickAccessLinkSettings(ObservableCollection<AccessLink> quickAccessLinks)
|
||||
{
|
||||
IsEdit = false;
|
||||
QuickAccessLinks = quickAccessLinks;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public QuickAccessLinkSettings(ObservableCollection<AccessLink> quickAccessLinks, AccessLink selectedAccessLink)
|
||||
{
|
||||
IsEdit = true;
|
||||
_selectedName = selectedAccessLink.Name;
|
||||
_selectedPath = selectedAccessLink.Path;
|
||||
SelectedAccessLink = selectedAccessLink;
|
||||
QuickAccessLinks = quickAccessLinks;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DialogResult = false;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void OnDoneButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Validate the input before proceeding
|
||||
if (string.IsNullOrEmpty(SelectedName) || string.IsNullOrEmpty(SelectedPath))
|
||||
{
|
||||
var warning = Main.Context.API.GetTranslation("plugin_explorer_quick_access_link_no_folder_selected");
|
||||
Main.Context.API.ShowMsgBox(warning);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the path already exists in the quick access links
|
||||
if (QuickAccessLinks.Any(x =>
|
||||
x.Path.Equals(SelectedPath, StringComparison.OrdinalIgnoreCase) &&
|
||||
x.Name.Equals(SelectedName, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
var warning = Main.Context.API.GetTranslation("plugin_explorer_quick_access_link_path_already_exists");
|
||||
Main.Context.API.ShowMsgBox(warning);
|
||||
return;
|
||||
}
|
||||
|
||||
// If editing, update the existing link
|
||||
if (IsEdit)
|
||||
{
|
||||
if (SelectedAccessLink == null) return;
|
||||
|
||||
var index = QuickAccessLinks.IndexOf(SelectedAccessLink);
|
||||
if (index >= 0)
|
||||
{
|
||||
var updatedLink = new AccessLink
|
||||
{
|
||||
Name = SelectedName,
|
||||
Type = SelectedAccessLink.Type,
|
||||
Path = SelectedPath
|
||||
};
|
||||
QuickAccessLinks[index] = updatedLink;
|
||||
}
|
||||
DialogResult = true;
|
||||
Close();
|
||||
}
|
||||
// Otherwise, add a new one
|
||||
else
|
||||
{
|
||||
var newAccessLink = new AccessLink
|
||||
{
|
||||
Name = SelectedName,
|
||||
Path = SelectedPath
|
||||
};
|
||||
QuickAccessLinks.Add(newAccessLink);
|
||||
DialogResult = true;
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectPath_OnClick(object commandParameter, RoutedEventArgs e)
|
||||
{
|
||||
var folderBrowserDialog = new FolderBrowserDialog();
|
||||
|
||||
if (folderBrowserDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK)
|
||||
return;
|
||||
|
||||
SelectedPath = folderBrowserDialog.SelectedPath;
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue