Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mac: Open/SaveFileDialog fixes #2738

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 44 additions & 71 deletions src/Eto.Mac/Forms/MacFileDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,56 +33,38 @@ public abstract class MacFileDialog<TControl, TWidget> : WidgetHandler<TControl,
where TWidget: FileDialog
{
List<string> macfilters;
readonly NSPopUpButton fileTypes;
readonly DropDown fileTypes;

protected MacFileDialog()
{
fileTypes = new NSPopUpButton();
fileTypes = new DropDown();
fileTypes.SelectedIndexChanged += (sender, e) => OnFileTypeChanged();
}

void Create()
{
if (Control.AccessoryView != null)
return;

var fileTypeView = new NSView();
fileTypeView.AutoresizingMask = NSViewResizingMask.HeightSizable | NSViewResizingMask.WidthSizable;

const int padding = 15;

if (Widget.Filters.Count > 0)
{
var label = new NSTextField();
label.StringValue = "Format";
label.DrawsBackground = false;
label.Bordered = false;
label.Bezeled = false;
label.Editable = false;
label.Selectable = false;
label.SizeToFit();
fileTypeView.AddSubview(label);

fileTypes.SizeToFit();
fileTypes.Activated += (sender, e) =>
{
SetCurrentItem();
Control.ValidateVisibleColumns();
Control.Update();
};
fileTypeView.AddSubview(fileTypes);
fileTypes.SetFrameOrigin(new CGPoint((nfloat)label.Frame.Width + 10, padding));

label.SetFrameOrigin(new CGPoint(0, (nfloat)(padding + (fileTypes.Frame.Height - label.Frame.Height) / 2)));

fileTypeView.Frame = new CGRect(0, 0, (nfloat)(fileTypes.Frame.Width + label.Frame.Width + 10), (nfloat)(fileTypes.Frame.Height + padding * 2));

Control.AccessoryView = fileTypeView;
SetCurrentItem();
if (Control.AccessoryView != null)
return;

var layout = new TableLayout { Padding = 15, Spacing = new Size(2, 2) };
layout.Rows.Add(new TableRow(null, fileTypes, null));

Control.AccessoryView = layout.ToNative(true);
SetAllowedFileTypes();
}
else
Control.AccessoryView = null;
}

protected virtual void OnFileTypeChanged()
{
SetAllowedFileTypes();
Control.ValidateVisibleColumns();
Control.Update();
}

string fileName;

public virtual string FileName
Expand All @@ -93,7 +75,7 @@ public virtual string FileName

public Uri Directory
{
get => new Uri(Control.DirectoryUrl.AbsoluteString);
get => (Uri)Control.DirectoryUrl;
set => Control.DirectoryUrl = new NSUrl(value.AbsoluteUri);
}

Expand All @@ -111,44 +93,38 @@ public string GetDefaultExtension()
return null;
}

public List<string> MacFilters
{
get { return macfilters; }
}
public List<string> MacFilters => macfilters;

public void SetCurrentItem()
internal void SetAllowedFileTypes()
{
macfilters = Widget.CurrentFilter.Extensions?.Select(r => r.TrimStart('*', '.')).ToList();

if (macfilters == null || macfilters.Count == 0 || macfilters.Contains(""))
var filters = Widget.CurrentFilter?.Extensions?.Select(r => r.TrimStart('*', '.')).ToList();
if (filters != null && (filters.Count == 0 || filters.Contains("")))
{
macfilters = null;
// MacOS throws exception when setting to null (ugh)
Messaging.void_objc_msgSend_IntPtr(Control.Handle, Selector.GetHandle("setAllowedFileTypes:"), IntPtr.Zero);
filters = null;
}
else
Control.AllowedFileTypes = macfilters.Distinct().ToArray();

if (macfilters == filters)
return;
macfilters = filters;

#if MACOS_NET
Control.AllowedContentTypes = macfilters.Distinct().Select(UniformTypeIdentifiers.UTType.CreateFromExtension).ToArray()
?? Array.Empty<UniformTypeIdentifiers.UTType>();
#else

Control.AllowedFileTypes = macfilters?.Distinct().ToArray();
#endif
}

public int CurrentFilterIndex
{
get
{
var title = fileTypes.TitleOfSelectedItem;
var item = Widget.Filters.FirstOrDefault(r => r.Name == title);
if (item == null)
return -1;
return Widget.Filters.IndexOf(item);
}
set
{
fileTypes.SelectItem(Widget.Filters[value].Name);
}
get => fileTypes.SelectedIndex;
set => fileTypes.SelectedIndex = value;
}

public bool CheckFileExists
{
get { return false; }
get { return true; }
set { }
}

Expand All @@ -172,24 +148,21 @@ public virtual DialogResult ShowDialog(Window parent)
return ret == 1 ? DialogResult.Ok : DialogResult.Cancel;
}

protected override void Dispose(bool disposing)
{
//base.Dispose (disposing);
}

public void InsertFilter(int index, FileFilter filter)
{
fileTypes.InsertItem(filter.Name, index);
fileTypes.Items.Insert(index, new ListItem { Text = filter.Name } );
if (fileTypes.SelectedIndex == -1)
fileTypes.SelectedIndex = index;
}

