Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/extensions/api/file_system/file_system_api.h" | 5 #include "chrome/browser/extensions/api/file_system/file_system_api.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/file_path.h" | 8 #include "base/file_path.h" |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 234 return true; | 234 return true; |
| 235 } | 235 } |
| 236 | 236 |
| 237 // Handles showing a dialog to the user to ask for the filename for a file to | 237 // Handles showing a dialog to the user to ask for the filename for a file to |
| 238 // save or open. | 238 // save or open. |
| 239 class FileSystemChooseFileFunction::FilePicker | 239 class FileSystemChooseFileFunction::FilePicker |
| 240 : public SelectFileDialog::Listener { | 240 : public SelectFileDialog::Listener { |
| 241 public: | 241 public: |
| 242 FilePicker(FileSystemChooseFileFunction* function, | 242 FilePicker(FileSystemChooseFileFunction* function, |
| 243 content::WebContents* web_contents, | 243 content::WebContents* web_contents, |
| 244 const FilePath& suggested_path, | 244 const FilePath& suggested_name, |
| 245 SelectFileDialog::Type picker_type, | 245 SelectFileDialog::Type picker_type, |
| 246 EntryType entry_type) | 246 EntryType entry_type) |
| 247 : suggested_path_(suggested_path), | 247 : suggested_name_(suggested_name), |
| 248 entry_type_(entry_type), | 248 entry_type_(entry_type), |
| 249 function_(function) { | 249 function_(function) { |
| 250 select_file_dialog_ = SelectFileDialog::Create( | 250 select_file_dialog_ = SelectFileDialog::Create( |
| 251 this, new ChromeSelectFilePolicy(web_contents)); | 251 this, new ChromeSelectFilePolicy(web_contents)); |
| 252 SelectFileDialog::FileTypeInfo file_type_info; | 252 SelectFileDialog::FileTypeInfo file_type_info; |
| 253 FilePath::StringType extension = suggested_path.Extension(); | 253 FilePath::StringType extension = suggested_name.Extension(); |
| 254 if (!extension.empty()) { | 254 if (!extension.empty()) { |
| 255 extension.erase(extension.begin()); // drop the . | 255 extension.erase(extension.begin()); // drop the . |
| 256 file_type_info.extensions.resize(1); | 256 file_type_info.extensions.resize(1); |
| 257 file_type_info.extensions[0].push_back(extension); | 257 file_type_info.extensions[0].push_back(extension); |
| 258 } | 258 } |
| 259 file_type_info.include_all_files = true; | 259 file_type_info.include_all_files = true; |
| 260 gfx::NativeWindow owning_window = web_contents ? | 260 gfx::NativeWindow owning_window = web_contents ? |
| 261 platform_util::GetTopLevel(web_contents->GetNativeView()) : NULL; | 261 platform_util::GetTopLevel(web_contents->GetNativeView()) : NULL; |
| 262 | 262 |
| 263 if (g_skip_picker_for_test) { | 263 if (g_skip_picker_for_test) { |
| 264 if (g_path_to_be_picked_for_test) { | 264 if (g_path_to_be_picked_for_test) { |
| 265 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, | 265 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, |
| 266 base::Bind( | 266 base::Bind( |
| 267 &FileSystemChooseFileFunction::FilePicker::FileSelected, | 267 &FileSystemChooseFileFunction::FilePicker::FileSelected, |
| 268 base::Unretained(this), *g_path_to_be_picked_for_test, 1, | 268 base::Unretained(this), *g_path_to_be_picked_for_test, 1, |
| 269 static_cast<void*>(NULL))); | 269 static_cast<void*>(NULL))); |
| 270 } else { | 270 } else { |
| 271 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, | 271 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, |
| 272 base::Bind( | 272 base::Bind( |
| 273 &FileSystemChooseFileFunction::FilePicker:: | 273 &FileSystemChooseFileFunction::FilePicker:: |
| 274 FileSelectionCanceled, | 274 FileSelectionCanceled, |
| 275 base::Unretained(this), static_cast<void*>(NULL))); | 275 base::Unretained(this), static_cast<void*>(NULL))); |
| 276 } | 276 } |
| 277 return; | 277 return; |
| 278 } | 278 } |
| 279 | 279 |
| 280 select_file_dialog_->SelectFile(picker_type, | 280 select_file_dialog_->SelectFile(picker_type, |
| 281 string16(), | 281 string16(), |
| 282 suggested_path, | 282 suggested_name, |
| 283 &file_type_info, 0, FILE_PATH_LITERAL(""), | 283 &file_type_info, 0, FILE_PATH_LITERAL(""), |
| 284 owning_window, NULL); | 284 owning_window, NULL); |
| 285 } | 285 } |
| 286 | 286 |
| 287 virtual ~FilePicker() {} | 287 virtual ~FilePicker() {} |
| 288 | 288 |
| 289 private: | 289 private: |
| 290 // SelectFileDialog::Listener implementation. | 290 // SelectFileDialog::Listener implementation. |
| 291 virtual void FileSelected(const FilePath& path, | 291 virtual void FileSelected(const FilePath& path, |
| 292 int index, | 292 int index, |
| 293 void* params) OVERRIDE { | 293 void* params) OVERRIDE { |
| 294 function_->FileSelected(path, entry_type_); | 294 function_->FileSelected(path, entry_type_); |
| 295 delete this; | 295 delete this; |
| 296 } | 296 } |
| 297 | 297 |
| 298 virtual void FileSelectionCanceled(void* params) OVERRIDE { | 298 virtual void FileSelectionCanceled(void* params) OVERRIDE { |
| 299 function_->FileSelectionCanceled(); | 299 function_->FileSelectionCanceled(); |
| 300 delete this; | 300 delete this; |
| 301 } | 301 } |
| 302 | 302 |
| 303 FilePath suggested_path_; | 303 FilePath suggested_name_; |
| 304 | 304 |
| 305 EntryType entry_type_; | 305 EntryType entry_type_; |
| 306 | 306 |
| 307 scoped_refptr<SelectFileDialog> select_file_dialog_; | 307 scoped_refptr<SelectFileDialog> select_file_dialog_; |
| 308 scoped_refptr<FileSystemChooseFileFunction> function_; | 308 scoped_refptr<FileSystemChooseFileFunction> function_; |
| 309 | 309 |
| 310 DISALLOW_COPY_AND_ASSIGN(FilePicker); | 310 DISALLOW_COPY_AND_ASSIGN(FilePicker); |
| 311 }; | 311 }; |
| 312 | 312 |
| 313 bool FileSystemChooseFileFunction::ShowPicker( | 313 bool FileSystemChooseFileFunction::ShowPicker( |
| 314 const FilePath& suggested_path, | 314 const FilePath& suggested_name, |
| 315 SelectFileDialog::Type picker_type, | 315 SelectFileDialog::Type picker_type, |
| 316 EntryType entry_type) { | 316 EntryType entry_type) { |
| 317 ShellWindowRegistry* registry = ShellWindowRegistry::Get(profile()); | 317 ShellWindowRegistry* registry = ShellWindowRegistry::Get(profile()); |
| 318 DCHECK(registry); | 318 DCHECK(registry); |
| 319 ShellWindow* shell_window = registry->GetShellWindowForRenderViewHost( | 319 ShellWindow* shell_window = registry->GetShellWindowForRenderViewHost( |
| 320 render_view_host()); | 320 render_view_host()); |
| 321 if (!shell_window) { | 321 if (!shell_window) { |
| 322 error_ = kInvalidCallingPage; | 322 error_ = kInvalidCallingPage; |
| 323 return false; | 323 return false; |
| 324 } | 324 } |
| 325 | 325 |
| 326 // The file picker will hold a reference to this function instance, preventing | 326 // The file picker will hold a reference to this function instance, preventing |
| 327 // its destruction (and subsequent sending of the function response) until the | 327 // its destruction (and subsequent sending of the function response) until the |
| 328 // user has selected a file or cancelled the picker. At that point, the picker | 328 // user has selected a file or cancelled the picker. At that point, the picker |
| 329 // will delete itself, which will also free the function instance. | 329 // will delete itself, which will also free the function instance. |
| 330 new FilePicker(this, shell_window->web_contents(), suggested_path, | 330 new FilePicker(this, shell_window->web_contents(), suggested_name, |
| 331 picker_type, entry_type); | 331 picker_type, entry_type); |
| 332 return true; | 332 return true; |
| 333 } | 333 } |
| 334 | 334 |
| 335 // static | 335 // static |
| 336 void FileSystemChooseFileFunction::SkipPickerAndAlwaysSelectPathForTest( | 336 void FileSystemChooseFileFunction::SkipPickerAndAlwaysSelectPathForTest( |
| 337 FilePath* path) { | 337 FilePath* path) { |
| 338 g_skip_picker_for_test = true; | 338 g_skip_picker_for_test = true; |
| 339 g_path_to_be_picked_for_test = path; | 339 g_path_to_be_picked_for_test = path; |
| 340 } | 340 } |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 365 | 365 |
| 366 void FileSystemChooseFileFunction::FileSelectionCanceled() { | 366 void FileSystemChooseFileFunction::FileSelectionCanceled() { |
| 367 error_ = kUserCancelled; | 367 error_ = kUserCancelled; |
| 368 SendResponse(false); | 368 SendResponse(false); |
| 369 } | 369 } |
| 370 | 370 |
| 371 bool FileSystemChooseFileFunction::RunImpl() { | 371 bool FileSystemChooseFileFunction::RunImpl() { |
| 372 scoped_ptr<ChooseFile::Params> params(ChooseFile::Params::Create(*args_)); | 372 scoped_ptr<ChooseFile::Params> params(ChooseFile::Params::Create(*args_)); |
| 373 EXTENSION_FUNCTION_VALIDATE(params.get()); | 373 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 374 | 374 |
| 375 FilePath suggested_name; | |
| 375 EntryType entry_type = READ_ONLY; | 376 EntryType entry_type = READ_ONLY; |
| 376 SelectFileDialog::Type picker_type = SelectFileDialog::SELECT_OPEN_FILE; | 377 SelectFileDialog::Type picker_type = SelectFileDialog::SELECT_OPEN_FILE; |
| 378 | |
| 377 file_system::ChooseFileOptions* options = params->options.get(); | 379 file_system::ChooseFileOptions* options = params->options.get(); |
| 378 if (options && options->type.get()) { | 380 if (options) { |
| 379 if (*options->type == kOpenWritableFileOption) { | 381 if (options->type.get()) { |
| 380 entry_type = WRITABLE; | 382 if (*options->type == kOpenWritableFileOption) { |
| 381 } else if (*options->type == kSaveFileOption) { | 383 entry_type = WRITABLE; |
| 382 entry_type = WRITABLE; | 384 } else if (*options->type == kSaveFileOption) { |
| 383 picker_type = SelectFileDialog::SELECT_SAVEAS_FILE; | 385 entry_type = WRITABLE; |
| 384 } else if (*options->type != kOpenFileOption) { | 386 picker_type = SelectFileDialog::SELECT_SAVEAS_FILE; |
| 385 error_ = kUnknownChooseFileType; | 387 } else if (*options->type != kOpenFileOption) { |
| 386 return false; | 388 error_ = kUnknownChooseFileType; |
| 389 return false; | |
| 390 } | |
| 391 } | |
| 392 | |
| 393 if (options->suggested_name.get()) { | |
| 394 suggested_name = FilePath::FromUTF8Unsafe( | |
| 395 *options->suggested_name.get()); | |
| 396 | |
| 397 // Don't allow any path components; shorten to the base name. This should | |
| 398 // result in a relative path, but in some cases may not be. Clear the | |
|
benwells
2012/07/12 08:48:01
nit: ...cases may not.
thorogood
2012/07/13 01:15:22
Done.
| |
| 399 // suggestion for safety if this is the case. | |
| 400 suggested_name = suggested_name.BaseName(); | |
| 401 if (suggested_name.IsAbsolute()) { | |
| 402 suggested_name = FilePath(); | |
| 403 } | |
| 387 } | 404 } |
| 388 } | 405 } |
| 389 | 406 |
| 390 if (entry_type == WRITABLE && !HasFileSystemWritePermission()) { | 407 if (entry_type == WRITABLE && !HasFileSystemWritePermission()) { |
| 391 error_ = kRequiresFileSystemWriteError; | 408 error_ = kRequiresFileSystemWriteError; |
| 392 return false; | 409 return false; |
| 393 } | 410 } |
| 394 | 411 |
| 395 return ShowPicker(FilePath(), picker_type, entry_type); | 412 return ShowPicker(suggested_name, picker_type, entry_type); |
| 396 } | 413 } |
| 397 | 414 |
| 398 } // namespace extensions | 415 } // namespace extensions |
| OLD | NEW |