From 1d612a12a1960f2f0c539faa68fae7523f583f25 Mon Sep 17 00:00:00 2001 From: Tan Wang Leng Date: Wed, 1 Feb 2017 23:34:21 +0800 Subject: [PATCH] :apple: Add additional options for Mac's save dialog Support additional attributes available in macOS's NSSavePanel: message, nameFieldLabel and showsTagField --- atom/browser/api/atom_api_dialog.cc | 9 ++++-- .../browser/atom_download_manager_delegate.cc | 1 + atom/browser/common_web_contents_delegate.cc | 2 +- atom/browser/ui/file_dialog.h | 6 ++++ atom/browser/ui/file_dialog_gtk.cc | 3 ++ atom/browser/ui/file_dialog_mac.mm | 31 ++++++++++++++++--- atom/browser/ui/file_dialog_win.cc | 6 ++++ atom/browser/web_dialog_helper.cc | 3 ++ lib/browser/api/dialog.js | 20 +++++++++++- 9 files changed, 72 insertions(+), 9 deletions(-) diff --git a/atom/browser/api/atom_api_dialog.cc b/atom/browser/api/atom_api_dialog.cc index 5d853e2d5900..1efb78d72d24 100644 --- a/atom/browser/api/atom_api_dialog.cc +++ b/atom/browser/api/atom_api_dialog.cc @@ -92,6 +92,9 @@ void ShowSaveDialog(const std::string& title, const std::string& button_label, const base::FilePath& default_path, const file_dialog::Filters& filters, + const std::string& message, + const std::string& name_field_label, + const bool& shows_tag_field, atom::NativeWindow* window, mate::Arguments* args) { v8::Local peek = args->PeekNext(); @@ -100,11 +103,13 @@ void ShowSaveDialog(const std::string& title, peek, &callback)) { file_dialog::ShowSaveDialog(window, title, button_label, default_path, - filters, callback); + filters, message, name_field_label, + shows_tag_field, callback); } else { base::FilePath path; if (file_dialog::ShowSaveDialog(window, title, button_label, default_path, - filters, &path)) + filters, message, name_field_label, + shows_tag_field, &path)) args->Return(path); } } diff --git a/atom/browser/atom_download_manager_delegate.cc b/atom/browser/atom_download_manager_delegate.cc index 0213216697a1..b92e3e18bc7d 100644 --- a/atom/browser/atom_download_manager_delegate.cc +++ b/atom/browser/atom_download_manager_delegate.cc @@ -93,6 +93,7 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated( if (path.empty() && file_dialog::ShowSaveDialog(window, item->GetURL().spec(), "", default_path, file_dialog::Filters(), + "", "", false, &path)) { // Remember the last selected download directory. AtomBrowserContext* browser_context = static_cast( diff --git a/atom/browser/common_web_contents_delegate.cc b/atom/browser/common_web_contents_delegate.cc index ed0fd5e4ba38..c3cca231c31c 100644 --- a/atom/browser/common_web_contents_delegate.cc +++ b/atom/browser/common_web_contents_delegate.cc @@ -297,7 +297,7 @@ void CommonWebContentsDelegate::DevToolsSaveToFile( file_dialog::Filters filters; base::FilePath default_path(base::FilePath::FromUTF8Unsafe(url)); if (!file_dialog::ShowSaveDialog(owner_window(), url, "", default_path, - filters, &path)) { + filters, "", "", false, &path)) { base::StringValue url_value(url); web_contents_->CallClientFunction( "DevToolsAPI.canceledSaveURL", &url_value, nullptr, nullptr); diff --git a/atom/browser/ui/file_dialog.h b/atom/browser/ui/file_dialog.h index a8703bebf8d8..8b2d7f0d99e3 100644 --- a/atom/browser/ui/file_dialog.h +++ b/atom/browser/ui/file_dialog.h @@ -58,6 +58,9 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window, const std::string& button_label, const base::FilePath& default_path, const Filters& filters, + const std::string& message, + const std::string& name_field_label, + const bool& shows_tag_field, base::FilePath* path); void ShowSaveDialog(atom::NativeWindow* parent_window, @@ -65,6 +68,9 @@ void ShowSaveDialog(atom::NativeWindow* parent_window, const std::string& button_label, const base::FilePath& default_path, const Filters& filters, + const std::string& message, + const std::string& name_field_label, + const bool& shows_tag_field, const SaveDialogCallback& callback); } // namespace file_dialog diff --git a/atom/browser/ui/file_dialog_gtk.cc b/atom/browser/ui/file_dialog_gtk.cc index 18f53eba6fbe..c39281d8f6e0 100644 --- a/atom/browser/ui/file_dialog_gtk.cc +++ b/atom/browser/ui/file_dialog_gtk.cc @@ -275,6 +275,9 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window, const std::string& button_label, const base::FilePath& default_path, const Filters& filters, + const std::string& message, + const std::string& name_field_label, + const bool& shows_tag_field, base::FilePath* path) { FileChooserDialog save_dialog(GTK_FILE_CHOOSER_ACTION_SAVE, parent_window, title, button_label, default_path, filters); diff --git a/atom/browser/ui/file_dialog_mac.mm b/atom/browser/ui/file_dialog_mac.mm index 9492fe90ee1a..ee07d2af0041 100644 --- a/atom/browser/ui/file_dialog_mac.mm +++ b/atom/browser/ui/file_dialog_mac.mm @@ -47,13 +47,24 @@ void SetupDialog(NSSavePanel* dialog, const std::string& title, const std::string& button_label, const base::FilePath& default_path, - const Filters& filters) { + const Filters& filters, + const std::string& message, + const std::string& name_field_label, + const bool& shows_tag_field) { if (!title.empty()) [dialog setTitle:base::SysUTF8ToNSString(title)]; if (!button_label.empty()) [dialog setPrompt:base::SysUTF8ToNSString(button_label)]; + if (!message.empty()) + [dialog setMessage:base::SysUTF8ToNSString(message)]; + + if (!name_field_label.empty()) + [dialog setNameFieldLabel:base::SysUTF8ToNSString(name_field_label)]; + + [dialog setShowsTagField:shows_tag_field]; + NSString* default_dir = nil; NSString* default_filename = nil; if (!default_path.empty()) { @@ -127,7 +138,8 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window, DCHECK(paths); NSOpenPanel* dialog = [NSOpenPanel openPanel]; - SetupDialog(dialog, title, button_label, default_path, filters); +// TODO yamgent: Fix this + SetupDialog(dialog, title, button_label, default_path, filters, "", "", false); SetupDialogForProperties(dialog, properties); int chosen = RunModalDialog(dialog, parent_window); @@ -147,7 +159,8 @@ void ShowOpenDialog(atom::NativeWindow* parent_window, const OpenDialogCallback& c) { NSOpenPanel* dialog = [NSOpenPanel openPanel]; - SetupDialog(dialog, title, button_label, default_path, filters); +// TODO yamgent: Fix this + SetupDialog(dialog, title, button_label, default_path, filters, "", "", false); SetupDialogForProperties(dialog, properties); // Duplicate the callback object here since c is a reference and gcd would @@ -172,11 +185,15 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window, const std::string& button_label, const base::FilePath& default_path, const Filters& filters, + const std::string& message, + const std::string& name_field_label, + const bool& shows_tag_field, base::FilePath* path) { DCHECK(path); NSSavePanel* dialog = [NSSavePanel savePanel]; - SetupDialog(dialog, title, button_label, default_path, filters); + SetupDialog(dialog, title, button_label, default_path, filters, message, + name_field_label, shows_tag_field); int chosen = RunModalDialog(dialog, parent_window); if (chosen == NSFileHandlingPanelCancelButton || ![[dialog URL] isFileURL]) @@ -191,10 +208,14 @@ void ShowSaveDialog(atom::NativeWindow* parent_window, const std::string& button_label, const base::FilePath& default_path, const Filters& filters, + const std::string& message, + const std::string& name_field_label, + const bool& shows_tag_field, const SaveDialogCallback& c) { NSSavePanel* dialog = [NSSavePanel savePanel]; - SetupDialog(dialog, title, button_label, default_path, filters); + SetupDialog(dialog, title, button_label, default_path, filters, message, + name_field_label, shows_tag_field); [dialog setCanSelectHiddenExtension:YES]; __block SaveDialogCallback callback = c; diff --git a/atom/browser/ui/file_dialog_win.cc b/atom/browser/ui/file_dialog_win.cc index 8e973432f5af..2c8017562488 100644 --- a/atom/browser/ui/file_dialog_win.cc +++ b/atom/browser/ui/file_dialog_win.cc @@ -268,6 +268,9 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window, const std::string& button_label, const base::FilePath& default_path, const Filters& filters, + const std::string& message, + const std::string& name_field_label, + const bool& shows_tag_field, base::FilePath* path) { FileDialog save_dialog( default_path, title, button_label, filters, @@ -289,6 +292,9 @@ void ShowSaveDialog(atom::NativeWindow* parent, const std::string& button_label, const base::FilePath& default_path, const Filters& filters, + const std::string& message, + const std::string& name_field_label, + const bool& shows_tag_field, const SaveDialogCallback& callback) { RunState run_state; if (!CreateDialogThread(&run_state)) { diff --git a/atom/browser/web_dialog_helper.cc b/atom/browser/web_dialog_helper.cc index e3942f1f717d..e5bd46672fd8 100644 --- a/atom/browser/web_dialog_helper.cc +++ b/atom/browser/web_dialog_helper.cc @@ -90,6 +90,9 @@ void WebDialogHelper::RunFileChooser( "", params.default_file_name, filters, + "", + "", + false, &path)) { content::FileChooserFileInfo info; info.file_path = path; diff --git a/lib/browser/api/dialog.js b/lib/browser/api/dialog.js index 85572b3b4fba..4088431c1518 100644 --- a/lib/browser/api/dialog.js +++ b/lib/browser/api/dialog.js @@ -136,7 +136,8 @@ module.exports = { } } - let {buttonLabel, defaultPath, filters, title} = options + let {buttonLabel, defaultPath, filters, title, message, nameFieldLabel, + showsTagField} = options if (title == null) { title = '' @@ -160,10 +161,27 @@ module.exports = { filters = [] } + if (message == null) { + message = '' + } else if (typeof message !== 'string') { + throw new TypeError('Message must be a string') + } + + if (nameFieldLabel == null) { + nameFieldLabel = '' + } else if (typeof nameFieldLabel !== 'string') { + throw new TypeError('Name field label must be a string') + } + + if (showsTagField == null) { + showsTagField = false + } + const wrappedCallback = typeof callback === 'function' ? function (success, result) { return callback(success ? result : void 0) } : null return binding.showSaveDialog(title, buttonLabel, defaultPath, filters, + message, nameFieldLabel, showsTagField, window, wrappedCallback) },