Skip to content

Commit ac61469

Browse files
authored
Merge pull request #3561 from onesounds/250520-FixFilesConfig
Improve File Manager Configuration Error Handling
2 parents b4a3e06 + 41b9cd4 commit ac61469

12 files changed

+336
-135
lines changed

Flow.Launcher.Infrastructure/UserSettings/Settings.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,8 @@ public CustomExplorerViewModel CustomExplorer
226226
new()
227227
{
228228
Name = "Files",
229-
Path = "Files",
230-
DirectoryArgument = "-select \"%d\"",
229+
Path = "Files-Stable",
230+
DirectoryArgument = "\"%d\"",
231231
FileArgument = "-select \"%f\""
232232
}
233233
};

Flow.Launcher/App.xaml.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ public App()
9898
.AddTransient<SettingsPanePluginStoreViewModel>()
9999
.AddTransient<SettingsPaneProxyViewModel>()
100100
.AddTransient<SettingsPaneThemeViewModel>()
101+
// Use transient instance for dialog view models because
102+
// settings will change and we need to recreate them
103+
.AddTransient<SelectBrowserViewModel>()
104+
.AddTransient<SelectFileManagerViewModel>()
101105
).Build();
102106
Ioc.Default.ConfigureServices(host.Services);
103107
}

Flow.Launcher/Languages/en.xaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,13 +366,16 @@
366366

367367
<!-- FileManager Setting Dialog -->
368368
<system:String x:Key="fileManagerWindow">Select File Manager</system:String>
369+
<system:String x:Key="fileManager_learnMore">Learn more</system:String>
369370
<system:String x:Key="fileManager_tips">Please specify the file location of the file manager you using and add arguments as required. The &quot;%d&quot; represents the directory path to open for, used by the Arg for Folder field and for commands opening specific directories. The &quot;%f&quot; represents the file path to open for, used by the Arg for File field and for commands opening specific files.</system:String>
370371
<system:String x:Key="fileManager_tips2">For example, if the file manager uses a command such as &quot;totalcmd.exe /A c:\windows&quot; to open the c:\windows directory, the File Manager Path will be totalcmd.exe, and the Arg For Folder will be /A &quot;%d&quot;. Certain file managers like QTTabBar may just require a path to be supplied, in this instance use &quot;%d&quot; as the File Manager Path and leave the rest of the fileds blank.</system:String>
371372
<system:String x:Key="fileManager_name">File Manager</system:String>
372373
<system:String x:Key="fileManager_profile_name">Profile Name</system:String>
373374
<system:String x:Key="fileManager_path">File Manager Path</system:String>
374375
<system:String x:Key="fileManager_directory_arg">Arg For Folder</system:String>
375376
<system:String x:Key="fileManager_file_arg">Arg For File</system:String>
377+
<system:String x:Key="fileManagerPathNotFound">The file manager '{0}' could not be located at '{1}'. Would you like to continue?</system:String>
378+
<system:String x:Key="fileManagerPathError">File Manager Path Error</system:String>
376379

377380
<!-- DefaultBrowser Setting Dialog -->
378381
<system:String x:Key="defaultBrowserTitle">Default Web Browser</system:String>
@@ -462,6 +465,14 @@
462465
<system:String x:Key="reportWindow_upload_log">1. Upload log file: {0}</system:String>
463466
<system:String x:Key="reportWindow_copy_below">2. Copy below exception message</system:String>
464467

468+
<!-- File Open Error -->
469+
<system:String x:Key="fileManagerNotFoundTitle">File Manager Error</system:String>
470+
<system:String x:Key="fileManagerNotFound">
471+
The specified file manager could not be found. Please check the Custom File Manager setting under Settings > General.
472+
</system:String>
473+
<system:String x:Key="errorTitle">Error</system:String>
474+
<system:String x:Key="folderOpenError">An error occurred while opening the folder. {0}</system:String>
475+
465476
<!-- General Notice -->
466477
<system:String x:Key="pleaseWait">Please wait...</system:String>
467478

Flow.Launcher/MessageBoxEx.xaml.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@ private MessageBoxEx(MessageBoxButton button)
2222
InitializeComponent();
2323
}
2424

