mac: Implement the filters option.

This commit is contained in:
Cheng Zhao 2014-08-06 13:47:44 +08:00
parent dc257f1f86
commit 0721b34847
3 changed files with 47 additions and 11 deletions

View file

@ -3,7 +3,10 @@ v8Util = process.atomBinding 'v8_util'
BrowserWindow = require 'browser-window'
fileDialogProperties =
openFile: 1, openDirectory: 2, multiSelections: 4, createDirectory: 8
openFile: 1 << 0
openDirectory: 1 << 1
multiSelections: 1 << 2
createDirectory: 1 << 3
messageBoxTypes = ['none', 'info', 'warning']

View file

@ -23,10 +23,10 @@ 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,
FILE_DIALOG_MULTI_SELECTIONS = 4,
FILE_DIALOG_CREATE_DIRECTORY = 8,
FILE_DIALOG_OPEN_FILE = 1 << 0,
FILE_DIALOG_OPEN_DIRECTORY = 1 << 1,
FILE_DIALOG_MULTI_SELECTIONS = 1 << 2,
FILE_DIALOG_CREATE_DIRECTORY = 1 << 3,
};
typedef base::Callback<void(

View file

@ -9,15 +9,45 @@
#include "atom/browser/native_window.h"
#include "base/file_util.h"
#include "base/mac/mac_util.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/strings/sys_string_conversions.h"
namespace file_dialog {
namespace {
CFStringRef CreateUTIFromExtension(const std::string& ext) {
base::ScopedCFTypeRef<CFStringRef> ext_cf(base::SysUTF8ToCFStringRef(ext));
return UTTypeCreatePreferredIdentifierForTag(
kUTTagClassFilenameExtension, ext_cf.get(), NULL);
}
void SetAllowedFileTypes(NSSavePanel* dialog, const Filters& filters) {
NSMutableSet* file_type_set = [NSMutableSet set];
for (size_t i = 0; i < filters.size(); ++i) {
const Filter& filter = filters[i];
for (size_t j = 0; j < filter.second.size(); ++j) {
base::ScopedCFTypeRef<CFStringRef> uti(
CreateUTIFromExtension(filter.second[j]));
[file_type_set addObject:base::mac::CFToNSCast(uti.get())];
// Always allow the extension itself, in case the UTI doesn't map
// back to the original extension correctly. This occurs with dynamic
// UTIs on 10.7 and 10.8.
// See http://crbug.com/148840, http://openradar.me/12316273
base::ScopedCFTypeRef<CFStringRef> ext_cf(
base::SysUTF8ToCFStringRef(filter.second[j]));
[file_type_set addObject:base::mac::CFToNSCast(ext_cf.get())];
}
}
[dialog setAllowedFileTypes:[file_type_set allObjects]];
}
void SetupDialog(NSSavePanel* dialog,
const std::string& title,
const base::FilePath& default_path) {
const base::FilePath& default_path,
const Filters& filters) {
if (!title.empty())
[dialog setTitle:base::SysUTF8ToNSString(title)];
@ -39,7 +69,10 @@ void SetupDialog(NSSavePanel* dialog,
[dialog setNameFieldStringValue:default_filename];
[dialog setCanSelectHiddenExtension:YES];
[dialog setAllowsOtherFileTypes:YES];
if (filters.empty())
[dialog setAllowsOtherFileTypes:YES];
else
SetAllowedFileTypes(dialog, filters);
}
void SetupDialogForProperties(NSOpenPanel* dialog, int properties) {
@ -89,7 +122,7 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window,
DCHECK(paths);
NSOpenPanel* dialog = [NSOpenPanel openPanel];
SetupDialog(dialog, title, default_path);
SetupDialog(dialog, title, default_path, filters);
SetupDialogForProperties(dialog, properties);
int chosen = RunModalDialog(dialog, parent_window);
@ -108,7 +141,7 @@ void ShowOpenDialog(atom::NativeWindow* parent_window,
const OpenDialogCallback& c) {
NSOpenPanel* dialog = [NSOpenPanel openPanel];
SetupDialog(dialog, title, default_path);
SetupDialog(dialog, title, default_path, filters);
SetupDialogForProperties(dialog, properties);
// Duplicate the callback object here since c is a reference and gcd would
@ -136,7 +169,7 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window,
DCHECK(path);
NSSavePanel* dialog = [NSSavePanel savePanel];
SetupDialog(dialog, title, default_path);
SetupDialog(dialog, title, default_path, filters);
int chosen = RunModalDialog(dialog, parent_window);
if (chosen == NSFileHandlingPanelCancelButton || ![[dialog URL] isFileURL])
@ -153,7 +186,7 @@ void ShowSaveDialog(atom::NativeWindow* parent_window,
const SaveDialogCallback& c) {
NSSavePanel* dialog = [NSSavePanel savePanel];
SetupDialog(dialog, title, default_path);
SetupDialog(dialog, title, default_path, filters);
__block SaveDialogCallback callback = c;