diff --git a/atom/browser/api/atom_api_dialog.cc b/atom/browser/api/atom_api_dialog.cc index 0a544c5646..5d853e2d59 100644 --- a/atom/browser/api/atom_api_dialog.cc +++ b/atom/browser/api/atom_api_dialog.cc @@ -67,6 +67,7 @@ void ShowMessageBox(int type, } void ShowOpenDialog(const std::string& title, + const std::string& button_label, const base::FilePath& default_path, const file_dialog::Filters& filters, int properties, @@ -77,17 +78,18 @@ void ShowOpenDialog(const std::string& title, if (mate::Converter::FromV8(args->isolate(), peek, &callback)) { - file_dialog::ShowOpenDialog(window, title, default_path, filters, - properties, callback); + file_dialog::ShowOpenDialog(window, title, button_label, default_path, + filters, properties, callback); } else { std::vector paths; - if (file_dialog::ShowOpenDialog(window, title, default_path, filters, - properties, &paths)) + if (file_dialog::ShowOpenDialog(window, title, button_label, default_path, + filters, properties, &paths)) args->Return(paths); } } void ShowSaveDialog(const std::string& title, + const std::string& button_label, const base::FilePath& default_path, const file_dialog::Filters& filters, atom::NativeWindow* window, @@ -97,11 +99,12 @@ void ShowSaveDialog(const std::string& title, if (mate::Converter::FromV8(args->isolate(), peek, &callback)) { - file_dialog::ShowSaveDialog(window, title, default_path, filters, callback); + file_dialog::ShowSaveDialog(window, title, button_label, default_path, + filters, callback); } else { base::FilePath path; - if (file_dialog::ShowSaveDialog(window, title, default_path, filters, - &path)) + if (file_dialog::ShowSaveDialog(window, title, button_label, default_path, + filters, &path)) args->Return(path); } } diff --git a/atom/browser/atom_download_manager_delegate.cc b/atom/browser/atom_download_manager_delegate.cc index bf09a40595..05e6899301 100644 --- a/atom/browser/atom_download_manager_delegate.cc +++ b/atom/browser/atom_download_manager_delegate.cc @@ -77,7 +77,8 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated( window = relay->window.get(); base::FilePath path; - if (file_dialog::ShowSaveDialog(window, item->GetURL().spec(), default_path, + if (file_dialog::ShowSaveDialog(window, item->GetURL().spec(), + "Save", default_path, file_dialog::Filters(), &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 da3647bc90..b36566383b 100644 --- a/atom/browser/common_web_contents_delegate.cc +++ b/atom/browser/common_web_contents_delegate.cc @@ -389,7 +389,7 @@ void CommonWebContentsDelegate::DevToolsSaveToFile( } else { file_dialog::Filters filters; base::FilePath default_path(base::FilePath::FromUTF8Unsafe(url)); - if (!file_dialog::ShowSaveDialog(owner_window(), url, default_path, + if (!file_dialog::ShowSaveDialog(owner_window(), url, "Save", default_path, filters, &path)) { base::StringValue url_value(url); web_contents_->CallClientFunction( @@ -455,7 +455,7 @@ void CommonWebContentsDelegate::DevToolsAddFileSystem( base::FilePath default_path; std::vector paths; int flag = file_dialog::FILE_DIALOG_OPEN_DIRECTORY; - if (!file_dialog::ShowOpenDialog(owner_window(), "", default_path, + if (!file_dialog::ShowOpenDialog(owner_window(), "", "Open", default_path, filters, flag, &paths)) return; diff --git a/atom/browser/ui/file_dialog.h b/atom/browser/ui/file_dialog.h index 51d7f5ee9d..b857648161 100644 --- a/atom/browser/ui/file_dialog.h +++ b/atom/browser/ui/file_dialog.h @@ -37,6 +37,7 @@ typedef base::Callback* paths) { bool ShowOpenDialog(atom::NativeWindow* parent_window, const std::string& title, + const std::string& button_label, const base::FilePath& default_path, const Filters& filters, int properties, @@ -121,7 +126,7 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window, DCHECK(paths); NSOpenPanel* dialog = [NSOpenPanel openPanel]; - SetupDialog(dialog, title, default_path, filters); + SetupDialog(dialog, title, button_label, default_path, filters); SetupDialogForProperties(dialog, properties); int chosen = RunModalDialog(dialog, parent_window); @@ -134,13 +139,14 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window, void ShowOpenDialog(atom::NativeWindow* parent_window, const std::string& title, + const std::string& button_label, const base::FilePath& default_path, const Filters& filters, int properties, const OpenDialogCallback& c) { NSOpenPanel* dialog = [NSOpenPanel openPanel]; - SetupDialog(dialog, title, default_path, filters); + SetupDialog(dialog, title, button_label, default_path, filters); SetupDialogForProperties(dialog, properties); // Duplicate the callback object here since c is a reference and gcd would @@ -162,13 +168,14 @@ void ShowOpenDialog(atom::NativeWindow* parent_window, bool ShowSaveDialog(atom::NativeWindow* parent_window, const std::string& title, + const std::string& button_label, const base::FilePath& default_path, const Filters& filters, base::FilePath* path) { DCHECK(path); NSSavePanel* dialog = [NSSavePanel savePanel]; - SetupDialog(dialog, title, default_path, filters); + SetupDialog(dialog, title, button_label, default_path, filters); int chosen = RunModalDialog(dialog, parent_window); if (chosen == NSFileHandlingPanelCancelButton || ![[dialog URL] isFileURL]) @@ -180,12 +187,13 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window, void ShowSaveDialog(atom::NativeWindow* parent_window, const std::string& title, + const std::string& button_label, const base::FilePath& default_path, const Filters& filters, const SaveDialogCallback& c) { NSSavePanel* dialog = [NSSavePanel savePanel]; - SetupDialog(dialog, title, default_path, filters); + SetupDialog(dialog, title, button_label, default_path, filters); __block SaveDialogCallback callback = c; diff --git a/atom/browser/ui/file_dialog_win.cc b/atom/browser/ui/file_dialog_win.cc index 6577e4c084..c5d81c3310 100644 --- a/atom/browser/ui/file_dialog_win.cc +++ b/atom/browser/ui/file_dialog_win.cc @@ -63,7 +63,9 @@ void ConvertFilters(const Filters& filters, template class FileDialog { public: - FileDialog(const base::FilePath& default_path, const std::string& title, + FileDialog(const base::FilePath& default_path, + const std::string& title, + const std::string& button_label, const Filters& filters, int options) { std::wstring file_part; if (!IsDirectory(default_path)) @@ -79,6 +81,9 @@ class FileDialog { if (!title.empty()) GetPtr()->SetTitle(base::UTF8ToUTF16(title).c_str()); + if (!button_label.empty()) + GetPtr()->SetOkButtonLabel(base::UTF8ToUTF16(button_label).c_str()); + // By default, *.* will be added to the file name if file type is "*.*". In // Electron, we disable it to make a better experience. // @@ -154,13 +159,14 @@ bool CreateDialogThread(RunState* run_state) { void RunOpenDialogInNewThread(const RunState& run_state, atom::NativeWindow* parent, const std::string& title, + const std::string& button_label, const base::FilePath& default_path, const Filters& filters, int properties, const OpenDialogCallback& callback) { std::vector paths; - bool result = ShowOpenDialog(parent, title, default_path, filters, properties, - &paths); + bool result = ShowOpenDialog(parent, title, button_label, default_path, + filters, properties, &paths); run_state.ui_message_loop->PostTask(FROM_HERE, base::Bind(callback, result, paths)); run_state.ui_message_loop->DeleteSoon(FROM_HERE, run_state.dialog_thread); @@ -169,6 +175,7 @@ void RunOpenDialogInNewThread(const RunState& run_state, void RunSaveDialogInNewThread(const RunState& run_state, atom::NativeWindow* parent, const std::string& title, + const std::string& button_label, const base::FilePath& default_path, const Filters& filters, const SaveDialogCallback& callback) { @@ -183,6 +190,7 @@ void RunSaveDialogInNewThread(const RunState& run_state, bool ShowOpenDialog(atom::NativeWindow* parent_window, const std::string& title, + const std::string& button_label, const base::FilePath& default_path, const Filters& filters, int properties, @@ -230,6 +238,7 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window, void ShowOpenDialog(atom::NativeWindow* parent, const std::string& title, + const std::string& button_label, const base::FilePath& default_path, const Filters& filters, int properties, @@ -248,6 +257,7 @@ void ShowOpenDialog(atom::NativeWindow* parent, bool ShowSaveDialog(atom::NativeWindow* parent_window, const std::string& title, + const std::string& button_label, const base::FilePath& default_path, const Filters& filters, base::FilePath* path) { @@ -268,6 +278,7 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window, void ShowSaveDialog(atom::NativeWindow* parent, const std::string& title, + const std::string& button_label, const base::FilePath& default_path, const Filters& filters, const SaveDialogCallback& callback) { diff --git a/atom/browser/web_dialog_helper.cc b/atom/browser/web_dialog_helper.cc index a082c3814c..be43584a5b 100644 --- a/atom/browser/web_dialog_helper.cc +++ b/atom/browser/web_dialog_helper.cc @@ -84,6 +84,7 @@ void WebDialogHelper::RunFileChooser(content::WebContents* web_contents, base::FilePath path; if (file_dialog::ShowSaveDialog(window_, base::UTF16ToUTF8(params.title), + "Save", params.default_file_name, filters, &path)) { @@ -114,6 +115,7 @@ void WebDialogHelper::RunFileChooser(content::WebContents* web_contents, prefs::kSelectFileLastDirectory).Append(params.default_file_name); if (file_dialog::ShowOpenDialog(window_, base::UTF16ToUTF8(params.title), + "Open", default_file_path, filters, flags, diff --git a/docs/api/dialog.md b/docs/api/dialog.md index 1444b5960e..bb76056d13 100644 --- a/docs/api/dialog.md +++ b/docs/api/dialog.md @@ -28,6 +28,7 @@ The `dialog` module has the following methods: * `options` Object * `title` String * `defaultPath` String + * `buttonLabel` String * `filters` Array * `properties` Array - Contains which features the dialog should use, can contain `openFile`, `openDirectory`, `multiSelections` and diff --git a/lib/browser/api/dialog.js b/lib/browser/api/dialog.js index a41d1fa46e..55c8935b2a 100644 --- a/lib/browser/api/dialog.js +++ b/lib/browser/api/dialog.js @@ -75,6 +75,15 @@ module.exports = { } else if (typeof options.title !== 'string') { throw new TypeError('Title must be a string') } + if (options.buttonLabel == null) { + if (options.properties.indexOf('openDirectory') !== -1) { + options.buttonLabel = 'Choose' + } else { + options.buttonLabel = 'Open' + } + } else if (typeof options.buttonLabel !== 'string') { + throw new TypeError('buttonLabel must be a string') + } if (options.defaultPath == null) { options.defaultPath = '' } else if (typeof options.defaultPath !== 'string') { @@ -86,7 +95,7 @@ module.exports = { wrappedCallback = typeof callback === 'function' ? function (success, result) { return callback(success ? result : void 0) } : null - return binding.showOpenDialog(String(options.title), String(options.defaultPath), options.filters, properties, window, wrappedCallback) + return binding.showOpenDialog(String(options.title), String(options.buttonLabel), String(options.defaultPath), options.filters, properties, window, wrappedCallback) }, showSaveDialog: function (...args) { @@ -103,6 +112,11 @@ module.exports = { } else if (typeof options.title !== 'string') { throw new TypeError('Title must be a string') } + if (options.buttonLabel == null) { + options.buttonLabel = 'Save' + } else if (typeof options.buttonLabel !== 'string') { + throw new TypeError('buttonLabel must be a string') + } if (options.defaultPath == null) { options.defaultPath = '' } else if (typeof options.defaultPath !== 'string') { @@ -114,7 +128,7 @@ module.exports = { wrappedCallback = typeof callback === 'function' ? function (success, result) { return callback(success ? result : void 0) } : null - return binding.showSaveDialog(String(options.title), String(options.defaultPath), options.filters, window, wrappedCallback) + return binding.showSaveDialog(String(options.title), String(options.buttonLabel), String(options.defaultPath), options.filters, window, wrappedCallback) }, showMessageBox: function (...args) {