6#include <android/log.h>
14#include "private/qhighdpiscaling_p.h"
16#include <QTextBoundaryFinder>
17#include <QTextCharFormat>
18#include <QtCore/QJniEnvironment>
19#include <QtCore/QJniObject>
26#include <qpa/qplatformwindow.h>
39 m_context->beginBatchEdit();
44 m_context->endBatchEdit();
83 qCDebug(lcQpaInputMethods) <<
"@@@ BEGINBATCH";
84 jboolean
res = JNI_FALSE;
94 qCDebug(lcQpaInputMethods) <<
"@@@ ENDBATCH";
96 jboolean
res = JNI_FALSE;
102static jboolean
commitText(JNIEnv *env, jobject , jstring
text, jint newCursorPosition)
108 const jchar *jstr = env->GetStringChars(
text, &isCopy);
110 env->ReleaseStringChars(
text, jstr);
112 qCDebug(lcQpaInputMethods) <<
"@@@ COMMIT" <<
str << newCursorPosition;
113 jboolean
res = JNI_FALSE;
123 qCDebug(lcQpaInputMethods) <<
"@@@ DELETE" << leftLength << rightLength;
124 jboolean
res = JNI_FALSE;
134 qCDebug(lcQpaInputMethods) <<
"@@@ FINISH";
135 jboolean
res = JNI_FALSE;
166 env->SetObjectField(
object,
168 env->NewString(
reinterpret_cast<const jchar *
>(extractedText.
text.
constData()),
181 qCDebug(lcQpaInputMethods) <<
"@@@ GETSEL" <<
text;
215 const jchar *jstr = env->GetStringChars(
text, &isCopy);
217 env->ReleaseStringChars(
text, jstr);
219 qCDebug(lcQpaInputMethods) <<
"@@@ SET" <<
str << newCursorPosition;
220 jboolean
res = JNI_FALSE;
231 jboolean
res = JNI_FALSE;
243 jboolean
res = JNI_FALSE;
254 qCDebug(lcQpaInputMethods) <<
"@@@ SELALL";
255 jboolean
res = JNI_FALSE;
260static jboolean
cut(JNIEnv *, jobject )
265 qCDebug(lcQpaInputMethods) <<
"@@@";
266 jboolean
res = JNI_FALSE;
271static jboolean
copy(JNIEnv *, jobject )
276 qCDebug(lcQpaInputMethods) <<
"@@@";
277 jboolean
res = JNI_FALSE;
287 qCDebug(lcQpaInputMethods) <<
"@@@";
288 jboolean
res = JNI_FALSE;
293static jboolean
paste(JNIEnv *, jobject )
298 qCDebug(lcQpaInputMethods) <<
"@@@ PASTE";
299 jboolean
res = JNI_FALSE;
309 qCDebug(lcQpaInputMethods) <<
"@@@ UPDATECURSORPOS";
319 {
"commitText",
"(Ljava/lang/String;I)Z", (
void *)
commitText},
323 {
"getExtractedText",
"(III)Lorg/qtproject/qt/android/QtExtractedText;", (
void *)
getExtractedText},
331 {
"cut",
"()Z", (
void *)
cut},
332 {
"copy",
"()Z", (
void *)
copy},
333 {
"copyURL",
"()Z", (
void *)
copyURL},
334 {
"paste",
"()Z", (
void *)
paste},
347 , m_composingTextStart(-1)
348 , m_composingCursor(-1)
349 , m_handleMode(Hidden)
350 , m_batchEditNestingLevel(0)
356 qCritical() <<
"Native registration unable to find class '"
363 qCritical() <<
"RegisterNatives failed for '"
371 qCritical() <<
"Native registration unable to find class '"
386 qCritical(
"Can't find field partialEndOffset");
392 qCritical(
"Can't find field partialStartOffset");
398 qCritical(
"Can't find field selectionEnd");
404 qCritical(
"Can't find field selectionStart");
410 qCritical(
"Can't find field startOffset");
419 qRegisterMetaType<QInputMethodEvent *>(
"QInputMethodEvent*");
420 qRegisterMetaType<QInputMethodQueryEvent *>(
"QInputMethodQueryEvent*");
428 auto im =
qGuiApp->inputMethod();
429 if (!im->inputItemClipRectangle().contains(im->anchorRectangle()) ||
430 !im->inputItemClipRectangle().contains(im->cursorRectangle())) {
431 m_handleMode = Hidden;
432 updateSelectionHandles();
477 focusObjectStopComposing();
479 m_batchEditNestingLevel = 0;
493 focusObjectStopComposing();
499 if (!
query.isNull() && m_batchEditNestingLevel == 0) {
501 const int composeLength = m_composingText.
length();
504 if (m_composingText.
isEmpty() != (m_composingTextStart == -1))
505 qWarning() <<
"Input method out of sync" << m_composingText << m_composingTextStart;
507 int realSelectionStart = cursorPos;
508 int realSelectionEnd = cursorPos;
512 if (cpos != anchor) {
513 if (!m_composingText.
isEmpty()) {
514 qWarning(
"Selecting text while preediting may give unpredictable results.");
515 focusObjectStopComposing();
518 realSelectionStart = blockPos + cpos;
519 realSelectionEnd = blockPos + anchor;
522 if (focusObjectIsComposing())
523 realSelectionStart = realSelectionEnd = m_composingCursor;
526 if (realSelectionStart > realSelectionEnd)
527 std::swap(realSelectionStart, realSelectionEnd);
530 m_composingTextStart, m_composingTextStart + composeLength);
537 if (noHandles || !m_focusObject)
540 auto im =
qGuiApp->inputMethod();
550 bool readOnly = readOnlyVariant.
toBool();
553 if ( cpos == anchor && (!readOnlyVariant.
isValid() || readOnly)) {
558 if (cpos == anchor || im->anchorRectangle().isNull()) {
561 QPoint(curRect.x() + (curRect.width() / 2), curRect.y() + curRect.height()));
562 QPoint cursorPoint(curRect.center().x(), curRect.bottom());
567 if (cursorPointGlobal != cursorPoint) {
568 x = cursorPointGlobal.
x();
569 y = cursorPointGlobal.
y();
580 if (m_hideCursorHandleTimer.
isActive())
581 m_hideCursorHandleTimer.
start();
589 std::swap(leftRect, rightRect);
594 QPoint rightPoint(qPlatformWindow->
mapToGlobal(rightRect.bottomRight().toPoint()));
597 if (platformIntegration) {
608 QPoint editPoint(qPlatformWindow->
mapToGlobal(leftRect.united(rightRect).topLeft().toPoint()));
614 m_hideCursorHandleTimer.
stop();
625 if (m_batchEditNestingLevel != 0) {
626 qWarning() <<
"QAndroidInputContext::handleLocationChanged returned";
640 std::swap(leftRect, rightRect);
643 if (handleId == 2 && point.
y() > rightRect.center().y()) {
644 point.
setY(rightRect.center().y());
645 }
else if (handleId == 3 && point.
y() < leftRect.center().y()) {
646 point.
setY(leftRect.center().y());
650 auto object = m_focusObject->
parent();
657 object =
object->parent();
671 int newAnchor = anchor;
672 if (newAnchor > newCpos)
673 std::swap(newAnchor, newCpos);
677 newAnchor = handlePos;
678 }
else if (handleId == 2) {
679 newAnchor = handlePos;
680 }
else if (handleId == 3) {
689 if ((handleId == 2 || handleId == 3) && newCpos <= newAnchor) {
693 const int oldSelectionStartPos =
qMin(cpos, anchor);
698 newAnchor = finder.
position() + oldSelectionStartPos;
702 newCpos = finder.
position() + oldSelectionStartPos;
707 if (!focusObjectIsComposing() && newCpos == cpos && newAnchor == anchor)
715 if (focusObjectIsComposing() && handleId == 1) {
719 const int blockPos = absoluteCpos - cpos;
721 if (blockPos + newCpos == m_composingCursor)
725 BatchEditLock batchEditLock(
this);
727 focusObjectStopComposing();
731 if (newCpos != newAnchor)
744 m_hideCursorHandleTimer.
stop();
746 if (focusObjectIsComposing()) {
749 const int touchPosition = curBlockPos
751 if (touchPosition != m_composingCursor)
752 focusObjectStopComposing();
766 BatchEditLock batchEditLock(
this);
768 focusObjectStopComposing();
778 for (
const auto &
ch : after) {
779 if (!
ch.isLetterOrNumber())
784 for (
auto itch = before.
rbegin(); itch != after.
rend(); ++itch) {
785 if (!itch->isLetterOrNumber())
789 if (
cursor == anchor || cursor < 0 || cursor - anchor > 500) {
820 m_hideCursorHandleTimer.
start();
829#warning TODO extract the needed data from query
834#warning TODO Handle at least QInputMethod::ContextMenu action
863 m_updateCursorPosConnection = {};
865 if (
qGuiApp->focusObject()->metaObject()->indexOfSignal(
"cursorPositionChanged(int,int)") >= 0)
867 else if (
qGuiApp->focusObject()->metaObject()->indexOfSignal(
"cursorPositionChanged()") >= 0)
904 return m_composingText.
length();
909 m_composingText.
clear();
910 m_composingTextStart = -1;
911 m_composingCursor = -1;
912 m_extractedText.
clear();
918 if (
object != m_focusObject) {
919 focusObjectStopComposing();
928 ++m_batchEditNestingLevel;
934 if (--m_batchEditNestingLevel == 0) {
935 focusObjectStartComposing();
947 BatchEditLock batchEditLock(
this);
953 BatchEditLock batchEditLock(
this);
955 focusObjectStopComposing();
961 if (leftLength < 0) {
962 rightLength += -leftLength;
981 ?
qMin(initialCursorPos, initialAnchorPos)
982 :
qMin(
qMin(initialCursorPos, initialAnchorPos), m_composingTextStart);
984 const int rightBegin =
986 ?
qMax(initialCursorPos, initialAnchorPos)
987 :
qMax(
qMax(initialCursorPos, initialAnchorPos),
988 m_composingTextStart + m_composingText.
length());
990 int textBeforeCursorLen;
991 int textAfterCursorLen;
999 textBeforeCursorLen = initialCursorPos - initialBlockPos;
1000 textAfterCursorLen =
1004 leftLength =
qMin(
qMax(0, textBeforeCursorLen - (initialCursorPos - leftEnd)), leftLength);
1005 rightLength =
qMin(
qMax(0, textAfterCursorLen - (rightBegin - initialCursorPos)), rightLength);
1007 if (leftLength == 0 && rightLength == 0)
1010 if (leftEnd == rightBegin) {
1013 event.setCommitString({}, -leftLength, leftLength + rightLength);
1016 if (initialCursorPos != initialAnchorPos) {
1024 int currentCursorPos = initialCursorPos;
1026 if (rightLength > 0) {
1028 event.setCommitString({}, rightBegin - currentCursorPos, rightLength);
1031 currentCursorPos = rightBegin;
1034 if (leftLength > 0) {
1035 const int leftBegin = leftEnd - leftLength;
1038 event.setCommitString({}, leftBegin - currentCursorPos, leftLength);
1041 currentCursorPos = leftBegin;
1043 if (!m_composingText.
isEmpty())
1044 m_composingTextStart -= leftLength;
1048 if (currentCursorPos != initialCursorPos - leftLength
1049 || initialCursorPos != initialAnchorPos) {
1056 initialAnchorPos - initialCursorPos },
1070 BatchEditLock batchEditLock(
this);
1072 if (!focusObjectStopComposing())
1079bool QAndroidInputContext::focusObjectIsComposing()
const
1081 return m_composingCursor != -1;
1084void QAndroidInputContext::focusObjectStartComposing()
1086 if (focusObjectIsComposing() || m_composingText.
isEmpty())
1090 if (m_composingText.
contains(u
'\n'))
1101 if (absoluteCursorPos < m_composingTextStart
1102 || absoluteCursorPos > m_composingTextStart + m_composingText.
length())
1105 m_composingCursor = absoluteCursorPos;
1115 event.setCommitString({}, m_composingTextStart - absoluteCursorPos, m_composingText.
length());
1120bool QAndroidInputContext::focusObjectStopComposing()
1122 if (!focusObjectIsComposing())
1130 const int localCursorPos = m_composingCursor - blockPos;
1132 m_composingCursor = -1;
1138 event.setCommitString(m_composingText);
1139 sendInputMethodEvent(&
event);
1147 sendInputMethodEvent(&
event);
1163 bool atWordBoundary =
1165 && (!focusObjectIsComposing() || m_composingCursor == m_composingTextStart);
1167 if (!atWordBoundary) {
1169 surroundingText.
truncate(localPos);
1170 if (focusObjectIsComposing())
1171 surroundingText +=
QStringView{m_composingText}.
left(m_composingCursor - m_composingTextStart);
1179 res |= CAP_MODE_SENTENCES;
1182 res |= CAP_MODE_CHARACTERS;
1198 return m_extractedText;
1211 if (focusObjectIsComposing()) {
1212 m_extractedText.
text =
1213 textBeforeCursor.
toString() + m_composingText + textAfterCursor.
toString();
1223 if (focusObjectIsComposing())
1224 m_extractedText.
text.
insert(cursorPos - blockPos, m_composingText);
1229 if (focusObjectIsComposing()) {
1242 return m_extractedText;
1262 if (reportedTextAfter.
isValid()) {
1274 if (focusObjectIsComposing()) {
1276 const int cursorPosInsidePreedit = m_composingCursor - m_composingTextStart;
1285 if (anchorPos > cursorPos)
1302 if (reportedTextBefore.
isValid()) {
1314 if (focusObjectIsComposing()) {
1316 const int cursorPosInsidePreedit = m_composingCursor - m_composingTextStart;
1325 if (anchorPos < cursorPos)
1351 BatchEditLock batchEditLock(
this);
1356 auto setCursorPosition = [=]() {
1364 if (!m_composingText.
isEmpty() && absoluteCursorPos != absoluteAnchorPos) {
1365 setCursorPosition();
1366 absoluteAnchorPos = absoluteCursorPos;
1372 setCursorPosition();
1378 const int effectiveAbsoluteCursorPos =
qMin(absoluteCursorPos, absoluteAnchorPos);
1379 if (m_composingTextStart == -1)
1380 m_composingTextStart = effectiveAbsoluteCursorPos;
1382 const int oldComposingTextLen = m_composingText.
length();
1383 m_composingText =
text;
1385 const int newAbsoluteCursorPos =
1386 newCursorPosition <= 0
1387 ? m_composingTextStart + newCursorPosition
1388 : m_composingTextStart + m_composingText.
length() + newCursorPosition - 1;
1390 const bool focusObjectWasComposing = focusObjectIsComposing();
1394 && newAbsoluteCursorPos >= m_composingTextStart
1395 && newAbsoluteCursorPos <= m_composingTextStart + m_composingText.
length())
1396 m_composingCursor = newAbsoluteCursorPos;
1398 m_composingCursor = -1;
1400 if (focusObjectIsComposing()) {
1409 if (oldComposingTextLen > 0 && !focusObjectWasComposing) {
1410 event.setCommitString({}, m_composingTextStart - effectiveAbsoluteCursorPos,
1411 oldComposingTextLen);
1413 if (m_composingText.
isEmpty())
1420 if (focusObjectWasComposing) {
1421 event.setCommitString(m_composingText);
1423 event.setCommitString(m_composingText,
1424 m_composingTextStart - effectiveAbsoluteCursorPos,
1425 oldComposingTextLen);
1427 if (m_composingText.
isEmpty())
1433 if (!focusObjectIsComposing() && newCursorPosition != 1) {
1458 BatchEditLock batchEditLock(
this);
1479 if (start < textOffset || end > textOffset +
text.
length()) {
1484 const int additionalSuffixLen = after.
length() - (
text.
length() - cursorPos);
1486 if (additionalSuffixLen > 0)
1490 if (
start < textOffset) {
1492 before.
chop(cursorPos);
1496 textOffset -= before.
length();
1500 if (start < textOffset || end - textOffset >
text.
length()) {
1501 qCDebug(lcQpaInputMethods) <<
"Warning: setComposingRegion: failed to retrieve text from composing region";
1508 m_composingTextStart =
start;
1519 BatchEditLock batchEditLock(
this);
1522 int localCursorPos =
start - blockPosition;
1524 if (focusObjectIsComposing() &&
start ==
end &&
start >= m_composingTextStart
1525 &&
start <= m_composingTextStart + m_composingText.
length()) {
1529 int pos = localCursorPos - localOldPos;
1540 m_composingCursor =
start;
1546 focusObjectStopComposing();
1559 BatchEditLock batchEditLock(
this);
1561 focusObjectStopComposing();
1569 BatchEditLock batchEditLock(
this);
1582 BatchEditLock batchEditLock(
this);
1584 focusObjectStopComposing();
1598 BatchEditLock batchEditLock(
this);
1610 for (
int i = 0;
i < sequence.
count(); ++
i) {
static JNINativeMethod methods[]
jboolean beginBatchEdit()
jboolean setSelection(jint start, jint end)
void touchDown(int x, int y)
void safeCall(const std::function< void()> &func, Qt::ConnectionType conType=Qt::BlockingQueuedConnection)
void longPress(int x, int y)
jboolean finishComposingText()
jint getCursorCapsMode(jint reqModes)
QString getSelectedText(jint flags)
bool isAnimating() const override
This function can be reimplemented to return true whenever input method is animating shown or hidden.
void hideSelectionHandles()
QString getTextAfterCursor(jint length, jint flags)
QRectF keyboardRect() const override
This function can be reimplemented to return virtual keyboard rectangle in currently active window co...
void reset() override
Method to be called when input method needs to be reset.
jboolean setComposingText(const QString &text, jint newCursorPosition)
void hideInputPanel() override
Request to hide input panel.
void setFocusObject(QObject *object) override
This virtual method gets called to notify updated focus to object.
jboolean commitText(const QString &text, jint newCursorPosition)
jboolean setComposingRegion(jint start, jint end)
static QAndroidInputContext * androidInputContext()
void updateSelectionHandles()
void update(Qt::InputMethodQueries queries) override
Notification on editor updates.
QString getTextBeforeCursor(jint length, jint flags)
void sendShortcut(const QKeySequence &)
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 updateCursorPosition()
jboolean deleteSurroundingText(jint leftLength, jint rightLength)
void handleLocationChanged(int handleId, int x, int y)
void showInputPanel() override
Request to show input panel.
const ExtractedText & getExtractedText(jint hintMaxChars, jint hintMaxLines, jint flags)
bool isInputPanelVisible() const override
Returns input panel visibility status.
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
static Qt::ApplicationState applicationState()
static QWindow * focusWindow()
Returns the QWindow that receives events tied to focus, such as key events.
static QInputMethod * inputMethod()
returns the input method.
The QKeyEvent class describes a key event.
The QKeySequence class encapsulates a key sequence as used by shortcuts.
int count() const
Returns the number of keys in the key sequence.
void append(parameter_type t)
QObject * parent() const
Returns a pointer to the parent object.
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
QVariant property(const char *name) const
Returns the value of the object's name property.
The QPlatformInputContext class abstracts the input method dependent data and composing state.
static QRectF anchorRectangle()
QPlatformInputContext::anchorRectangle.
static void setSelectionOnFocusObject(const QPointF &anchorPos, const QPointF &cursorPos)
QPlatformInputContext::setSelectionOnFocusObject.
static QVariant queryFocusObject(Qt::InputMethodQuery query, QPointF position)
QPlatformInputContext::queryFocusObject.
static QRectF cursorRectangle()
QPlatformInputContext::cursorRectangle.
static QRectF inputItemRectangle()
QPlatformInputContext::inputItemRectangle.
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
constexpr int x() const noexcept
Returns the x coordinate of this point.
constexpr void setY(int y) noexcept
Sets the y coordinate of this point to the given y coordinate.
constexpr int y() const noexcept
Returns the y coordinate of this point.
constexpr void setX(int x) noexcept
Sets the x coordinate of this point to the given x coordinate.
\inmodule QtCore\reentrant
constexpr QRect toRect() const noexcept
Returns a QRect based on the values of this rectangle.
\inmodule QtCore\reentrant
constexpr QPoint topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
constexpr QSize size() const noexcept
Returns the size of the rectangle.
constexpr int right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
\macro QT_RESTRICTED_CAST_FROM_ASCII
QString right(qsizetype n) const
Returns a substring that contains the n rightmost characters of the string.
void chop(qsizetype n)
Removes n characters from the end of the string.
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void truncate(qsizetype pos)
Truncates the string at the given position index.
void clear()
Clears the contents of the string and makes it null.
const QChar * constData() const
Returns a pointer to the data stored in the QString.
QString mid(qsizetype position, qsizetype n=-1) const
Returns a string that contains n characters of this string, starting at the specified position index.
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
int compare(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
QString & insert(qsizetype i, QChar c)
bool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString left(qsizetype n) const
Returns a substring that contains the n leftmost characters of the string.
QString & remove(qsizetype i, qsizetype len)
Removes n characters from the string, starting at the given position index, and returns a reference t...
qsizetype length() const
Returns the number of characters in this string.
reverse_iterator rbegin()
BatchEditLock(const BatchEditLock &)=delete
BatchEditLock(QAndroidInputContext *context)
BatchEditLock & operator=(const BatchEditLock &)=delete
void setPosition(qsizetype position)
Sets the current position of the QTextBoundaryFinder to position.
qsizetype toNextBoundary()
Moves the QTextBoundaryFinder to the next boundary position and returns that position.
qsizetype toPreviousBoundary()
Moves the QTextBoundaryFinder to the previous boundary position and returns that position.
void toStart()
Moves the finder to the start of the string.
void toEnd()
Moves the finder to the end of the string.
bool isAtBoundary() const
Returns true if the object's position() is currently at a valid text boundary.
qsizetype position() const
Returns the current position of the QTextBoundaryFinder.
void setFontUnderline(bool underline)
If underline is true, sets the text format's font to be underlined; otherwise it is displayed non-und...
static QThread * currentThread()
void setSingleShot(bool singleShot)
void start(int msec)
Starts or restarts the timer with a timeout interval of msec milliseconds.
void setInterval(int msec)
bool isActive() const
Returns true if the timer is running (pending); otherwise returns false.
void stop()
Stops the timer.
void timeout(QPrivateSignal)
This signal is emitted when the timer times out.
void setTimerType(Qt::TimerType atype)
bool isValid() const
Returns true if the storage type of this variant is not QMetaType::UnknownType; otherwise returns fal...
int toInt(bool *ok=nullptr) const
Returns the variant as an int if the variant has userType() \l QMetaType::Int, \l QMetaType::Bool,...
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
bool toBool() const
Returns the variant as a bool if the variant has userType() Bool.
T fromNativePixels(const T &value, const C *context)
Combined button and popup list for selecting options.
QAndroidPlatformIntegration * androidPlatformIntegration()
@ BlockingQueuedConnection
static int getBlockPosition(const QSharedPointer< QInputMethodQueryEvent > &query)
static char const *const QtExtractedTextClassName
static jboolean cut(JNIEnv *, jobject)
static jint getCursorCapsMode(JNIEnv *, jobject, jint reqModes)
static QAndroidInputContext * m_androidInputContext
static JNINativeMethod methods[]
static QRect screenInputItemRectangle()
static jboolean finishComposingText(JNIEnv *, jobject)
static jobject getExtractedText(JNIEnv *env, jobject, int hintMaxChars, int hintMaxLines, jint flags)
static char const *const QtNativeInputConnectionClassName
static jfieldID m_partialStartOffsetFieldID
static jboolean copy(JNIEnv *, jobject)
static jstring getTextBeforeCursor(JNIEnv *env, jobject, jint length, jint flags)
static jfieldID m_selectionEndFieldID
static jboolean copyURL(JNIEnv *, jobject)
static jmethodID m_classConstructorMethodID
static jfieldID m_startOffsetFieldID
static void runOnQtThread(const std::function< void()> &func)
static jboolean commitText(JNIEnv *env, jobject, jstring text, jint newCursorPosition)
static jfieldID m_partialEndOffsetFieldID
static jboolean paste(JNIEnv *, jobject)
static jboolean beginBatchEdit(JNIEnv *, jobject)
static jstring getSelectedText(JNIEnv *env, jobject, jint flags)
static jboolean setComposingRegion(JNIEnv *, jobject, jint start, jint end)
static jfieldID m_textFieldID
static jboolean deleteSurroundingText(JNIEnv *, jobject, jint leftLength, jint rightLength)
static jboolean setComposingText(JNIEnv *env, jobject, jstring text, jint newCursorPosition)
static jboolean updateCursorPosition(JNIEnv *, jobject)
static int m_selectHandleWidth
static jstring getTextAfterCursor(JNIEnv *env, jobject, jint length, jint flags)
static int getAbsoluteCursorPosition(const QSharedPointer< QInputMethodQueryEvent > &query)
static jboolean endBatchEdit(JNIEnv *, jobject)
static jclass m_extractedTextClass
static jfieldID m_selectionStartFieldID
static jboolean setSelection(JNIEnv *, jobject, jint start, jint end)
static jboolean selectAll(JNIEnv *, jobject)
#define qCDebug(category,...)
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qMax(const T &a, const T &b)
#define Q_ARG(Type, data)
static bool contains(const QJsonArray &haystack, unsigned needle)
GLint GLint GLint GLint GLint x
[0]
GLenum GLuint GLenum GLsizei length
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=nullptr) noexcept
myObject disconnect()
[26]