Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qohosplatformfiledialoghelper.cpp
Go to the documentation of this file.
1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
7#include <QtCore/qeventloop.h>
8#include <QtCore/qfileinfo.h>
9#include <qohosjsenv_p.h>
10#include <QtGui/qguiapplication.h>
11#include <QtGui/qwindow.h>
12#include <algorithm>
13#include <qohoswindowmanager.h>
14
16
17namespace {
18
20mapQFileDialogOptionsToOhosDocumentSelectMode(const QFileDialogOptions &options)
21{
22 using FileMode = QFileDialogOptions::FileMode;
23 using DocumentSelectMode = QOhosWindowManager::DocumentSelectMode;
24
25 switch (options.fileMode()) {
26 case FileMode::Directory:
27 case FileMode::DirectoryOnly:
28 return DocumentSelectMode::FOLDER;
29 case FileMode::ExistingFile:
30 case FileMode::ExistingFiles:
31 return DocumentSelectMode::FILE;
32 case FileMode::AnyFile:
33 return DocumentSelectMode::MIXED;
34 }
35 return DocumentSelectMode::MIXED;
36}
37
39mapQFileDialogOptionsToOhosResultMultiplicity(const QFileDialogOptions &options)
40{
41 return options.fileMode() == QFileDialogOptions::FileMode::ExistingFile
42 ? QOhosWindowManager::ResultMultiplicity::SINGLE
43 : QOhosWindowManager::ResultMultiplicity::MULTIPLE;
44}
45
47{
48 auto *platformWindow = QOhosPlatformWindow::fromQWindowOrNull(qWindow);
49 auto windowId = platformWindow != nullptr
50 ? platformWindow->internalWindowId()
51 : QtOhos::InternalWindowId::invalidWindowId();
52
53 if (!windowId.isValid())
54 qOhosReportFatalErrorAndAbort("%s: Failed to retrieve window id", Q_FUNC_INFO);
55
56 return windowId;
57}
58
60{
61 auto *focusedWindow = QGuiApplication::focusWindow();
62 return focusedWindow != nullptr
63 ? getQWindowInternalWindowIdOrFail(focusedWindow)
64 : QtOhos::InternalWindowId::invalidWindowId();
65}
66
68{
69public:
72
74 void setDirectory(const QUrl &directory) override;
75 QUrl directory() const override;
76 void selectFile(const QUrl &filename) override;
77 QList<QUrl> selectedFiles() const override;
79 void selectNameFilter(const QString &filter) override;
80 QString selectedNameFilter() const override;
81 void hide() override;
82 void exec() override;
83 bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) override;
84
85private:
86 void setDialogResult(bool accepted, QStringList files, QOhosOptional<int> optSelectedFilterIndex);
87 static QStringList convertQtNameFiltersToOhosStandard(const QStringList &);
88
89 QEventLoop m_eventLoop;
90 bool m_shown;
91
92 QUrl m_directory;
93 QUrl m_selectFileName;
94 QString m_selectedNameFilter;
95
96 QList<QUrl> m_selectedFiles;
97};
98
104
106{
107 auto _dbg = make_QCScopedDebug("QOhosPlatformFileDialogHelperImpl::defaultNameFilterDisables");
108 return false;
109}
110
112{
113 auto _dbg = make_QCScopedDebug("QOhosPlatformFileDialogHelperImpl::setDirectory");
114 m_directory = directory;
115}
116
118{
119 auto _dbg = make_QCScopedDebug("QOhosPlatformFileDialogHelperImpl::directory");
120 return m_directory;
121}
122
124{
125 auto _dbg = make_QCScopedDebug("QOhosPlatformFileDialogHelperImpl::selectFile");
126 m_selectFileName = filename;
127}
128
130{
131 auto _dbg = make_QCScopedDebug("QOhosPlatformFileDialogHelperImpl::setFilter");
132}
133
135{
136 m_selectedNameFilter = filter;
137 auto _dbg = make_QCScopedDebug("QOhosPlatformFileDialogHelperImpl::selectNameFilter");
138}
139
141{
142 auto _dbg = make_QCScopedDebug("QOhosPlatformFileDialogHelperImpl::selectedNameFilter");
143 return m_selectedNameFilter;
144}
145
147{
148 auto _dbg = make_QCScopedDebug("QOhosPlatformFileDialogHelperImpl::selectedFiles");
149 return m_selectedFiles;
150}
151
153{
154 m_shown = false;
155 // Programmatically closing the DocumentViewPicker is not supported by the
156 // HarmonyOS platform API. The picker can only be dismissed by the user.
157 // See: https://developer.huawei.com/consumer/en/doc/harmonyos-references/js-apis-file-picker#documentviewpicker
158 m_eventLoop.exit();
159 auto _dbg = make_QCScopedDebug("QOhosPlatformFileDialogHelperImpl::hide()");
160}
161
162void QOhosPlatformFileDialogHelperImpl::setDialogResult(
163 bool accepted, QStringList files, QOhosOptional<int> optSelectedFilterIndex)
164{
165 auto _dbg = make_QCScopedDebug("QOhosPlatformFileDialogHelperImpl::dialogResult()");
166
167 hide();
168 m_selectedFiles.clear();
169 if (accepted) {
170 if (optSelectedFilterIndex.hasValue()) {
171 auto nameFilters = options()->nameFilters();
172 auto selectedFilterIndex = optSelectedFilterIndex.value();
173 if (selectedFilterIndex >= 0 && selectedFilterIndex < nameFilters.count())
174 selectNameFilter(nameFilters.at(selectedFilterIndex));
175 }
176 std::copy(files.constBegin(), files.constEnd(), std::back_inserter(m_selectedFiles));
177 emit accept();
178 } else {
179 emit reject();
180 }
181
182}
183
185{
186 auto _dbg = make_QCScopedDebug("QOhosPlatformFileDialogHelperImpl::exec()");
187
188 if (!m_shown)
189 show(Qt::Dialog, Qt::ApplicationModal, 0);
190
191 // Run event loop only if the call was successful
192 if (m_shown)
193 m_eventLoop.exec();
194}
195
196QStringList QOhosPlatformFileDialogHelperImpl::convertQtNameFiltersToOhosStandard(const QStringList &qtNameFilters)
197{
198 const auto qtAnyFilesFilter = QString::fromUtf8("*");
199 const auto ohosAnyFilesFilter = QString::fromUtf8(".*");
200 QStringList ohosNameFilters;
201 for (const auto &qtFilter : qtNameFilters) {
202 QStringList qtCleanFilters = QPlatformFileDialogHelper::cleanFilterList(qtFilter);
203 QStringList ohosExtensionList;
204 for (auto &qtCleanFilter : qtCleanFilters) {
205 QString extensionOnly = qtCleanFilter.replace(QLatin1String("*."), QLatin1String("."));
206 ohosExtensionList.append(extensionOnly);
207 }
208 QString ohosExtensionsSeparatedByComma = ohosExtensionList.join(QString::fromUtf8(","));
209 if (ohosExtensionsSeparatedByComma == qtAnyFilesFilter)
210 ohosExtensionsSeparatedByComma = ohosAnyFilesFilter;
211 auto ohosNameFilter = qtFilter + QLatin1String("|") + ohosExtensionsSeparatedByComma;
212 ohosNameFilters.append(ohosNameFilter);
213 }
214 return ohosNameFilters;
215}
216
218 Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
219{
220 Q_UNUSED(windowFlags)
221 Q_UNUSED(windowModality)
222
223 const auto contextWinId = parent != nullptr
224 ? getQWindowInternalWindowIdOrFail(parent)
225 : tryGetFocusedWindowInternalWindowId();
226
227 // TODO: don't assume that "this" is always alive
228 QSharedPointer<QFileDialogOptions> opt = options();
229 auto ohosNameFilters = convertQtNameFiltersToOhosStandard(opt->nameFilters());
230 if (opt->acceptMode() == QFileDialogOptions::AcceptOpen)
232 contextWinId,
233 ohosNameFilters,
234 !m_selectFileName.isEmpty()
235 ? m_selectFileName.toLocalFile()
236 : !m_directory.isEmpty()
237 ? m_directory.toLocalFile()
238 : QString(),
239 mapQFileDialogOptionsToOhosDocumentSelectMode(*opt),
240 mapQFileDialogOptionsToOhosResultMultiplicity(*opt),
241 [this](QOhosOptional<QOhosWindowManager::OpenResult> optOpenResult) {
242 auto filesPaths = optOpenResult.hasValue()
243 ? optOpenResult.value().selectedUrls
244 : QStringList();
245 setDialogResult(!filesPaths.isEmpty(), filesPaths, {});
246 });
247 else
249 contextWinId,
250 !m_selectFileName.isEmpty()
251 ? QStringList(QFileInfo(m_selectFileName.toLocalFile()).fileName())
252 : QStringList(),
253 !m_directory.isEmpty()
254 ? m_directory.toLocalFile()
255 : !m_selectFileName.isEmpty()
256 ? QFileInfo(m_selectFileName.toLocalFile()).absoluteDir().path()
257 : QString(),
258 ohosNameFilters,
259 [this](QOhosOptional<QOhosWindowManager::SaveResult> optSaveResult) {
260 auto filesPaths = optSaveResult.hasValue()
261 ? optSaveResult.value().savedUrls
262 : QStringList();
263 auto optSelectedFilterIndex = optSaveResult.transform(
264 [](const auto &saveResult) {
265 return saveResult.selectedFileSuffixChoiceIndex;
266 });
267 setDialogResult(!filesPaths.isEmpty(), filesPaths, optSelectedFilterIndex);
268 });
269 m_shown = true;
270
271 return true;
272}
273
274}
275
280
281QT_END_NAMESPACE
std::enable_if_t< qohosplugincore_h_detail::isQOhosOptional< QOhosInvokeResult< Func, T > >, QOhosInvokeResult< Func, T > > andThen(Func &&func) const
bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) override
void showFileDialogOpen(QtOhos::InternalWindowId contextWinId, QStringList filters, QString defaultPath, DocumentSelectMode documentSelectMode, ResultMultiplicity resultMultiplicity, QOhosConsumer< QOhosOptional< OpenResult > > resultCallback)
void showFileDialogSave(QtOhos::InternalWindowId contextWinId, QStringList newFileNames, QString defaultFilePath, QStringList fileSuffixChoices, QOhosConsumer< QOhosOptional< SaveResult > > resultCallback)
Combined button and popup list for selecting options.
QOhosWindowManager::ResultMultiplicity mapQFileDialogOptionsToOhosResultMultiplicity(const QFileDialogOptions &options)
QtOhos::InternalWindowId tryGetFocusedWindowInternalWindowId()
QOhosWindowManager::DocumentSelectMode mapQFileDialogOptionsToOhosDocumentSelectMode(const QFileDialogOptions &options)
QtOhos::InternalWindowId getQWindowInternalWindowIdOrFail(QWindow *qWindow)
QPlatformFileDialogHelper * makeQOhosPlatformFileDialogHelper()