Merge pull request #8623 from electron/dialog-options-helper

Add DialogSettings helper
This commit is contained in:
Kevin Sawicki 2017-02-09 11:07:02 -08:00 committed by GitHub
commit c3f3a6f133
9 changed files with 151 additions and 235 deletions

View file

@ -35,6 +35,24 @@ struct Converter<file_dialog::Filter> {
} }
}; };
template<>
struct Converter<file_dialog::DialogSettings> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
file_dialog::DialogSettings* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
return false;
dict.Get("window", &(out->parent_window));
dict.Get("title", &(out->title));
dict.Get("buttonLabel", &(out->button_label));
dict.Get("defaultPath", &(out->default_path));
dict.Get("filters", &(out->filters));
dict.Get("properties", &(out->properties));
return true;
}
};
} // namespace mate } // namespace mate
namespace { namespace {
@ -68,45 +86,32 @@ void ShowMessageBox(int type,
} }
} }
void ShowOpenDialog(const std::string& title, void ShowOpenDialog(const file_dialog::DialogSettings& settings,
const std::string& button_label,
const base::FilePath& default_path,
const file_dialog::Filters& filters,
int properties,
atom::NativeWindow* window,
mate::Arguments* args) { mate::Arguments* args) {
v8::Local<v8::Value> peek = args->PeekNext(); v8::Local<v8::Value> peek = args->PeekNext();
file_dialog::OpenDialogCallback callback; file_dialog::OpenDialogCallback callback;
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, button_label, default_path, file_dialog::ShowOpenDialog(settings, callback);
filters, properties, callback);
} else { } else {
std::vector<base::FilePath> paths; std::vector<base::FilePath> paths;
if (file_dialog::ShowOpenDialog(window, title, button_label, default_path, if (file_dialog::ShowOpenDialog(settings, &paths))
filters, properties, &paths))
args->Return(paths); args->Return(paths);
} }
} }
void ShowSaveDialog(const std::string& title, void ShowSaveDialog(const file_dialog::DialogSettings& settings,
const std::string& button_label,
const base::FilePath& default_path,
const file_dialog::Filters& filters,
atom::NativeWindow* window,
mate::Arguments* args) { mate::Arguments* args) {
v8::Local<v8::Value> peek = args->PeekNext(); v8::Local<v8::Value> peek = args->PeekNext();
file_dialog::SaveDialogCallback callback; file_dialog::SaveDialogCallback callback;
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, button_label, default_path, file_dialog::ShowSaveDialog(settings, callback);
filters, callback);
} else { } else {
base::FilePath path; base::FilePath path;
if (file_dialog::ShowSaveDialog(window, title, button_label, default_path, if (file_dialog::ShowSaveDialog(settings, &path))
filters, &path))
args->Return(path); args->Return(path);
} }
} }

View file

