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 26 namespace { 27 28 // Optional dialog factory. Leaked. 29 ui::SelectFileDialogFactory* dialog_factory_ = NULL; 30 31 // The global shell dialogs delegate. 32 ui::ShellDialogsDelegate* g_shell_dialogs_delegate_ = NULL; 33 34 } // namespace 35 36 namespace ui { 37 38 SelectFileDialog::FileTypeInfo::FileTypeInfo() 39 : include_all_files(false), 40 support_drive(false) {} 41 42 SelectFileDialog::FileTypeInfo::~FileTypeInfo() {} 43 44 void 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 52 void 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 63 void SelectFileDialog::SetFactory(ui::SelectFileDialogFactory* factory) { 64 delete dialog_factory_; 65 dialog_factory_ = factory; 66 } 67 68 // static 69 scoped_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 98 void 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 127 bool SelectFileDialog::HasMultipleFileTypeChoices() { 128 return HasMultipleFileTypeChoicesImpl(); 129 } 130 131 // static 132 void SelectFileDialog::SetShellDialogsDelegate(ShellDialogsDelegate* delegate) { 133 g_shell_dialogs_delegate_ = delegate; 134 } 135 136 SelectFileDialog::SelectFileDialog(Listener* listener, 137 ui::SelectFilePolicy* policy) 138 : listener_(listener), 139 select_file_policy_(policy) { 140 DCHECK(listener_); 141 } 142 143 SelectFileDialog::~SelectFileDialog() {} 144 145 void SelectFileDialog::CancelFileSelection(void* params) { 146 if (listener_) 147 listener_->FileSelectionCanceled(params); 148 } 149 150 ShellDialogsDelegate* SelectFileDialog::GetShellDialogsDelegate() { 151 return g_shell_dialogs_delegate_; 152 } 153 154 } // namespace ui 155