File: select_file_dialog_linux_portal.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (168 lines) | stat: -rw-r--r-- 6,237 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_SHELL_DIALOGS_SELECT_FILE_DIALOG_LINUX_PORTAL_H_
#define UI_SHELL_DIALOGS_SELECT_FILE_DIALOG_LINUX_PORTAL_H_

#include <memory>
#include <optional>

#include "base/functional/callback_forward.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/task/sequenced_task_runner.h"
#include "components/dbus/properties/types.h"
#include "components/dbus/xdg/request.h"
#include "dbus/bus.h"
#include "ui/shell_dialogs/select_file_dialog_linux.h"

namespace ui {

using OnSelectFileExecutedCallback =
    base::OnceCallback<void(std::vector<base::FilePath> paths,
                            std::string current_filter)>;
using OnSelectFileCanceledCallback = base::OnceCallback<void()>;

// Implementation of SelectFileDialog that has the XDG file chooser portal show
// a platform-dependent file selection dialog. This acts as a modal dialog.
class SelectFileDialogLinuxPortal : public SelectFileDialogLinux {
 public:
  SelectFileDialogLinuxPortal(Listener* listener,
                              std::unique_ptr<ui::SelectFilePolicy> policy);

  SelectFileDialogLinuxPortal(const SelectFileDialogLinuxPortal& other) =
      delete;
  SelectFileDialogLinuxPortal& operator=(
      const SelectFileDialogLinuxPortal& other) = delete;

  // Starts running a test to check for the presence of the file chooser portal.
  // Must be called on the UI thread. This should only be called once,
  // preferably around program start.
  static void StartAvailabilityTestInBackground();

  // Checks if the file chooser portal is available. Logs a warning if the
  // availability test has not yet completed.
  static bool IsPortalAvailable();

 protected:
  ~SelectFileDialogLinuxPortal() override;

  // BaseShellDialog:
  bool IsRunning(gfx::NativeWindow parent_window) const override;

  // 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,
                      const GURL* caller) override;
  bool HasMultipleFileTypeChoicesImpl() override;

 private:
  // Glob-style patterns are indicated by 0, MIME types by 1. Patterns are
  // case-sensitive.
  using DbusFilterPattern = DbusStruct<DbusUint32, DbusString>;
  using DbusFilterPatterns = DbusArray<DbusFilterPattern>;
  // The first string is a user-visible name for the filter.
  using DbusFilter = DbusStruct<DbusString, DbusFilterPatterns>;
  using DbusFilters = DbusArray<DbusFilter>;

  // A named set of patterns used as a dialog filter.
  struct PortalFilter {
    PortalFilter();
    PortalFilter(const PortalFilter& other);
    PortalFilter(PortalFilter&& other);
    ~PortalFilter();

    PortalFilter& operator=(const PortalFilter& other) = default;
    PortalFilter& operator=(PortalFilter&& other) = default;

    std::string name;
    std::vector<std::string> patterns;
  };

  // A set of PortalFilters, potentially with a default.
  struct PortalFilterSet {
    PortalFilterSet();
    PortalFilterSet(const PortalFilterSet& other);
    PortalFilterSet(PortalFilterSet&& other);
    ~PortalFilterSet();

    PortalFilterSet& operator=(const PortalFilterSet& other) = default;
    PortalFilterSet& operator=(PortalFilterSet&& other) = default;

    std::vector<PortalFilter> filters;
    std::optional<PortalFilter> default_filter;
  };

  PortalFilterSet BuildFilterSet();

  void SelectFileImplWithParentHandle(
      std::u16string title,
      base::FilePath default_path,
      PortalFilterSet filter_set,
      base::FilePath::StringType default_extension,
      std::string parent_handle);

  void SelectFileImplOnMainThread(std::u16string title,
                                  base::FilePath default_path,
                                  const bool default_path_exists,
                                  PortalFilterSet filter_set,
                                  base::FilePath::StringType default_extension,
                                  std::string parent_handle);

  DbusDictionary BuildOptionsDictionary(const base::FilePath& default_path,
                                        bool default_path_exists,
                                        const PortalFilterSet& filter_set);

  DbusFilter MakeFilterStruct(const PortalFilter& filter);

  void MakeFileChooserRequest(const std::string& method,
                              const std::string& title,
                              DbusDictionary options,
                              std::string parent_handle);

  void OnFileChooserResponse(
      base::expected<DbusDictionary, dbus_xdg::ResponseError> results);

  void CompleteOpen(std::vector<base::FilePath> paths,
                    std::string current_filter);

  void CancelOpen();

  void DialogCreatedOnInvoker();
  void CompleteOpenOnInvoker(std::vector<base::FilePath> paths,
                             std::string current_filter);
  void CancelOpenOnInvoker();

  // Removes the DialogInfo parent.
  void UnparentOnInvoker();

  Type type_ = SELECT_NONE;

  // The task runner the SelectFileImpl method was called on.
  scoped_refptr<base::SequencedTaskRunner> invoker_task_runner_;

  // This should be used by the invoker task runner.
  base::WeakPtr<aura::WindowTreeHost> host_;

  std::vector<PortalFilter> filters_;

  // The Request representing an in-flight file chooser call, if any.
  // We keep this alive until the response arrives or until the dialog
  // is destroyed, whichever comes first.
  std::unique_ptr<dbus_xdg::Request> file_chooser_request_;

  // Event handling on the parent window is disabled while the dialog is active
  // to make the dialog modal.  This closure should be run when the dialog is
  // closed to reenable event handling.
  base::OnceClosure reenable_window_event_handling_;
};

}  // namespace ui

#endif  // UI_SHELL_DIALOGS_SELECT_FILE_DIALOG_LINUX_PORTAL_H_