Browse Source

:apple: Add additional options for Mac's save dialog

Support additional attributes available in macOS's NSSavePanel: message,
nameFieldLabel and showsTagField
Tan Wang Leng 8 years ago
parent
commit
1d612a12a1

+ 7 - 2
atom/browser/api/atom_api_dialog.cc

@@ -92,6 +92,9 @@ void ShowSaveDialog(const std::string& title,
                     const std::string& button_label,
                     const base::FilePath& default_path,
                     const file_dialog::Filters& filters,
+                    const std::string& message,
+                    const std::string& name_field_label,
+                    const bool& shows_tag_field,
                     atom::NativeWindow* window,
                     mate::Arguments* args) {
   v8::Local<v8::Value> peek = args->PeekNext();
@@ -100,11 +103,13 @@ void ShowSaveDialog(const std::string& title,
                                                                peek,
                                                                &callback)) {
     file_dialog::ShowSaveDialog(window, title, button_label, default_path,
-                                filters, callback);
+                                filters, message, name_field_label,
+                                shows_tag_field, callback);
   } else {
     base::FilePath path;
     if (file_dialog::ShowSaveDialog(window, title, button_label, default_path,
-                                    filters, &path))
+                                    filters, message, name_field_label,
+                                    shows_tag_field, &path))
       args->Return(path);
   }
 }

+ 1 - 0
atom/browser/atom_download_manager_delegate.cc

