Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Side by Side Diff: chrome/browser/ui/views/select_file_dialog_extension.cc

Issue 10584026: Allow ChromeOS file selection dialog to be shown from shell windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Another rebase Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/ui/views/select_file_dialog_extension.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/views/select_file_dialog_extension.h" 5 #include "chrome/browser/ui/views/select_file_dialog_extension.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/ref_counted.h" 10 #include "base/memory/ref_counted.h"
11 #include "base/memory/singleton.h" 11 #include "base/memory/singleton.h"
12 #include "base/message_loop.h" 12 #include "base/message_loop.h"
13 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/chromeos/extensions/file_browser_private_api.h" 14 #include "chrome/browser/chromeos/extensions/file_browser_private_api.h"
14 #include "chrome/browser/chromeos/extensions/file_manager_util.h" 15 #include "chrome/browser/chromeos/extensions/file_manager_util.h"
15 #include "chrome/browser/extensions/extension_host.h" 16 #include "chrome/browser/extensions/extension_host.h"
16 #include "chrome/browser/extensions/extension_service.h" 17 #include "chrome/browser/extensions/extension_service.h"
18 #include "chrome/browser/extensions/shell_window_registry.h"
19 #include "chrome/browser/profiles/profile_manager.h"
17 #include "chrome/browser/sessions/restore_tab_helper.h" 20 #include "chrome/browser/sessions/restore_tab_helper.h"
21 #include "chrome/browser/ui/base_window.h"
18 #include "chrome/browser/ui/browser.h" 22 #include "chrome/browser/ui/browser.h"
19 #include "chrome/browser/ui/browser_finder.h" 23 #include "chrome/browser/ui/browser_finder.h"
20 #include "chrome/browser/ui/browser_list.h" 24 #include "chrome/browser/ui/browser_list.h"
21 #include "chrome/browser/ui/browser_window.h" 25 #include "chrome/browser/ui/browser_window.h"
26 #include "chrome/browser/ui/extensions/shell_window.h"
22 #include "chrome/browser/ui/tab_contents/tab_contents.h" 27 #include "chrome/browser/ui/tab_contents/tab_contents.h"
23 #include "chrome/browser/ui/views/extensions/extension_dialog.h" 28 #include "chrome/browser/ui/views/extensions/extension_dialog.h"
24 #include "content/public/browser/browser_thread.h" 29 #include "content/public/browser/browser_thread.h"
25 #include "content/public/common/selected_file_info.h" 30 #include "content/public/common/selected_file_info.h"
26 31
27 using content::BrowserThread; 32 using content::BrowserThread;
28 33
29 namespace { 34 namespace {
30 35
31 const int kFileManagerWidth = 954; // pixels 36 const int kFileManagerWidth = 954; // pixels
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 // static 94 // static
90 SelectFileDialogExtension* SelectFileDialogExtension::Create( 95 SelectFileDialogExtension* SelectFileDialogExtension::Create(
91 Listener* listener) { 96 Listener* listener) {
92 return new SelectFileDialogExtension(listener); 97 return new SelectFileDialogExtension(listener);
93 } 98 }
94 99
95 SelectFileDialogExtension::SelectFileDialogExtension(Listener* listener) 100 SelectFileDialogExtension::SelectFileDialogExtension(Listener* listener)
96 : SelectFileDialog(listener), 101 : SelectFileDialog(listener),
97 has_multiple_file_type_choices_(false), 102 has_multiple_file_type_choices_(false),
98 tab_id_(0), 103 tab_id_(0),
99 owner_browser_(NULL), 104 profile_(NULL),
100 owner_window_(NULL), 105 owner_window_(NULL),
101 selection_type_(CANCEL), 106 selection_type_(CANCEL),
102 selection_index_(0), 107 selection_index_(0),
103 params_(NULL) { 108 params_(NULL) {
104 } 109 }
105 110
106 SelectFileDialogExtension::~SelectFileDialogExtension() { 111 SelectFileDialogExtension::~SelectFileDialogExtension() {
107 if (extension_dialog_) 112 if (extension_dialog_)
108 extension_dialog_->ObserverDestroyed(); 113 extension_dialog_->ObserverDestroyed();
109 } 114 }
110 115
111 bool SelectFileDialogExtension::IsRunning( 116 bool SelectFileDialogExtension::IsRunning(
112 gfx::NativeWindow owner_window) const { 117 gfx::NativeWindow owner_window) const {
113 return owner_window_ == owner_window; 118 return owner_window_ == owner_window;
114 } 119 }
115 120
116 void SelectFileDialogExtension::ListenerDestroyed() { 121 void SelectFileDialogExtension::ListenerDestroyed() {
117 listener_ = NULL; 122 listener_ = NULL;
118 params_ = NULL; 123 params_ = NULL;
119 PendingDialog::GetInstance()->Remove(tab_id_); 124 PendingDialog::GetInstance()->Remove(tab_id_);
120 } 125 }
121 126
122 void SelectFileDialogExtension::ExtensionDialogClosing( 127 void SelectFileDialogExtension::ExtensionDialogClosing(
123 ExtensionDialog* dialog) { 128 ExtensionDialog* dialog) {
124 owner_browser_ = NULL; 129 profile_ = NULL;
125 owner_window_ = NULL; 130 owner_window_ = NULL;
126 // Release our reference to the dialog to allow it to close. 131 // Release our reference to the dialog to allow it to close.
127 extension_dialog_ = NULL; 132 extension_dialog_ = NULL;
128 PendingDialog::GetInstance()->Remove(tab_id_); 133 PendingDialog::GetInstance()->Remove(tab_id_);
129 // Actually invoke the appropriate callback on our listener. 134 // Actually invoke the appropriate callback on our listener.
130 NotifyListener(); 135 NotifyListener();
131 } 136 }
132 137
133 void SelectFileDialogExtension::ExtensionTerminated( 138 void SelectFileDialogExtension::ExtensionTerminated(
134 ExtensionDialog* dialog) { 139 ExtensionDialog* dialog) {
135 // The extension would have been unloaded because of the termination, 140 // The extension would have been unloaded because of the termination,
136 // reload it. 141 // reload it.
137 std::string extension_id = dialog->host()->extension()->id(); 142 std::string extension_id = dialog->host()->extension()->id();
138 // Reload the extension after a bit; the extension may not have been unloaded 143 // Reload the extension after a bit; the extension may not have been unloaded
139 // yet. We don't want to try to reload the extension only to have the Unload 144 // yet. We don't want to try to reload the extension only to have the Unload
140 // code execute after us and re-unload the extension. 145 // code execute after us and re-unload the extension.
141 // 146 //
142 // TODO(rkc): This is ugly. The ideal solution is that we shouldn't need to 147 // TODO(rkc): This is ugly. The ideal solution is that we shouldn't need to
143 // reload the extension at all - when we try to open the extension the next 148 // reload the extension at all - when we try to open the extension the next
144 // time, the extension subsystem would automatically reload it for us. At 149 // time, the extension subsystem would automatically reload it for us. At
145 // this time though this is broken because of some faulty wiring in 150 // this time though this is broken because of some faulty wiring in
146 // ExtensionProcessManager::CreateViewHost. Once that is fixed, remove this. 151 // ExtensionProcessManager::CreateViewHost. Once that is fixed, remove this.
147 if (owner_browser_) { 152 if (profile_) {
148 MessageLoop::current()->PostTask(FROM_HERE, 153 MessageLoop::current()->PostTask(FROM_HERE,
149 base::Bind(&ExtensionService::ReloadExtension, 154 base::Bind(&ExtensionService::ReloadExtension,
150 base::Unretained(owner_browser_->profile()->GetExtensionService()), 155 base::Unretained(profile_->GetExtensionService()),
151 extension_id)); 156 extension_id));
152 } 157 }
153 158
154 dialog->Close(); 159 dialog->Close();
155 } 160 }
156 161
157 // static 162 // static
158 void SelectFileDialogExtension::OnFileSelected( 163 void SelectFileDialogExtension::OnFileSelected(
159 int32 tab_id, 164 int32 tab_id,
160 const content::SelectedFileInfo& file, 165 const content::SelectedFileInfo& file,
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 const FilePath& default_path, 244 const FilePath& default_path,
240 const FileTypeInfo* file_types, 245 const FileTypeInfo* file_types,
241 int file_type_index, 246 int file_type_index,
242 const FilePath::StringType& default_extension, 247 const FilePath::StringType& default_extension,
243 gfx::NativeWindow owner_window, 248 gfx::NativeWindow owner_window,
244 void* params) { 249 void* params) {
245 if (owner_window_) { 250 if (owner_window_) {
246 LOG(ERROR) << "File dialog already in use!"; 251 LOG(ERROR) << "File dialog already in use!";
247 return; 252 return;
248 } 253 }
249 // Extension background pages may not supply an owner_window. 254
250 owner_browser_ = (owner_window ? 255 // The base window to associate the dialog with.
256 BaseWindow* base_window = NULL;
257
258 // The tab contents to associate the dialog with.
259 const TabContents* tab = NULL;
260
261 // First try to find a Browser using the supplied owner_window. If no owner
262 // window has been supplied, this is running from a background page and should
263 // be associated with the last active browser.
264 Browser* owner_browser = (owner_window ?
251 browser::FindBrowserWithWindow(owner_window) : 265 browser::FindBrowserWithWindow(owner_window) :
252 BrowserList::GetLastActive()); 266 BrowserList::GetLastActive());
253 if (!owner_browser_) { 267 if (owner_browser) {
254 NOTREACHED() << "Can't find owning browser"; 268 base_window = owner_browser->window();
269 tab = owner_browser->GetActiveTabContents();
270 profile_ = tab->profile();
271 } else if (owner_window) {
272 // If an owner_window was supplied but we couldn't find a browser, this
273 // could be for a shell window.
274 // TODO(benwells): Find a better way to get a shell window from a native
275 // window.
276 std::vector<Profile*> profiles =
277 g_browser_process->profile_manager()->GetLoadedProfiles();
278 for (std::vector<Profile*>::const_iterator iter = profiles.begin();
279 iter < profiles.end(); iter++) {
280 ShellWindowRegistry* registry = ShellWindowRegistry::Get(*iter);
281 DCHECK(registry);
282 ShellWindow* shell_window = registry->GetShellWindowForNativeWindow(
283 owner_window);
284 if (shell_window) {
285 base_window = shell_window;
286 tab = shell_window->tab_contents();
287 profile_ = *iter;
288 break;
289 }
290 }
291 }
292
293 if (!base_window) {
294 NOTREACHED() << "Can't find owning window.";
255 return; 295 return;
256 } 296 }
257 297 DCHECK(profile_);
258 TabContents* tab = owner_browser_->GetActiveTabContents();
259 298
260 // Check if we have another dialog opened in the tab. It's unlikely, but 299 // Check if we have another dialog opened in the tab. It's unlikely, but
261 // possible. 300 // possible. If there is no tab contents use a tab_id of 0. A dialog without
301 // an associated tab contents will be shown fully screen; only one at a time
302 // is allowed in this state.
262 int32 tab_id = tab ? tab->restore_tab_helper()->session_id().id() : 0; 303 int32 tab_id = tab ? tab->restore_tab_helper()->session_id().id() : 0;
263 if (PendingExists(tab_id)) { 304 if (PendingExists(tab_id)) {
264 DLOG(WARNING) << "Pending dialog exists with id " << tab_id; 305 DLOG(WARNING) << "Pending dialog exists with id " << tab_id;
265 return; 306 return;
266 } 307 }
267 308
268 FilePath virtual_path; 309 FilePath virtual_path;
269 if (!file_manager_util::ConvertFileToRelativeFileSystemPath( 310 if (!file_manager_util::ConvertFileToRelativeFileSystemPath(
270 owner_browser_->profile(), default_path, &virtual_path)) { 311 profile_, default_path, &virtual_path)) {
271 virtual_path = default_path.BaseName(); 312 virtual_path = default_path.BaseName();
272 } 313 }
273 314
274 has_multiple_file_type_choices_ = 315 has_multiple_file_type_choices_ =
275 file_types ? file_types->extensions.size() > 1 : true; 316 file_types ? file_types->extensions.size() > 1 : true;
276 317
277 GURL file_browser_url = file_manager_util::GetFileBrowserUrlWithParams( 318 GURL file_browser_url = file_manager_util::GetFileBrowserUrlWithParams(
278 type, title, virtual_path, file_types, file_type_index, 319 type, title, virtual_path, file_types, file_type_index,
279 default_extension); 320 default_extension);
280 321
281 ExtensionDialog* dialog = ExtensionDialog::Show(file_browser_url, 322 ExtensionDialog* dialog = ExtensionDialog::Show(file_browser_url,
282 owner_browser_, tab->web_contents(), 323 base_window, profile_, tab->web_contents(),
283 kFileManagerWidth, kFileManagerHeight, 324 kFileManagerWidth, kFileManagerHeight,
284 #if defined(USE_AURA) 325 #if defined(USE_AURA)
285 file_manager_util::GetTitleFromType(type), 326 file_manager_util::GetTitleFromType(type),
286 #else 327 #else
287 // HTML-based header used. 328 // HTML-based header used.
288 string16(), 329 string16(),
289 #endif 330 #endif
290 this /* ExtensionDialog::Observer */); 331 this /* ExtensionDialog::Observer */);
291 if (!dialog) { 332 if (!dialog) {
292 LOG(ERROR) << "Unable to create extension dialog"; 333 LOG(ERROR) << "Unable to create extension dialog";
293 return; 334 return;
294 } 335 }
295 336
296 // Connect our listener to FileDialogFunction's per-tab callbacks. 337 // Connect our listener to FileDialogFunction's per-tab callbacks.
297 AddPending(tab_id); 338 AddPending(tab_id);
298 339
299 extension_dialog_ = dialog; 340 extension_dialog_ = dialog;
300 params_ = params; 341 params_ = params;
301 tab_id_ = tab_id; 342 tab_id_ = tab_id;
302 owner_window_ = owner_window; 343 owner_window_ = owner_window;
303 } 344 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/select_file_dialog_extension.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698