@ -90,10 +90,11 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
base::FilePath path; base::FilePath path;
GetItemSavePath(item, &path); GetItemSavePath(item, &path);
// Show save dialog if save path was not set already on item // Show save dialog if save path was not set already on item
if (path.empty() && file_dialog::ShowSaveDialog(window, item->GetURL().spec(), file_dialog::DialogSettings settings;
"", default_path, settings.parent_window = window;
file_dialog::Filters(), settings.title = item->GetURL().spec();
&path)) { settings.default_path = default_path;
if (path.empty() && file_dialog::ShowSaveDialog(settings, &path)) {
// Remember the last selected download directory. // Remember the last selected download directory.
AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>( AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>(
download_manager_->GetBrowserContext()); download_manager_->GetBrowserContext());

View file

@ -294,10 +294,11 @@ void CommonWebContentsDelegate::DevToolsSaveToFile(
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; file_dialog::DialogSettings settings;
base::FilePath default_path(base::FilePath::FromUTF8Unsafe(url)); settings.parent_window = owner_window();
if (!file_dialog::ShowSaveDialog(owner_window(), url, "", default_path, settings.title = url;
filters, &path)) { settings.default_path = base::FilePath::FromUTF8Unsafe(url);
if (!file_dialog::ShowSaveDialog(settings, &path)) {
base::StringValue url_value(url); base::StringValue url_value(url);
web_contents_->CallClientFunction( web_contents_->CallClientFunction(
"DevToolsAPI.canceledSaveURL", &url_value, nullptr, nullptr); "DevToolsAPI.canceledSaveURL", &url_value, nullptr, nullptr);
@ -358,12 +359,11 @@ void CommonWebContentsDelegate::DevToolsAddFileSystem(
const base::FilePath& file_system_path) { const base::FilePath& file_system_path) {
base::FilePath path = file_system_path; base::FilePath path = file_system_path;
if (path.empty()) { if (path.empty()) {
file_dialog::Filters filters;
base::FilePath default_path;
std::vector<base::FilePath> paths; std::vector<base::FilePath> paths;
int flag = file_dialog::FILE_DIALOG_OPEN_DIRECTORY; file_dialog::DialogSettings settings;
if (!file_dialog::ShowOpenDialog(owner_window(), "", "", default_path, settings.parent_window = owner_window();
filters, flag, &paths)) settings.properties = file_dialog::FILE_DIALOG_OPEN_DIRECTORY;
if (!file_dialog::ShowOpenDialog(settings, &paths))
return; return;
path = paths[0]; path = paths[0];

View file

@ -37,34 +37,25 @@ typedef base::Callback<void(
typedef base::Callback<void( typedef base::Callback<void(
bool result, const base::FilePath& path)> SaveDialogCallback; bool result, const base::FilePath& path)> SaveDialogCallback;
bool ShowOpenDialog(atom::NativeWindow* parent_window, struct DialogSettings {
const std::string& title, atom::NativeWindow* parent_window = nullptr;
const std::string& button_label, std::string title;
const base::FilePath& default_path, std::string button_label;
const Filters& filters, base::FilePath default_path;
int properties, Filters filters;
int properties = 0;
};
bool ShowOpenDialog(const DialogSettings& settings,
std::vector<base::FilePath>* paths); std::vector<base::FilePath>* paths);
void ShowOpenDialog(atom::NativeWindow* parent_window, void ShowOpenDialog(const DialogSettings& settings,
const std::string& title,
const std::string& button_label,
const base::FilePath& default_path,
const Filters& filters,
int properties,
const OpenDialogCallback& callback); const OpenDialogCallback& callback);
bool ShowSaveDialog(atom::NativeWindow* parent_window, bool ShowSaveDialog(const DialogSettings& settings,
const std::string& title,
const std::string& button_label,
const base::FilePath& default_path,
const Filters& filters,
base::FilePath* path); base::FilePath* path);
void ShowSaveDialog(atom::NativeWindow* parent_window, void ShowSaveDialog(const DialogSettings& settings,
const std::string& title,
const std::string& button_label,
const base::FilePath& default_path,
const Filters& filters,
const SaveDialogCallback& callback); const SaveDialogCallback& callback);
} // namespace file_dialog } // namespace file_dialog

View file

@ -36,24 +36,20 @@ void OnFileFilterDataDestroyed(std::string* file_extension) {
class FileChooserDialog { class FileChooserDialog {
public: public:
FileChooserDialog(GtkFileChooserAction action, FileChooserDialog(GtkFileChooserAction action,
atom::NativeWindow* parent_window, const DialogSettings& settings)
const std::string& title, : parent_(static_cast<atom::NativeWindowViews*>(settings.parent_window)),
const std::string& button_label, filters_(settings.filters) {
const base::FilePath& default_path,
const Filters& filters)
: parent_(static_cast<atom::NativeWindowViews*>(parent_window)),
filters_(filters) {
const char* confirm_text = GTK_STOCK_OK; const char* confirm_text = GTK_STOCK_OK;
if (!button_label.empty()) if (!settings.button_label.empty())
confirm_text = button_label.c_str(); confirm_text = settings.button_label.c_str();
else if (action == GTK_FILE_CHOOSER_ACTION_SAVE) else if (action == GTK_FILE_CHOOSER_ACTION_SAVE)
confirm_text = GTK_STOCK_SAVE; confirm_text = GTK_STOCK_SAVE;
else if (action == GTK_FILE_CHOOSER_ACTION_OPEN) else if (action == GTK_FILE_CHOOSER_ACTION_OPEN)
confirm_text = GTK_STOCK_OPEN; confirm_text = GTK_STOCK_OPEN;
dialog_ = gtk_file_chooser_dialog_new( dialog_ = gtk_file_chooser_dialog_new(
title.c_str(), settings.title.c_str(),
NULL, NULL,
action, action,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
@ -71,20 +67,20 @@ class FileChooserDialog {
if (action != GTK_FILE_CHOOSER_ACTION_OPEN) if (action != GTK_FILE_CHOOSER_ACTION_OPEN)
gtk_file_chooser_set_create_folders(GTK_FILE_CHOOSER(dialog_), TRUE); gtk_file_chooser_set_create_folders(GTK_FILE_CHOOSER(dialog_), TRUE);
if (!default_path.empty()) { if (!settings.default_path.empty()) {
if (base::DirectoryExists(default_path)) { if (base::DirectoryExists(settings.default_path)) {
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog_), gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog_),
default_path.value().c_str()); settings.default_path.value().c_str());
} else { } else {
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog_), gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog_),
default_path.DirName().value().c_str()); settings.default_path.DirName().value().c_str());
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog_), gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog_),
default_path.BaseName().value().c_str()); settings.default_path.BaseName().value().c_str());
} }
} }
if (!filters.empty()) if (!settings.filters.empty())
AddFilters(filters); AddFilters(settings.filters);
} }
~FileChooserDialog() { ~FileChooserDialog() {
@ -230,19 +226,13 @@ base::FilePath FileChooserDialog::AddExtensionForFilename(
} // namespace } // namespace
bool ShowOpenDialog(atom::NativeWindow* parent_window, bool ShowOpenDialog(const DialogSettings& settings,
const std::string& title,
const std::string& button_label,
const base::FilePath& default_path,
const Filters& filters,
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;
if (properties & FILE_DIALOG_OPEN_DIRECTORY) if (settings.properties & FILE_DIALOG_OPEN_DIRECTORY)
action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER; action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
FileChooserDialog open_dialog(action, parent_window, title, button_label, FileChooserDialog open_dialog(action, settings);
default_path, filters); open_dialog.SetupProperties(settings.properties);
open_dialog.SetupProperties(properties);
gtk_widget_show_all(open_dialog.dialog()); gtk_widget_show_all(open_dialog.dialog());
int response = gtk_dialog_run(GTK_DIALOG(open_dialog.dialog())); int response = gtk_dialog_run(GTK_DIALOG(open_dialog.dialog()));
@ -254,30 +244,19 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window,
} }
} }
void ShowOpenDialog(atom::NativeWindow* parent_window, void ShowOpenDialog(const DialogSettings& settings,
const std::string& title,
const std::string& button_label,
const base::FilePath& default_path,
const Filters& filters,
int properties,
const OpenDialogCallback& callback) { const OpenDialogCallback& callback) {
GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN; GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN;
if (properties & FILE_DIALOG_OPEN_DIRECTORY) if (settings.properties & FILE_DIALOG_OPEN_DIRECTORY)
action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER; action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
FileChooserDialog* open_dialog = new FileChooserDialog( FileChooserDialog* open_dialog = new FileChooserDialog(action, settings);
action, parent_window, title, button_label, default_path, filters); open_dialog->SetupProperties(settings.properties);
open_dialog->SetupProperties(properties);
open_dialog->RunOpenAsynchronous(callback); open_dialog->RunOpenAsynchronous(callback);
} }
bool ShowSaveDialog(atom::NativeWindow* parent_window, bool ShowSaveDialog(const DialogSettings& settings,
const std::string& title,
const std::string& button_label,
const base::FilePath& default_path,
const Filters& filters,
base::FilePath* path) { base::FilePath* path) {
FileChooserDialog save_dialog(GTK_FILE_CHOOSER_ACTION_SAVE, parent_window, FileChooserDialog save_dialog(GTK_FILE_CHOOSER_ACTION_SAVE, settings);
title, button_label, default_path, filters);
gtk_widget_show_all(save_dialog.dialog()); gtk_widget_show_all(save_dialog.dialog());
int response = gtk_dialog_run(GTK_DIALOG(save_dialog.dialog())); int response = gtk_dialog_run(GTK_DIALOG(save_dialog.dialog()));
if (response == GTK_RESPONSE_ACCEPT) { if (response == GTK_RESPONSE_ACCEPT) {
@ -288,15 +267,10 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window,
} }
} }
void ShowSaveDialog(atom::NativeWindow* parent_window, void ShowSaveDialog(const DialogSettings& settings,
const std::string& title,
const std::string& button_label,
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, button_label, GTK_FILE_CHOOSER_ACTION_SAVE, settings);
default_path, filters);
save_dialog->RunSaveAsynchronous(callback); save_dialog->RunSaveAsynchronous(callback);
} }

