Add "filters" parameter for file dialogs.

This commit is contained in:
Cheng Zhao 2014-08-06 12:44:02 +08:00
parent dfe111b95a
commit dc257f1f86
7 changed files with 60 additions and 8 deletions

View file

@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
#include <string> #include <string>
#include <utility>
#include <vector> #include <vector>
#include "atom/browser/api/atom_api_window.h" #include "atom/browser/api/atom_api_window.h"
@ -16,6 +17,26 @@
#include "atom/common/node_includes.h" #include "atom/common/node_includes.h"
namespace mate {
template<>
struct Converter<file_dialog::Filter> {
static bool FromV8(v8::Isolate* isolate,
v8::Handle<v8::Value> 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 { namespace {
void ShowMessageBox(int type, void ShowMessageBox(int type,
@ -41,6 +62,7 @@ void ShowMessageBox(int type,
void ShowOpenDialog(const std::string& title, void ShowOpenDialog(const std::string& title,
const base::FilePath& default_path, const base::FilePath& default_path,
const file_dialog::Filters& filters,
int properties, int properties,
atom::NativeWindow* window, atom::NativeWindow* window,
mate::Arguments* args) { mate::Arguments* args) {
@ -49,18 +71,19 @@ void ShowOpenDialog(const std::string& title,
if (mate::Converter<file_dialog::OpenDialogCallback>::FromV8(args->isolate(), if (mate::Converter<file_dialog::OpenDialogCallback>::FromV8(args->isolate(),
peek, peek,
&callback)) { &callback)) {
file_dialog::ShowOpenDialog(window, title, default_path, properties, file_dialog::ShowOpenDialog(window, title, default_path, filters,
callback); properties, callback);
} else { } else {
std::vector<base::FilePath> paths; std::vector<base::FilePath> paths;
if (file_dialog::ShowOpenDialog(window, title, default_path, properties, if (file_dialog::ShowOpenDialog(window, title, default_path, filters,
&paths)) properties, &paths))
args->Return(paths); args->Return(paths);
} }
} }
void ShowSaveDialog(const std::string& title, void ShowSaveDialog(const std::string& title,
const base::FilePath& default_path, const base::FilePath& default_path,
const file_dialog::Filters& filters,
atom::NativeWindow* window, atom::NativeWindow* window,
mate::Arguments* args) { mate::Arguments* args) {
v8::Handle<v8::Value> peek = args->PeekNext(); v8::Handle<v8::Value> peek = args->PeekNext();
@ -68,10 +91,11 @@ void ShowSaveDialog(const std::string& title,
if (mate::Converter<file_dialog::SaveDialogCallback>::FromV8(args->isolate(), if (mate::Converter<file_dialog::SaveDialogCallback>::FromV8(args->isolate(),
peek, peek,
&callback)) { &callback)) {
file_dialog::ShowSaveDialog(window, title, default_path, callback); file_dialog::ShowSaveDialog(window, title, default_path, filters, callback);
} else { } else {
base::FilePath path; 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); args->Return(path);
} }
} }

View file

@ -25,6 +25,7 @@ module.exports =
options.title ?= '' options.title ?= ''
options.defaultPath ?= '' options.defaultPath ?= ''
options.filters ?= []
wrappedCallback = wrappedCallback =
if typeof callback is 'function' if typeof callback is 'function'
@ -34,6 +35,7 @@ module.exports =
binding.showOpenDialog String(options.title), binding.showOpenDialog String(options.title),
String(options.defaultPath), String(options.defaultPath),
options.filters
properties, properties,
window, window,
wrappedCallback wrappedCallback
@ -48,6 +50,7 @@ module.exports =
options ?= title: 'Save' options ?= title: 'Save'
options.title ?= '' options.title ?= ''
options.defaultPath ?= '' options.defaultPath ?= ''
options.filter ?= []
wrappedCallback = wrappedCallback =
if typeof callback is 'function' if typeof callback is 'function'
@ -57,6 +60,7 @@ module.exports =
binding.showSaveDialog String(options.title), binding.showSaveDialog String(options.title),
String(options.defaultPath), String(options.defaultPath),
options.filters
window, window,
wrappedCallback wrappedCallback

View file

@ -528,8 +528,9 @@ void NativeWindow::DevToolsSaveToFile(const std::string& url,
if (it != saved_files_.end() && !save_as) { if (it != saved_files_.end() && !save_as) {
path = it->second; path = it->second;
} else { } else {
file_dialog::Filters filters;
base::FilePath default_path(base::FilePath::FromUTF8Unsafe(url)); 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); base::StringValue url_value(url);
CallDevToolsFunction("InspectorFrontendAPI.canceledSaveURL", &url_value); CallDevToolsFunction("InspectorFrontendAPI.canceledSaveURL", &url_value);
return; return;

View file

@ -6,6 +6,7 @@
#define ATOM_BROWSER_UI_FILE_DIALOG_H_ #define ATOM_BROWSER_UI_FILE_DIALOG_H_
#include <string> #include <string>
#include <utility>
#include <vector> #include <vector>
#include "base/callback_forward.h" #include "base/callback_forward.h"
@ -17,6 +18,10 @@ class NativeWindow;
namespace file_dialog { namespace file_dialog {
// <description, extensions>
typedef std::pair<std::string, std::vector<std::string> > Filter;
typedef std::vector<Filter> Filters;
enum FileDialogProperty { enum FileDialogProperty {
FILE_DIALOG_OPEN_FILE = 1, FILE_DIALOG_OPEN_FILE = 1,
FILE_DIALOG_OPEN_DIRECTORY = 2, FILE_DIALOG_OPEN_DIRECTORY = 2,
@ -33,23 +38,27 @@ typedef base::Callback<void(
bool ShowOpenDialog(atom::NativeWindow* parent_window, bool ShowOpenDialog(atom::NativeWindow* parent_window,
const std::string& title, const std::string& title,
const base::FilePath& default_path, const base::FilePath& default_path,
const Filters& filters,
int properties, int properties,
std::vector<base::FilePath>* paths); std::vector<base::FilePath>* paths);
void ShowOpenDialog(atom::NativeWindow* parent_window, void ShowOpenDialog(atom::NativeWindow* parent_window,
const std::string& title, const std::string& title,
const base::FilePath& default_path, const base::FilePath& default_path,
const Filters& filters,
int properties, int properties,
const OpenDialogCallback& callback); const OpenDialogCallback& callback);
bool ShowSaveDialog(atom::NativeWindow* parent_window, bool ShowSaveDialog(atom::NativeWindow* parent_window,
const std::string& title, const std::string& title,
const base::FilePath& default_path, const base::FilePath& default_path,
const Filters& filters,
base::FilePath* path); base::FilePath* path);
void ShowSaveDialog(atom::NativeWindow* parent_window, void ShowSaveDialog(atom::NativeWindow* parent_window,
const std::string& title, const std::string& title,
const base::FilePath& default_path, const base::FilePath& default_path,
const Filters& filters,
const SaveDialogCallback& callback); const SaveDialogCallback& callback);
} // namespace file_dialog } // namespace file_dialog

View file

@ -167,6 +167,7 @@ void FileChooserDialog::OnFileDialogResponse(GtkWidget* widget, int response) {
bool ShowOpenDialog(atom::NativeWindow* parent_window, bool ShowOpenDialog(atom::NativeWindow* parent_window,
const std::string& title, const std::string& title,
const base::FilePath& default_path, const base::FilePath& default_path,
const Filters& filters,
int properties, int properties,
std::vector<base::FilePath>* paths) { std::vector<base::FilePath>* paths) {
GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN; GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN;
@ -190,6 +191,7 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window,
void ShowOpenDialog(atom::NativeWindow* parent_window, void ShowOpenDialog(atom::NativeWindow* parent_window,
const std::string& title, const std::string& title,
const base::FilePath& default_path, const base::FilePath& default_path,
const Filters& filters,
int properties, int properties,
const OpenDialogCallback& callback) { const OpenDialogCallback& callback) {
GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN; GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN;
@ -207,6 +209,7 @@ void ShowOpenDialog(atom::NativeWindow* parent_window,
bool ShowSaveDialog(atom::NativeWindow* parent_window, bool ShowSaveDialog(atom::NativeWindow* parent_window,
const std::string& title, const std::string& title,
const base::FilePath& default_path, const base::FilePath& default_path,
const Filters& filters,
base::FilePath* path) { base::FilePath* path) {
FileChooserDialog save_dialog( FileChooserDialog save_dialog(
GTK_FILE_CHOOSER_ACTION_SAVE, parent_window, title, default_path); 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, void ShowSaveDialog(atom::NativeWindow* parent_window,
const std::string& title, const std::string& title,
const base::FilePath& default_path, const base::FilePath& default_path,
const Filters& filters,
const SaveDialogCallback& callback) { const SaveDialogCallback& callback) {
FileChooserDialog* save_dialog = new FileChooserDialog( FileChooserDialog* save_dialog = new FileChooserDialog(
GTK_FILE_CHOOSER_ACTION_SAVE, parent_window, title, default_path); GTK_FILE_CHOOSER_ACTION_SAVE, parent_window, title, default_path);

View file

@ -83,6 +83,7 @@ void ReadDialogPaths(NSOpenPanel* dialog, std::vector<base::FilePath>* paths) {
bool ShowOpenDialog(atom::NativeWindow* parent_window, bool ShowOpenDialog(atom::NativeWindow* parent_window,
const std::string& title, const std::string& title,
const base::FilePath& default_path, const base::FilePath& default_path,
const Filters& filters,
int properties, int properties,
std::vector<base::FilePath>* paths) { std::vector<base::FilePath>* paths) {
DCHECK(paths); DCHECK(paths);
@ -102,6 +103,7 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window,
void ShowOpenDialog(atom::NativeWindow* parent_window, void ShowOpenDialog(atom::NativeWindow* parent_window,
const std::string& title, const std::string& title,
const base::FilePath& default_path, const base::FilePath& default_path,
const Filters& filters,
int properties, int properties,
const OpenDialogCallback& c) { const OpenDialogCallback& c) {
NSOpenPanel* dialog = [NSOpenPanel openPanel]; NSOpenPanel* dialog = [NSOpenPanel openPanel];
@ -129,6 +131,7 @@ void ShowOpenDialog(atom::NativeWindow* parent_window,
bool ShowSaveDialog(atom::NativeWindow* parent_window, bool ShowSaveDialog(atom::NativeWindow* parent_window,
const std::string& title, const std::string& title,
const base::FilePath& default_path, const base::FilePath& default_path,
const Filters& filters,
base::FilePath* path) { base::FilePath* path) {
DCHECK(path); DCHECK(path);
NSSavePanel* dialog = [NSSavePanel savePanel]; NSSavePanel* dialog = [NSSavePanel savePanel];
@ -146,6 +149,7 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window,
void ShowSaveDialog(atom::NativeWindow* parent_window, void ShowSaveDialog(atom::NativeWindow* parent_window,
const std::string& title, const std::string& title,
const base::FilePath& default_path, const base::FilePath& default_path,
const Filters& filters,
const SaveDialogCallback& c) { const SaveDialogCallback& c) {
NSSavePanel* dialog = [NSSavePanel savePanel]; NSSavePanel* dialog = [NSSavePanel savePanel];

View file

@ -205,6 +205,7 @@ class FileDialog {
bool ShowOpenDialog(atom::NativeWindow* parent_window, bool ShowOpenDialog(atom::NativeWindow* parent_window,
const std::string& title, const std::string& title,
const base::FilePath& default_path, const base::FilePath& default_path,
const Filters& filters,
int properties, int properties,
std::vector<base::FilePath>* paths) { std::vector<base::FilePath>* paths) {
int options = FOS_FORCEFILESYSTEM | FOS_FILEMUSTEXIST; int options = FOS_FORCEFILESYSTEM | FOS_FILEMUSTEXIST;
@ -255,6 +256,7 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window,
void ShowOpenDialog(atom::NativeWindow* parent_window, void ShowOpenDialog(atom::NativeWindow* parent_window,
const std::string& title, const std::string& title,
const base::FilePath& default_path, const base::FilePath& default_path,
const Filters& filters,
int properties, int properties,
const OpenDialogCallback& callback) { const OpenDialogCallback& callback) {
std::vector<base::FilePath> paths; std::vector<base::FilePath> paths;
@ -262,6 +264,7 @@ void ShowOpenDialog(atom::NativeWindow* parent_window,
title, title,
default_path, default_path,
properties, properties,
filters,
&paths); &paths);
callback.Run(result, paths); callback.Run(result, paths);
} }
@ -269,6 +272,7 @@ void ShowOpenDialog(atom::NativeWindow* parent_window,
bool ShowSaveDialog(atom::NativeWindow* parent_window, bool ShowSaveDialog(atom::NativeWindow* parent_window,
const std::string& title, const std::string& title,
const base::FilePath& default_path, const base::FilePath& default_path,
const Filters& filters,
base::FilePath* path) { base::FilePath* path) {
// TODO(zcbenz): Accept custom filters from caller. // TODO(zcbenz): Accept custom filters from caller.
std::vector<std::wstring> file_ext; std::vector<std::wstring> file_ext;
@ -312,9 +316,11 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window,
void ShowSaveDialog(atom::NativeWindow* parent_window, void ShowSaveDialog(atom::NativeWindow* parent_window,
const std::string& title, const std::string& title,
const base::FilePath& default_path, const base::FilePath& default_path,
const Filters& filters,
const SaveDialogCallback& callback) { const SaveDialogCallback& callback) {
base::FilePath path; 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); callback.Run(result, path);
} }