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 3// found in the LICENSE file. 4 5#include "ui/shell_dialogs/select_file_dialog.h" 6 7#include "base/bind.h" 8#include "base/logging.h" 9#include "base/message_loop/message_loop.h" 10#include "build/build_config.h" 11#include "ui/shell_dialogs/select_file_dialog_factory.h" 12#include "ui/shell_dialogs/select_file_policy.h" 13#include "ui/shell_dialogs/selected_file_info.h" 14#include "ui/shell_dialogs/shell_dialogs_delegate.h" 15 16#if defined(OS_WIN) 17#include "ui/shell_dialogs/select_file_dialog_win.h" 18#elif defined(OS_MACOSX) 19#include "ui/shell_dialogs/select_file_dialog_mac.h" 20#elif defined(OS_ANDROID) 21#include "ui/shell_dialogs/select_file_dialog_android.h" 22#elif defined(USE_AURA) && defined(OS_LINUX) && !defined(OS_CHROMEOS) 23#include "ui/shell_dialogs/linux_shell_dialog.h" 24#endif 25 26namespace { 27 28// Optional dialog factory. Leaked. 29ui::SelectFileDialogFactory* dialog_factory_ = NULL; 30 31// The global shell dialogs delegate. 32ui::ShellDialogsDelegate* g_shell_dialogs_delegate_ = NULL; 33 34} // namespace 35 36namespace ui { 37 38SelectFileDialog::FileTypeInfo::FileTypeInfo() 39 : include_all_files(false), 40 support_drive(false) {} 41 42SelectFileDialog::FileTypeInfo::~FileTypeInfo() {} 43 44void SelectFileDialog::Listener::FileSelectedWithExtraInfo( 45 const ui::SelectedFileInfo& file, 46 int index, 47 void* params) { 48 // Most of the dialogs need actual local path, so default to it. 49 FileSelected(file.local_path, index, params); 50} 51 52void SelectFileDialog::Listener::MultiFilesSelectedWithExtraInfo( 53 const std::vector<ui::SelectedFileInfo>& files, 54 void* params) { 55 std::vector<base::FilePath> file_paths; 56 for (size_t i = 0; i < files.size(); ++i) 57 file_paths.push_back(files[i].local_path); 58 59 MultiFilesSelected(file_paths, params); 60} 61 62// static 63void SelectFileDialog::SetFactory(ui::SelectFileDialogFactory* factory) { 64 delete dialog_factory_; 65 dialog_factory_ = factory; 66} 67 68// static 69scoped_refptr<SelectFileDialog> SelectFileDialog::Create( 70 Listener* listener, 71 ui::SelectFilePolicy* policy) { 72 if (dialog_factory_) { 73 SelectFileDialog* dialog = dialog_factory_->Create(listener, policy); 74 if (dialog) 75 return dialog; 76 } 77 78#if defined(USE_AURA) && defined(OS_LINUX) && !defined(OS_CHROMEOS) 79 const ui::LinuxShellDialog* shell_dialogs = ui::LinuxShellDialog::instance(); 80 if (shell_dialogs) 81 return shell_dialogs->CreateSelectFileDialog(listener, policy); 82#endif 83 84#if defined(OS_WIN) 85 // TODO(ananta) 86 // Fix this for Chrome ASH on Windows. 87 return CreateDefaultWinSelectFileDialog(listener, policy); 88#elif defined(OS_MACOSX) && !defined(USE_AURA) 89 return CreateMacSelectFileDialog(listener, policy); 90#elif defined(OS_ANDROID) 91 return CreateAndroidSelectFileDialog(listener, policy); 92#else 93 NOTIMPLEMENTED(); 94 return NULL; 95#endif 96} 97 98void SelectFileDialog::SelectFile( 99 Type type, 100 const base::string16& title, 101 const base::FilePath& default_path, 102 const FileTypeInfo* file_types, 103 int file_type_index, 104 const base::FilePath::StringType& default_extension, 105 gfx::NativeWindow owning_window, 106 void* params) { 107 DCHECK(listener_); 108 109 if (select_file_policy_.get() && 110 !select_file_policy_->CanOpenSelectFileDialog()) { 111 select_file_policy_->SelectFileDenied(); 112 113 // Inform the listener that no file was selected. 114 // Post a task rather than calling FileSelectionCanceled directly to ensure 115 // that the listener is called asynchronously. 116 base::MessageLoop::current()->PostTask( 117 FROM_HERE, 118 base::Bind(&SelectFileDialog::CancelFileSelection, this, params)); 119 return; 120 } 121 122 // Call the platform specific implementation of the file selection dialog. 123 SelectFileImpl(type, title, default_path, file_types, file_type_index, 124 default_extension, owning_window, params); 125} 126 127bool SelectFileDialog::HasMultipleFileTypeChoices() { 128 return HasMultipleFileTypeChoicesImpl(); 129} 130 131// static 132void SelectFileDialog::SetShellDialogsDelegate(ShellDialogsDelegate* delegate) { 133 g_shell_dialogs_delegate_ = delegate; 134} 135 136SelectFileDialog::SelectFileDialog(Listener* listener, 137 ui::SelectFilePolicy* policy) 138 : listener_(listener), 139 select_file_policy_(policy) { 140 DCHECK(listener_); 141} 142 143SelectFileDialog::~SelectFileDialog() {} 144 145void SelectFileDialog::CancelFileSelection(void* params) { 146 if (listener_) 147 listener_->FileSelectionCanceled(params); 148} 149 150ShellDialogsDelegate* SelectFileDialog::GetShellDialogsDelegate() { 151 return g_shell_dialogs_delegate_; 152} 153 154} // namespace ui 155