public void RemoveFilter(int index)
{
fileTypes.RemoveItem(index);
fileTypes.Items.RemoveAt(index);
}

public void ClearFilters()
{
fileTypes.RemoveAllItems();
fileTypes.Items.Clear();
}
}
}
2 changes: 0 additions & 2 deletions src/Eto.Mac/Forms/OpenFileDialogHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ protected override NSOpenPanel CreateControl()
return NSOpenPanel.OpenPanel;
}

protected override bool DisposeControl { get { return false; } }

public bool MultiSelect
{
get { return Control.AllowsMultipleSelection; }
Expand Down
11 changes: 7 additions & 4 deletions src/Eto.Mac/Forms/OpenWithDialogHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ public class OpenWithDialogHandler : WidgetHandler<NSOpenPanel, OpenWithDialog,

public DialogResult ShowDialog(Window parent)
{
Control = new NSOpenPanel();
Control.ReleasedWhenClosed = true;
Control.DirectoryUrl = new NSUrl("/Applications");
Control.Prompt = "Choose Application";
Control = NSOpenPanel.OpenPanel;
Control.DirectoryUrl = NSUrl.FromFilename("/Applications");
Control.Prompt = Application.Instance.Localize(Widget, "Choose Application");
#if MACOS_NET
Control.AllowedContentTypes = new [] { UniformTypeIdentifiers.UTTypes.Application };
#else
Control.AllowedFileTypes = new[] { "app" };
#endif

if (Control.RunModal() == 1)
Process.Start("open", "-a \"" + Control.Url.Path + "\" \"" + FilePath + "\"");
Expand Down
16 changes: 14 additions & 2 deletions src/Eto.Mac/Forms/SaveFileDialogHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public override string FileName
var name = value;
if (!string.IsNullOrEmpty(name))
{
SetAllowedFileTypes();
var dir = Path.GetDirectoryName(name);
if (!string.IsNullOrEmpty(dir) && System.IO.Directory.Exists(dir))
Directory = new Uri(dir);
Expand All @@ -25,15 +26,14 @@ public override string FileName
}
}

protected override bool DisposeControl { get { return false; } }

protected override NSSavePanel CreateControl()
{
return NSSavePanel.SavePanel;
}

protected override void Initialize()
{
Control.ExtensionHidden = false;
Control.AllowsOtherFileTypes = true;
Control.CanSelectHiddenExtension = true;
base.Initialize();
Expand All @@ -50,5 +50,17 @@ public override DialogResult ShowDialog(Window parent)

return result;
}

protected override void OnFileTypeChanged()
{
base.OnFileTypeChanged();
var extension = Widget.CurrentFilter?.Extensions?.FirstOrDefault()?.TrimStart('*', '.');
if (!string.IsNullOrEmpty(extension))
{
var fileName = Control.NameFieldStringValue;
if (fileName != null)
Control.NameFieldStringValue = $"{Path.GetFileNameWithoutExtension(fileName)}.{extension}";
}
}
}
}
27 changes: 10 additions & 17 deletions test/Eto.Test/Sections/Dialogs/FileDialogSection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,12 @@ Control OpenFileWithFilters()
{
Filters =
{
new FileFilter("All Formats", "png", "jpg", "jpeg", "gif", "tiff"),
new FileFilter("All Formats", ".png", ".jpg", ".jpeg", ".gif", ".tiff"),
new FileFilter("All Files", "*"),
"PNG Files|png",
new FileFilter("JPeg Files", "jpg", "jpeg"),
new FileFilter("GIF Files", "gif"),
new FileFilter("TIFF Files", "tiff"),
"PNG Files|.png",
new FileFilter("JPeg Files", ".jpg", ".jpeg"),
new FileFilter("GIF Files", ".gif"),
new FileFilter("TIFF Files", ".tiff"),
}
};
SetAttributes(dialog);
Expand All @@ -135,17 +135,14 @@ Control SaveFileWithFilters()
new FileFilter("JPeg Files", ".jpg", ".jpeg"),
new FileFilter("GIF Files", ".gif"),
new FileFilter("TIFF Files", ".tiff"),
new FileFilter("CS Files", ".cs"),
}
};
SetAttributes(dialog);

var result = dialog.ShowDialog(ParentWindow);
if (result == DialogResult.Ok)
{
Log.Write(dialog, "Result: {0}, CurrentFilter: {1}, FileName: {2}", result, dialog.CurrentFilter, dialog.FileName);
}
else
Log.Write(dialog, "Result: {0}", result);
Log.Write(dialog, "Result: {0}, CurrentFilter: {1}, FileName: {2}", result, dialog.CurrentFilter, dialog.FileName);
dialog.Dispose();
};
return button;
}
Expand All @@ -158,12 +155,8 @@ Control SaveFile()
var dialog = new SaveFileDialog();
SetAttributes(dialog);
var result = dialog.ShowDialog(ParentWindow);
if (result == DialogResult.Ok)
{
Log.Write(dialog, "Result: {0}, FileName: {1}", result, dialog.FileName);
}
else
Log.Write(dialog, "Result: {0}", result);
Log.Write(dialog, "Result: {0}, FileName: {1}", result, dialog.FileName);
dialog.Dispose();
};
return button;
}
Expand Down
Loading