Browse Source

Add "filters" parameter for file dialogs.

Cheng Zhao 10 years ago
parent
commit
dc257f1f86

+ 30 - 6
atom/browser/api/atom_api_dialog.cc

@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "atom/browser/api/atom_api_window.h"
@@ -16,6 +17,26 @@
 
 #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 {
 
 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<file_dialog::OpenDialogCallback>::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<base::FilePath> 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<v8::Value> peek = args->PeekNext();
@@ -68,10 +91,11 @@ void ShowSaveDialog(const std::string& title,
   if (mate::Converter<file_dialog::SaveDialogCallback>::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);
   }
 }

+ 4 - 0
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
 

+ 2 - 1
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;

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

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

+ 4 - 0
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<base::FilePath>* 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);

+ 4 - 0
atom/browser/ui/file_dialog_mac.mm

@@ -83,6 +83,7 @@ void ReadDialogPaths(NSOpenPanel* dialog, std::vector<base::FilePath>* paths) {
 bool ShowOpenDialog(atom::NativeWindow* parent_window,
                     const std::string& title,
                     const base::FilePath& default_path,
+                    const Filters& filters,
                     int properties,
                     std::vector<base::FilePath>* 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];
 

+ 7 - 1
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<base::FilePath>* 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<base::FilePath> 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<std::wstring> 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);
 }