aboutsummaryrefslogtreecommitdiffstats
path: root/src/virtualkeyboard
diff options
context:
space:
mode:
Diffstat (limited to 'src/virtualkeyboard')
-rw-r--r--src/virtualkeyboard/3rdparty/hunspell/hunspell.pro2
-rw-r--r--src/virtualkeyboard/3rdparty/lipi-toolkit/lipi-toolkit.pro3
-rw-r--r--src/virtualkeyboard/3rdparty/lipi-toolkit/projects/alphanumeric/alphanumeric.pro7
-rw-r--r--src/virtualkeyboard/3rdparty/lipi-toolkit/projects/demonumerals/demonumerals.pro7
-rw-r--r--src/virtualkeyboard/3rdparty/lipi-toolkit/projects/lipiengine.pro7
-rw-r--r--src/virtualkeyboard/3rdparty/lipi-toolkit/projects/projects.pro8
-rw-r--r--src/virtualkeyboard/3rdparty/lipi-toolkit/src/lipicommon.pri3
-rw-r--r--src/virtualkeyboard/3rdparty/t9write/t9write.pro1
-rw-r--r--src/virtualkeyboard/content/InputPanel.qml3
-rw-r--r--src/virtualkeyboard/content/components/AlternativeKeys.qml5
-rw-r--r--src/virtualkeyboard/content/components/BaseKey.qml3
-rw-r--r--src/virtualkeyboard/content/components/CharacterPreviewBubble.qml3
-rw-r--r--src/virtualkeyboard/content/components/Keyboard.qml65
-rw-r--r--src/virtualkeyboard/content/components/SelectionControl.qml27
-rw-r--r--src/virtualkeyboard/content/components/ShadowInputControl.qml138
-rw-r--r--src/virtualkeyboard/content/components/ShiftKey.qml4
-rw-r--r--src/virtualkeyboard/content/components/WordCandidatePopupList.qml6
-rw-r--r--src/virtualkeyboard/content/content.qrc1
-rw-r--r--src/virtualkeyboard/content/styles/default/style.qml20
-rw-r--r--src/virtualkeyboard/content/styles/retro/style.qml24
-rw-r--r--src/virtualkeyboard/doc/src/qtvirtualkeyboard-index.qdoc6
-rw-r--r--src/virtualkeyboard/inputcontext.cpp154
-rw-r--r--src/virtualkeyboard/inputcontext.h12
-rw-r--r--src/virtualkeyboard/platforminputcontext.cpp4
-rw-r--r--src/virtualkeyboard/plugin.cpp4
-rw-r--r--src/virtualkeyboard/settings.cpp19
-rw-r--r--src/virtualkeyboard/settings.h4
-rw-r--r--src/virtualkeyboard/shadowinputcontext.cpp253
-rw-r--r--src/virtualkeyboard/shadowinputcontext.h90
-rw-r--r--src/virtualkeyboard/shifthandler.cpp17
-rw-r--r--src/virtualkeyboard/shifthandler.h1
-rw-r--r--src/virtualkeyboard/styles/KeyPanel.qml2
-rw-r--r--src/virtualkeyboard/styles/KeyboardStyle.qml104
-rw-r--r--src/virtualkeyboard/styles/styles_plugin.cpp5
-rw-r--r--src/virtualkeyboard/tcinputmethod.cpp2
-rw-r--r--src/virtualkeyboard/virtualkeyboard.pro13
-rw-r--r--src/virtualkeyboard/virtualkeyboardsettings.cpp33
-rw-r--r--src/virtualkeyboard/virtualkeyboardsettings.h5
38 files changed, 962 insertions, 103 deletions
diff --git a/src/virtualkeyboard/3rdparty/hunspell/hunspell.pro b/src/virtualkeyboard/3rdparty/hunspell/hunspell.pro
index 7df90098..bd5eccb3 100644
--- a/src/virtualkeyboard/3rdparty/hunspell/hunspell.pro
+++ b/src/virtualkeyboard/3rdparty/hunspell/hunspell.pro
@@ -16,7 +16,6 @@ SOURCES += \
src/hunspell/affentry.cxx \
src/hunspell/affixmgr.cxx \
src/hunspell/csutil.cxx \
- src/hunspell/dictmgr.cxx \
src/hunspell/filemgr.cxx \
src/hunspell/hashmgr.cxx \
src/hunspell/hunspell.cxx \
@@ -32,7 +31,6 @@ HEADERS += \
src/hunspell/atypes.hxx \
src/hunspell/baseaffix.hxx \
src/hunspell/csutil.hxx \
- src/hunspell/dictmgr.hxx \
src/hunspell/filemgr.hxx \
src/hunspell/hashmgr.hxx \
src/hunspell/htypes.hxx \
diff --git a/src/virtualkeyboard/3rdparty/lipi-toolkit/lipi-toolkit.pro b/src/virtualkeyboard/3rdparty/lipi-toolkit/lipi-toolkit.pro
index bd678b99..9593051a 100644
--- a/src/virtualkeyboard/3rdparty/lipi-toolkit/lipi-toolkit.pro
+++ b/src/virtualkeyboard/3rdparty/lipi-toolkit/lipi-toolkit.pro
@@ -1,5 +1,4 @@
TEMPLATE = subdirs
SUBDIRS += \
- src \
- projects
+ src
diff --git a/src/virtualkeyboard/3rdparty/lipi-toolkit/projects/alphanumeric/alphanumeric.pro b/src/virtualkeyboard/3rdparty/lipi-toolkit/projects/alphanumeric/alphanumeric.pro
deleted file mode 100644
index d65137db..00000000
--- a/src/virtualkeyboard/3rdparty/lipi-toolkit/projects/alphanumeric/alphanumeric.pro
+++ /dev/null
@@ -1,7 +0,0 @@
-TEMPLATE = aux
-
-cfg.files = config
-cfg.path = $$[QT_INSTALL_DATA]/qtvirtualkeyboard/lipi_toolkit/projects/alphanumeric
-INSTALLS += cfg
-
-!prefix_build: COPIES += cfg
diff --git a/src/virtualkeyboard/3rdparty/lipi-toolkit/projects/demonumerals/demonumerals.pro b/src/virtualkeyboard/3rdparty/lipi-toolkit/projects/demonumerals/demonumerals.pro
deleted file mode 100644
index a16edd28..00000000
--- a/src/virtualkeyboard/3rdparty/lipi-toolkit/projects/demonumerals/demonumerals.pro
+++ /dev/null
@@ -1,7 +0,0 @@
-TEMPLATE = aux
-
-cfg.files = config
-cfg.path = $$[QT_INSTALL_DATA]/qtvirtualkeyboard/lipi_toolkit/projects/demonumerals
-INSTALLS += cfg
-
-!prefix_build: COPIES += cfg
diff --git a/src/virtualkeyboard/3rdparty/lipi-toolkit/projects/lipiengine.pro b/src/virtualkeyboard/3rdparty/lipi-toolkit/projects/lipiengine.pro
deleted file mode 100644
index f9ad55a7..00000000
--- a/src/virtualkeyboard/3rdparty/lipi-toolkit/projects/lipiengine.pro
+++ /dev/null
@@ -1,7 +0,0 @@
-TEMPLATE = aux
-
-cfg.files += lipiengine.cfg
-cfg.path = $$[QT_INSTALL_DATA]/qtvirtualkeyboard/lipi_toolkit/projects
-INSTALLS += cfg
-
-!prefix_build: COPIES += cfg
diff --git a/src/virtualkeyboard/3rdparty/lipi-toolkit/projects/projects.pro b/src/virtualkeyboard/3rdparty/lipi-toolkit/projects/projects.pro
deleted file mode 100644
index 7109dc45..00000000
--- a/src/virtualkeyboard/3rdparty/lipi-toolkit/projects/projects.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-TEMPLATE = subdirs
-
-SUBDIRS += \
- alphanumeric \
- demonumerals \
- lipiengine
-
-lipiengine.file = lipiengine.pro
diff --git a/src/virtualkeyboard/3rdparty/lipi-toolkit/src/lipicommon.pri b/src/virtualkeyboard/3rdparty/lipi-toolkit/src/lipicommon.pri
index df20b654..a1b770bb 100644
--- a/src/virtualkeyboard/3rdparty/lipi-toolkit/src/lipicommon.pri
+++ b/src/virtualkeyboard/3rdparty/lipi-toolkit/src/lipicommon.pri
@@ -4,6 +4,9 @@ CONFIG -= qt
CONFIG += exceptions
CONFIG += warn_off
+contains(QT_CONFIG, debug_and_release): CONFIG += debug_and_release
+contains(QT_CONFIG, build_all): CONFIG += build_all
+
INCLUDEPATH += $$PWD/include
load(qt_build_paths)
diff --git a/src/virtualkeyboard/3rdparty/t9write/t9write.pro b/src/virtualkeyboard/3rdparty/t9write/t9write.pro
index 8d6b4b91..05f723a7 100644
--- a/src/virtualkeyboard/3rdparty/t9write/t9write.pro
+++ b/src/virtualkeyboard/3rdparty/t9write/t9write.pro
@@ -19,3 +19,4 @@ load(qt_helper_lib)
# Needed for resources
CONFIG += qt
+QT = core
diff --git a/src/virtualkeyboard/content/InputPanel.qml b/src/virtualkeyboard/content/InputPanel.qml
index d2792fa9..f9d25a02 100644
--- a/src/virtualkeyboard/content/InputPanel.qml
+++ b/src/virtualkeyboard/content/InputPanel.qml
@@ -65,8 +65,10 @@ Item {
property alias keyboard: keyboard
SelectionControl {
+ objectName: "selectionControl"
x: -parent.x
y: -parent.y
+ enabled: active && !keyboard.fullScreenMode
}
implicitHeight: keyboard.height
@@ -79,5 +81,6 @@ Item {
MouseArea {
z: -1
anchors.fill: keyboard
+ enabled: active
}
}
diff --git a/src/virtualkeyboard/content/components/AlternativeKeys.qml b/src/virtualkeyboard/content/components/AlternativeKeys.qml
index 8801099c..a1fcfe14 100644
--- a/src/virtualkeyboard/content/components/AlternativeKeys.qml
+++ b/src/virtualkeyboard/content/components/AlternativeKeys.qml
@@ -36,7 +36,6 @@ Item {
property alias listView: listView
property int keyCode
property point origin
- property bool uppercased: keyboard.uppercased
signal clicked
z: 1
@@ -86,7 +85,7 @@ Item {
if (active && listView.currentIndex >= 0 && listView.currentIndex < listView.model.count) {
var activeKey = listView.model.get(listView.currentIndex)
InputContext.inputEngine.virtualKeyClick(keyCode, activeKey.text,
- uppercased ? Qt.ShiftModifier : 0)
+ InputContext.uppercase ? Qt.ShiftModifier : 0)
}
}
@@ -95,7 +94,7 @@ Item {
var alternativeKeys = key.effectiveAlternativeKeys
if (alternativeKeys.length > 0) {
for (var i = 0; i < alternativeKeys.length; i++) {
- listModel.append({ "text": uppercased ? alternativeKeys[i].toUpperCase() : alternativeKeys[i] })
+ listModel.append({ "text": InputContext.uppercase ? alternativeKeys[i].toUpperCase() : alternativeKeys[i] })
}
listView.width = keyboard.style.alternateKeysListItemWidth * listModel.count
listView.forceLayout()
diff --git a/src/virtualkeyboard/content/components/BaseKey.qml b/src/virtualkeyboard/content/components/BaseKey.qml
index 07989e01..5c686adf 100644
--- a/src/virtualkeyboard/content/components/BaseKey.qml
+++ b/src/virtualkeyboard/content/components/BaseKey.qml
@@ -29,6 +29,7 @@
import QtQuick 2.0
import QtQuick.Layouts 1.0
+import QtQuick.VirtualKeyboard 2.1
/*!
\qmltype BaseKey
@@ -203,7 +204,7 @@ Item {
By default, this property reflects the uppercase status of the keyboard.
*/
- property bool uppercased: keyboard.uppercased && !noModifier
+ property bool uppercased: InputContext.uppercase && !noModifier
/*! Sets the key panel delegate for the key.
diff --git a/src/virtualkeyboard/content/components/CharacterPreviewBubble.qml b/src/virtualkeyboard/content/components/CharacterPreviewBubble.qml
index 3a7490aa..1f9a05a2 100644
--- a/src/virtualkeyboard/content/components/CharacterPreviewBubble.qml
+++ b/src/virtualkeyboard/content/components/CharacterPreviewBubble.qml
@@ -28,6 +28,7 @@
****************************************************************************/
import QtQuick 2.0
+import QtQuick.VirtualKeyboard 2.1
Item {
property bool active
@@ -44,7 +45,7 @@ Item {
onActiveKeyChanged: {
if (activeKey && characterPreview.item !== null) {
- characterPreview.item.text = keyboard.uppercased ? activeKey.text.toUpperCase() : activeKey.text
+ characterPreview.item.text = InputContext.uppercase ? activeKey.text.toUpperCase() : activeKey.text
width = activeKey.width
height = activeKey.height
var position = keyboard.mapFromItem(activeKey, 0, 0)
diff --git a/src/virtualkeyboard/content/components/Keyboard.qml b/src/virtualkeyboard/content/components/Keyboard.qml
index 27d66d2a..2bd2ff2e 100644
--- a/src/virtualkeyboard/content/components/Keyboard.qml
+++ b/src/virtualkeyboard/content/components/Keyboard.qml
@@ -29,7 +29,8 @@
import QtQuick 2.0
import QtQuick.Layouts 1.0
-import QtQuick.VirtualKeyboard 2.1
+import QtQuick.Window 2.2
+import QtQuick.VirtualKeyboard 2.2
import QtQuick.VirtualKeyboard.Styles 2.1
import QtQuick.VirtualKeyboard.Settings 2.2
import Qt.labs.folderlistmodel 2.0
@@ -59,10 +60,10 @@ Item {
return "main"
}
property bool active: Qt.inputMethod.visible
- property bool uppercased: InputContext.shift
property bool handwritingMode
property bool fullScreenHandwritingMode
property bool symbolMode
+ property bool fullScreenMode: VirtualKeyboardSettings.fullScreenMode
property var defaultInputMethod: initDefaultInputMethod()
property var plainInputMethod: PlainInputMethod {}
property var customInputMethod: null
@@ -105,6 +106,10 @@ Item {
if (!isValidLocale(localeIndex) || VirtualKeyboardSettings.locale)
localeIndex = defaultLocaleIndex
}
+ onFullScreenModeChanged: {
+ wordCandidateView.disableAnimation = VirtualKeyboardSettings.fullScreenMode
+ keyboard.fullScreenMode = VirtualKeyboardSettings.fullScreenMode
+ }
}
onAvailableLocaleIndicesChanged: hideLanguagePopup()
onAvailableCustomLocaleIndicesChanged: hideLanguagePopup()
@@ -466,7 +471,10 @@ Item {
Binding {
target: InputContext
property: "keyboardRectangle"
- value: Qt.rect(keyboard.x, keyboard.y + wordCandidateView.currentYOffset, keyboard.width, keyboard.height - wordCandidateView.currentYOffset)
+ value: Qt.rect(keyboard.x,
+ keyboard.y + wordCandidateView.currentYOffset - (shadowInputControl.visible ? shadowInputControl.height : 0),
+ keyboard.width,
+ keyboard.height - wordCandidateView.currentYOffset + (shadowInputControl.visible ? shadowInputControl.height : 0))
when: keyboard.active && !InputContext.animating
}
Binding {
@@ -541,15 +549,58 @@ Item {
}
}
+ ShadowInputControl {
+ id: shadowInputControl
+ objectName: "shadowInputControl"
+ z: -3
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.bottom: wordCandidateView.top
+ height: (keyboard.parent.parent ? keyboard.parent.parent.height : Screen.height) -
+ keyboard.height - (wordCandidateView.visibleCondition ? wordCandidateView.height : 0)
+ visible: fullScreenMode && (shadowInputControlVisibleTimer.running || InputContext.animating)
+
+ Connections {
+ target: keyboard
+ onActiveChanged: {
+ if (keyboard.active)
+ shadowInputControlVisibleTimer.start()
+ else
+ shadowInputControlVisibleTimer.stop()
+ }
+ }
+
+ Timer {
+ id: shadowInputControlVisibleTimer
+ interval: 2147483647
+ repeat: true
+ }
+
+ MouseArea {
+ onPressed: keyboard.hideLanguagePopup()
+ anchors.fill: parent
+ enabled: languagePopupList.enabled
+ }
+ }
+
+ SelectionControl {
+ objectName: "fullScreenModeSelectionControl"
+ inputContext: InputContext.shadow
+ anchors.top: shadowInputControl.top
+ anchors.left: shadowInputControl.left
+ enabled: keyboard.enabled && fullScreenMode
+ }
+
ListView {
id: wordCandidateView
objectName: "wordCandidateView"
clip: true
z: -2
+ property bool disableAnimation: VirtualKeyboardSettings.fullScreenMode
property bool empty: true
- readonly property bool visibleCondition: (((!wordCandidateView.empty || wordCandidateViewAutoHideTimer.running) &&
+ readonly property bool visibleCondition: (((!wordCandidateView.empty || wordCandidateViewAutoHideTimer.running || shadowInputControl.visible) &&
InputContext.inputEngine.wordCandidateListVisibleHint) || VirtualKeyboardSettings.wordCandidateList.alwaysVisible) &&
- keyboard.active
+ (keyboard.active || shadowInputControl.visible)
readonly property real visibleYOffset: VirtualKeyboardSettings.wordCandidateList.alwaysVisible ? 0 : -height
readonly property real currentYOffset: visibleCondition || wordCandidateViewTransition.running ? visibleYOffset : 0
height: Math.round(style.selectionListHeight)
@@ -610,7 +661,7 @@ Item {
transitions: Transition {
id: wordCandidateViewTransition
to: "visible"
- enabled: !InputContext.animating && !VirtualKeyboardSettings.wordCandidateList.alwaysVisible
+ enabled: !InputContext.animating && !VirtualKeyboardSettings.wordCandidateList.alwaysVisible && !wordCandidateView.disableAnimation
reversible: true
ParallelAnimation {
NumberAnimation {
@@ -748,7 +799,7 @@ Item {
function click(key) {
if (key && key.enabled) {
if (!key.noKeyEvent)
- InputContext.inputEngine.virtualKeyClick(key.key, keyboard.uppercased ? key.text.toUpperCase() : key.text, keyboard.uppercased ? Qt.ShiftModifier : 0)
+ InputContext.inputEngine.virtualKeyClick(key.key, InputContext.uppercase ? key.text.toUpperCase() : key.text, InputContext.uppercase ? Qt.ShiftModifier : 0)
key.clicked()
}
}
diff --git a/src/virtualkeyboard/content/components/SelectionControl.qml b/src/virtualkeyboard/content/components/SelectionControl.qml
index a24c1116..125a8eb7 100644
--- a/src/virtualkeyboard/content/components/SelectionControl.qml
+++ b/src/virtualkeyboard/content/components/SelectionControl.qml
@@ -33,18 +33,19 @@ import QtQuick.VirtualKeyboard 2.1
Item {
id: root
property bool handleIsMoving: false
- visible: InputContext.selectionControlVisible || handleIsMoving
+ property var inputContext: InputContext
+ visible: enabled && (inputContext.selectionControlVisible || handleIsMoving) && !InputContext.animating
Loader {
id: anchorHandle
sourceComponent: keyboard.style.selectionHandle
- x: visible ? Qt.inputMethod.anchorRectangle.x - width/2 : 0
- y: visible ? Qt.inputMethod.anchorRectangle.y + Qt.inputMethod.anchorRectangle.height : 0
+ x: visible ? inputContext.anchorRectangle.x - width/2 : 0
+ y: visible ? inputContext.anchorRectangle.y + inputContext.anchorRectangle.height : 0
Behavior on opacity {
NumberAnimation { duration: 200 }
}
- opacity: InputContext.anchorRectIntersectsClipRect ? 1.0 : 0.0
+ opacity: inputContext.anchorRectIntersectsClipRect ? 1.0 : 0.0
MouseArea {
width: parent.width * 2
@@ -55,10 +56,10 @@ Item {
// The middle of a handle is mapped to the middle of the line above it
root.handleIsMoving = true
var xx = x + anchorHandle.x + mouse.x
- var yy = y + anchorHandle.y + mouse.y - (anchorHandle.height + Qt.inputMethod.anchorRectangle.height)/2
+ var yy = y + anchorHandle.y + mouse.y - (anchorHandle.height + inputContext.anchorRectangle.height)/2
var x2 = cursorHandle.x + cursorHandle.width/2
- var y2 = cursorHandle.y - Qt.inputMethod.cursorRectangle.height/2
- InputContext.setSelectionOnFocusObject(Qt.point(xx,yy), Qt.point(x2,y2))
+ var y2 = cursorHandle.y - inputContext.cursorRectangle.height/2
+ inputContext.setSelectionOnFocusObject(Qt.point(xx,yy), Qt.point(x2,y2))
}
onReleased: {
root.handleIsMoving = false
@@ -70,13 +71,13 @@ Item {
Loader {
id: cursorHandle
sourceComponent: keyboard.style.selectionHandle
- x: visible ? Qt.inputMethod.cursorRectangle.x - width/2 : 0
- y: visible ? Qt.inputMethod.cursorRectangle.y + Qt.inputMethod.cursorRectangle.height : 0
+ x: visible ? inputContext.cursorRectangle.x - width/2 : 0
+ y: visible ? inputContext.cursorRectangle.y + inputContext.cursorRectangle.height : 0
Behavior on opacity {
NumberAnimation { duration: 200 }
}
- opacity: InputContext.cursorRectIntersectsClipRect ? 1.0 : 0.0
+ opacity: inputContext.cursorRectIntersectsClipRect ? 1.0 : 0.0
MouseArea {
width: parent.width * 2
@@ -86,10 +87,10 @@ Item {
// we don't move the handles, the handles will move as the selection changes.
root.handleIsMoving = true
var xx = anchorHandle.x + anchorHandle.width/2
- var yy = anchorHandle.y - Qt.inputMethod.anchorRectangle.height/2
+ var yy = anchorHandle.y - inputContext.anchorRectangle.height/2
var x2 = x + cursorHandle.x + mouse.x
- var y2 = y + cursorHandle.y + mouse.y - (cursorHandle.height + Qt.inputMethod.cursorRectangle.height)/2
- InputContext.setSelectionOnFocusObject(Qt.point(xx, yy), Qt.point(x2, y2))
+ var y2 = y + cursorHandle.y + mouse.y - (cursorHandle.height + inputContext.cursorRectangle.height)/2
+ inputContext.setSelectionOnFocusObject(Qt.point(xx, yy), Qt.point(x2, y2))
}
onReleased: {
root.handleIsMoving = false
diff --git a/src/virtualkeyboard/content/components/ShadowInputControl.qml b/src/virtualkeyboard/content/components/ShadowInputControl.qml
new file mode 100644
index 00000000..b935d5c6
--- /dev/null
+++ b/src/virtualkeyboard/content/components/ShadowInputControl.qml
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 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$
+**
+****************************************************************************/
+
+import QtQuick 2.7
+import QtQuick.VirtualKeyboard 2.2
+import QtQuick.VirtualKeyboard.Settings 2.2
+
+Item {
+ id: control
+
+ enabled: keyboard.active && VirtualKeyboardSettings.fullScreenMode
+
+ MouseArea {
+ anchors.fill: parent
+ }
+
+ onXChanged: InputContext.shadow.updateSelectionProperties()
+ onYChanged: InputContext.shadow.updateSelectionProperties()
+
+ Loader {
+ sourceComponent: keyboard.style.fullScreenInputContainerBackground
+ anchors.fill: parent
+ Loader {
+ id: fullScreenInputBackground
+ sourceComponent: keyboard.style.fullScreenInputBackground
+ anchors.fill: parent
+ anchors.margins: keyboard.style.fullScreenInputMargins
+ z: 1
+ Flickable {
+ id: flickable
+ clip: true
+ z: 2
+ width: parent.width
+ height: parent.height
+ flickableDirection: Flickable.HorizontalFlick
+ interactive: contentWidth > width
+ contentWidth: shadowInput.width
+ onContentXChanged: InputContext.shadow.updateSelectionProperties()
+
+ function ensureVisible(rectangle) {
+ if (contentX >= rectangle.x)
+ contentX = rectangle.x
+ else if (contentX + width <= rectangle.x + rectangle.width)
+ contentX = rectangle.x + rectangle.width - width;
+ }
+
+ TextInput {
+ id: shadowInput
+ objectName: "shadowInput"
+ property bool blinkStatus: true
+ width: Math.max(flickable.width, implicitWidth)
+ height: implicitHeight
+ anchors.verticalCenter: parent.verticalCenter
+ leftPadding: keyboard.style.fullScreenInputPadding
+ rightPadding: keyboard.style.fullScreenInputPadding
+ activeFocusOnPress: false
+ font: keyboard.style.fullScreenInputFont
+ inputMethodHints: InputContext.inputMethodHints
+ cursorDelegate: keyboard.style.fullScreenInputCursor
+ passwordCharacter: keyboard.style.fullScreenInputPasswordCharacter
+ color: keyboard.style.fullScreenInputColor
+ selectionColor: keyboard.style.fullScreenInputSelectionColor
+ selectedTextColor: keyboard.style.fullScreenInputSelectedTextColor
+ echoMode: (InputContext.inputMethodHints & Qt.ImhHiddenText) ? TextInput.Password : TextInput.Normal
+ selectByMouse: true
+ onCursorPositionChanged: {
+ cursorSyncTimer.restart()
+ blinkStatus = true
+ cursorTimer.restart()
+ }
+ onSelectionStartChanged: cursorSyncTimer.restart()
+ onSelectionEndChanged: cursorSyncTimer.restart()
+ onCursorRectangleChanged: flickable.ensureVisible(cursorRectangle)
+
+ function getAnchorPosition() {
+ if (selectionStart == selectionEnd)
+ return cursorPosition
+ else if (selectionStart == cursorPosition)
+ return selectionEnd
+ else
+ return selectionStart
+ }
+
+ Timer {
+ id: cursorSyncTimer
+ interval: 0
+ onTriggered: {
+ var anchorPosition = shadowInput.getAnchorPosition()
+ if (anchorPosition !== InputContext.anchorPosition || shadowInput.cursorPosition !== InputContext.cursorPosition)
+ InputContext.forceCursorPosition(anchorPosition, shadowInput.cursorPosition)
+ }
+ }
+
+ Timer {
+ id: cursorTimer
+ interval: Qt.styleHints.cursorFlashTime / 2
+ repeat: true
+ running: true
+ onTriggered: shadowInput.blinkStatus = !shadowInput.blinkStatus
+ }
+ }
+ }
+ }
+ }
+
+ Binding {
+ target: InputContext.shadow
+ property: "inputItem"
+ value: shadowInput
+ when: VirtualKeyboardSettings.fullScreenMode
+ }
+}
diff --git a/src/virtualkeyboard/content/components/ShiftKey.qml b/src/virtualkeyboard/content/components/ShiftKey.qml
index b8424a5b..d7705d9f 100644
--- a/src/virtualkeyboard/content/components/ShiftKey.qml
+++ b/src/virtualkeyboard/content/components/ShiftKey.qml
@@ -48,9 +48,5 @@ BaseKey {
highlighted: InputContext.capsLock
functionKey: true
keyPanelDelegate: keyboard.style ? keyboard.style.shiftKeyPanel : undefined
- /*! \internal */
- property bool capsLock: InputContext.capsLock
- /*! \internal */
- property bool shift: InputContext.shift
onClicked: InputContext.shiftHandler.toggleShift()
}
diff --git a/src/virtualkeyboard/content/components/WordCandidatePopupList.qml b/src/virtualkeyboard/content/components/WordCandidatePopupList.qml
index 5057dfa8..7740cbf9 100644
--- a/src/virtualkeyboard/content/components/WordCandidatePopupList.qml
+++ b/src/virtualkeyboard/content/components/WordCandidatePopupList.qml
@@ -54,16 +54,16 @@ ListView {
Binding {
target: wordCandidatePopupList
property: "x"
- value: Qt.inputMethod.cursorRectangle.x -
+ value: Math.round(Qt.inputMethod.cursorRectangle.x -
(wordCandidatePopupList.currentItem ?
(wordCandidatePopupList.currentItem.hasOwnProperty("cursorAnchor") ?
- wordCandidatePopupList.currentItem.cursorAnchor : wordCandidatePopupList.currentItem.width) : 0)
+ wordCandidatePopupList.currentItem.cursorAnchor : wordCandidatePopupList.currentItem.width) : 0))
when: wordCandidatePopupList.visible
}
Binding {
target: wordCandidatePopupList
property: "y"
- value: wordCandidatePopupList.flipVertical ? Qt.inputMethod.cursorRectangle.y - wordCandidatePopupList.height : Qt.inputMethod.cursorRectangle.y + Qt.inputMethod.cursorRectangle.height
+ value: Math.round(wordCandidatePopupList.flipVertical ? Qt.inputMethod.cursorRectangle.y - wordCandidatePopupList.height : Qt.inputMethod.cursorRectangle.y + Qt.inputMethod.cursorRectangle.height)
when: wordCandidatePopupList.visible
}
orientation: ListView.Vertical
diff --git a/src/virtualkeyboard/content/content.qrc b/src/virtualkeyboard/content/content.qrc
index 20627466..431e4205 100644
--- a/src/virtualkeyboard/content/content.qrc
+++ b/src/virtualkeyboard/content/content.qrc
@@ -29,5 +29,6 @@
<file>components/WordCandidatePopupList.qml</file>
<file>components/LanguagePopupList.qml</file>
<file>components/SelectionControl.qml</file>
+ <file>components/ShadowInputControl.qml</file>
</qresource>
</RCC>
diff --git a/src/virtualkeyboard/content/styles/default/style.qml b/src/virtualkeyboard/content/styles/default/style.qml
index e02b749e..03f0344f 100644
--- a/src/virtualkeyboard/content/styles/default/style.qml
+++ b/src/virtualkeyboard/content/styles/default/style.qml
@@ -954,4 +954,24 @@ KeyboardStyle {
sourceSize.width: 20
source: resourcePrefix + "images/selectionhandle-bottom.svg"
}
+
+ fullScreenInputContainerBackground: Rectangle {
+ color: "#FFF"
+ }
+
+ fullScreenInputBackground: Rectangle {
+ color: "#FFF"
+ }
+
+ fullScreenInputMargins: Math.round(15 * scaleHint)
+
+ fullScreenInputPadding: Math.round(30 * scaleHint)
+
+ fullScreenInputCursor: Rectangle {
+ width: 1
+ color: "#000"
+ visible: parent.blinkStatus
+ }
+
+ fullScreenInputFont.pixelSize: 58 * scaleHint
}
diff --git a/src/virtualkeyboard/content/styles/retro/style.qml b/src/virtualkeyboard/content/styles/retro/style.qml
index 04e7ea81..a1cb3ffc 100644
--- a/src/virtualkeyboard/content/styles/retro/style.qml
+++ b/src/virtualkeyboard/content/styles/retro/style.qml
@@ -994,4 +994,28 @@ KeyboardStyle {
sourceSize.width: 20
source: resourcePrefix + "images/selectionhandle-bottom.svg"
}
+
+ fullScreenInputContainerBackground: Rectangle {
+ color: "#FFF"
+ }
+
+ fullScreenInputBackground: Rectangle {
+ color: "#FFF"
+ }
+
+ fullScreenInputMargins: Math.round(15 * scaleHint)
+
+ fullScreenInputPadding: Math.round(30 * scaleHint)
+
+ fullScreenInputCursor: Rectangle {
+ width: 1
+ color: "#000"
+ visible: parent.blinkStatus
+ }
+
+ fullScreenInputFont.pixelSize: 58 * scaleHint
+
+ fullScreenInputPasswordCharacter: "*"
+
+ fullScreenInputSelectionColor: "#B57C47"
}
diff --git a/src/virtualkeyboard/doc/src/qtvirtualkeyboard-index.qdoc b/src/virtualkeyboard/doc/src/qtvirtualkeyboard-index.qdoc
index ca19f825..91373b23 100644
--- a/src/virtualkeyboard/doc/src/qtvirtualkeyboard-index.qdoc
+++ b/src/virtualkeyboard/doc/src/qtvirtualkeyboard-index.qdoc
@@ -124,7 +124,7 @@
*/
/*!
-\qmlmodule QtQuick.VirtualKeyboard 2.0
+\qmlmodule QtQuick.VirtualKeyboard 2.2
\title Qt Virtual Keyboard QML Types
\ingroup qmlmodules
\brief Provides QML types for an input framework and a reference keyboard front
@@ -134,8 +134,8 @@ end.
import statements in your .qml file:
\code
- import QtQuick.VirtualKeyboard 2.0
- import QtQuick.VirtualKeyboard.Styles 2.0
+ import QtQuick.VirtualKeyboard 2.2
+ import QtQuick.VirtualKeyboard.Styles 2.2
import QtQuick.VirtualKeyboard.Settings 2.2
\endcode
diff --git a/src/virtualkeyboard/inputcontext.cpp b/src/virtualkeyboard/inputcontext.cpp
index 50255e6e..d069927b 100644
--- a/src/virtualkeyboard/inputcontext.cpp
+++ b/src/virtualkeyboard/inputcontext.cpp
@@ -31,6 +31,7 @@
#include "inputengine.h"
#include "shifthandler.h"
#include "platforminputcontext.h"
+#include "shadowinputcontext.h"
#include "virtualkeyboarddebug.h"
#include "enterkeyaction.h"
#include "settings.h"
@@ -70,7 +71,8 @@ public:
ReselectEventState = 0x1,
InputMethodEventState = 0x2,
KeyEventState = 0x4,
- InputMethodClickState = 0x8
+ InputMethodClickState = 0x8,
+ SyncShadowInputState = 0x10
};
Q_DECLARE_FLAGS(StateFlags, StateFlag)
@@ -87,6 +89,8 @@ public:
shift(false),
capsLock(false),
cursorPosition(0),
+ anchorPosition(0),
+ forceAnchorPosition(-1),
forceCursorPosition(-1),
inputMethodHints(Qt::ImhNone),
preeditText(),
@@ -116,6 +120,8 @@ public:
bool capsLock;
StateFlags stateFlags;
int cursorPosition;
+ int anchorPosition;
+ int forceAnchorPosition;
int forceCursorPosition;
Qt::InputMethodHints inputMethodHints;
QString preeditText;
@@ -131,6 +137,7 @@ public:
QSet<int> activeNavigationKeys;
#endif
QSet<quint32> activeKeys;
+ ShadowInputContext shadow;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(InputContextPrivate::StateFlags)
@@ -162,6 +169,7 @@ InputContext::InputContext(PlatformInputContext *parent) :
{
Q_D(InputContext);
d->inputContext = parent;
+ d->shadow.setInputContext(this);
if (d->inputContext) {
d->inputContext->setInputContext(this);
connect(d->inputContext, SIGNAL(focusObjectChanged()), SLOT(onInputItemChanged()));
@@ -225,6 +233,12 @@ bool InputContext::uppercase() const
return d->shift || d->capsLock;
}
+int InputContext::anchorPosition() const
+{
+ Q_D(const InputContext);
+ return d->anchorPosition;
+}
+
int InputContext::cursorPosition() const
{
Q_D(const InputContext);
@@ -247,29 +261,24 @@ void InputContext::setPreeditText(const QString &text, QList<QInputMethodEvent::
{
// Add default attributes
if (!text.isEmpty()) {
- bool containsTextFormat = false;
- for (QList<QInputMethodEvent::Attribute>::ConstIterator attribute = attributes.constBegin();
- attribute != attributes.constEnd(); attribute++) {
- if (attribute->type == QInputMethodEvent::TextFormat) {
- containsTextFormat = true;
- break;
- }
- }
- if (!containsTextFormat) {
+ if (!testAttribute(attributes, QInputMethodEvent::TextFormat)) {
QTextCharFormat textFormat;
textFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline);
attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, text.length(), textFormat));
}
} else {
- Q_D(InputContext);
- if (d->forceCursorPosition != -1)
- attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, d->forceCursorPosition, 0, QVariant()));
- d->forceCursorPosition = -1;
+ addSelectionAttribute(attributes);
}
sendPreedit(text, attributes, replaceFrom, replaceLength);
}
+QList<QInputMethodEvent::Attribute> InputContext::preeditTextAttributes() const
+{
+ Q_D(const InputContext);
+ return d->preeditTextAttributes;
+}
+
QString InputContext::surroundingText() const
{
Q_D(const InputContext);
@@ -491,13 +500,11 @@ void InputContext::commit(const QString &text, int replaceFrom, int replaceLengt
VIRTUALKEYBOARD_DEBUG() << "InputContext::commit():" << text << replaceFrom << replaceLength;
bool preeditChanged = !d->preeditText.isEmpty();
d->preeditText.clear();
+ d->preeditTextAttributes.clear();
if (d->inputContext) {
QList<QInputMethodEvent::Attribute> attributes;
- if (d->forceCursorPosition != -1) {
- attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, d->forceCursorPosition, 0, QVariant()));
- d->forceCursorPosition = -1;
- }
+ addSelectionAttribute(attributes);
QInputMethodEvent inputEvent(QString(), attributes);
inputEvent.setCommitString(text, replaceFrom, replaceLength);
d->stateFlags |= InputContextPrivate::InputMethodEventState;
@@ -524,13 +531,11 @@ void InputContext::clear()
Q_D(InputContext);
bool preeditChanged = !d->preeditText.isEmpty();
d->preeditText.clear();
+ d->preeditTextAttributes.clear();
if (d->inputContext) {
QList<QInputMethodEvent::Attribute> attributes;
- if (d->forceCursorPosition != -1) {
- attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, d->forceCursorPosition, 0, QVariant()));
- d->forceCursorPosition = -1;
- }
+ addSelectionAttribute(attributes);
QInputMethodEvent event(QString(), attributes);
d->stateFlags |= InputContextPrivate::InputMethodEventState;
d->inputContext->sendEvent(&event);
@@ -576,6 +581,42 @@ void InputContext::setSelectionOnFocusObject(const QPointF &anchorPos, const QPo
QPlatformInputContext::setSelectionOnFocusObject(anchorPos, cursorPos);
}
+/*!
+ \internal
+*/
+void InputContext::forceCursorPosition(int anchorPosition, int cursorPosition)
+{
+ Q_D(InputContext);
+ if (!d->shadow.inputItem())
+ return;
+ if (!d->inputContext->m_visible)
+ return;
+ if (d->stateFlags.testFlag(InputContextPrivate::ReselectEventState))
+ return;
+ if (d->stateFlags.testFlag(InputContextPrivate::SyncShadowInputState))
+ return;
+
+ VIRTUALKEYBOARD_DEBUG() << "InputContext::forceCursorPosition():" << cursorPosition << "anchorPosition:" << anchorPosition;
+ if (!d->preeditText.isEmpty()) {
+ d->forceAnchorPosition = -1;
+ d->forceCursorPosition = cursorPosition;
+ if (cursorPosition > d->cursorPosition)
+ d->forceCursorPosition += d->preeditText.length();
+ d->inputEngine->update();
+ } else {
+ d->forceAnchorPosition = anchorPosition;
+ d->forceCursorPosition = cursorPosition;
+ setPreeditText("");
+ if (!d->inputMethodHints.testFlag(Qt::ImhNoPredictiveText) &&
+ cursorPosition > 0 && d->selectedText.isEmpty()) {
+ d->stateFlags |= InputContextPrivate::ReselectEventState;
+ if (d->inputEngine->reselect(cursorPosition, InputEngine::WordAtCursor))
+ d->stateFlags |= InputContextPrivate::InputMethodClickState;
+ d->stateFlags &= ~InputContextPrivate::ReselectEventState;
+ }
+ }
+}
+
bool InputContext::anchorRectIntersectsClipRect() const
{
Q_D(const InputContext);
@@ -594,6 +635,12 @@ bool InputContext::selectionControlVisible() const
return d->selectionControlVisible;
}
+ShadowInputContext *InputContext::shadow() const
+{
+ Q_D(const InputContext);
+ return const_cast<ShadowInputContext *>(&d->shadow);
+}
+
void InputContext::onInputItemChanged()
{
Q_D(InputContext);
@@ -630,16 +677,30 @@ void InputContext::sendPreedit(const QString &text, const QList<QInputMethodEven
if (d->inputContext) {
QInputMethodEvent event(text, attributes);
- if (replaceFrom != 0 || replaceLength > 0)
+ const bool replace = replaceFrom != 0 || replaceLength > 0;
+ if (replace)
event.setCommitString(QString(), replaceFrom, replaceLength);
d->stateFlags |= InputContextPrivate::InputMethodEventState;
d->inputContext->sendEvent(&event);
d->stateFlags &= ~InputContextPrivate::InputMethodEventState;
+
+ // Send also to shadow input if only attributes changed.
+ // In this case the update() may not be called, so the shadow
+ // input may be out of sync.
+ if (d->shadow.inputItem() && !replace && !text.isEmpty() &&
+ !textChanged && attributesChanged) {
+ VIRTUALKEYBOARD_DEBUG() << "InputContext::sendPreedit(shadow):" << text << replaceFrom << replaceLength;
+ event.setAccepted(true);
+ QGuiApplication::sendEvent(d->shadow.inputItem(), &event);
+ }
}
if (textChanged)
emit preeditTextChanged();
}
+
+ if (d->preeditText.isEmpty())
+ d->preeditTextAttributes.clear();
}
void InputContext::reset()
@@ -679,6 +740,7 @@ void InputContext::update(Qt::InputMethodQueries queries)
bool newInputMethodHints = inputMethodHints != d->inputMethodHints;
bool newSurroundingText = surroundingText != d->surroundingText;
bool newSelectedText = selectedText != d->selectedText;
+ bool newAnchorPosition = anchorPosition != d->anchorPosition;
bool newCursorPosition = cursorPosition != d->cursorPosition;
bool newAnchorRectangle = anchorRectangle != d->anchorRectangle;
bool newCursorRectangle = cursorRectangle != d->cursorRectangle;
@@ -699,6 +761,7 @@ void InputContext::update(Qt::InputMethodQueries queries)
d->inputMethodHints = inputMethodHints;
d->surroundingText = surroundingText;
d->selectedText = selectedText;
+ d->anchorPosition = anchorPosition;
d->cursorPosition = cursorPosition;
d->anchorRectangle = anchorRectangle;
d->cursorRectangle = cursorRectangle;
@@ -725,6 +788,9 @@ void InputContext::update(Qt::InputMethodQueries queries)
if (newSelectedText) {
emit selectedTextChanged();
}
+ if (newAnchorPosition) {
+ emit anchorPositionChanged();
+ }
if (newCursorPosition) {
emit cursorPositionChanged();
}
@@ -755,6 +821,12 @@ void InputContext::update(Qt::InputMethodQueries queries)
d->stateFlags |= InputContextPrivate::InputMethodClickState;
d->stateFlags &= ~InputContextPrivate::ReselectEventState;
}
+
+ if (!d->stateFlags.testFlag(InputContextPrivate::SyncShadowInputState)) {
+ d->stateFlags |= InputContextPrivate::SyncShadowInputState;
+ d->shadow.update(queries);
+ d->stateFlags &= ~InputContextPrivate::SyncShadowInputState;
+ }
}
void InputContext::invokeAction(QInputMethod::Action action, int cursorPosition)
@@ -822,6 +894,28 @@ bool InputContext::filterEvent(const QEvent *event)
return false;
}
+void InputContext::addSelectionAttribute(QList<QInputMethodEvent::Attribute> &attributes)
+{
+ Q_D(InputContext);
+ if (!testAttribute(attributes, QInputMethodEvent::Selection) && d->forceCursorPosition != -1) {
+ if (d->forceAnchorPosition != -1)
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, d->forceAnchorPosition, d->forceCursorPosition - d->forceAnchorPosition, QVariant()));
+ else
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, d->forceCursorPosition, 0, QVariant()));
+ }
+ d->forceAnchorPosition = -1;
+ d->forceCursorPosition = -1;
+}
+
+bool InputContext::testAttribute(const QList<QInputMethodEvent::Attribute> &attributes, QInputMethodEvent::AttributeType attributeType) const
+{
+ for (const QInputMethodEvent::Attribute &attribute : qAsConst(attributes)) {
+ if (attribute.type == attributeType)
+ return true;
+ }
+ return false;
+}
+
/*!
\qmlproperty bool InputContext::focus
@@ -876,6 +970,20 @@ bool InputContext::filterEvent(const QEvent *event)
*/
/*!
+ \qmlproperty int InputContext::anchorPosition
+ \since QtQuick.VirtualKeyboard 2.2
+
+ This property is changed when the anchor position changes.
+*/
+
+/*!
+ \property QtVirtualKeyboard::InputContext::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.
diff --git a/src/virtualkeyboard/inputcontext.h b/src/virtualkeyboard/inputcontext.h
index 925745bd..3b0727e2 100644
--- a/src/virtualkeyboard/inputcontext.h
+++ b/src/virtualkeyboard/inputcontext.h
@@ -39,6 +39,7 @@
namespace QtVirtualKeyboard {
class PlatformInputContext;
+class ShadowInputContext;
class InputEngine;
class ShiftHandler;
class InputContextPrivate;
@@ -52,6 +53,7 @@ class InputContext : public QObject
Q_PROPERTY(bool shift READ shift WRITE setShift NOTIFY shiftChanged)
Q_PROPERTY(bool capsLock READ capsLock WRITE setCapsLock NOTIFY capsLockChanged)
Q_PROPERTY(bool uppercase READ uppercase NOTIFY uppercaseChanged)
+ Q_PROPERTY(int anchorPosition READ anchorPosition NOTIFY anchorPositionChanged)
Q_PROPERTY(int cursorPosition READ cursorPosition NOTIFY cursorPositionChanged)
Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ inputMethodHints NOTIFY inputMethodHintsChanged)
Q_PROPERTY(QString preeditText READ preeditText WRITE setPreeditText NOTIFY preeditTextChanged)
@@ -70,6 +72,7 @@ class InputContext : public QObject
Q_PROPERTY(bool selectionControlVisible READ selectionControlVisible NOTIFY selectionControlVisibleChanged)
Q_PROPERTY(bool anchorRectIntersectsClipRect READ anchorRectIntersectsClipRect NOTIFY anchorRectIntersectsClipRectChanged)
Q_PROPERTY(bool cursorRectIntersectsClipRect READ cursorRectIntersectsClipRect NOTIFY cursorRectIntersectsClipRectChanged)
+ Q_PROPERTY(ShadowInputContext *shadow READ shadow CONSTANT)
public:
explicit InputContext(PlatformInputContext *parent = 0);
@@ -81,10 +84,12 @@ public:
bool capsLock() const;
void setCapsLock(bool enable);
bool uppercase() const;
+ int anchorPosition() const;
int cursorPosition() const;
Qt::InputMethodHints inputMethodHints() const;
QString preeditText() const;
void setPreeditText(const QString &text, QList<QInputMethodEvent::Attribute> attributes = QList<QInputMethodEvent::Attribute>(), int replaceFrom = 0, int replaceLength = 0);
+ QList<QInputMethodEvent::Attribute> preeditTextAttributes() const;
QString surroundingText() const;
QString selectedText() const;
QRectF anchorRectangle() const;
@@ -106,6 +111,7 @@ public:
bool selectionControlVisible() const;
bool anchorRectIntersectsClipRect() const;
bool cursorRectIntersectsClipRect() const;
+ ShadowInputContext *shadow() const;
Q_INVOKABLE void hideInputPanel();
Q_INVOKABLE void sendKeyClick(int key, const QString &text, int modifiers = 0);
@@ -120,6 +126,9 @@ public:
// For selection handles
Q_INVOKABLE void setSelectionOnFocusObject(const QPointF &anchorPos, const QPointF &cursorPos);
+ // For shadow input
+ Q_INVOKABLE void forceCursorPosition(int anchorPosition, int cursorPosition);
+
signals:
void focusChanged();
void focusEditorChanged();
@@ -127,6 +136,7 @@ signals:
void inputMethodHintsChanged();
void surroundingTextChanged();
void selectedTextChanged();
+ void anchorPositionChanged();
void cursorPositionChanged();
void anchorRectangleChanged();
void cursorRectangleChanged();
@@ -156,6 +166,8 @@ private:
void update(Qt::InputMethodQueries queries);
void invokeAction(QInputMethod::Action action, int cursorPosition);
bool filterEvent(const QEvent *event);
+ void addSelectionAttribute(QList<QInputMethodEvent::Attribute> &attributes);
+ bool testAttribute(const QList<QInputMethodEvent::Attribute> &attributes, QInputMethodEvent::AttributeType attributeType) const;
private:
friend class PlatformInputContext;
diff --git a/src/virtualkeyboard/platforminputcontext.cpp b/src/virtualkeyboard/platforminputcontext.cpp
index d9378195..6d555160 100644
--- a/src/virtualkeyboard/platforminputcontext.cpp
+++ b/src/virtualkeyboard/platforminputcontext.cpp
@@ -29,6 +29,7 @@
#include "platforminputcontext.h"
#include "inputcontext.h"
+#include "shadowinputcontext.h"
#include "abstractinputpanel.h"
#ifdef QT_VIRTUALKEYBOARD_DESKTOP
#include "desktopinputpanel.h"
@@ -181,6 +182,9 @@ QObject *PlatformInputContext::focusObject()
void PlatformInputContext::setFocusObject(QObject *object)
{
VIRTUALKEYBOARD_DEBUG() << "PlatformInputContext::setFocusObject():" << object;
+ Q_ASSERT(m_inputContext == 0 ||
+ m_inputContext->shadow()->inputItem() == 0 ||
+ m_inputContext->shadow()->inputItem() != object);
if (m_focusObject != object) {
if (m_focusObject)
m_focusObject->removeEventFilter(this);
diff --git a/src/virtualkeyboard/plugin.cpp b/src/virtualkeyboard/plugin.cpp
index 5349e735..73ddeabc 100644
--- a/src/virtualkeyboard/plugin.cpp
+++ b/src/virtualkeyboard/plugin.cpp
@@ -59,6 +59,7 @@
#include "enterkeyactionattachedtype.h"
#include "virtualkeyboardsettings.h"
#include "trace.h"
+#include "shadowinputcontext.h"
#if defined(QT_STATICPLUGIN)
#include <QtPlugin>
// This macro is similar to Q_IMPORT_PLUGIN, except it does not
@@ -182,6 +183,8 @@ QPlatformInputContext *QVirtualKeyboardPlugin::create(const QString &system, con
qmlRegisterType<EnterKeyAction>(pluginUri, 1, 0, "EnterKeyAction");
qmlRegisterType<EnterKeyAction>(pluginUri, 2, 0, "EnterKeyAction");
qmlRegisterType<Trace>(pluginUri, 2, 0, "Trace");
+ qRegisterMetaType<QtVirtualKeyboard::ShadowInputContext *>("ShadowInputContext*");
+ qmlRegisterUncreatableType<ShadowInputContext>(pluginUri, 2, 2, "ShadowInputContext", QLatin1String("Cannot create shadow input context"));
qmlRegisterSingletonType<VirtualKeyboardSettings>(pluginSettingsUri, 1, 0, "VirtualKeyboardSettings", VirtualKeyboardSettings::registerSettingsModule);
qmlRegisterSingletonType<VirtualKeyboardSettings>(pluginSettingsUri, 1, 1, "VirtualKeyboardSettings", VirtualKeyboardSettings::registerSettingsModule);
qmlRegisterSingletonType<VirtualKeyboardSettings>(pluginSettingsUri, 1, 2, "VirtualKeyboardSettings", VirtualKeyboardSettings::registerSettingsModule);
@@ -195,6 +198,7 @@ QPlatformInputContext *QVirtualKeyboardPlugin::create(const QString &system, con
qmlRegisterType(QUrl(path + QLatin1String("InputPanel.qml")), pluginUri, 1, 3, "InputPanel");
qmlRegisterType(QUrl(path + QLatin1String("InputPanel.qml")), pluginUri, 2, 0, "InputPanel");
qmlRegisterType(QUrl(path + QLatin1String("InputPanel.qml")), pluginUri, 2, 1, "InputPanel");
+ qmlRegisterType(QUrl(path + QLatin1String("InputPanel.qml")), pluginUri, 2, 2, "InputPanel");
qmlRegisterType(QUrl(path + QLatin1String("HandwritingInputPanel.qml")), pluginUri, 2, 0, "HandwritingInputPanel");
const QString componentsPath = path + QStringLiteral("components/");
qmlRegisterType(QUrl(componentsPath + QLatin1String("AlternativeKeys.qml")), pluginUri, 1, 0, "AlternativeKeys");
diff --git a/src/virtualkeyboard/settings.cpp b/src/virtualkeyboard/settings.cpp
index 85a0f3a2..259516aa 100644
--- a/src/virtualkeyboard/settings.cpp
+++ b/src/virtualkeyboard/settings.cpp
@@ -45,7 +45,8 @@ public:
layoutPath(),
wclAutoHideDelay(5000),
wclAlwaysVisible(false),
- wclAutoCommitWord(false)
+ wclAutoCommitWord(false),
+ fullScreenMode(false)
{}
QString style;
@@ -57,6 +58,7 @@ public:
int wclAutoHideDelay;
bool wclAlwaysVisible;
bool wclAutoCommitWord;
+ bool fullScreenMode;
};
static QScopedPointer<Settings> s_settingsInstance;
@@ -213,4 +215,19 @@ void Settings::setWclAutoCommitWord(bool wclAutoCommitWord)
}
}
+bool Settings::fullScreenMode() const
+{
+ Q_D(const Settings);
+ return d->fullScreenMode;
+}
+
+void Settings::setFullScreenMode(bool fullScreenMode)
+{
+ Q_D(Settings);
+ if (d->fullScreenMode != fullScreenMode) {
+ d->fullScreenMode = fullScreenMode;
+ emit fullScreenModeChanged();
+ }
+}
+
} // namespace QtVirtualKeyboard
diff --git a/src/virtualkeyboard/settings.h b/src/virtualkeyboard/settings.h
index 09e6bcb2..9d4684fa 100644
--- a/src/virtualkeyboard/settings.h
+++ b/src/virtualkeyboard/settings.h
@@ -75,6 +75,9 @@ public:
bool wclAutoCommitWord() const;
void setWclAutoCommitWord(bool wclAutoCommitWord);
+ bool fullScreenMode() const;
+ void setFullScreenMode(bool fullScreenMode);
+
signals:
void styleChanged();
void styleNameChanged();
@@ -85,6 +88,7 @@ signals:
void wclAutoHideDelayChanged();
void wclAlwaysVisibleChanged();
void wclAutoCommitWordChanged();
+ void fullScreenModeChanged();
};
} // namespace QtVirtualKeyboard
diff --git a/src/virtualkeyboard/shadowinputcontext.cpp b/src/virtualkeyboard/shadowinputcontext.cpp
new file mode 100644
index 00000000..b350e249
--- /dev/null
+++ b/src/virtualkeyboard/shadowinputcontext.cpp
@@ -0,0 +1,253 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 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 "shadowinputcontext.h"
+#include "inputcontext.h"
+#include "virtualkeyboarddebug.h"
+
+#include <QtCore/private/qobject_p.h>
+#include <QGuiApplication>
+#include <QQuickItem>
+
+QT_BEGIN_NAMESPACE
+bool operator==(const QInputMethodEvent::Attribute &attribute1, const QInputMethodEvent::Attribute &attribute2);
+QT_END_NAMESPACE
+
+namespace QtVirtualKeyboard {
+
+class ShadowInputContextPrivate : public QObjectPrivate
+{
+public:
+ ShadowInputContextPrivate() :
+ QObjectPrivate(),
+ inputContext(0),
+ anchorRectIntersectsClipRect(false),
+ cursorRectIntersectsClipRect(false),
+ selectionControlVisible(false)
+ {
+ }
+
+ InputContext *inputContext;
+ QPointer<QObject> inputItem;
+ QString preeditText;
+ QList<QInputMethodEvent::Attribute> preeditTextAttributes;
+ QRectF anchorRectangle;
+ QRectF cursorRectangle;
+ bool anchorRectIntersectsClipRect;
+ bool cursorRectIntersectsClipRect;
+ bool selectionControlVisible;
+};
+
+ShadowInputContext::ShadowInputContext(QObject *parent) :
+ QObject(*new ShadowInputContextPrivate(), parent)
+{
+}
+
+void ShadowInputContext::setInputContext(InputContext *inputContext)
+{
+ Q_D(ShadowInputContext);
+ d->inputContext = inputContext;
+}
+
+QObject *ShadowInputContext::inputItem() const
+{
+ Q_D(const ShadowInputContext);
+ return d->inputItem.data();
+}
+
+void ShadowInputContext::setInputItem(QObject *inputItem)
+{
+ Q_D(ShadowInputContext);
+ if (d->inputItem != inputItem) {
+ d->inputItem = inputItem;
+ emit inputItemChanged();
+ update(Qt::ImQueryAll);
+ }
+}
+
+QRectF ShadowInputContext::anchorRectangle() const
+{
+ Q_D(const ShadowInputContext);
+ return d->anchorRectangle;
+}
+
+QRectF ShadowInputContext::cursorRectangle() const
+{
+ Q_D(const ShadowInputContext);
+ return d->cursorRectangle;
+}
+
+bool ShadowInputContext::anchorRectIntersectsClipRect() const
+{
+ Q_D(const ShadowInputContext);
+ return d->anchorRectIntersectsClipRect;
+}
+
+bool ShadowInputContext::cursorRectIntersectsClipRect() const
+{
+ Q_D(const ShadowInputContext);
+ return d->cursorRectIntersectsClipRect;
+}
+
+bool ShadowInputContext::selectionControlVisible() const
+{
+ Q_D(const ShadowInputContext);
+ return d->selectionControlVisible;
+}
+
+void ShadowInputContext::setSelectionOnFocusObject(const QPointF &anchorPos, const QPointF &cursorPos)
+{
+ Q_D(ShadowInputContext);
+ QObject *focus = d->inputItem;
+ if (!focus)
+ return;
+
+ QQuickItem *quickItem = qobject_cast<QQuickItem *>(d->inputItem);
+ bool success;
+ int anchor = queryFocusObject(Qt::ImCursorPosition, quickItem ? quickItem->mapFromScene(anchorPos) : anchorPos).toInt(&success);
+ if (success) {
+ int cursor = queryFocusObject(Qt::ImCursorPosition, quickItem ? quickItem->mapFromScene(cursorPos) : cursorPos).toInt(&success);
+ if (success) {
+ QList<QInputMethodEvent::Attribute> imAttributes;
+ imAttributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, anchor, cursor - anchor, QVariant()));
+ QInputMethodEvent event(QString(), imAttributes);
+ QGuiApplication::sendEvent(QGuiApplication::focusObject(), &event);
+ }
+ }
+}
+
+void ShadowInputContext::updateSelectionProperties()
+{
+ Q_D(ShadowInputContext);
+ if (!d->inputItem)
+ return;
+
+ QInputMethodQueryEvent imQueryEvent(Qt::ImAnchorRectangle |
+ Qt::ImCursorRectangle |
+ Qt::ImInputItemClipRectangle);
+ QGuiApplication::sendEvent(d->inputItem, &imQueryEvent);
+ QQuickItem *quickItem = qobject_cast<QQuickItem *>(d->inputItem);
+ const QRectF anchorRect = imQueryEvent.value(Qt::ImAnchorRectangle).toRectF();
+ const QRectF cursorRect = imQueryEvent.value(Qt::ImCursorRectangle).toRectF();
+ const QRectF anchorRectangle = quickItem ? quickItem->mapRectToScene(anchorRect) : anchorRect;
+ const QRectF cursorRectangle = quickItem ? quickItem->mapRectToScene(cursorRect) : cursorRect;
+ const QRectF inputItemClipRect = imQueryEvent.value(Qt::ImInputItemClipRectangle).toRectF();
+ const bool anchorRectIntersectsClipRect = inputItemClipRect.intersects(anchorRect);
+ const bool cursorRectIntersectsClipRect = inputItemClipRect.intersects(cursorRect);
+ const bool selectionControlVisible = d->inputContext->selectionControlVisible();
+
+ const bool newAnchorRectangle = anchorRectangle != d->anchorRectangle;
+ const bool newCursorRectangle = cursorRectangle != d->cursorRectangle;
+ const bool newAnchorRectIntersectsClipRect = anchorRectIntersectsClipRect != d->anchorRectIntersectsClipRect;
+ const bool newCursorRectIntersectsClipRect = cursorRectIntersectsClipRect != d->cursorRectIntersectsClipRect;
+ const bool newSelectionControlVisible = selectionControlVisible != d->selectionControlVisible;
+
+ d->anchorRectangle = anchorRectangle;
+ d->cursorRectangle = cursorRectangle;
+ d->anchorRectIntersectsClipRect = anchorRectIntersectsClipRect;
+ d->cursorRectIntersectsClipRect = cursorRectIntersectsClipRect;
+ d->selectionControlVisible = selectionControlVisible;
+
+ if (newAnchorRectangle)
+ emit anchorRectangleChanged();
+ if (newCursorRectangle)
+ emit cursorRectangleChanged();
+ if (newAnchorRectIntersectsClipRect)
+ emit anchorRectIntersectsClipRectChanged();
+ if (newCursorRectIntersectsClipRect)
+ emit cursorRectIntersectsClipRectChanged();
+ if (newSelectionControlVisible)
+ emit selectionControlVisibleChanged();
+}
+
+void ShadowInputContext::update(Qt::InputMethodQueries queries)
+{
+ Q_UNUSED(queries)
+ Q_D(ShadowInputContext);
+ if (!d->inputItem)
+ return;
+
+ QInputMethodQueryEvent imQueryEvent(Qt::ImQueryInput);
+ QGuiApplication::sendEvent(d->inputItem, &imQueryEvent);
+
+ const QString surroundingText = imQueryEvent.value(Qt::ImSurroundingText).toString();
+ const int cursorPosition = imQueryEvent.value(Qt::ImCursorPosition).toInt();
+ const int anchorPosition = imQueryEvent.value(Qt::ImAnchorPosition).toInt();
+
+ const QString newSurroundingText = d->inputContext->surroundingText();
+ const int newCursorPosition = d->inputContext->cursorPosition();
+ const int newAnchorPosition = d->inputContext->anchorPosition();
+
+ bool updateSurroundingText = newSurroundingText != surroundingText;
+ bool updateSelection = newCursorPosition != cursorPosition || newAnchorPosition != anchorPosition;
+ if (updateSurroundingText || updateSelection) {
+ QList<QInputMethodEvent::Attribute> attributes;
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection,
+ newAnchorPosition,
+ newCursorPosition - newAnchorPosition, QVariant()));
+ QInputMethodEvent inputEvent(QString(), attributes);
+ if (updateSurroundingText)
+ inputEvent.setCommitString(newSurroundingText, -cursorPosition, surroundingText.length());
+ QGuiApplication::sendEvent(d->inputItem, &inputEvent);
+ }
+
+ const QString newPreeditText = d->inputContext->preeditText();
+ const QList<QInputMethodEvent::Attribute> newPreeditAttributes = d->inputContext->preeditTextAttributes();
+ if (d->preeditText != newPreeditText || d->preeditTextAttributes != newPreeditAttributes) {
+ d->preeditText = newPreeditText;
+ d->preeditTextAttributes = newPreeditAttributes;
+ QInputMethodEvent inputEvent(d->preeditText, d->preeditTextAttributes);
+ QGuiApplication::sendEvent(d->inputItem, &inputEvent);
+ }
+
+ updateSelectionProperties();
+}
+
+QVariant ShadowInputContext::queryFocusObject(Qt::InputMethodQuery query, QVariant argument)
+{
+ Q_D(ShadowInputContext);
+ QVariant retval;
+ QObject *focusObject = d->inputItem;
+ if (!focusObject)
+ return retval;
+
+ bool newMethodWorks = QMetaObject::invokeMethod(focusObject, "inputMethodQuery",
+ Qt::DirectConnection,
+ Q_RETURN_ARG(QVariant, retval),
+ Q_ARG(Qt::InputMethodQuery, query),
+ Q_ARG(QVariant, argument));
+ if (newMethodWorks)
+ return retval;
+
+ QInputMethodQueryEvent queryEvent(query);
+ QCoreApplication::sendEvent(focusObject, &queryEvent);
+ return queryEvent.value(query);
+}
+
+} // namespace QtVirtualKeyboard
diff --git a/src/virtualkeyboard/shadowinputcontext.h b/src/virtualkeyboard/shadowinputcontext.h
new file mode 100644
index 00000000..1a2e0577
--- /dev/null
+++ b/src/virtualkeyboard/shadowinputcontext.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 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$
+**
+****************************************************************************/
+
+#ifndef SHADOWINPUTCONTEXT_H
+#define SHADOWINPUTCONTEXT_H
+
+#include <QObject>
+#include <QPointer>
+#include <QMetaType>
+#include <QRectF>
+
+namespace QtVirtualKeyboard {
+
+class InputContext;
+class ShadowInputContextPrivate;
+
+class ShadowInputContext : public QObject
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(ShadowInputContext)
+ Q_DECLARE_PRIVATE(ShadowInputContext)
+ Q_PROPERTY(QObject *inputItem READ inputItem WRITE setInputItem NOTIFY inputItemChanged)
+ Q_PROPERTY(QRectF anchorRectangle READ anchorRectangle NOTIFY anchorRectangleChanged)
+ Q_PROPERTY(QRectF cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged)
+ Q_PROPERTY(bool anchorRectIntersectsClipRect READ anchorRectIntersectsClipRect NOTIFY anchorRectIntersectsClipRectChanged)
+ Q_PROPERTY(bool cursorRectIntersectsClipRect READ cursorRectIntersectsClipRect NOTIFY cursorRectIntersectsClipRectChanged)
+ Q_PROPERTY(bool selectionControlVisible READ selectionControlVisible NOTIFY selectionControlVisibleChanged)
+
+ explicit ShadowInputContext(QObject *parent = 0);
+
+ void setInputContext(InputContext *inputContext);
+
+public:
+ QObject *inputItem() const;
+ void setInputItem(QObject *inputItem);
+ QRectF anchorRectangle() const;
+ QRectF cursorRectangle() const;
+ bool anchorRectIntersectsClipRect() const;
+ bool cursorRectIntersectsClipRect() const;
+ bool selectionControlVisible() const;
+
+ Q_INVOKABLE void setSelectionOnFocusObject(const QPointF &anchorPos, const QPointF &cursorPos);
+ Q_INVOKABLE void updateSelectionProperties();
+
+signals:
+ void inputItemChanged();
+ void anchorRectangleChanged();
+ void cursorRectangleChanged();
+ void anchorRectIntersectsClipRectChanged();
+ void cursorRectIntersectsClipRectChanged();
+ void selectionControlVisibleChanged();
+
+private:
+ void update(Qt::InputMethodQueries queries);
+ QVariant queryFocusObject(Qt::InputMethodQuery query, QVariant argument);
+
+private:
+ friend class InputContextPrivate;
+ friend class InputContext;
+};
+
+} // namespace QtVirtualKeyboard
+
+#endif // SHADOWINPUTCONTEXT_H
diff --git a/src/virtualkeyboard/shifthandler.cpp b/src/virtualkeyboard/shifthandler.cpp
index 486dea75..c40fd78e 100644
--- a/src/virtualkeyboard/shifthandler.cpp
+++ b/src/virtualkeyboard/shifthandler.cpp
@@ -48,6 +48,7 @@ public:
autoCapitalizationEnabled(false),
toggleShiftEnabled(false),
shiftChanged(false),
+ resetWhenVisible(false),
manualShiftLanguageFilter(QSet<QLocale::Language>() << QLocale::Arabic << QLocale::Persian << QLocale::Hindi << QLocale::Korean),
manualCapsInputModeFilter(QSet<InputEngine::InputMode>() << InputEngine::Cangjie << InputEngine::Zhuyin),
noAutoUppercaseInputModeFilter(QSet<InputEngine::InputMode>() << InputEngine::FullwidthLatin << InputEngine::Pinyin << InputEngine::Cangjie << InputEngine::Zhuyin),
@@ -61,6 +62,7 @@ public:
bool autoCapitalizationEnabled;
bool toggleShiftEnabled;
bool shiftChanged;
+ bool resetWhenVisible;
QLocale locale;
QTime timer;
const QSet<QLocale::Language> manualShiftLanguageFilter;
@@ -100,6 +102,7 @@ ShiftHandler::ShiftHandler(InputContext *parent) :
connect(d->inputContext, SIGNAL(shiftChanged()), SLOT(shiftChanged()));
connect(d->inputContext, SIGNAL(capsLockChanged()), SLOT(shiftChanged()));
connect(d->inputContext, SIGNAL(localeChanged()), SLOT(localeChanged()));
+ connect(qGuiApp->inputMethod(), SIGNAL(visibleChanged()), SLOT(inputMethodVisibleChanged()));
d->locale = QLocale(d->inputContext->locale());
}
}
@@ -255,6 +258,11 @@ void ShiftHandler::autoCapitalize()
void ShiftHandler::restart()
{
+ Q_D(ShiftHandler);
+ if (!qGuiApp->inputMethod()->isVisible()) {
+ d->resetWhenVisible = true;
+ return;
+ }
reset();
}
@@ -271,6 +279,15 @@ void ShiftHandler::localeChanged()
restart();
}
+void ShiftHandler::inputMethodVisibleChanged()
+{
+ Q_D(ShiftHandler);
+ if (d->resetWhenVisible && qGuiApp->inputMethod()->isVisible()) {
+ d->resetWhenVisible = false;
+ reset();
+ }
+}
+
void ShiftHandler::setAutoCapitalizationEnabled(bool enabled)
{
Q_D(ShiftHandler);
diff --git a/src/virtualkeyboard/shifthandler.h b/src/virtualkeyboard/shifthandler.h
index 4e63a946..c28a9581 100644
--- a/src/virtualkeyboard/shifthandler.h
+++ b/src/virtualkeyboard/shifthandler.h
@@ -69,6 +69,7 @@ private slots:
void restart();
void localeChanged();
void shiftChanged();
+ void inputMethodVisibleChanged();
private:
void setAutoCapitalizationEnabled(bool enabled);
diff --git a/src/virtualkeyboard/styles/KeyPanel.qml b/src/virtualkeyboard/styles/KeyPanel.qml
index 68bb0850..4e12b9a8 100644
--- a/src/virtualkeyboard/styles/KeyPanel.qml
+++ b/src/virtualkeyboard/styles/KeyPanel.qml
@@ -52,8 +52,6 @@ Item {
\li \c control.enabled Set to true when the key is enabled.
\li \c control.pressed Set to true when the key is currently pressed.
\li \c control.uppercased Set to true when the key is uppercased.
- \li \c control.capsLock Set to true when caps lock is enabled.
- \note Deprecated since 1.2. Use \l {InputContext::capsLock} {InputContext.capsLock} instead.
\endlist
*/
property Item control
diff --git a/src/virtualkeyboard/styles/KeyboardStyle.qml b/src/virtualkeyboard/styles/KeyboardStyle.qml
index 547aa8be..f0095146 100644
--- a/src/virtualkeyboard/styles/KeyboardStyle.qml
+++ b/src/virtualkeyboard/styles/KeyboardStyle.qml
@@ -44,7 +44,7 @@ import QtQuick 2.0
*/
QtObject {
- /*! The current size of the keyboard. */
+ /*! The current height of the keyboard. */
property real keyboardHeight
/*! The design width of the keyboard. */
@@ -53,8 +53,8 @@ QtObject {
/*! The design height of the keyboard. */
property real keyboardDesignHeight
- /*! The keyboard style scale hint. This value is determined by the
- physical size and the design size of the keyboard. All pixel
+ /*! The keyboard style scale hint. This value is determined by dividing
+ \l keyboardHeight by \l keyboardDesignHeight. All pixel
dimensions must be proportional to this value.
*/
readonly property real scaleHint: keyboardHeight / keyboardDesignHeight
@@ -426,4 +426,102 @@ QtObject {
\l {Integration Method}{application-based integration method}.
*/
property Component selectionHandle: null
+
+ /*!
+ \since QtQuick.VirtualKeyboard.Styles 2.2
+
+ This property holds the delegate for the background of the full screen
+ input container.
+ */
+ property Component fullScreenInputContainerBackground: null
+
+ /*!
+ \since QtQuick.VirtualKeyboard.Styles 2.2
+
+ This property holds the delegate for the background of the full screen
+ input.
+ */
+ property Component fullScreenInputBackground: null
+
+ /*!
+ \since QtQuick.VirtualKeyboard.Styles 2.2
+
+ This property holds the margins around the full screen input field.
+
+ The default value is \c 0.
+ */
+ property real fullScreenInputMargins: 0
+
+ /*!
+ \since QtQuick.VirtualKeyboard.Styles 2.2
+
+ This property holds the padding around the full screen input content.
+
+ The default value is \c 0.
+ */
+ property real fullScreenInputPadding: 0
+
+ /*!
+ \since QtQuick.VirtualKeyboard.Styles 2.2
+
+ This property holds the delegate for the cursor in the full screen input
+ field.
+
+ The delegate should toggle the visibility of the cursor according to
+ the \c {parent.blinkStatus} property defined for the full screen input
+ field. For example:
+
+ \code
+ fullScreenInputCursor: Rectangle {
+ width: 1
+ color: "#000"
+ visible: parent.blinkStatus
+ }
+ \endcode
+ */
+ property Component fullScreenInputCursor: null
+
+ /*!
+ \since QtQuick.VirtualKeyboard.Styles 2.2
+
+ This property holds the \c font for the full screen input field.
+ */
+ property font fullScreenInputFont
+
+ /*!
+ \since QtQuick.VirtualKeyboard.Styles 2.2
+
+ This property holds the password mask character for the full screen
+ input field.
+ */
+ property string fullScreenInputPasswordCharacter: "\u2022"
+
+ /*!
+ \since QtQuick.VirtualKeyboard.Styles 2.2
+
+ This property holds the text color for the full screen input field.
+
+ The default color is black.
+ */
+ property color fullScreenInputColor: "#000"
+
+ /*!
+ \since QtQuick.VirtualKeyboard.Styles 2.2
+
+ This property holds the selection color for the full screen input
+ field.
+
+ The default color is semi-transparent black.
+ */
+ property color fullScreenInputSelectionColor: Qt.rgba(0, 0, 0, 0.15)
+
+ /*!
+ \since QtQuick.VirtualKeyboard.Styles 2.2
+
+ This property holds the selected text color for the full screen input
+ field.
+
+ The default color is set to \l full screenInputColor.
+ */
+ property color fullScreenInputSelectedTextColor: fullScreenInputColor
}
diff --git a/src/virtualkeyboard/styles/styles_plugin.cpp b/src/virtualkeyboard/styles/styles_plugin.cpp
index d6e17f5c..9a73d728 100644
--- a/src/virtualkeyboard/styles/styles_plugin.cpp
+++ b/src/virtualkeyboard/styles/styles_plugin.cpp
@@ -34,7 +34,7 @@
#include <QtCore/QLibraryInfo>
/*!
- \qmlmodule QtQuick.VirtualKeyboard.Styles 2.0
+ \qmlmodule QtQuick.VirtualKeyboard.Styles 2.2
\title Qt Quick Virtual Keyboard Styles QML Types
\ingroup qmlmodules
@@ -44,7 +44,7 @@
import statements in your .qml file:
\code
- import QtQuick.VirtualKeyboard.Styles 2.0
+ import QtQuick.VirtualKeyboard.Styles 2.2
\endcode
*/
@@ -58,6 +58,7 @@ void QtVirtualKeyboardStylesPlugin::registerTypes(const char *uri)
qmlRegisterType(QUrl(path + QLatin1String("KeyboardStyle.qml")), uri, 1, 3, "KeyboardStyle");
qmlRegisterType(QUrl(path + QLatin1String("KeyboardStyle.qml")), uri, 2, 0, "KeyboardStyle");
qmlRegisterType(QUrl(path + QLatin1String("KeyboardStyle.qml")), uri, 2, 1, "KeyboardStyle");
+ qmlRegisterType(QUrl(path + QLatin1String("KeyboardStyle.qml")), uri, 2, 2, "KeyboardStyle");
qmlRegisterType(QUrl(path + QLatin1String("KeyIcon.qml")), uri, 1, 0, "KeyIcon");
qmlRegisterType(QUrl(path + QLatin1String("KeyIcon.qml")), uri, 2, 0, "KeyIcon");
qmlRegisterType(QUrl(path + QLatin1String("KeyPanel.qml")), uri, 1, 0, "KeyPanel");
diff --git a/src/virtualkeyboard/tcinputmethod.cpp b/src/virtualkeyboard/tcinputmethod.cpp
index 8a7a415a..6628ef7c 100644
--- a/src/virtualkeyboard/tcinputmethod.cpp
+++ b/src/virtualkeyboard/tcinputmethod.cpp
@@ -238,7 +238,7 @@ public:
// Compose back the text after the finals replacement.
input.clear();
for (int i = 0; i < decomposed.length(); ++i) {
- if (decomposed[i] != 0)
+ if (!decomposed[i].isNull())
input.append(decomposed[i]);
}
} else {
diff --git a/src/virtualkeyboard/virtualkeyboard.pro b/src/virtualkeyboard/virtualkeyboard.pro
index 6866f4ff..4f3ca694 100644
--- a/src/virtualkeyboard/virtualkeyboard.pro
+++ b/src/virtualkeyboard/virtualkeyboard.pro
@@ -33,7 +33,8 @@ SOURCES += platforminputcontext.cpp \
settings.cpp \
virtualkeyboardsettings.cpp \
trace.cpp \
- desktopinputselectioncontrol.cpp
+ desktopinputselectioncontrol.cpp \
+ shadowinputcontext.cpp
HEADERS += platforminputcontext.h \
inputcontext.h \
@@ -53,7 +54,8 @@ HEADERS += platforminputcontext.h \
virtualkeyboardsettings.h \
plugin.h \
trace.h \
- desktopinputselectioncontrol.h
+ desktopinputselectioncontrol.h \
+ shadowinputcontext.h
RESOURCES += \
content/styles/default/default_style.qrc \
@@ -164,7 +166,8 @@ t9write: LAYOUT_FILES += \
contains(CONFIG, lang-ro.*) {
LAYOUT_FILES += \
content/layouts/ro_RO/main.qml \
- content/layouts/ro_RO/symbols.qml \
+ content/layouts/ro_RO/symbols.qml
+t9write: LAYOUT_FILES += \
content/layouts/ro_RO/handwriting.qml
}
contains(CONFIG, lang-ru.*) {
@@ -323,6 +326,10 @@ lipi-toolkit {
win32: LIBS += Advapi32.lib
else: LIBS += -ldl
record-trace-input: DEFINES += QT_VIRTUALKEYBOARD_LIPI_RECORD_TRACE_INPUT
+ ltk_projects.files = $$PWD/3rdparty/lipi-toolkit/projects
+ ltk_projects.path = $$[QT_INSTALL_DATA]/qtvirtualkeyboard/lipi_toolkit
+ INSTALLS += ltk_projects
+ !prefix_build: COPIES += ltk_projects
}
t9write {
diff --git a/src/virtualkeyboard/virtualkeyboardsettings.cpp b/src/virtualkeyboard/virtualkeyboardsettings.cpp
index 92908730..12f85cc2 100644
--- a/src/virtualkeyboard/virtualkeyboardsettings.cpp
+++ b/src/virtualkeyboard/virtualkeyboardsettings.cpp
@@ -166,6 +166,7 @@ VirtualKeyboardSettings::VirtualKeyboardSettings(QQmlEngine *engine) :
connect(settings, SIGNAL(wclAutoHideDelayChanged()), &d->wordCandidateListSettings, SIGNAL(autoHideDelayChanged()));
connect(settings, SIGNAL(wclAlwaysVisibleChanged()), &d->wordCandidateListSettings, SIGNAL(alwaysVisibleChanged()));
connect(settings, SIGNAL(wclAutoCommitWordChanged()), &d->wordCandidateListSettings, SIGNAL(autoCommitWordChanged()));
+ connect(settings, SIGNAL(fullScreenModeChanged()), SIGNAL(fullScreenModeChanged()));
}
/*!
@@ -278,6 +279,16 @@ WordCandidateListSettings *VirtualKeyboardSettings::wordCandidateList() const
return const_cast<WordCandidateListSettings *>(&d->wordCandidateListSettings);
}
+bool VirtualKeyboardSettings::fullScreenMode() const
+{
+ return Settings::instance()->fullScreenMode();
+}
+
+void VirtualKeyboardSettings::setFullScreenMode(bool fullScreenMode)
+{
+ return Settings::instance()->setFullScreenMode(fullScreenMode);
+}
+
void VirtualKeyboardSettings::resetStyle()
{
Q_D(VirtualKeyboardSettings);
@@ -358,6 +369,28 @@ void VirtualKeyboardSettings::resetStyle()
*/
/*!
+ \qmlproperty bool VirtualKeyboardSettings::fullScreenMode
+ \since QtQuick.VirtualKeyboard.Settings 2.2
+
+ This property enables the fullscreen mode for the virtual keyboard.
+
+ In fullscreen mode, the virtual keyboard replicates the contents of the
+ focused input field to the fullscreen input field located at the top of the
+ keyboard.
+
+ For example, to activate the fullscreen mode when the screen aspect ratio
+ is greater than 16:9:
+
+ \code
+ Binding {
+ target: VirtualKeyboardSettings
+ property: "fullScreenMode"
+ value: (Screen.width / Screen.height) > (16.0 / 9.0)
+ }
+ \endcode
+*/
+
+/*!
\since QtQuick.VirtualKeyboard.Settings 2.2
\qmlpropertygroup QtQuick.VirtualKeyboard::VirtualKeyboardSettings::wordCandidateList
\qmlproperty int QtQuick.VirtualKeyboard::VirtualKeyboardSettings::wordCandidateList.autoHideDelay
diff --git a/src/virtualkeyboard/virtualkeyboardsettings.h b/src/virtualkeyboard/virtualkeyboardsettings.h
index da43d10e..ca61db2a 100644
--- a/src/virtualkeyboard/virtualkeyboardsettings.h
+++ b/src/virtualkeyboard/virtualkeyboardsettings.h
@@ -48,6 +48,7 @@ class VirtualKeyboardSettings : public QObject
Q_PROPERTY(QStringList availableLocales READ availableLocales NOTIFY availableLocalesChanged)
Q_PROPERTY(QStringList activeLocales READ activeLocales WRITE setActiveLocales NOTIFY activeLocalesChanged)
Q_PROPERTY(WordCandidateListSettings *wordCandidateList READ wordCandidateList CONSTANT)
+ Q_PROPERTY(bool fullScreenMode READ fullScreenMode WRITE setFullScreenMode NOTIFY fullScreenModeChanged)
public:
static QObject *registerSettingsModule(QQmlEngine *engine, QJSEngine *jsEngine);
@@ -72,6 +73,9 @@ public:
WordCandidateListSettings *wordCandidateList() const;
+ bool fullScreenMode() const;
+ void setFullScreenMode(bool fullScreenMode);
+
signals:
void styleChanged();
void styleNameChanged();
@@ -79,6 +83,7 @@ signals:
void availableLocalesChanged();
void activeLocalesChanged();
void layoutPathChanged();
+ void fullScreenModeChanged();
private:
void resetStyle();