summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoravi@google.com <avi@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-14 20:08:00 +0000
committeravi@google.com <avi@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-14 20:08:00 +0000
commit7bea1c588a1951e65f525cdab0e99c0839be691c (patch)
tree872e6a34522220a976c15b45759e665137deb5d1
parent106c901495fac4d0a09656144e37c6c5abe7a6e0 (diff)
downloadchromium_src-7bea1c588a1951e65f525cdab0e99c0839be691c.zip
chromium_src-7bea1c588a1951e65f525cdab0e99c0839be691c.tar.gz
chromium_src-7bea1c588a1951e65f525cdab0e99c0839be691c.tar.bz2
Add a Cocoa file picker.
Review URL: http://codereview.chromium.org/73044 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@13695 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/nibs/en.lproj/SaveAccessoryView.xib264
-rw-r--r--chrome/browser/browser.h10
-rw-r--r--chrome/browser/cocoa/bookmark_bar_state_controller.mm2
-rw-r--r--chrome/browser/cocoa/browser_window_controller.mm13
-rw-r--r--chrome/browser/cocoa/shell_dialogs_mac.mm333
-rw-r--r--chrome/browser/cocoa/tab_strip_controller.mm11
-rw-r--r--chrome/browser/download/download_manager.cc5
-rw-r--r--chrome/browser/download/download_manager.h8
-rw-r--r--chrome/browser/download/save_package.cc5
-rw-r--r--chrome/browser/download/save_package.h8
-rw-r--r--chrome/browser/gtk/dialogs_gtk.cc5
-rw-r--r--chrome/browser/shell_dialogs.h2
-rw-r--r--chrome/browser/tab_contents/web_contents.h4
-rw-r--r--chrome/chrome.gyp1
-rw-r--r--chrome/common/platform_util_mac.mm10
-rw-r--r--chrome/common/temp_scaffolding_stubs.h28
16 files changed, 628 insertions, 81 deletions
diff --git a/chrome/app/nibs/en.lproj/SaveAccessoryView.xib b/chrome/app/nibs/en.lproj/SaveAccessoryView.xib
new file mode 100644
index 0000000..b7038a0
--- /dev/null
+++ b/chrome/app/nibs/en.lproj/SaveAccessoryView.xib
@@ -0,0 +1,264 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.03">
+ <data>
+ <int key="IBDocument.SystemTarget">1050</int>
+ <string key="IBDocument.SystemVersion">9G55</string>
+ <string key="IBDocument.InterfaceBuilderVersion">677</string>
+ <string key="IBDocument.AppKitVersion">949.43</string>
+ <string key="IBDocument.HIToolboxVersion">353.00</string>
+ <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="1"/>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSCustomObject" id="1001">
+ <string key="NSClassName">NSObject</string>
+ </object>
+ <object class="NSCustomObject" id="1003">
+ <string key="NSClassName">FirstResponder</string>
+ </object>
+ <object class="NSCustomObject" id="1004">
+ <string key="NSClassName">NSApplication</string>
+ </object>
+ <object class="NSCustomView" id="1005">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">268</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSTextField" id="389753419">
+ <reference key="NSNextResponder" ref="1005"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{29, 22}, {124, 17}}</string>
+ <reference key="NSSuperview" ref="1005"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="102144016">
+ <int key="NSCellFlags">68288064</int>
+ <int key="NSCellFlags2">71304192</int>
+ <string key="NSContents">File Format:</string>
+ <object class="NSFont" key="NSSupport" id="260980192">
+ <string key="NSName">LucidaGrande</string>
+ <double key="NSSize">1.300000e+01</double>
+ <int key="NSfFlags">1044</int>
+ </object>
+ <reference key="NSControlView" ref="389753419"/>
+ <object class="NSColor" key="NSBackgroundColor">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">controlColor</string>
+ <object class="NSColor" key="NSColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC42NjY2NjY2OQA</bytes>
+ </object>
+ </object>
+ <object class="NSColor" key="NSTextColor">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">controlTextColor</string>
+ <object class="NSColor" key="NSColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MAA</bytes>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="NSPopUpButton" id="777100300">
+ <reference key="NSNextResponder" ref="1005"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{155, 16}, {237, 26}}</string>
+ <reference key="NSSuperview" ref="1005"/>
+ <int key="NSTag">1234</int>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSPopUpButtonCell" key="NSCell" id="974543815">
+ <int key="NSCellFlags">-2076049856</int>
+ <int key="NSCellFlags2">2048</int>
+ <reference key="NSSupport" ref="260980192"/>
+ <reference key="NSControlView" ref="777100300"/>
+ <int key="NSButtonFlags">109199615</int>
+ <int key="NSButtonFlags2">129</int>
+ <string key="NSAlternateContents"/>
+ <string key="NSKeyEquivalent"/>
+ <int key="NSPeriodicDelay">400</int>
+ <int key="NSPeriodicInterval">75</int>
+ <nil key="NSMenuItem"/>
+ <bool key="NSMenuItemRespectAlignment">YES</bool>
+ <object class="NSMenu" key="NSMenu" id="277609328">
+ <string key="NSTitle">OtherViews</string>
+ <object class="NSMutableArray" key="NSMenuItems">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <int key="NSSelectedIndex">-1</int>
+ <int key="NSPreferredEdge">1</int>
+ <bool key="NSUsesItemFromMenu">YES</bool>
+ <bool key="NSAltersState">YES</bool>
+ <int key="NSArrowPosition">2</int>
+ </object>
+ </object>
+ </object>
+ <string key="NSFrameSize">{480, 59}</string>
+ <reference key="NSSuperview"/>
+ <string key="NSClassName">NSView</string>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <object class="NSArray" key="object" id="1002">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="1001"/>
+ <reference key="parent" ref="1002"/>
+ <string type="base64-UTF8" key="objectName">RmlsZSdzIE93bmVyA</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="1003"/>
+ <reference key="parent" ref="1002"/>
+ <string key="objectName">First Responder</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-3</int>
+ <reference key="object" ref="1004"/>
+ <reference key="parent" ref="1002"/>
+ <string key="objectName">Application</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1</int>
+ <reference key="object" ref="1005"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="777100300"/>
+ <reference ref="389753419"/>
+ </object>
+ <reference key="parent" ref="1002"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">2</int>
+ <reference key="object" ref="389753419"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="102144016"/>
+ </object>
+ <reference key="parent" ref="1005"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">3</int>
+ <reference key="object" ref="102144016"/>
+ <reference key="parent" ref="389753419"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">4</int>
+ <reference key="object" ref="777100300"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="974543815"/>
+ </object>
+ <reference key="parent" ref="1005"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">5</int>
+ <reference key="object" ref="974543815"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="277609328"/>
+ </object>
+ <reference key="parent" ref="777100300"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">6</int>
+ <reference key="object" ref="277609328"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="parent" ref="974543815"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSMutableArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.IBPluginDependency</string>
+ <string>-2.IBPluginDependency</string>
+ <string>-3.IBPluginDependency</string>
+ <string>1.IBEditorWindowLastContentRect</string>
+ <string>1.IBPluginDependency</string>
+ <string>1.WindowOrigin</string>
+ <string>1.editorWindowContentRectSynchronizationRect</string>
+ <string>2.IBPluginDependency</string>
+ <string>3.IBPluginDependency</string>
+ <string>4.IBPluginDependency</string>
+ <string>5.IBPluginDependency</string>
+ <string>6.IBEditorWindowLastContentRect</string>
+ <string>6.IBPluginDependency</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>{{105, 660}, {480, 59}}</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>{628, 654}</string>
+ <string>{{357, 416}, {480, 272}}</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>{{254, 696}, {237, 6}}</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">9</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes"/>
+ <int key="IBDocument.localizationMode">0</int>
+ <nil key="IBDocument.LastKnownRelativeProjectPath"/>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ </data>
+</archive>
diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h
index 1cd85c3..65dba6e 100644
--- a/chrome/browser/browser.h
+++ b/chrome/browser/browser.h
@@ -10,15 +10,11 @@
#include <set>
#include <vector>
-#if defined(OS_MACOSX)
-// Remove when we've finished porting the supporting classes.
-#include "chrome/common/temp_scaffolding_stubs.h"
-#endif
-
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/command_updater.h"
#include "chrome/browser/sessions/session_id.h"
+#include "chrome/browser/shell_dialogs.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/tab_contents/tab_contents_delegate.h"
@@ -30,10 +26,6 @@
#include "base/task.h"
#include "skia/include/SkBitmap.h"
-#if defined(OS_WIN) || defined(OS_LINUX)
-#include "chrome/browser/shell_dialogs.h"
-#endif
-
class BrowserIdleTimer;
class BrowserWindow;
class DebuggerWindow;
diff --git a/chrome/browser/cocoa/bookmark_bar_state_controller.mm b/chrome/browser/cocoa/bookmark_bar_state_controller.mm
index 69d7aa2..e4f9d11a 100644
--- a/chrome/browser/cocoa/bookmark_bar_state_controller.mm
+++ b/chrome/browser/cocoa/bookmark_bar_state_controller.mm
@@ -3,7 +3,9 @@
// found in the LICENSE file.
#import "chrome/browser/cocoa/bookmark_bar_state_controller.h"
+
#include "chrome/browser/bookmarks/bookmark_utils.h"
+#include "chrome/browser/browser.h"
#include "chrome/browser/profile.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
diff --git a/chrome/browser/cocoa/browser_window_controller.mm b/chrome/browser/cocoa/browser_window_controller.mm
index 47b3ef9..7a1cbc4 100644
--- a/chrome/browser/cocoa/browser_window_controller.mm
+++ b/chrome/browser/cocoa/browser_window_controller.mm
@@ -36,6 +36,11 @@ const int kWindowGradientHeight = 24;
// heuristic.
- (void)fixWindowGradient;
+// We need to adjust where sheets come out of the window, as by default they
+// erupt from the omnibox, which is rather weird.
+- (NSRect)window:(NSWindow *)window
+willPositionSheet:(NSWindow *)sheet
+ usingRect:(NSRect)defaultSheetRect;
@end
@@ -413,4 +418,12 @@ const int kWindowGradientHeight = 24;
}
}
+- (NSRect)window:(NSWindow *)window
+willPositionSheet:(NSWindow *)sheet
+ usingRect:(NSRect)defaultSheetRect {
+ NSRect windowFrame = [window frame];
+ defaultSheetRect.origin.y = windowFrame.size.height - 10;
+ return defaultSheetRect;
+}
+
@end
diff --git a/chrome/browser/cocoa/shell_dialogs_mac.mm b/chrome/browser/cocoa/shell_dialogs_mac.mm
index f14beac..2cb35aa 100644
--- a/chrome/browser/cocoa/shell_dialogs_mac.mm
+++ b/chrome/browser/cocoa/shell_dialogs_mac.mm
@@ -4,14 +4,337 @@
#include "chrome/browser/shell_dialogs.h"
+#include <CoreServices/CoreServices.h>
+#import <Cocoa/Cocoa.h>
+#include <map>
+#include <set>
+
#include "base/logging.h"
+#include "base/scoped_cftyperef.h"
+#include "base/scoped_nsobject.h"
+#include "base/sys_string_conversions.h"
+
+static const int kFileTypePopupTag = 1234;
+
+class SelectFileDialogImpl;
+
+// A bridge class to act as the modal delegate to the save/open sheet and send
+// the results to the C++ class.
+@interface SelectFileDialogBridge : NSObject {
+ @private
+ SelectFileDialogImpl* selectFileDialogImpl_; // WEAK; owns us
+}
+
+- (id)initWithSelectFileDialogImpl:(SelectFileDialogImpl*)s;
+- (void)endedPanel:(NSSavePanel *)panel
+ withReturn:(int)returnCode
+ context:(void *)context;
+
+@end
+
+// Implementation of SelectFileDialog that shows Cocoa dialogs for choosing a
+// file or folder.
+class SelectFileDialogImpl : public SelectFileDialog {
+ public:
+ explicit SelectFileDialogImpl(Listener* listener);
+ virtual ~SelectFileDialogImpl();
+
+ // BaseShellDialog implementation.
+ virtual bool IsRunning(gfx::NativeWindow parent_window) const;
+ virtual void ListenerDestroyed();
+
+ // SelectFileDialog implementation.
+ // |params| is user data we pass back via the Listener interface.
+ virtual void SelectFile(Type type,
+ const string16& title,
+ const FilePath& default_path,
+ const FileTypeInfo* file_types,
+ int file_type_index,
+ const FilePath::StringType& default_extension,
+ gfx::NativeWindow owning_window,
+ void* params);
+
+ // Callback from ObjC bridge.
+ void FileWasSelected(NSPanel* dialog,
+ NSWindow* parent_window,
+ bool was_cancelled,
+ bool is_multi,
+ const std::vector<FilePath>& files,
+ int index);
+
+ struct SheetContext {
+ Type type;
+ NSWindow* owning_window;
+ };
+
+ private:
+ // Gets the accessory view for the save dialog.
+ NSView* GetAccessoryView(const FileTypeInfo* file_types,
+ int file_type_index);
+
+ // The listener to be notified of selection completion.
+ Listener* listener_;
+
+ // The bridge for results from Cocoa to return to us.
+ scoped_nsobject<SelectFileDialogBridge> bridge_;
+
+ // A map from file dialogs to the |params| user data associated with them.
+ std::map<NSPanel*, void*> params_map_;
+ // The set of all parent windows for which we are currently running dialogs.
+ std::set<NSWindow*> parents_;
+
+ DISALLOW_COPY_AND_ASSIGN(SelectFileDialogImpl);
+};
+
+// static
SelectFileDialog* SelectFileDialog::Create(Listener* listener) {
- NOTREACHED() << "Implement me.";
- return NULL;
+ return new SelectFileDialogImpl(listener);
+}
+
+SelectFileDialogImpl::SelectFileDialogImpl(Listener* listener)
+ : listener_(listener),
+ bridge_([[SelectFileDialogBridge alloc]
+ initWithSelectFileDialogImpl:this]) {
+}
+
+SelectFileDialogImpl::~SelectFileDialogImpl() {
+}
+
+bool SelectFileDialogImpl::IsRunning(gfx::NativeWindow parent_window) const {
+ return parents_.find(parent_window) != parents_.end();
+}
+
+void SelectFileDialogImpl::ListenerDestroyed() {
+ listener_ = NULL;
+}
+
+void SelectFileDialogImpl::SelectFile(
+ Type type,
+ const string16& title,
+ const FilePath& default_path,
+ const FileTypeInfo* file_types,
+ int file_type_index,
+ const FilePath::StringType& default_extension,
+ gfx::NativeWindow owning_window,
+ void* params) {
+ DCHECK(type == SELECT_FOLDER ||
+ type == SELECT_OPEN_FILE ||
+ type == SELECT_OPEN_MULTI_FILE ||
+ type == SELECT_SAVEAS_FILE);
+ DCHECK(owning_window);
+ parents_.insert(owning_window);
+
+ NSSavePanel* dialog;
+ if (type == SELECT_SAVEAS_FILE)
+ dialog = [NSSavePanel savePanel];
+ else
+ dialog = [NSOpenPanel openPanel];
+
+ if (!title.empty())
+ [dialog setTitle:base::SysUTF16ToNSString(title)];
+
+ NSString* default_dir = nil;
+ NSString* default_filename = nil;
+ if (!default_path.empty()) {
+ default_dir = base::SysUTF8ToNSString(default_path.DirName().value());
+ default_filename = base::SysUTF8ToNSString(default_path.BaseName().value());
+ }
+
+ NSMutableArray* allowed_file_types = nil;
+ if (file_types) {
+ if (!file_types->extensions.empty()) {
+ allowed_file_types = [NSMutableArray array];
+ for (size_t i=0; i < file_types->extensions.size(); ++i) {
+ const std::vector<FilePath::StringType>& ext_list =
+ file_types->extensions[i];
+ for (size_t j=0; j < ext_list.size(); ++j) {
+ [allowed_file_types addObject:base::SysUTF8ToNSString(ext_list[j])];
+ }
+ }
+ }
+ if (type == SELECT_SAVEAS_FILE)
+ [dialog setAllowedFileTypes:allowed_file_types];
+ // else we'll pass it in when we run the open panel
+
+ if (file_types->include_all_files)
+ [dialog setAllowsOtherFileTypes:YES];
+
+ if (!file_types->extension_description_overrides.empty()) {
+ NSView* accessory_view = GetAccessoryView(file_types, file_type_index);
+ [dialog setAccessoryView:accessory_view];
+ }
+ } else {
+ // If no type info is specified, anything goes.
+ [dialog setAllowsOtherFileTypes:YES];
+ }
+
+ if (!default_extension.empty())
+ [dialog setRequiredFileType:base::SysUTF8ToNSString(default_extension)];
+
+ params_map_[dialog] = params;
+
+ SheetContext* context = new SheetContext;
+ context->type = type;
+ context->owning_window = owning_window;
+
+ if (type == SELECT_SAVEAS_FILE) {
+ [dialog beginSheetForDirectory:default_dir
+ file:default_filename
+ modalForWindow:owning_window
+ modalDelegate:bridge_.get()
+ didEndSelector:@selector(endedPanel:withReturn:context:)
+ contextInfo:context];
+ } else {
+ NSOpenPanel* open_dialog = (NSOpenPanel*)dialog;
+
+ if (type == SELECT_OPEN_MULTI_FILE)
+ [open_dialog setAllowsMultipleSelection:YES];
+ else
+ [open_dialog setAllowsMultipleSelection:NO];
+
+ if (type == SELECT_FOLDER) {
+ [open_dialog setCanChooseFiles:NO];
+ [open_dialog setCanChooseDirectories:YES];
+ } else {
+ [open_dialog setCanChooseFiles:YES];
+ [open_dialog setCanChooseDirectories:NO];
+ }
+
+ [open_dialog beginSheetForDirectory:default_dir
+ file:default_filename
+ types:allowed_file_types
+ modalForWindow:owning_window
+ modalDelegate:bridge_.get()
+ didEndSelector:@selector(endedPanel:withReturn:context:)
+ contextInfo:context];
+ }
}
-SelectFontDialog* SelectFontDialog::Create(Listener* listener) {
- NOTREACHED() << "Implement me.";
- return NULL;
+void SelectFileDialogImpl::FileWasSelected(NSPanel* dialog,
+ NSWindow* parent_window,
+ bool was_cancelled,
+ bool is_multi,
+ const std::vector<FilePath>& files,
+ int index) {
+ void* params = params_map_[dialog];
+ params_map_.erase(dialog);
+ parents_.erase(parent_window);
+
+ if (!listener_)
+ return;
+
+ if (was_cancelled) {
+ listener_->FileSelectionCanceled(params);
+ } else {
+ if (is_multi) {
+ listener_->MultiFilesSelected(files, params);
+ } else {
+ listener_->FileSelected(files[0], index, params);
+ }
+ }
}
+
+NSView* SelectFileDialogImpl::GetAccessoryView(const FileTypeInfo* file_types,
+ int file_type_index) {
+ DCHECK(file_types);
+ scoped_nsobject<NSNib> nib (
+ [[NSNib alloc] initWithNibNamed:@"SaveAccessoryView" bundle:nil]);
+ if (!nib)
+ return nil;
+
+ NSArray* objects;
+ BOOL success = [nib instantiateNibWithOwner:nil
+ topLevelObjects:&objects];
+ if (!success)
+ return nil;
+
+ // This is a one-object nib, but IB insists on creating a second object, the
+ // NSApplication. I don't know why.
+ size_t view_index = 0;
+ while (view_index < [objects count] &&
+ ![[objects objectAtIndex:view_index] isKindOfClass:[NSView class]])
+ ++view_index;
+ DCHECK(view_index < [objects count]);
+ NSView* accessory_view = [objects objectAtIndex:view_index];
+
+ NSPopUpButton* popup = [accessory_view viewWithTag:kFileTypePopupTag];
+ DCHECK(popup);
+
+ size_t type_count = file_types->extensions.size();
+ for (size_t type = 0; type<type_count; ++type) {
+ NSString* type_description;
+ if (type < file_types->extension_description_overrides.size()) {
+ type_description = base::SysUTF16ToNSString(
+ file_types->extension_description_overrides[type]);
+ } else {
+ const std::vector<FilePath::StringType>& ext_list =
+ file_types->extensions[type];
+ DCHECK(!ext_list.empty());
+ NSString* type_extension = base::SysUTF8ToNSString(ext_list[0]);
+ scoped_cftyperef<CFStringRef> uti(
+ UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension,
+ (CFStringRef)type_extension,
+ NULL));
+ scoped_cftyperef<CFStringRef> description(
+ UTTypeCopyDescription(uti.get()));
+
+ type_description =
+ [NSString stringWithString:(NSString*)description.get()];
+ }
+ [popup addItemWithTitle:type_description];
+ }
+
+ [popup selectItemAtIndex:file_type_index-1]; // 1-based
+ return accessory_view;
+}
+
+@implementation SelectFileDialogBridge
+
+- (id)initWithSelectFileDialogImpl:(SelectFileDialogImpl*)s {
+ self = [super init];
+ if (self != nil) {
+ selectFileDialogImpl_ = s;
+ }
+ return self;
+}
+
+- (void)endedPanel:(id)panel
+ withReturn:(int)returnCode
+ context:(void *)context {
+ int index = 0;
+ SelectFileDialogImpl::SheetContext* context_struct =
+ (SelectFileDialogImpl::SheetContext*)context;
+
+ SelectFileDialog::Type type = context_struct->type;
+ NSWindow* parentWindow = context_struct->owning_window;
+ delete context_struct;
+
+ bool isMulti = type == SelectFileDialog::SELECT_OPEN_MULTI_FILE;
+
+ std::vector<FilePath> paths;
+ if (type == SelectFileDialog::SELECT_SAVEAS_FILE) {
+ paths.push_back(FilePath(base::SysNSStringToUTF8([panel filename])));
+
+ NSView* accessoryView = [panel accessoryView];
+ if (accessoryView) {
+ NSPopUpButton* popup = [accessoryView viewWithTag:kFileTypePopupTag];
+ if (popup) {
+ index = [popup indexOfSelectedItem]+1; // file type indexes are 1-based
+ }
+ }
+ } else {
+ NSArray* filenames = [panel filenames];
+ for (NSString* filename in filenames)
+ paths.push_back(FilePath(base::SysNSStringToUTF8(filename)));
+ }
+
+ selectFileDialogImpl_->FileWasSelected(panel,
+ parentWindow,
+ returnCode==NSCancelButton,
+ isMulti,
+ paths,
+ index);
+}
+
+@end
diff --git a/chrome/browser/cocoa/tab_strip_controller.mm b/chrome/browser/cocoa/tab_strip_controller.mm
index 920438c..8528ef1 100644
--- a/chrome/browser/cocoa/tab_strip_controller.mm
+++ b/chrome/browser/cocoa/tab_strip_controller.mm
@@ -4,17 +4,18 @@
#import "chrome/browser/cocoa/tab_strip_controller.h"
-#import "base/sys_string_conversions.h"
-#import "chrome/app/chrome_dll_resource.h"
-#import "chrome/browser/browser.h"
+#include "base/sys_string_conversions.h"
+#include "chrome/app/chrome_dll_resource.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/profile.h"
#import "chrome/browser/cocoa/tab_strip_view.h"
#import "chrome/browser/cocoa/tab_cell.h"
#import "chrome/browser/cocoa/tab_contents_controller.h"
#import "chrome/browser/cocoa/tab_controller.h"
#import "chrome/browser/cocoa/tab_strip_model_observer_bridge.h"
#import "chrome/browser/cocoa/tab_view.h"
-#import "chrome/browser/tab_contents/tab_contents.h"
-#import "chrome/browser/tabs/tab_strip_model.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/tabs/tab_strip_model.h"
@implementation TabStripController
diff --git a/chrome/browser/download/download_manager.cc b/chrome/browser/download/download_manager.cc
index e6a1b0c..92d20db 100644
--- a/chrome/browser/download/download_manager.cc
+++ b/chrome/browser/download/download_manager.cc
@@ -628,7 +628,6 @@ void DownloadManager::CheckIfSuggestedPathExists(DownloadCreateInfo* info) {
}
void DownloadManager::OnPathExistenceAvailable(DownloadCreateInfo* info) {
-#if defined(OS_WIN) || defined(OS_LINUX)
DCHECK(MessageLoop::current() == ui_loop_);
DCHECK(info);
@@ -654,10 +653,6 @@ void DownloadManager::OnPathExistenceAvailable(DownloadCreateInfo* info) {
// No prompting for download, just continue with the suggested name.
ContinueStartDownload(info, info->suggested_path);
}
-#elif defined(OS_MACOSX)
- // TODO(port): port this file -- need dialogs.
- NOTIMPLEMENTED();
-#endif
}
void DownloadManager::ContinueStartDownload(DownloadCreateInfo* info,
diff --git a/chrome/browser/download/download_manager.h b/chrome/browser/download/download_manager.h
index 8e7c9d4..5cb22a4 100644
--- a/chrome/browser/download/download_manager.h
+++ b/chrome/browser/download/download_manager.h
@@ -51,14 +51,8 @@
#include "chrome/browser/cancelable_request.h"
#include "chrome/browser/history/download_types.h"
#include "chrome/browser/history/history.h"
-#include "chrome/common/pref_member.h"
-
-#if defined(OS_WIN) || defined(OS_LINUX)
-// TODO(port): port this header.
#include "chrome/browser/shell_dialogs.h"
-#elif defined(OS_MACOSX)
-#include "chrome/common/temp_scaffolding_stubs.h"
-#endif
+#include "chrome/common/pref_member.h"
class DownloadFileManager;
class DownloadItemView;
diff --git a/chrome/browser/download/save_package.cc b/chrome/browser/download/save_package.cc
index 01a1b26..0c40a82 100644
--- a/chrome/browser/download/save_package.cc
+++ b/chrome/browser/download/save_package.cc
@@ -1025,7 +1025,6 @@ void SavePackage::GetSaveInfo() {
file_type_index = 1;
}
-#if defined(OS_LINUX) || defined(OS_WIN)
if (g_should_prompt_for_filename) {
if (!select_file_dialog_.get())
select_file_dialog_ = SelectFileDialog::Create(this);
@@ -1038,9 +1037,7 @@ void SavePackage::GetSaveInfo() {
platform_util::GetTopLevel(
web_contents_->GetNativeView()),
save_params);
- } else
-#endif // defined(OS_LINUX) || defined(OS_WIN)
- {
+ } else {
// Just use 'suggested_path' instead of opening the dialog prompt.
ContinueSave(save_params, suggested_path, file_type_index);
delete save_params;
diff --git a/chrome/browser/download/save_package.h b/chrome/browser/download/save_package.h
index 5a42fe3..8feabd3 100644
--- a/chrome/browser/download/save_package.h
+++ b/chrome/browser/download/save_package.h
@@ -19,6 +19,7 @@
#include "chrome/browser/download/save_item.h"
#include "chrome/browser/download/save_types.h"
#include "chrome/browser/renderer_host/render_view_host_delegate.h"
+#include "chrome/browser/shell_dialogs.h"
class SaveFileManager;
class SavePackage;
@@ -32,13 +33,6 @@ class WebContents;
class URLRequestContext;
class WebContents;
-#if defined(OS_WIN) || defined(OS_LINUX)
-// TODO(port): port this header.
-#include "chrome/browser/shell_dialogs.h"
-#elif defined(OS_MACOSX)
-#include "chrome/common/temp_scaffolding_stubs.h"
-#endif
-
namespace base {
class Thread;
class Time;
diff --git a/chrome/browser/gtk/dialogs_gtk.cc b/chrome/browser/gtk/dialogs_gtk.cc
index 113edb2..f25b695 100644
--- a/chrome/browser/gtk/dialogs_gtk.cc
+++ b/chrome/browser/gtk/dialogs_gtk.cc
@@ -83,9 +83,6 @@ class SelectFileDialogImpl : public SelectFileDialog {
// The listener to be notified of selection completion.
Listener* listener_;
- // Our parent window.
- gfx::NativeWindow parent_window_;
-
// A map from dialog windows to the |params| user data associated with them.
std::map<GtkWidget*, void*> params_map_;
@@ -126,7 +123,7 @@ void SelectFileDialogImpl::SelectFile(
const FilePath::StringType& default_extension,
gfx::NativeWindow owning_window,
void* params) {
- // TODO(estade): on windows, parent_window may be null. But I'm not sure when
+ // TODO(estade): on windows, owning_window may be null. But I'm not sure when
// that's used and how to deal with it here. For now, don't allow it.
DCHECK(owning_window);
parents_.insert(owning_window);
diff --git a/chrome/browser/shell_dialogs.h b/chrome/browser/shell_dialogs.h
index 4285364..421f461 100644
--- a/chrome/browser/shell_dialogs.h
+++ b/chrome/browser/shell_dialogs.h
@@ -18,7 +18,7 @@ class ChromeFont;
// A base class for shell dialogs.
class BaseShellDialog {
public:
- // Returns true if the a shell dialog box is currently being shown modally
+ // Returns true if a shell dialog box is currently being shown modally
// to the specified owner.
virtual bool IsRunning(gfx::NativeWindow owning_window) const = 0;
diff --git a/chrome/browser/tab_contents/web_contents.h b/chrome/browser/tab_contents/web_contents.h
index d02322e..09cdba3 100644
--- a/chrome/browser/tab_contents/web_contents.h
+++ b/chrome/browser/tab_contents/web_contents.h
@@ -15,6 +15,7 @@
#include "chrome/browser/fav_icon_helper.h"
#include "chrome/browser/find_notification_details.h"
#include "chrome/browser/renderer_host/render_view_host_delegate.h"
+#include "chrome/browser/shell_dialogs.h"
#include "chrome/browser/tab_contents/navigation_controller.h"
#include "chrome/browser/tab_contents/render_view_host_manager.h"
#include "chrome/browser/tab_contents/tab_contents.h"
@@ -29,9 +30,6 @@
#elif defined(OS_WIN)
#include "chrome/browser/printing/print_view_manager.h"
#endif
-#if defined(OS_LINUX) || defined(OS_WIN)
-#include "chrome/browser/shell_dialogs.h"
-#endif
class AutofillForm;
class AutofillManager;
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 9fca304..cfa4ee4 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -1570,6 +1570,7 @@
'mac_bundle_resources': [
'app/nibs/en.lproj/BrowserWindow.xib',
'app/nibs/en.lproj/MainMenu.xib',
+ 'app/nibs/en.lproj/SaveAccessoryView.xib',
'app/nibs/en.lproj/TabContents.xib',
'app/nibs/en.lproj/TabView.xib',
'app/nibs/en.lproj/Toolbar.xib',
diff --git a/chrome/common/platform_util_mac.mm b/chrome/common/platform_util_mac.mm
index 3ee3a2f..308c3af 100644
--- a/chrome/common/platform_util_mac.mm
+++ b/chrome/common/platform_util_mac.mm
@@ -4,18 +4,22 @@
#include "chrome/common/platform_util.h"
+#import <Cocoa/Cocoa.h>
+
#include "base/file_path.h"
#include "base/logging.h"
+#include "base/sys_string_conversions.h"
namespace platform_util {
void ShowItemInFolder(const FilePath& full_path) {
- NOTIMPLEMENTED();
+ NSString* path_string = base::SysUTF8ToNSString(full_path.value());
+ [[NSWorkspace sharedWorkspace] selectFile:path_string
+ inFileViewerRootedAtPath:nil];
}
gfx::NativeWindow GetTopLevel(gfx::NativeView view) {
- NOTIMPLEMENTED();
- return NULL;
+ return [view window];
}
} // namespace platform_util
diff --git a/chrome/common/temp_scaffolding_stubs.h b/chrome/common/temp_scaffolding_stubs.h
index f617781..803db6a 100644
--- a/chrome/common/temp_scaffolding_stubs.h
+++ b/chrome/common/temp_scaffolding_stubs.h
@@ -362,34 +362,6 @@ class FaviconStatus {
GURL url_;
};
-#if defined(OS_MACOSX)
-class SelectFileDialog : public base::RefCountedThreadSafe<SelectFileDialog> {
- public:
- enum Type {
- SELECT_FOLDER,
- SELECT_SAVEAS_FILE,
- SELECT_OPEN_FILE,
- SELECT_OPEN_MULTI_FILE
- };
- class Listener {
- public:
- };
- struct FileTypeInfo {
- std::vector<std::vector<FilePath::StringType> > extensions;
- std::vector<string16> extension_description_overrides;
- bool include_all_files;
- };
- void ListenerDestroyed() { NOTIMPLEMENTED(); }
- void SelectFile(Type, const string16&, const FilePath&,
- const FileTypeInfo*, int, const FilePath::StringType&,
- gfx::NativeWindow, void*) { NOTIMPLEMENTED(); }
- static SelectFileDialog* Create(WebContents*) {
- NOTIMPLEMENTED();
- return new SelectFileDialog;
- }
-};
-#endif
-
class DockInfo {
public:
bool GetNewWindowBounds(gfx::Rect*, bool*) const {