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