Browse Source

Add DialogSettings helper struct

Kevin Sawicki 8 years ago
parent
commit
867bb5a94e

+ 24 - 19
atom/browser/api/atom_api_dialog.cc

@@ -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 {
@@ -68,45 +86,32 @@ 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,
-                    atom::NativeWindow* window,
+void ShowOpenDialog(const file_dialog::DialogSettings& settings,
                     mate::Arguments* args) {
   v8::Local<v8::Value> peek = args->PeekNext();
   file_dialog::OpenDialogCallback callback;
   if (mate::Converter<file_dialog::OpenDialogCallback>::FromV8(args->isolate(),
                                                                peek,
                                                                &callback)) {
-    file_dialog::ShowOpenDialog(window, title, button_label, default_path,
-                                filters, properties, callback);
+    file_dialog::ShowOpenDialog(settings, callback);
   } else {
     std::vector<base::FilePath> paths;
-    if (file_dialog::ShowOpenDialog(window, title, button_label, default_path,
-                                    filters, properties, &paths))
+    if (file_dialog::ShowOpenDialog(settings, &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,
+void ShowSaveDialog(const file_dialog::DialogSettings& settings,
                     mate::Arguments* args) {
   v8::Local<v8::Value> peek = args->PeekNext();
   file_dialog::SaveDialogCallback callback;
   if (mate::Converter<file_dialog::SaveDialogCallback>::FromV8(args->isolate(),
                                                                peek,
                                                                &callback)) {
-    file_dialog::ShowSaveDialog(window, title, button_label, default_path,
-                                filters, callback);
+    file_dialog::ShowSaveDialog(settings, callback);
   } else {
     base::FilePath path;
-    if (file_dialog::ShowSaveDialog(window, title, button_label, default_path,
-                                    filters, &path))
+    if (file_dialog::ShowSaveDialog(settings, &path))
       args->Return(path);
   }
 }

+ 5 - 4
atom/browser/atom_download_manager_delegate.cc

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

+ 9 - 9
atom/browser/common_web_contents_delegate.cc

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

+ 13 - 22
atom/browser/ui/file_dialog.h

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

+ 25 - 51
atom/browser/ui/file_dialog_gtk.cc

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

+ 31 - 47
atom/browser/ui/file_dialog_mac.mm

@@ -44,25 +44,23 @@ void SetAllowedFileTypes(NSSavePanel* dialog, const Filters& filters) {
 }
 
 void SetupDialog(NSSavePanel* dialog,
-                 const std::string& title,
-                 const std::string& button_label,
-                 const base::FilePath& default_path,
-                 const Filters& filters) {
-  if (!title.empty())
-    [dialog setTitle:base::SysUTF8ToNSString(title)];
+                 const DialogSettings& settings) {
+  if (!settings.title.empty())
+    [dialog setTitle:base::SysUTF8ToNSString(settings.title)];
 
-  if (!button_label.empty())
-    [dialog setPrompt:base::SysUTF8ToNSString(button_label)];
+  if (!settings.button_label.empty())
+    [dialog setPrompt:base::SysUTF8ToNSString(settings.button_label)];
 
   NSString* default_dir = nil;
   NSString* default_filename = nil;
-  if (!default_path.empty()) {
-    if (base::DirectoryExists(default_path)) {
-      default_dir = base::SysUTF8ToNSString(default_path.value());
+  if (!settings.default_path.empty()) {
+    if (base::DirectoryExists(settings.default_path)) {
+      default_dir = base::SysUTF8ToNSString(settings.default_path.value());
     } else {
-      default_dir = base::SysUTF8ToNSString(default_path.DirName().value());
+      default_dir =
+          base::SysUTF8ToNSString(settings.default_path.DirName().value());
       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)
     [dialog setNameFieldStringValue:default_filename];
 
-  if (filters.empty())
+  if (settings.filters.empty())
     [dialog setAllowsOtherFileTypes:YES];
   else
-    SetAllowedFileTypes(dialog, filters);
+    SetAllowedFileTypes(dialog, settings.filters);
 }
 
 void SetupDialogForProperties(NSOpenPanel* dialog, int properties) {
@@ -117,20 +115,15 @@ void ReadDialogPaths(NSOpenPanel* dialog, std::vector<base::FilePath>* paths) {
 
 }  // namespace
 
-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,
+bool ShowOpenDialog(const DialogSettings& settings,
                     std::vector<base::FilePath>* paths) {
   DCHECK(paths);
   NSOpenPanel* dialog = [NSOpenPanel openPanel];
 
-  SetupDialog(dialog, title, button_label, default_path, filters);
-  SetupDialogForProperties(dialog, properties);
+  SetupDialog(dialog, settings);
+  SetupDialogForProperties(dialog, settings.properties);
 
-  int chosen = RunModalDialog(dialog, parent_window);
+  int chosen = RunModalDialog(dialog, settings.parent_window);
   if (chosen == NSFileHandlingPanelCancelButton)
     return false;
 
@@ -138,23 +131,20 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window,
   return true;
 }
 
-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,
+void ShowOpenDialog(const DialogSettings& settings,
                     const OpenDialogCallback& c) {
   NSOpenPanel* dialog = [NSOpenPanel openPanel];
 
-  SetupDialog(dialog, title, button_label, default_path, filters);
-  SetupDialogForProperties(dialog, properties);
+  SetupDialog(dialog, settings);
+  SetupDialogForProperties(dialog, settings.properties);
 
   // 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.
   __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
                  completionHandler:^(NSInteger chosen) {
     if (chosen == NSFileHandlingPanelCancelButton) {
@@ -167,18 +157,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,
+bool ShowSaveDialog(const DialogSettings& settings,
                     base::FilePath* path) {
   DCHECK(path);
   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])
     return false;
 
@@ -186,20 +172,18 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window,
   return true;
 }
 
-void ShowSaveDialog(atom::NativeWindow* parent_window,
-                    const std::string& title,
-                    const std::string& button_label,
-                    const base::FilePath& default_path,
-                    const Filters& filters,
+void ShowSaveDialog(const DialogSettings& settings,
                     const SaveDialogCallback& c) {
   NSSavePanel* dialog = [NSSavePanel savePanel];
 
-  SetupDialog(dialog, title, button_label, default_path, filters);
+  SetupDialog(dialog, settings);
   [dialog setCanSelectHiddenExtension:YES];
 
   __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
                  completionHandler:^(NSInteger chosen) {
     if (chosen == NSFileHandlingPanelCancelButton) {

+ 28 - 63
atom/browser/ui/file_dialog_win.cc

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

+ 11 - 16
atom/browser/web_dialog_helper.cc

@@ -81,16 +81,16 @@ void WebDialogHelper::RunFileChooser(
     content::RenderFrameHost* render_frame_host,
     const content::FileChooserParams& params) {
   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) {
     base::FilePath path;
-    if (file_dialog::ShowSaveDialog(window_,
-                                    base::UTF16ToUTF8(params.title),
-                                    "",
-                                    params.default_file_name,
-                                    filters,
-                                    &path)) {
+    settings.default_path = params.default_file_name;
+    if (file_dialog::ShowSaveDialog(settings, &path)) {
       content::FileChooserFileInfo info;
       info.file_path = path;
       info.display_name = path.BaseName().value();
@@ -114,15 +114,10 @@ void WebDialogHelper::RunFileChooser(
     std::vector<base::FilePath> paths;
     AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>(
         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);
-    if (file_dialog::ShowOpenDialog(window_,
-                                    base::UTF16ToUTF8(params.title),
-                                    "",
-                                    default_file_path,
-                                    filters,
-                                    flags,
-                                    &paths)) {
+    settings.properties = flags;
+    if (file_dialog::ShowOpenDialog(settings, &paths)) {
       for (auto& path : paths) {
         content::FileChooserFileInfo info;
         info.file_path = path;

+ 5 - 4
lib/browser/api/dialog.js

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