blob: fb65b29e8a43b88d14238141eb4e339ab1a646f7 [file] [log] [blame]
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtVirtualKeyboard/qvirtualkeyboardinputcontext.h>
#include <QtVirtualKeyboard/private/qvirtualkeyboardinputcontext_p.h>
#include <QtVirtualKeyboard/private/shifthandler_p.h>
#include <QtVirtualKeyboard/private/platforminputcontext_p.h>
#include <QtVirtualKeyboard/private/virtualkeyboarddebug_p.h>
#include <QTextFormat>
#include <QGuiApplication>
QT_BEGIN_NAMESPACE
using namespace QtVirtualKeyboard;
/*!
\qmltype InputContext
\instantiates QVirtualKeyboardInputContext
\inqmlmodule QtQuick.VirtualKeyboard
\ingroup qtvirtualkeyboard-qml
\brief Provides access to an input context.
The InputContext can be accessed as singleton instance.
*/
/*!
\class QVirtualKeyboardInputContext
\inmodule QtVirtualKeyboard
\brief Provides access to an input context.
*/
/*!
\internal
Constructs an input context with \a parent as the platform input
context.
*/
QVirtualKeyboardInputContext::QVirtualKeyboardInputContext(QObject *parent) :
QObject(parent),
d_ptr(new QVirtualKeyboardInputContextPrivate(this))
{
Q_D(QVirtualKeyboardInputContext);
d->init();
QObject::connect(d->_shiftHandler, &ShiftHandler::shiftActiveChanged, this, &QVirtualKeyboardInputContext::shiftActiveChanged);
QObject::connect(d->_shiftHandler, &ShiftHandler::capsLockActiveChanged, this, &QVirtualKeyboardInputContext::capsLockActiveChanged);
QObject::connect(d->_shiftHandler, &ShiftHandler::uppercaseChanged, this, &QVirtualKeyboardInputContext::uppercaseChanged);
QObject::connect(d, &QVirtualKeyboardInputContextPrivate::localeChanged, this, &QVirtualKeyboardInputContext::localeChanged);
QObject::connect(d, &QVirtualKeyboardInputContextPrivate::inputItemChanged, this, &QVirtualKeyboardInputContext::inputItemChanged);
}
/*!
\internal
Destroys the input context and frees all allocated resources.
*/
QVirtualKeyboardInputContext::~QVirtualKeyboardInputContext()
{
}
bool QVirtualKeyboardInputContext::isShiftActive() const
{
Q_D(const QVirtualKeyboardInputContext);
return d->_shiftHandler->isShiftActive();
}
bool QVirtualKeyboardInputContext::isCapsLockActive() const
{
Q_D(const QVirtualKeyboardInputContext);
return d->_shiftHandler->isCapsLockActive();
}
bool QVirtualKeyboardInputContext::isUppercase() const
{
Q_D(const QVirtualKeyboardInputContext);
return d->_shiftHandler->isUppercase();
}
int QVirtualKeyboardInputContext::anchorPosition() const
{
Q_D(const QVirtualKeyboardInputContext);
return d->anchorPosition;
}
int QVirtualKeyboardInputContext::cursorPosition() const
{
Q_D(const QVirtualKeyboardInputContext);
return d->cursorPosition;
}
Qt::InputMethodHints QVirtualKeyboardInputContext::inputMethodHints() const
{
Q_D(const QVirtualKeyboardInputContext);
return d->inputMethodHints;
}
QString QVirtualKeyboardInputContext::preeditText() const
{
Q_D(const QVirtualKeyboardInputContext);
return d->preeditText;
}
void QVirtualKeyboardInputContext::setPreeditText(const QString &text, QList<QInputMethodEvent::Attribute> attributes, int replaceFrom, int replaceLength)
{
Q_D(QVirtualKeyboardInputContext);
// Add default attributes
if (!text.isEmpty()) {
if (!d->testAttribute(attributes, QInputMethodEvent::TextFormat)) {
QTextCharFormat textFormat;
textFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline);
attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, text.length(), textFormat));
}
} else if (d->_forceCursorPosition != -1) {
d->addSelectionAttribute(attributes);
}
d->sendPreedit(text, attributes, replaceFrom, replaceLength);
}
QList<QInputMethodEvent::Attribute> QVirtualKeyboardInputContext::preeditTextAttributes() const
{
Q_D(const QVirtualKeyboardInputContext);
return d->preeditTextAttributes;
}
QString QVirtualKeyboardInputContext::surroundingText() const
{
Q_D(const QVirtualKeyboardInputContext);
return d->surroundingText;
}
QString QVirtualKeyboardInputContext::selectedText() const
{
Q_D(const QVirtualKeyboardInputContext);
return d->selectedText;
}
QRectF QVirtualKeyboardInputContext::anchorRectangle() const
{
Q_D(const QVirtualKeyboardInputContext);
return d->anchorRectangle;
}
QRectF QVirtualKeyboardInputContext::cursorRectangle() const
{
Q_D(const QVirtualKeyboardInputContext);
return d->cursorRectangle;
}
bool QVirtualKeyboardInputContext::isAnimating() const
{
Q_D(const QVirtualKeyboardInputContext);
return d->animating;
}
void QVirtualKeyboardInputContext::setAnimating(bool animating)
{
Q_D(QVirtualKeyboardInputContext);
if (d->animating != animating) {
VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputContext::setAnimating():" << animating;
d->animating = animating;
emit animatingChanged();
d->platformInputContext->emitAnimatingChanged();
}
}
QString QVirtualKeyboardInputContext::locale() const
{
Q_D(const QVirtualKeyboardInputContext);
return d->locale();
}
QObject *QVirtualKeyboardInputContext::inputItem() const
{
Q_D(const QVirtualKeyboardInputContext);
return d->inputItem();
}
QVirtualKeyboardInputEngine *QVirtualKeyboardInputContext::inputEngine() const
{
Q_D(const QVirtualKeyboardInputContext);
return d->inputEngine;
}
/*!
\qmlmethod void InputContext::sendKeyClick(int key, string text, int modifiers = 0)
Sends a key click event with the given \a key, \a text and \e modifiers to
the input item that currently has focus.
*/
/*!
Sends a key click event with the given \a key, \a text and \a modifiers to
the input item that currently has focus.
*/
void QVirtualKeyboardInputContext::sendKeyClick(int key, const QString &text, int modifiers)
{
Q_D(QVirtualKeyboardInputContext);
if ((d->_focus && d->platformInputContext) || QT_VIRTUALKEYBOARD_FORCE_EVENTS_WITHOUT_FOCUS) {
QKeyEvent pressEvent(QEvent::KeyPress, key, Qt::KeyboardModifiers(modifiers), text);
QKeyEvent releaseEvent(QEvent::KeyRelease, key, Qt::KeyboardModifiers(modifiers), text);
VIRTUALKEYBOARD_DEBUG().nospace() << "InputContext::sendKeyClick()"
#ifdef SENSITIVE_DEBUG
<< ": " << key
#endif
;
d->setState(QVirtualKeyboardInputContextPrivate::State::KeyEvent);
d->platformInputContext->sendKeyEvent(&pressEvent);
d->platformInputContext->sendKeyEvent(&releaseEvent);
if (d->activeKeys.isEmpty())
d->clearState(QVirtualKeyboardInputContextPrivate::State::KeyEvent);
} else {
VIRTUALKEYBOARD_WARN() << "InputContext::sendKeyClick(): no focus to send key click"
#ifdef SENSITIVE_DEBUG
<< key << text
#endif
<< "- QGuiApplication::focusWindow() is:" << QGuiApplication::focusWindow();
}
}
/*!
\qmlmethod void InputContext::commit()
Commits the current pre-edit text.
*/
/*!
\fn void QVirtualKeyboardInputContext::commit()
Commits the current pre-edit text.
*/
void QVirtualKeyboardInputContext::commit()
{
Q_D(QVirtualKeyboardInputContext);
QString text = d->preeditText;
commit(text);
}
/*!
\qmlmethod void InputContext::commit(string text, int replaceFrom = 0, int replaceLength = 0)
Commits the final \a text to the input item and optionally
modifies the text relative to the start of the pre-edit text.
If \e replaceFrom is non-zero, the \a text replaces the
contents relative to \e replaceFrom with a length of
\e replaceLength.
*/
/*!
Commits the final \a text to the input item and optionally
modifies the text relative to the start of the pre-edit text.
If \a replaceFrom is non-zero, the \a text replaces the
contents relative to \a replaceFrom with a length of
\a replaceLength.
*/
void QVirtualKeyboardInputContext::commit(const QString &text, int replaceFrom, int replaceLength)
{
Q_D(QVirtualKeyboardInputContext);
VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputContext::commit()"
#ifdef SENSITIVE_DEBUG
<< text << replaceFrom << replaceLength
#endif
;
bool preeditChanged = !d->preeditText.isEmpty();
if (d->platformInputContext) {
QList<QInputMethodEvent::Attribute> attributes;
d->addSelectionAttribute(attributes);
d->preeditText.clear();
d->preeditTextAttributes.clear();
QInputMethodEvent inputEvent(QString(), attributes);
inputEvent.setCommitString(text, replaceFrom, replaceLength);
d->sendInputMethodEvent(&inputEvent);
} else {
d->preeditText.clear();
d->preeditTextAttributes.clear();
}
if (preeditChanged)
emit preeditTextChanged();
}
/*!
\qmlmethod void InputContext::clear()
Clears the pre-edit text.
*/
/*!
\fn void QVirtualKeyboardInputContext::clear()
Clears the pre-edit text.
*/
void QVirtualKeyboardInputContext::clear()
{
Q_D(QVirtualKeyboardInputContext);
bool preeditChanged = !d->preeditText.isEmpty();
d->preeditText.clear();
d->preeditTextAttributes.clear();
if (d->platformInputContext) {
QList<QInputMethodEvent::Attribute> attributes;
d->addSelectionAttribute(attributes);
QInputMethodEvent event(QString(), attributes);
d->sendInputMethodEvent(&event);
}
if (preeditChanged)
emit preeditTextChanged();
}
/*!
\internal
*/
void QVirtualKeyboardInputContext::setSelectionOnFocusObject(const QPointF &anchorPos, const QPointF &cursorPos)
{
QPlatformInputContext::setSelectionOnFocusObject(anchorPos, cursorPos);
}
/*!
\property QVirtualKeyboardInputContext::anchorRectIntersectsClipRect
\brief Holds \c true if the bounding rectangle of the selection anchor
intersects the exposed input item rectangle.
\sa Qt::ImAnchorRectangle, Qt::ImInputItemClipRectangle
*/
/*!
\qmlproperty bool InputContext::anchorRectIntersectsClipRect
\readonly
\brief Holds \c true if the bounding rectangle of the selection anchor
intersects the exposed input item rectangle.
\sa Qt::ImAnchorRectangle, Qt::ImInputItemClipRectangle
*/
bool QVirtualKeyboardInputContext::anchorRectIntersectsClipRect() const
{
Q_D(const QVirtualKeyboardInputContext);
return d->anchorRectIntersectsClipRect;
}
/*!
\property QVirtualKeyboardInputContext::cursorRectIntersectsClipRect
\brief Holds \c true if the bounding rectangle of the input cursor
intersects the exposed input item rectangle.
\sa Qt::ImCursorRectangle, Qt::ImInputItemClipRectangle
*/
/*!
\qmlproperty bool InputContext::cursorRectIntersectsClipRect
\readonly
\brief Holds \c true if the bounding rectangle of the input cursor
intersects the exposed input item rectangle.
\sa Qt::ImCursorRectangle, Qt::ImInputItemClipRectangle
*/
bool QVirtualKeyboardInputContext::cursorRectIntersectsClipRect() const
{
Q_D(const QVirtualKeyboardInputContext);
return d->cursorRectIntersectsClipRect;
}
/*!
\property QVirtualKeyboardInputContext::selectionControlVisible
\brief Holds \c true if the selection control is currently visible.
*/
/*!
\qmlproperty bool InputContext::selectionControlVisible
\readonly
\brief Holds \c true if the selection control is currently visible.
*/
bool QVirtualKeyboardInputContext::isSelectionControlVisible() const
{
Q_D(const QVirtualKeyboardInputContext);
return d->selectionControlVisible;
}
/*!
\internal
*/
QVirtualKeyboardInputContextPrivate *QVirtualKeyboardInputContext::priv() const
{
Q_D(const QVirtualKeyboardInputContext);
return const_cast<QVirtualKeyboardInputContextPrivate *>(d);
}
/*!
\qmlproperty bool InputContext::shift
\deprecated
Use \l shiftActive instead.
This property is changed when the shift status changes.
*/
/*!
\property QVirtualKeyboardInputContext::shift
\brief the shift status.
\deprecated
Use \l shiftActive instead.
This property is changed when the shift status changes.
*/
/*!
\qmlproperty bool InputContext::shiftActive
\since QtQuick.VirtualKeyboard 2.4
This property is changed when the shift status changes.
*/
/*!
\property QVirtualKeyboardInputContext::shiftActive
\brief the shift status.
This property is changed when the shift status changes.
*/
/*!
\qmlproperty bool InputContext::capsLock
\deprecated
Use \l capsLockActive instead.
This property is changed when the caps lock status changes.
*/
/*!
\property QVirtualKeyboardInputContext::capsLock
\brief the caps lock status.
\deprecated
Use \l capsLockActive instead.
This property is changed when the caps lock status changes.
*/
/*!
\qmlproperty bool InputContext::capsLockActive
\since QtQuick.VirtualKeyboard 2.4
This property is changed when the caps lock status changes.
*/
/*!
\property QVirtualKeyboardInputContext::capsLockActive
\brief the caps lock status.
This property is changed when the caps lock status changes.
*/
/*!
\qmlproperty bool InputContext::uppercase
\since QtQuick.VirtualKeyboard 2.2
This property is \c true when either \l shiftActive or \l capsLockActive is \c true.
*/
/*!
\property QVirtualKeyboardInputContext::uppercase
\brief the uppercase status.
This property is \c true when either \l shiftActive or \l capsLockActive is \c true.
*/
/*!
\qmlproperty int InputContext::anchorPosition
\since QtQuick.VirtualKeyboard 2.2
This property is changed when the anchor position changes.
*/
/*!
\property QVirtualKeyboardInputContext::anchorPosition
\brief the anchor position.
This property is changed when the anchor position changes.
*/
/*!
\qmlproperty int InputContext::cursorPosition
This property is changed when the cursor position changes.
*/
/*!
\property QVirtualKeyboardInputContext::cursorPosition
\brief the cursor position.
This property is changed when the cursor position changes.
*/
/*!
\qmlproperty int InputContext::inputMethodHints
This property is changed when the input method hints changes.
*/
/*!
\property QVirtualKeyboardInputContext::inputMethodHints
\brief the input method hints.
This property is changed when the input method hints changes.
*/
/*!
\qmlproperty string InputContext::preeditText
This property sets the pre-edit text.
*/
/*!
\property QVirtualKeyboardInputContext::preeditText
\brief the pre-edit text.
This property sets the pre-edit text.
*/
/*!
\qmlproperty string InputContext::surroundingText
This property is changed when the surrounding text around the cursor changes.
*/
/*!
\property QVirtualKeyboardInputContext::surroundingText
\brief the surrounding text around cursor.
This property is changed when the surrounding text around the cursor changes.
*/
/*!
\qmlproperty string InputContext::selectedText
This property is changed when the selected text changes.
*/
/*!
\property QVirtualKeyboardInputContext::selectedText
\brief the selected text.
This property is changed when the selected text changes.
*/
/*!
\qmlproperty rect InputContext::anchorRectangle
\since QtQuick.VirtualKeyboard 2.1
This property is changed when the anchor rectangle changes.
*/
/*!
\property QVirtualKeyboardInputContext::anchorRectangle
\brief the anchor rectangle.
This property is changed when the anchor rectangle changes.
*/
/*!
\qmlproperty rect InputContext::cursorRectangle
This property is changed when the cursor rectangle changes.
*/
/*!
\property QVirtualKeyboardInputContext::cursorRectangle
\brief the cursor rectangle.
This property is changed when the cursor rectangle changes.
*/
/*!
\qmlproperty bool InputContext::animating
Use this property to set the animating status, for example
during UI transitioning states.
*/
/*!
\property QVirtualKeyboardInputContext::animating
\brief the animating status.
Use this property to set the animating status, for example
during UI transitioning states.
*/
/*!
\qmlproperty string InputContext::locale
This property is changed when the input locale changes.
*/
/*!
\property QVirtualKeyboardInputContext::locale
\brief the locale.
This property is changed when the input locale changes.
*/
/*!
\qmlproperty QtObject InputContext::inputItem
\deprecated
This property is changed when the focused input item changes.
*/
/*!
\property QVirtualKeyboardInputContext::inputItem
\brief the focused input item.
\deprecated
This property is changed when the focused input item changes.
*/
/*!
\qmlproperty InputEngine InputContext::inputEngine
This property stores the input engine.
*/
/*!
\property QVirtualKeyboardInputContext::inputEngine
\brief the input engine.
This property stores the input engine.
*/
/*!
\property QVirtualKeyboardInputContext::priv
\internal
*/
QT_END_NAMESPACE