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
qohosjsenv_p.h
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
4#ifndef QOHOSJSENV_H
5#define QOHOSJSENV_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtCore/private/qnapi_p.h>
19#include <QtCore/private/qohoslogger_p.h>
20#include <QtCore/qjsonarray.h>
21#include <QtCore/qjsonobject.h>
22#include <QtCore/qjsonvalue.h>
23#include <QtCore/qstring.h>
24
25#include <algorithm>
26#include <array>
27#include <cstdint>
28#include <iterator>
29#include <limits>
30#include <type_traits>
31#include <memory>
32#include <napi/native_api.h>
33#include <napi.h>
34#include <utility>
35
36QT_BEGIN_NAMESPACE
37
38struct QOhosJsEnv
39{
40 template <typename T, typename Enable = void>
41 struct QNapiValue {
42 static QNapi::Value create(napi_env /*env*/, T /*value*/) {
43 static_assert(sizeof(T) == 0, "Unsupported type - provide proper QOhosJsEnv::QNapiValue"
44 " overload");
45 }
46 static Napi::Maybe<T> get(const QNapi::Value &/*value*/) {
47 static_assert(sizeof(T) == 0, "Unsupported type - provide proper QOhosJsEnv::QNapiValue"
48 " overload");
49 }
50 };
51
52 template <typename T>
53 static QNapi::Value toNapiValue(napi_env env, T &&value) {
54 return QNapiValue<typename std::decay<T>::type>::create(env, std::forward<T>(value));
55 }
56
57 template<typename ReturnType>
58 static ReturnType fromNapiValue(const QNapi::Value &value)
59 {
60 return QNapiValue<typename std::decay<ReturnType>::type>::get(value).UnwrapOr(ReturnType());
61 }
62};
63
64//
65// overloads of QNapiValue to support various types
66//
67
68template<>
69struct QOhosJsEnv::QNapiValue<QList<QJsonValue>>
70{
71 static QNapi::Value create(napi_env env, const QList<QJsonValue> &inputValue);
72 static Napi::Maybe<QList<QJsonValue>> get(const QNapi::Value &inputValue);
73};
74
75template<>
76struct QOhosJsEnv::QNapiValue<QJsonValue>
77{
78 static QNapi::Value create(napi_env env, const QJsonValue &inputValue);
79 static Napi::Maybe<QJsonValue> get(const QNapi::Value &inputValue);
80};
81
82template<>
83struct QOhosJsEnv::QNapiValue<QJsonArray>
84{
85 static QNapi::Value create(napi_env env, const QJsonArray &inputValue);
86 static Napi::Maybe<QJsonArray> get(const QNapi::Value &inputValue);
87};
88
89template<>
90struct QOhosJsEnv::QNapiValue<QJsonObject>
91{
92 static QNapi::Value create(napi_env env, const QJsonObject &inputValue);
93 static Napi::Maybe<QJsonObject> get(const QNapi::Value &inputValue);
94};
95
96inline QNapi::Value QOhosJsEnv::QNapiValue<QList<QJsonValue>>::create(napi_env env, const QList<QJsonValue> &inputValue)
97{
98 return QNapi::runEscapingHandleScope<QNapi::Array>(
99 env,
100 [&]() {
101 auto outputArray = QNapi::Array::New(env, inputValue.length());
102 for (int i = 0; i < inputValue.length(); ++i)
103 outputArray.Set(i, QNapiValue<QJsonValue>::create(env, inputValue[i]));
104 return outputArray;
105 });
106}
107
108inline Napi::Maybe<QList<QJsonValue>> QOhosJsEnv::QNapiValue<QList<QJsonValue>>::get(const QNapi::Value &inputValue)
109{
110 if (!inputValue.IsArray())
111 return Napi::Nothing<QList<QJsonValue>>();
112
113 auto inputArray = QNapi::checkedCast<QNapi::Array>(inputValue);
114 std::uint32_t rawInputArrayLength = inputArray.Length();
115 if (rawInputArrayLength > std::numeric_limits<int>::max())
116 return Napi::Nothing<QList<QJsonValue>>();
117 int inputArrayLength = static_cast<int>(rawInputArrayLength);
118
119 QList<QJsonValue> outputList;
120 outputList.reserve(inputArrayLength);
121
122 for (int i = 0; i < inputArrayLength; ++i) {
123 Napi::HandleScope inputElementScope{inputValue.Env()};
124 auto optOutputElem = QNapiValue<QJsonValue>::get(inputArray.Get(i));
125 if (optOutputElem.IsNothing())
126 break;
127 outputList.append(optOutputElem.Unwrap());
128 }
129
130 return outputList.length() == inputArrayLength
131 ? Napi::Just(outputList)
132 : Napi::Nothing<QList<QJsonValue>>();
133}
134
135inline QNapi::Value QOhosJsEnv::QNapiValue<QJsonValue>::create(napi_env env, const QJsonValue &inputValue)
136{
137 switch (inputValue.type()) {
138 case QJsonValue::Type::Array:
139 return QNapiValue<QJsonArray>::create(env, inputValue.toArray());
140 case QJsonValue::Type::Bool:
141 return QNapi::Boolean::New(env, inputValue.toBool());
142 case QJsonValue::Type::Double:
143 return QNapi::Number::New(env, inputValue.toDouble());
144 case QJsonValue::Type::Null:
145 case QJsonValue::Type::Undefined:
146 return Napi::Env(env).Null();
147 case QJsonValue::Type::Object:
148 return QNapiValue<QJsonObject>::create(env, inputValue.toObject());
149 case QJsonValue::Type::String:
150 return QNapi::String::New(env, inputValue.toString().toStdString());
151 }
152
153 throw Napi::Error::New(env, "Got unsupported (impossible) QJsonValue");
154}
155
156inline Napi::Maybe<QJsonValue> QOhosJsEnv::QNapiValue<QJsonValue>::get(const QNapi::Value &inputValue)
157{
158 if (inputValue.IsArray()) {
159 const auto arrayValue = QNapiValue<QJsonArray>::get(inputValue);
160 return arrayValue.IsJust() ? Napi::Just<QJsonValue>(arrayValue.Unwrap()) : Napi::Nothing<QJsonValue>();
161 } else if (inputValue.IsBoolean()) {
162 const auto boolValue = QNapi::checkedCast<QNapi::Boolean>(inputValue).Value();
163 return Napi::Just(QJsonValue(boolValue));
164 } else if (inputValue.IsNumber()) {
165 const auto numberValue = QNapi::checkedCast<QNapi::Number>(inputValue).DoubleValue();
166 return Napi::Just(QJsonValue(numberValue));
167 } else if (inputValue.IsObject()) {
168 const auto objectValue = QNapiValue<QJsonObject>::get(inputValue);
169 return objectValue.IsJust() ? Napi::Just<QJsonValue>(objectValue.Unwrap()) : Napi::Nothing<QJsonValue>();
170 } else if (inputValue.IsString()) {
171 const auto stringValue = QString::fromStdString(QNapi::checkedCast<QNapi::String>(inputValue));
172 return Napi::Just<QJsonValue>(stringValue);
173 } else {
174 return Napi::Nothing<QJsonValue>();
175 }
176}
177
178inline QNapi::Value QOhosJsEnv::QNapiValue<QJsonArray>::create(napi_env env, const QJsonArray &inputValue)
179{
180 QList<QJsonValue> listInputValue;
181 listInputValue.reserve(inputValue.size());
182 std::copy(inputValue.begin(), inputValue.end(), std::back_inserter(listInputValue));
183 return QNapiValue<QList<QJsonValue>>::create(env, listInputValue);
184}
185
186inline Napi::Maybe<QJsonArray> QOhosJsEnv::QNapiValue<QJsonArray>::get(const QNapi::Value &inputValue)
187{
188 const auto transform = [](const QList<QJsonValue> &input) -> QJsonArray {
189 QJsonArray result;
190 std::copy(input.begin(), input.end(), std::back_inserter(result));
191 return result;
192 };
193
194 const auto listValue = QNapiValue<QList<QJsonValue>>::get(inputValue);
195 return listValue.IsJust()
196 ? Napi::Just(transform(listValue.Unwrap()))
197 : Napi::Nothing<QJsonArray>();
198}
199
200inline QNapi::Value QOhosJsEnv::QNapiValue<QJsonObject>::create(napi_env env, const QJsonObject &inputValue)
201{
202 return QNapi::runEscapingHandleScope<QNapi::Object>(
203 env,
204 [&]() {
205 auto outputObject = QNapi::Object::New(env);
206 for (auto inputValueIter = inputValue.begin(); inputValueIter != inputValue.end(); ++inputValueIter) {
207 outputObject.Set(
208 inputValueIter.key().toStdString(),
209 QNapiValue<QJsonValue>::create(env, inputValueIter.value()));
210 }
211 return outputObject;
212 });
213}
214
215inline Napi::Maybe<QJsonObject> QOhosJsEnv::QNapiValue<QJsonObject>::get(const QNapi::Value &inputValue)
216{
217 if (!inputValue.IsObject())
218 return Napi::Nothing<QJsonObject>();
219
220 auto inputObject = QNapi::checkedCast<QNapi::Object>(inputValue);
221
222 QJsonObject result;
223 bool allElementsSet = true;
224
225 for (const auto &inputElement : inputObject) {
226 if (inputElement.first.IsString()) {
227 const auto key = QString::fromStdString(QNapi::checkedCast<QNapi::String>(inputElement.first));
228
229 auto optPropValue = QNapiValue<QJsonValue>::get(inputElement.second);
230 if (optPropValue.IsNothing()) {
231 allElementsSet = false;
232 break;
233 }
234
235 result[key] = optPropValue.Unwrap();
236 }
237 }
238
239 return allElementsSet
240 ? Napi::Just(result)
241 : Napi::Nothing<QJsonObject>();
242}
243
244QT_END_NAMESPACE
245
246#endif // QOHOSJSENV_H
void update(Qt::InputMethodQueries queries) override
Notification on editor updates.
QRectF keyboardRect() const override
This function can be reimplemented to return virtual keyboard rectangle in currently active window co...
void setSoftwareKeyboardVisibilityStatus(bool visible)
void showInputPanel() override
Request to show input panel.
void invokeAction(QInputMethod::Action action, int cursorPosition) override
Called when the word currently being composed in the input item is tapped by the user.
void setLastInputTypeToTriggerSoftKeyboard(RequestKeyboardReason inputType)
void reset() override
Method to be called when input method needs to be reset.
void hideInputPanel() override
Request to hide input panel.
bool eventFilter(QObject *obj, QEvent *event) override
Filters events if this object has been installed as an event filter for the watched object.
bool isInputPanelVisible() const override
Returns input panel visibility status.
QObject * focusObjectOrNull() const
void setFocusObject(QObject *object) override
This virtual method gets called to notify updated focus to object.
bool isAnimating() const override
This function can be reimplemented to return true whenever input method is animating shown or hidden.
std::enable_if_t< qohosplugincore_h_detail::isQOhosOptional< QOhosInvokeResult< Func, T > >, QOhosInvokeResult< Func, T > > andThen(Func &&func) const
JsInputMethodInsertedTextComposer & operator=(const JsInputMethodInsertedTextComposer &)=delete
JsInputMethodInsertedTextComposer(JsInputMethodInsertedTextComposer &&)=delete
static JsInputMethodInsertedTextComposer & instance()
JsInputMethodInsertedTextComposer & operator=(JsInputMethodInsertedTextComposer &&)=delete
QOhosOptional< InsertedTextId > lastId() const
JsInputMethodInsertedTextComposer(const JsInputMethodInsertedTextComposer &)=delete
QOhosInsertedText makeInsertedText(const std::string &text)
QOhosInsertedText(const std::string &text, const InsertedTextId &id)
Combined button and popup list for selecting options.
QOhosOptional< QOhosInputContext::Direction > tryMapInputMethodDirectionToQt(::InputMethod_Direction direction)
::InputMethod_TextInputType mapQtInputMethodHintsToOhosImeTextInputType(Qt::InputMethodHints hints)
::InputMethod_EnterKeyType mapQtToOhosImeEnterKeyType(Qt::EnterKeyType qtEnterKeyType)
const Qt::EnterKeyType defaultEnterKeyType
void notifyOhosInputMethodAboutPossibleAutocorrection(const QOhosInsertedText &insertedText, int cursorPosition)
const Qt::InputMethodHints defaultInputMethodHints
QPoint clampToRect(const QPoint &p, const QRect &rect)
::InputMethod_RequestKeyboardReason mapQtToOhosImeRequestReason(QOhosInputContext::RequestKeyboardReason qtRequestKeyboardReason)
QOhosOptional< int > tryGetIntPropertyFromQuery(Qt::InputMethodQuery property, QSharedPointer< QInputMethodQueryEvent > query)
void invokeInJsThreadAndWaitForContinue(std::function< void(JsState &, std::function< void()>)> &&task)
QOhosOptional< void > makeEmptyQOhosOptional()