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