@@ -93,6 +93,7 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
   if (path.empty() && file_dialog::ShowSaveDialog(window, item->GetURL().spec(),
                                                   "", default_path,
                                                   file_dialog::Filters(),
+                                                  "", "", false,
                                                   &path)) {
     // Remember the last selected download directory.
     AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>(

+ 1 - 1
atom/browser/common_web_contents_delegate.cc

@@ -297,7 +297,7 @@ void CommonWebContentsDelegate::DevToolsSaveToFile(
     file_dialog::Filters filters;
     base::FilePath default_path(base::FilePath::FromUTF8Unsafe(url));
     if (!file_dialog::ShowSaveDialog(owner_window(), url, "", default_path,
-                                     filters, &path)) {
+                                     filters, "", "", false, &path)) {
       base::StringValue url_value(url);
       web_contents_->CallClientFunction(
           "DevToolsAPI.canceledSaveURL", &url_value, nullptr, nullptr);

+ 6 - 0
atom/browser/ui/file_dialog.h

@@ -58,6 +58,9 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window,
                     const std::string& button_label,
                     const base::FilePath& default_path,
                     const Filters& filters,
+                    const std::string& message,
+                    const std::string& name_field_label,
+                    const bool& shows_tag_field,
                     base::FilePath* path);
 
 void ShowSaveDialog(atom::NativeWindow* parent_window,
@@ -65,6 +68,9 @@ void ShowSaveDialog(atom::NativeWindow* parent_window,
                     const std::string& button_label,
                     const base::FilePath& default_path,
                     const Filters& filters,
+                    const std::string& message,
+                    const std::string& name_field_label,
+                    const bool& shows_tag_field,
                     const SaveDialogCallback& callback);
 
 }  // namespace file_dialog

+ 3 - 0
atom/browser/ui/file_dialog_gtk.cc

@@ -275,6 +275,9 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window,
                     const std::string& button_label,
                     const base::FilePath& default_path,
                     const Filters& filters,
+                    const std::string& message,
+                    const std::string& name_field_label,
+                    const bool& shows_tag_field,
                     base::FilePath* path) {
   FileChooserDialog save_dialog(GTK_FILE_CHOOSER_ACTION_SAVE, parent_window,
                                 title, button_label, default_path, filters);

+ 26 - 5
atom/browser/ui/file_dialog_mac.mm

@@ -47,13 +47,24 @@ void SetupDialog(NSSavePanel* dialog,
                  const std::string& title,
                  const std::string& button_label,
                  const base::FilePath& default_path,
-                 const Filters& filters) {
+                 const Filters& filters,
+                 const std::string& message,
+                 const std::string& name_field_label,
+                 const bool& shows_tag_field) {
   if (!title.empty())
     [dialog setTitle:base::SysUTF8ToNSString(title)];
 
   if (!button_label.empty())
     [dialog setPrompt:base::SysUTF8ToNSString(button_label)];
 
+  if (!message.empty())
+    [dialog setMessage:base::SysUTF8ToNSString(message)];
+
+  if (!name_field_label.empty())
+    [dialog setNameFieldLabel:base::SysUTF8ToNSString(name_field_label)];
+
+  [dialog setShowsTagField:shows_tag_field];
+
   NSString* default_dir = nil;
   NSString* default_filename = nil;
   if (!default_path.empty()) {
@@ -127,7 +138,8 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window,
   DCHECK(paths);
   NSOpenPanel* dialog = [NSOpenPanel openPanel];
 
-  SetupDialog(dialog, title, button_label, default_path, filters);
+// TODO yamgent: Fix this
+  SetupDialog(dialog, title, button_label, default_path, filters, "", "", false);
   SetupDialogForProperties(dialog, properties);
 
   int chosen = RunModalDialog(dialog, parent_window);
@@ -147,7 +159,8 @@ void ShowOpenDialog(atom::NativeWindow* parent_window,
                     const OpenDialogCallback& c) {
   NSOpenPanel* dialog = [NSOpenPanel openPanel];
 
-  SetupDialog(dialog, title, button_label, default_path, filters);
+// TODO yamgent: Fix this
+  SetupDialog(dialog, title, button_label, default_path, filters, "", "", false);
   SetupDialogForProperties(dialog, properties);
 
   // Duplicate the callback object here since c is a reference and gcd would
@@ -172,11 +185,15 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window,
                     const std::string& button_label,
                     const base::FilePath& default_path,
                     const Filters& filters,
+                    const std::string& message,
+                    const std::string& name_field_label,
+                    const bool& shows_tag_field,
                     base::FilePath* path) {
   DCHECK(path);
   NSSavePanel* dialog = [NSSavePanel savePanel];
 
-  SetupDialog(dialog, title, button_label, default_path, filters);
+  SetupDialog(dialog, title, button_label, default_path, filters, message,
+                name_field_label, shows_tag_field);
 
   int chosen = RunModalDialog(dialog, parent_window);
   if (chosen == NSFileHandlingPanelCancelButton || ![[dialog URL] isFileURL])
@@ -191,10 +208,14 @@ void ShowSaveDialog(atom::NativeWindow* parent_window,
                     const std::string& button_label,
                     const base::FilePath& default_path,
                     const Filters& filters,
+                    const std::string& message,
+                    const std::string& name_field_label,
+                    const bool& shows_tag_field,
                     const SaveDialogCallback& c) {
   NSSavePanel* dialog = [NSSavePanel savePanel];
 
-  SetupDialog(dialog, title, button_label, default_path, filters);
+  SetupDialog(dialog, title, button_label, default_path, filters, message,
+                name_field_label, shows_tag_field);
   [dialog setCanSelectHiddenExtension:YES];
 
   __block SaveDialogCallback callback = c;

+ 6 - 0
atom/browser/ui/file_dialog_win.cc

@@ -268,6 +268,9 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window,
                     const std::string& button_label,
                     const base::FilePath& default_path,
                     const Filters& filters,
+                    const std::string& message,
+                    const std::string& name_field_label,
+                    const bool& shows_tag_field,
                     base::FilePath* path) {
   FileDialog<CShellFileSaveDialog> save_dialog(
       default_path, title, button_label, filters,
@@ -289,6 +292,9 @@ void ShowSaveDialog(atom::NativeWindow* parent,
                     const std::string& button_label,
                     const base::FilePath& default_path,
                     const Filters& filters,
+                    const std::string& message,
+                    const std::string& name_field_label,
+                    const bool& shows_tag_field,
                     const SaveDialogCallback& callback) {
   RunState run_state;
   if (!CreateDialogThread(&run_state)) {

+ 3 - 0
atom/browser/web_dialog_helper.cc

@@ -90,6 +90,9 @@ void WebDialogHelper::RunFileChooser(
                                     "",
                                     params.default_file_name,
                                     filters,
+                                    "",
+                                    "",
+                                    false,
                                     &path)) {
       content::FileChooserFileInfo info;
       info.file_path = path;

+ 19 - 1
lib/browser/api/dialog.js

@@ -136,7 +136,8 @@ module.exports = {
       }
     }
 
-    let {buttonLabel, defaultPath, filters, title} = options
+    let {buttonLabel, defaultPath, filters, title, message, nameFieldLabel,
+      showsTagField} = options
 
     if (title == null) {
       title = ''
@@ -160,10 +161,27 @@ module.exports = {
       filters = []
     }
 
+    if (message == null) {
+      message = ''
+    } else if (typeof message !== 'string') {
+      throw new TypeError('Message must be a string')
+    }
+
+    if (nameFieldLabel == null) {
+      nameFieldLabel = ''
+    } else if (typeof nameFieldLabel !== 'string') {
+      throw new TypeError('Name field label must be a string')
+    }
+
+    if (showsTagField == null) {
+      showsTagField = false
+    }
+
     const wrappedCallback = typeof callback === 'function' ? function (success, result) {
       return callback(success ? result : void 0)
     } : null
     return binding.showSaveDialog(title, buttonLabel, defaultPath, filters,
+                                  message, nameFieldLabel, showsTagField,
                                   window, wrappedCallback)
   },