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
qohoswindowmanager.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
5#include <QtCore/qcoreapplication.h>
6#include <QtCore/private/qnapi_p.h>
7#include <QtCore/private/qohoscommon_p.h>
8#include <QtCore/private/qohoslogger_p.h>
9#include <QtCore/private/qohospathutils_p.h>
10#include <qohosjsenv_p.h>
11#include <qohosplugincore.h>
12#include <QtCore/qurl.h>
13#include <algorithm>
14#include <iterator>
15#include <vector>
17
19
20namespace {
21
27
29 QtOhos::JsState &jsState, QtOhos::QObjectThreadSafeRef qWindowRef)
30{
31 auto optQAbility = jsState.tryGetQAbilityByQWindow(qWindowRef);
32 return optQAbility ? optQAbility : jsState.defaultQAbility();
33}
34
36 QtOhos::JsState &jsState, QNapi::Object qAbility,
37 QtOhos::QObjectThreadSafeRef contextWindowRef)
38{
39 auto optContextJsWindow = jsState.tryGetJsWindowByQWindow(contextWindowRef);
40
41 std::vector<QNapi::ValueWrapper> constructorParams = {qAbility.get("context")};
42 if (optContextJsWindow)
43 constructorParams.push_back(optContextJsWindow.value());
44
45 return jsState.eval<QNapi::Object>(
46 "@ohos.file.picker.DocumentViewPicker<new>(*)", constructorParams);
47}
48
50 QtOhos::JsState &jsState, QtOhos::QObjectThreadSafeRef contextWindowRef,
51 const std::string &pickerActionName, QNapi::Object pickerActionOptions,
52 QOhosConsumer<std::optional<FilePickerResult>> resultConsumer)
53{
54 auto sharedResultConsumer = QtOhos::moveToSharedPtr(std::move(resultConsumer));
55
56 auto optQAbility = tryGetQAbilityForQWindow(jsState, contextWindowRef);
57 if (!optQAbility) {
58 qOhosPrintfError(
59 "Cannot call DocumentViewPicker.%s(): no UIAbility to use", pickerActionName.c_str());
60 (*sharedResultConsumer)(std::nullopt);
61 return;
62 }
63
64 qOhosPrintfDebug(
65 "Calling DocumentViewPicker.%s() with options: %s",
66 pickerActionName.c_str(), QNapi::toJsonString(pickerActionOptions).c_str());
67 auto documentViewPicker = QtOhos::moveToSharedPtr(
68 QNapi::Reference<>::makePersistentFrom(
69 makeDocumentViewPicker(jsState, optQAbility.value(), contextWindowRef)));
70 documentViewPicker->evalToPromiseOrRejectOnThrow(pickerActionName + "(*)", {pickerActionOptions}).onThen(
71 [documentViewPicker, pickerActionName, sharedResultConsumer](const QtOhos::CallbackInfo &cbInfo) {
72 auto actionResult = cbInfo.getFirstArg<QNapi::Array>(Q_FUNC_INFO);
73 auto resultOhosUris = QNapi::getArrayElements<std::vector<std::string>, QNapi::String>(actionResult);
74
75 qOhosPrintfDebug(
76 "Called DocumentViewPicker.%s() callback with result: %s",
77 pickerActionName.c_str(), QNapi::toJsonString(actionResult).c_str());
78
79 std::vector<std::string> resultPaths;
80 std::transform(
81 resultOhosUris.cbegin(), resultOhosUris.cend(), std::back_inserter(resultPaths),
82 [&](const auto &uri) {
83 return tryMapOhosFileUriToPath(uri).value_or("");
84 });
85
86 (*sharedResultConsumer)(
87 std::optional<FilePickerResult>(
88 {
89 .resultPaths = std::move(resultPaths),
90 .selectedIndex = documentViewPicker->eval<QNapi::Number>("getSelectedIndex()"),
91 }));
92 },
93 [pickerActionName, sharedResultConsumer]() {
94 qOhosPrintfError("DocumentViewPicker.%s() call failed", pickerActionName.c_str());
95 (*sharedResultConsumer)({});
96 });
97}
98
99QStringList mapFilePathsToQtUrls(const std::vector<std::string> &filePaths)
100{
101 QStringList qtUrls;
102 std::transform(
103 filePaths.cbegin(), filePaths.cend(), std::back_inserter(qtUrls),
104 [&](const auto &path) {
105 return QUrl::fromLocalFile(QString::fromStdString(path)).toString();
106 });
107 return qtUrls;
108}
109
110}
111
112namespace QOhosWindowManager {
113
115 QtOhos::QObjectThreadSafeRef contextWindowRef, QStringList filters, QString defaultPath,
116 DocumentSelectMode documentSelectMode, ResultMultiplicity resultMultiplicity,
117 QOhosConsumer<std::optional<OpenResult>> resultCallback)
118{
119 auto sharedResultCallback = QtOhos::moveToSharedPtr(std::move(resultCallback));
120
122 [contextWindowRef, filters, defaultPath, documentSelectMode, resultMultiplicity, sharedResultCallback](QtOhos::JsState &jsState) {
123 constexpr auto ohosMaxValueForMaxSelectNumber = 500;
124
125 auto *env = jsState.env();
126
127 auto documentSelectOptions = QNapi::makeObject(
128 env,
129 {
130 {"maxSelectNumber", resultMultiplicity == ResultMultiplicity::SINGLE ? 1 : ohosMaxValueForMaxSelectNumber},
131 {"fileSuffixFilters", QNapi::makeArray(env, filters, std::mem_fn(&QString::toStdString))},
132 {"defaultFilePathUri", tryMapPathToOhosFileUri(defaultPath.toStdString()).value_or("")},
133 {"selectMode", jsState.mapOhosEnumToJs(documentSelectMode)},
134 });
135
136 startOhosFilePicker(
137 jsState, contextWindowRef, "select", documentSelectOptions,
138 [sharedResultCallback](auto optResult) {
139 auto optQtOpenResult = qTransform(
140 optResult,
141 [](const auto &result) {
142 return OpenResult{
143 .selectedUrls = mapFilePathsToQtUrls(result.resultPaths),
144 };
145 });
146 QtOhos::invokeInQtThread(
147 [sharedResultCallback, optQtOpenResult]() {
148 (*sharedResultCallback)(optQtOpenResult);
149 });
150 });
151 });
152}
153
155 QtOhos::QObjectThreadSafeRef contextWindowRef, QStringList newFileNames,
156 QString defaultFilePath, QStringList fileSuffixChoices,
157 QOhosConsumer<std::optional<SaveResult>> resultCallback)
158{
159 auto sharedResultCallback = QtOhos::moveToSharedPtr(std::move(resultCallback));
160
162 [contextWindowRef, newFileNames, defaultFilePath, fileSuffixChoices, sharedResultCallback](QtOhos::JsState &jsState) {
163 auto *env = jsState.env();
164 auto documentSaveOptions = QNapi::Object::New(env);
165 if (!newFileNames.isEmpty())
166 documentSaveOptions.Set("newFileNames", QNapi::makeArray(env, newFileNames, std::mem_fn(&QString::toStdString)));
167 if (!defaultFilePath.isEmpty())
168 documentSaveOptions.Set("defaultFilePathUri", tryMapPathToOhosFileUri(defaultFilePath.toStdString()).value_or(""));
169 if (!fileSuffixChoices.isEmpty())
170 documentSaveOptions.Set("fileSuffixChoices", QNapi::makeArray(env, fileSuffixChoices, std::mem_fn(&QString::toStdString)));
171 documentSaveOptions.Set("autoCreateEmptyFile", false);
172
173 startOhosFilePicker(
174 jsState, contextWindowRef, "save", documentSaveOptions,
175 [sharedResultCallback](auto optResult) {
176 auto optQtSaveResult = qTransform(
177 optResult,
178 [](const auto &result) {
179 return SaveResult{
180 .savedUrls = mapFilePathsToQtUrls(result.resultPaths),
181 .selectedFileSuffixChoiceIndex = result.selectedIndex,
182 };
183 });
184 QtOhos::invokeInQtThread(
185 [sharedResultCallback, optQtSaveResult]() {
186 (*sharedResultCallback)(optQtSaveResult);
187 });
188 });
189 });
190}
191
192}
193
194QT_END_NAMESPACE
void showFileDialogOpen(QtOhos::QObjectThreadSafeRef contextWindowRef, QStringList filters, QString defaultPath, DocumentSelectMode documentSelectMode, ResultMultiplicity resultMultiplicity, QOhosConsumer< std::optional< OpenResult > > resultCallback)
void showFileDialogSave(QtOhos::QObjectThreadSafeRef contextWindowRef, QStringList newFileNames, QString defaultFilePath, QStringList fileSuffixChoices, QOhosConsumer< std::optional< SaveResult > > resultCallback)
Combined button and popup list for selecting options.
std::optional< QNapi::Object > tryGetQAbilityForQWindow(QtOhos::JsState &jsState, QtOhos::QObjectThreadSafeRef qWindowRef)
QNapi::Object makeDocumentViewPicker(QtOhos::JsState &jsState, QNapi::Object qAbility, QtOhos::QObjectThreadSafeRef contextWindowRef)
void startOhosFilePicker(QtOhos::JsState &jsState, QtOhos::QObjectThreadSafeRef contextWindowRef, const std::string &pickerActionName, QNapi::Object pickerActionOptions, QOhosConsumer< std::optional< FilePickerResult > > resultConsumer)
QStringList mapFilePathsToQtUrls(const std::vector< std::string > &filePaths)
void invokeInJsThread(std::function< void(JsState &)> task)