fake_folder_selection_dialog_factory.cc 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // Copyright 2021 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. #include "ash/capture_mode/fake_folder_selection_dialog_factory.h"
  5. #include <memory>
  6. #include "base/check.h"
  7. #include "base/check_op.h"
  8. #include "ui/aura/window.h"
  9. #include "ui/aura/window_observer.h"
  10. #include "ui/gfx/geometry/insets.h"
  11. #include "ui/shell_dialogs/select_file_dialog.h"
  12. #include "ui/shell_dialogs/select_file_policy.h"
  13. #include "ui/views/widget/unique_widget_ptr.h"
  14. #include "ui/views/widget/widget.h"
  15. namespace ash {
  16. namespace {
  17. FakeFolderSelectionDialogFactory* g_factory_instance = nullptr;
  18. } // namespace
  19. // -----------------------------------------------------------------------------
  20. // FakeFolderSelectionDialog:
  21. class FakeFolderSelectionDialog : public ui::SelectFileDialog {
  22. public:
  23. FakeFolderSelectionDialog(Listener* listener,
  24. std::unique_ptr<ui::SelectFilePolicy> policy)
  25. : ui::SelectFileDialog(listener, std::move(policy)) {}
  26. aura::Window* GetDialogWindow() {
  27. DCHECK(dialog_widget_);
  28. return dialog_widget_->GetNativeWindow();
  29. }
  30. void AcceptPath(const base::FilePath& path) {
  31. DCHECK(dialog_widget_);
  32. if (listener_)
  33. listener_->FileSelected(path, /*index=*/0, /*params=*/nullptr);
  34. DismissDialog();
  35. }
  36. void CancelDialog() {
  37. DCHECK(dialog_widget_);
  38. if (listener_)
  39. listener_->FileSelectionCanceled(/*params=*/nullptr);
  40. DismissDialog();
  41. }
  42. // ui::BaseShellDialog:
  43. bool IsRunning(gfx::NativeWindow owning_window) const override {
  44. // The dialog is not shown modally.
  45. return false;
  46. }
  47. void ListenerDestroyed() override { listener_ = nullptr; }
  48. protected:
  49. ~FakeFolderSelectionDialog() override {
  50. if (g_factory_instance)
  51. g_factory_instance->OnDialogDeleted(this);
  52. }
  53. // ui::SelectFileDialog:
  54. void SelectFileImpl(Type type,
  55. const std::u16string& title,
  56. const base::FilePath& default_path,
  57. const FileTypeInfo* file_types,
  58. int file_type_index,
  59. const base::FilePath::StringType& default_extension,
  60. gfx::NativeWindow owning_window,
  61. void* params) override {
  62. dialog_widget_ = views::UniqueWidgetPtr(std::make_unique<views::Widget>());
  63. views::Widget::InitParams widget_params(
  64. views::Widget::InitParams::TYPE_POPUP);
  65. widget_params.parent = owning_window;
  66. widget_params.bounds = owning_window->GetRootWindow()->bounds();
  67. widget_params.bounds.Inset(gfx::Insets(20));
  68. widget_params.name = "FakeFolderSelectionDialogWidget";
  69. dialog_widget_->Init(std::move(widget_params));
  70. dialog_widget_->Show();
  71. }
  72. private:
  73. void DismissDialog() {
  74. dialog_widget_->CloseNow();
  75. // |this| is deleted after the above call.
  76. DCHECK(!g_factory_instance || !(g_factory_instance->dialog_));
  77. }
  78. // ui::SelectFileDialog:
  79. bool HasMultipleFileTypeChoicesImpl() override { return false; }
  80. views::UniqueWidgetPtr dialog_widget_;
  81. };
  82. // -----------------------------------------------------------------------------
  83. // FakeFolderSelectionDialogFactory:
  84. // static
  85. void FakeFolderSelectionDialogFactory::Start() {
  86. ui::SelectFileDialog::SetFactory(new FakeFolderSelectionDialogFactory());
  87. }
  88. // static
  89. void FakeFolderSelectionDialogFactory::Stop() {
  90. ui::SelectFileDialog::SetFactory(nullptr);
  91. DCHECK(!g_factory_instance);
  92. }
  93. // static
  94. FakeFolderSelectionDialogFactory* FakeFolderSelectionDialogFactory::Get() {
  95. DCHECK(g_factory_instance);
  96. return g_factory_instance;
  97. }
  98. aura::Window* FakeFolderSelectionDialogFactory::GetDialogWindow() {
  99. DCHECK(dialog_);
  100. return dialog_->GetDialogWindow();
  101. }
  102. void FakeFolderSelectionDialogFactory::AcceptPath(const base::FilePath& path) {
  103. DCHECK(dialog_);
  104. dialog_->AcceptPath(path);
  105. }
  106. void FakeFolderSelectionDialogFactory::CancelDialog() {
  107. DCHECK(dialog_);
  108. dialog_->CancelDialog();
  109. }
  110. ui::SelectFileDialog* FakeFolderSelectionDialogFactory::Create(
  111. ui::SelectFileDialog::Listener* listener,
  112. std::unique_ptr<ui::SelectFilePolicy> policy) {
  113. dialog_ = new FakeFolderSelectionDialog(listener, std::move(policy));
  114. return dialog_;
  115. }
  116. FakeFolderSelectionDialogFactory::FakeFolderSelectionDialogFactory() {
  117. DCHECK(!g_factory_instance);
  118. g_factory_instance = this;
  119. }
  120. FakeFolderSelectionDialogFactory::~FakeFolderSelectionDialogFactory() {
  121. DCHECK_EQ(g_factory_instance, this);
  122. g_factory_instance = nullptr;
  123. }
  124. void FakeFolderSelectionDialogFactory::OnDialogDeleted(
  125. FakeFolderSelectionDialog* dialog) {
  126. DCHECK_EQ(dialog_, dialog);
  127. dialog_ = nullptr;
  128. }
  129. } // namespace ash