1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/logging.h"
6 #include "chrome/browser/extensions/extension_file_browser_private_api.h"
7 #include "chrome/browser/extensions/file_manager_util.h"
8 #include "chrome/browser/metrics/user_metrics.h"
9 #include "chrome/browser/profiles/profile_manager.h"
10 #include "chrome/browser/ui/browser.h"
11 #include "chrome/browser/ui/browser_dialogs.h"
12 #include "chrome/browser/ui/browser_list.h"
13 #include "chrome/browser/ui/views/html_dialog_view.h"
14 #include "chrome/browser/ui/views/window.h"
15 #include "chrome/browser/ui/webui/html_dialog_ui.h"
16 #include "content/browser/browser_thread.h"
17 #include "content/browser/tab_contents/tab_contents.h"
18 #include "views/window/window.h"
19 #include "ui/gfx/rect.h"
20 #include "ui/gfx/size.h"
21
22 // Shows a dialog box for selecting a file or a folder.
23 class FileManagerDialog
24 : public SelectFileDialog,
25 public HtmlDialogUIDelegate {
26
27 public:
28 explicit FileManagerDialog(Listener* listener);
29
CreateHtmlDialogView(Profile * profile,void * params)30 void CreateHtmlDialogView(Profile* profile, void* params) {
31 HtmlDialogView* html_view = new HtmlDialogView(profile, this);
32 browser::CreateViewsWindow(owner_window_, gfx::Rect(), html_view);
33 html_view->InitDialog();
34 html_view->window()->Show();
35 tab_id_ = html_view->tab_contents()->controller().session_id().id();
36
37 // Register our callback and associate it with our tab.
38 FileDialogFunction::Callback::Add(tab_id_, listener_, html_view, params);
39 }
40
41 // BaseShellDialog implementation.
42
IsRunning(gfx::NativeWindow owner_window) const43 virtual bool IsRunning(gfx::NativeWindow owner_window) const {
44 return owner_window_ == owner_window;
45 }
46
ListenerDestroyed()47 virtual void ListenerDestroyed() {
48 listener_ = NULL;
49 FileDialogFunction::Callback::Remove(tab_id_);
50 }
51
52 // SelectFileDialog implementation.
set_browser_mode(bool value)53 virtual void set_browser_mode(bool value) {
54 browser_mode_ = value;
55 }
56
57 // HtmlDialogUIDelegate implementation.
58
IsDialogModal() const59 virtual bool IsDialogModal() const {
60 return true;
61 }
62
GetDialogTitle() const63 virtual std::wstring GetDialogTitle() const {
64 return title_;
65 }
66
GetDialogContentURL() const67 virtual GURL GetDialogContentURL() const {
68 return dialog_url_;
69 }
70
GetWebUIMessageHandlers(std::vector<WebUIMessageHandler * > * handlers) const71 virtual void GetWebUIMessageHandlers(
72 std::vector<WebUIMessageHandler*>* handlers) const {
73 }
74
75 // Get the size of the dialog.
GetDialogSize(gfx::Size * size) const76 virtual void GetDialogSize(gfx::Size* size) const {
77 size->set_width(720);
78 size->set_height(580);
79 }
80
GetDialogArgs() const81 virtual std::string GetDialogArgs() const {
82 return "";
83 }
84
85 // A callback to notify the delegate that the dialog closed.
OnDialogClosed(const std::string & json_retval)86 virtual void OnDialogClosed(const std::string& json_retval) {
87 owner_window_ = NULL;
88 }
89
OnWindowClosed()90 virtual void OnWindowClosed() {
91 // Directly closing the window selects no files.
92 const FileDialogFunction::Callback& callback =
93 FileDialogFunction::Callback::Find(tab_id_);
94 if (!callback.IsNull())
95 callback.listener()->FileSelectionCanceled(callback.params());
96 }
97
98 // A callback to notify the delegate that the contents have gone
99 // away. Only relevant if your dialog hosts code that calls
100 // windows.close() and you've allowed that. If the output parameter
101 // is set to true, then the dialog is closed. The default is false.
OnCloseContents(TabContents * source,bool * out_close_dialog)102 virtual void OnCloseContents(TabContents* source, bool* out_close_dialog) {
103 *out_close_dialog = true;
104 }
105
106 // A callback to allow the delegate to dictate that the window should not
107 // have a title bar. This is useful when presenting branded interfaces.
ShouldShowDialogTitle() const108 virtual bool ShouldShowDialogTitle() const {
109 return false;
110 }
111
112 // A callback to allow the delegate to inhibit context menu or show
113 // customized menu.
HandleContextMenu(const ContextMenuParams & params)114 virtual bool HandleContextMenu(const ContextMenuParams& params) {
115 return true;
116 }
117
118 protected:
119 // SelectFileDialog implementation.
120 virtual void SelectFileImpl(Type type,
121 const string16& title,
122 const FilePath& default_path,
123 const FileTypeInfo* file_types,
124 int file_type_index,
125 const FilePath::StringType& default_extension,
126 gfx::NativeWindow owning_window,
127 void* params);
128
129 private:
~FileManagerDialog()130 virtual ~FileManagerDialog() {}
131
132 int32 tab_id_;
133
134 // True when opening in browser, otherwise in OOBE/login mode.
135 bool browser_mode_;
136
137 gfx::NativeWindow owner_window_;
138
139 std::wstring title_;
140
141 // Base url plus query string.
142 GURL dialog_url_;
143
144 DISALLOW_COPY_AND_ASSIGN(FileManagerDialog);
145 };
146
147 // Linking this implementation of SelectFileDialog::Create into the target
148 // selects FileManagerDialog as the dialog of choice.
149 // static
Create(Listener * listener)150 SelectFileDialog* SelectFileDialog::Create(Listener* listener) {
151 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
152 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::FILE));
153 return new FileManagerDialog(listener);
154 }
155
FileManagerDialog(Listener * listener)156 FileManagerDialog::FileManagerDialog(Listener* listener)
157 : SelectFileDialog(listener),
158 tab_id_(0),
159 browser_mode_(true),
160 owner_window_(0) {
161 }
162
SelectFileImpl(Type type,const string16 & title,const FilePath & default_path,const FileTypeInfo * file_types,int file_type_index,const FilePath::StringType & default_extension,gfx::NativeWindow owner_window,void * params)163 void FileManagerDialog::SelectFileImpl(
164 Type type,
165 const string16& title,
166 const FilePath& default_path,
167 const FileTypeInfo* file_types,
168 int file_type_index,
169 const FilePath::StringType& default_extension,
170 gfx::NativeWindow owner_window,
171 void* params) {
172
173 if (owner_window_) {
174 LOG(ERROR) << "File dialog already in use!";
175 return;
176 }
177
178 title_ = UTF16ToWide(title);
179 owner_window_ = owner_window;
180
181 dialog_url_ = FileManagerUtil::GetFileBrowserUrlWithParams(type, title,
182 default_path, file_types, file_type_index, default_extension);
183
184 if (browser_mode_) {
185 Browser* browser = BrowserList::GetLastActive();
186 if (browser) {
187 DCHECK_EQ(browser->type(), Browser::TYPE_NORMAL);
188 CreateHtmlDialogView(browser->profile(), params);
189 return;
190 }
191 }
192
193 BrowserThread::PostTask(
194 BrowserThread::UI,
195 FROM_HERE,
196 NewRunnableMethod(this,
197 &FileManagerDialog::CreateHtmlDialogView,
198 ProfileManager::GetDefaultProfile(), params));
199 }
200
201