25-
public static MessageBoxResult Show(string messageBoxText)
26-
=> Show(messageBoxText, string.Empty, MessageBoxButton.OK, MessageBoxImage.None, MessageBoxResult.OK);
27-
2825
public static MessageBoxResult Show(
2926
string messageBoxText,
3027
string caption = "",

Flow.Launcher/PublicAPIInstance.cs

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,14 @@
3232
using JetBrains.Annotations;
3333
using Squirrel;
3434
using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;
35+
using System.ComponentModel;
3536

3637
namespace Flow.Launcher
3738
{
3839
public class PublicAPIInstance : IPublicAPI, IRemovable
3940
{
41+
private static readonly string ClassName = nameof(PublicAPIInstance);
42+
4043
private readonly Settings _settings;
4144
private readonly MainViewModel _mainVM;
4245

@@ -316,40 +319,63 @@ public void SavePluginSettings()
316319

317320
public void OpenDirectory(string DirectoryPath, string FileNameOrFilePath = null)
318321
{
319-
using var explorer = new Process();
320-
var explorerInfo = _settings.CustomExplorer;
321-
var explorerPath = explorerInfo.Path.Trim().ToLowerInvariant();
322-
var targetPath = FileNameOrFilePath is null
323-
? DirectoryPath
324-
: Path.IsPathRooted(FileNameOrFilePath)
325-
? FileNameOrFilePath
326-
: Path.Combine(DirectoryPath, FileNameOrFilePath);
327-
328-
if (Path.GetFileNameWithoutExtension(explorerPath) == "explorer")
322+
try
329323
{
330-
// Windows File Manager
331-
// We should ignore and pass only the path to Shell to prevent zombie explorer.exe processes
332-
explorer.StartInfo = new ProcessStartInfo
324+
using var explorer = new Process();
325+
var explorerInfo = _settings.CustomExplorer;
326+
var explorerPath = explorerInfo.Path.Trim().ToLowerInvariant();
327+
var targetPath = FileNameOrFilePath is null
328+
? DirectoryPath
329+
: Path.IsPathRooted(FileNameOrFilePath)
330+
? FileNameOrFilePath
331+
: Path.Combine(DirectoryPath, FileNameOrFilePath);
332+
333+
if (Path.GetFileNameWithoutExtension(explorerPath) == "explorer")
333334
{
334-
FileName = targetPath, // Not explorer, Only path.
335-
UseShellExecute = true // Must be true to open folder
336-
};
335+
// Windows File Manager
336+
explorer.StartInfo = new ProcessStartInfo
337+
{
338+
FileName = targetPath,
339+
UseShellExecute = true
340+
};
341+
}
342+
else
343+
{
344+
// Custom File Manager
345+
explorer.StartInfo = new ProcessStartInfo
346+
{
347+
FileName = explorerInfo.Path.Replace("%d", DirectoryPath),
348+
UseShellExecute = true,
349+
Arguments = FileNameOrFilePath is null
350+
? explorerInfo.DirectoryArgument.Replace("%d", DirectoryPath)
351+
: explorerInfo.FileArgument
352+
.Replace("%d", DirectoryPath)
353+
.Replace("%f", targetPath)
354+
};
355+
}
356+
357+
explorer.Start();
337358
}
338-
else
359+
catch (Win32Exception ex) when (ex.NativeErrorCode == 2)
339360
{
340-
// Custom File Manager
341-
explorer.StartInfo = new ProcessStartInfo
342-
{
343-
FileName = explorerInfo.Path.Replace("%d", DirectoryPath),
344-
UseShellExecute = true,
345-
Arguments = FileNameOrFilePath is null
346-
? explorerInfo.DirectoryArgument.Replace("%d", DirectoryPath)
347-
: explorerInfo.FileArgument
348-
.Replace("%d", DirectoryPath)
349-
.Replace("%f", targetPath)
350-
};
361+
LogError(ClassName, "File Manager not found");
362+
ShowMsgBox(
363+
string.Format(GetTranslation("fileManagerNotFound"), ex.Message),
364+
GetTranslation("fileManagerNotFoundTitle"),
365+
MessageBoxButton.OK,
366+
MessageBoxImage.Error
367+
);
368+
}
369+
catch (Exception ex)
370+
{
371+
LogException(ClassName, "Failed to open folder", ex);
372+
ShowMsgBox(
373+
string.Format(GetTranslation("folderOpenError"), ex.Message),
374+
GetTranslation("errorTitle"),
375+
MessageBoxButton.OK,
376+
MessageBoxImage.Error
377+
);
351378
}
352-
explorer.Start();
353379
}
354380

355381
private void OpenUri(Uri uri, bool? inPrivate = null)

Flow.Launcher/SelectBrowserWindow.xaml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@
66
xmlns:local="clr-namespace:Flow.Launcher"
77
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
88
xmlns:ui="http://schemas.modernwpf.com/2019"
9+
xmlns:vm="clr-namespace:Flow.Launcher.ViewModel"
910
Title="{DynamicResource defaultBrowserTitle}"
1011
Width="550"
12+
d:DataContext="{d:DesignInstance vm:SelectBrowserViewModel}"
1113
Background="{DynamicResource PopuBGColor}"
12-
DataContext="{Binding RelativeSource={RelativeSource Self}}"
1314
Foreground="{DynamicResource PopupTextColor}"
1415
ResizeMode="NoResize"
1516
SizeToContent="Height"
@@ -97,11 +98,11 @@
9798
</ComboBox>
9899
<Button
99100
Margin="10 0 0 0"
100-
Click="btnAdd_Click"
101+
Command="{Binding AddCommand}"
101102
Content="{DynamicResource add}" />
102103
<Button
103104
Margin="10 0 0 0"
104-
Click="btnDelete_Click"
105+
Command="{Binding DeleteCommand}"
105106
Content="{DynamicResource delete}"
106107
IsEnabled="{Binding CustomBrowser.Editable}" />
107108

Flow.Launcher/SelectBrowserWindow.xaml.cs

Lines changed: 15 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,18 @@
1-
using System.Collections.ObjectModel;
2-
using System.Linq;
3-
using System.Windows;
1+
using System.Windows;
42
using System.Windows.Controls;
5-
using CommunityToolkit.Mvvm.ComponentModel;
6-
using Flow.Launcher.Infrastructure.UserSettings;
3+
using CommunityToolkit.Mvvm.DependencyInjection;
4+
using Flow.Launcher.ViewModel;
75

86
namespace Flow.Launcher
97
{
10-
[INotifyPropertyChanged]
118
public partial class SelectBrowserWindow : Window
129
{
13-
private readonly Settings _settings;
10+
private readonly SelectBrowserViewModel _viewModel;
1411

15-
private int selectedCustomBrowserIndex;
16-
17-
public int SelectedCustomBrowserIndex
18-
{
19-
get => selectedCustomBrowserIndex;
20-
set
21-
{
22-
selectedCustomBrowserIndex = value;
23-
OnPropertyChanged(nameof(CustomBrowser));
24-
}
25-
}
26-
public ObservableCollection<CustomBrowserViewModel> CustomBrowsers { get; set; }
27-
28-
public CustomBrowserViewModel CustomBrowser => CustomBrowsers[SelectedCustomBrowserIndex];
29-
public SelectBrowserWindow(Settings settings)
12+
public SelectBrowserWindow()
3013
{
31-
_settings = settings;
32-
CustomBrowsers = new ObservableCollection<CustomBrowserViewModel>(_settings.CustomBrowserList.Select(x => x.Copy()));
33-
SelectedCustomBrowserIndex = _settings.CustomBrowserIndex;
14+
_viewModel = Ioc.Default.GetRequiredService<SelectBrowserViewModel>();
15+
DataContext = _viewModel;
3416
InitializeComponent();
3517
}
3618

@@ -41,33 +23,20 @@ private void btnCancel_Click(object sender, RoutedEventArgs e)
4123

4224
private void btnDone_Click(object sender, RoutedEventArgs e)
4325
{
44-
_settings.CustomBrowserList = CustomBrowsers.ToList();
45-
_settings.CustomBrowserIndex = SelectedCustomBrowserIndex;
46-
Close();
47-
}
48-
49-
private void btnAdd_Click(object sender, RoutedEventArgs e)
50-
{
51-
CustomBrowsers.Add(new()
26+
if (_viewModel.SaveSettings())
5227
{
53-
Name = "New Profile"
54-
});
55-
SelectedCustomBrowserIndex = CustomBrowsers.Count - 1;
56-
}
57-
58-
private void btnDelete_Click(object sender, RoutedEventArgs e)
59-
{
60-
CustomBrowsers.RemoveAt(SelectedCustomBrowserIndex--);
28+
Close();
29+
}
6130
}
6231

6332
private void btnBrowseFile_Click(object sender, RoutedEventArgs e)
6433
{
65-
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
66-
var result = dlg.ShowDialog();
67-
if (result == true)
34+
var selectedFilePath = _viewModel.SelectFile();
35+
36+
if (!string.IsNullOrEmpty(selectedFilePath))
6837
{
69-
TextBox path = (TextBox)(((FrameworkElement)sender).Parent as FrameworkElement).FindName("PathTextBox");
70-
path.Text = dlg.FileName;
38+
var path = (TextBox)(((FrameworkElement)sender).Parent as FrameworkElement).FindName("PathTextBox");
39+
path.Text = selectedFilePath;
7140
path.Focus();
7241
((Button)sender).Focus();
7342
}

Flow.Launcher/SelectFileManagerWindow.xaml

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@
66
xmlns:local="clr-namespace:Flow.Launcher"
77
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
88
xmlns:ui="http://schemas.modernwpf.com/2019"
9+
xmlns:vm="clr-namespace:Flow.Launcher.ViewModel"
910
Title="{DynamicResource fileManagerWindow}"
1011
Width="600"
12+
d:DataContext="{d:DesignInstance vm:SelectFileManagerViewModel}"
1113
Background="{DynamicResource PopuBGColor}"
12-
DataContext="{Binding RelativeSource={RelativeSource Self}}"
1314
Foreground="{DynamicResource PopupTextColor}"
1415
ResizeMode="NoResize"
1516
SizeToContent="Height"
@@ -73,9 +74,17 @@
7374
<TextBlock Margin="0 14 0 0" FontSize="14">
7475
<TextBlock Text="{DynamicResource fileManager_tips2}" TextWrapping="WrapWithOverflow" />
7576
</TextBlock>
77+
<TextBlock Margin="0 14 0 0" VerticalAlignment="Center">
78+
<Hyperlink NavigateUri="https://www.flowlauncher.com/docs/#/filemanager" RequestNavigate="Hyperlink_RequestNavigate">
79+
<TextBlock FontSize="14" Text="{DynamicResource fileManager_learnMore}" />
80+
</Hyperlink>
81+
</TextBlock>
7682
</StackPanel>
77-
78-
<StackPanel Margin="14 28 0 0" Orientation="Horizontal">
83+
<Rectangle
84+
Height="1"
85+
Margin="0 20 0 20"
86+
Fill="{StaticResource SeparatorForeground}" />
87+
<StackPanel Margin="14 0 0 0" Orientation="Horizontal">
7988
<TextBlock
8089
Grid.Column="1"
8190
HorizontalAlignment="Left"
@@ -99,19 +108,19 @@
99108
</ComboBox>
100109
<Button
101110
Margin="10 0 0 0"
102-
Click="btnAdd_Click"
111+
Command="{Binding AddCommand}"
103112
Content="{DynamicResource add}" />
104113
<Button
105114
Margin="10 0 0 0"
106-
Click="btnDelete_Click"
115+
Command="{Binding DeleteCommand}"
107116
Content="{DynamicResource delete}"
108117
IsEnabled="{Binding CustomExplorer.Editable}" />
109118

110119
</StackPanel>
111120
<Rectangle
112121
Height="1"
113122
Margin="0 20 0 12"
114-
Fill="{StaticResource Color03B}" />
123+
Fill="{StaticResource SeparatorForeground}" />
115124
<StackPanel
116125
Margin="0 0 0 0"
117126
HorizontalAlignment="Stretch"

0 commit comments

Comments
 (0)