From 38e2ab818a5b68becab6be93b9259e07bc9ddaa7 Mon Sep 17 00:00:00 2001 From: Luthfi Tri Atmaja Date: Wed, 16 Feb 2022 13:09:49 +0700 Subject: [PATCH 01/24] introduce gtk_file_chooser_set_current_folder --- src/Avalonia.X11/NativeDialogs/Gtk.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Avalonia.X11/NativeDialogs/Gtk.cs b/src/Avalonia.X11/NativeDialogs/Gtk.cs index a0f146afa8..73e6a2d6a4 100644 --- a/src/Avalonia.X11/NativeDialogs/Gtk.cs +++ b/src/Avalonia.X11/NativeDialogs/Gtk.cs @@ -195,7 +195,10 @@ namespace Avalonia.X11.NativeDialogs [DllImport(GtkName)] public static extern void gtk_file_chooser_set_current_name(IntPtr chooser, Utf8Buffer file); - + + [DllImport(GtkName)] + public static extern void gtk_file_chooser_set_current_folder(IntPtr chooser, Utf8Buffer file); + [DllImport(GtkName)] public static extern IntPtr gtk_file_filter_new(); From 1888ab9fe5388d8058dbac6e91aaf242e2509621 Mon Sep 17 00:00:00 2001 From: Luthfi Tri Atmaja Date: Wed, 16 Feb 2022 13:28:06 +0700 Subject: [PATCH 02/24] navigate to initial directory --- .../NativeDialogs/GtkNativeFileDialogs.cs | 66 +++++++++++++------ 1 file changed, 46 insertions(+), 20 deletions(-) diff --git a/src/Avalonia.X11/NativeDialogs/GtkNativeFileDialogs.cs b/src/Avalonia.X11/NativeDialogs/GtkNativeFileDialogs.cs index 1a6514eb03..9539f024b7 100644 --- a/src/Avalonia.X11/NativeDialogs/GtkNativeFileDialogs.cs +++ b/src/Avalonia.X11/NativeDialogs/GtkNativeFileDialogs.cs @@ -15,8 +15,9 @@ namespace Avalonia.X11.NativeDialogs class GtkSystemDialog : ISystemDialogImpl { private Task _initialized; - private unsafe Task ShowDialog(string title, IWindowImpl parent, GtkFileChooserAction action, - bool multiSelect, string initialFileName, IEnumerable filters, string defaultExtension, bool overwritePrompt) + + private unsafe Task ShowDialog(string title, IWindowImpl parent, GtkFileChooserAction action, + bool multiSelect, string initialDirectory, string initialFileName, IEnumerable filters, string defaultExtension, bool overwritePrompt) { IntPtr dlg; using (var name = new Utf8Buffer(title)) @@ -44,7 +45,7 @@ namespace Avalonia.X11.NativeDialogs filtersDic[filter] = f; using (var b = new Utf8Buffer(f.Name)) gtk_file_filter_set_name(filter, b); - + foreach (var e in f.Extensions) using (var b = new Utf8Buffer("*." + e)) gtk_file_filter_add_pattern(filter, b); @@ -100,17 +101,32 @@ namespace Avalonia.X11.NativeDialogs gtk_dialog_add_button(dlg, open, GtkResponseType.Accept); using (var open = new Utf8Buffer("Cancel")) gtk_dialog_add_button(dlg, open, GtkResponseType.Cancel); + + if (initialDirectory != null) + { + using var dir = new Utf8Buffer(initialDirectory); + gtk_file_chooser_set_current_folder(dlg, dir); + } + if (initialFileName != null) - using (var fn = new Utf8Buffer(initialFileName)) + { + // gtk_file_chooser_set_filename() expects full path + using var fn = action == GtkFileChooserAction.Open + ? new Utf8Buffer(Path.Combine(initialDirectory ?? "", initialFileName)) + : new Utf8Buffer(initialFileName); + + if (action == GtkFileChooserAction.Save) { - if (action == GtkFileChooserAction.Save) - gtk_file_chooser_set_current_name(dlg, fn); - else - gtk_file_chooser_set_filename(dlg, fn); + gtk_file_chooser_set_current_name(dlg, fn); } + else + { + gtk_file_chooser_set_filename(dlg, fn); + } + } gtk_file_chooser_set_do_overwrite_confirmation(dlg, overwritePrompt); - + gtk_window_present(dlg); return tcs.Task; } @@ -144,13 +160,15 @@ namespace Avalonia.X11.NativeDialogs var platformImpl = parent?.PlatformImpl; - return await await RunOnGlibThread( - () => ShowDialog(dialog.Title, platformImpl, - dialog is OpenFileDialog ? GtkFileChooserAction.Open : GtkFileChooserAction.Save, - (dialog as OpenFileDialog)?.AllowMultiple ?? false, - Path.Combine(string.IsNullOrEmpty(dialog.Directory) ? "" : dialog.Directory, - string.IsNullOrEmpty(dialog.InitialFileName) ? "" : dialog.InitialFileName), dialog.Filters, - (dialog as SaveFileDialog)?.DefaultExtension, (dialog as SaveFileDialog)?.ShowOverwritePrompt ?? false)); + return await await RunOnGlibThread(() => ShowDialog( + dialog.Title, platformImpl, + dialog is OpenFileDialog ? GtkFileChooserAction.Open : GtkFileChooserAction.Save, + (dialog as OpenFileDialog)?.AllowMultiple ?? false, + dialog.Directory, + dialog.InitialFileName, + dialog.Filters, + (dialog as SaveFileDialog)?.DefaultExtension, + (dialog as SaveFileDialog)?.ShowOverwritePrompt ?? false)); } public async Task ShowFolderDialogAsync(OpenFolderDialog dialog, Window parent) @@ -161,12 +179,20 @@ namespace Avalonia.X11.NativeDialogs return await await RunOnGlibThread(async () => { - var res = await ShowDialog(dialog.Title, platformImpl, - GtkFileChooserAction.SelectFolder, false, dialog.Directory, null, null, false); + var res = await ShowDialog( + dialog.Title, + platformImpl,GtkFileChooserAction.SelectFolder, + false, + dialog.Directory, + null, + null, + null, + false); + return res?.FirstOrDefault(); }); } - + async Task EnsureInitialized() { if (_initialized == null) _initialized = StartGtk(); @@ -174,7 +200,7 @@ namespace Avalonia.X11.NativeDialogs if (!(await _initialized)) throw new Exception("Unable to initialize GTK on separate thread"); } - + void UpdateParent(IntPtr chooser, IWindowImpl parentWindow) { var xid = parentWindow.Handle.Handle; From eefe009a810473abb0b0d4699ff8d01b9fc041a6 Mon Sep 17 00:00:00 2001 From: Luthfi Tri Atmaja Date: Wed, 16 Feb 2022 13:38:48 +0700 Subject: [PATCH 03/24] update dialogs sample page --- .../ControlCatalog/Pages/DialogsPage.xaml.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/samples/ControlCatalog/Pages/DialogsPage.xaml.cs b/samples/ControlCatalog/Pages/DialogsPage.xaml.cs index e96b7aff08..a7af9c5cb7 100644 --- a/samples/ControlCatalog/Pages/DialogsPage.xaml.cs +++ b/samples/ControlCatalog/Pages/DialogsPage.xaml.cs @@ -42,13 +42,17 @@ namespace ControlCatalog.Pages this.FindControl