diff --git a/atom/browser/api/atom_api_dialog.cc b/atom/browser/api/atom_api_dialog.cc index a15a9d8e7e73..6305b5f24792 100644 --- a/atom/browser/api/atom_api_dialog.cc +++ b/atom/browser/api/atom_api_dialog.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include +#include #include #include "atom/browser/api/atom_api_window.h" @@ -16,6 +17,26 @@ #include "atom/common/node_includes.h" +namespace mate { + +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, + v8::Handle val, + file_dialog::Filter* out) { + mate::Dictionary dict(isolate); + if (!ConvertFromV8(isolate, val, &dict)) + return false; + if (!dict.Get("name", &(out->first))) + return false; + if (!dict.Get("extensions", &(out->second))) + return false; + return true; + } +}; + +} // namespace mate + namespace { void ShowMessageBox(int type, @@ -41,6 +62,7 @@ void ShowMessageBox(int type, void ShowOpenDialog(const std::string& title, const base::FilePath& default_path, + const file_dialog::Filters& filters, int properties, atom::NativeWindow* window, mate::Arguments* args) { @@ -49,18 +71,19 @@ void ShowOpenDialog(const std::string& title, if (mate::Converter::FromV8(args->isolate(), peek, &callback)) { - file_dialog::ShowOpenDialog(window, title, default_path, properties, - callback); + file_dialog::ShowOpenDialog(window, title, default_path, filters, + properties, callback); } else { std::vector paths; - if (file_dialog::ShowOpenDialog(window, title, default_path, properties, - &paths)) + if (file_dialog::ShowOpenDialog(window, title, default_path, filters, + properties, &paths)) args->Return(paths); } } void ShowSaveDialog(const std::string& title, const base::FilePath& default_path, + const file_dialog::Filters& filters, atom::NativeWindow* window, mate::Arguments* args) { v8::Handle peek = args->PeekNext(); @@ -68,10 +91,11 @@ void ShowSaveDialog(const std::string& title, if (mate::Converter::FromV8(args->isolate(), peek, &callback)) { - file_dialog::ShowSaveDialog(window, title, default_path, callback); + file_dialog::ShowSaveDialog(window, title, default_path, filters, callback); } else { base::FilePath path; - if (file_dialog::ShowSaveDialog(window, title, default_path, &path)) + if (file_dialog::ShowSaveDialog(window, title, default_path, filters, + &path)) args->Return(path); } } diff --git a/atom/browser/api/lib/dialog.coffee b/atom/browser/api/lib/dialog.coffee index 19cae0b3a2c4..b95ff4d96a30 100644 --- a/atom/browser/api/lib/dialog.coffee +++ b/atom/browser/api/lib/dialog.coffee @@ -25,6 +25,7 @@ module.exports = options.title ?= '' options.defaultPath ?= '' + options.filters ?= [] wrappedCallback = if typeof callback is 'function' @@ -34,6 +35,7 @@ module.exports = binding.showOpenDialog String(options.title), String(options.defaultPath), + options.filters properties, window, wrappedCallback @@ -48,6 +50,7 @@ module.exports = options ?= title: 'Save' options.title ?= '' options.defaultPath ?= '' + options.filter ?= [] wrappedCallback = if typeof callback is 'function' @@ -57,6 +60,7 @@ module.exports = binding.showSaveDialog String(options.title), String(options.defaultPath), + options.filters window, wrappedCallback diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index ca3e8789f294..04f89d52187a 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -528,8 +528,9 @@ void NativeWindow::DevToolsSaveToFile(const std::string& url, if (it != saved_files_.end() && !save_as) { path = it->second; } else { + file_dialog::Filters filters; base::FilePath default_path(base::FilePath::FromUTF8Unsafe(url)); - if (!file_dialog::ShowSaveDialog(this, url, default_path, &path)) { + if (!file_dialog::ShowSaveDialog(this, url, default_path, filters, &path)) { base::StringValue url_value(url); CallDevToolsFunction("InspectorFrontendAPI.canceledSaveURL", &url_value); return; diff --git a/atom/browser/ui/file_dialog.h b/atom/browser/ui/file_dialog.h index 4a30df28b193..861ec14c06e8 100644 --- a/atom/browser/ui/file_dialog.h +++ b/atom/browser/ui/file_dialog.h @@ -6,6 +6,7 @@ #define ATOM_BROWSER_UI_FILE_DIALOG_H_ #include +#include #include #include "base/callback_forward.h" @@ -17,6 +18,10 @@ class NativeWindow; namespace file_dialog { +// +typedef std::pair > Filter; +typedef std::vector Filters; + enum FileDialogProperty { FILE_DIALOG_OPEN_FILE = 1, FILE_DIALOG_OPEN_DIRECTORY = 2, @@ -33,23 +38,27 @@ typedef base::Callback* paths); void ShowOpenDialog(atom::NativeWindow* parent_window, const std::string& title, const base::FilePath& default_path, + const Filters& filters, int properties, const OpenDialogCallback& callback); bool ShowSaveDialog(atom::NativeWindow* parent_window, const std::string& title, const base::FilePath& default_path, + const Filters& filters, base::FilePath* path); void ShowSaveDialog(atom::NativeWindow* parent_window, const std::string& title, const base::FilePath& default_path, + const Filters& filters, 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 21cd14166500..c27001f5a370 100644 --- a/atom/browser/ui/file_dialog_gtk.cc +++ b/atom/browser/ui/file_dialog_gtk.cc @@ -167,6 +167,7 @@ void FileChooserDialog::OnFileDialogResponse(GtkWidget* widget, int response) { bool ShowOpenDialog(atom::NativeWindow* parent_window, const std::string& title, const base::FilePath& default_path, + const Filters& filters, int properties, std::vector* paths) { GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN; @@ -190,6 +191,7 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window, void ShowOpenDialog(atom::NativeWindow* parent_window, const std::string& title, const base::FilePath& default_path, + const Filters& filters, int properties, const OpenDialogCallback& callback) { GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN; @@ -207,6 +209,7 @@ void ShowOpenDialog(atom::NativeWindow* parent_window, bool ShowSaveDialog(atom::NativeWindow* parent_window, const std::string& title, const base::FilePath& default_path, + const Filters& filters, base::FilePath* path) { FileChooserDialog save_dialog( GTK_FILE_CHOOSER_ACTION_SAVE, parent_window, title, default_path); @@ -223,6 +226,7 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window, void ShowSaveDialog(atom::NativeWindow* parent_window, const std::string& title, const base::FilePath& default_path, + const Filters& filters, const SaveDialogCallback& callback) { FileChooserDialog* save_dialog = new FileChooserDialog( GTK_FILE_CHOOSER_ACTION_SAVE, parent_window, title, default_path); diff --git a/atom/browser/ui/file_dialog_mac.mm b/atom/browser/ui/file_dialog_mac.mm index e6292c30102b..fb62e4272861 100644 --- a/atom/browser/ui/file_dialog_mac.mm +++ b/atom/browser/ui/file_dialog_mac.mm @@ -83,6 +83,7 @@ void ReadDialogPaths(NSOpenPanel* dialog, std::vector* paths) { bool ShowOpenDialog(atom::NativeWindow* parent_window, const std::string& title, const base::FilePath& default_path, + const Filters& filters, int properties, std::vector* paths) { DCHECK(paths); @@ -102,6 +103,7 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window, void ShowOpenDialog(atom::NativeWindow* parent_window, const std::string& title, const base::FilePath& default_path, + const Filters& filters, int properties, const OpenDialogCallback& c) { NSOpenPanel* dialog = [NSOpenPanel openPanel]; @@ -129,6 +131,7 @@ void ShowOpenDialog(atom::NativeWindow* parent_window, bool ShowSaveDialog(atom::NativeWindow* parent_window, const std::string& title, const base::FilePath& default_path, + const Filters& filters, base::FilePath* path) { DCHECK(path); NSSavePanel* dialog = [NSSavePanel savePanel]; @@ -146,6 +149,7 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window, void ShowSaveDialog(atom::NativeWindow* parent_window, const std::string& title, const base::FilePath& default_path, + const Filters& filters, const SaveDialogCallback& c) { NSSavePanel* dialog = [NSSavePanel savePanel]; diff --git a/atom/browser/ui/file_dialog_win.cc b/atom/browser/ui/file_dialog_win.cc index e0436d96c07a..9a7873347a52 100644 --- a/atom/browser/ui/file_dialog_win.cc +++ b/atom/browser/ui/file_dialog_win.cc @@ -205,6 +205,7 @@ class FileDialog { bool ShowOpenDialog(atom::NativeWindow* parent_window, const std::string& title, const base::FilePath& default_path, + const Filters& filters, int properties, std::vector* paths) { int options = FOS_FORCEFILESYSTEM | FOS_FILEMUSTEXIST; @@ -255,6 +256,7 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window, void ShowOpenDialog(atom::NativeWindow* parent_window, const std::string& title, const base::FilePath& default_path, + const Filters& filters, int properties, const OpenDialogCallback& callback) { std::vector paths; @@ -262,6 +264,7 @@ void ShowOpenDialog(atom::NativeWindow* parent_window, title, default_path, properties, + filters, &paths); callback.Run(result, paths); } @@ -269,6 +272,7 @@ void ShowOpenDialog(atom::NativeWindow* parent_window, bool ShowSaveDialog(atom::NativeWindow* parent_window, const std::string& title, const base::FilePath& default_path, + const Filters& filters, base::FilePath* path) { // TODO(zcbenz): Accept custom filters from caller. std::vector file_ext; @@ -312,9 +316,11 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window, void ShowSaveDialog(atom::NativeWindow* parent_window, const std::string& title, const base::FilePath& default_path, + const Filters& filters, const SaveDialogCallback& callback) { base::FilePath path; - bool result = ShowSaveDialog(parent_window, title, default_path, &path); + bool result = ShowSaveDialog(parent_window, title, default_path, filters, + &path); callback.Run(result, path); }