1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include <QtVirtualKeyboard/qvirtualkeyboardinputengine.h>
5#include <QtVirtualKeyboard/qvirtualkeyboardinputcontext.h>
6#include <QtVirtualKeyboard/private/qvirtualkeyboardinputcontext_p.h>
7#include <QtVirtualKeyboard/private/shifthandler_p.h>
8#include <QtVirtualKeyboard/private/fallbackinputmethod_p.h>
9#include <QtVirtualKeyboard/qvirtualkeyboardtrace.h>
10#include <QtVirtualKeyboard/private/virtualkeyboarddebug_p.h>
11
12#include <QQmlContext>
13#include <QQmlEngine>
14#include <QTimerEvent>
15#include <QtCore/private/qobject_p.h>
16
17QT_BEGIN_NAMESPACE
18using namespace QtVirtualKeyboard;
19
20class QVirtualKeyboardInputEnginePrivate : public QObjectPrivate
21{
22 Q_DECLARE_PUBLIC(QVirtualKeyboardInputEngine)
23
24public:
25 QVirtualKeyboardInputEnginePrivate(QVirtualKeyboardInputEngine *q_ptr) :
26 QObjectPrivate(),
27 q_ptr(q_ptr),
28 inputContext(nullptr),
29 fallbackInputMethod(nullptr),
30 textCase(QVirtualKeyboardInputEngine::TextCase::Lower),
31 inputMode(QVirtualKeyboardInputEngine::InputMode::Latin),
32 activeKey(Qt::Key_unknown),
33 activeKeyModifiers(Qt::NoModifier),
34 previousKey(Qt::Key_unknown),
35 repeatTimer(0),
36 repeatCount(0),
37 recursiveMethodLock(0)
38 {
39 }
40
41 virtual ~QVirtualKeyboardInputEnginePrivate()
42 {
43 }
44
45 bool virtualKeyClick(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers, bool isAutoRepeat)
46 {
47 Q_Q(QVirtualKeyboardInputEngine);
48 bool accept = false;
49 if (inputMethod) {
50 accept = inputMethod->keyEvent(key, text, modifiers);
51 if (!accept) {
52 accept = fallbackInputMethod->keyEvent(key, text, modifiers);
53 }
54 emit q->virtualKeyClicked(key, text, modifiers, isAutoRepeat);
55 } else if (QT_VIRTUALKEYBOARD_FORCE_EVENTS_WITHOUT_FOCUS) {
56 accept = fallbackInputMethod->keyEvent(key, text, modifiers);
57 emit q->virtualKeyClicked(key, text, modifiers, isAutoRepeat);
58 } else {
59 qWarning() << "input method is not set";
60 }
61 return accept;
62 }
63
64 QVirtualKeyboardInputEngine* q_ptr;
65 QVirtualKeyboardInputContext *inputContext;
66 QPointer<QVirtualKeyboardAbstractInputMethod> inputMethod;
67 QVirtualKeyboardAbstractInputMethod *fallbackInputMethod;
68 QVirtualKeyboardInputEngine::TextCase textCase;
69 QVirtualKeyboardInputEngine::InputMode inputMode;
70 QList<int> inputModes;
71 QMap<QVirtualKeyboardSelectionListModel::Type, QVirtualKeyboardSelectionListModel *> selectionListModels;
72 Qt::Key activeKey;
73 QString activeKeyText;
74 Qt::KeyboardModifiers activeKeyModifiers;
75 Qt::Key previousKey;
76 int repeatTimer;
77 int repeatCount;
78 int recursiveMethodLock;
79};
80
81class RecursiveMethodGuard
82{
83public:
84 explicit RecursiveMethodGuard(int &ref) : m_ref(ref)
85 {
86 m_ref++;
87 }
88 ~RecursiveMethodGuard()
89 {
90 m_ref--;
91 }
92 bool locked() const
93 {
94 return m_ref > 1;
95 }
96private:
97 int &m_ref;
98};
99
100/*!
101 \qmltype InputEngine
102 \inqmlmodule QtQuick.VirtualKeyboard
103 \ingroup qtvirtualkeyboard-internal-qml
104 \instantiates QVirtualKeyboardInputEngine
105 \brief Maps the user input to the input methods.
106
107 The input engine is responsible for routing input events to input
108 methods. The actual input logic is implemented by the input methods.
109
110 The input engine also includes the default input method, which takes
111 care of default processing if the active input method does not handle
112 the event.
113*/
114
115/*!
116 \class QVirtualKeyboardInputEngine
117 \inmodule QtVirtualKeyboard
118 \ingroup qtvirtualkeyboard-cpp-for-devs
119 \brief The InputEngine class provides an input engine
120 that supports C++ and QML integration.
121
122 The input engine is responsible for routing input events to input
123 methods. The actual input logic is implemented by the input methods.
124
125 The input engine also includes the default input method, which takes
126 care of default processing if the active input method does not handle
127 the event.
128*/
129
130/*!
131 \internal
132 Constructs an input engine with input context as \a parent.
133*/
134QVirtualKeyboardInputEngine::QVirtualKeyboardInputEngine(QVirtualKeyboardInputContext *parent) :
135 QObject(*new QVirtualKeyboardInputEnginePrivate(this), parent)
136{
137 Q_D(QVirtualKeyboardInputEngine);
138 d->inputContext = parent;
139}
140
141void QVirtualKeyboardInputEngine::init()
142{
143 Q_D(QVirtualKeyboardInputEngine);
144 ShiftHandler *shiftHandler = d->inputContext->priv()->shiftHandler();
145 QObject::connect(sender: shiftHandler, signal: &ShiftHandler::shiftActiveChanged, context: this, slot: &QVirtualKeyboardInputEngine::shiftChanged);
146 QObject::connect(sender: d->inputContext, signal: &QVirtualKeyboardInputContext::localeChanged, context: this, slot: &QVirtualKeyboardInputEngine::update);
147 QObject::connect(sender: d->inputContext, signal: &QVirtualKeyboardInputContext::inputMethodHintsChanged, context: this, slot: &QVirtualKeyboardInputEngine::updateSelectionListModels);
148 QObject::connect(sender: d->inputContext, signal: &QVirtualKeyboardInputContext::localeChanged, context: this, slot: &QVirtualKeyboardInputEngine::updateInputModes);
149 QObject::connect(sender: this, signal: &QVirtualKeyboardInputEngine::inputMethodChanged, context: this, slot: &QVirtualKeyboardInputEngine::updateInputModes);
150 d->fallbackInputMethod = new FallbackInputMethod(this);
151 if (d->fallbackInputMethod)
152 d->fallbackInputMethod->setInputEngine(this);
153 d->selectionListModels[QVirtualKeyboardSelectionListModel::Type::WordCandidateList] = new QVirtualKeyboardSelectionListModel(this);
154}
155
156/*!
157 \internal
158 Destroys the input engine and frees all allocated resources.
159*/
160QVirtualKeyboardInputEngine::~QVirtualKeyboardInputEngine()
161{
162}
163
164/*!
165 \qmlmethod bool InputEngine::virtualKeyPress(int key, string text, int modifiers, bool repeat)
166
167 Called by the keyboard layer to indicate that \a key was pressed, with
168 the given \a text and \a modifiers.
169
170 The \a key is set as an active key (down key). The actual key event is
171 triggered when the key is released by the virtualKeyRelease() method. The
172 key press event can be discarded by calling virtualKeyCancel().
173
174 The key press also initiates the key repeat timer if \a repeat is \c true.
175
176 Returns \c true if the key was accepted by this input engine.
177
178 \sa virtualKeyCancel(), virtualKeyRelease()
179*/
180/*!
181 Called by the keyboard layer to indicate that \a key was pressed, with
182 the given \a text and \a modifiers.
183
184 The \a key is set as an active key (down key). The actual key event is
185 triggered when the key is released by the virtualKeyRelease() method. The
186 key press event can be discarded by calling virtualKeyCancel().
187
188 The key press also initiates the key repeat timer if \a repeat is \c true.
189
190 Returns \c true if the key was accepted by this input engine.
191
192 \sa virtualKeyCancel(), virtualKeyRelease()
193*/
194bool QVirtualKeyboardInputEngine::virtualKeyPress(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers, bool repeat)
195{
196 Q_D(QVirtualKeyboardInputEngine);
197 VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputEngine::virtualKeyPress()"
198#ifdef SENSITIVE_DEBUG
199 << key << text << modifiers << repeat
200#endif
201 ;
202
203 bool accept = false;
204 if (d->activeKey == Qt::Key_unknown || d->activeKey == key) {
205 d->activeKey = key;
206 d->activeKeyText = text;
207 d->activeKeyModifiers = modifiers;
208 if (repeat) {
209 d->repeatTimer = startTimer(interval: 600);
210 }
211 accept = true;
212 emit activeKeyChanged(key: d->activeKey);
213 } else {
214 qWarning(msg: "key press ignored; key is already active");
215 }
216 return accept;
217}
218
219/*!
220 \qmlmethod void InputEngine::virtualKeyCancel()
221
222 Reverts the active key state without emitting the key event.
223 This method is useful when the user discards the current key and
224 the key state needs to be restored.
225*/
226/*!
227 \fn void QVirtualKeyboardInputEngine::virtualKeyCancel()
228
229 Reverts the active key state without emitting the key event.
230 This method is useful when the user discards the current key and
231 the key state needs to be restored.
232*/
233void QVirtualKeyboardInputEngine::virtualKeyCancel()
234{
235 Q_D(QVirtualKeyboardInputEngine);
236 VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputEngine::virtualKeyCancel()";
237 if (d->activeKey != Qt::Key_unknown) {
238 d->activeKey = Qt::Key_unknown;
239 d->activeKeyText = QString();
240 d->activeKeyModifiers = Qt::KeyboardModifiers();
241 if (d->repeatTimer) {
242 killTimer(id: d->repeatTimer);
243 d->repeatTimer = 0;
244 d->repeatCount = 0;
245 }
246 emit activeKeyChanged(key: d->activeKey);
247 }
248}
249
250/*!
251 \qmlmethod bool InputEngine::virtualKeyRelease(int key, string text, int modifiers)
252
253 Releases the key at \a key. The method emits a key event for the input
254 method if the event has not been generated by a repeating timer.
255 The \a text and \a modifiers are passed to the input method.
256
257 Returns \c true if the key was accepted by the input engine.
258*/
259/*!
260 Releases the key at \a key. The method emits a key event for the input
261 method if the event has not been generated by a repeating timer.
262 The \a text and \a modifiers are passed to the input method.
263
264 Returns \c true if the key was accepted by the input engine.
265*/
266bool QVirtualKeyboardInputEngine::virtualKeyRelease(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers)
267{
268 Q_D(QVirtualKeyboardInputEngine);
269 VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputEngine::virtualKeyRelease()"
270#ifdef SENSITIVE_DEBUG
271 << key << text << modifiers
272#endif
273 ;
274
275 bool accept = false;
276 if (d->activeKey == key) {
277 if (!d->repeatCount) {
278 accept = d->virtualKeyClick(key, text, modifiers, isAutoRepeat: false);
279 } else {
280 accept = true;
281 }
282 } else {
283 qWarning(msg: "key release ignored; key is not pressed");
284 }
285 if (d->activeKey != Qt::Key_unknown) {
286 d->previousKey = d->activeKey;
287 emit previousKeyChanged(key: d->previousKey);
288 d->activeKey = Qt::Key_unknown;
289 d->activeKeyText = QString();
290 d->activeKeyModifiers = Qt::KeyboardModifiers();
291 if (d->repeatTimer) {
292 killTimer(id: d->repeatTimer);
293 d->repeatTimer = 0;
294 d->repeatCount = 0;
295 }
296 emit activeKeyChanged(key: d->activeKey);
297 }
298 return accept;
299}
300
301/*!
302 \qmlmethod bool InputEngine::virtualKeyClick(int key, string text, int modifiers)
303
304 Emits a key click event for the given \a key, \a text and \a modifiers.
305 Returns \c true if the key event was accepted by the input engine.
306*/
307/*!
308 Emits a key click event for the given \a key, \a text and \a modifiers.
309 Returns \c true if the key event was accepted by the input engine.
310*/
311bool QVirtualKeyboardInputEngine::virtualKeyClick(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers)
312{
313 Q_D(QVirtualKeyboardInputEngine);
314 VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputEngine::virtualKeyClick()"
315#ifdef SENSITIVE_DEBUG
316 << key << text << modifiers
317#endif
318 ;
319 return d->virtualKeyClick(key, text, modifiers, isAutoRepeat: false);
320}
321
322/*!
323 Returns the \c InputContext instance associated with the input
324 engine.
325*/
326QVirtualKeyboardInputContext *QVirtualKeyboardInputEngine::inputContext() const
327{
328 Q_D(const QVirtualKeyboardInputEngine);
329 return d->inputContext;
330}
331
332/*!
333 Returns the currently active key, or Qt::Key_unknown if no key is active.
334*/
335Qt::Key QVirtualKeyboardInputEngine::activeKey() const
336{
337 Q_D(const QVirtualKeyboardInputEngine);
338 return d->activeKey;
339}
340
341/*!
342 Returns the previously active key, or Qt::Key_unknown if no key has been
343 active.
344*/
345Qt::Key QVirtualKeyboardInputEngine::previousKey() const
346{
347 Q_D(const QVirtualKeyboardInputEngine);
348 return d->previousKey;
349}
350
351/*!
352 Returns the active input method.
353*/
354QVirtualKeyboardAbstractInputMethod *QVirtualKeyboardInputEngine::inputMethod() const
355{
356 Q_D(const QVirtualKeyboardInputEngine);
357 return d->inputMethod;
358}
359
360/*!
361 Sets \a inputMethod as the active input method.
362*/
363void QVirtualKeyboardInputEngine::setInputMethod(QVirtualKeyboardAbstractInputMethod *inputMethod)
364{
365 Q_D(QVirtualKeyboardInputEngine);
366 VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputEngine::setInputMethod():" << inputMethod;
367 if (d->inputMethod != inputMethod) {
368 update();
369 if (d->inputMethod) {
370 d->inputMethod->clearInputMode();
371 QObject::disconnect(sender: d->inputMethod.data(), signal: &QVirtualKeyboardAbstractInputMethod::selectionListsChanged, receiver: this, slot: &QVirtualKeyboardInputEngine::updateSelectionListModels);
372 d->inputMethod->setInputEngine(nullptr);
373 }
374 d->inputMethod = inputMethod;
375 if (d->inputMethod) {
376 d->inputMethod->setInputEngine(this);
377 QObject::connect(sender: d->inputMethod.data(), signal: &QVirtualKeyboardAbstractInputMethod::selectionListsChanged, context: this, slot: &QVirtualKeyboardInputEngine::updateSelectionListModels);
378
379 // Set current text case
380 d->inputMethod->setTextCase(d->textCase);
381 }
382 updateSelectionListModels();
383 emit inputMethodChanged();
384 emit patternRecognitionModesChanged();
385 }
386}
387
388/*!
389 Returns the list of available input modes.
390*/
391QList<int> QVirtualKeyboardInputEngine::inputModes() const
392{
393 Q_D(const QVirtualKeyboardInputEngine);
394 return d->inputModes;
395}
396
397QVirtualKeyboardInputEngine::InputMode QVirtualKeyboardInputEngine::inputMode() const
398{
399 Q_D(const QVirtualKeyboardInputEngine);
400 return d->inputMode;
401}
402
403void QVirtualKeyboardInputEngine::setInputMode(QVirtualKeyboardInputEngine::InputMode inputMode)
404{
405 Q_D(QVirtualKeyboardInputEngine);
406 VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputEngine::setInputMode():" << inputMode;
407 if (d->inputMethod) {
408#ifdef QT_DEBUG
409 // Cached input modes should be in sync with the input method
410 // If the assert below fails, we have missed an update somewhere
411 QList<int> cachedInputModes(d->inputModes);
412 updateInputModes();
413 Q_ASSERT(cachedInputModes == d->inputModes);
414#endif
415 if (d->inputModes.contains(t: static_cast<int>(inputMode))) {
416 d->inputMethod->setInputMode(locale: d->inputContext->locale(), inputMode);
417 if (d->inputMode != inputMode) {
418 d->inputMode = inputMode;
419 emit inputModeChanged();
420 }
421 } else {
422 qWarning() << "Input mode" << inputMode <<
423 "is not in the list of available input modes" << d->inputModes;
424 }
425 }
426}
427
428QVirtualKeyboardSelectionListModel *QVirtualKeyboardInputEngine::wordCandidateListModel() const
429{
430 Q_D(const QVirtualKeyboardInputEngine);
431 return d->selectionListModels[QVirtualKeyboardSelectionListModel::Type::WordCandidateList];
432}
433
434bool QVirtualKeyboardInputEngine::wordCandidateListVisibleHint() const
435{
436 Q_D(const QVirtualKeyboardInputEngine);
437 const auto it = d->selectionListModels.constFind(key: QVirtualKeyboardSelectionListModel::Type::WordCandidateList);
438 if (it == d->selectionListModels.cend())
439 return false;
440 return it.value()->dataSource() != nullptr;
441}
442
443/*!
444 Returns list of supported pattern recognition modes.
445*/
446QList<int> QVirtualKeyboardInputEngine::patternRecognitionModes() const
447{
448 Q_D(const QVirtualKeyboardInputEngine);
449 QList<PatternRecognitionMode> patterRecognitionModeList;
450 if (d->inputMethod)
451 patterRecognitionModeList = d->inputMethod->patternRecognitionModes();
452 QList<int> resultList;
453 if (patterRecognitionModeList.isEmpty())
454 return resultList;
455 resultList.reserve(asize: patterRecognitionModeList.size());
456 for (const PatternRecognitionMode &patternRecognitionMode : std::as_const(t&: patterRecognitionModeList))
457 resultList.append(t: static_cast<int>(patternRecognitionMode));
458 return resultList;
459}
460
461/*!
462 \qmlmethod Trace InputEngine::traceBegin(int traceId, int patternRecognitionMode, var traceCaptureDeviceInfo, var traceScreenInfo)
463 \since QtQuick.VirtualKeyboard 2.0
464
465 Starts a trace interaction with the input engine.
466
467 The trace is uniquely identified by the \a traceId. The input engine will assign
468 the id to the Trace object if the input method accepts the event.
469
470 The \a patternRecognitionMode specifies the recognition mode used for the pattern.
471
472 If the current input method accepts the event it returns a Trace object associated with this interaction.
473 If the input method discards the event, it returns a null value.
474
475 The \a traceCaptureDeviceInfo provides information about the source device and the \a traceScreenInfo
476 provides information about the screen context.
477
478 By definition, the Trace object remains valid until the traceEnd() method is called.
479
480 The trace interaction is ended by calling the \l {InputEngine::traceEnd()} {InputEngine.traceEnd()} method.
481*/
482/*!
483 \since QtQuick.VirtualKeyboard 2.0
484
485 Starts a trace interaction with the input engine.
486
487 The trace is uniquely identified by the \a traceId. The input engine will assign
488 the id to the QVirtualKeyboardTrace object if the input method accepts the event.
489
490 The \a patternRecognitionMode specifies the recognition mode used for the pattern.
491
492 If the current input method accepts the event it returns a QVirtualKeyboardTrace object associated with this interaction.
493 If the input method discards the event, it returns a NULL value.
494
495 The \a traceCaptureDeviceInfo provides information about the source device and the \a traceScreenInfo
496 provides information about the screen context.
497
498 By definition, the QVirtualKeyboardTrace object remains valid until the traceEnd() method is called.
499
500 The trace interaction is ended by calling the traceEnd() method.
501*/
502QVirtualKeyboardTrace *QVirtualKeyboardInputEngine::traceBegin(
503 int traceId, PatternRecognitionMode patternRecognitionMode,
504 const QVariantMap &traceCaptureDeviceInfo, const QVariantMap &traceScreenInfo)
505{
506 Q_D(QVirtualKeyboardInputEngine);
507 VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputEngine::traceBegin():"
508 << "traceId:" << traceId
509 << "patternRecognitionMode:" << patternRecognitionMode
510 << "traceCaptureDeviceInfo:" << traceCaptureDeviceInfo
511 << "traceScreenInfo:" << traceScreenInfo;
512 if (!d->inputMethod)
513 return nullptr;
514 if (patternRecognitionMode == PatternRecognitionMode::None)
515 return nullptr;
516 if (!d->inputMethod->patternRecognitionModes().contains(t: patternRecognitionMode))
517 return nullptr;
518 QVirtualKeyboardTrace *trace = d->inputMethod->traceBegin(traceId, patternRecognitionMode, traceCaptureDeviceInfo, traceScreenInfo);
519 if (trace) {
520 if (QQmlContext *context = QQmlEngine::contextForObject(this)) {
521 if (QQmlEngine *engine = context->engine()) {
522 engine->setObjectOwnership(trace, QQmlEngine::CppOwnership);
523 }
524 }
525 trace->setTraceId(traceId);
526 }
527 return trace;
528}
529
530/*!
531 \qmlmethod bool InputEngine::traceEnd(Trace trace)
532
533 Ends the trace interaction with the input engine.
534
535 The \a trace object may be discarded at any point after calling this function.
536
537 The function returns true if the trace interaction was accepted (i.e. the touch
538 events should not be used for anything else).
539*/
540/*!
541 Ends the trace interaction with the input engine.
542
543 The \a trace object may be discarded at any point after calling this function.
544
545 The function returns true if the trace interaction was accepted (i.e. the touch
546 events should not be used for anything else).
547*/
548bool QVirtualKeyboardInputEngine::traceEnd(QVirtualKeyboardTrace *trace)
549{
550 Q_D(QVirtualKeyboardInputEngine);
551 VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputEngine::traceEnd():" << trace;
552 Q_ASSERT(trace);
553 if (!d->inputMethod)
554 return false;
555 return d->inputMethod->traceEnd(trace);
556}
557
558/*!
559 \since QtQuick.VirtualKeyboard 2.0
560
561 This function attempts to reselect a word located at the \a cursorPosition.
562 The \a reselectFlags define the rules for how the word should be selected in
563 relation to the cursor position.
564
565 The function returns \c true if the word was successfully reselected.
566*/
567bool QVirtualKeyboardInputEngine::reselect(int cursorPosition, const ReselectFlags &reselectFlags)
568{
569 Q_D(QVirtualKeyboardInputEngine);
570 VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputEngine::reselect():" << cursorPosition << reselectFlags;
571 if (!d->inputMethod || !wordCandidateListVisibleHint())
572 return false;
573 return d->inputMethod->reselect(cursorPosition, reselectFlags);
574}
575
576/*!
577 \internal
578 This method is called when the current preedit text is clicked.
579*/
580bool QVirtualKeyboardInputEngine::clickPreeditText(int cursorPosition)
581{
582 Q_D(QVirtualKeyboardInputEngine);
583 if (!d->inputMethod)
584 return false;
585 return d->inputMethod->clickPreeditText(cursorPosition);
586}
587
588/*!
589 \internal
590 Resets the input method.
591*/
592void QVirtualKeyboardInputEngine::reset()
593{
594 Q_D(QVirtualKeyboardInputEngine);
595 if (d->inputMethod) {
596 RecursiveMethodGuard guard(d->recursiveMethodLock);
597 if (!guard.locked()) {
598 emit inputMethodReset();
599 updateInputModes();
600 }
601 } else {
602 updateInputModes();
603 }
604}
605
606/*!
607 \internal
608 Updates the input method's state. This method is called whenever the input
609 context is changed.
610*/
611void QVirtualKeyboardInputEngine::update()
612{
613 Q_D(QVirtualKeyboardInputEngine);
614 if (d->inputMethod) {
615 RecursiveMethodGuard guard(d->recursiveMethodLock);
616 if (!guard.locked()) {
617 emit inputMethodUpdate();
618 }
619 }
620}
621
622/*!
623 \internal
624 Updates the text case for the input method.
625*/
626void QVirtualKeyboardInputEngine::shiftChanged()
627{
628 Q_D(QVirtualKeyboardInputEngine);
629 TextCase newCase = d->inputContext->priv()->shiftHandler()->isShiftActive() ? TextCase::Upper : TextCase::Lower;
630 if (d->textCase != newCase) {
631 d->textCase = newCase;
632 if (d->inputMethod) {
633 d->inputMethod->setTextCase(d->textCase);
634 }
635 }
636}
637
638/*!
639 \internal
640*/
641void QVirtualKeyboardInputEngine::updateSelectionListModels()
642{
643 Q_D(QVirtualKeyboardInputEngine);
644 QList<QVirtualKeyboardSelectionListModel::Type> inactiveSelectionLists = d->selectionListModels.keys();
645 if (d->inputMethod) {
646 // Allocate selection lists for the input method
647 const QList<QVirtualKeyboardSelectionListModel::Type> activeSelectionLists = d->inputMethod->selectionLists();
648 for (const QVirtualKeyboardSelectionListModel::Type &selectionListType : activeSelectionLists) {
649 auto it = d->selectionListModels.find(key: selectionListType);
650 if (it == d->selectionListModels.end()) {
651 it = d->selectionListModels.insert(key: selectionListType, value: new QVirtualKeyboardSelectionListModel(this));
652 if (selectionListType == QVirtualKeyboardSelectionListModel::Type::WordCandidateList)
653 emit wordCandidateListModelChanged();
654 }
655 it.value()->setDataSource(dataSource: d->inputMethod, type: selectionListType);
656 if (selectionListType == QVirtualKeyboardSelectionListModel::Type::WordCandidateList)
657 emit wordCandidateListVisibleHintChanged();
658 inactiveSelectionLists.removeAll(t: selectionListType);
659 }
660 }
661
662 // Deallocate inactive selection lists
663 for (const QVirtualKeyboardSelectionListModel::Type &selectionListType : std::as_const(t&: inactiveSelectionLists)) {
664 const auto it = d->selectionListModels.constFind(key: selectionListType);
665 if (it != d->selectionListModels.cend()) {
666 it.value()->setDataSource(dataSource: nullptr, type: selectionListType);
667 if (selectionListType == QVirtualKeyboardSelectionListModel::Type::WordCandidateList)
668 emit wordCandidateListVisibleHintChanged();
669 }
670 }
671}
672
673/*!
674 \internal
675*/
676void QVirtualKeyboardInputEngine::updateInputModes()
677{
678 Q_D(QVirtualKeyboardInputEngine);
679 QList<int> newInputModes;
680 QList<InputMode> tmpList;
681 if (d->inputMethod) {
682 tmpList = d->inputMethod->inputModes(locale: d->inputContext->locale());
683 if (!tmpList.isEmpty()) {
684 std::transform(first: tmpList.constBegin(), last: tmpList.constEnd(),
685 result: std::back_inserter(x&: newInputModes),
686 unary_op: [tmpList] (InputMode inputMode) {
687 return static_cast<int>(inputMode);
688 });
689 }
690 }
691 if (d->inputModes != newInputModes) {
692 d->inputModes = newInputModes;
693 VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputEngine::inputModesChanged():" << tmpList;
694 emit inputModesChanged();
695 }
696}
697
698/*!
699 \internal
700*/
701void QVirtualKeyboardInputEngine::timerEvent(QTimerEvent *timerEvent)
702{
703 Q_D(QVirtualKeyboardInputEngine);
704 if (timerEvent->timerId() == d->repeatTimer) {
705 d->virtualKeyClick(key: d->activeKey, text: d->activeKeyText, modifiers: d->activeKeyModifiers, isAutoRepeat: true);
706 if (!d->repeatCount) {
707 killTimer(id: d->repeatTimer);
708 d->repeatTimer = startTimer(interval: 50);
709 }
710 d->repeatCount++;
711 }
712}
713
714/*!
715 \qmlproperty int InputEngine::activeKey
716
717 Currently pressed key.
718*/
719
720/*!
721 \property QVirtualKeyboardInputEngine::activeKey
722 \brief the active key.
723
724 Currently pressed key.
725*/
726
727/*!
728 \qmlproperty int InputEngine::previousKey
729
730 Previously pressed key.
731*/
732/*!
733 \property QVirtualKeyboardInputEngine::previousKey
734 \brief the previous active key.
735
736 Previously pressed key.
737*/
738
739/*!
740 \qmlproperty InputMethod InputEngine::inputMethod
741
742 Use this property to set the active input method, or to monitor when the
743 active input method changes.
744*/
745
746/*!
747 \property QVirtualKeyboardInputEngine::inputMethod
748 \brief the active input method.
749
750 Use this property to set active the input method, or to monitor when the
751 active input method changes.
752*/
753
754/*!
755 \qmlproperty list<int> InputEngine::inputModes
756
757 The list of available input modes is dependent on the input method and
758 locale. This property is updated when either of the dependencies change.
759*/
760
761/*!
762 \property QVirtualKeyboardInputEngine::inputModes
763 \brief the available input modes for active input method.
764
765 The list of available input modes is dependent on the input method and
766 locale. This property is updated when either of the dependencies changes.
767*/
768
769/*!
770 \qmlproperty int InputEngine::inputMode
771
772 Use this property to get or set the current input mode. The
773 InputEngine::inputModes property provides the list of valid input modes
774 for the current input method and locale.
775
776 The predefined input modes are:
777
778 \list
779 \li \c InputEngine.InputMode.Latin The default input mode for latin text.
780 \li \c InputEngine.InputMode.Numeric Only numeric input is allowed.
781 \li \c InputEngine.InputMode.Dialable Only dialable input is allowed.
782 \li \c InputEngine.InputMode.Pinyin Pinyin input mode for Chinese.
783 \li \c InputEngine.InputMode.Cangjie Cangjie input mode for Chinese.
784 \li \c InputEngine.InputMode.Zhuyin Zhuyin input mode for Chinese.
785 \li \c InputEngine.InputMode.Hangul Hangul input mode for Korean.
786 \li \c InputEngine.InputMode.Hiragana Hiragana input mode for Japanese.
787 \li \c InputEngine.InputMode.Katakana Katakana input mode for Japanese.
788 \li \c InputEngine.InputMode.FullwidthLatin Fullwidth latin input mode for East Asian languages.
789 \li \c InputEngine.InputMode.Greek Greek input mode.
790 \li \c InputEngine.InputMode.Cyrillic Cyrillic input mode.
791 \li \c InputEngine.InputMode.Arabic Arabic input mode.
792 \li \c InputEngine.InputMode.Hebrew Hebrew input mode.
793 \li \c InputEngine.InputMode.ChineseHandwriting Chinese handwriting.
794 \li \c InputEngine.InputMode.JapaneseHandwriting Japanese handwriting.
795 \li \c InputEngine.InputMode.KoreanHandwriting Korean handwriting.
796 \li \c InputEngine.InputMode.Thai Thai input mode.
797 \li \c InputEngine.InputMode.Stroke Stroke input mode for Chinese.
798 \li \c InputEngine.InputMode.Romaji Romaji input mode for Japanese.
799 \endlist
800*/
801
802/*!
803 \property QVirtualKeyboardInputEngine::inputMode
804 \brief the current input mode.
805
806 Use this property to get or set the current input mode. The
807 InputEngine::inputModes provides list of valid input modes
808 for current input method and locale.
809*/
810
811/*!
812 \qmlproperty SelectionListModel InputEngine::wordCandidateListModel
813
814 Use this property to access the list model for the word candidate
815 list.
816*/
817
818/*!
819 \property QVirtualKeyboardInputEngine::wordCandidateListModel
820 \brief list model for the word candidate list.
821
822 Use this property to access the list model for the word candidate
823 list.
824*/
825
826/*!
827 \qmlproperty bool InputEngine::wordCandidateListVisibleHint
828
829 Use this property to check if the word candidate list should be visible
830 in the UI.
831*/
832
833/*!
834 \property QVirtualKeyboardInputEngine::wordCandidateListVisibleHint
835 \brief visible hint for the word candidate list.
836
837 Use this property to check if the word candidate list should be visible
838 in the UI.
839*/
840
841/*!
842 \enum QVirtualKeyboardInputEngine::InputMode
843
844 This enum specifies the input mode for the input method.
845
846 \value Latin
847 The default input mode for latin text.
848 \value Numeric
849 Only numeric input is allowed.
850 \value Dialable
851 Only dialable input is allowed.
852 \value Pinyin
853 Pinyin input mode for Chinese.
854 \value Cangjie
855 Cangjie input mode for Chinese.
856 \value Zhuyin
857 Zhuyin input mode for Chinese.
858 \value Hangul
859 Hangul input mode for Korean.
860 \value Hiragana
861 Hiragana input mode for Japanese.
862 \value Katakana
863 Katakana input mode for Japanese.
864 \value FullwidthLatin
865 Fullwidth latin input mode for East Asian languages.
866 \value Greek
867 Greek input mode.
868 \value Cyrillic
869 Cyrillic input mode.
870 \value Arabic
871 Arabic input mode.
872 \value Hebrew
873 Hebrew input mode.
874 \value ChineseHandwriting
875 Chinese handwriting input mode.
876 \value JapaneseHandwriting
877 Japanese handwriting input mode.
878 \value KoreanHandwriting
879 Korean handwriting input mode.
880 \value Thai
881 Thai input mode.
882 \value Stroke
883 Stroke input mode for Chinese.
884 \value Romaji
885 Romaji input mode for Japanese.
886*/
887
888/*!
889 \enum QVirtualKeyboardInputEngine::TextCase
890
891 This enum specifies the text case for the input method.
892
893 \value Lower
894 Lower case text.
895 \value Upper
896 Upper case text.
897*/
898
899/*!
900 \enum QVirtualKeyboardInputEngine::PatternRecognitionMode
901
902 This enum specifies the input mode for the input method.
903
904 \value None
905 Pattern recognition is not available.
906 \value PatternRecognitionDisabled
907 \c obsolete Use PatternRecognitionMode::None
908 \value Handwriting
909 Pattern recognition mode for handwriting recognition.
910 \value HandwritingRecoginition
911 \c obsolete Use PatternRecognitionMode::Handwriting
912*/
913
914/*!
915 \enum QVirtualKeyboardInputEngine::ReselectFlag
916
917 This enum specifies the rules for word reselection.
918
919 \value WordBeforeCursor
920 Activate the word before the cursor. When this flag is used exclusively, the word must end exactly at the cursor.
921 \value WordAfterCursor
922 Activate the word after the cursor. When this flag is used exclusively, the word must start exactly at the cursor.
923 \value WordAtCursor
924 Activate the word at the cursor. This flag is a combination of the above flags with the exception that the word cannot start or stop at the cursor.
925*/
926
927/*!
928 \qmlsignal void InputEngine::virtualKeyClicked(int key, string text, int modifiers)
929
930 Indicates that the virtual \a key was clicked with the given \a text and
931 \a modifiers.
932 This signal is emitted after the input method has processed the key event.
933*/
934
935/*!
936 \fn void QVirtualKeyboardInputEngine::virtualKeyClicked(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers, bool isAutoRepeat)
937
938 Indicates that the virtual \a key was clicked with the given \a text and
939 \a modifiers. The \a isAutoRepeat indicates if the event is automatically
940 repeated while the key is being pressed.
941 This signal is emitted after the input method has processed the key event.
942*/
943
944/*!
945 \qmlproperty list<int> InputEngine::patternRecognitionModes
946 \since QtQuick.VirtualKeyboard 2.0
947
948 The list of available pattern recognition modes.
949
950 Possible values:
951
952 \value InputEngine.PatternRecognitionMode.None
953 Pattern recognition is not available.
954 \value InputEngine.PatternRecognitionMode.PatternRecognitionDisabled
955 \c obsolete - Use \c None instead.
956 \value InputEngine.PatternRecognitionMode.Handwriting
957 Pattern recognition mode for handwriting recognition.
958 \value InputEngine.PatternRecognitionMode.HandwritingRecoginition
959 \c obsolete - Use \c Handwriting instead.
960
961*/
962
963/*!
964 \property QVirtualKeyboardInputEngine::patternRecognitionModes
965 \since QtQuick.VirtualKeyboard 2.0
966 \brief the list of available pattern recognition modes.
967
968 The list of available pattern recognition modes.
969*/
970
971/*!
972 \qmlsignal void InputEngine::activeKeyChanged(int key)
973
974 Indicates that the active \a key has changed.
975*/
976
977/*!
978 \fn void QVirtualKeyboardInputEngine::activeKeyChanged(Qt::Key key)
979
980 Indicates that the active \a key has changed.
981*/
982
983/*!
984 \qmlsignal void InputEngine::previousKeyChanged(int key)
985
986 Indicates that the previous \a key has changed.
987*/
988
989/*!
990 \fn void QVirtualKeyboardInputEngine::previousKeyChanged(Qt::Key key)
991
992 Indicates that the previous \a key has changed.
993*/
994
995/*!
996 \qmlsignal void InputEngine::inputMethodChanged()
997
998 Indicates that the input method has changed.
999*/
1000
1001/*!
1002 \fn void QVirtualKeyboardInputEngine::inputMethodChanged()
1003
1004 Indicates that the input method has changed.
1005*/
1006
1007/*!
1008 \qmlsignal void InputEngine::inputMethodReset()
1009
1010 Emitted when the input method needs to be reset.
1011
1012 \note This signal is automatically connected to QVirtualKeyboardAbstractInputMethod::reset()
1013 and InputMethod::reset() when the input method is activated.
1014*/
1015
1016/*!
1017 \fn void QVirtualKeyboardInputEngine::inputMethodReset()
1018
1019 Emitted when the input method needs to be reset.
1020
1021 \note This signal is automatically connected to QVirtualKeyboardAbstractInputMethod::reset()
1022 and InputMethod::reset() when the input method is activated.
1023*/
1024
1025/*!
1026 \qmlsignal void InputEngine::inputMethodUpdate()
1027
1028 \note This signal is automatically connected to QVirtualKeyboardAbstractInputMethod::update()
1029 and InputMethod::update() when the input method is activated.
1030*/
1031
1032/*!
1033 \fn void QVirtualKeyboardInputEngine::inputMethodUpdate()
1034
1035 \note This signal is automatically connected to QVirtualKeyboardAbstractInputMethod::update()
1036 and InputMethod::update() when the input method is activated.
1037*/
1038
1039/*!
1040 \qmlsignal void InputEngine::inputModesChanged()
1041
1042 Indicates that the available input modes have changed.
1043*/
1044
1045/*!
1046 \fn void QVirtualKeyboardInputEngine::inputModesChanged()
1047
1048 Indicates that the available input modes have changed.
1049*/
1050
1051/*!
1052 \qmlsignal void InputEngine::inputModeChanged()
1053
1054 Indicates that the input mode has changed.
1055*/
1056
1057/*!
1058 \fn void QVirtualKeyboardInputEngine::inputModeChanged()
1059
1060 Indicates that the input mode has changed.
1061*/
1062
1063/*!
1064 \qmlsignal void InputEngine::patternRecognitionModesChanged()
1065 \since QtQuick.VirtualKeyboard 2.0
1066
1067 Indicates that the available pattern recognition modes have changed.
1068
1069 The predefined pattern recognition modes are:
1070
1071 \list
1072 \li \c InputEngine.PatternRecognitionMode.None Pattern recognition is not available.
1073 \li \c InputEngine.PatternRecognitionMode.PatternRecognitionDisabled \c obsolete Use InputEngine.PatternRecognitionMode.None
1074 \li \c InputEngine.PatternRecognitionMode.Handwriting Pattern recognition mode for handwriting recognition.
1075 \li \c InputEngine.PatternRecognitionMode.HandwritingRecoginition \c obsolete Use InputEngine.PatternRecognitionMode.Handwriting
1076 \endlist
1077*/
1078
1079/*!
1080 \fn void QVirtualKeyboardInputEngine::patternRecognitionModesChanged()
1081 \since QtQuick.VirtualKeyboard 2.0
1082
1083 Indicates that the available pattern recognition modes have changed.
1084*/
1085
1086QT_END_NAMESPACE
1087

source code of qtvirtualkeyboard/src/virtualkeyboard/qvirtualkeyboardinputengine.cpp