| // Copyright 2021 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 "ash/capture_mode/fake_folder_selection_dialog_factory.h" |
| |
| #include <memory> |
| |
| #include "base/check.h" |
| #include "base/check_op.h" |
| #include "ui/aura/window.h" |
| #include "ui/aura/window_observer.h" |
| #include "ui/gfx/geometry/insets.h" |
| #include "ui/shell_dialogs/select_file_dialog.h" |
| #include "ui/shell_dialogs/select_file_policy.h" |
| #include "ui/views/widget/unique_widget_ptr.h" |
| #include "ui/views/widget/widget.h" |
| |
| namespace ash { |
| |
| namespace { |
| FakeFolderSelectionDialogFactory* g_factory_instance = nullptr; |
| } // namespace |
| |
| // ----------------------------------------------------------------------------- |
| // FakeFolderSelectionDialog: |
| |
| class FakeFolderSelectionDialog : public ui::SelectFileDialog { |
| public: |
| FakeFolderSelectionDialog(Listener* listener, |
| std::unique_ptr<ui::SelectFilePolicy> policy) |
| : ui::SelectFileDialog(listener, std::move(policy)) {} |
| |
| aura::Window* GetDialogWindow() { |
| DCHECK(dialog_widget_); |
| return dialog_widget_->GetNativeWindow(); |
| } |
| |
| void AcceptPath(const base::FilePath& path) { |
| DCHECK(dialog_widget_); |
| if (listener_) |
| listener_->FileSelected(path, /*index=*/0, /*params=*/nullptr); |
| DismissDialog(); |
| } |
| |
| void CancelDialog() { |
| DCHECK(dialog_widget_); |
| if (listener_) |
| listener_->FileSelectionCanceled(/*params=*/nullptr); |
| DismissDialog(); |
| } |
| |
| // ui::BaseShellDialog: |
| bool IsRunning(gfx::NativeWindow owning_window) const override { |
| // The dialog is not shown modally. |
| return false; |
| } |
| void ListenerDestroyed() override { listener_ = nullptr; } |
| |
| protected: |
| ~FakeFolderSelectionDialog() override { |
| if (g_factory_instance) |
| g_factory_instance->OnDialogDeleted(this); |
| } |
| |
| // ui::SelectFileDialog: |
| void SelectFileImpl(Type type, |
| const std::u16string& 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) override { |
| dialog_widget_ = views::UniqueWidgetPtr(std::make_unique<views::Widget>()); |
| views::Widget::InitParams widget_params( |
| views::Widget::InitParams::TYPE_POPUP); |
| widget_params.parent = owning_window; |
| widget_params.bounds = owning_window->GetRootWindow()->bounds(); |
| widget_params.bounds.Inset(gfx::Insets(20)); |
| widget_params.name = "FakeFolderSelectionDialogWidget"; |
| dialog_widget_->Init(std::move(widget_params)); |
| dialog_widget_->Show(); |
| } |
| |
| private: |
| void DismissDialog() { |
| dialog_widget_->CloseNow(); |
| // |this| is deleted after the above call. |
| DCHECK(!g_factory_instance || !(g_factory_instance->dialog_)); |
| } |
| |
| // ui::SelectFileDialog: |
| bool HasMultipleFileTypeChoicesImpl() override { return false; } |
| |
| views::UniqueWidgetPtr dialog_widget_; |
| }; |
| |
| // ----------------------------------------------------------------------------- |
| // FakeFolderSelectionDialogFactory: |
| |
| // static |
| void FakeFolderSelectionDialogFactory::Start() { |
| ui::SelectFileDialog::SetFactory(new FakeFolderSelectionDialogFactory()); |
| } |
| |
| // static |
| void FakeFolderSelectionDialogFactory::Stop() { |
| ui::SelectFileDialog::SetFactory(nullptr); |
| DCHECK(!g_factory_instance); |
| } |
| |
| // static |
| FakeFolderSelectionDialogFactory* FakeFolderSelectionDialogFactory::Get() { |
| DCHECK(g_factory_instance); |
| return g_factory_instance; |
| } |
| |
| aura::Window* FakeFolderSelectionDialogFactory::GetDialogWindow() { |
| DCHECK(dialog_); |
| return dialog_->GetDialogWindow(); |
| } |
| |
| void FakeFolderSelectionDialogFactory::AcceptPath(const base::FilePath& path) { |
| DCHECK(dialog_); |
| dialog_->AcceptPath(path); |
| } |
| |
| void FakeFolderSelectionDialogFactory::CancelDialog() { |
| DCHECK(dialog_); |
| dialog_->CancelDialog(); |
| } |
| |
| ui::SelectFileDialog* FakeFolderSelectionDialogFactory::Create( |
| ui::SelectFileDialog::Listener* listener, |
| std::unique_ptr<ui::SelectFilePolicy> policy) { |
| dialog_ = new FakeFolderSelectionDialog(listener, std::move(policy)); |
| return dialog_; |
| } |
| |
| FakeFolderSelectionDialogFactory::FakeFolderSelectionDialogFactory() { |
| DCHECK(!g_factory_instance); |
| g_factory_instance = this; |
| } |
| |
| FakeFolderSelectionDialogFactory::~FakeFolderSelectionDialogFactory() { |
| DCHECK_EQ(g_factory_instance, this); |
| g_factory_instance = nullptr; |
| } |
| |
| void FakeFolderSelectionDialogFactory::OnDialogDeleted( |
| FakeFolderSelectionDialog* dialog) { |
| DCHECK_EQ(dialog_, dialog); |
| dialog_ = nullptr; |
| } |
| |
| } // namespace ash |