Browse Source

Add Support for Overwrite Prompt option in save dialog (#7531)

Add support for overwrite prompt option
pull/7548/head
Emmanuel Hansen 4 years ago
committed by GitHub
parent
commit
ecb0de2c32
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      src/Avalonia.Controls/SystemDialog.cs
  2. 14
      src/Avalonia.Dialogs/ManagedFileChooserViewModel.cs
  3. 70
      src/Avalonia.Dialogs/ManagedFileDialogExtensions.cs
  4. 3
      src/Avalonia.X11/NativeDialogs/Gtk.cs
  5. 8
      src/Avalonia.X11/NativeDialogs/GtkNativeFileDialogs.cs
  6. 10
      src/Windows/Avalonia.Win32/SystemDialogImpl.cs

5
src/Avalonia.Controls/SystemDialog.cs

@ -52,6 +52,11 @@ namespace Avalonia.Controls
/// </summary>
public string? DefaultExtension { get; set; }
/// <summary>
/// Gets or sets a value indicating whether to display a warning if the user specifies the name of a file that already exists.
/// </summary>
public bool? ShowOverwritePrompt { get; set; }
/// <summary>
/// Shows the save file dialog.
/// </summary>

14
src/Avalonia.Dialogs/ManagedFileChooserViewModel.cs

@ -17,6 +17,7 @@ namespace Avalonia.Dialogs
private readonly ManagedFileDialogOptions _options;
public event Action CancelRequested;
public event Action<string[]> CompleteRequested;
public event Action<string> OverwritePrompt;
public AvaloniaList<ManagedFileChooserItemViewModel> QuickLinks { get; } =
new AvaloniaList<ManagedFileChooserItemViewModel>();
@ -39,6 +40,7 @@ namespace Avalonia.Dialogs
private bool _scheduledSelectionValidation;
private bool _alreadyCancelled = false;
private string _defaultExtension;
private bool _overwritePrompt;
private CompositeDisposable _disposables;
public string Location
@ -167,6 +169,7 @@ namespace Avalonia.Dialogs
{
_savingFile = true;
_defaultExtension = sfd.DefaultExtension;
_overwritePrompt = sfd.ShowOverwritePrompt ?? true;
FileName = sfd.InitialFileName;
}
@ -360,7 +363,16 @@ namespace Avalonia.Dialogs
FileName = Path.ChangeExtension(FileName, _defaultExtension);
}
CompleteRequested?.Invoke(new[] { Path.Combine(Location, FileName) });
var fullName = Path.Combine(Location, FileName);
if (_overwritePrompt && File.Exists(fullName))
{
OverwritePrompt?.Invoke(fullName);
}
else
{
CompleteRequested?.Invoke(new[] { fullName });
}
}
}
else

70
src/Avalonia.Dialogs/ManagedFileDialogExtensions.cs

@ -1,3 +1,4 @@
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Avalonia.Controls;
@ -31,6 +32,75 @@ namespace Avalonia.Dialogs
dialog.Close();
};
model.OverwritePrompt += async (filename) =>
{
Window overwritePromptDialog = new Window()
{
Title = "Confirm Save As",
SizeToContent = SizeToContent.WidthAndHeight,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
Padding = new Thickness(10),
MinWidth = 270
};
string name = Path.GetFileName(filename);
var panel = new DockPanel()
{
HorizontalAlignment = Layout.HorizontalAlignment.Stretch
};
var label = new Label()
{
Content = $"{name} already exists.\nDo you want to replace it?"
};
panel.Children.Add(label);
DockPanel.SetDock(label, Dock.Top);
var buttonPanel = new StackPanel()
{
HorizontalAlignment = Layout.HorizontalAlignment.Right,
Orientation = Layout.Orientation.Horizontal,
Spacing = 10
};
var button = new Button()
{
Content = "Yes",
HorizontalAlignment = Layout.HorizontalAlignment.Right
};
button.Click += (sender, args) =>
{
result = new string[1] { filename };
overwritePromptDialog.Close();
dialog.Close();
};
buttonPanel.Children.Add(button);
button = new Button()
{
Content = "No",
HorizontalAlignment = Layout.HorizontalAlignment.Right
};
button.Click += (sender, args) =>
{
overwritePromptDialog.Close();
};
buttonPanel.Children.Add(button);
panel.Children.Add(buttonPanel);
DockPanel.SetDock(buttonPanel, Dock.Bottom);
overwritePromptDialog.Content = panel;
await overwritePromptDialog.ShowDialog(dialog);
};
model.CancelRequested += dialog.Close;
await dialog.ShowDialog<object>(parent);

3
src/Avalonia.X11/NativeDialogs/Gtk.cs

@ -179,6 +179,9 @@ namespace Avalonia.X11.NativeDialogs
[DllImport(GtkName)]
public static extern void gtk_file_chooser_set_select_multiple(IntPtr chooser, bool allow);
[DllImport(GtkName)]
public static extern void gtk_file_chooser_set_do_overwrite_confirmation(IntPtr chooser, bool do_overwrite_confirmation);
[DllImport(GtkName)]
public static extern void

8
src/Avalonia.X11/NativeDialogs/GtkNativeFileDialogs.cs

@ -16,7 +16,7 @@ namespace Avalonia.X11.NativeDialogs
{
private Task<bool> _initialized;
private unsafe Task<string[]> ShowDialog(string title, IWindowImpl parent, GtkFileChooserAction action,
bool multiSelect, string initialFileName, IEnumerable<FileDialogFilter> filters, string defaultExtension)
bool multiSelect, string initialFileName, IEnumerable<FileDialogFilter> filters, string defaultExtension, bool overwritePrompt)
{
IntPtr dlg;
using (var name = new Utf8Buffer(title))
@ -109,6 +109,8 @@ namespace Avalonia.X11.NativeDialogs
gtk_file_chooser_set_filename(dlg, fn);
}
gtk_file_chooser_set_do_overwrite_confirmation(dlg, overwritePrompt);
gtk_window_present(dlg);
return tcs.Task;
}
@ -148,7 +150,7 @@ namespace Avalonia.X11.NativeDialogs
(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)?.DefaultExtension, (dialog as SaveFileDialog)?.ShowOverwritePrompt ?? false));
}
public async Task<string> ShowFolderDialogAsync(OpenFolderDialog dialog, Window parent)
@ -160,7 +162,7 @@ namespace Avalonia.X11.NativeDialogs
return await await RunOnGlibThread(async () =>
{
var res = await ShowDialog(dialog.Title, platformImpl,
GtkFileChooserAction.SelectFolder, false, dialog.Directory, null, null);
GtkFileChooserAction.SelectFolder, false, dialog.Directory, null, null, false);
return res?.FirstOrDefault();
});
}

10
src/Windows/Avalonia.Win32/SystemDialogImpl.cs

@ -40,6 +40,16 @@ namespace Avalonia.Win32
{
options |= FILEOPENDIALOGOPTIONS.FOS_ALLOWMULTISELECT;
}
if (dialog is SaveFileDialog saveFileDialog)
{
var overwritePrompt = saveFileDialog.ShowOverwritePrompt ?? true;
if (!overwritePrompt)
{
options &= ~FILEOPENDIALOGOPTIONS.FOS_OVERWRITEPROMPT;
}
}
frm.SetOptions(options);
var defaultExtension = (dialog as SaveFileDialog)?.DefaultExtension ?? "";

Loading…
Cancel
Save