View file

@ -44,25 +44,23 @@ void SetAllowedFileTypes(NSSavePanel* dialog, const Filters& filters) {
} }
void SetupDialog(NSSavePanel* dialog, void SetupDialog(NSSavePanel* dialog,
const std::string& title, const DialogSettings& settings) {
const std::string& button_label, if (!settings.title.empty())
const base::FilePath& default_path, [dialog setTitle:base::SysUTF8ToNSString(settings.title)];
const Filters& filters) {
if (!title.empty())
[dialog setTitle:base::SysUTF8ToNSString(title)];
if (!button_label.empty()) if (!settings.button_label.empty())
[dialog setPrompt:base::SysUTF8ToNSString(button_label)]; [dialog setPrompt:base::SysUTF8ToNSString(settings.button_label)];
NSString* default_dir = nil; NSString* default_dir = nil;
NSString* default_filename = nil; NSString* default_filename = nil;
if (!default_path.empty()) { if (!settings.default_path.empty()) {
if (base::DirectoryExists(default_path)) { if (base::DirectoryExists(settings.default_path)) {
default_dir = base::SysUTF8ToNSString(default_path.value()); default_dir = base::SysUTF8ToNSString(settings.default_path.value());
} else { } else {
default_dir = base::SysUTF8ToNSString(default_path.DirName().value()); default_dir =
base::SysUTF8ToNSString(settings.default_path.DirName().value());
default_filename = default_filename =
base::SysUTF8ToNSString(default_path.BaseName().value()); base::SysUTF8ToNSString(settings.default_path.BaseName().value());
} }
} }
@ -71,10 +69,10 @@ void SetupDialog(NSSavePanel* dialog,
if (default_filename) if (default_filename)
[dialog setNameFieldStringValue:default_filename]; [dialog setNameFieldStringValue:default_filename];
if (filters.empty()) if (settings.filters.empty())
[dialog setAllowsOtherFileTypes:YES]; [dialog setAllowsOtherFileTypes:YES];
else else
SetAllowedFileTypes(dialog, filters); SetAllowedFileTypes(dialog, settings.filters);
} }
void SetupDialogForProperties(NSOpenPanel* dialog, int properties) { void SetupDialogForProperties(NSOpenPanel* dialog, int properties) {
@ -117,20 +115,15 @@ void ReadDialogPaths(NSOpenPanel* dialog, std::vector<base::FilePath>* paths) {
} // namespace } // namespace
bool ShowOpenDialog(atom::NativeWindow* parent_window, bool ShowOpenDialog(const DialogSettings& settings,
const std::string& title,
const std::string& button_label,
const base::FilePath& default_path,
const Filters& filters,
int properties,
std::vector<base::FilePath>* paths) { std::vector<base::FilePath>* paths) {
DCHECK(paths); DCHECK(paths);
NSOpenPanel* dialog = [NSOpenPanel openPanel]; NSOpenPanel* dialog = [NSOpenPanel openPanel];
SetupDialog(dialog, title, button_label, default_path, filters); SetupDialog(dialog, settings);
SetupDialogForProperties(dialog, properties); SetupDialogForProperties(dialog, settings.properties);
int chosen = RunModalDialog(dialog, parent_window); int chosen = RunModalDialog(dialog, settings.parent_window);
if (chosen == NSFileHandlingPanelCancelButton) if (chosen == NSFileHandlingPanelCancelButton)
return false; return false;
@ -138,23 +131,20 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window,
return true; return true;
} }
void ShowOpenDialog(atom::NativeWindow* parent_window, void ShowOpenDialog(const DialogSettings& settings,
const std::string& title,
const std::string& button_label,
const base::FilePath& default_path,
const Filters& filters,
int properties,
const OpenDialogCallback& c) { const OpenDialogCallback& c) {
NSOpenPanel* dialog = [NSOpenPanel openPanel]; NSOpenPanel* dialog = [NSOpenPanel openPanel];
SetupDialog(dialog, title, button_label, default_path, filters); SetupDialog(dialog, settings);
SetupDialogForProperties(dialog, properties); SetupDialogForProperties(dialog, settings.properties);
// Duplicate the callback object here since c is a reference and gcd would // Duplicate the callback object here since c is a reference and gcd would
// only store the pointer, by duplication we can force gcd to store a copy. // only store the pointer, by duplication we can force gcd to store a copy.
__block OpenDialogCallback callback = c; __block OpenDialogCallback callback = c;
NSWindow* window = parent_window ? parent_window->GetNativeWindow() : NULL; NSWindow* window = settings.parent_window ?
settings.parent_window->GetNativeWindow() :
NULL;
[dialog beginSheetModalForWindow:window [dialog beginSheetModalForWindow:window
completionHandler:^(NSInteger chosen) { completionHandler:^(NSInteger chosen) {
if (chosen == NSFileHandlingPanelCancelButton) { if (chosen == NSFileHandlingPanelCancelButton) {
@ -167,18 +157,14 @@ void ShowOpenDialog(atom::NativeWindow* parent_window,
}]; }];
} }
bool ShowSaveDialog(atom::NativeWindow* parent_window, bool ShowSaveDialog(const DialogSettings& settings,
const std::string& title,
const std::string& button_label,
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];
SetupDialog(dialog, title, button_label, default_path, filters); SetupDialog(dialog, settings);
int chosen = RunModalDialog(dialog, parent_window); int chosen = RunModalDialog(dialog, settings.parent_window);
if (chosen == NSFileHandlingPanelCancelButton || ![[dialog URL] isFileURL]) if (chosen == NSFileHandlingPanelCancelButton || ![[dialog URL] isFileURL])
return false; return false;
@ -186,20 +172,18 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window,
return true; return true;
} }
void ShowSaveDialog(atom::NativeWindow* parent_window, void ShowSaveDialog(const DialogSettings& settings,
const std::string& title,
const std::string& button_label,
const base::FilePath& default_path,
const Filters& filters,
const SaveDialogCallback& c) { const SaveDialogCallback& c) {
NSSavePanel* dialog = [NSSavePanel savePanel]; NSSavePanel* dialog = [NSSavePanel savePanel];
SetupDialog(dialog, title, button_label, default_path, filters); SetupDialog(dialog, settings);
[dialog setCanSelectHiddenExtension:YES]; [dialog setCanSelectHiddenExtension:YES];
__block SaveDialogCallback callback = c; __block SaveDialogCallback callback = c;
NSWindow* window = parent_window ? parent_window->GetNativeWindow() : NULL; NSWindow* window = settings.parent_window ?
settings.parent_window->GetNativeWindow() :
NULL;
[dialog beginSheetModalForWindow:window [dialog beginSheetModalForWindow:window
completionHandler:^(NSInteger chosen) { completionHandler:^(NSInteger chosen) {
if (chosen == NSFileHandlingPanelCancelButton) { if (chosen == NSFileHandlingPanelCancelButton) {

View file

@ -66,26 +66,24 @@ void ConvertFilters(const Filters& filters,
template <typename T> template <typename T>
class FileDialog { class FileDialog {
public: public:
FileDialog(const base::FilePath& default_path, FileDialog(const DialogSettings& settings, int options) {
const std::string& title,
const std::string& button_label,
const Filters& filters, int options) {
std::wstring file_part; std::wstring file_part;
if (!IsDirectory(default_path)) if (!IsDirectory(settings.default_path))
file_part = default_path.BaseName().value(); file_part = settings.default_path.BaseName().value();
std::vector<std::wstring> buffer; std::vector<std::wstring> buffer;
std::vector<COMDLG_FILTERSPEC> filterspec; std::vector<COMDLG_FILTERSPEC> filterspec;
ConvertFilters(filters, &buffer, &filterspec); ConvertFilters(settings.filters, &buffer, &filterspec);
dialog_.reset(new T(file_part.c_str(), options, NULL, dialog_.reset(new T(file_part.c_str(), options, NULL,
filterspec.data(), filterspec.size())); filterspec.data(), filterspec.size()));
if (!title.empty()) if (!settings.title.empty())
GetPtr()->SetTitle(base::UTF8ToUTF16(title).c_str()); GetPtr()->SetTitle(base::UTF8ToUTF16(settings.title).c_str());
if (!button_label.empty()) if (!settings.button_label.empty())
GetPtr()->SetOkButtonLabel(base::UTF8ToUTF16(button_label).c_str()); GetPtr()->SetOkButtonLabel(
base::UTF8ToUTF16(settings.button_label).c_str());
// By default, *.* will be added to the file name if file type is "*.*". In // By default, *.* will be added to the file name if file type is "*.*". In
// Electron, we disable it to make a better experience. // Electron, we disable it to make a better experience.
@ -107,7 +105,7 @@ class FileDialog {
} }
} }
SetDefaultFolder(default_path); SetDefaultFolder(settings.default_path);
} }
bool Show(atom::NativeWindow* parent_window) { bool Show(atom::NativeWindow* parent_window) {
@ -160,31 +158,20 @@ bool CreateDialogThread(RunState* run_state) {
} }
void RunOpenDialogInNewThread(const RunState& run_state, void RunOpenDialogInNewThread(const RunState& run_state,
atom::NativeWindow* parent, const DialogSettings& settings,
const std::string& title,
const std::string& button_label,
const base::FilePath& default_path,
const Filters& filters,
int properties,
const OpenDialogCallback& callback) { const OpenDialogCallback& callback) {
std::vector<base::FilePath> paths; std::vector<base::FilePath> paths;
bool result = ShowOpenDialog(parent, title, button_label, default_path, bool result = ShowOpenDialog(settings, &paths);
filters, properties, &paths);
run_state.ui_task_runner->PostTask(FROM_HERE, run_state.ui_task_runner->PostTask(FROM_HERE,
base::Bind(callback, result, paths)); base::Bind(callback, result, paths));
run_state.ui_task_runner->DeleteSoon(FROM_HERE, run_state.dialog_thread); run_state.ui_task_runner->DeleteSoon(FROM_HERE, run_state.dialog_thread);
} }
void RunSaveDialogInNewThread(const RunState& run_state, void RunSaveDialogInNewThread(const RunState& run_state,
atom::NativeWindow* parent, const DialogSettings& settings,
const std::string& title,
const std::string& button_label,
const base::FilePath& default_path,
const Filters& filters,
const SaveDialogCallback& callback) { const SaveDialogCallback& callback) {
base::FilePath path; base::FilePath path;
bool result = ShowSaveDialog(parent, title, button_label, default_path, bool result = ShowSaveDialog(settings, &path);
filters, &path);
run_state.ui_task_runner->PostTask(FROM_HERE, run_state.ui_task_runner->PostTask(FROM_HERE,
base::Bind(callback, result, path)); base::Bind(callback, result, path));
run_state.ui_task_runner->DeleteSoon(FROM_HERE, run_state.dialog_thread); run_state.ui_task_runner->DeleteSoon(FROM_HERE, run_state.dialog_thread);
@ -192,26 +179,20 @@ void RunSaveDialogInNewThread(const RunState& run_state,
} // namespace } // namespace
bool ShowOpenDialog(atom::NativeWindow* parent_window, bool ShowOpenDialog(const DialogSettings& settings,
const std::string& title,
const std::string& button_label,
const base::FilePath& default_path,
const Filters& filters,
int properties,
std::vector<base::FilePath>* paths) { std::vector<base::FilePath>* paths) {
int options = FOS_FORCEFILESYSTEM | FOS_FILEMUSTEXIST; int options = FOS_FORCEFILESYSTEM | FOS_FILEMUSTEXIST;
if (properties & FILE_DIALOG_OPEN_DIRECTORY) if (settings.properties & FILE_DIALOG_OPEN_DIRECTORY)
options |= FOS_PICKFOLDERS; options |= FOS_PICKFOLDERS;
if (properties & FILE_DIALOG_MULTI_SELECTIONS) if (settings.properties & FILE_DIALOG_MULTI_SELECTIONS)
options |= FOS_ALLOWMULTISELECT; options |= FOS_ALLOWMULTISELECT;
if (properties & FILE_DIALOG_SHOW_HIDDEN_FILES) if (settings.properties & FILE_DIALOG_SHOW_HIDDEN_FILES)
options |= FOS_FORCESHOWHIDDEN; options |= FOS_FORCESHOWHIDDEN;
if (properties & FILE_DIALOG_PROMPT_TO_CREATE) if (settings.properties & FILE_DIALOG_PROMPT_TO_CREATE)
options |= FOS_CREATEPROMPT; options |= FOS_CREATEPROMPT;
FileDialog<CShellFileOpenDialog> open_dialog( FileDialog<CShellFileOpenDialog> open_dialog(settings, options);
default_path, title, button_label, filters, options); if (!open_dialog.Show(settings.parent_window))
if (!open_dialog.Show(parent_window))
return false; return false;
ATL::CComPtr<IShellItemArray> items; ATL::CComPtr<IShellItemArray> items;
@ -244,12 +225,7 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window,
return true; return true;
} }
void ShowOpenDialog(atom::NativeWindow* parent, void ShowOpenDialog(const DialogSettings& settings,
const std::string& title,
const std::string& button_label,
const base::FilePath& default_path,
const Filters& filters,
int properties,
const OpenDialogCallback& callback) { const OpenDialogCallback& callback) {
RunState run_state; RunState run_state;
if (!CreateDialogThread(&run_state)) { if (!CreateDialogThread(&run_state)) {
@ -259,20 +235,14 @@ void ShowOpenDialog(atom::NativeWindow* parent,
run_state.dialog_thread->task_runner()->PostTask( run_state.dialog_thread->task_runner()->PostTask(
FROM_HERE, FROM_HERE,
base::Bind(&RunOpenDialogInNewThread, run_state, parent, title, base::Bind(&RunOpenDialogInNewThread, run_state, settings, callback));
button_label, default_path, filters, properties, callback));
} }
bool ShowSaveDialog(atom::NativeWindow* parent_window, bool ShowSaveDialog(const DialogSettings& settings,
const std::string& title,
const std::string& button_label,
const base::FilePath& default_path,
const Filters& filters,
base::FilePath* path) { base::FilePath* path) {
FileDialog<CShellFileSaveDialog> save_dialog( FileDialog<CShellFileSaveDialog> save_dialog(
default_path, title, button_label, filters, settings, FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_OVERWRITEPROMPT);
FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_OVERWRITEPROMPT); if (!save_dialog.Show(settings.parent_window))
if (!save_dialog.Show(parent_window))
return false; return false;
wchar_t buffer[MAX_PATH]; wchar_t buffer[MAX_PATH];
@ -284,11 +254,7 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window,
return true; return true;
} }
void ShowSaveDialog(atom::NativeWindow* parent, void ShowSaveDialog(const DialogSettings& settings,
const std::string& title,
const std::string& button_label,
const base::FilePath& default_path,
const Filters& filters,
const SaveDialogCallback& callback) { const SaveDialogCallback& callback) {
RunState run_state; RunState run_state;
if (!CreateDialogThread(&run_state)) { if (!CreateDialogThread(&run_state)) {
@ -298,8 +264,7 @@ void ShowSaveDialog(atom::NativeWindow* parent,
run_state.dialog_thread->task_runner()->PostTask( run_state.dialog_thread->task_runner()->PostTask(
FROM_HERE, FROM_HERE,
base::Bind(&RunSaveDialogInNewThread, run_state, parent, title, base::Bind(&RunSaveDialogInNewThread, run_state, settings, callback));
button_label, default_path, filters, callback));
} }
} // namespace file_dialog } // namespace file_dialog

View file

@ -81,16 +81,16 @@ void WebDialogHelper::RunFileChooser(
content::RenderFrameHost* render_frame_host, content::RenderFrameHost* render_frame_host,
const content::FileChooserParams& params) { const content::FileChooserParams& params) {
std::vector<content::FileChooserFileInfo> result; std::vector<content::FileChooserFileInfo> result;
file_dialog::Filters filters = GetFileTypesFromAcceptType(
params.accept_types); file_dialog::DialogSettings settings;
settings.filters = GetFileTypesFromAcceptType(params.accept_types);
settings.parent_window = window_;
settings.title = base::UTF16ToUTF8(params.title);
if (params.mode == content::FileChooserParams::Save) { if (params.mode == content::FileChooserParams::Save) {
base::FilePath path; base::FilePath path;
if (file_dialog::ShowSaveDialog(window_, settings.default_path = params.default_file_name;
base::UTF16ToUTF8(params.title), if (file_dialog::ShowSaveDialog(settings, &path)) {
"",
params.default_file_name,
filters,
&path)) {
content::FileChooserFileInfo info; content::FileChooserFileInfo info;
info.file_path = path; info.file_path = path;
info.display_name = path.BaseName().value(); info.display_name = path.BaseName().value();
@ -114,15 +114,10 @@ void WebDialogHelper::RunFileChooser(
std::vector<base::FilePath> paths; std::vector<base::FilePath> paths;
AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>( AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>(
window_->web_contents()->GetBrowserContext()); window_->web_contents()->GetBrowserContext());
base::FilePath default_file_path = browser_context->prefs()->GetFilePath( settings.default_path = browser_context->prefs()->GetFilePath(
prefs::kSelectFileLastDirectory).Append(params.default_file_name); prefs::kSelectFileLastDirectory).Append(params.default_file_name);
if (file_dialog::ShowOpenDialog(window_, settings.properties = flags;
base::UTF16ToUTF8(params.title), if (file_dialog::ShowOpenDialog(settings, &paths)) {
"",
default_file_path,
filters,
flags,
&paths)) {
for (auto& path : paths) { for (auto& path : paths) {
content::FileChooserFileInfo info; content::FileChooserFileInfo info;
info.file_path = path; info.file_path = path;

View file

@ -121,8 +121,9 @@ module.exports = {
const wrappedCallback = typeof callback === 'function' ? function (success, result) { const wrappedCallback = typeof callback === 'function' ? function (success, result) {
return callback(success ? result : void 0) return callback(success ? result : void 0)
} : null } : null
return binding.showOpenDialog(title, buttonLabel, defaultPath, filters, const settings = {title, buttonLabel, defaultPath, filters, window}
dialogProperties, window, wrappedCallback) settings.properties = dialogProperties
return binding.showOpenDialog(settings, wrappedCallback)
}, },
showSaveDialog: function (...args) { showSaveDialog: function (...args) {
@ -163,8 +164,8 @@ module.exports = {
const wrappedCallback = typeof callback === 'function' ? function (success, result) { const wrappedCallback = typeof callback === 'function' ? function (success, result) {
return callback(success ? result : void 0) return callback(success ? result : void 0)
} : null } : null
return binding.showSaveDialog(title, buttonLabel, defaultPath, filters, const settings = {title, buttonLabel, defaultPath, filters, window}
window, wrappedCallback) return binding.showSaveDialog(settings, wrappedCallback)
}, },
showMessageBox: function (...args) { showMessageBox: function (...args) {