| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ui/shell_dialogs/select_file_dialog.h" |
| |
| #include "base/bind.h" |
| #include "base/logging.h" |
| #include "base/message_loop/message_loop.h" |
| #include "build/build_config.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/shell_dialogs/select_file_dialog_factory.h" |
| #include "ui/shell_dialogs/select_file_policy.h" |
| #include "ui/shell_dialogs/selected_file_info.h" |
| #include "ui/shell_dialogs/shell_dialogs_delegate.h" |
| |
| #if defined(OS_WIN) |
| #include "ui/shell_dialogs/select_file_dialog_win.h" |
| #elif defined(OS_MACOSX) |
| #include "ui/shell_dialogs/select_file_dialog_mac.h" |
| #elif defined(TOOLKIT_GTK) |
| #include "ui/shell_dialogs/gtk/select_file_dialog_impl.h" |
| #elif defined(OS_ANDROID) |
| #include "ui/shell_dialogs/select_file_dialog_android.h" |
| #elif defined(USE_AURA) && !defined(USE_ASH) && defined(OS_LINUX) |
| #include "ui/shell_dialogs/linux_shell_dialog.h" |
| #endif |
| |
| namespace { |
| |
| // Optional dialog factory. Leaked. |
| ui::SelectFileDialogFactory* dialog_factory_ = NULL; |
| |
| // The global shell dialogs delegate. |
| ui::ShellDialogsDelegate* g_shell_dialogs_delegate_ = NULL; |
| |
| } // namespace |
| |
| namespace ui { |
| |
| SelectFileDialog::FileTypeInfo::FileTypeInfo() |
| : include_all_files(false), |
| support_drive(false) {} |
| |
| SelectFileDialog::FileTypeInfo::~FileTypeInfo() {} |
| |
| void SelectFileDialog::Listener::FileSelectedWithExtraInfo( |
| const ui::SelectedFileInfo& file, |
| int index, |
| void* params) { |
| // Most of the dialogs need actual local path, so default to it. |
| FileSelected(file.local_path, index, params); |
| } |
| |
| void SelectFileDialog::Listener::MultiFilesSelectedWithExtraInfo( |
| const std::vector<ui::SelectedFileInfo>& files, |
| void* params) { |
| std::vector<base::FilePath> file_paths; |
| for (size_t i = 0; i < files.size(); ++i) |
| file_paths.push_back(files[i].local_path); |
| |
| MultiFilesSelected(file_paths, params); |
| } |
| |
| // static |
| void SelectFileDialog::SetFactory(ui::SelectFileDialogFactory* factory) { |
| delete dialog_factory_; |
| dialog_factory_ = factory; |
| } |
| |
| // static |
| scoped_refptr<SelectFileDialog> SelectFileDialog::Create( |
| Listener* listener, |
| ui::SelectFilePolicy* policy) { |
| if (dialog_factory_) { |
| SelectFileDialog* dialog = dialog_factory_->Create(listener, policy); |
| if (dialog) |
| return dialog; |
| } |
| |
| #if defined(USE_AURA) && !defined(USE_ASH) && defined(OS_LINUX) |
| const ui::LinuxShellDialog* shell_dialogs = ui::LinuxShellDialog::instance(); |
| if (shell_dialogs) |
| return shell_dialogs->CreateSelectFileDialog(listener, policy); |
| #endif |
| |
| #if defined(OS_WIN) |
| // TODO(ananta) |
| // Fix this for Chrome ASH on Windows. |
| return CreateWinSelectFileDialog(listener, policy); |
| #elif defined(OS_MACOSX) && !defined(USE_AURA) |
| return CreateMacSelectFileDialog(listener, policy); |
| #elif defined(TOOLKIT_GTK) |
| return CreateLinuxSelectFileDialog(listener, policy); |
| #elif defined(OS_ANDROID) |
| return CreateAndroidSelectFileDialog(listener, policy); |
| #endif |
| |
| return NULL; |
| } |
| |
| void SelectFileDialog::SelectFile( |
| Type type, |
| const base::string16& title, |
| const base::FilePath& default_path, |
| const FileTypeInfo* file_types, |
| int file_type_index, |
| const base::FilePath::StringType& default_extension, |
| gfx::NativeWindow owning_window, |
| void* params) { |
| DCHECK(listener_); |
| |
| if (select_file_policy_.get() && |
| !select_file_policy_->CanOpenSelectFileDialog()) { |
| select_file_policy_->SelectFileDenied(); |
| |
| // Inform the listener that no file was selected. |
| // Post a task rather than calling FileSelectionCanceled directly to ensure |
| // that the listener is called asynchronously. |
| base::MessageLoop::current()->PostTask( |
| FROM_HERE, |
| base::Bind(&SelectFileDialog::CancelFileSelection, this, params)); |
| return; |
| } |
| |
| // Call the platform specific implementation of the file selection dialog. |
| SelectFileImpl(type, title, default_path, file_types, file_type_index, |
| default_extension, owning_window, params); |
| } |
| |
| bool SelectFileDialog::HasMultipleFileTypeChoices() { |
| return HasMultipleFileTypeChoicesImpl(); |
| } |
| |
| // static |
| void SelectFileDialog::SetShellDialogsDelegate(ShellDialogsDelegate* delegate) { |
| g_shell_dialogs_delegate_ = delegate; |
| } |
| |
| SelectFileDialog::SelectFileDialog(Listener* listener, |
| ui::SelectFilePolicy* policy) |
| : listener_(listener), |
| select_file_policy_(policy) { |
| DCHECK(listener_); |
| } |
| |
| SelectFileDialog::~SelectFileDialog() {} |
| |
| void SelectFileDialog::CancelFileSelection(void* params) { |
| if (listener_) |
| listener_->FileSelectionCanceled(params); |
| } |
| |
| ShellDialogsDelegate* SelectFileDialog::GetShellDialogsDelegate() { |
| return g_shell_dialogs_delegate_; |
| } |
| |
| } // namespace ui |