diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Exceptions/codemap.md b/Plugins/Flow.Launcher.Plugin.Explorer/Exceptions/codemap.md
new file mode 100644
index 000000000..cb51ed434
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Exceptions/codemap.md
@@ -0,0 +1,19 @@
+# Plugins/Flow.Launcher.Plugin.Explorer/Exceptions/
+
+
+
+## Responsibility
+
+
+
+## Design
+
+
+
+## Flow
+
+
+
+## Integration
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj
index f290ba3c7..6f643830e 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Flow.Launcher.Plugin.Explorer.csproj
@@ -8,7 +8,7 @@
true
false
en
- warnings
+ enable
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Helper/codemap.md b/Plugins/Flow.Launcher.Plugin.Explorer/Helper/codemap.md
new file mode 100644
index 000000000..c262d8db4
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Helper/codemap.md
@@ -0,0 +1,19 @@
+# Plugins/Flow.Launcher.Plugin.Explorer/Helper/
+
+
+
+## Responsibility
+
+
+
+## Design
+
+
+
+## Flow
+
+
+
+## Integration
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs
index 1ca4ea3ec..4571fdc5a 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Main.cs
@@ -2,16 +2,15 @@ using Flow.Launcher.Plugin.Explorer.Helper;
using Flow.Launcher.Plugin.Explorer.Search;
using Flow.Launcher.Plugin.Explorer.Search.Everything;
using Flow.Launcher.Plugin.Explorer.ViewModels;
-using Flow.Launcher.Plugin.Explorer.Views;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
-using System.Windows.Controls;
using Flow.Launcher.Plugin.Explorer.Exceptions;
using System.Linq;
using System.Globalization;
+using System.Windows.Controls;
using AvaloniaControl = Avalonia.Controls.Control;
namespace Flow.Launcher.Plugin.Explorer
@@ -32,7 +31,7 @@ namespace Flow.Launcher.Plugin.Explorer
public Control CreateSettingPanel()
{
- return new ExplorerSettings(viewModel);
+ throw new NotSupportedException("WPF settings are no longer supported. Use Avalonia version instead.");
}
public AvaloniaControl CreateSettingPanelAvalonia()
@@ -45,6 +44,7 @@ namespace Flow.Launcher.Plugin.Explorer
Context = context;
Settings = context.API.LoadSettingJsonStorage();
+ ActionKeywordModel.Init(Settings);
FillQuickAccessLinkNames();
viewModel = new SettingsViewModel(context, Settings);
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/DirectoryInfo/codemap.md b/Plugins/Flow.Launcher.Plugin.Explorer/Search/DirectoryInfo/codemap.md
new file mode 100644
index 000000000..7e2379493
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/DirectoryInfo/codemap.md
@@ -0,0 +1,19 @@
+# Plugins/Flow.Launcher.Plugin.Explorer/Search/DirectoryInfo/
+
+
+
+## Responsibility
+
+
+
+## Design
+
+
+
+## Flow
+
+
+
+## Integration
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/Exceptions/codemap.md b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/Exceptions/codemap.md
new file mode 100644
index 000000000..acfd3365f
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/Exceptions/codemap.md
@@ -0,0 +1,19 @@
+# Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/Exceptions/
+
+
+
+## Responsibility
+
+
+
+## Design
+
+
+
+## Flow
+
+
+
+## Integration
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/codemap.md b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/codemap.md
new file mode 100644
index 000000000..0fe828bae
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/codemap.md
@@ -0,0 +1,19 @@
+# Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/
+
+
+
+## Responsibility
+
+
+
+## Design
+
+
+
+## Flow
+
+
+
+## Integration
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/IProvider/codemap.md b/Plugins/Flow.Launcher.Plugin.Explorer/Search/IProvider/codemap.md
new file mode 100644
index 000000000..da9327288
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/IProvider/codemap.md
@@ -0,0 +1,19 @@
+# Plugins/Flow.Launcher.Plugin.Explorer/Search/IProvider/
+
+
+
+## Responsibility
+
+
+
+## Design
+
+
+
+## Flow
+
+
+
+## Integration
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/codemap.md b/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/codemap.md
new file mode 100644
index 000000000..c163b125d
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/codemap.md
@@ -0,0 +1,19 @@
+# Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/
+
+
+
+## Responsibility
+
+
+
+## Design
+
+
+
+## Flow
+
+
+
+## Integration
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
index 18eb168b9..38590bda3 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
@@ -1,11 +1,10 @@
-using System;
+using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Input;
using Flow.Launcher.Plugin.Explorer.Search.Everything;
-using Flow.Launcher.Plugin.Explorer.Views;
using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.Plugin.SharedModels;
using Peter;
@@ -106,7 +105,6 @@ namespace Flow.Launcher.Plugin.Explorer.Search
{
FilePath = path,
},
- PreviewPanel = new Lazy(() => new PreviewPanel(Settings, path, ResultType.Folder)),
Action = c =>
{
if (c.SpecialKeyState.ToModifierKeys() == ModifierKeys.Alt)
@@ -305,7 +303,6 @@ namespace Flow.Launcher.Plugin.Explorer.Search
TitleHighlightData = Context.API.FuzzySearch(query.Search, title).MatchData,
Score = score,
CopyText = filePath,
- PreviewPanel = new Lazy(() => new PreviewPanel(Settings, filePath, ResultType.File)),
Action = c =>
{
if (c.SpecialKeyState.ToModifierKeys() == ModifierKeys.Alt)
@@ -371,9 +368,9 @@ namespace Flow.Launcher.Plugin.Explorer.Search
{
try
{
- var fileSize = PreviewPanel.GetFileSize(filePath);
- var fileCreatedAt = PreviewPanel.GetFileCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
- var fileModifiedAt = PreviewPanel.GetFileLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ var fileSize = Views.Avalonia.PreviewPanel.GetFileSize(filePath);
+ var fileCreatedAt = Views.Avalonia.PreviewPanel.GetFileCreatedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ var fileModifiedAt = Views.Avalonia.PreviewPanel.GetFileLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
return Localize.plugin_explorer_plugin_tooltip_more_info(filePath, fileSize, fileCreatedAt, fileModifiedAt, Environment.NewLine);
}
catch (Exception e)
@@ -387,9 +384,9 @@ namespace Flow.Launcher.Plugin.Explorer.Search
{
try
{
- var folderSize = PreviewPanel.GetFolderSize(folderPath);
- var folderCreatedAt = PreviewPanel.GetFolderCreatedAt(folderPath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
- var folderModifiedAt = PreviewPanel.GetFolderLastModifiedAt(folderPath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ var folderSize = Views.Avalonia.PreviewPanel.GetFolderSize(folderPath);
+ var folderCreatedAt = Views.Avalonia.PreviewPanel.GetFolderCreatedAt(folderPath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
+ var folderModifiedAt = Views.Avalonia.PreviewPanel.GetFolderLastModifiedAt(folderPath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
return Localize.plugin_explorer_plugin_tooltip_more_info(folderPath, folderSize, folderCreatedAt, folderModifiedAt, Environment.NewLine);
}
catch (Exception e)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/codemap.md b/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/codemap.md
new file mode 100644
index 000000000..ed7a11978
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/codemap.md
@@ -0,0 +1,19 @@
+# Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/
+
+
+
+## Responsibility
+
+
+
+## Design
+
+
+
+## Flow
+
+
+
+## Integration
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/codemap.md b/Plugins/Flow.Launcher.Plugin.Explorer/Search/codemap.md
new file mode 100644
index 000000000..d0c67afe1
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/codemap.md
@@ -0,0 +1,19 @@
+# Plugins/Flow.Launcher.Plugin.Explorer/Search/
+
+
+
+## Responsibility
+
+
+
+## Design
+
+
+
+## Flow
+
+
+
+## Integration
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
index 10b3af170..aa10f1a5b 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
@@ -8,26 +8,36 @@ using System.IO;
using System.Linq;
using System.Threading.Tasks;
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;
using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks;
-using Flow.Launcher.Plugin.Explorer.Views;
+using Flow.Launcher.Plugin.Explorer.Views.Avalonia;
using AvaloniaApp = Avalonia.Application;
-using AvaloniaQuickAccessLinkSettings = Flow.Launcher.Plugin.Explorer.Views.Avalonia.QuickAccessLinkSettings;
namespace Flow.Launcher.Plugin.Explorer.ViewModels
{
public partial class SettingsViewModel : BaseModel
{
///
- /// Detects if we're running in an Avalonia application context
+ /// Gets the current active Avalonia window to use as dialog owner
///
- private static bool IsAvalonia => AvaloniaApp.Current != null;
-
+ private static global::Avalonia.Controls.Window? GetAvaloniaOwnerWindow()
+ {
+ if (AvaloniaApp.Current?.ApplicationLifetime is not global::Avalonia.Controls.ApplicationLifetimes.IClassicDesktopStyleApplicationLifetime desktop)
+ return null;
+
+ // First try to find an active window
+ var activeWindow = desktop.Windows.FirstOrDefault(w => w.IsActive);
+ if (activeWindow != null)
+ return activeWindow;
+
+ // Fall back to main window
+ return desktop.MainWindow;
+ }
+
public Settings Settings { get; set; }
internal PluginInitContext Context { get; set; }
@@ -41,6 +51,7 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
Context = context;
Settings = settings;
+ ActionKeywordModel.Init(settings);
InitializeEngineSelection();
InitializeActionKeywordModels();
}
@@ -162,7 +173,6 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
Settings.ShowCreatedDateInPreviewPanel = value;
OnPropertyChanged();
OnPropertyChanged(nameof(ShowPreviewPanelDateTimeChoices));
- OnPropertyChanged(nameof(PreviewPanelDateTimeChoicesVisibility));
}
}
@@ -174,7 +184,6 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
Settings.ShowModifiedDateInPreviewPanel = value;
OnPropertyChanged();
OnPropertyChanged(nameof(ShowPreviewPanelDateTimeChoices));
- OnPropertyChanged(nameof(PreviewPanelDateTimeChoicesVisibility));
}
}
@@ -186,7 +195,6 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
Settings.ShowFileAgeInPreviewPanel = value;
OnPropertyChanged();
OnPropertyChanged(nameof(ShowPreviewPanelDateTimeChoices));
- OnPropertyChanged(nameof(PreviewPanelDateTimeChoicesVisibility));
}
}
@@ -217,9 +225,6 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
public bool ShowPreviewPanelDateTimeChoices => ShowCreatedDateInPreviewPanel || ShowModifiedDateInPreviewPanel;
- public Visibility PreviewPanelDateTimeChoicesVisibility => ShowCreatedDateInPreviewPanel || ShowModifiedDateInPreviewPanel ? Visibility.Visible : Visibility.Collapsed;
-
-
public List TimeFormatList { get; } = new()
{
"h:mm",
@@ -296,7 +301,7 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
public ActionKeywordModel? SelectedActionKeyword { get; set; }
[RelayCommand]
- private void EditActionKeyword(object obj)
+ private async Task EditActionKeywordAsync(object obj)
{
if (SelectedActionKeyword is not { } actionKeyword)
{
@@ -304,14 +309,32 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
return;
}
- var actionKeywordWindow = new ActionKeywordSetting(actionKeyword);
+ var dialog = new ActionKeywordSetting(actionKeyword);
+ var ownerWindow = GetAvaloniaOwnerWindow();
+ bool dialogResult;
+ if (ownerWindow != null)
+ {
+ dialogResult = await dialog.ShowDialog(ownerWindow) ?? false;
+ }
+ else
+ {
+ // Fallback: show as normal window if owner is not available
+ dialog.Show();
+ var tcs = new TaskCompletionSource();
+ dialog.Closed += (_, _) => tcs.TrySetResult(true);
+ await tcs.Task;
+ dialogResult = true;
+ }
- if (!(actionKeywordWindow.ShowDialog() ?? false))
+ if (!dialogResult)
{
return;
}
- switch (actionKeyword.Enabled, actionKeywordWindow.KeywordEnabled)
+ var newKeyword = dialog.ActionKeyword;
+ var newEnabled = dialog.KeywordEnabled;
+
+ switch (actionKeyword.Enabled, newEnabled)
{
case (true, false):
Context.API.RemoveActionKeyword(Context.CurrentPluginMetadata.ID, actionKeyword.Keyword);
@@ -319,18 +342,16 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
case (true, true):
// same keyword will have dialog result false
Context.API.RemoveActionKeyword(Context.CurrentPluginMetadata.ID, actionKeyword.Keyword);
- Context.API.AddActionKeyword(Context.CurrentPluginMetadata.ID, actionKeywordWindow.ActionKeyword);
+ Context.API.AddActionKeyword(Context.CurrentPluginMetadata.ID, newKeyword);
break;
case (false, true):
- Context.API.AddActionKeyword(Context.CurrentPluginMetadata.ID, actionKeywordWindow.ActionKeyword);
+ Context.API.AddActionKeyword(Context.CurrentPluginMetadata.ID, newKeyword);
break;
case (false, false):
- throw new ArgumentException(
- $"Both false in {nameof(actionKeyword)}.{nameof(actionKeyword.Enabled)} and {nameof(actionKeywordWindow)}.{nameof(actionKeywordWindow.KeywordEnabled)} should suggest that the ShowDialog() result is false");
+ break;
}
- (actionKeyword.Keyword, actionKeyword.Enabled) = (actionKeywordWindow.ActionKeyword, actionKeywordWindow.KeywordEnabled);
-
+ (actionKeyword.Keyword, actionKeyword.Enabled) = (newKeyword, newEnabled);
}
#endregion
@@ -352,7 +373,7 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
}
[RelayCommand]
- private void EditIndexSearchExcludePaths()
+ private async Task EditIndexSearchExcludePathsAsync()
{
var selectedLink = SelectedIndexSearchExcludedPath;
var collection = Settings.IndexSearchExcludedSubdirectoryPaths;
@@ -363,7 +384,7 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
return;
}
- var path = PromptUserSelectPath(selectedLink.Type,
+ var path = await PromptUserSelectPathAsync(selectedLink.Type,
selectedLink.Type == ResultType.Folder
? selectedLink.Path
: Path.GetDirectoryName(selectedLink.Path));
@@ -380,21 +401,21 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
}
[RelayCommand]
- private void AddIndexSearchExcludePaths()
+ private async Task AddIndexSearchExcludePathsAsync()
{
var container = Settings.IndexSearchExcludedSubdirectoryPaths;
if (container is null) return;
-
- var folderBrowserDialog = new FolderBrowserDialog();
- if (folderBrowserDialog.ShowDialog() != DialogResult.OK)
+ var path = await PromptUserSelectFolderAsync();
+
+ if (path is null)
return;
var newAccessLink = new AccessLink
{
- Name = folderBrowserDialog.SelectedPath.GetPathName(),
- Path = folderBrowserDialog.SelectedPath
+ Name = path.GetPathName(),
+ Path = path
};
container.Add(newAccessLink);
@@ -413,50 +434,52 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
return;
}
- if (IsAvalonia)
+ var dialog = new QuickAccessLinkSettings(collection, selectedLink);
+ var ownerWindow = GetAvaloniaOwnerWindow();
+ bool dialogResult;
+ if (ownerWindow != null)
{
- var dialog = new AvaloniaQuickAccessLinkSettings(collection, selectedLink);
- var mainWindow = AvaloniaApp.Current?.ApplicationLifetime is global::Avalonia.Controls.ApplicationLifetimes.IClassicDesktopStyleApplicationLifetime desktop
- ? desktop.MainWindow
- : null;
- var result = await dialog.ShowDialog(mainWindow!);
- if (result == true)
- {
- Save();
- }
+ dialogResult = await dialog.ShowDialog(ownerWindow) ?? false;
}
else
{
- var quickAccessLinkSettings = new QuickAccessLinkSettings(collection, SelectedQuickAccessLink);
- if (quickAccessLinkSettings.ShowDialog() == true)
- {
- Save();
- }
+ // Fallback: show as normal window if owner is not available
+ dialog.Show();
+ var tcs = new TaskCompletionSource();
+ dialog.Closed += (_, _) => tcs.TrySetResult(true);
+ await tcs.Task;
+ dialogResult = true;
+ }
+
+ if (dialogResult)
+ {
+ Save();
}
}
-
+
[RelayCommand]
private async Task AddQuickAccessLinkAsync()
{
- if (IsAvalonia)
+ var dialog = new QuickAccessLinkSettings(Settings.QuickAccessLinks);
+ var ownerWindow = GetAvaloniaOwnerWindow();
+ bool dialogResult;
+ if (ownerWindow != null)
{
- var dialog = new AvaloniaQuickAccessLinkSettings(Settings.QuickAccessLinks);
- var mainWindow = AvaloniaApp.Current?.ApplicationLifetime is global::Avalonia.Controls.ApplicationLifetimes.IClassicDesktopStyleApplicationLifetime desktop
- ? desktop.MainWindow
- : null;
- var result = await dialog.ShowDialog(mainWindow!);
- if (result == true)
- {
- Save();
- }
+ dialogResult = await dialog.ShowDialog(ownerWindow) ?? false;
}
else
{
- var quickAccessLinkSettings = new QuickAccessLinkSettings(Settings.QuickAccessLinks);
- if (quickAccessLinkSettings.ShowDialog() == true)
- {
- Save();
- }
+ // Fallback: show as normal window if owner is not available
+ dialog.Show();
+ var tcs = new TaskCompletionSource();
+ dialog.Closed += (_, _) => tcs.TrySetResult(true);
+ await tcs.Task;
+ dialogResult = true;
+ }
+
+ if (dialogResult)
+ {
+ Save();
}
}
@@ -492,45 +515,60 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
}
Save();
}
-
+
private void ShowUnselectedMessage()
{
var warning = Localize.plugin_explorer_make_selection_warning();
Context.API.ShowMsgBox(warning);
}
- #endregion
-
- private static string? PromptUserSelectPath(ResultType type, string? initialDirectory = null)
+ private static async Task PromptUserSelectPathAsync(ResultType type, string? initialDirectory = null)
{
string? path = null;
if (type is ResultType.Folder)
{
- var folderBrowserDialog = new FolderBrowserDialog();
-
- if (initialDirectory is not null)
- folderBrowserDialog.InitialDirectory = initialDirectory;
-
- if (folderBrowserDialog.ShowDialog() != DialogResult.OK)
- return path;
-
- path = folderBrowserDialog.SelectedPath;
+ path = await PromptUserSelectFolderAsync(initialDirectory);
}
else if (type is ResultType.File)
{
- var openFileDialog = new OpenFileDialog();
- if (initialDirectory is not null)
- openFileDialog.InitialDirectory = initialDirectory;
-
- if (openFileDialog.ShowDialog() != DialogResult.OK)
- return path;
-
- path = openFileDialog.FileName;
+ path = await PromptUserSelectFileAsync(initialDirectory);
}
return path;
}
+ private static async Task PromptUserSelectFolderAsync(string? initialDirectory = null)
+ {
+ var mainWindow = AvaloniaApp.Current?.ApplicationLifetime is global::Avalonia.Controls.ApplicationLifetimes.IClassicDesktopStyleApplicationLifetime desktop
+ ? desktop.MainWindow
+ : null;
+
+ if (mainWindow == null) return null;
+
+ var folders = await mainWindow.StorageProvider.OpenFolderPickerAsync(new global::Avalonia.Platform.Storage.FolderPickerOpenOptions
+ {
+ AllowMultiple = false
+ });
+
+ return folders.Count > 0 ? folders[0].Path.LocalPath : null;
+ }
+
+ private static async Task PromptUserSelectFileAsync(string? initialDirectory = null)
+ {
+ var mainWindow = AvaloniaApp.Current?.ApplicationLifetime is global::Avalonia.Controls.ApplicationLifetimes.IClassicDesktopStyleApplicationLifetime desktop
+ ? desktop.MainWindow
+ : null;
+
+ if (mainWindow == null) return null;
+
+ var files = await mainWindow.StorageProvider.OpenFilePickerAsync(new global::Avalonia.Platform.Storage.FilePickerOpenOptions
+ {
+ AllowMultiple = false
+ });
+
+ return files.Count > 0 ? files[0].Path.LocalPath : null;
+ }
+
internal static void OpenWindowsIndexingOptions()
{
var psi = new ProcessStartInfo
@@ -544,9 +582,9 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
}
[RelayCommand]
- private void OpenFileEditorPath()
+ private async Task OpenFileEditorPathAsync()
{
- var path = PromptUserSelectPath(ResultType.File, Settings.EditorPath != null ? Path.GetDirectoryName(Settings.EditorPath) : null);
+ var path = await PromptUserSelectFileAsync(Settings.EditorPath != null ? Path.GetDirectoryName(Settings.EditorPath) : null);
if (path is null)
return;
@@ -554,9 +592,9 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
}
[RelayCommand]
- private void OpenFolderEditorPath()
+ private async Task OpenFolderEditorPathAsync()
{
- var path = PromptUserSelectPath(ResultType.File, Settings.FolderEditorPath != null ? Path.GetDirectoryName(Settings.FolderEditorPath) : null);
+ var path = await PromptUserSelectFolderAsync(Settings.FolderEditorPath != null ? Path.GetDirectoryName(Settings.FolderEditorPath) : null);
if (path is null)
return;
@@ -564,9 +602,9 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
}
[RelayCommand]
- private void OpenShellPath()
+ private async Task OpenShellPathAsync()
{
- var path = PromptUserSelectPath(ResultType.File, Settings.EditorPath != null ? Path.GetDirectoryName(Settings.EditorPath) : null);
+ var path = await PromptUserSelectFileAsync(Settings.EditorPath != null ? Path.GetDirectoryName(Settings.EditorPath) : null);
if (path is null)
return;
@@ -628,6 +666,8 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
}
}
+ #endregion
+
#region Everything FastSortWarning
public List AllEverythingSortOptions { get; } = EverythingSortOptionLocalized.GetValues();
@@ -646,23 +686,23 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels
}
}
- public Visibility FastSortWarningVisibility
+ public bool FastSortWarningVisibility
{
get
{
try
{
- return EverythingApi.IsFastSortOption(Settings.SortOption) ? Visibility.Collapsed : Visibility.Visible;
+ return !EverythingApi.IsFastSortOption(Settings.SortOption);
}
catch (IPCErrorException)
{
// this error occurs if the Everything service is not running, in this instance show the warning and
// update the message to let user know in the settings panel.
- return Visibility.Visible;
+ return true;
}
catch (DllNotFoundException)
{
- return Visibility.Collapsed;
+ return false;
}
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/codemap.md b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/codemap.md
new file mode 100644
index 000000000..f55400af2
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/codemap.md
@@ -0,0 +1,19 @@
+# Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/
+
+
+
+## Responsibility
+
+
+
+## Design
+
+
+
+## Flow
+
+
+
+## Integration
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml
deleted file mode 100644
index ae0f91d93..000000000
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml
+++ /dev/null
@@ -1,129 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs
deleted file mode 100644
index 562170062..000000000
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs
+++ /dev/null
@@ -1,115 +0,0 @@
-using System.Linq;
-using System.Windows;
-using System.Windows.Input;
-using CommunityToolkit.Mvvm.ComponentModel;
-using Flow.Launcher.Plugin.Explorer.ViewModels;
-
-namespace Flow.Launcher.Plugin.Explorer.Views
-{
- [INotifyPropertyChanged]
- public partial class ActionKeywordSetting
- {
- private ActionKeywordModel CurrentActionKeyword { get; }
-
- public string ActionKeyword
- {
- get => actionKeyword;
- set
- {
- // Set Enable to be true if user change ActionKeyword
- KeywordEnabled = true;
- _ = SetProperty(ref actionKeyword, value);
- }
- }
-
- public bool KeywordEnabled
- {
- get => _keywordEnabled;
- set => _ = SetProperty(ref _keywordEnabled, value);
- }
-
- private string actionKeyword;
- private bool _keywordEnabled;
-
- public ActionKeywordSetting(ActionKeywordModel selectedActionKeyword)
- {
- CurrentActionKeyword = selectedActionKeyword;
- ActionKeyword = selectedActionKeyword.Keyword;
- KeywordEnabled = selectedActionKeyword.Enabled;
-
- InitializeComponent();
-
- TxtCurrentActionKeyword.Focus();
- }
-
- private void OnDoneButtonClick(object sender, RoutedEventArgs e)
- {
- if (string.IsNullOrEmpty(ActionKeyword))
- ActionKeyword = Query.GlobalPluginWildcardSign;
-
- if (CurrentActionKeyword.Keyword == ActionKeyword && CurrentActionKeyword.Enabled == KeywordEnabled)
- {
- DialogResult = false;
- Close();
- return;
- }
-
- if (ActionKeyword == Query.GlobalPluginWildcardSign)
- switch (CurrentActionKeyword.KeywordProperty, KeywordEnabled)
- {
- case (Settings.ActionKeyword.FileContentSearchActionKeyword, true):
- Main.Context.API.ShowMsgBox(Localize.plugin_explorer_globalActionKeywordInvalid());
- return;
- case (Settings.ActionKeyword.QuickAccessActionKeyword, true):
- Main.Context.API.ShowMsgBox(Localize.plugin_explorer_quickaccess_globalActionKeywordInvalid());
- return;
- }
-
- if (!KeywordEnabled || !Main.Context.API.ActionKeywordAssigned(ActionKeyword))
- {
- DialogResult = true;
- Close();
- return;
- }
-
- // The keyword is not valid, so show message
- Main.Context.API.ShowMsgBox(Localize.plugin_explorer_new_action_keyword_assigned());
- }
-
- private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
- {
- DialogResult = false;
- Close();
- }
-
- private void TxtCurrentActionKeyword_OnKeyDown(object sender, KeyEventArgs e)
- {
- if (e.Key == Key.Enter)
- {
- DownButton.Focus();
- OnDoneButtonClick(sender, e);
- e.Handled = true;
- }
- if (e.Key == Key.Space)
- {
- e.Handled = true;
- }
- }
-
- private void TextBox_Pasting(object sender, DataObjectPastingEventArgs e)
- {
- if (e.DataObject.GetDataPresent(DataFormats.Text))
- {
- string text = e.DataObject.GetData(DataFormats.Text) as string;
- if (!string.IsNullOrEmpty(text) && text.Any(char.IsWhiteSpace))
- {
- e.CancelCommand();
- }
- }
- else
- {
- e.CancelCommand();
- }
- }
- }
-}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/Avalonia/ActionKeywordSetting.axaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/Avalonia/ActionKeywordSetting.axaml
index 7aad85fcf..1d646107c 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/Avalonia/ActionKeywordSetting.axaml
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/Avalonia/ActionKeywordSetting.axaml
@@ -7,7 +7,7 @@
Title="{DynamicResource plugin_explorer_manageactionkeywords_header}"
Width="400"
Height="255"
- WindowStartupLocation="CenterOwner"
+ WindowStartupLocation="CenterScreen"
CanResize="False">
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/Avalonia/ActionKeywordSetting.axaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/Avalonia/ActionKeywordSetting.axaml.cs
index 16d84778d..4f815d71e 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/Avalonia/ActionKeywordSetting.axaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/Avalonia/ActionKeywordSetting.axaml.cs
@@ -1,4 +1,5 @@
#nullable enable
+using System;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
@@ -49,7 +50,11 @@ public partial class ActionKeywordSetting : Window, INotifyPropertyChanged
InitializeComponent();
DataContext = this;
+ }
+ protected override void OnOpened(EventArgs e)
+ {
+ base.OnOpened(e);
this.FindControl("TxtCurrentActionKeyword")?.Focus();
}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/Avalonia/PreviewPanel.axaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/Avalonia/PreviewPanel.axaml
new file mode 100644
index 000000000..353e02e9b
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/Avalonia/PreviewPanel.axaml
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/Avalonia/PreviewPanel.axaml.cs
similarity index 80%
rename from Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
rename to Plugins/Flow.Launcher.Plugin.Explorer/Views/Avalonia/PreviewPanel.axaml.cs
index 3c627cc06..55d99b37f 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/Avalonia/PreviewPanel.axaml.cs
@@ -1,59 +1,93 @@
-using System;
+#nullable enable
+using System;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
+using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
+using Avalonia.Controls;
+using Avalonia.Media;
+using Avalonia.Media.Imaging;
using Flow.Launcher.Plugin.Explorer.Search;
-using CommunityToolkit.Mvvm.ComponentModel;
-namespace Flow.Launcher.Plugin.Explorer.Views;
+namespace Flow.Launcher.Plugin.Explorer.Views.Avalonia;
-#nullable enable
-
-[INotifyPropertyChanged]
-public partial class PreviewPanel : UserControl
+public partial class PreviewPanel : UserControl, INotifyPropertyChanged
{
private static readonly string ClassName = nameof(PreviewPanel);
public string FilePath { get; }
public string FileName { get; }
- [ObservableProperty]
private string _fileSize = Localize.plugin_explorer_plugin_tooltip_more_info_unknown();
-
- [ObservableProperty]
private string _createdAt = "";
-
- [ObservableProperty]
private string _lastModifiedAt = "";
+ private IImage? _previewImage;
- [ObservableProperty]
- private ImageSource _previewImage = new BitmapImage();
+ public string FileSize
+ {
+ get => _fileSize;
+ set
+ {
+ if (_fileSize != value)
+ {
+ _fileSize = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
+ public string CreatedAt
+ {
+ get => _createdAt;
+ set
+ {
+ if (_createdAt != value)
+ {
+ _createdAt = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
+ public string LastModifiedAt
+ {
+ get => _lastModifiedAt;
+ set
+ {
+ if (_lastModifiedAt != value)
+ {
+ _lastModifiedAt = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
+ public IImage? PreviewImage
+ {
+ get => _previewImage;
+ set
+ {
+ if (_previewImage != value)
+ {
+ _previewImage = value;
+ OnPropertyChanged();
+ }
+ }
+ }
private Settings Settings { get; }
- public Visibility FileSizeVisibility => Settings.ShowFileSizeInPreviewPanel
- ? Visibility.Visible
- : Visibility.Collapsed;
- public Visibility CreatedAtVisibility => Settings.ShowCreatedDateInPreviewPanel
- ? Visibility.Visible
- : Visibility.Collapsed;
- public Visibility LastModifiedAtVisibility => Settings.ShowModifiedDateInPreviewPanel
- ? Visibility.Visible
- : Visibility.Collapsed;
+ public bool FileSizeVisibility => Settings.ShowFileSizeInPreviewPanel;
+ public bool CreatedAtVisibility => Settings.ShowCreatedDateInPreviewPanel;
+ public bool LastModifiedAtVisibility => Settings.ShowModifiedDateInPreviewPanel;
- public Visibility FileInfoVisibility =>
+ public bool FileInfoVisibility =>
Settings.ShowFileSizeInPreviewPanel ||
Settings.ShowCreatedDateInPreviewPanel ||
- Settings.ShowModifiedDateInPreviewPanel
- ? Visibility.Visible
- : Visibility.Collapsed;
+ Settings.ShowModifiedDateInPreviewPanel;
public PreviewPanel(Settings settings, string filePath, ResultType type)
{
@@ -62,6 +96,7 @@ public partial class PreviewPanel : UserControl
FileName = Path.GetFileName(filePath);
InitializeComponent();
+ DataContext = this;
if (Settings.ShowFileSizeInPreviewPanel)
{
@@ -73,8 +108,8 @@ public partial class PreviewPanel : UserControl
{
_ = Task.Run(() =>
{
- FileSize = GetFolderSize(filePath);
- OnPropertyChanged(nameof(FileSize));
+ var size = GetFolderSize(filePath);
+ global::Avalonia.Threading.Dispatcher.UIThread.Post(() => FileSize = size);
}).ConfigureAwait(false);
}
}
@@ -88,7 +123,7 @@ public partial class PreviewPanel : UserControl
if (Settings.ShowModifiedDateInPreviewPanel)
{
- LastModifiedAt = type == ResultType.File ?
+ LastModifiedAt = type == ResultType.File ?
GetFileLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel) :
GetFolderLastModifiedAt(filePath, Settings.PreviewPanelDateFormat, Settings.PreviewPanelTimeFormat, Settings.ShowFileAgeInPreviewPanel);
}
@@ -98,7 +133,24 @@ public partial class PreviewPanel : UserControl
private async Task LoadImageAsync()
{
- PreviewImage = await Main.Context.API.LoadImageAsync(FilePath, true).ConfigureAwait(false);
+ try
+ {
+ var imagePath = FilePath;
+ if (string.IsNullOrEmpty(imagePath) || !File.Exists(imagePath))
+ return;
+
+ var bitmap = new Bitmap(imagePath);
+ global::Avalonia.Threading.Dispatcher.UIThread.Post(() => PreviewImage = bitmap);
+ }
+ catch (Exception e)
+ {
+ Main.Context.API.LogException(ClassName, $"Failed to load image for {FilePath}", e);
+ }
+ }
+
+ private void InitializeComponent()
+ {
+ global::Avalonia.Markup.Xaml.AvaloniaXamlLoader.Load(this);
}
public static string GetFileSize(string filePath)
@@ -323,8 +375,15 @@ public partial class PreviewPanel : UserControl
var yearsDiff = now.Year - fileDateTime.Year;
if (now.Month < fileDateTime.Month || (now.Month == fileDateTime.Month && now.Day < fileDateTime.Day))
- yearsDiff--;
+ yearsDiff--;
- return yearsDiff == 1 ? Localize.OneYearAgo(): Localize.YearsAgo(yearsDiff);
+ return yearsDiff == 1 ? Localize.OneYearAgo() : Localize.YearsAgo(yearsDiff);
+ }
+
+ public event PropertyChangedEventHandler? PropertyChanged;
+
+ protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/Avalonia/codemap.md b/Plugins/Flow.Launcher.Plugin.Explorer/Views/Avalonia/codemap.md
new file mode 100644
index 000000000..8c892edfe
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/Avalonia/codemap.md
@@ -0,0 +1,19 @@
+# Plugins/Flow.Launcher.Plugin.Explorer/Views/Avalonia/
+
+
+
+## Responsibility
+
+
+
+## Design
+
+
+
+## Flow
+
+
+
+## Integration
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
deleted file mode 100644
index 08abc3ba6..000000000
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
+++ /dev/null
@@ -1,861 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs
deleted file mode 100644
index a62a2b6c0..000000000
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml.cs
+++ /dev/null
@@ -1,139 +0,0 @@
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.IO;
-using System.Linq;
-using System.Windows;
-using System.Windows.Controls;
-using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks;
-using Flow.Launcher.Plugin.Explorer.ViewModels;
-using DataFormats = System.Windows.DataFormats;
-using DragDropEffects = System.Windows.DragDropEffects;
-using DragEventArgs = System.Windows.DragEventArgs;
-
-namespace Flow.Launcher.Plugin.Explorer.Views
-{
- public partial class ExplorerSettings
- {
- private readonly SettingsViewModel _viewModel;
- private readonly List _expanders;
-
- public ExplorerSettings(SettingsViewModel viewModel)
- {
- _viewModel = viewModel;
- DataContext = viewModel;
-
- InitializeComponent();
-
- DataContext = viewModel;
-
- ActionKeywordModel.Init(viewModel.Settings);
-
- _expanders = new List
- {
- GeneralSettingsExpander,
- ContextMenuExpander,
- PreviewPanelExpander,
- EverythingExpander,
- ActionKeywordsExpander,
- QuickAccessExpander,
- ExcludedPathsExpander
- };
- }
-
- private void AccessLinkDragDrop(string containerName, DragEventArgs e)
- {
- var files = (string[])e.Data.GetData(DataFormats.FileDrop);
-
- if (files == null || files.Length == 0)
- {
- return;
- }
- foreach (var s in files)
- {
- if (Directory.Exists(s))
- {
- var newFolderLink = new AccessLink
- {
- Path = s
- };
- _viewModel.AppendLink(containerName, newFolderLink);
- }
- }
- }
-
- private void lbxAccessLinks_DragEnter(object sender, DragEventArgs e)
- {
- if (e.Data.GetDataPresent(DataFormats.FileDrop))
- {
- e.Effects = DragDropEffects.Link;
- }
- else
- {
- e.Effects = DragDropEffects.None;
- }
- }
-
- private void btnOpenIndexingOptions_Click(object sender, RoutedEventArgs e)
- {
- SettingsViewModel.OpenWindowsIndexingOptions();
- }
-
- private void LbxAccessLinks_OnDrop(object sender, DragEventArgs e)
- {
- AccessLinkDragDrop("QuickAccessLink", e);
- }
- private void LbxExcludedPaths_OnDrop(object sender, DragEventArgs e)
- {
- AccessLinkDragDrop("IndexSearchExcludedPath", e);
- }
-
- private void AllowOnlyNumericInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
- {
- e.Handled = e.Text.ToCharArray().Any(c => !char.IsDigit(c));
- }
-
- private void Expander_Expanded(object sender, RoutedEventArgs e)
- {
- if (sender is Expander expandedExpander)
- {
- // Ensure _expanders is not null and contains items
- if (_expanders == null || _expanders.Count == 0) return;
-
- foreach (var expander in _expanders)
- {
- if (expander != null && expander != expandedExpander && expander.IsExpanded)
- {
- expander.IsExpanded = false;
- }
- }
- }
- }
-
- private void lbxAccessLinks_Loaded(object sender, RoutedEventArgs e)
- {
- lbxAccessLinks.Items.SortDescriptions.Add(new SortDescription("Path", ListSortDirection.Ascending));
- }
-
- private void lbxExcludedPaths_Loaded(object sender, RoutedEventArgs e)
- {
- 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;
- }
- }
-}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml
deleted file mode 100644
index 6082fe6c4..000000000
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/PreviewPanel.xaml
+++ /dev/null
@@ -1,145 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml
deleted file mode 100644
index e977a72c2..000000000
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml
+++ /dev/null
@@ -1,174 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
deleted file mode 100644
index f8929549b..000000000
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/QuickAccessLinkSettings.xaml.cs
+++ /dev/null
@@ -1,218 +0,0 @@
-using System;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.IO;
-using System.Linq;
-using System.Windows;
-using System.Windows.Forms;
-using Flow.Launcher.Plugin.Explorer.Helper;
-using Flow.Launcher.Plugin.Explorer.Search;
-using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks;
-using CommunityToolkit.Mvvm.ComponentModel;
-
-namespace Flow.Launcher.Plugin.Explorer.Views;
-
-[INotifyPropertyChanged]
-public partial class QuickAccessLinkSettings
-{
- private static readonly string ClassName = nameof(QuickAccessLinkSettings);
-
- private string _selectedPath;
- public string SelectedPath
- {
- get => _selectedPath;
- set
- {
- if (_selectedPath != value)
- {
- _selectedPath = value;
- OnPropertyChanged();
- if (string.IsNullOrEmpty(_selectedName))
- {
- SelectedName = _selectedPath.GetPathName();
- }
- if (!string.IsNullOrEmpty(_selectedPath))
- {
- _accessLinkType = GetResultType(_selectedPath);
- }
- }
- }
- }
-
- private string _selectedName;
- public string SelectedName
- {
- get
- {
- return string.IsNullOrEmpty(_selectedName) ? _selectedPath.GetPathName() : _selectedName;
- }
- set
- {
- if (_selectedName != value)
- {
- _selectedName = value;
- OnPropertyChanged();
- }
- }
- }
-
- public bool IsFileSelected { get; set; }
- public bool IsFolderSelected { get; set; } = true; // Default to Folder
-
- private bool IsEdit { get; }
- private AccessLink SelectedAccessLink { get; }
-
- public ObservableCollection QuickAccessLinks { get; }
-
- private ResultType _accessLinkType = ResultType.Folder; // Default to Folder
-
- public QuickAccessLinkSettings(ObservableCollection quickAccessLinks)
- {
- IsEdit = false;
- QuickAccessLinks = quickAccessLinks;
- InitializeComponent();
- }
-
- public QuickAccessLinkSettings(ObservableCollection quickAccessLinks, AccessLink selectedAccessLink)
- {
- IsEdit = true;
- _selectedName = selectedAccessLink.Name;
- _selectedPath = selectedAccessLink.Path;
- _accessLinkType = GetResultType(_selectedPath); // Initialize link type
- IsFileSelected = selectedAccessLink.Type == ResultType.File; // Initialize default selection
- IsFolderSelected = !IsFileSelected;
- 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 = Localize.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 = Localize.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)
- {
- var index = QuickAccessLinks.IndexOf(SelectedAccessLink);
- if (index >= 0)
- {
- var updatedLink = new AccessLink
- {
- Name = SelectedName,
- Type = _accessLinkType,
- Path = SelectedPath
- };
- QuickAccessLinks[index] = updatedLink;
- }
- DialogResult = true;
- Close();
- }
- // Add a new one if the selected access link is null (should not happen in edit mode, but just in case)
- else
- {
- AddNewAccessLink();
- }
- }
- // Otherwise, add a new one
- else
- {
- AddNewAccessLink();
- }
-
- void AddNewAccessLink()
- {
- var newAccessLink = new AccessLink
- {
- Name = SelectedName,
- Type = _accessLinkType,
- Path = SelectedPath
- };
- QuickAccessLinks.Add(newAccessLink);
- DialogResult = true;
- Close();
- }
- }
-
- private void SelectPath_OnClick(object commandParameter, RoutedEventArgs e)
- {
- // Open file or folder selection dialog based on the selected radio button
- if (IsFileSelected)
- {
- var openFileDialog = new OpenFileDialog
- {
- Multiselect = false,
- CheckFileExists = true,
- CheckPathExists = true
- };
-
- if (openFileDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK ||
- string.IsNullOrEmpty(openFileDialog.FileName))
- return;
-
- SelectedPath = openFileDialog.FileName;
- }
- else // Folder selection
- {
- var folderBrowserDialog = new FolderBrowserDialog
- {
- ShowNewFolderButton = true
- };
-
- if (folderBrowserDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK ||
- string.IsNullOrEmpty(folderBrowserDialog.SelectedPath))
- return;
-
- SelectedPath = folderBrowserDialog.SelectedPath;
- }
- }
-
- private static ResultType GetResultType(string path)
- {
- // Check if the path is a file or folder
- if (File.Exists(path))
- {
- return ResultType.File;
- }
- else if (Directory.Exists(path))
- {
- if (string.Equals(Path.GetPathRoot(path), path, StringComparison.OrdinalIgnoreCase))
- {
- return ResultType.Volume;
- }
- else
- {
- return ResultType.Folder;
- }
- }
- else
- {
- // This should not happen, but just in case, we assume it's a folder
- Main.Context.API.LogError(ClassName, $"The path '{path}' does not exist or is invalid. Defaulting to Folder type.");
- return ResultType.Folder;
- }
- }
-}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/codemap.md b/Plugins/Flow.Launcher.Plugin.Explorer/Views/codemap.md
new file mode 100644
index 000000000..422e403f6
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/codemap.md
@@ -0,0 +1,19 @@
+# Plugins/Flow.Launcher.Plugin.Explorer/Views/
+
+
+
+## Responsibility
+
+
+
+## Design
+
+
+
+## Flow
+
+
+
+## Integration
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/codemap.md b/Plugins/Flow.Launcher.Plugin.Explorer/codemap.md
new file mode 100644
index 000000000..691d38506
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/codemap.md
@@ -0,0 +1,19 @@
+# Plugins/Flow.Launcher.Plugin.Explorer/
+
+
+
+## Responsibility
+
+
+
+## Design
+
+
+
+## Flow
+
+
+
+## Integration
+
+