aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMitch Curtis <mitch.curtis@digia.com>2014-01-27 14:06:59 +0100
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2014-01-28 14:50:17 +0200
commit9778eb24c145ce24c80ca753ea3526e104e9aa91 (patch)
tree988e487da09aee27157dd23ac6c4e7673603bd63 /src
parent631db7a021c80949b122311e5f38203989319743 (diff)
Restructure and rename.
This restructures the repo to match other Qt modules, like the Enterprise Controls. It also renames the plugin and usages of its name in the documentation so that the abbreviated "VKB" is not used anywhere. Change-Id: I5de3fc67846a50438e52f4be057abfa0d9be0d91 Reviewed-by: Frederik Gladhorn <frederik.gladhorn@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/src.pro9
-rw-r--r--src/virtualkeyboard/abstractinputmethod.cpp242
-rw-r--r--src/virtualkeyboard/abstractinputmethod.h76
-rw-r--r--src/virtualkeyboard/abstractinputpanel.cpp97
-rw-r--r--src/virtualkeyboard/abstractinputpanel.h42
-rw-r--r--src/virtualkeyboard/appinputpanel.cpp57
-rw-r--r--src/virtualkeyboard/appinputpanel.h42
-rw-r--r--src/virtualkeyboard/content/InputPanel.qml47
-rw-r--r--src/virtualkeyboard/content/components/AlternativeKeys.qml106
-rw-r--r--src/virtualkeyboard/content/components/AutoScroller.qml94
-rw-r--r--src/virtualkeyboard/content/components/BackspaceKey.qml26
-rw-r--r--src/virtualkeyboard/content/components/BaseKey.qml53
-rw-r--r--src/virtualkeyboard/content/components/ChangeLanguageKey.qml26
-rw-r--r--src/virtualkeyboard/content/components/CharacterPreviewBubble.qml44
-rw-r--r--src/virtualkeyboard/content/components/EnterKey.qml30
-rw-r--r--src/virtualkeyboard/content/components/FillerKey.qml23
-rw-r--r--src/virtualkeyboard/content/components/HideKeyboardKey.qml26
-rw-r--r--src/virtualkeyboard/content/components/Key.qml24
-rw-r--r--src/virtualkeyboard/content/components/Keyboard.qml313
-rw-r--r--src/virtualkeyboard/content/components/KeyboardColumn.qml25
-rw-r--r--src/virtualkeyboard/content/components/KeyboardLayout.qml28
-rw-r--r--src/virtualkeyboard/content/components/KeyboardRow.qml25
-rw-r--r--src/virtualkeyboard/content/components/MultitapInputMethod.qml121
-rw-r--r--src/virtualkeyboard/content/components/NumberKey.qml23
-rw-r--r--src/virtualkeyboard/content/components/ShiftKey.qml42
-rw-r--r--src/virtualkeyboard/content/components/SpaceKey.qml28
-rw-r--r--src/virtualkeyboard/content/components/SymbolModeKey.qml27
-rw-r--r--src/virtualkeyboard/content/layouts/ar_AR.qml94
-rw-r--r--src/virtualkeyboard/content/layouts/en_GB.qml194
-rw-r--r--src/virtualkeyboard/content/layouts/fi_FI.qml195
-rw-r--r--src/virtualkeyboard/content/layouts/numbers.qml114
-rw-r--r--src/virtualkeyboard/content/layouts/symbols_ar_AR.qml359
-rw-r--r--src/virtualkeyboard/content/layouts/symbols_en_GB.qml359
-rw-r--r--src/virtualkeyboard/content/layouts/symbols_fi_FI.qml359
-rw-r--r--src/virtualkeyboard/content/qmldir2
-rwxr-xr-xsrc/virtualkeyboard/content/styles/default/fonts/OpenSans-Regular.ttfbin0 -> 217360 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/default/fonts/OpenSans-Semibold.ttfbin0 -> 221328 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/default/images/backspace.pngbin0 -> 1844 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/default/images/enter.pngbin0 -> 1873 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/default/images/globe.pngbin0 -> 5697 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/default/images/hidekeyboard.pngbin0 -> 1870 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/default/images/shift.pngbin0 -> 2483 bytes
-rw-r--r--src/virtualkeyboard/content/styles/default/style.qml548
-rw-r--r--src/virtualkeyboard/content/styles/default/style.qrc12
-rw-r--r--src/virtualkeyboard/content/styles/retro/fonts/Courier Prime Bold.ttfbin0 -> 91368 bytes
-rw-r--r--src/virtualkeyboard/content/styles/retro/fonts/Courier Prime.ttfbin0 -> 98156 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/retro/images/backspace.pngbin0 -> 1844 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/retro/images/enter.pngbin0 -> 1873 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/retro/images/globe.pngbin0 -> 5697 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/retro/images/hidekeyboard.pngbin0 -> 1870 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/retro/images/key154px_black.pngbin0 -> 9977 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/retro/images/key154px_black_long.pngbin0 -> 11828 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/retro/images/key154px_capslock.pngbin0 -> 21410 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/retro/images/key154px_capslock_long.pngbin0 -> 24503 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/retro/images/key154px_colorA.pngbin0 -> 16911 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/retro/images/key154px_colorA_long.pngbin0 -> 21161 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/retro/images/key154px_colorB.pngbin0 -> 17447 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/retro/images/key154px_shiftcase.pngbin0 -> 9675 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/retro/images/key154px_shiftcase_long.pngbin0 -> 10444 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/retro/images/key156px_black_long.pngbin0 -> 10931 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/retro/images/key156px_black_medium_long.pngbin0 -> 11989 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/retro/images/key156px_colorA.pngbin0 -> 17049 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/retro/images/key156px_colorB.pngbin0 -> 17462 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/retro/images/key160px_black.pngbin0 -> 10165 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/retro/images/key160px_colorA.pngbin0 -> 17575 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/retro/images/key160px_colorB.pngbin0 -> 18291 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/retro/images/key_preview.pngbin0 -> 14779 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/retro/images/shift.pngbin0 -> 2483 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/retro/images/triangle_black.pngbin0 -> 2249 bytes
-rwxr-xr-xsrc/virtualkeyboard/content/styles/retro/images/triangle_highlight.pngbin0 -> 2120 bytes
-rw-r--r--src/virtualkeyboard/content/styles/retro/style.qml667
-rw-r--r--src/virtualkeyboard/content/styles/retro/style.qrc31
-rw-r--r--src/virtualkeyboard/declarativeinputcontext.cpp673
-rw-r--r--src/virtualkeyboard/declarativeinputcontext.h112
-rw-r--r--src/virtualkeyboard/declarativeinputengine.cpp733
-rw-r--r--src/virtualkeyboard/declarativeinputengine.h110
-rw-r--r--src/virtualkeyboard/declarativeinputmethod.cpp258
-rw-r--r--src/virtualkeyboard/declarativeinputmethod.h49
-rw-r--r--src/virtualkeyboard/declarativeselectionlistmodel.cpp223
-rw-r--r--src/virtualkeyboard/declarativeselectionlistmodel.h72
-rw-r--r--src/virtualkeyboard/declarativeshifthandler.cpp152
-rw-r--r--src/virtualkeyboard/declarativeshifthandler.h59
-rw-r--r--src/virtualkeyboard/defaultinputmethod.cpp58
-rw-r--r--src/virtualkeyboard/defaultinputmethod.h41
-rw-r--r--src/virtualkeyboard/doc/doc.pri7
-rw-r--r--src/virtualkeyboard/doc/images/virtualkeyboard-demo.pngbin0 -> 69025 bytes
-rw-r--r--src/virtualkeyboard/doc/qtvirtualkeyboard.qdocconf68
-rw-r--r--src/virtualkeyboard/doc/src/build.qdoc90
-rw-r--r--src/virtualkeyboard/doc/src/deployment-guide.qdoc140
-rw-r--r--src/virtualkeyboard/doc/src/qtvirtualkeyboard-examples.qdoc35
-rw-r--r--src/virtualkeyboard/doc/src/qtvirtualkeyboard-index.qdoc55
-rw-r--r--src/virtualkeyboard/doc/src/snippets/CustomInputMethod.qml50
-rw-r--r--src/virtualkeyboard/doc/src/technical-guide.qdoc244
-rw-r--r--src/virtualkeyboard/doc/style/style.css150
-rw-r--r--src/virtualkeyboard/hunspell/config.h2
-rw-r--r--src/virtualkeyboard/hunspell/hunspell.pro74
-rw-r--r--src/virtualkeyboard/hunspellinputmethod.cpp305
-rw-r--r--src/virtualkeyboard/hunspellinputmethod.h52
-rw-r--r--src/virtualkeyboard/hunspellworker.cpp162
-rw-r--r--src/virtualkeyboard/hunspellworker.h100
-rw-r--r--src/virtualkeyboard/inputview.cpp30
-rw-r--r--src/virtualkeyboard/inputview.h37
-rw-r--r--src/virtualkeyboard/plaininputmethod.cpp66
-rw-r--r--src/virtualkeyboard/plaininputmethod.h42
-rw-r--r--src/virtualkeyboard/platforminputcontext.cpp217
-rw-r--r--src/virtualkeyboard/platforminputcontext.h83
-rw-r--r--src/virtualkeyboard/plugin.cpp79
-rw-r--r--src/virtualkeyboard/qtvirtualkeyboard.json3
-rw-r--r--src/virtualkeyboard/styles/KeyIcon.qml56
-rw-r--r--src/virtualkeyboard/styles/KeyPanel.qml72
-rw-r--r--src/virtualkeyboard/styles/KeyboardStyle.qml233
-rw-r--r--src/virtualkeyboard/styles/SelectionListItem.qml39
-rw-r--r--src/virtualkeyboard/styles/plugins.qmltypes4
-rw-r--r--src/virtualkeyboard/styles/qmldir6
-rw-r--r--src/virtualkeyboard/styles/styles.pro32
-rw-r--r--src/virtualkeyboard/styles/styles_plugin.cpp32
-rw-r--r--src/virtualkeyboard/styles/styles_plugin.h34
-rw-r--r--src/virtualkeyboard/virtualkeyboard.pro112
-rw-r--r--src/virtualkeyboard/virtualkeyboarddebug.h31
-rw-r--r--src/virtualkeyboard/xcbinputpanel.cpp155
-rw-r--r--src/virtualkeyboard/xcbinputpanel.h54
121 files changed, 10121 insertions, 0 deletions
diff --git a/src/src.pro b/src/src.pro
new file mode 100644
index 00000000..6128996e
--- /dev/null
+++ b/src/src.pro
@@ -0,0 +1,9 @@
+TEMPLATE = subdirs
+
+SUBDIRS += \
+ virtualkeyboard \
+ virtualkeyboard/styles
+
+!disable-hunspell:exists(virtualkeyboard/hunspell/src/hunspell/hunspell.h) {
+ SUBDIRS += virtualkeyboard/hunspell
+}
diff --git a/src/virtualkeyboard/abstractinputmethod.cpp b/src/virtualkeyboard/abstractinputmethod.cpp
new file mode 100644
index 00000000..ca5e02e4
--- /dev/null
+++ b/src/virtualkeyboard/abstractinputmethod.cpp
@@ -0,0 +1,242 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "abstractinputmethod.h"
+
+/*!
+ \class AbstractInputMethod
+
+ \inmodule InputFramework
+
+ \brief The base class for input methods.
+
+ Use this class if you want to implement a custom input
+ method using C/C++ language.
+*/
+
+/*!
+ Constructs an input method with \a d_ptr as the private data
+ from the derived class and \a parent as the parent.
+*/
+AbstractInputMethod::AbstractInputMethod(AbstractInputMethodPrivate *d_ptr, QObject *parent) :
+ QObject(parent),
+ d_ptr(d_ptr)
+{
+}
+
+/*!
+ Constructs an input method with \a parent.
+*/
+AbstractInputMethod::AbstractInputMethod(QObject *parent) :
+ QObject(parent),
+ d_ptr(new AbstractInputMethodPrivate())
+{
+}
+
+/*!
+ Destroys the input method and frees all allocated resources.
+*/
+AbstractInputMethod::~AbstractInputMethod()
+{
+}
+
+/*!
+ Returns the meta class name of this instance.
+*/
+QString AbstractInputMethod::className() const
+{
+ return metaObject()->className();
+}
+
+/*!
+ Returns the input context associated with the input method.
+ This method returns \c NULL if the input method is not active.
+*/
+DeclarativeInputContext *AbstractInputMethod::inputContext() const
+{
+ Q_D(const AbstractInputMethod);
+ return d->inputEngine ? d->inputEngine->inputContext() : 0;
+}
+
+/*!
+ Returns the input engine associated with the input method.
+ This method returns \c NULL if the input method is not active.
+*/
+DeclarativeInputEngine *AbstractInputMethod::inputEngine() const
+{
+ Q_D(const AbstractInputMethod);
+ return d->inputEngine;
+}
+
+/*!
+ This method is called by the input engine when the input method needs
+ to be reset. The input method must reset its internal state only. The main
+ difference to the update() method is that reset() modifies only
+ the input method state, i.e. it must not modify the input context.
+*/
+void AbstractInputMethod::reset()
+{
+}
+
+/*!
+ This method is called by the input engine when the input method needs to be
+ updated. The input method must close the current pre-edit text and
+ restore its internal state to the default.
+*/
+void AbstractInputMethod::update()
+{
+}
+
+/*!
+ \internal
+ Called by the input engine when the input method is activated and
+ deactivated.
+*/
+void AbstractInputMethod::setInputEngine(DeclarativeInputEngine *inputEngine)
+{
+ Q_D(AbstractInputMethod);
+ if (d->inputEngine) {
+ disconnect(this, SLOT(reset()));
+ disconnect(this, SLOT(update()));
+ }
+ d->inputEngine = inputEngine;
+ if (d->inputEngine) {
+ connect(d->inputEngine, SIGNAL(inputMethodReset()), SLOT(reset()));
+ connect(d->inputEngine, SIGNAL(inputMethodUpdate()), SLOT(update()));
+ }
+}
+
+QList<DeclarativeSelectionListModel::Type> AbstractInputMethod::selectionLists()
+{
+ return QList<DeclarativeSelectionListModel::Type>();
+}
+
+int AbstractInputMethod::selectionListItemCount(DeclarativeSelectionListModel::Type type)
+{
+ Q_UNUSED(type)
+ return 0;
+}
+
+QVariant AbstractInputMethod::selectionListData(DeclarativeSelectionListModel::Type type, int index, int role)
+{
+ Q_UNUSED(type)
+ Q_UNUSED(index)
+ switch (role) {
+ case DeclarativeSelectionListModel::DisplayRole:
+ return QVariant("");
+ case DeclarativeSelectionListModel::WordCompletionLengthRole:
+ return QVariant(0);
+ }
+ return QVariant();
+}
+
+void AbstractInputMethod::selectionListItemSelected(DeclarativeSelectionListModel::Type type, int index)
+{
+ Q_UNUSED(type)
+ Q_UNUSED(index)
+}
+
+/*!
+ \property AbstractInputMethod::className
+ \brief Class name of this input method.
+
+ This property is used to distinguish different input method classes.
+ The class name is taken from the Qt meta class object.
+*/
+
+/*!
+ \fn QList<DeclarativeInputEngine::InputMode> AbstractInputMethod::inputModes(const QString& locale)
+
+ Returns the list of input modes for \a locale.
+*/
+
+/*!
+ \fn bool AbstractInputMethod::setInputMode(const QString& locale, DeclarativeInputEngine::InputMode inputMode)
+
+ Sets the \a inputMode and \a locale for this input method. Returns \c true
+ if successful.
+*/
+
+/*!
+ \fn bool AbstractInputMethod::setTextCase(DeclarativeInputEngine::TextCase textCase)
+
+ Updates the \a textCase for this input method. The method returns \c true
+ if successful.
+*/
+
+/*!
+ \fn bool AbstractInputMethod::keyEvent(Qt::Key key, const QString& text, Qt::KeyboardModifiers modifiers)
+
+ The purpose of this method is to handle the key events generated by the the
+ input engine.
+
+ The \a key parameter specifies the code of the key to handle. The key code
+ does not distinguish between capital and non-capital letters. The \a
+ text parameter contains the Unicode text for the key. The \a modifiers
+ parameter contains the key modifiers that apply to key.
+
+ This method returns \c true if the key event was successfully handled.
+ If the return value is \c false, the key event is redirected to the default
+ input method for futher processing.
+*/
+
+/*!
+ \fn QList<DeclarativeSelectionListModel::Type> AbstractInputMethod::selectionLists()
+
+ Returns the list of selection lists used by this input method.
+
+ This method is called by input engine when the input method is being
+ activated. The input method can reserve the selection lists for its use
+ by returning a list of selection list types required.
+*/
+
+/*!
+ \fn int AbstractInputMethod::selectionListItemCount(DeclarativeSelectionListModel::Type type)
+
+ Returns the number of items in the selection list identified by \a type.
+*/
+
+/*!
+ \fn QVariant AbstractInputMethod::selectionListData(DeclarativeSelectionListModel::Type type, int index, int role)
+
+ Returns item data for the selection list identified by \a type. The \a role
+ parameter specifies which data is requested. The \a index parameter is a
+ zero based index into the list.
+*/
+
+/*!
+ \fn void AbstractInputMethod::selectionListItemSelected(DeclarativeSelectionListModel::Type type, int index)
+
+ This method is called when an item at \a index has been selected by the
+ user. The selection list is identified by the \a type parameter.
+*/
+
+/*!
+ \fn void AbstractInputMethod::selectionListChanged(int type)
+
+ The input method emits this signal when the contents of the selection list
+ has changed. The \a type parameter specifies which selection list has
+ changed.
+*/
+
+/*!
+ \fn void AbstractInputMethod::selectionListActiveItemChanged(int type, int index)
+
+ The input method emits this signal when the current \a index has changed
+ in the selection list identified by \a type.
+*/
diff --git a/src/virtualkeyboard/abstractinputmethod.h b/src/virtualkeyboard/abstractinputmethod.h
new file mode 100644
index 00000000..8ea91559
--- /dev/null
+++ b/src/virtualkeyboard/abstractinputmethod.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef ABSTRACTINPUTMETHOD_H
+#define ABSTRACTINPUTMETHOD_H
+
+#include "declarativeinputengine.h"
+#include "declarativeselectionlistmodel.h"
+
+class AbstractInputMethodPrivate
+{
+public:
+ virtual ~AbstractInputMethodPrivate() {}
+ DeclarativeInputEngine *inputEngine;
+};
+
+class AbstractInputMethod : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(AbstractInputMethod)
+ Q_PROPERTY(QString className READ className CONSTANT)
+
+protected:
+ AbstractInputMethod(AbstractInputMethodPrivate *d_ptr, QObject *parent = 0);
+public:
+ explicit AbstractInputMethod(QObject *parent = 0);
+ ~AbstractInputMethod();
+
+ QString className() const;
+ DeclarativeInputContext *inputContext() const;
+ DeclarativeInputEngine *inputEngine() const;
+
+ virtual QList<DeclarativeInputEngine::InputMode> inputModes(const QString &locale) = 0;
+ virtual bool setInputMode(const QString &locale, DeclarativeInputEngine::InputMode inputMode) = 0;
+ virtual bool setTextCase(DeclarativeInputEngine::TextCase textCase) = 0;
+
+ virtual bool keyEvent(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers) = 0;
+
+ virtual QList<DeclarativeSelectionListModel::Type> selectionLists();
+ virtual int selectionListItemCount(DeclarativeSelectionListModel::Type type);
+ virtual QVariant selectionListData(DeclarativeSelectionListModel::Type type, int index, int role);
+ virtual void selectionListItemSelected(DeclarativeSelectionListModel::Type type, int index);
+
+signals:
+ void selectionListChanged(int type);
+ void selectionListActiveItemChanged(int type, int index);
+
+public slots:
+ virtual void reset();
+ virtual void update();
+
+private:
+ void setInputEngine(DeclarativeInputEngine *inputEngine);
+
+ friend class DeclarativeInputEngine;
+
+protected:
+ QScopedPointer<AbstractInputMethodPrivate> d_ptr;
+};
+
+#endif
diff --git a/src/virtualkeyboard/abstractinputpanel.cpp b/src/virtualkeyboard/abstractinputpanel.cpp
new file mode 100644
index 00000000..da77a975
--- /dev/null
+++ b/src/virtualkeyboard/abstractinputpanel.cpp
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "abstractinputpanel.h"
+
+/*!
+ \class AbstractInputPanel
+
+ \inmodule InputFramework
+
+ \brief Base class for an input panel.
+
+ Input panel is a container for InputPanel qml view.
+
+ The virtual keyboard currently supports the following input panels:
+ \list
+ \li AppInputPanel Input panel type that is integrated directly into the
+ application.
+ \li XcbInputPanel Input panel type for X-windowing system.
+ \endlist
+*/
+
+/*!
+ Creates an input panel container with \a parent but does not construct
+ the view. The view is explicitly constructed by the
+ AbstractInputPanel::createView() method.
+*/
+AbstractInputPanel::AbstractInputPanel(QObject *parent) :
+ QObject(parent)
+{
+}
+
+/*!
+ Destroys the input panel container.
+*/
+AbstractInputPanel::~AbstractInputPanel()
+{
+}
+
+/*!
+ \fn void AbstractInputPanel::show() = 0
+
+ Shows the input panel.
+*/
+
+/*!
+ \fn void AbstractInputPanel::hide() = 0
+
+ Hides the input panel.
+*/
+
+/*!
+ \fn bool AbstractInputPanel::isVisible() const = 0
+
+ Returns \c true if the input panel is currently visible.
+*/
+
+/*!
+ This method adjusts the input rectangle of the input panel.
+ The \a inputRect specifies the area in which mouse input is accepted.
+*/
+void AbstractInputPanel::setInputRect(const QRect &inputRect)
+{
+ Q_UNUSED(inputRect);
+}
+
+/*!
+ Creates the view of the input panel. If the view is already created,
+ this method does nothing.
+*/
+void AbstractInputPanel::createView()
+{
+}
+
+/*!
+ \fn void AbstractInputPanel::destroyView()
+
+ Destroys the view of the input panel.
+*/
+void AbstractInputPanel::destroyView()
+{
+}
diff --git a/src/virtualkeyboard/abstractinputpanel.h b/src/virtualkeyboard/abstractinputpanel.h
new file mode 100644
index 00000000..7b85def2
--- /dev/null
+++ b/src/virtualkeyboard/abstractinputpanel.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef ABSTRACTINPUTPANEL_H
+#define ABSTRACTINPUTPANEL_H
+
+#include <QObject>
+
+class AbstractInputPanel : public QObject
+{
+ Q_OBJECT
+public:
+ explicit AbstractInputPanel(QObject *parent = 0);
+ ~AbstractInputPanel();
+
+ virtual void show() = 0;
+ virtual void hide() = 0;
+ virtual bool isVisible() const = 0;
+
+ virtual void setInputRect(const QRect &inputRect);
+
+public slots:
+ virtual void createView();
+ virtual void destroyView();
+};
+
+#endif // ABSTRACTINPUTPANEL_H
diff --git a/src/virtualkeyboard/appinputpanel.cpp b/src/virtualkeyboard/appinputpanel.cpp
new file mode 100644
index 00000000..cf929452
--- /dev/null
+++ b/src/virtualkeyboard/appinputpanel.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "appinputpanel.h"
+
+class AppInputPanelPrivate
+{
+public:
+ bool visible;
+};
+
+AppInputPanel::AppInputPanel(QObject *parent) :
+ AbstractInputPanel(parent),
+ d_ptr(new AppInputPanelPrivate())
+{
+}
+
+AppInputPanel::~AppInputPanel()
+{
+}
+
+void AppInputPanel::show()
+{
+ Q_D(AppInputPanel);
+ if (!d->visible) {
+ d->visible = true;
+ }
+}
+
+void AppInputPanel::hide()
+{
+ Q_D(AppInputPanel);
+ if (d->visible) {
+ d->visible = false;
+ }
+}
+
+bool AppInputPanel::isVisible() const
+{
+ Q_D(const AppInputPanel);
+ return d->visible;
+}
diff --git a/src/virtualkeyboard/appinputpanel.h b/src/virtualkeyboard/appinputpanel.h
new file mode 100644
index 00000000..346cc670
--- /dev/null
+++ b/src/virtualkeyboard/appinputpanel.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef APPINPUTPANEL_H
+#define APPINPUTPANEL_H
+
+#include "abstractinputpanel.h"
+
+class AppInputPanelPrivate;
+
+class AppInputPanel : public AbstractInputPanel
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(AppInputPanel)
+public:
+ explicit AppInputPanel(QObject *parent = 0);
+ ~AppInputPanel();
+
+ void show();
+ void hide();
+ bool isVisible() const;
+
+private:
+ QScopedPointer<AppInputPanelPrivate> d_ptr;
+};
+
+#endif // APPINPUTPANEL_H
diff --git a/src/virtualkeyboard/content/InputPanel.qml b/src/virtualkeyboard/content/InputPanel.qml
new file mode 100644
index 00000000..e8966f4a
--- /dev/null
+++ b/src/virtualkeyboard/content/InputPanel.qml
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import "components"
+
+/*!
+ \qmltype InputPanel
+ \inqmlmodule QtQuick.Enterprise.VirtualKeyboard
+
+ \brief Provides the virtual keyboard UI.
+
+ The keyboard size is automatically calculated from the available
+ width, i.e. the keyboard maintains the aspect ratio specified by the current
+ style. Therefore the application should only set the \c width and \c y
+ coordinates of the InputPanel, and not the height.
+*/
+
+Item {
+ height: keyboard.height
+ Keyboard {
+ id: keyboard
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ }
+ AutoScroller { }
+ MouseArea {
+ z: -1
+ anchors.fill: keyboard
+ }
+}
diff --git a/src/virtualkeyboard/content/components/AlternativeKeys.qml b/src/virtualkeyboard/content/components/AlternativeKeys.qml
new file mode 100644
index 00000000..2768452f
--- /dev/null
+++ b/src/virtualkeyboard/content/components/AlternativeKeys.qml
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Enterprise.VirtualKeyboard 1.0
+
+Item {
+ property bool active: listView.currentIndex != -1
+ property int highlightIndex: -1
+ property int keyCode
+ property point origin
+ property bool uppercased: keyboard.uppercased
+ signal clicked
+
+ z: 1
+ visible: active
+ anchors.fill: parent
+
+ ListModel {
+ id: listModel
+ }
+
+ ListView {
+ id: listView
+ spacing: 0
+ model: listModel
+ delegate: keyboard.style.alternateKeysListDelegate
+ highlight: keyboard.style.alternateKeysListHighlight
+ highlightMoveDuration: 0
+ orientation: ListView.Horizontal
+ height: keyboard.style.alternateKeysListItemHeight
+ x: origin.x
+ y: origin.y - height - keyboard.style.alternateKeysListBottomMargin
+ }
+
+ Loader {
+ id: backgroundLoader
+ sourceComponent: keyboard.style.alternateKeysListBackground
+ anchors.fill: listView
+ z: -1
+ Binding {
+ target: backgroundLoader.item
+ property: "currentItemHighlight"
+ value: listView.currentIndex === highlightIndex
+ when: backgroundLoader.item !== null && listView.currentIndex != -1
+ }
+ }
+
+ onClicked: {
+ if (active) {
+ var activeKey = listView.model.get(listView.currentIndex)
+ InputContext.inputEngine.virtualKeyClick(keyCode, activeKey.text,
+ uppercased ? Qt.ShiftModifier : 0)
+ }
+ }
+
+ function open(key, originX, originY) {
+ keyCode = key.key
+ var alternativeKeys = key.alternativeKeys
+ if (alternativeKeys.length > 0) {
+ for (var i = 0; i < alternativeKeys.length; i++) {
+ listModel.append({ "text": uppercased ? alternativeKeys[i].toUpperCase() : alternativeKeys[i] })
+ }
+ listView.width = keyboard.style.alternateKeysListItemWidth * listModel.count
+ listView.forceLayout()
+ highlightIndex = alternativeKeys.indexOf(key.text)
+ if (highlightIndex === -1) {
+ console.log("AlternativeKeys: active key \"" + key.text + "\" not found in alternativeKeys \"" + alternativeKeys + ".\"")
+ highlightIndex = 0
+ }
+ listView.currentIndex = highlightIndex
+ var currentItemOffset = (listView.currentIndex + 0.5) * keyboard.style.alternateKeysListItemWidth
+ origin = Qt.point(Math.min(Math.max(keyboard.style.alternateKeysListLeftMargin, originX - currentItemOffset), width - listView.width - keyboard.style.alternateKeysListRightMargin), originY)
+ if (backgroundLoader.item && backgroundLoader.item.hasOwnProperty("currentItemOffset")) {
+ backgroundLoader.item.currentItemOffset = currentItemOffset
+ }
+ }
+ return active
+ }
+
+ function move(mouseX) {
+ var newIndex = listView.indexAt(Math.max(1, Math.min(listView.width - 1, mapToItem(listView, mouseX, 0).x)), 1)
+ if (newIndex !== listView.currentIndex) {
+ listView.currentIndex = newIndex
+ }
+ }
+
+ function close() {
+ listModel.clear()
+ }
+}
diff --git a/src/virtualkeyboard/content/components/AutoScroller.qml b/src/virtualkeyboard/content/components/AutoScroller.qml
new file mode 100644
index 00000000..97f631a1
--- /dev/null
+++ b/src/virtualkeyboard/content/components/AutoScroller.qml
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Enterprise.VirtualKeyboard 1.0
+
+Item {
+
+ property var innerFlickable
+ property var outerFlickable
+ property var inputItem: InputContext.inputItem
+
+ onInputItemChanged: {
+ if (inputItem !== null) {
+ var parent_ = inputItem.parent
+ while (parent_) {
+ if (parent_.maximumFlickVelocity) {
+ if (innerFlickable) {
+ outerFlickable = parent_
+ break
+ } else {
+ innerFlickable = parent_
+ }
+ }
+ parent_ = parent_.parent
+ }
+ delayedLoading.triggered()
+ }
+ }
+
+ function ensureVisible(flickable) {
+ if (Qt.inputMethod.visible && inputItem && flickable && flickable.visible && flickable.interactive) {
+
+ var verticallyFlickable = (flickable.flickableDirection === Flickable.HorizontalAndVerticalFlick || flickable.flickableDirection === Flickable.VerticalFlick
+ || (flickable.flickableDirection === Flickable.AutoFlickDirection && flickable.contentHeight > flickable.height))
+ var horizontallyFlickable = (flickable.flickableDirection === Flickable.HorizontalAndVerticalFlick || flickable.flickableDirection === Flickable.HorizontalFlick
+ || (flickable.flickableDirection === Flickable.AutoFlickDirection && flickable.contentWidth > flickable.width))
+
+ if ((!verticallyFlickable && !horizontallyFlickable) || !inputItem.hasOwnProperty("cursorRectangle"))
+ return
+
+ var cursorRectangle = flickable.contentItem.mapFromItem(inputItem, inputItem.cursorRectangle.x, inputItem.cursorRectangle.y)
+
+ var oldContentY = flickable.contentY
+ if (verticallyFlickable) {
+ var scrollMarginVertical = (flickable && flickable.scrollMarginVertical) ? flickable.scrollMarginVertical : 10
+ if (flickable.contentY >= cursorRectangle.y - scrollMarginVertical)
+ flickable.contentY = Math.max(0, cursorRectangle.y - scrollMarginVertical)
+ else if (flickable.contentY + flickable.height <= cursorRectangle.y + inputItem.cursorRectangle.height + scrollMarginVertical)
+ flickable.contentY = Math.min(flickable.contentHeight - flickable.height, cursorRectangle.y + inputItem.cursorRectangle.height - flickable.height + scrollMarginVertical)
+ }
+ if (horizontallyFlickable) {
+ var scrollMarginHorizontal = (flickable && flickable.scrollMarginHorizontal) ? flickable.scrollMarginHorizontal : 10
+ if (flickable.contentX >= cursorRectangle.x - scrollMarginHorizontal)
+ flickable.contentX = Math.max(0, cursorRectangle.x - scrollMarginHorizontal)
+ else if (flickable.contentX + flickable.width <= cursorRectangle.x + inputItem.cursorRectangle.width + scrollMarginHorizontal)
+ flickable.contentX = Math.min(flickable.contentWidth - flickable.width, cursorRectangle.x + inputItem.cursorRectangle.width - flickable.width + scrollMarginHorizontal)
+ }
+ }
+ }
+ Timer {
+ id: delayedLoading
+ interval: 10
+ onTriggered: {
+ ensureVisible(innerFlickable)
+ ensureVisible(outerFlickable)
+ }
+ }
+ Connections {
+ ignoreUnknownSignals: true
+ target: InputContext.inputItem && Qt.inputMethod.animating ? Qt.inputMethod : null
+ onKeyboardRectangleChanged: delayedLoading.triggered()
+ }
+ Connections {
+ ignoreUnknownSignals: true
+ target: InputContext.inputItem && InputContext.inputItem.activeFocus ? InputContext.inputItem : null
+ onCursorRectangleChanged: delayedLoading.triggered()
+ }
+}
diff --git a/src/virtualkeyboard/content/components/BackspaceKey.qml b/src/virtualkeyboard/content/components/BackspaceKey.qml
new file mode 100644
index 00000000..7da7a0f3
--- /dev/null
+++ b/src/virtualkeyboard/content/components/BackspaceKey.qml
@@ -0,0 +1,26 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+BaseKey {
+ key: Qt.Key_Backspace
+ repeat: true
+ functionKey: true
+ keyPanelDelegate: keyboard.style ? keyboard.style.backspaceKeyPanel : undefined
+}
diff --git a/src/virtualkeyboard/content/components/BaseKey.qml b/src/virtualkeyboard/content/components/BaseKey.qml
new file mode 100644
index 00000000..e9812db0
--- /dev/null
+++ b/src/virtualkeyboard/content/components/BaseKey.qml
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Layouts 1.0
+
+Item {
+ id: keyItem
+
+ property real weight: parent.keyWeight
+ property string text: ""
+ property string displayText: text
+ property var alternativeKeys: []
+ property int key: Qt.Key_unknown
+ property bool active: false
+ property bool repeat: false
+ property bool highlighted: false
+ property bool functionKey: false
+ property bool showPreview: !functionKey
+ property bool enabled: true
+ property bool pressed: enabled && active
+ property bool uppercased: keyboard.uppercased
+ property alias keyPanelDelegate: keyPanel.sourceComponent
+
+ Layout.minimumWidth: keyPanel.implicitWidth
+ Layout.minimumHeight: keyPanel.implicitHeight
+ Layout.preferredWidth: weight
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ Loader {
+ id: keyPanel
+ anchors.fill: parent
+ onStatusChanged: if (status == Loader.Ready) keyPanel.item.control = keyItem
+ }
+
+ signal clicked
+}
diff --git a/src/virtualkeyboard/content/components/ChangeLanguageKey.qml b/src/virtualkeyboard/content/components/ChangeLanguageKey.qml
new file mode 100644
index 00000000..94a7dba1
--- /dev/null
+++ b/src/virtualkeyboard/content/components/ChangeLanguageKey.qml
@@ -0,0 +1,26 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+BaseKey {
+ functionKey: true
+ displayText: keyboard.locale.split("_")[0]
+ keyPanelDelegate: keyboard.style ? keyboard.style.languageKeyPanel : undefined
+ onClicked: keyboard.changeInputLanguage()
+}
diff --git a/src/virtualkeyboard/content/components/CharacterPreviewBubble.qml b/src/virtualkeyboard/content/components/CharacterPreviewBubble.qml
new file mode 100644
index 00000000..df6e5ae1
--- /dev/null
+++ b/src/virtualkeyboard/content/components/CharacterPreviewBubble.qml
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+ property bool active
+ property var activeKey: keyboard.activeKey
+
+ visible: active && activeKey !== undefined && activeKey !== null && activeKey.showPreview
+ z: 1
+
+ Loader {
+ id: characterPreview
+ anchors.fill: parent
+ sourceComponent: keyboard.style.characterPreviewDelegate
+ }
+
+ onActiveKeyChanged: {
+ if (activeKey && characterPreview.item !== null) {
+ characterPreview.item.text = keyboard.uppercased ? activeKey.text.toUpperCase() : activeKey.text
+ width = activeKey.width
+ height = activeKey.height
+ var position = keyboard.mapFromItem(activeKey, 0, 0)
+ x = position.x
+ y = position.y - height - keyboard.style.characterPreviewMargin
+ }
+ }
+}
diff --git a/src/virtualkeyboard/content/components/EnterKey.qml b/src/virtualkeyboard/content/components/EnterKey.qml
new file mode 100644
index 00000000..e0f528c6
--- /dev/null
+++ b/src/virtualkeyboard/content/components/EnterKey.qml
@@ -0,0 +1,30 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Enterprise.VirtualKeyboard 1.0
+
+BaseKey {
+ text: "\n"
+ displayText: InputContext.inputItem && InputContext.inputItem.enterKeyText !== undefined ? InputContext.inputItem.enterKeyText : ""
+ key: Qt.Key_Return
+ functionKey: true
+ highlighted: enabled && displayText.length > 0
+ enabled: InputContext.inputItem && InputContext.inputItem.enterKeyEnabled !== undefined ? InputContext.inputItem.enterKeyEnabled : true
+ keyPanelDelegate: keyboard.style ? keyboard.style.enterKeyPanel : undefined
+}
diff --git a/src/virtualkeyboard/content/components/FillerKey.qml b/src/virtualkeyboard/content/components/FillerKey.qml
new file mode 100644
index 00000000..4fb990b8
--- /dev/null
+++ b/src/virtualkeyboard/content/components/FillerKey.qml
@@ -0,0 +1,23 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+BaseKey {
+ showPreview: false
+}
diff --git a/src/virtualkeyboard/content/components/HideKeyboardKey.qml b/src/virtualkeyboard/content/components/HideKeyboardKey.qml
new file mode 100644
index 00000000..3d76c243
--- /dev/null
+++ b/src/virtualkeyboard/content/components/HideKeyboardKey.qml
@@ -0,0 +1,26 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Enterprise.VirtualKeyboard 1.0
+
+BaseKey {
+ functionKey: true
+ onClicked: InputContext.hideInputPanel()
+ keyPanelDelegate: keyboard.style ? keyboard.style.hideKeyPanel : undefined
+}
diff --git a/src/virtualkeyboard/content/components/Key.qml b/src/virtualkeyboard/content/components/Key.qml
new file mode 100644
index 00000000..cc10ac9f
--- /dev/null
+++ b/src/virtualkeyboard/content/components/Key.qml
@@ -0,0 +1,24 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+BaseKey {
+ id: keyItem
+ keyPanelDelegate: keyboard.style ? keyboard.style.keyPanel : undefined
+}
diff --git a/src/virtualkeyboard/content/components/Keyboard.qml b/src/virtualkeyboard/content/components/Keyboard.qml
new file mode 100644
index 00000000..726a5f38
--- /dev/null
+++ b/src/virtualkeyboard/content/components/Keyboard.qml
@@ -0,0 +1,313 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Layouts 1.0
+import QtQuick.Enterprise.VirtualKeyboard 1.0
+import QtQuick.Enterprise.VirtualKeyboard.Styles 1.0
+import Qt.labs.folderlistmodel 2.0
+
+Item {
+ id: keyboard
+
+ property alias style: styleLoader.item
+ property var activeKey: undefined
+ property int localeIndex: 1
+ property string locale: layoutsModel.count > 0 ? layoutsModel.get(localeIndex, "fileBaseName") : "en_GB"
+ property string layout: keyboard.symbolMode && !keyboard.numberMode ? "symbols_"+keyboard.locale : (keyboard.numberMode ? "numbers" : keyboard.locale)
+ property bool active: Qt.inputMethod.visible
+ property bool uppercased: uppercaseOnly ? true : (lowercaseOnly ? false : InputContext.shift || InputContext.capsLock)
+ property bool uppercaseOnly: InputContext.inputMethodHints & Qt.ImhUppercaseOnly
+ property bool lowercaseOnly: InputContext.inputMethodHints & Qt.ImhLowercaseOnly
+ property bool numberMode: InputContext.inputMethodHints & (Qt.ImhDialableCharactersOnly | Qt.ImhFormattedNumbersOnly | Qt.ImhDigitsOnly)
+ property bool symbolMode
+ property bool shiftChanged: true
+ property var defaultInputMethod: initDefaultInputMethod()
+ property var plainInputMethod: PlainInputMethod {}
+ property int defaultInputMode: InputEngine.Latin
+
+ function initDefaultInputMethod() {
+ try {
+ return Qt.createQmlObject('import QtQuick 2.0; import QtQuick.Enterprise.VirtualKeyboard 1.0; HunspellInputMethod {}', keyboard, "defaultInputMethod")
+ } catch (e) { }
+ return plainInputMethod
+ }
+
+ width: keyboardBackground.width
+ height: wordCandidateView.height + keyboardBackground.height
+ onLocaleChanged: InputContext.locale = locale
+ onUppercasedChanged: shiftChanged = true
+
+ function changeInputLanguage() {
+ localeIndex = (localeIndex+1) % layoutsModel.count
+ }
+
+ Connections {
+ target: InputContext
+ onFocusEditorChanged: {
+ keyboard.symbolMode = false
+ }
+ }
+ Connections {
+ target: InputContext.inputEngine
+ onVirtualKeyClicked: {
+ if (key === Qt.Key_Space) {
+ var surroundingText = InputContext.surroundingText.trim()
+ if (InputContext.shiftHandler.sentenceEndingCharacters.indexOf(surroundingText.charAt(surroundingText.length-1)) >= 0)
+ keyboard.symbolMode = false
+ }
+ }
+ }
+ FolderListModel {
+ id: layoutsModel
+ folder: "../layouts"
+ nameFilters: ["??_??.qml"]
+ }
+ AlternativeKeys { id: alternativeKeys }
+ Timer {
+ id: releaseInaccuracyTimer
+ interval: 500
+ onTriggered: {
+ if (keyboardMouse.pressed && !alternativeKeys.active && !keyboardMouse.dragSymbolMode) {
+ var key = keyboardMouse.keyOnMouse(keyboardMouse.mouseX, keyboardMouse.mouseY)
+ if (key !== keyboard.activeKey) {
+ InputContext.inputEngine.virtualKeyCancel()
+ keyboardMouse.setActiveKey(key)
+ keyboardMouse.press(key)
+ }
+ }
+ }
+ }
+ CharacterPreviewBubble { active: keyboardMouse.pressed && !alternativeKeys.active }
+ Binding {
+ target: InputContext
+ property: "keyboardRectangle"
+ value: Qt.rect(keyboard.x, keyboard.y, keyboard.width, keyboard.height)
+ when: !InputContext.animating
+ }
+ Loader {
+ id: styleLoader
+ source: "qrc:/style.qml"
+ Binding {
+ target: styleLoader.item
+ property: "keyboardHeight"
+ value: keyboardInnerContainer.height
+ when: keyboardLayoutLoader.item !== null
+ }
+ }
+ ListView {
+ id: wordCandidateView
+ clip: true
+ height: Math.round(style.selectionListHeight)
+ anchors.left: parent.left
+ anchors.top: parent.top
+ anchors.right: parent.right
+ spacing: 0
+ orientation: ListView.Horizontal
+ delegate: style.selectionListDelegate
+ highlight: style.selectionListHighlight
+ highlightMoveDuration: 0
+ model: InputContext.inputEngine.wordCandidateListModel
+ Connections {
+ target: wordCandidateView.model ? wordCandidateView.model : null
+ onActiveItemChanged: wordCandidateView.currentIndex = index
+ }
+ Loader {
+ sourceComponent: style.selectionListBackground
+ anchors.fill: parent
+ z: -1
+ }
+ }
+
+ Loader {
+ id: keyboardBackground
+ z: -1
+ anchors.left: parent.left
+ anchors.top: wordCandidateView.bottom
+ anchors.right: parent.right
+ height: keyboardInnerContainer.height
+ sourceComponent: style.keyboardBackground
+
+ Item {
+ id: keyboardInnerContainer
+ z: 1
+ width: Math.round(keyboardBackground.width)
+ height: Math.round(style.keyboardDesignHeight * width / style.keyboardDesignWidth)
+ anchors.horizontalCenter: parent.horizontalCenter
+
+ Loader {
+ id: keyboardLayoutLoader
+
+ anchors.fill: parent
+ anchors.leftMargin: Math.round(style.keyboardRelativeLeftMargin * parent.width)
+ anchors.rightMargin: Math.round(style.keyboardRelativeRightMargin * parent.width)
+ anchors.topMargin: Math.round(style.keyboardRelativeTopMargin * parent.height)
+ anchors.bottomMargin: Math.round(style.keyboardRelativeBottomMargin * parent.height)
+
+ source: layoutsModel.folder + "/" + keyboard.layout +".qml"
+ onItemChanged: if (keyboardLayoutLoader.item) keyboard.updateInputMethod()
+
+ MouseArea {
+ id: keyboardMouse
+
+ property var initialKey
+ property bool dragSymbolMode
+ property real releaseMargin: 18
+
+ anchors.fill: keyboardLayoutLoader
+
+ function press(key) {
+ if (key && key.enabled) {
+ if (key.key !== Qt.Key_unknown || key.text.length > 0)
+ InputContext.inputEngine.virtualKeyPress(key.key, keyboard.uppercased ? key.text.toUpperCase() : key.text, keyboard.uppercased ? Qt.ShiftModifier : 0, key.repeat)
+ }
+ }
+ function release(key) {
+ if (key && key.enabled) {
+ if (key.key !== Qt.Key_unknown || key.text.length > 0)
+ InputContext.inputEngine.virtualKeyRelease(key.key, keyboard.uppercased ? key.text.toUpperCase() : key.text, keyboard.uppercased ? Qt.ShiftModifier : 0)
+ key.clicked()
+ }
+ }
+ function click(key) {
+ if (key && key.enabled) {
+ if (key.key !== Qt.Key_unknown || key.text.length > 0)
+ InputContext.inputEngine.virtualKeyClick(key.key, keyboard.uppercased ? key.text.toUpperCase() : key.text, keyboard.uppercased ? Qt.ShiftModifier : 0)
+ key.clicked()
+ }
+ }
+ function setActiveKey(activeKey) {
+ if (keyboard.activeKey) {
+ keyboard.activeKey.active = false
+ }
+ keyboard.activeKey = activeKey
+ if (keyboard.activeKey) {
+ keyboard.activeKey.active = true
+ }
+ }
+ function keyOnMouse(mx, my) {
+ var parentItem = keyboardLayoutLoader
+ var child = parentItem.childAt(mx, my)
+ while (child !== null) {
+ var position = parentItem.mapToItem(child, mx, my)
+ mx = position.x; my = position.y
+ parentItem = child
+ child = parentItem.childAt(mx, my)
+ if (child && child.key !== undefined)
+ return child
+ }
+ return undefined
+ }
+ function hitInitialKey(mouseX, mouseY, margin) {
+ if (!initialKey)
+ return false
+ var position = initialKey.mapFromItem(keyboardMouse, mouseX, mouseY)
+ return (position.x > -margin
+ && position.y > -margin
+ && position.x < initialKey.width + margin
+ && position.y < initialKey.height + margin)
+ }
+ function reset() {
+ releaseInaccuracyTimer.stop()
+ alternativeKeys.close()
+ setActiveKey(undefined)
+ if (dragSymbolMode) {
+ keyboard.symbolMode = false
+ dragSymbolMode = false
+ }
+ }
+
+ onPressed: {
+ releaseInaccuracyTimer.start()
+ initialKey = keyOnMouse(mouseX, mouseY)
+ setActiveKey(initialKey)
+ press(initialKey)
+ }
+ onPositionChanged: {
+ if (alternativeKeys.active) {
+ alternativeKeys.move(mapToItem(alternativeKeys, mouseX, 0).x)
+ } else {
+ var key
+ if (releaseInaccuracyTimer.running) {
+ if (hitInitialKey(mouseX, mouseY, releaseMargin)) {
+ key = initialKey
+ } else if (initialKey) {
+ releaseInaccuracyTimer.stop()
+ initialKey = undefined
+ }
+ }
+ if (key === undefined) {
+ key = keyOnMouse(mouseX, mouseY)
+ }
+ if (key !== keyboard.activeKey) {
+ InputContext.inputEngine.virtualKeyCancel()
+ setActiveKey(key)
+ press(key)
+ }
+ }
+ }
+ onPressAndHold: {
+ if (keyboard.activeKey && keyboard.activeKey === initialKey) {
+ var origin = keyboard.mapFromItem(activeKey, activeKey.width / 2, 0)
+ if (alternativeKeys.open(keyboard.activeKey, origin.x, origin.y)) {
+ InputContext.inputEngine.virtualKeyCancel()
+ } else if (keyboard.activeKey.key === Qt.Key_Context1) {
+ InputContext.inputEngine.virtualKeyCancel()
+ dragSymbolMode = true
+ keyboard.symbolMode = true
+ }
+ }
+ }
+ onClicked: {}
+ onReleased: {
+ if (alternativeKeys.active) {
+ alternativeKeys.clicked()
+ } else {
+ release(keyboard.activeKey)
+ }
+ reset()
+ }
+ onCanceled: reset()
+ }
+ }
+ }
+ }
+ Connections {
+ target: InputContext
+ onInputMethodHintsChanged: updateInputMethod()
+ }
+ function updateInputMethod() {
+ var inputMethod = keyboard.defaultInputMethod
+ var inputMode = keyboard.defaultInputMode
+ if (keyboardLayoutLoader.item) {
+ if (keyboardLayoutLoader.item.inputMethod) {
+ inputMethod = keyboardLayoutLoader.item.inputMethod
+ }
+ if (keyboardLayoutLoader.item.inputMode) {
+ inputMode = keyboardLayoutLoader.item.inputMode
+ }
+ }
+ if (InputContext.inputMethodHints & (Qt.ImhHiddenText | Qt.ImhSensitiveData | Qt.ImhNoPredictiveText)) {
+ inputMethod = keyboard.plainInputMethod
+ }
+ if (inputMethod !== undefined) {
+ InputContext.inputEngine.inputMethod = inputMethod
+ InputContext.inputEngine.inputMode = inputMode
+ }
+ }
+}
diff --git a/src/virtualkeyboard/content/components/KeyboardColumn.qml b/src/virtualkeyboard/content/components/KeyboardColumn.qml
new file mode 100644
index 00000000..b4747b60
--- /dev/null
+++ b/src/virtualkeyboard/content/components/KeyboardColumn.qml
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Layouts 1.0
+
+ColumnLayout {
+ property real keyWeight: parent ? parent.keyWeight : undefined
+ spacing: 0
+}
diff --git a/src/virtualkeyboard/content/components/KeyboardLayout.qml b/src/virtualkeyboard/content/components/KeyboardLayout.qml
new file mode 100644
index 00000000..b154f227
--- /dev/null
+++ b/src/virtualkeyboard/content/components/KeyboardLayout.qml
@@ -0,0 +1,28 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Layouts 1.0
+import QtQuick.Enterprise.VirtualKeyboard 1.0
+
+ColumnLayout {
+ property var inputMethod
+ property int inputMode: InputEngine.Latin
+ property real keyWeight
+ spacing: 0
+}
diff --git a/src/virtualkeyboard/content/components/KeyboardRow.qml b/src/virtualkeyboard/content/components/KeyboardRow.qml
new file mode 100644
index 00000000..22760d44
--- /dev/null
+++ b/src/virtualkeyboard/content/components/KeyboardRow.qml
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Layouts 1.0
+
+RowLayout {
+ property real keyWeight: parent ? parent.keyWeight : undefined
+ spacing: 0
+}
diff --git a/src/virtualkeyboard/content/components/MultitapInputMethod.qml b/src/virtualkeyboard/content/components/MultitapInputMethod.qml
new file mode 100644
index 00000000..1a8d392a
--- /dev/null
+++ b/src/virtualkeyboard/content/components/MultitapInputMethod.qml
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Enterprise.VirtualKeyboard 1.0
+
+InputMethod {
+ property string multitapSequence
+ property int multitapIndex: -1
+
+ onMultitapSequenceChanged: selectionListChanged(SelectionListModel.WordCandidateList)
+ onMultitapIndexChanged: selectionListActiveItemChanged(SelectionListModel.WordCandidateList, multitapIndex)
+
+ property variant multiTapTimer: Timer {
+ interval: 1200
+ onTriggered: {
+ update()
+ }
+ }
+
+ function inputModes(locale) {
+ return [InputEngine.Latin, InputEngine.Numeric, InputEngine.Dialable];
+ }
+
+ function setInputMode(locale, inputMode) {
+ return true
+ }
+
+ function setTextCase(textCase) {
+ return true
+ }
+
+ function reset() {
+ multiTapTimer.stop()
+ multitapIndex = -1
+ multitapSequence = ""
+ }
+
+ function update() {
+ multiTapTimer.stop()
+ multitapIndex = -1
+ multitapSequence = ""
+ if (inputContext !== null && inputContext.preeditText.length > 0) {
+ inputContext.commit()
+ }
+ }
+
+ function keyEvent(key, text, modifiers) {
+ var accept = false
+ switch (key) {
+ case Qt.Key_Enter:
+ case Qt.Key_Return:
+ case Qt.Key_Tab:
+ update()
+ break
+ case Qt.Key_Backspace:
+ if (inputContext.preeditText.length > 0) {
+ inputContext.clear()
+ update()
+ accept = true
+ }
+ break
+ default:
+ if (key !== inputEngine.previousKey) {
+ update()
+ }
+ multitapSequence = text
+ if (multitapSequence.length > 1) {
+ multitapIndex = multiTapTimer.running ? (multitapIndex + 1) % multitapSequence.length : 0
+ inputContext.preeditText = multitapSequence.charAt(multitapIndex)
+ multiTapTimer.restart()
+ } else {
+ inputContext.commit(text)
+ }
+ accept = true
+ break
+ }
+ return accept;
+ }
+
+ function selectionLists() {
+ return [SelectionListModel.WordCandidateList];
+ }
+
+ function selectionListItemCount(type) {
+ return multitapSequence.length > 1 ? multitapSequence.length : 0
+ }
+
+ function selectionListData(type, index, role) {
+ var result = null
+ switch (role) {
+ case SelectionListModel.DisplayRole:
+ result = multitapSequence.charAt(index)
+ break
+ default:
+ break
+ }
+ return result
+ }
+
+ function selectionListItemSelected(type, index) {
+ multitapIndex = index
+ inputContext.preeditText = multitapSequence.charAt(multitapIndex)
+ update()
+ }
+}
diff --git a/src/virtualkeyboard/content/components/NumberKey.qml b/src/virtualkeyboard/content/components/NumberKey.qml
new file mode 100644
index 00000000..5c2b3c72
--- /dev/null
+++ b/src/virtualkeyboard/content/components/NumberKey.qml
@@ -0,0 +1,23 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Key {
+ showPreview: false
+}
diff --git a/src/virtualkeyboard/content/components/ShiftKey.qml b/src/virtualkeyboard/content/components/ShiftKey.qml
new file mode 100644
index 00000000..372b69c3
--- /dev/null
+++ b/src/virtualkeyboard/content/components/ShiftKey.qml
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Enterprise.VirtualKeyboard 1.0
+
+BaseKey {
+ id: shiftKey
+ key: Qt.Key_Shift
+ enabled: !keyboard.uppercaseOnly && !keyboard.lowercaseOnly
+ visible: enabled
+ highlighted: InputContext.capsLock
+ functionKey: true
+ keyPanelDelegate: keyboard.style ? keyboard.style.shiftKeyPanel : undefined
+ property bool capsLock: InputContext.capsLock
+ property bool shift: InputContext.shift
+ onClicked: {
+ if (InputContext.inputMethodHints & Qt.ImhNoAutoUppercase) {
+ InputContext.capsLock = !InputContext.capsLock
+ InputContext.shift = !InputContext.shift
+ } else {
+ InputContext.capsLock = !InputContext.capsLock && (InputContext.shift && !keyboard.shiftChanged)
+ InputContext.shift = InputContext.capsLock || !InputContext.shift ? true : false
+ keyboard.shiftChanged = false
+ }
+ }
+}
diff --git a/src/virtualkeyboard/content/components/SpaceKey.qml b/src/virtualkeyboard/content/components/SpaceKey.qml
new file mode 100644
index 00000000..0165a388
--- /dev/null
+++ b/src/virtualkeyboard/content/components/SpaceKey.qml
@@ -0,0 +1,28 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Key {
+ text: " "
+ displayText: ""
+ repeat: true
+ showPreview: false
+ key: Qt.Key_Space
+ keyPanelDelegate: keyboard.style ? keyboard.style.spaceKeyPanel : undefined
+}
diff --git a/src/virtualkeyboard/content/components/SymbolModeKey.qml b/src/virtualkeyboard/content/components/SymbolModeKey.qml
new file mode 100644
index 00000000..e4efcfa1
--- /dev/null
+++ b/src/virtualkeyboard/content/components/SymbolModeKey.qml
@@ -0,0 +1,27 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Key {
+ key: Qt.Key_Context1
+ displayText: "&123"
+ functionKey: true
+ onClicked: keyboard.symbolMode = !keyboard.symbolMode
+ keyPanelDelegate: keyboard.style ? keyboard.style.symbolKeyPanel : undefined
+}
diff --git a/src/virtualkeyboard/content/layouts/ar_AR.qml b/src/virtualkeyboard/content/layouts/ar_AR.qml
new file mode 100644
index 00000000..1c8458c2
--- /dev/null
+++ b/src/virtualkeyboard/content/layouts/ar_AR.qml
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Enterprise.VirtualKeyboard 1.0
+import "../components"
+
+KeyboardLayout {
+ keyWeight: 160
+ property var keys: ["ضصثقفغعهخحجد", "شسيبلاتنمكط", "ئءؤرلىةوزظ"]
+ KeyboardRow {
+ Repeater {
+ model: keys[0].length
+ Key {
+ text: keys[0][index]
+ }
+ }
+ BackspaceKey {}
+ }
+ KeyboardRow {
+ FillerKey {
+ weight: 56
+ }
+ Repeater {
+ model: keys[1].length
+ Key {
+ text: keys[1][index]
+ }
+ }
+ EnterKey {
+ weight: 283
+ }
+ }
+ KeyboardRow {
+ keyWeight: 156
+ FillerKey {}
+ Repeater {
+ model: keys[2].length
+ Key {
+ text: keys[2][index]
+ }
+ }
+ Key {
+ key: Qt.Key_Comma
+ text: ","
+ }
+ Key {
+ key: Qt.Key_Period
+ text: "."
+ }
+ FillerKey {
+ weight: 204
+ }
+ }
+ KeyboardRow {
+ keyWeight: 154
+ SymbolModeKey {
+ weight: 217
+ }
+ ChangeLanguageKey {
+ weight: 154
+ }
+ SpaceKey {
+ weight: 864
+ }
+ Key {
+ key: Qt.Key_Apostrophe
+ text: "'"
+ }
+ Key {
+ key: 0xE000
+ text: ":-)"
+ alternativeKeys: [ ";-)", ":-)", ":-D", ":-(", "<3" ]
+ }
+ HideKeyboardKey {
+ weight: 204
+ }
+ }
+}
diff --git a/src/virtualkeyboard/content/layouts/en_GB.qml b/src/virtualkeyboard/content/layouts/en_GB.qml
new file mode 100644
index 00000000..1c56caad
--- /dev/null
+++ b/src/virtualkeyboard/content/layouts/en_GB.qml
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Enterprise.VirtualKeyboard 1.0
+import "../components"
+
+KeyboardLayout {
+ keyWeight: 160
+ KeyboardRow {
+ Key {
+ key: Qt.Key_Q
+ text: "q"
+ }
+ Key {
+ key: Qt.Key_W
+ text: "w"
+ }
+ Key {
+ key: Qt.Key_E
+ text: "e"
+ alternativeKeys: "êeëèé"
+ }
+ Key {
+ key: Qt.Key_R
+ text: "r"
+ alternativeKeys: "ŕrř"
+ }
+ Key {
+ key: Qt.Key_T
+ text: "t"
+ alternativeKeys: "ţtŧť"
+ }
+ Key {
+ key: Qt.Key_Y
+ text: "y"
+ alternativeKeys: "ÿyýŷ"
+ }
+ Key {
+ key: Qt.Key_U
+ text: "u"
+ alternativeKeys: "űūũûüuùú"
+ }
+ Key {
+ key: Qt.Key_I
+ text: "i"
+ alternativeKeys: "îïīĩiìí"
+ }
+ Key {
+ key: Qt.Key_O
+ text: "o"
+ alternativeKeys: "œøõôöòóo"
+ }
+ Key {
+ key: Qt.Key_P
+ text: "p"
+ }
+ BackspaceKey {}
+ }
+ KeyboardRow {
+ FillerKey {
+ weight: 56
+ }
+ Key {
+ key: Qt.Key_A
+ text: "a"
+ alternativeKeys: "aäåãâàá"
+ }
+ Key {
+ key: Qt.Key_S
+ text: "s"
+ alternativeKeys: "šsşś"
+ }
+ Key {
+ key: Qt.Key_D
+ text: "d"
+ alternativeKeys: "dđď"
+ }
+ Key {
+ key: Qt.Key_F
+ text: "f"
+ }
+ Key {
+ key: Qt.Key_G
+ text: "g"
+ alternativeKeys: "ġgģĝğ"
+ }
+ Key {
+ key: Qt.Key_H
+ text: "h"
+ }
+ Key {
+ key: Qt.Key_J
+ text: "j"
+ }
+ Key {
+ key: Qt.Key_K
+ text: "k"
+ }
+ Key {
+ key: Qt.Key_L
+ text: "l"
+ alternativeKeys: "ĺŀłļľl"
+ }
+ EnterKey {
+ weight: 283
+ }
+ }
+ KeyboardRow {
+ keyWeight: 156
+ ShiftKey {}
+ Key {
+ key: Qt.Key_Z
+ text: "z"
+ alternativeKeys: "zžż"
+ }
+ Key {
+ key: Qt.Key_X
+ text: "x"
+ }
+ Key {
+ key: Qt.Key_C
+ text: "c"
+ alternativeKeys: "çcċčć"
+ }
+ Key {
+ key: Qt.Key_V
+ text: "v"
+ }
+ Key {
+ key: Qt.Key_B
+ text: "b"
+ }
+ Key {
+ key: Qt.Key_N
+ text: "n"
+ alternativeKeys: "ņńnň"
+ }
+ Key {
+ key: Qt.Key_M
+ text: "m"
+ }
+ Key {
+ key: Qt.Key_Comma
+ text: ","
+ }
+ Key {
+ key: Qt.Key_Period
+ text: "."
+ }
+ ShiftKey {
+ weight: 204
+ }
+ }
+ KeyboardRow {
+ keyWeight: 154
+ SymbolModeKey {
+ weight: 217
+ }
+ ChangeLanguageKey {
+ weight: 154
+ }
+ SpaceKey {
+ weight: 864
+ }
+ Key {
+ key: Qt.Key_Apostrophe
+ text: "'"
+ }
+ Key {
+ key: 0xE000
+ text: ":-)"
+ alternativeKeys: [ ";-)", ":-)", ":-D", ":-(", "<3" ]
+ }
+ HideKeyboardKey {
+ weight: 204
+ }
+ }
+}
diff --git a/src/virtualkeyboard/content/layouts/fi_FI.qml b/src/virtualkeyboard/content/layouts/fi_FI.qml
new file mode 100644
index 00000000..76885e67
--- /dev/null
+++ b/src/virtualkeyboard/content/layouts/fi_FI.qml
@@ -0,0 +1,195 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Enterprise.VirtualKeyboard 1.0
+import "../components"
+
+KeyboardLayout {
+ keyWeight: 160
+ KeyboardRow {
+ Key {
+ key: Qt.Key_Q
+ text: "q"
+ }
+ Key {
+ key: Qt.Key_W
+ text: "w"
+ }
+ Key {
+ key: Qt.Key_E
+ text: "e"
+ }
+ Key {
+ key: Qt.Key_R
+ text: "r"
+ }
+ Key {
+ key: Qt.Key_T
+ text: "t"
+ }
+ Key {
+ key: Qt.Key_Y
+ text: "y"
+ }
+ Key {
+ key: Qt.Key_U
+ text: "u"
+ }
+ Key {
+ key: Qt.Key_I
+ text: "i"
+ }
+ Key {
+ key: Qt.Key_O
+ text: "o"
+ }
+ Key {
+ key: Qt.Key_P
+ text: "p"
+ }
+ Key {
+ key: Qt.Key_Adiaeresis
+ text: "å"
+ }
+ BackspaceKey {}
+ }
+ KeyboardRow {
+ FillerKey {
+ weight: 66
+ }
+ Key {
+ key: Qt.Key_A
+ text: "a"
+ }
+ Key {
+ key: Qt.Key_S
+ text: "s"
+ }
+ Key {
+ key: Qt.Key_D
+ text: "d"
+ }
+ Key {
+ key: Qt.Key_F
+ text: "f"
+ }
+ Key {
+ key: Qt.Key_G
+ text: "g"
+ }
+ Key {
+ key: Qt.Key_H
+ text: "h"
+ }
+ Key {
+ key: Qt.Key_J
+ text: "j"
+ }
+ Key {
+ key: Qt.Key_K
+ text: "k"
+ }
+ Key {
+ key: Qt.Key_L
+ text: "l"
+ }
+ Key {
+ key: Qt.Key_Odiaeresis
+ text: "ö"
+ }
+ Key {
+ key: Qt.Key_Adiaeresis
+ text: "ä"
+ }
+ EnterKey {
+ weight: 283
+ }
+ }
+ KeyboardRow {
+ keyWeight: 156
+ ShiftKey { }
+ Key {
+ key: Qt.Key_Z
+ text: "z"
+ }
+ Key {
+ key: Qt.Key_X
+ text: "x"
+ }
+ Key {
+ key: Qt.Key_C
+ text: "c"
+ }
+ Key {
+ key: Qt.Key_V
+ text: "v"
+ }
+ Key {
+ key: Qt.Key_B
+ text: "b"
+ }
+ Key {
+ key: Qt.Key_N
+ text: "n"
+ }
+ Key {
+ key: Qt.Key_M
+ text: "m"
+ }
+ Key {
+ key: Qt.Key_Comma
+ text: ","
+ }
+ Key {
+ key: Qt.Key_Period
+ text: "."
+ }
+ Key {
+ key: Qt.Key_Minus
+ text: "-"
+ }
+ ShiftKey {
+ weight: 264
+ }
+ }
+ KeyboardRow {
+ keyWeight: 154
+ SymbolModeKey {
+ weight: 217
+ }
+ ChangeLanguageKey {
+ weight: 154
+ }
+ SpaceKey {
+ weight: 864
+ }
+ Key {
+ key: Qt.Key_Apostrophe
+ text: "'"
+ }
+ Key {
+ key: 0xE000
+ text: ":-)"
+ alternativeKeys: [ ";-)", ":-)", ":-D", ":-(", "<3" ]
+ }
+ HideKeyboardKey {
+ weight: 204
+ }
+ }
+}
diff --git a/src/virtualkeyboard/content/layouts/numbers.qml b/src/virtualkeyboard/content/layouts/numbers.qml
new file mode 100644
index 00000000..2c6d94dc
--- /dev/null
+++ b/src/virtualkeyboard/content/layouts/numbers.qml
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Layouts 1.0
+import "../components"
+import QtQuick.Enterprise.VirtualKeyboard 1.0
+
+KeyboardLayout {
+ inputMethod: MultitapInputMethod {}
+ inputMode: InputEngine.Numeric
+
+ KeyboardColumn {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+ Layout.alignment: Qt.AlignHCenter
+ Layout.preferredWidth: height
+ KeyboardRow {
+ Key {
+ id: keyOne
+ key: Qt.Key_1
+ text: "1"
+ }
+ Key {
+ key: Qt.Key_2
+ text: "2"
+ }
+ Key {
+ key: Qt.Key_3
+ text: "3"
+ }
+ BackspaceKey { }
+ }
+ KeyboardRow {
+ Key {
+ key: Qt.Key_4
+ text: "4"
+ }
+ Key {
+ key: Qt.Key_5
+ text: "5"
+ }
+ Key {
+ key: Qt.Key_6
+ text: "6"
+ }
+ Key {
+ text: "_"
+ repeat: true
+ showPreview: false
+ key: Qt.Key_Space
+ }
+ }
+ KeyboardRow {
+ Key {
+ key: Qt.Key_7
+ text: "7"
+ }
+ Key {
+ key: Qt.Key_8
+ text: "8"
+ }
+ Key {
+ key: Qt.Key_9
+ text: "9"
+ }
+ HideKeyboardKey { }
+ }
+ KeyboardRow {
+ Key {
+ key: Qt.Key_Asterisk
+ displayText: "*+"
+ text: "*+"
+ visible: InputContext.inputMethodHints & Qt.ImhDialableCharactersOnly
+ }
+ Key {
+ key: Qt.Key_0
+ text: "0"
+ }
+ Key {
+ id: signKey
+ text: "#"
+ key: Qt.Key_NumberSign
+ visible: !(InputContext.inputMethodHints & Qt.ImhDigitsOnly)
+ states: State {
+ when: InputContext.inputMethodHints & Qt.ImhFormattedNumbersOnly
+ PropertyChanges {
+ target: signKey
+
+ text: "."
+ key: Qt.Key_Period
+ enabled: InputContext.surroundingText.indexOf(".") === -1
+ }
+ }
+ }
+ EnterKey { }
+ }
+ }
+}
diff --git a/src/virtualkeyboard/content/layouts/symbols_ar_AR.qml b/src/virtualkeyboard/content/layouts/symbols_ar_AR.qml
new file mode 100644
index 00000000..f12c0935
--- /dev/null
+++ b/src/virtualkeyboard/content/layouts/symbols_ar_AR.qml
@@ -0,0 +1,359 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Layouts 1.0
+import "../components"
+
+KeyboardLayout {
+ property bool secondPage
+ onVisibleChanged: if (!visible) secondPage = false
+ keyWeight: 160
+ KeyboardColumn {
+ anchors.fill: parent
+ visible: !secondPage
+ KeyboardRow {
+ Key {
+ key: 0x0661
+ text: "\u0661"
+ }
+ Key {
+ key: 0x0662
+ text: "\u0662"
+ }
+ Key {
+ key: 0x0663
+ text: "\u0664"
+ }
+ Key {
+ key: 0x0664
+ text: "\u0664"
+ }
+ Key {
+ key: 0x0665
+ text: "\u0665"
+ }
+ Key {
+ key: 0x0666
+ text: "\u0666"
+ }
+ Key {
+ key: 0x0667
+ text: "\u0667"
+ }
+ Key {
+ key: 0x0668
+ text: "\u0668"
+ }
+ Key {
+ key: 0x0669
+ text: "\u0669"
+ }
+ Key {
+ key: 0x0660
+ text: "\u0660"
+ }
+ BackspaceKey {}
+ }
+ KeyboardRow {
+ FillerKey {
+ weight: 56
+ }
+ Key {
+ key: Qt.Key_At
+ text: "@"
+ }
+ Key {
+ key: Qt.Key_NumberSign
+ text: "#"
+ }
+ Key {
+ key: Qt.Key_Percent
+ text: "%"
+ }
+ Key {
+ key: Qt.Key_Ampersand
+ text: "&"
+ }
+ Key {
+ key: Qt.Key_Asterisk
+ text: "*"
+ }
+ Key {
+ key: Qt.Key_Minus
+ text: "-"
+ }
+ Key {
+ key: Qt.Key_Plus
+ text: "+"
+ }
+ Key {
+ key: Qt.Key_ParenLeft
+ text: "("
+ }
+ Key {
+ key: Qt.Key_ParenRight
+ text: ")"
+ }
+ EnterKey {
+ weight: 283
+ }
+ }
+ KeyboardRow {
+ keyWeight: 156
+ Key {
+ displayText: "1/2"
+ functionKey: true
+ onClicked: secondPage = !secondPage
+ }
+ Key {
+ key: Qt.Key_Exclam
+ text: "!"
+ }
+ Key {
+ key: Qt.Key_QuoteDbl
+ text: '"'
+ }
+ Key {
+ key: Qt.Key_Less
+ text: "<"
+ }
+ Key {
+ key: Qt.Key_Greater
+ text: ">"
+ }
+ Key {
+ key: Qt.Key_Apostrophe
+ text: "'"
+ }
+ Key {
+ key: Qt.Key_Colon
+ text: ":"
+ }
+ Key {
+ key: Qt.Key_Semicolon
+ text: ";"
+ }
+ Key {
+ key: Qt.Key_Slash
+ text: "/"
+ }
+ Key {
+ key: Qt.Key_Question
+ text: "?"
+ }
+ Key {
+ weight: 204
+ displayText: "1/2"
+ functionKey: true
+ onClicked: secondPage = !secondPage
+ }
+ }
+ KeyboardRow {
+ keyWeight: 154
+ SymbolModeKey {
+ weight: 217
+ displayText: "ABC"
+ }
+ ChangeLanguageKey {
+ weight: 154
+ }
+ SpaceKey {
+ weight: 864
+ }
+ Key {
+ key: Qt.Key_Apostrophe
+ text: "'"
+ }
+ Key {
+ key: 0xE000
+ text: ":-)"
+ alternativeKeys: [ ";-)", ":-)", ":-D", ":-(", "<3" ]
+ }
+ HideKeyboardKey {
+ weight: 204
+ }
+ }
+ }
+ KeyboardColumn {
+ anchors.fill: parent
+ visible: secondPage
+ KeyboardRow {
+ Key {
+ key: Qt.Key_AsciiTilde
+ text: "~"
+ }
+ Key {
+ key: Qt.Key_Agrave
+ text: "`"
+ }
+ Key {
+ key: Qt.Key_Bar
+ text: "|"
+ }
+ Key {
+ key: 0x7B
+ text: "·"
+ }
+ Key {
+ key: 0x221A
+ text: "√"
+ }
+ Key {
+ key: Qt.Key_division
+ text: "÷"
+ }
+ Key {
+ key: Qt.Key_multiply
+ text: "×"
+ }
+ Key {
+ key: Qt.Key_onehalf
+ text: "½"
+ }
+ Key {
+ key: Qt.Key_BraceLeft
+ text: "{"
+ }
+ Key {
+ key: Qt.Key_BraceRight
+ text: "}"
+ }
+ BackspaceKey {}
+ }
+ KeyboardRow {
+ FillerKey {
+ weight: 56
+ }
+ Key {
+ key: Qt.Key_Dollar
+ text: "$"
+ }
+ Key {
+ key: 0x20AC
+ text: "€"
+ }
+ Key {
+ key: 0xC2
+ text: "£"
+ }
+ Key {
+ key: Qt.Key_AsciiCircum
+ text: "^"
+ }
+ Key {
+ key: Qt.Key_Underscore
+ text: "_"
+ }
+ Key {
+ key: Qt.Key_Equal
+ text: "="
+ }
+ Key {
+ key: Qt.Key_section
+ text: "§"
+ }
+ Key {
+ key: Qt.Key_BracketLeft
+ text: "["
+ }
+ Key {
+ key: Qt.Key_BracketRight
+ text: "]"
+ }
+ EnterKey {
+ weight: 283
+ }
+ }
+ KeyboardRow {
+ keyWeight: 156
+ Key {
+ displayText: "2/2"
+ functionKey: true
+ onClicked: secondPage = !secondPage
+ }
+ Key {
+ key: Qt.Key_exclamdown
+ text: "¡"
+ }
+ Key {
+ key: 0x2122
+ text: '™'
+ }
+ Key {
+ key: 0x00AE
+ text: '®'
+ }
+ Key {
+ key: Qt.Key_guillemotleft
+ text: '«'
+ }
+ Key {
+ key: Qt.Key_guillemotright
+ text: '»'
+ }
+ Key {
+ key: 0x201C
+ text: '“'
+ }
+ Key {
+ key: 0x201D
+ text: '”'
+ }
+ Key {
+ key: Qt.Key_Backslash
+ text: "\\"
+ }
+ Key {
+ key: Qt.Key_questiondown
+ text: "¿"
+ }
+ Key {
+ weight: 204
+ displayText: "2/2"
+ functionKey: true
+ onClicked: secondPage = !secondPage
+ }
+ }
+ KeyboardRow {
+ keyWeight: 154
+ SymbolModeKey {
+ weight: 217
+ displayText: "ABC"
+ }
+ ChangeLanguageKey {
+ weight: 154
+ }
+ SpaceKey {
+ weight: 864
+ }
+ Key {
+ key: Qt.Key_Apostrophe
+ text: "'"
+ }
+ Key {
+ key: 0xE000
+ text: ":-)"
+ alternativeKeys: [ ";-)", ":-)", ":-D", ":-(", "<3" ]
+ }
+ HideKeyboardKey {
+ weight: 204
+ }
+ }
+ }
+}
diff --git a/src/virtualkeyboard/content/layouts/symbols_en_GB.qml b/src/virtualkeyboard/content/layouts/symbols_en_GB.qml
new file mode 100644
index 00000000..a79453b1
--- /dev/null
+++ b/src/virtualkeyboard/content/layouts/symbols_en_GB.qml
@@ -0,0 +1,359 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Layouts 1.0
+import "../components"
+
+KeyboardLayout {
+ property bool secondPage
+ onVisibleChanged: if (!visible) secondPage = false
+ keyWeight: 160
+ KeyboardColumn {
+ anchors.fill: parent
+ visible: !secondPage
+ KeyboardRow {
+ Key {
+ key: Qt.Key_1
+ text: "1"
+ }
+ Key {
+ key: Qt.Key_2
+ text: "2"
+ }
+ Key {
+ key: Qt.Key_3
+ text: "3"
+ }
+ Key {
+ key: Qt.Key_4
+ text: "4"
+ }
+ Key {
+ key: Qt.Key_5
+ text: "5"
+ }
+ Key {
+ key: Qt.Key_6
+ text: "6"
+ }
+ Key {
+ key: Qt.Key_7
+ text: "7"
+ }
+ Key {
+ key: Qt.Key_8
+ text: "8"
+ }
+ Key {
+ key: Qt.Key_9
+ text: "9"
+ }
+ Key {
+ key: Qt.Key_0
+ text: "0"
+ }
+ BackspaceKey {}
+ }
+ KeyboardRow {
+ FillerKey {
+ weight: 56
+ }
+ Key {
+ key: Qt.Key_At
+ text: "@"
+ }
+ Key {
+ key: Qt.Key_NumberSign
+ text: "#"
+ }
+ Key {
+ key: Qt.Key_Percent
+ text: "%"
+ }
+ Key {
+ key: Qt.Key_Ampersand
+ text: "&"
+ }
+ Key {
+ key: Qt.Key_Asterisk
+ text: "*"
+ }
+ Key {
+ key: Qt.Key_Minus
+ text: "-"
+ }
+ Key {
+ key: Qt.Key_Plus
+ text: "+"
+ }
+ Key {
+ key: Qt.Key_ParenLeft
+ text: "("
+ }
+ Key {
+ key: Qt.Key_ParenRight
+ text: ")"
+ }
+ EnterKey {
+ weight: 283
+ }
+ }
+ KeyboardRow {
+ keyWeight: 156
+ Key {
+ displayText: "1/2"
+ functionKey: true
+ onClicked: secondPage = !secondPage
+ }
+ Key {
+ key: Qt.Key_Exclam
+ text: "!"
+ }
+ Key {
+ key: Qt.Key_QuoteDbl
+ text: '"'
+ }
+ Key {
+ key: Qt.Key_Less
+ text: "<"
+ }
+ Key {
+ key: Qt.Key_Greater
+ text: ">"
+ }
+ Key {
+ key: Qt.Key_Apostrophe
+ text: "'"
+ }
+ Key {
+ key: Qt.Key_Colon
+ text: ":"
+ }
+ Key {
+ key: Qt.Key_Semicolon
+ text: ";"
+ }
+ Key {
+ key: Qt.Key_Slash
+ text: "/"
+ }
+ Key {
+ key: Qt.Key_Question
+ text: "?"
+ }
+ Key {
+ weight: 204
+ displayText: "1/2"
+ functionKey: true
+ onClicked: secondPage = !secondPage
+ }
+ }
+ KeyboardRow {
+ keyWeight: 154
+ SymbolModeKey {
+ weight: 217
+ displayText: "ABC"
+ }
+ ChangeLanguageKey {
+ weight: 154
+ }
+ SpaceKey {
+ weight: 864
+ }
+ Key {
+ key: Qt.Key_Apostrophe
+ text: "'"
+ }
+ Key {
+ key: 0xE000
+ text: ":-)"
+ alternativeKeys: [ ";-)", ":-)", ":-D", ":-(", "<3" ]
+ }
+ HideKeyboardKey {
+ weight: 204
+ }
+ }
+ }
+ KeyboardColumn {
+ anchors.fill: parent
+ visible: secondPage
+ KeyboardRow {
+ Key {
+ key: Qt.Key_AsciiTilde
+ text: "~"
+ }
+ Key {
+ key: Qt.Key_Agrave
+ text: "`"
+ }
+ Key {
+ key: Qt.Key_Bar
+ text: "|"
+ }
+ Key {
+ key: 0x7B
+ text: "·"
+ }
+ Key {
+ key: 0x221A
+ text: "√"
+ }
+ Key {
+ key: Qt.Key_division
+ text: "÷"
+ }
+ Key {
+ key: Qt.Key_multiply
+ text: "×"
+ }
+ Key {
+ key: Qt.Key_onehalf
+ text: "½"
+ }
+ Key {
+ key: Qt.Key_BraceLeft
+ text: "{"
+ }
+ Key {
+ key: Qt.Key_BraceRight
+ text: "}"
+ }
+ BackspaceKey {}
+ }
+ KeyboardRow {
+ FillerKey {
+ weight: 56
+ }
+ Key {
+ key: Qt.Key_Dollar
+ text: "$"
+ }
+ Key {
+ key: 0x20AC
+ text: "€"
+ }
+ Key {
+ key: 0xC2
+ text: "£"
+ }
+ Key {
+ key: Qt.Key_AsciiCircum
+ text: "^"
+ }
+ Key {
+ key: Qt.Key_Underscore
+ text: "_"
+ }
+ Key {
+ key: Qt.Key_Equal
+ text: "="
+ }
+ Key {
+ key: Qt.Key_section
+ text: "§"
+ }
+ Key {
+ key: Qt.Key_BracketLeft
+ text: "["
+ }
+ Key {
+ key: Qt.Key_BracketRight
+ text: "]"
+ }
+ EnterKey {
+ weight: 283
+ }
+ }
+ KeyboardRow {
+ keyWeight: 156
+ Key {
+ displayText: "2/2"
+ functionKey: true
+ onClicked: secondPage = !secondPage
+ }
+ Key {
+ key: Qt.Key_exclamdown
+ text: "¡"
+ }
+ Key {
+ key: 0x2122
+ text: '™'
+ }
+ Key {
+ key: 0x00AE
+ text: '®'
+ }
+ Key {
+ key: Qt.Key_guillemotleft
+ text: '«'
+ }
+ Key {
+ key: Qt.Key_guillemotright
+ text: '»'
+ }
+ Key {
+ key: 0x201C
+ text: '“'
+ }
+ Key {
+ key: 0x201D
+ text: '”'
+ }
+ Key {
+ key: Qt.Key_Backslash
+ text: "\\"
+ }
+ Key {
+ key: Qt.Key_questiondown
+ text: "¿"
+ }
+ Key {
+ weight: 204
+ displayText: "2/2"
+ functionKey: true
+ onClicked: secondPage = !secondPage
+ }
+ }
+ KeyboardRow {
+ keyWeight: 154
+ SymbolModeKey {
+ weight: 217
+ displayText: "ABC"
+ }
+ ChangeLanguageKey {
+ weight: 154
+ }
+ SpaceKey {
+ weight: 864
+ }
+ Key {
+ key: Qt.Key_Apostrophe
+ text: "'"
+ }
+ Key {
+ key: 0xE000
+ text: ":-)"
+ alternativeKeys: [ ";-)", ":-)", ":-D", ":-(", "<3" ]
+ }
+ HideKeyboardKey {
+ weight: 204
+ }
+ }
+ }
+}
diff --git a/src/virtualkeyboard/content/layouts/symbols_fi_FI.qml b/src/virtualkeyboard/content/layouts/symbols_fi_FI.qml
new file mode 100644
index 00000000..a79453b1
--- /dev/null
+++ b/src/virtualkeyboard/content/layouts/symbols_fi_FI.qml
@@ -0,0 +1,359 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Layouts 1.0
+import "../components"
+
+KeyboardLayout {
+ property bool secondPage
+ onVisibleChanged: if (!visible) secondPage = false
+ keyWeight: 160
+ KeyboardColumn {
+ anchors.fill: parent
+ visible: !secondPage
+ KeyboardRow {
+ Key {
+ key: Qt.Key_1
+ text: "1"
+ }
+ Key {
+ key: Qt.Key_2
+ text: "2"
+ }
+ Key {
+ key: Qt.Key_3
+ text: "3"
+ }
+ Key {
+ key: Qt.Key_4
+ text: "4"
+ }
+ Key {
+ key: Qt.Key_5
+ text: "5"
+ }
+ Key {
+ key: Qt.Key_6
+ text: "6"
+ }
+ Key {
+ key: Qt.Key_7
+ text: "7"
+ }
+ Key {
+ key: Qt.Key_8
+ text: "8"
+ }
+ Key {
+ key: Qt.Key_9
+ text: "9"
+ }
+ Key {
+ key: Qt.Key_0
+ text: "0"
+ }
+ BackspaceKey {}
+ }
+ KeyboardRow {
+ FillerKey {
+ weight: 56
+ }
+ Key {
+ key: Qt.Key_At
+ text: "@"
+ }
+ Key {
+ key: Qt.Key_NumberSign
+ text: "#"
+ }
+ Key {
+ key: Qt.Key_Percent
+ text: "%"
+ }
+ Key {
+ key: Qt.Key_Ampersand
+ text: "&"
+ }
+ Key {
+ key: Qt.Key_Asterisk
+ text: "*"
+ }
+ Key {
+ key: Qt.Key_Minus
+ text: "-"
+ }
+ Key {
+ key: Qt.Key_Plus
+ text: "+"
+ }
+ Key {
+ key: Qt.Key_ParenLeft
+ text: "("
+ }
+ Key {
+ key: Qt.Key_ParenRight
+ text: ")"
+ }
+ EnterKey {
+ weight: 283
+ }
+ }
+ KeyboardRow {
+ keyWeight: 156
+ Key {
+ displayText: "1/2"
+ functionKey: true
+ onClicked: secondPage = !secondPage
+ }
+ Key {
+ key: Qt.Key_Exclam
+ text: "!"
+ }
+ Key {
+ key: Qt.Key_QuoteDbl
+ text: '"'
+ }
+ Key {
+ key: Qt.Key_Less
+ text: "<"
+ }
+ Key {
+ key: Qt.Key_Greater
+ text: ">"
+ }
+ Key {
+ key: Qt.Key_Apostrophe
+ text: "'"
+ }
+ Key {
+ key: Qt.Key_Colon
+ text: ":"
+ }
+ Key {
+ key: Qt.Key_Semicolon
+ text: ";"
+ }
+ Key {
+ key: Qt.Key_Slash
+ text: "/"
+ }
+ Key {
+ key: Qt.Key_Question
+ text: "?"
+ }
+ Key {
+ weight: 204
+ displayText: "1/2"
+ functionKey: true
+ onClicked: secondPage = !secondPage
+ }
+ }
+ KeyboardRow {
+ keyWeight: 154
+ SymbolModeKey {
+ weight: 217
+ displayText: "ABC"
+ }
+ ChangeLanguageKey {
+ weight: 154
+ }
+ SpaceKey {
+ weight: 864
+ }
+ Key {
+ key: Qt.Key_Apostrophe
+ text: "'"
+ }
+ Key {
+ key: 0xE000
+ text: ":-)"
+ alternativeKeys: [ ";-)", ":-)", ":-D", ":-(", "<3" ]
+ }
+ HideKeyboardKey {
+ weight: 204
+ }
+ }
+ }
+ KeyboardColumn {
+ anchors.fill: parent
+ visible: secondPage
+ KeyboardRow {
+ Key {
+ key: Qt.Key_AsciiTilde
+ text: "~"
+ }
+ Key {
+ key: Qt.Key_Agrave
+ text: "`"
+ }
+ Key {
+ key: Qt.Key_Bar
+ text: "|"
+ }
+ Key {
+ key: 0x7B
+ text: "·"
+ }
+ Key {
+ key: 0x221A
+ text: "√"
+ }
+ Key {
+ key: Qt.Key_division
+ text: "÷"
+ }
+ Key {
+ key: Qt.Key_multiply
+ text: "×"
+ }
+ Key {
+ key: Qt.Key_onehalf
+ text: "½"
+ }
+ Key {
+ key: Qt.Key_BraceLeft
+ text: "{"
+ }
+ Key {
+ key: Qt.Key_BraceRight
+ text: "}"
+ }
+ BackspaceKey {}
+ }
+ KeyboardRow {
+ FillerKey {
+ weight: 56
+ }
+ Key {
+ key: Qt.Key_Dollar
+ text: "$"
+ }
+ Key {
+ key: 0x20AC
+ text: "€"
+ }
+ Key {
+ key: 0xC2
+ text: "£"
+ }
+ Key {
+ key: Qt.Key_AsciiCircum
+ text: "^"
+ }
+ Key {
+ key: Qt.Key_Underscore
+ text: "_"
+ }
+ Key {
+ key: Qt.Key_Equal
+ text: "="
+ }
+ Key {
+ key: Qt.Key_section
+ text: "§"
+ }
+ Key {
+ key: Qt.Key_BracketLeft
+ text: "["
+ }
+ Key {
+ key: Qt.Key_BracketRight
+ text: "]"
+ }
+ EnterKey {
+ weight: 283
+ }
+ }
+ KeyboardRow {
+ keyWeight: 156
+ Key {
+ displayText: "2/2"
+ functionKey: true
+ onClicked: secondPage = !secondPage
+ }
+ Key {
+ key: Qt.Key_exclamdown
+ text: "¡"
+ }
+ Key {
+ key: 0x2122
+ text: '™'
+ }
+ Key {
+ key: 0x00AE
+ text: '®'
+ }
+ Key {
+ key: Qt.Key_guillemotleft
+ text: '«'
+ }
+ Key {
+ key: Qt.Key_guillemotright
+ text: '»'
+ }
+ Key {
+ key: 0x201C
+ text: '“'
+ }
+ Key {
+ key: 0x201D
+ text: '”'
+ }
+ Key {
+ key: Qt.Key_Backslash
+ text: "\\"
+ }
+ Key {
+ key: Qt.Key_questiondown
+ text: "¿"
+ }
+ Key {
+ weight: 204
+ displayText: "2/2"
+ functionKey: true
+ onClicked: secondPage = !secondPage
+ }
+ }
+ KeyboardRow {
+ keyWeight: 154
+ SymbolModeKey {
+ weight: 217
+ displayText: "ABC"
+ }
+ ChangeLanguageKey {
+ weight: 154
+ }
+ SpaceKey {
+ weight: 864
+ }
+ Key {
+ key: Qt.Key_Apostrophe
+ text: "'"
+ }
+ Key {
+ key: 0xE000
+ text: ":-)"
+ alternativeKeys: [ ";-)", ":-)", ":-D", ":-(", "<3" ]
+ }
+ HideKeyboardKey {
+ weight: 204
+ }
+ }
+ }
+}
diff --git a/src/virtualkeyboard/content/qmldir b/src/virtualkeyboard/content/qmldir
new file mode 100644
index 00000000..d5b24827
--- /dev/null
+++ b/src/virtualkeyboard/content/qmldir
@@ -0,0 +1,2 @@
+module QtQuick.Enterprise.VirtualKeyboard
+InputPanel 1.0 InputPanel.qml
diff --git a/src/virtualkeyboard/content/styles/default/fonts/OpenSans-Regular.ttf b/src/virtualkeyboard/content/styles/default/fonts/OpenSans-Regular.ttf
new file mode 100755
index 00000000..db433349
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/default/fonts/OpenSans-Regular.ttf
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/default/fonts/OpenSans-Semibold.ttf b/src/virtualkeyboard/content/styles/default/fonts/OpenSans-Semibold.ttf
new file mode 100755
index 00000000..1a7679e3
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/default/fonts/OpenSans-Semibold.ttf
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/default/images/backspace.png b/src/virtualkeyboard/content/styles/default/images/backspace.png
new file mode 100755
index 00000000..0a33e95f
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/default/images/backspace.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/default/images/enter.png b/src/virtualkeyboard/content/styles/default/images/enter.png
new file mode 100755
index 00000000..03335a0f
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/default/images/enter.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/default/images/globe.png b/src/virtualkeyboard/content/styles/default/images/globe.png
new file mode 100755
index 00000000..93da92f4
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/default/images/globe.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/default/images/hidekeyboard.png b/src/virtualkeyboard/content/styles/default/images/hidekeyboard.png
new file mode 100755
index 00000000..ca515036
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/default/images/hidekeyboard.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/default/images/shift.png b/src/virtualkeyboard/content/styles/default/images/shift.png
new file mode 100755
index 00000000..ae5ad0b7
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/default/images/shift.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/default/style.qml b/src/virtualkeyboard/content/styles/default/style.qml
new file mode 100644
index 00000000..92376ad1
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/default/style.qml
@@ -0,0 +1,548 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Enterprise.VirtualKeyboard.Styles 1.0
+
+KeyboardStyle {
+ readonly property string fontFamily: openSansRegular.name
+ readonly property real keyBackgroundMargin: Math.round(13 * scaleHint)
+ readonly property real keyContentMargin: Math.round(45 * scaleHint)
+
+ property var openSansRegular: FontLoader {
+ source: "qrc:/fonts/OpenSans-Regular.ttf"
+ }
+ property var openSansSemibold: FontLoader {
+ source: "qrc:/fonts/OpenSans-Semibold.ttf"
+ }
+
+ keyboardDesignWidth: 2560
+ keyboardDesignHeight: 800
+ keyboardRelativeLeftMargin: 114 / keyboardDesignWidth
+ keyboardRelativeRightMargin: 114 / keyboardDesignWidth
+ keyboardRelativeTopMargin: 13 / keyboardDesignHeight
+ keyboardRelativeBottomMargin: 86 / keyboardDesignHeight
+
+ keyboardBackground: Rectangle {
+ color: "black"
+ }
+
+ keyPanel: KeyPanel {
+ Rectangle {
+ id: keyBackground
+ radius: 5
+ color: "#35322f"
+ anchors.fill: parent
+ anchors.margins: keyBackgroundMargin
+ Text {
+ id: keyText
+ text: control.displayText
+ color: "white"
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ anchors.fill: parent
+ anchors.margins: keyContentMargin
+ font {
+ family: fontFamily
+ weight: Font.DemiBold
+ pixelSize: 52 * scaleHint
+ capitalization: control.uppercased ? Font.AllUppercase : Font.MixedCase
+ }
+ }
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: control.pressed
+ PropertyChanges {
+ target: keyBackground
+ opacity: 0.75
+ }
+ PropertyChanges {
+ target: keyText
+ opacity: 0.5
+ }
+ },
+ State {
+ name: "disabled"
+ when: !control.enabled
+ PropertyChanges {
+ target: keyBackground
+ opacity: 0.75
+ }
+ PropertyChanges {
+ target: keyText
+ opacity: 0.05
+ }
+ }
+ ]
+ }
+
+ backspaceKeyPanel: KeyPanel {
+ Rectangle {
+ id: backspaceKeyBackground
+ radius: 5
+ color: "#1e1b18"
+ anchors.fill: parent
+ anchors.margins: keyBackgroundMargin
+ KeyIcon {
+ id: backspaceKeyIcon
+ source: "qrc:/images/backspace.png"
+ color: "#868482"
+ anchors.fill: parent
+ anchors.margins: keyContentMargin
+ }
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: control.pressed
+ PropertyChanges {
+ target: backspaceKeyBackground
+ opacity: 0.80
+ }
+ PropertyChanges {
+ target: backspaceKeyIcon
+ opacity: 0.6
+ }
+ },
+ State {
+ name: "disabled"
+ when: !control.enabled
+ PropertyChanges {
+ target: backspaceKeyBackground
+ opacity: 0.8
+ }
+ PropertyChanges {
+ target: backspaceKeyIcon
+ opacity: 0.2
+ }
+ }
+ ]
+ }
+
+ languageKeyPanel: KeyPanel {
+ Rectangle {
+ id: languageKeyBackground
+ radius: 5
+ color: "#35322f"
+ anchors.fill: parent
+ anchors.margins: keyBackgroundMargin
+ KeyIcon {
+ id: languageKeyIcon
+ source: "qrc:/images/globe.png"
+ color: "#868482"
+ anchors.fill: parent
+ anchors.margins: keyContentMargin
+ }
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: control.pressed
+ PropertyChanges {
+ target: languageKeyBackground
+ opacity: 0.80
+ }
+ PropertyChanges {
+ target: languageKeyIcon
+ opacity: 0.75
+ }
+ },
+ State {
+ name: "disabled"
+ when: !control.enabled
+ PropertyChanges {
+ target: languageKeyBackground
+ opacity: 0.8
+ }
+ PropertyChanges {
+ target: languageKeyIcon
+ opacity: 0.2
+ }
+ }
+ ]
+ }
+
+ enterKeyPanel: KeyPanel {
+ Rectangle {
+ id: enterKeyBackground
+ radius: 5
+ color: "#1e1b18"
+ anchors.fill: parent
+ anchors.margins: keyBackgroundMargin
+ KeyIcon {
+ id: enterKeyIcon
+ visible: control.displayText.length === 0
+ source: "qrc:/images/enter.png"
+ color: "#868482"
+ anchors.fill: parent
+ anchors.topMargin: Math.round(50 * scaleHint)
+ anchors.bottomMargin: Math.round(50 * scaleHint)
+ anchors.leftMargin: Math.round(150 * scaleHint)
+ anchors.rightMargin: Math.round(85 * scaleHint)
+ }
+ Text {
+ id: enterKeyText
+ visible: control.displayText.length !== 0
+ text: control.displayText
+ clip: true
+ fontSizeMode: Text.HorizontalFit
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ color: "#80c342"
+ font {
+ family: fontFamily
+ weight: Font.DemiBold
+ pixelSize: 44 * scaleHint
+ capitalization: Font.AllUppercase
+ }
+ anchors.fill: parent
+ anchors.margins: Math.round(42 * scaleHint)
+ }
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: control.pressed
+ PropertyChanges {
+ target: enterKeyBackground
+ opacity: 0.80
+ }
+ PropertyChanges {
+ target: enterKeyIcon
+ opacity: 0.6
+ }
+ PropertyChanges {
+ target: enterKeyText
+ opacity: 0.6
+ }
+ },
+ State {
+ name: "disabled"
+ when: !control.enabled
+ PropertyChanges {
+ target: enterKeyBackground
+ opacity: 0.8
+ }
+ PropertyChanges {
+ target: enterKeyIcon
+ opacity: 0.2
+ }
+ PropertyChanges {
+ target: enterKeyText
+ opacity: 0.05
+ }
+ }
+ ]
+ }
+
+ hideKeyPanel: KeyPanel {
+ Rectangle {
+ id: hideKeyBackground
+ radius: 5
+ color: "#1e1b18"
+ anchors.fill: parent
+ anchors.margins: keyBackgroundMargin
+ KeyIcon {
+ id: hideKeyIcon
+ source: "qrc:/images/hidekeyboard.png"
+ color: "#868482"
+ anchors.fill: parent
+ anchors.margins: keyContentMargin
+ }
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: control.pressed
+ PropertyChanges {
+ target: hideKeyBackground
+ opacity: 0.80
+ }
+ PropertyChanges {
+ target: hideKeyIcon
+ opacity: 0.6
+ }
+ },
+ State {
+ name: "disabled"
+ when: !control.enabled
+ PropertyChanges {
+ target: hideKeyBackground
+ opacity: 0.8
+ }
+ PropertyChanges {
+ target: hideKeyIcon
+ opacity: 0.2
+ }
+ }
+ ]
+ }
+
+ shiftKeyPanel: KeyPanel {
+ Rectangle {
+ id: shiftKeyBackground
+ radius: 5
+ color: "#1e1b18"
+ anchors.fill: parent
+ anchors.margins: keyBackgroundMargin
+ KeyIcon {
+ id: shiftKeyIcon
+ source: "qrc:/images/shift.png"
+ color: "#868482"
+ anchors.fill: parent
+ anchors.margins: keyContentMargin
+ }
+ states: [
+ State {
+ name: "capslock"
+ when: control.capsLock
+ PropertyChanges {
+ target: shiftKeyBackground
+ color: "#5a892e"
+ }
+ PropertyChanges {
+ target: shiftKeyIcon
+ color: "#c5d6b6"
+ }
+ },
+ State {
+ name: "shift"
+ when: control.shift
+ PropertyChanges {
+ target: shiftKeyIcon
+ color: "#80c342"
+ }
+ }
+ ]
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: control.pressed
+ PropertyChanges {
+ target: shiftKeyBackground
+ opacity: 0.80
+ }
+ PropertyChanges {
+ target: shiftKeyIcon
+ opacity: 0.6
+ }
+ },
+ State {
+ name: "disabled"
+ when: !control.enabled
+ PropertyChanges {
+ target: shiftKeyBackground
+ opacity: 0.8
+ }
+ PropertyChanges {
+ target: shiftKeyIcon
+ opacity: 0.2
+ }
+ }
+ ]
+ }
+
+ spaceKeyPanel: KeyPanel {
+ Rectangle {
+ id: spaceKeyBackground
+ radius: 5
+ color: "#35322f"
+ anchors.fill: parent
+ anchors.margins: keyBackgroundMargin
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: control.pressed
+ PropertyChanges {
+ target: spaceKeyBackground
+ opacity: 0.80
+ }
+ },
+ State {
+ name: "disabled"
+ when: !control.enabled
+ PropertyChanges {
+ target: spaceKeyBackground
+ opacity: 0.8
+ }
+ }
+ ]
+ }
+
+ symbolKeyPanel: KeyPanel {
+ Rectangle {
+ id: symbolKeyBackground
+ radius: 5
+ color: "#1e1b18"
+ anchors.fill: parent
+ anchors.margins: keyBackgroundMargin
+ Text {
+ id: symbolKeyText
+ text: control.displayText
+ color: "white"
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ anchors.fill: parent
+ anchors.margins: keyContentMargin
+ font {
+ family: fontFamily
+ weight: Font.DemiBold
+ pixelSize: 44 * scaleHint
+ capitalization: Font.AllUppercase
+ }
+ }
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: control.pressed
+ PropertyChanges {
+ target: symbolKeyBackground
+ opacity: 0.80
+ }
+ PropertyChanges {
+ target: symbolKeyText
+ opacity: 0.6
+ }
+ },
+ State {
+ name: "disabled"
+ when: !control.enabled
+ PropertyChanges {
+ target: symbolKeyBackground
+ opacity: 0.8
+ }
+ PropertyChanges {
+ target: symbolKeyText
+ opacity: 0.2
+ }
+ }
+ ]
+ }
+
+ characterPreviewMargin: 0
+ characterPreviewDelegate: Item {
+ property string text
+ id: characterPreview
+ Rectangle {
+ id: characterPreviewBackground
+ anchors.fill: parent
+ color: "#5d5b59"
+ radius: 5
+ Text {
+ id: characterPreviewText
+ color: "white"
+ text: characterPreview.text
+ fontSizeMode: Text.HorizontalFit
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ anchors.fill: parent
+ anchors.margins: Math.round(48 * scaleHint)
+ font {
+ family: fontFamily
+ weight: Font.DemiBold
+ pixelSize: 82 * scaleHint
+ }
+ }
+ }
+ }
+
+ alternateKeysListItemWidth: 99 * scaleHint
+ alternateKeysListItemHeight: 150 * scaleHint
+ alternateKeysListDelegate: Item {
+ id: alternateKeysListItem
+ width: alternateKeysListItemWidth
+ height: alternateKeysListItemHeight
+ Text {
+ id: listItemText
+ text: model.text
+ color: "#868482"
+ font {
+ family: fontFamily
+ weight: Font.DemiBold
+ pixelSize: 52 * scaleHint
+ }
+ anchors.centerIn: parent
+ }
+ states: State {
+ name: "current"
+ when: alternateKeysListItem.ListView.isCurrentItem
+ PropertyChanges {
+ target: listItemText
+ color: "white"
+ }
+ }
+ }
+ alternateKeysListHighlight: Rectangle {
+ color: "#5d5b59"
+ radius: 5
+ }
+ alternateKeysListBackground: Rectangle {
+ color: "#1e1b18"
+ radius: 5
+ }
+
+ selectionListHeight: 85 * scaleHint
+ selectionListDelegate: SelectionListItem {
+ id: selectionListItem
+ width: Math.round(selectionListLabel.width + selectionListLabel.anchors.leftMargin * 2)
+ Text {
+ id: selectionListLabel
+ anchors.left: parent.left
+ anchors.leftMargin: Math.round(140 * scaleHint)
+ anchors.verticalCenter: parent.verticalCenter
+ text: decorateText(display, wordCompletionLength)
+ color: "#80c342"
+ font {
+ family: fontFamily
+ weight: Font.Normal
+ pixelSize: 44 * scaleHint
+ }
+ function decorateText(text, wordCompletionLength) {
+ if (wordCompletionLength > 0) {
+ return text.slice(0, -wordCompletionLength) + '<u>' + text.slice(-wordCompletionLength) + '</u>'
+ }
+ return text
+ }
+ }
+ Rectangle {
+ id: selectionListSeparator
+ width: 4 * scaleHint
+ height: 36 * scaleHint
+ radius: 2
+ color: "#35322f"
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.right: parent.left
+ }
+ states: State {
+ name: "current"
+ when: selectionListItem.ListView.isCurrentItem
+ PropertyChanges {
+ target: selectionListLabel
+ color: "white"
+ }
+ }
+ }
+ selectionListBackground: Rectangle {
+ color: "#1e1b18"
+ }
+}
diff --git a/src/virtualkeyboard/content/styles/default/style.qrc b/src/virtualkeyboard/content/styles/default/style.qrc
new file mode 100644
index 00000000..c7051c42
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/default/style.qrc
@@ -0,0 +1,12 @@
+<RCC>
+ <qresource prefix="/">
+ <file>style.qml</file>
+ <file>fonts/OpenSans-Regular.ttf</file>
+ <file>fonts/OpenSans-Semibold.ttf</file>
+ <file>images/backspace.png</file>
+ <file>images/enter.png</file>
+ <file>images/hidekeyboard.png</file>
+ <file>images/shift.png</file>
+ <file>images/globe.png</file>
+ </qresource>
+</RCC>
diff --git a/src/virtualkeyboard/content/styles/retro/fonts/Courier Prime Bold.ttf b/src/virtualkeyboard/content/styles/retro/fonts/Courier Prime Bold.ttf
new file mode 100644
index 00000000..1b0888c2
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/fonts/Courier Prime Bold.ttf
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/fonts/Courier Prime.ttf b/src/virtualkeyboard/content/styles/retro/fonts/Courier Prime.ttf
new file mode 100644
index 00000000..db4e6c14
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/fonts/Courier Prime.ttf
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/images/backspace.png b/src/virtualkeyboard/content/styles/retro/images/backspace.png
new file mode 100755
index 00000000..0a33e95f
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/backspace.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/images/enter.png b/src/virtualkeyboard/content/styles/retro/images/enter.png
new file mode 100755
index 00000000..03335a0f
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/enter.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/images/globe.png b/src/virtualkeyboard/content/styles/retro/images/globe.png
new file mode 100755
index 00000000..93da92f4
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/globe.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/images/hidekeyboard.png b/src/virtualkeyboard/content/styles/retro/images/hidekeyboard.png
new file mode 100755
index 00000000..ca515036
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/hidekeyboard.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/images/key154px_black.png b/src/virtualkeyboard/content/styles/retro/images/key154px_black.png
new file mode 100755
index 00000000..d9bf8e72
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/key154px_black.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/images/key154px_black_long.png b/src/virtualkeyboard/content/styles/retro/images/key154px_black_long.png
new file mode 100755
index 00000000..492c718a
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/key154px_black_long.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/images/key154px_capslock.png b/src/virtualkeyboard/content/styles/retro/images/key154px_capslock.png
new file mode 100755
index 00000000..7cb0bd4a
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/key154px_capslock.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/images/key154px_capslock_long.png b/src/virtualkeyboard/content/styles/retro/images/key154px_capslock_long.png
new file mode 100755
index 00000000..429d4bb5
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/key154px_capslock_long.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/images/key154px_colorA.png b/src/virtualkeyboard/content/styles/retro/images/key154px_colorA.png
new file mode 100755
index 00000000..778384cd
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/key154px_colorA.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/images/key154px_colorA_long.png b/src/virtualkeyboard/content/styles/retro/images/key154px_colorA_long.png
new file mode 100755
index 00000000..e1b6e5b8
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/key154px_colorA_long.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/images/key154px_colorB.png b/src/virtualkeyboard/content/styles/retro/images/key154px_colorB.png
new file mode 100755
index 00000000..cef9fd29
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/key154px_colorB.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/images/key154px_shiftcase.png b/src/virtualkeyboard/content/styles/retro/images/key154px_shiftcase.png
new file mode 100755
index 00000000..58bf8282
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/key154px_shiftcase.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/images/key154px_shiftcase_long.png b/src/virtualkeyboard/content/styles/retro/images/key154px_shiftcase_long.png
new file mode 100755
index 00000000..bfcba5fd
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/key154px_shiftcase_long.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/images/key156px_black_long.png b/src/virtualkeyboard/content/styles/retro/images/key156px_black_long.png
new file mode 100755
index 00000000..a22109bd
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/key156px_black_long.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/images/key156px_black_medium_long.png b/src/virtualkeyboard/content/styles/retro/images/key156px_black_medium_long.png
new file mode 100755
index 00000000..8c92d3b1
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/key156px_black_medium_long.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/images/key156px_colorA.png b/src/virtualkeyboard/content/styles/retro/images/key156px_colorA.png
new file mode 100755
index 00000000..6da57d60
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/key156px_colorA.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/images/key156px_colorB.png b/src/virtualkeyboard/content/styles/retro/images/key156px_colorB.png
new file mode 100755
index 00000000..af0912e3
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/key156px_colorB.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/images/key160px_black.png b/src/virtualkeyboard/content/styles/retro/images/key160px_black.png
new file mode 100755
index 00000000..565c4bf7
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/key160px_black.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/images/key160px_colorA.png b/src/virtualkeyboard/content/styles/retro/images/key160px_colorA.png
new file mode 100755
index 00000000..e2125cf8
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/key160px_colorA.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/images/key160px_colorB.png b/src/virtualkeyboard/content/styles/retro/images/key160px_colorB.png
new file mode 100755
index 00000000..9b543b05
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/key160px_colorB.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/images/key_preview.png b/src/virtualkeyboard/content/styles/retro/images/key_preview.png
new file mode 100755
index 00000000..3e9e9557
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/key_preview.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/images/shift.png b/src/virtualkeyboard/content/styles/retro/images/shift.png
new file mode 100755
index 00000000..ae5ad0b7
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/shift.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/images/triangle_black.png b/src/virtualkeyboard/content/styles/retro/images/triangle_black.png
new file mode 100755
index 00000000..a45e733b
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/triangle_black.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/images/triangle_highlight.png b/src/virtualkeyboard/content/styles/retro/images/triangle_highlight.png
new file mode 100755
index 00000000..34853263
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/triangle_highlight.png
Binary files differ
diff --git a/src/virtualkeyboard/content/styles/retro/style.qml b/src/virtualkeyboard/content/styles/retro/style.qml
new file mode 100644
index 00000000..a33c9608
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/style.qml
@@ -0,0 +1,667 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Enterprise.VirtualKeyboard.Styles 1.0
+
+KeyboardStyle {
+ readonly property string fontFamily: courierPrimeRegular.name
+ readonly property real keyBackgroundMargin: Math.round(9 * scaleHint)
+ readonly property real keyContentMargin: Math.round(50 * scaleHint)
+
+ property var courierPrimeRegular: FontLoader {
+ source: "qrc:/fonts/Courier Prime.ttf"
+ }
+ property var courierPrimeBold: FontLoader {
+ source: "qrc:/fonts/Courier Prime Bold.ttf"
+ }
+
+ keyboardDesignWidth: 2560
+ keyboardDesignHeight: 800
+ keyboardRelativeLeftMargin: 114 / keyboardDesignWidth
+ keyboardRelativeRightMargin: 114 / keyboardDesignWidth
+ keyboardRelativeTopMargin: 9 / keyboardDesignHeight
+ keyboardRelativeBottomMargin: 88 / keyboardDesignHeight
+
+ keyboardBackground: Rectangle {
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: "#272727" }
+ GradientStop { position: 1.0; color: "black" }
+ }
+ }
+
+ keyPanel: KeyPanel {
+ Image {
+ id: keyBackground
+ source: "qrc:/images/key154px_colorA.png"
+ fillMode: Image.PreserveAspectFit
+ anchors.fill: parent
+ anchors.margins: keyBackgroundMargin
+ states: [
+ State {
+ name: "key154px_colorB"
+ when: ['q', 'r', 'y', 'p', 's', 'd', 'j', 'l', 'v', 'b', '\'',
+ '1', '4', '6', '0', '#', '%', '+', ')', '>',
+ '~', '·', '÷', '}', '€', '£', '§', ']', '«', '»'].indexOf(control.displayText.toLowerCase()) >= 0
+ PropertyChanges {
+ target: keyBackground
+ source: "qrc:/images/key154px_colorB.png"
+ }
+ },
+ State {
+ name: "key154px_black"
+ when: control.displayText.length > 1
+ PropertyChanges {
+ target: keyBackground
+ source: "qrc:/images/key154px_black.png"
+ }
+ }
+ ]
+ }
+ Text {
+ id: keyText
+ text: control.displayText
+ color: "#110b05"
+ anchors.centerIn: parent
+ anchors.verticalCenterOffset: 18 * scaleHint
+ font {
+ family: fontFamily
+ weight: Font.Bold
+ pixelSize: 82 * scaleHint
+ capitalization: control.uppercased ? Font.AllUppercase : Font.MixedCase
+ }
+ states: [
+ State {
+ name: "fontB"
+ when: control.displayText.length > 1
+ PropertyChanges {
+ target: keyText
+ color: "#c5a96f"
+ font.pixelSize: 74 * scaleHint
+ font.letterSpacing: -10 * scaleHint
+ }
+ }
+ ]
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: control.pressed
+ PropertyChanges {
+ target: keyBackground
+ opacity: 0.70
+ }
+ PropertyChanges {
+ target: keyText
+ opacity: 0.75
+ }
+ },
+ State {
+ name: "disabled"
+ when: !control.enabled
+ PropertyChanges {
+ target: keyBackground
+ opacity: 0.30
+ }
+ PropertyChanges {
+ target: keyText
+ opacity: 0.50
+ }
+ }
+ ]
+ }
+
+ backspaceKeyPanel: KeyPanel {
+ BorderImage {
+ id: backspaceKeyBackground
+ source: "qrc:/images/key154px_black.png"
+ width: (parent.width - 2 * keyBackgroundMargin) / scale
+ height: sourceSize.height
+ anchors.centerIn: parent
+ border.left: 76
+ border.top: 76
+ border.right: 76
+ border.bottom: 76
+ horizontalTileMode: BorderImage.Stretch
+ scale: (parent.height - 2 * keyBackgroundMargin) / sourceSize.height
+ }
+ KeyIcon {
+ id: backspaceKeyIcon
+ source: "qrc:/images/backspace.png"
+ color: "#c5a96f"
+ anchors.fill: parent
+ anchors.margins: Math.round(keyContentMargin * 1.2)
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: control.pressed
+ PropertyChanges {
+ target: backspaceKeyBackground
+ opacity: 0.70
+ }
+ PropertyChanges {
+ target: backspaceKeyIcon
+ opacity: 0.70
+ }
+ },
+ State {
+ name: "disabled"
+ when: !control.enabled
+ PropertyChanges {
+ target: backspaceKeyBackground
+ opacity: 0.20
+ }
+ PropertyChanges {
+ target: backspaceKeyIcon
+ opacity: 0.20
+ }
+ }
+ ]
+ }
+
+ languageKeyPanel: KeyPanel {
+ Image {
+ id: languageKeyBackground
+ source: "qrc:/images/key154px_colorB.png"
+ fillMode: Image.PreserveAspectFit
+ anchors.fill: parent
+ anchors.margins: keyBackgroundMargin
+ }
+ KeyIcon {
+ id: languageKeyIcon
+ source: "qrc:/images/globe.png"
+ color: "#110b05"
+ anchors.fill: parent
+ anchors.margins: keyContentMargin
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: control.pressed
+ PropertyChanges {
+ target: languageKeyBackground
+ opacity: 0.70
+ }
+ PropertyChanges {
+ target: languageKeyIcon
+ opacity: 0.30
+ }
+ },
+ State {
+ name: "disabled"
+ when: !control.enabled
+ PropertyChanges {
+ target: languageKeyBackground
+ opacity: 0.75
+ }
+ PropertyChanges {
+ target: languageKeyIcon
+ opacity: 0.50
+ }
+ }
+ ]
+ }
+
+ enterKeyPanel: KeyPanel {
+ BorderImage {
+ id: enterKeyBackground
+ source: "qrc:/images/key154px_black.png"
+ width: (parent.width - 2 * keyBackgroundMargin) / scale
+ height: sourceSize.height
+ anchors.centerIn: parent
+ border.left: 76
+ border.top: 76
+ border.right: 76
+ border.bottom: 76
+ horizontalTileMode: BorderImage.Stretch
+ scale: (parent.height - 2 * keyBackgroundMargin) / sourceSize.height
+ }
+ KeyIcon {
+ id: enterKeyIcon
+ visible: control.displayText.length === 0
+ source: "qrc:/images/enter.png"
+ color: "#c5a96f"
+ anchors.fill: parent
+ anchors.topMargin: Math.round(59 * scaleHint)
+ anchors.bottomMargin: Math.round(59 * scaleHint)
+ anchors.leftMargin: Math.round(142 * scaleHint)
+ anchors.rightMargin: Math.round(59 * scaleHint)
+ }
+ Text {
+ id: enterKeyText
+ visible: control.displayText.length !== 0
+ text: control.displayText
+ clip: true
+ fontSizeMode: Text.HorizontalFit
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ anchors.fill: parent
+ anchors.leftMargin: keyContentMargin
+ anchors.topMargin: Math.round(60 * scaleHint)
+ anchors.rightMargin: keyContentMargin
+ anchors.bottomMargin: Math.round(30 * scaleHint)
+ color: "#c5a96f"
+ font {
+ family: fontFamily
+ weight: Font.Bold
+ pixelSize: 74 * scaleHint
+ capitalization: Font.AllUppercase
+ }
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: control.pressed
+ PropertyChanges {
+ target: enterKeyBackground
+ opacity: 0.70
+ }
+ PropertyChanges {
+ target: enterKeyIcon
+ opacity: 0.70
+ }
+ PropertyChanges {
+ target: enterKeyText
+ opacity: 0.70
+ }
+ },
+ State {
+ name: "disabled"
+ when: !control.enabled
+ PropertyChanges {
+ target: enterKeyBackground
+ opacity: 0.20
+ }
+ PropertyChanges {
+ target: enterKeyIcon
+ opacity: 0.20
+ }
+ PropertyChanges {
+ target: enterKeyText
+ opacity: 0.20
+ }
+ }
+ ]
+ }
+
+ hideKeyPanel: KeyPanel {
+ BorderImage {
+ id: hideKeyBackground
+ source: "qrc:/images/key154px_black.png"
+ width: (parent.width - 2 * keyBackgroundMargin) / scale
+ height: sourceSize.height
+ anchors.centerIn: parent
+ border.left: 76
+ border.top: 76
+ border.right: 76
+ border.bottom: 76
+ horizontalTileMode: BorderImage.Stretch
+ scale: (parent.height - 2 * keyBackgroundMargin) / sourceSize.height
+ }
+ KeyIcon {
+ id: hideKeyIcon
+ source: "qrc:/images/hidekeyboard.png"
+ color: "#c5a96f"
+ anchors.fill: parent
+ anchors.margins: keyContentMargin
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: control.pressed
+ PropertyChanges {
+ target: hideKeyBackground
+ opacity: 0.70
+ }
+ PropertyChanges {
+ target: hideKeyIcon
+ opacity: 0.70
+ }
+ },
+ State {
+ name: "disabled"
+ when: !control.enabled
+ PropertyChanges {
+ target: hideKeyBackground
+ opacity: 0.20
+ }
+ PropertyChanges {
+ target: hideKeyIcon
+ opacity: 0.20
+ }
+ }
+ ]
+ }
+
+ shiftKeyPanel: KeyPanel {
+ BorderImage {
+ id: shiftKeyBackground
+ source: "qrc:/images/key154px_black.png"
+ width: (parent.width - 2 * keyBackgroundMargin) / scale
+ height: sourceSize.height
+ anchors.centerIn: parent
+ border.left: 76
+ border.top: 76
+ border.right: 76
+ border.bottom: 76
+ horizontalTileMode: BorderImage.Stretch
+ scale: (parent.height - 2 * keyBackgroundMargin) / sourceSize.height
+ states: [
+ State {
+ name: "capslock"
+ when: control.capsLock
+ PropertyChanges {
+ target: shiftKeyBackground
+ source: "qrc:/images/key154px_capslock.png"
+ }
+ PropertyChanges {
+ target: shiftKeyIcon
+ color: "#cd8865"
+ }
+ },
+ State {
+ name: "shift"
+ when: control.shift
+ PropertyChanges {
+ target: shiftKeyBackground
+ source: "qrc:/images/key154px_shiftcase.png"
+ }
+ PropertyChanges {
+ target: shiftKeyIcon
+ color: "#dc4f28"
+ }
+ }
+ ]
+ }
+ KeyIcon {
+ id: shiftKeyIcon
+ source: "qrc:/images/shift.png"
+ color: "#c5a96f"
+ anchors.fill: parent
+ anchors.margins: keyContentMargin
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: control.pressed
+ PropertyChanges {
+ target: shiftKeyBackground
+ opacity: 0.70
+ }
+ PropertyChanges {
+ target: shiftKeyIcon
+ opacity: 0.70
+ }
+ },
+ State {
+ name: "disabled"
+ when: !control.enabled
+ PropertyChanges {
+ target: shiftKeyBackground
+ opacity: 0.20
+ }
+ PropertyChanges {
+ target: shiftKeyIcon
+ opacity: 0.20
+ }
+ }
+ ]
+ }
+
+ spaceKeyPanel: KeyPanel {
+ BorderImage {
+ id: spaceKeyBackground
+ source: "qrc:/images/key154px_colorA.png"
+ width: (parent.width - 2 * keyBackgroundMargin) / scale
+ height: sourceSize.height
+ anchors.centerIn: parent
+ border.left: 76
+ border.top: 76
+ border.right: 76
+ border.bottom: 76
+ horizontalTileMode: BorderImage.Stretch
+ scale: (parent.height - 2 * keyBackgroundMargin) / sourceSize.height
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: control.pressed
+ PropertyChanges {
+ target: spaceKeyBackground
+ opacity: 0.70
+ }
+ },
+ State {
+ name: "disabled"
+ when: !control.enabled
+ PropertyChanges {
+ target: spaceKeyBackground
+ opacity: 0.30
+ }
+ }
+ ]
+ }
+
+ symbolKeyPanel: KeyPanel {
+ BorderImage {
+ id: symbolKeyBackground
+ source: "qrc:/images/key154px_black.png"
+ width: (parent.width - 2 * keyBackgroundMargin) / scale
+ height: sourceSize.height
+ anchors.centerIn: parent
+ border.left: 76
+ border.top: 76
+ border.right: 76
+ border.bottom: 76
+ horizontalTileMode: BorderImage.Stretch
+ scale: (parent.height - 2 * keyBackgroundMargin) / sourceSize.height
+ }
+ Text {
+ id: symbolKeyText
+ text: control.displayText
+ color: "#c5a96f"
+ anchors.centerIn: parent
+ anchors.verticalCenterOffset: 12 * scaleHint
+ font {
+ family: fontFamily
+ weight: Font.DemiBold
+ pixelSize: 74 * scaleHint
+ letterSpacing: -5 * scaleHint
+ capitalization: Font.AllUppercase
+ }
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: control.pressed
+ PropertyChanges {
+ target: symbolKeyBackground
+ opacity: 0.70
+ }
+ PropertyChanges {
+ target: symbolKeyText
+ opacity: 0.70
+ }
+ },
+ State {
+ name: "disabled"
+ when: !control.enabled
+ PropertyChanges {
+ target: symbolKeyBackground
+ opacity: 0.20
+ }
+ PropertyChanges {
+ target: symbolKeyText
+ opacity: 0.20
+ }
+ }
+ ]
+ }
+
+ characterPreviewMargin: Math.round(20 * scaleHint)
+ characterPreviewDelegate: Item {
+ property string text
+ id: characterPreview
+ Image {
+ id: characterPreviewBackground
+ source: "qrc:/images/key_preview.png"
+ fillMode: Image.PreserveAspectFit
+ anchors.fill: parent
+ }
+ Text {
+ id: characterPreviewText
+ color: "#c5a96f"
+ text: characterPreview.text
+ anchors.centerIn: characterPreviewBackground
+ anchors.verticalCenterOffset: 18 * scaleHint
+ font {
+ family: fontFamily
+ weight: Font.Bold
+ pixelSize: 85 * scaleHint
+ }
+ states: [
+ State {
+ name: "fit"
+ when: text.length > 1
+ PropertyChanges {
+ target: characterPreviewText
+ font.letterSpacing: -10 * scaleHint
+ }
+ }
+ ]
+ }
+ }
+
+ alternateKeysListItemWidth: Math.round(111 * scaleHint)
+ alternateKeysListItemHeight: Math.round(154 * scaleHint)
+ alternateKeysListBottomMargin: Math.round(15 * scaleHint)
+ alternateKeysListLeftMargin: Math.round(79 * scaleHint)
+ alternateKeysListRightMargin: Math.round(79 * scaleHint)
+ alternateKeysListDelegate: Item {
+ id: alternateKeysListItem
+ width: alternateKeysListItemWidth
+ height: alternateKeysListItemHeight
+ Text {
+ id: listItemText
+ text: model.text
+ color: "#868482"
+ font {
+ family: fontFamily
+ weight: Font.DemiBold
+ pixelSize: 52 * scaleHint
+ letterSpacing: -6 * scaleHint
+ }
+ anchors.centerIn: parent
+ }
+ states: State {
+ name: "current"
+ when: alternateKeysListItem.ListView.isCurrentItem
+ PropertyChanges {
+ target: listItemText
+ color: "white"
+ }
+ }
+ }
+ alternateKeysListHighlight: Item {
+ Rectangle {
+ anchors.fill: parent
+ anchors.topMargin: Math.round(8 * scaleHint)
+ anchors.bottomMargin: Math.round(8 * scaleHint)
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: "#64462a" }
+ GradientStop { position: 0.18; color: "#a37648" }
+ GradientStop { position: 0.5; color: "#c4a47c" }
+ GradientStop { position: 0.82; color: "#a37648" }
+ GradientStop { position: 1.0; color: "#64462a" }
+ }
+ }
+ }
+ alternateKeysListBackground: Item {
+ property real currentItemOffset
+ property bool currentItemHighlight: false
+ BorderImage {
+ cache: false
+ source: "qrc:/images/key160px_black.png"
+ width: sourceSize.width + parent.width / scale
+ height: sourceSize.height
+ anchors.centerIn: parent
+ border.left: 79
+ border.top: 79
+ border.right: 79
+ border.bottom: 79
+ horizontalTileMode: BorderImage.Stretch
+ scale: parent.height / sourceSize.height
+ }
+ Image {
+ visible: currentItemOffset !== undefined
+ source: currentItemHighlight ? "qrc:/images/triangle_highlight.png" : "qrc:/images/triangle_black.png"
+ fillMode: Image.PreserveAspectFit
+ width: sourceSize.width * scaleHint
+ height: sourceSize.height * scaleHint
+ anchors.top: parent.bottom
+ anchors.topMargin: Math.round(-8 * scaleHint)
+ anchors.left: parent.left
+ anchors.leftMargin: Math.round(currentItemOffset - width / 2)
+ }
+ }
+
+ selectionListHeight: 85 * scaleHint
+ selectionListDelegate: SelectionListItem {
+ id: selectionListItem
+ width: Math.round(selectionListLabel.width + selectionListLabel.anchors.leftMargin * 2)
+ Text {
+ id: selectionListLabel
+ anchors.left: parent.left
+ anchors.leftMargin: Math.round(140 * scaleHint)
+ anchors.verticalCenter: parent.verticalCenter
+ text: decorateText(display, wordCompletionLength)
+ color: "white"
+ font {
+ family: fontFamily
+ weight: Font.Bold
+ pixelSize: 44 * scaleHint
+ }
+ function decorateText(text, wordCompletionLength) {
+ if (wordCompletionLength > 0) {
+ return text.slice(0, -wordCompletionLength) + '<u>' + text.slice(-wordCompletionLength) + '</u>'
+ }
+ return text
+ }
+ }
+ Rectangle {
+ id: selectionListSeparator
+ width: 4 * scaleHint
+ height: 36 * scaleHint
+ color: "#35322f"
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.right: parent.left
+ }
+ states: State {
+ name: "current"
+ when: selectionListItem.ListView.isCurrentItem
+ PropertyChanges {
+ target: selectionListLabel
+ color: "#c5a96f"
+ }
+ }
+ }
+ selectionListBackground: Rectangle {
+ color: "#222222"
+ }
+}
diff --git a/src/virtualkeyboard/content/styles/retro/style.qrc b/src/virtualkeyboard/content/styles/retro/style.qrc
new file mode 100644
index 00000000..4d4c41c8
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/style.qrc
@@ -0,0 +1,31 @@
+<RCC>
+ <qresource prefix="/">
+ <file>style.qml</file>
+ <file>fonts/Courier Prime.ttf</file>
+ <file>fonts/Courier Prime Bold.ttf</file>
+ <file>images/key154px_black.png</file>
+ <file>images/key154px_black_long.png</file>
+ <file>images/key154px_capslock_long.png</file>
+ <file>images/key154px_capslock.png</file>
+ <file>images/key154px_colorA_long.png</file>
+ <file>images/key154px_colorA.png</file>
+ <file>images/key154px_colorB.png</file>
+ <file>images/key154px_shiftcase_long.png</file>
+ <file>images/key154px_shiftcase.png</file>
+ <file>images/key156px_black_long.png</file>
+ <file>images/key156px_black_medium_long.png</file>
+ <file>images/key156px_colorA.png</file>
+ <file>images/key156px_colorB.png</file>
+ <file>images/key160px_black.png</file>
+ <file>images/key160px_colorA.png</file>
+ <file>images/key160px_colorB.png</file>
+ <file>images/key_preview.png</file>
+ <file>images/triangle_black.png</file>
+ <file>images/triangle_highlight.png</file>
+ <file>images/backspace.png</file>
+ <file>images/enter.png</file>
+ <file>images/hidekeyboard.png</file>
+ <file>images/shift.png</file>
+ <file>images/globe.png</file>
+ </qresource>
+</RCC>
diff --git a/src/virtualkeyboard/declarativeinputcontext.cpp b/src/virtualkeyboard/declarativeinputcontext.cpp
new file mode 100644
index 00000000..c7b2bbad
--- /dev/null
+++ b/src/virtualkeyboard/declarativeinputcontext.cpp
@@ -0,0 +1,673 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "declarativeinputcontext.h"
+#include "declarativeinputengine.h"
+#include "declarativeshifthandler.h"
+#include "platforminputcontext.h"
+#include "virtualkeyboarddebug.h"
+
+#include <QEvent>
+#include <QTextFormat>
+#include <QGuiApplication>
+
+/*!
+ \qmlmodule QtQuick.Enterprise.VirtualKeyboard 1.0
+
+ This module provides a collection of QML components for Qt Virtual Keyboard.
+*/
+
+/*!
+ \module InputFramework
+
+ \title Input Framework
+
+ \brief Contains classes for integrating input methods.
+*/
+
+class DeclarativeInputContextPrivate
+{
+public:
+ PlatformInputContext *inputContext;
+ DeclarativeInputEngine *inputEngine;
+ DeclarativeShiftHandler *shiftHandler;
+ QRectF keyboardRect;
+ bool animating;
+ bool focus;
+ bool shift;
+ bool capsLock;
+ int cursorPosition;
+ Qt::InputMethodHints inputMethodHints;
+ QString preeditText;
+ QString surroundingText;
+ QString selectedText;
+ QRectF cursorRectangle;
+};
+
+/*!
+ \qmltype InputContext
+ \instantiates DeclarativeInputContext
+ \inqmlmodule QtQuick.Enterprise.VirtualKeyboard 1.0
+ \brief Provides access to an input context.
+
+ The InputContext can be accessed as singleton instance.
+*/
+
+/*!
+ \class DeclarativeInputContext
+ \inmodule InputFramework
+ \brief Provides access to an input context.
+*/
+
+/*!
+ \internal
+ Constructs a declarative input context with \a parent as the platform input
+ context.
+*/
+DeclarativeInputContext::DeclarativeInputContext(PlatformInputContext *parent) :
+ QObject(parent),
+ d_ptr(new DeclarativeInputContextPrivate())
+{
+ Q_D(DeclarativeInputContext);
+ d->inputContext = parent;
+ if (d->inputContext) {
+ d->inputContext->setDeclarativeContext(this);
+ connect(d->inputContext, SIGNAL(focusObjectChanged()), SIGNAL(inputItemChanged()));
+ }
+ d->inputEngine = new DeclarativeInputEngine(this);
+ d->shiftHandler = new DeclarativeShiftHandler(this);
+}
+
+/*!
+ \internal
+ Destroys the input context and frees all allocated resources.
+*/
+DeclarativeInputContext::~DeclarativeInputContext()
+{
+ Q_D(DeclarativeInputContext);
+ if (d->inputContext)
+ d->inputContext->setDeclarativeContext(0);
+}
+
+bool DeclarativeInputContext::focus() const
+{
+ Q_D(const DeclarativeInputContext);
+ return d->focus;
+}
+
+bool DeclarativeInputContext::shift() const
+{
+ Q_D(const DeclarativeInputContext);
+ return d->shift;
+}
+
+void DeclarativeInputContext::setShift(bool enable)
+{
+ Q_D(DeclarativeInputContext);
+ if (d->shift != enable) {
+ d->shift = enable;
+ emit shiftChanged();
+ }
+}
+
+bool DeclarativeInputContext::capsLock() const
+{
+ Q_D(const DeclarativeInputContext);
+ return d->capsLock;
+}
+
+void DeclarativeInputContext::setCapsLock(bool enable)
+{
+ Q_D(DeclarativeInputContext);
+ if (d->capsLock != enable) {
+ d->capsLock = enable;
+ emit capsLockChanged();
+ }
+}
+
+int DeclarativeInputContext::cursorPosition() const
+{
+ Q_D(const DeclarativeInputContext);
+ return d->cursorPosition;
+}
+
+Qt::InputMethodHints DeclarativeInputContext::inputMethodHints() const
+{
+ Q_D(const DeclarativeInputContext);
+ return d->inputMethodHints;
+}
+
+QString DeclarativeInputContext::preeditText() const
+{
+ Q_D(const DeclarativeInputContext);
+ return d->preeditText;
+}
+
+void DeclarativeInputContext::setPreeditText(const QString &text)
+{
+ Q_D(DeclarativeInputContext);
+ if (text != d->preeditText)
+ sendPreedit(text);
+}
+
+QString DeclarativeInputContext::surroundingText() const
+{
+ Q_D(const DeclarativeInputContext);
+ return d->surroundingText;
+}
+
+QString DeclarativeInputContext::selectedText() const
+{
+ Q_D(const DeclarativeInputContext);
+ return d->selectedText;
+}
+
+QRectF DeclarativeInputContext::cursorRectangle() const
+{
+ Q_D(const DeclarativeInputContext);
+ return d->cursorRectangle;
+}
+
+QRectF DeclarativeInputContext::keyboardRectangle() const
+{
+ Q_D(const DeclarativeInputContext);
+ return d->keyboardRect;
+}
+
+void DeclarativeInputContext::setKeyboardRectangle(QRectF rectangle)
+{
+ Q_D(DeclarativeInputContext);
+ if (d->keyboardRect != rectangle) {
+ d->keyboardRect = rectangle;
+ emit keyboardRectangleChanged();
+ d->inputContext->emitKeyboardRectChanged();
+ }
+}
+
+bool DeclarativeInputContext::animating() const
+{
+ Q_D(const DeclarativeInputContext);
+ return d->animating;
+}
+
+void DeclarativeInputContext::setAnimating(bool animating)
+{
+ Q_D(DeclarativeInputContext);
+ if (d->animating != animating) {
+ d->animating = animating;
+ emit animatingChanged();
+ d->inputContext->emitAnimatingChanged();
+ }
+}
+
+
+QString DeclarativeInputContext::locale() const
+{
+ Q_D(const DeclarativeInputContext);
+ return d->inputContext->locale().name();
+}
+
+void DeclarativeInputContext::setLocale(const QString &locale)
+{
+ Q_D(DeclarativeInputContext);
+ VIRTUALKEYBOARD_DEBUG() << "DeclarativeInputContext::setLocale():" << locale;
+ QLocale newLocale(locale);
+ if (newLocale != d->inputContext->locale()) {
+ d->inputContext->setLocale(newLocale);
+ d->inputContext->setInputDirection(newLocale.textDirection());
+ emit localeChanged();
+ }
+}
+
+QObject *DeclarativeInputContext::inputItem() const
+{
+ Q_D(const DeclarativeInputContext);
+ return d->inputContext ? d->inputContext->focusObject() : 0;
+}
+
+DeclarativeShiftHandler *DeclarativeInputContext::shiftHandler() const
+{
+ Q_D(const DeclarativeInputContext);
+ return d->shiftHandler;
+}
+
+DeclarativeInputEngine *DeclarativeInputContext::inputEngine() const
+{
+ Q_D(const DeclarativeInputContext);
+ return d->inputEngine;
+}
+
+/*!
+ \qmlmethod void InputContext::hideInputPanel()
+
+ This method hides the input panel. This method should only be called
+ when the user initiates the hide, e.g. by pressing a dedicated button
+ on the keyboard.
+*/
+/*!
+ This method hides the input panel. This method should only be called
+ when the user initiates the hide, e.g. by pressing a dedicated button
+ on the keyboard.
+*/
+void DeclarativeInputContext::hideInputPanel()
+{
+ Q_D(DeclarativeInputContext);
+ d->inputContext->hideInputPanel();
+}
+
+/*!
+ \qmlmethod void InputContext::sendKeyClick(int key, string text, int modifiers = 0)
+
+ Sends a key click event with the given \a key, \a text and \a 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 DeclarativeInputContext::sendKeyClick(int key, const QString &text, int modifiers)
+{
+ Q_D(DeclarativeInputContext);
+ if (d->focus && d->inputContext) {
+ QKeyEvent pressEvent(QEvent::KeyPress, key, Qt::KeyboardModifiers(modifiers), text);
+ QKeyEvent releaseEvent(QEvent::KeyRelease, key, Qt::KeyboardModifiers(modifiers), text);
+ VIRTUALKEYBOARD_DEBUG() << "DeclarativeInputContext::::sendKeyClick():" << key;
+
+ d->inputContext->sendKeyEvent(&pressEvent);
+ d->inputContext->sendKeyEvent(&releaseEvent);
+ } else {
+ qWarning() << "DeclarativeInputContext::::sendKeyClick():" << key << "no focus";
+ }
+}
+
+/*!
+ \qmlmethod void InputContext::commit()
+
+ Commits the current pre-edit text.
+*/
+/*!
+ Commits the current pre-edit text.
+*/
+void DeclarativeInputContext::commit()
+{
+ Q_D(DeclarativeInputContext);
+ QString text = d->preeditText;
+ commit(text);
+}
+
+/*!
+ \qmlmethod void InputContext::commit(string text, int replacementStart = 0, int replacementEnd = 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 \a replacementStart is non-zero, the \a text replaces the
+ contents relative to \a replacementStart with length of
+ \a replacementLength.
+*/
+/*!
+ 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 replacementStart is non-zero, the \a text replaces the
+ contents relative to \a replacementStart with length of
+ \a replacementLength.
+*/
+void DeclarativeInputContext::commit(const QString &text, int replacementStart, int replacementLength)
+{
+ Q_D(DeclarativeInputContext);
+ VIRTUALKEYBOARD_DEBUG() << "DeclarativeInputContext::commit():" << text << replacementStart << replacementLength;
+ bool preeditChanged = !d->preeditText.isEmpty();
+ d->preeditText.clear();
+
+ if (d->inputContext) {
+ QInputMethodEvent inputEvent;
+ inputEvent.setCommitString(text, replacementStart, replacementLength);
+ d->inputContext->sendEvent(&inputEvent);
+ }
+
+ if (preeditChanged)
+ emit preeditTextChanged();
+}
+
+/*!
+ \qmlmethod void InputContext::clear()
+
+ Clears the pre-edit text.
+*/
+/*!
+ Clears the pre-edit text.
+*/
+void DeclarativeInputContext::clear()
+{
+ Q_D(DeclarativeInputContext);
+ bool preeditChanged = !d->preeditText.isEmpty();
+ d->preeditText.clear();
+
+ if (d->inputContext) {
+ QInputMethodEvent event;
+ d->inputContext->sendEvent(&event);
+ }
+
+ if (preeditChanged)
+ emit preeditTextChanged();
+}
+
+void DeclarativeInputContext::setFocus(bool enable)
+{
+ Q_D(DeclarativeInputContext);
+ if (d->focus != enable) {
+ VIRTUALKEYBOARD_DEBUG() << "DeclarativeInputContext::setFocus():" << enable;
+ d->focus = enable;
+ emit focusChanged();
+ }
+ emit focusEditorChanged();
+}
+
+void DeclarativeInputContext::sendPreedit(const QString &text, int cursor)
+{
+ Q_D(DeclarativeInputContext);
+ VIRTUALKEYBOARD_DEBUG() << "DeclarativeInputContext::sendPreedit():" << text << cursor;
+ const QString preedit = d->preeditText;
+ d->preeditText = text;
+
+ if (d->inputContext) {
+ QList<QInputMethodEvent::Attribute> attributes;
+
+ if (cursor >= 0 && cursor <= text.length()) {
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, cursor, text.length(), QVariant()));
+ }
+
+ if (!d->preeditText.isEmpty()) {
+ QTextCharFormat textFormat;
+ textFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline);
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, text.length(), textFormat));
+ }
+
+ QInputMethodEvent event(text, attributes);
+ d->inputContext->sendEvent(&event);
+ }
+
+ if (d->preeditText != preedit)
+ emit preeditTextChanged();
+}
+
+void DeclarativeInputContext::reset()
+{
+ Q_D(DeclarativeInputContext);
+ d->inputEngine->reset();
+}
+
+void DeclarativeInputContext::externalCommit()
+{
+ Q_D(DeclarativeInputContext);
+ d->inputEngine->update();
+}
+
+void DeclarativeInputContext::update(Qt::InputMethodQueries queries)
+{
+ Q_D(DeclarativeInputContext);
+ Q_UNUSED(queries);
+
+ // fetch
+ Qt::InputMethodHints inputMethodHints = Qt::InputMethodHints(d->inputContext->inputMethodQuery(Qt::ImHints).toInt());
+ int cursorPosition = d->inputContext->inputMethodQuery(Qt::ImCursorPosition).toInt();
+ QRectF cursorRectangle = qApp->inputMethod()->cursorRectangle();
+ QString surroundingText = d->inputContext->inputMethodQuery(Qt::ImSurroundingText).toString();
+ QString selectedText = d->inputContext->inputMethodQuery(Qt::ImCurrentSelection).toString();
+
+ // check against changes
+ bool newInputMethodHints = inputMethodHints != d->inputMethodHints;
+ bool newSurroundingText = surroundingText != d->surroundingText;
+ bool newSelectedTextChange = selectedText != d->selectedText;
+ bool newCursorPosition = cursorPosition != d->cursorPosition;
+ bool newCursorRectangle = cursorRectangle != d->cursorRectangle;
+
+ // update
+ d->inputMethodHints = inputMethodHints;
+ d->surroundingText = surroundingText;
+ d->selectedText = selectedText;
+ d->cursorPosition = cursorPosition;
+ d->cursorRectangle = cursorRectangle;
+
+ d->inputEngine->update();
+
+ // notify
+ if (newInputMethodHints) {
+ emit inputMethodHintsChanged();
+ }
+ if (newSurroundingText) {
+ emit surroundingTextChanged();
+ }
+ if (newSelectedTextChange) {
+ emit selectedTextChanged();
+ }
+ if (newCursorPosition) {
+ emit cursorPositionChanged();
+ }
+ if (newCursorRectangle) {
+ emit cursorRectangleChanged();
+ }
+}
+
+/*!
+ \qmlproperty bool InputContext::focus
+
+ This property is changed when the input method receives or loses focus.
+*/
+
+/*!
+ \property DeclarativeInputContext::focus
+ \brief the focus status.
+
+ This property is changed when the input method receives or loses focus.
+*/
+
+/*!
+ \qmlproperty bool InputContext::shift
+
+ This property is changed when the shift status changes.
+*/
+
+/*!
+ \property DeclarativeInputContext::shift
+ \brief the shift status.
+
+ This property is changed when the shift status changes.
+*/
+
+/*!
+ \qmlproperty bool InputContext::capsLock
+
+ This property is changed when the caps lock status changes.
+*/
+
+/*!
+ \property DeclarativeInputContext::capsLock
+ \brief the caps lock status.
+
+ This property is changed when the caps lock status changes.
+*/
+
+/*!
+ \qmlproperty int InputContext::cursorPosition
+
+ This property is changed when the cursor position changes.
+*/
+
+/*!
+ \property DeclarativeInputContext::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 DeclarativeInputContext::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 DeclarativeInputContext::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 DeclarativeInputContext::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 DeclarativeInputContext::selectedText
+ \brief the selected text.
+
+ This property is changed when the selected text changes.
+*/
+
+/*!
+ \qmlproperty int InputContext::cursorRectangle
+
+ This property is changed when the cursor rectangle changes.
+*/
+
+/*!
+ \property DeclarativeInputContext::cursorRectangle
+ \brief the cursor rectangle.
+
+ This property is changed when the cursor rectangle changes.
+*/
+
+/*!
+ \qmlproperty rect InputContext::keyboardRectangle
+
+ Use this property to set the keyboard rectangle.
+*/
+
+/*!
+ \property DeclarativeInputContext::keyboardRectangle
+ \brief the keyboard rectangle.
+
+ Use this property to set the keyboard rectangle.
+*/
+
+/*!
+ \qmlproperty bool InputContext::animating
+
+ Use this property to set the animating status, for example
+ during UI transitioning states.
+*/
+
+/*!
+ \property DeclarativeInputContext::animating
+ \brief the animating status.
+
+ Use this property to set the animating status, for example
+ during UI transitioning states.
+*/
+
+/*!
+ \qmlproperty string InputContext::locale
+
+ Sets the locale for this input context.
+*/
+
+/*!
+ \property DeclarativeInputContext::locale
+ \brief the locale.
+
+ Sets the locale for this input context.
+*/
+
+/*!
+ \qmlproperty QtObject InputContext::inputItem
+
+ This property is changed when the focused input item changes.
+*/
+
+/*!
+ \property DeclarativeInputContext::inputItem
+ \brief the focused input item.
+
+ This property is changed when the focused input item changes.
+*/
+
+/*!
+ \qmlproperty ShiftHandler InputContext::shiftHandler
+
+ This property stores the shift handler.
+*/
+
+/*!
+ \property DeclarativeInputContext::shiftHandler
+ \brief the shift handler instance.
+
+ This property stores the shift handler.
+*/
+
+/*!
+ \qmlproperty InputEngine InputContext::inputEngine
+
+ This property stores the input engine.
+*/
+
+/*!
+ \property DeclarativeInputContext::inputEngine
+ \brief the input engine.
+
+ This property stores the input engine.
+*/
+
+/*!
+ \qmlsignal InputContext::focusEditorChanged()
+
+ This signal is emitted when the focus editor changes.
+*/
+
+/*!
+ \fn void DeclarativeInputContext::focusEditorChanged()
+
+ This signal is emitted when the focus editor changes.
+*/
diff --git a/src/virtualkeyboard/declarativeinputcontext.h b/src/virtualkeyboard/declarativeinputcontext.h
new file mode 100644
index 00000000..3ba54370
--- /dev/null
+++ b/src/virtualkeyboard/declarativeinputcontext.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef DECLARATIVEINPUTCONTEXT_H
+#define DECLARATIVEINPUTCONTEXT_H
+
+#include <QObject>
+#include <QRectF>
+#include <QLocale>
+
+class PlatformInputContext;
+class DeclarativeInputEngine;
+class DeclarativeShiftHandler;
+class DeclarativeInputContextPrivate;
+
+class DeclarativeInputContext : public QObject
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(DeclarativeInputContext)
+ Q_DECLARE_PRIVATE(DeclarativeInputContext)
+ Q_PROPERTY(bool focus READ focus NOTIFY focusChanged)
+ Q_PROPERTY(bool shift READ shift WRITE setShift NOTIFY shiftChanged)
+ Q_PROPERTY(bool capsLock READ capsLock WRITE setCapsLock NOTIFY capsLockChanged)
+ 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)
+ Q_PROPERTY(QString surroundingText READ surroundingText NOTIFY surroundingTextChanged)
+ Q_PROPERTY(QString selectedText READ selectedText NOTIFY selectedTextChanged)
+ Q_PROPERTY(QRectF cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged)
+ Q_PROPERTY(QRectF keyboardRectangle READ keyboardRectangle WRITE setKeyboardRectangle NOTIFY keyboardRectangleChanged)
+ Q_PROPERTY(bool animating READ animating WRITE setAnimating NOTIFY animatingChanged)
+ Q_PROPERTY(QString locale READ locale WRITE setLocale NOTIFY localeChanged)
+ Q_PROPERTY(QObject *inputItem READ inputItem NOTIFY inputItemChanged)
+ Q_PROPERTY(DeclarativeShiftHandler *shiftHandler READ shiftHandler CONSTANT)
+ Q_PROPERTY(DeclarativeInputEngine *inputEngine READ inputEngine CONSTANT)
+
+public:
+ explicit DeclarativeInputContext(PlatformInputContext *parent = 0);
+ ~DeclarativeInputContext();
+
+ bool focus() const;
+ bool shift() const;
+ void setShift(bool enable);
+ bool capsLock() const;
+ void setCapsLock(bool enable);
+ int cursorPosition() const;
+ Qt::InputMethodHints inputMethodHints() const;
+ QString preeditText() const;
+ void setPreeditText(const QString &text);
+ QString surroundingText() const;
+ QString selectedText() const;
+ QRectF cursorRectangle() const;
+ QRectF keyboardRectangle() const;
+ void setKeyboardRectangle(QRectF rectangle);
+ bool animating() const;
+ void setAnimating(bool animating);
+ QString locale() const;
+ void setLocale(const QString &locale);
+ QObject *inputItem() const;
+ DeclarativeShiftHandler *shiftHandler() const;
+ DeclarativeInputEngine *inputEngine() const;
+
+ Q_INVOKABLE void hideInputPanel();
+ Q_INVOKABLE void sendKeyClick(int key, const QString &text, int modifiers = 0);
+ Q_INVOKABLE void commit();
+ Q_INVOKABLE void commit(const QString &text, int replacementStart = 0, int replacementEnd = 0);
+ Q_INVOKABLE void clear();
+
+signals:
+ void focusChanged();
+ void focusEditorChanged();
+ void preeditTextChanged();
+ void inputMethodHintsChanged();
+ void surroundingTextChanged();
+ void selectedTextChanged();
+ void cursorPositionChanged();
+ void cursorRectangleChanged();
+ void shiftChanged();
+ void capsLockChanged();
+ void keyboardRectangleChanged();
+ void animatingChanged();
+ void localeChanged();
+ void inputItemChanged();
+
+private:
+ void setFocus(bool enable);
+ void sendPreedit(const QString &text, int cursor = -1);
+ void reset();
+ void externalCommit();
+ void update(Qt::InputMethodQueries queries);
+
+private:
+ friend class PlatformInputContext;
+ QScopedPointer<DeclarativeInputContextPrivate> d_ptr;
+};
+
+#endif
diff --git a/src/virtualkeyboard/declarativeinputengine.cpp b/src/virtualkeyboard/declarativeinputengine.cpp
new file mode 100644
index 00000000..548543c6
--- /dev/null
+++ b/src/virtualkeyboard/declarativeinputengine.cpp
@@ -0,0 +1,733 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "declarativeinputengine.h"
+#include "declarativeinputcontext.h"
+#include "defaultinputmethod.h"
+#include "virtualkeyboarddebug.h"
+
+#include <QTimerEvent>
+
+class DeclarativeInputEnginePrivate
+{
+public:
+ virtual ~DeclarativeInputEnginePrivate() { }
+ DeclarativeInputContext *inputContext;
+ QPointer<AbstractInputMethod> inputMethod;
+ AbstractInputMethod *defaultInputMethod;
+ DeclarativeInputEngine::TextCase textCase;
+ DeclarativeInputEngine::InputMode inputMode;
+ QMap<DeclarativeSelectionListModel::Type, DeclarativeSelectionListModel *> selectionListModels;
+ Qt::Key activeKey;
+ QString activeKeyText;
+ Qt::KeyboardModifiers activeKeyModifiers;
+ Qt::Key previousKey;
+ int repeatTimer;
+ int repeatCount;
+ int recursiveMethodLock;
+};
+
+class RecursiveMethodGuard
+{
+public:
+ explicit RecursiveMethodGuard(int &ref) : m_ref(ref)
+ {
+ m_ref++;
+ }
+ ~RecursiveMethodGuard()
+ {
+ m_ref--;
+ }
+ bool locked() const
+ {
+ return m_ref > 1;
+ }
+private:
+ int &m_ref;
+};
+
+/*!
+ \qmltype InputEngine
+ \inqmlmodule QtQuick.Enterprise.VirtualKeyboard 1.0
+ \instantiates DeclarativeInputEngine
+ \brief Maps the user input to the input methods.
+
+ The input engine is responsible for routing input events to input
+ methods. The actual input logic is implemented by the input methods.
+
+ The input engine also includes the default input method, which takes
+ care of default processing if the active input method does not handle
+ the event.
+*/
+
+/*!
+ \class DeclarativeInputEngine
+ \inmodule InputFramework
+ \brief The DeclarativeInputEngine class provides an input engine
+ that supports C++ and QML integration.
+
+ The input engine is responsible for routing input events to input
+ methods. The actual input logic is implemented by the input methods.
+
+ The input engine also includes the default input method, which takes
+ care of default processing if the active input method does not handle
+ the event.
+*/
+
+/*!
+ \internal
+ Constructs an input engine with input context as \a parent.
+*/
+DeclarativeInputEngine::DeclarativeInputEngine(DeclarativeInputContext *parent) :
+ QObject(parent),
+ d_ptr(new DeclarativeInputEnginePrivate())
+{
+ Q_D(DeclarativeInputEngine);
+ d->inputContext = parent;
+ if (d->inputContext) {
+ connect(d->inputContext, SIGNAL(shiftChanged()), SLOT(shiftChanged()));
+ connect(d->inputContext, SIGNAL(localeChanged()), SLOT(localeChanged()));
+ }
+ d->defaultInputMethod = new DefaultInputMethod(this);
+ if (d->defaultInputMethod)
+ d->defaultInputMethod->setInputEngine(this);
+ d->textCase = Lower;
+ d->inputMode = Latin;
+ d->selectionListModels[DeclarativeSelectionListModel::WordCandidateList] = new DeclarativeSelectionListModel(this);
+ d->activeKey = Qt::Key_unknown;
+ d->previousKey = Qt::Key_unknown;
+}
+
+/*!
+ \internal
+ Destroys the input engine and frees all allocated resources.
+*/
+DeclarativeInputEngine::~DeclarativeInputEngine()
+{
+}
+
+/*!
+ \qmlmethod bool InputEngine::virtualKeyPress(int key, string text, int modifiers, bool repeat)
+
+ Called by the keyboard layer to indicate that \a key was pressed, with
+ the given \a text and \a modifiers.
+
+ The \a key is set as an active key (down key). The actual key event is
+ triggered when the key is released by the virtualKeyRelease() method. The
+ key press event can be discarded by calling virtualKeyCancel().
+
+ The key press also initiates the key repeat timer if \a repeat is \c true.
+
+ Returns \c true if the key was accepted by this input engine.
+
+ \sa virtualKeyCancel(), virtualKeyRelease()
+*/
+/*!
+ Called by the keyboard layer to indicate that \a key was pressed, with
+ the given \a text and \a modifiers.
+
+ The \a key is set as an active key (down key). The actual key event is
+ triggered when the key is released by the virtualKeyRelease() method. The
+ key press event can be discarded by calling virtualKeyCancel().
+
+ The key press also initiates the key repeat timer if \a repeat is \c true.
+
+ Returns \c true if the key was accepted by this input engine.
+
+ \sa virtualKeyCancel(), virtualKeyRelease()
+*/
+bool DeclarativeInputEngine::virtualKeyPress(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers, bool repeat)
+{
+ Q_D(DeclarativeInputEngine);
+ VIRTUALKEYBOARD_DEBUG() << "DeclarativeInputEngine::virtualKeyPress():" << key << text << modifiers << repeat;
+ bool accept = false;
+ if (d->activeKey == Qt::Key_unknown || d->activeKey == key) {
+ d->activeKey = key;
+ d->activeKeyText = text;
+ d->activeKeyModifiers = modifiers;
+ if (repeat) {
+ d->repeatTimer = startTimer(600);
+ }
+ accept = true;
+ emit activeKeyChanged(d->activeKey);
+ } else {
+ qWarning("key press ignored; key is already active");
+ }
+ return accept;
+}
+
+/*!
+ \qmlmethod void InputEngine::virtualKeyCancel()
+
+ Reverts the active key state without emitting the key event.
+ This method is useful when the user discards the current key and
+ the key state needs to be restored.
+*/
+/*!
+ Reverts the active key state without emitting the key event.
+ This method is useful when the user discards the current key and
+ the key state needs to be restored.
+*/
+void DeclarativeInputEngine::virtualKeyCancel()
+{
+ Q_D(DeclarativeInputEngine);
+ VIRTUALKEYBOARD_DEBUG() << "DeclarativeInputEngine::virtualKeyCancel()";
+ if (d->activeKey != Qt::Key_unknown) {
+ d->activeKey = Qt::Key_unknown;
+ d->activeKeyText = QString();
+ d->activeKeyModifiers = Qt::KeyboardModifiers();
+ if (d->repeatTimer) {
+ killTimer(d->repeatTimer);
+ d->repeatTimer = 0;
+ d->repeatCount = 0;
+ }
+ emit activeKeyChanged(d->activeKey);
+ }
+}
+
+/*!
+ \qmlmethod bool InputEngine::virtualKeyRelease(int key, string text, int modifiers)
+
+ Releases the key at \a key. The method emits a key event for the input
+ method if the event has not been generated by a repeating timer.
+ The \a text and \a modifiers are passed to the input method.
+
+ Returns \c true if the key was accepted by the input engine.
+*/
+/*!
+ Releases the key at \a key. The method emits a key event for the input
+ method if the event has not been generated by a repeating timer.
+ The \a text and \a modifiers are passed to the input method.
+
+ Returns \c true if the key was accepted by the input engine.
+*/
+bool DeclarativeInputEngine::virtualKeyRelease(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers)
+{
+ Q_D(DeclarativeInputEngine);
+ VIRTUALKEYBOARD_DEBUG() << "DeclarativeInputEngine::virtualKeyRelease():" << key << text << modifiers;
+ bool accept = false;
+ if (d->activeKey == key) {
+ if (!d->repeatCount) {
+ accept = virtualKeyClick(key, text, modifiers);
+ } else {
+ accept = true;
+ }
+ } else {
+ qWarning("key release ignored; key is not pressed");
+ }
+ if (d->activeKey != Qt::Key_unknown) {
+ d->previousKey = d->activeKey;
+ emit previousKeyChanged(d->previousKey);
+ d->activeKey = Qt::Key_unknown;
+ d->activeKeyText = QString();
+ d->activeKeyModifiers = Qt::KeyboardModifiers();
+ if (d->repeatTimer) {
+ killTimer(d->repeatTimer);
+ d->repeatTimer = 0;
+ d->repeatCount = 0;
+ }
+ emit activeKeyChanged(d->activeKey);
+ }
+ return accept;
+}
+
+/*!
+ \qmlmethod bool InputEngine::virtualKeyClick(int key, string text, int modifiers)
+
+ Emits a key click event for the given \a key, \a text and \a modifiers.
+ Returns \c true if the key event was accepted by the input engine.
+*/
+/*!
+ Emits a key click event for the given \a key, \a text and \a modifiers.
+ Returns \c true if the key event was accepted by the input engine.
+*/
+bool DeclarativeInputEngine::virtualKeyClick(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers)
+{
+ Q_D(DeclarativeInputEngine);
+ bool accept = false;
+ if (d->inputMethod) {
+ RecursiveMethodGuard guard(d->recursiveMethodLock);
+ if (!guard.locked()) {
+ accept = d->inputMethod->keyEvent(key, text, modifiers);
+ if (!accept) {
+ accept = d->defaultInputMethod->keyEvent(key, text, modifiers);
+ }
+ emit virtualKeyClicked(key, text, modifiers);
+ }
+ } else {
+ qWarning() << "input method is not set";
+ }
+ return accept;
+}
+
+/*!
+ Returns the \c DeclarativeInputContext instance associated with the input
+ engine.
+*/
+DeclarativeInputContext *DeclarativeInputEngine::inputContext() const
+{
+ Q_D(const DeclarativeInputEngine);
+ return d->inputContext;
+}
+
+/*!
+ Returns the currently active key, or Qt::Key_unknown if no key is active.
+*/
+Qt::Key DeclarativeInputEngine::activeKey() const
+{
+ Q_D(const DeclarativeInputEngine);
+ return d->activeKey;
+}
+
+/*!
+ Returns the previously active key, or Qt::Key_unknown if no key has been
+ active.
+*/
+Qt::Key DeclarativeInputEngine::previousKey() const
+{
+ Q_D(const DeclarativeInputEngine);
+ return d->previousKey;
+}
+
+/*!
+ Returns the active input method.
+*/
+AbstractInputMethod *DeclarativeInputEngine::inputMethod() const
+{
+ Q_D(const DeclarativeInputEngine);
+ return d->inputMethod;
+}
+
+/*!
+ Sets \a inputMethod as the active input method.
+*/
+void DeclarativeInputEngine::setInputMethod(AbstractInputMethod *inputMethod)
+{
+ Q_D(DeclarativeInputEngine);
+ VIRTUALKEYBOARD_DEBUG() << "DeclarativeInputEngine::setInputMethod():" << inputMethod;
+ if (!d->inputMethod || !inputMethod || d->inputMethod->className() != inputMethod->className()) {
+ update();
+ if (d->inputMethod) {
+ d->inputMethod->setInputEngine(0);
+ }
+ d->inputMethod = inputMethod;
+ if (d->inputMethod) {
+ d->inputMethod->setInputEngine(this);
+
+ // Allocate selection lists for the input method
+ QList<DeclarativeSelectionListModel::Type> activeSelectionLists = d->inputMethod->selectionLists();
+ QList<DeclarativeSelectionListModel::Type> inactiveSelectionLists = d->selectionListModels.keys();
+ foreach (const DeclarativeSelectionListModel::Type &selectionListType, activeSelectionLists) {
+ if (!d->selectionListModels.contains(selectionListType)) {
+ d->selectionListModels[selectionListType] = new DeclarativeSelectionListModel(this);
+ if (selectionListType == DeclarativeSelectionListModel::WordCandidateList) {
+ emit wordCandidateListModelChanged();
+ }
+ }
+ d->selectionListModels[selectionListType]->setDataSource(inputMethod, selectionListType);
+ if (selectionListType == DeclarativeSelectionListModel::WordCandidateList) {
+ emit wordCandidateListVisibleHintChanged();
+ }
+ inactiveSelectionLists.removeAll(selectionListType);
+ }
+
+ // Deallocate inactive selection lists
+ foreach (const DeclarativeSelectionListModel::Type &selectionListType, inactiveSelectionLists) {
+ if (d->selectionListModels.contains(selectionListType)) {
+ d->selectionListModels[selectionListType]->setDataSource(0, selectionListType);
+ if (selectionListType == DeclarativeSelectionListModel::WordCandidateList) {
+ emit wordCandidateListVisibleHintChanged();
+ }
+ }
+ }
+ }
+ emit inputMethodChanged();
+ emit inputModesChanged();
+ }
+}
+
+/*!
+ Returns the list of available input modes.
+*/
+QList<int> DeclarativeInputEngine::inputModes() const
+{
+ Q_D(const DeclarativeInputEngine);
+ QList<InputMode> inputModeList;
+ if (d->inputMethod) {
+ inputModeList = d->inputMethod->inputModes(d->inputContext->locale());
+ }
+ if (inputModeList.isEmpty()) {
+ return QList<int>();
+ }
+ QList<int> resultList;
+ foreach (const InputMode &inputMode, inputModeList) {
+ resultList.append(inputMode);
+ }
+ return resultList;
+}
+
+DeclarativeInputEngine::InputMode DeclarativeInputEngine::inputMode() const
+{
+ Q_D(const DeclarativeInputEngine);
+ return d->inputMode;
+}
+
+void DeclarativeInputEngine::setInputMode(DeclarativeInputEngine::InputMode inputMode)
+{
+ Q_D(DeclarativeInputEngine);
+ VIRTUALKEYBOARD_DEBUG() << "DeclarativeInputEngine::setInputMode():" << inputMode;
+ if (d->inputMethod) {
+ const QString locale(d->inputContext->locale());
+ QList<DeclarativeInputEngine::InputMode> inputModeList(d->inputMethod->inputModes(locale));
+ if (inputModeList.contains(inputMode)) {
+ d->inputMethod->setInputMode(locale, d->inputMode);
+ d->inputMode = inputMode;
+ emit inputModeChanged();
+ } else {
+ qWarning() << "the input mode" << inputMode << "is not valid";
+ }
+ }
+}
+
+DeclarativeSelectionListModel *DeclarativeInputEngine::wordCandidateListModel() const
+{
+ Q_D(const DeclarativeInputEngine);
+ return d->selectionListModels[DeclarativeSelectionListModel::WordCandidateList];
+}
+
+bool DeclarativeInputEngine::wordCandidateListVisibleHint() const
+{
+ Q_D(const DeclarativeInputEngine);
+ if (!d->selectionListModels.contains(DeclarativeSelectionListModel::WordCandidateList))
+ return false;
+ return d->selectionListModels[DeclarativeSelectionListModel::WordCandidateList]->dataSource() != 0;
+}
+
+/*!
+ \internal
+ Resets the input method.
+*/
+void DeclarativeInputEngine::reset()
+{
+ Q_D(DeclarativeInputEngine);
+ if (d->inputMethod) {
+ RecursiveMethodGuard guard(d->recursiveMethodLock);
+ if (!guard.locked()) {
+ emit inputMethodReset();
+ }
+ }
+}
+
+/*!
+ \internal
+ Updates the input method's state. This method is called whenever the input
+ context is changed.
+*/
+void DeclarativeInputEngine::update()
+{
+ Q_D(DeclarativeInputEngine);
+ if (d->inputMethod) {
+ RecursiveMethodGuard guard(d->recursiveMethodLock);
+ if (!guard.locked()) {
+ emit inputMethodUpdate();
+ }
+ }
+}
+
+/*!
+ \internal
+ Updates the text case for the input method.
+*/
+void DeclarativeInputEngine::shiftChanged()
+{
+ Q_D(DeclarativeInputEngine);
+ TextCase newCase = d->inputContext->shift() ? Upper : Lower;
+ if (d->textCase == newCase) {
+ d->textCase = newCase;
+ if (d->inputMethod) {
+ d->inputMethod->setTextCase(d->textCase);
+ }
+ }
+}
+
+/*!
+ \internal
+ Updates the input mode when the locale has changed.
+*/
+void DeclarativeInputEngine::localeChanged()
+{
+ Q_D(DeclarativeInputEngine);
+ update();
+ setInputMode(d->inputMode);
+}
+
+/*!
+ \internal
+*/
+void DeclarativeInputEngine::timerEvent(QTimerEvent *timerEvent)
+{
+ Q_D(DeclarativeInputEngine);
+ if (timerEvent->timerId() == d->repeatTimer) {
+ d->repeatTimer = 0;
+ virtualKeyClick(d->activeKey, d->activeKeyText, d->activeKeyModifiers);
+ d->repeatTimer = startTimer(50);
+ d->repeatCount++;
+ }
+}
+
+/*!
+ \qmlproperty int InputEngine::activeKey
+
+ Currently pressed key.
+*/
+
+/*!
+ \property DeclarativeInputEngine::activeKey
+ \brief the active key.
+
+ Currently pressed key.
+*/
+
+/*!
+ \qmlproperty int InputEngine::previousKey
+
+ Previously pressed key.
+*/
+/*!
+ \property DeclarativeInputEngine::previousKey
+ \brief the previous active key.
+
+ Previously pressed key.
+*/
+
+/*!
+ \qmlproperty InputMethod InputEngine::inputMethod
+
+ Use this property to set the active input method, or to monitor when the
+ active input method changes.
+*/
+
+/*!
+ \property DeclarativeInputEngine::inputMethod
+ \brief the active input method.
+
+ Use this property to set active the input method, or to monitor when the
+ active input method changes.
+*/
+
+/*!
+ \qmlproperty list<int> InputEngine::inputModes
+
+ The list of available input modes is dependent on the input method and
+ locale. This property is updated when either of the dependencies change.
+*/
+
+/*!
+ \property DeclarativeInputEngine::inputModes
+ \brief the available input modes for active input method.
+
+ The list of available input modes is dependent on the input method and
+ locale. This property is updated when either of the dependencies changes.
+*/
+
+/*!
+ \qmlproperty int InputEngine::inputMode
+
+ Use this property to get or set the current input mode. The
+ InputEngine::inputModes property provides the list of valid input modes
+ for the current input method and locale.
+
+ The predefined input modes are:
+
+ \list
+ \li \c InputEngine.Latin The default input mode for latin text.
+ \li \c InputEngine.Numeric Only numeric input is allowed.
+ \li \c InputEngine.Dialable Only dialable input is allowed.
+ \endlist
+*/
+
+/*!
+ \property DeclarativeInputEngine::inputMode
+ \brief the current input mode.
+
+ Use this property to get or set the current input mode. The
+ DeclarativeInputEngine::inputModes provides list of valid input modes
+ for current input method and locale.
+*/
+
+/*!
+ \qmlproperty SelectionListModel InputEngine::wordCandidateListModel
+
+ Use this property to access the list model for the word candidate
+ list.
+*/
+
+/*!
+ \property DeclarativeInputEngine::wordCandidateListModel
+ \brief list model for the word candidate list.
+
+ Use this property to access the list model for the word candidate
+ list.
+*/
+
+/*!
+ \qmlproperty bool InputEngine::wordCandidateListVisibleHint
+
+ Use this property to check if the word candidate list should be visible
+ in the UI.
+*/
+
+/*!
+ \property DeclarativeInputEngine::wordCandidateListVisibleHint
+ \brief visible hint for the word candidate list.
+
+ Use this property to check if the word candidate list should be visible
+ in the UI.
+*/
+
+/*!
+ \enum DeclarativeInputEngine::InputMode
+
+ This enum specifies the input mode for the input method.
+
+ \value Latin
+ The default input mode for latin text.
+ \value Numeric
+ Only numeric input is allowed.
+ \value Dialable
+ Only dialable input is allowed.
+*/
+
+/*!
+ \enum DeclarativeInputEngine::TextCase
+
+ This enum specifies the text case for the input method.
+
+ \value Lower
+ Lower case text.
+ \value Upper
+ Upper case text.
+*/
+
+/*!
+ \qmlsignal void InputEngine::virtualKeyClicked(int key, string text, int modifiers)
+
+ Indicates that the virtual \a key was clicked with the given \a text and
+ \a modifiers.
+ This signal is emitted after the input method has processed the key event.
+*/
+
+/*!
+ \fn void DeclarativeInputEngine::virtualKeyClicked(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers)
+
+ Indicates that the virtual \a key was clicked with the given \a text and
+ \a modifiers.
+ This signal is emitted after the input method has processed the key event.
+*/
+
+/*!
+ \qmlsignal void InputEngine::activeKeyChanged(int key)
+
+ Indicates that the active \a key has changed.
+*/
+
+/*!
+ \fn void DeclarativeInputEngine::activeKeyChanged(Qt::Key key)
+
+ Indicates that the active \a key has changed.
+*/
+
+/*!
+ \qmlsignal void InputEngine::previousKeyChanged(int key)
+
+ Indicates that the previous \a key has changed.
+*/
+
+/*!
+ \fn void DeclarativeInputEngine::previousKeyChanged(Qt::Key key)
+
+ Indicates that the previous \a key has changed.
+*/
+
+/*!
+ \qmlsignal void InputEngine::inputMethodChanged()
+
+ Indicates that the input method has changed.
+*/
+
+/*!
+ \fn void DeclarativeInputEngine::inputMethodChanged()
+
+ Indicates that the input method has changed.
+*/
+
+/*!
+ \qmlsignal void InputEngine::inputMethodReset()
+
+ Emitted when the input method needs to be reset.
+
+ \note This signal is automatically connected to AbstractInputMethod::reset()
+ and InputMethod::reset() when the input method is activated.
+*/
+
+/*!
+ \fn void DeclarativeInputEngine::inputMethodReset()
+
+ Emitted when the input method needs to be reset.
+
+ \note This signal is automatically connected to AbstractInputMethod::reset()
+ and InputMethod::reset() when the input method is activated.
+*/
+
+/*!
+ \qmlsignal void InputEngine::inputMethodUpdate()
+
+ \note This signal is automatically connected to AbstractInputMethod::update()
+ and InputMethod::update() when the input method is activated.
+*/
+
+/*!
+ \fn void DeclarativeInputEngine::inputMethodUpdate()
+
+ \note This signal is automatically connected to AbstractInputMethod::update()
+ and InputMethod::update() when the input method is activated.
+*/
+
+/*!
+ \qmlsignal void InputEngine::inputModesChanged()
+
+ Indicates that the available input modes have changed.
+*/
+
+/*!
+ \fn void DeclarativeInputEngine::inputModesChanged()
+
+ Indicates that the available input modes have changed.
+*/
+
+/*!
+ \qmlsignal void InputEngine::inputModeChanged()
+
+ Indicates that the input mode has changed.
+*/
+
+/*!
+ \fn void DeclarativeInputEngine::inputModeChanged()
+
+ Indicates that the input mode has changed.
+*/
diff --git a/src/virtualkeyboard/declarativeinputengine.h b/src/virtualkeyboard/declarativeinputengine.h
new file mode 100644
index 00000000..280fe9f5
--- /dev/null
+++ b/src/virtualkeyboard/declarativeinputengine.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef INPUTENGINE_H
+#define INPUTENGINE_H
+
+#include <QObject>
+#include <QPointer>
+
+class DeclarativeInputContext;
+class DeclarativeSelectionListModel;
+class AbstractInputMethod;
+class DeclarativeInputEnginePrivate;
+
+class DeclarativeInputEngine : public QObject
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(DeclarativeInputEngine)
+ Q_DECLARE_PRIVATE(DeclarativeInputEngine)
+ Q_ENUMS(TextCase)
+ Q_ENUMS(InputMode)
+ Q_PROPERTY(Qt::Key activeKey READ activeKey NOTIFY activeKeyChanged)
+ Q_PROPERTY(Qt::Key previousKey READ previousKey NOTIFY previousKeyChanged)
+ Q_PROPERTY(AbstractInputMethod *inputMethod READ inputMethod WRITE setInputMethod NOTIFY inputMethodChanged)
+ Q_PROPERTY(QList<int> inputModes READ inputModes NOTIFY inputModesChanged)
+ Q_PROPERTY(InputMode inputMode READ inputMode WRITE setInputMode NOTIFY inputModeChanged)
+ Q_PROPERTY(DeclarativeSelectionListModel *wordCandidateListModel READ wordCandidateListModel NOTIFY wordCandidateListModelChanged)
+ Q_PROPERTY(bool wordCandidateListVisibleHint READ wordCandidateListVisibleHint NOTIFY wordCandidateListVisibleHintChanged)
+
+ explicit DeclarativeInputEngine(DeclarativeInputContext *parent = 0);
+
+public:
+ enum TextCase {
+ Lower,
+ Upper
+ };
+ enum InputMode {
+ Latin,
+ Numeric,
+ Dialable
+ };
+
+public:
+ ~DeclarativeInputEngine();
+
+ Q_INVOKABLE bool virtualKeyPress(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers, bool repeat);
+ Q_INVOKABLE void virtualKeyCancel();
+ Q_INVOKABLE bool virtualKeyRelease(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers);
+ Q_INVOKABLE bool virtualKeyClick(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers);
+
+ DeclarativeInputContext *inputContext() const;
+ Qt::Key activeKey() const;
+ Qt::Key previousKey() const;
+
+ AbstractInputMethod *inputMethod() const;
+ void setInputMethod(AbstractInputMethod *inputMethod);
+
+ QList<int> inputModes() const;
+
+ InputMode inputMode() const;
+ void setInputMode(InputMode inputMode);
+
+ DeclarativeSelectionListModel *wordCandidateListModel() const;
+ bool wordCandidateListVisibleHint() const;
+
+signals:
+ void virtualKeyClicked(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers);
+ void activeKeyChanged(Qt::Key key);
+ void previousKeyChanged(Qt::Key key);
+ void inputMethodChanged();
+ void inputMethodReset();
+ void inputMethodUpdate();
+ void inputModesChanged();
+ void inputModeChanged();
+ void wordCandidateListModelChanged();
+ void wordCandidateListVisibleHintChanged();
+
+private slots:
+ void reset();
+ void update();
+ void shiftChanged();
+ void localeChanged();
+
+protected:
+ void timerEvent(QTimerEvent *timerEvent);
+
+private:
+ friend class DeclarativeInputContext;
+ const QScopedPointer<DeclarativeInputEnginePrivate> d_ptr;
+};
+
+Q_DECLARE_METATYPE(DeclarativeInputEngine::TextCase)
+Q_DECLARE_METATYPE(DeclarativeInputEngine::InputMode)
+
+#endif
diff --git a/src/virtualkeyboard/declarativeinputmethod.cpp b/src/virtualkeyboard/declarativeinputmethod.cpp
new file mode 100644
index 00000000..980d25d3
--- /dev/null
+++ b/src/virtualkeyboard/declarativeinputmethod.cpp
@@ -0,0 +1,258 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "declarativeinputmethod.h"
+#include <QVariant>
+
+/*!
+ \qmltype InputMethod
+ \instantiates DeclarativeInputMethod
+ \inqmlmodule QtQuick.Enterprise.VirtualKeyboard 1.0
+ \brief Base type for creating input method in QML.
+
+ The InputMethod type lets you create a custom input method
+ which can be assigned to InputEngine.
+*/
+
+/*!
+ \qmlproperty string InputMethod::className
+
+ See AbstractInputMethod::className.
+*/
+
+/*!
+ \qmlproperty InputContext InputMethod::inputContext
+
+ The input context.
+*/
+
+/*!
+ \qmlproperty InputEngine InputMethod::inputEngine
+
+ The input engine.
+*/
+
+/*!
+ \qmlmethod list<int> InputMethod::inputModes(string locale)
+
+ Returns a list of input modes for \a locale.
+*/
+
+/*!
+ \qmlmethod bool InputMethod::setInputMode(string locale, int inputMode)
+
+ Changes \a inputMode and \a locale for this input method. The method returns
+ \c true if successful.
+*/
+
+/*!
+ \qmlmethod bool InputMethod::setTextCase(int textCase)
+
+ Updates \a textCase for this input method. The method returns \c true if
+ successful.
+
+ The possible values for the text case are:
+
+ \list
+ \li \c InputEngine.Lower Lower case text.
+ \li \c InputEngine.Upper Upper case text.
+ \endlist
+*/
+
+/*!
+ \qmlmethod bool InputMethod::keyEvent(int key, string text, int modifiers)
+
+ The purpose of this method is to handle the key events generated by the the
+ input engine.
+
+ The \a key parameter specifies the code of the key to handle. The key code
+ does not distinguish between capital and non-capital letters. The \a
+ text parameter contains the Unicode text for the key. The \a modifiers
+ parameter contains the key modifiers that apply to \a key.
+
+ This method returns \c true if the key event was successfully handled.
+ If the return value is \c false, the key event is redirected to the default
+ input method for futher processing.
+*/
+
+/*!
+ \qmlmethod InputMethod::reset()
+
+ This method is called by the input engine when this input method needs to be
+ reset. The input method must reset its internal state only. The main
+ difference to the update() method is that reset() modifies only
+ the input method state; it must not modify the input context.
+*/
+
+/*!
+ \qmlmethod InputMethod::update()
+
+ This method is called by the input engine when the input method needs to be
+ updated. The input method must close the current pre-edit text and
+ restore the internal state to the default.
+*/
+
+/*!
+ \qmlmethod list<int> InputMethod::selectionLists()
+
+ Returns the list of selection types used for this input method.
+
+ This method is called by the input engine when the input method is being
+ activated. The input method can reserve the selection lists for its use
+ by returning a list of selection list types required.
+*/
+
+/*!
+ \qmlmethod int InputMethod::selectionListItemCount(int type)
+
+ Returns the number of items in the selection list identified by \a type.
+*/
+
+/*!
+ \qmlmethod var InputMethod::selectionListData(int type, int index, int role)
+
+ Returns item data for a selection list identified by \a type. The \a role
+ parameter specifies which data is requested. The \a index parameter is a
+ zero based index into the selecteion list.
+*/
+
+/*!
+ \qmlmethod void InputMethod::selectionListItemSelected(int type, int index)
+
+ This method is called when an item at \a index has been selected by the
+ user. The selection list is identified by the \a type parameter.
+*/
+
+/*!
+ \qmlsignal InputMethod::selectionListChanged(int type)
+
+ The input method emits this signal when the contents of the selection list
+ are changed. The \a type parameter specifies which selection list has
+ changed.
+*/
+
+/*!
+ \qmlsignal InputMethod::selectionListActiveItemChanged(int type, int index)
+
+ The input method emits this signal when the current \a index has changed
+ in the selection list identified by \a type.
+*/
+
+DeclarativeInputMethod::DeclarativeInputMethod(QObject *parent) :
+ AbstractInputMethod(parent)
+{
+}
+
+DeclarativeInputMethod::~DeclarativeInputMethod()
+{
+}
+
+QList<DeclarativeInputEngine::InputMode> DeclarativeInputMethod::inputModes(const QString &locale)
+{
+ QVariant result;
+ QMetaObject::invokeMethod(this, "inputModes",
+ Q_RETURN_ARG(QVariant, result),
+ Q_ARG(QVariant, locale));
+ QList<DeclarativeInputEngine::InputMode> inputModeList;
+ foreach (const QVariant &inputMode, result.toList()) {
+ inputModeList.append(static_cast<DeclarativeInputEngine::InputMode>(inputMode.toInt()));
+ }
+ return inputModeList;
+}
+
+bool DeclarativeInputMethod::setInputMode(const QString &locale, DeclarativeInputEngine::InputMode inputMode)
+{
+ QVariant result;
+ QMetaObject::invokeMethod(this, "setInputMode",
+ Q_RETURN_ARG(QVariant, result),
+ Q_ARG(QVariant, locale),
+ Q_ARG(QVariant, static_cast<int>(inputMode)));
+ return result.toBool();
+}
+
+bool DeclarativeInputMethod::setTextCase(DeclarativeInputEngine::TextCase textCase)
+{
+ QVariant result;
+ QMetaObject::invokeMethod(this, "setTextCase",
+ Q_RETURN_ARG(QVariant, result),
+ Q_ARG(QVariant, static_cast<int>(textCase)));
+ return result.toBool();
+}
+
+bool DeclarativeInputMethod::keyEvent(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers)
+{
+ QVariant result;
+ QMetaObject::invokeMethod(this, "keyEvent",
+ Q_RETURN_ARG(QVariant, result),
+ Q_ARG(QVariant, key),
+ Q_ARG(QVariant, text),
+ Q_ARG(QVariant, (int)modifiers));
+ return result.toBool();
+}
+
+QList<DeclarativeSelectionListModel::Type> DeclarativeInputMethod::selectionLists()
+{
+ QVariant result;
+ QMetaObject::invokeMethod(this, "selectionLists",
+ Q_RETURN_ARG(QVariant, result));
+ QList<DeclarativeSelectionListModel::Type> selectionListsList;
+ foreach (const QVariant &selectionListType, result.toList()) {
+ selectionListsList.append(static_cast<DeclarativeSelectionListModel::Type>(selectionListType.toInt()));
+ }
+ return selectionListsList;
+}
+
+int DeclarativeInputMethod::selectionListItemCount(DeclarativeSelectionListModel::Type type)
+{
+ QVariant result;
+ QMetaObject::invokeMethod(this, "selectionListItemCount",
+ Q_RETURN_ARG(QVariant, result),
+ Q_ARG(QVariant, static_cast<int>(type)));
+ return result.toInt();
+}
+
+QVariant DeclarativeInputMethod::selectionListData(DeclarativeSelectionListModel::Type type, int index, int role)
+{
+ QVariant result;
+ QMetaObject::invokeMethod(this, "selectionListData",
+ Q_RETURN_ARG(QVariant, result),
+ Q_ARG(QVariant, static_cast<int>(type)),
+ Q_ARG(QVariant, index),
+ Q_ARG(QVariant, role));
+ if (result.isNull()) {
+ result = AbstractInputMethod::selectionListData(type, index, role);
+ }
+ return result;
+}
+
+void DeclarativeInputMethod::selectionListItemSelected(DeclarativeSelectionListModel::Type type, int index)
+{
+ QMetaObject::invokeMethod(this, "selectionListItemSelected",
+ Q_ARG(QVariant, static_cast<int>(type)),
+ Q_ARG(QVariant, index));
+}
+
+void DeclarativeInputMethod::reset()
+{
+ QMetaObject::invokeMethod(this, "reset");
+}
+
+void DeclarativeInputMethod::update()
+{
+ QMetaObject::invokeMethod(this, "update");
+}
diff --git a/src/virtualkeyboard/declarativeinputmethod.h b/src/virtualkeyboard/declarativeinputmethod.h
new file mode 100644
index 00000000..0ec7572c
--- /dev/null
+++ b/src/virtualkeyboard/declarativeinputmethod.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef DECLARATIVEINPUTMETHOD_H
+#define DECLARATIVEINPUTMETHOD_H
+
+#include "abstractinputmethod.h"
+
+class DeclarativeInputMethod : public AbstractInputMethod
+{
+ Q_OBJECT
+ Q_PROPERTY(DeclarativeInputContext *inputContext READ inputContext CONSTANT)
+ Q_PROPERTY(DeclarativeInputEngine *inputEngine READ inputEngine CONSTANT)
+
+public:
+ explicit DeclarativeInputMethod(QObject *parent = 0);
+ ~DeclarativeInputMethod();
+
+ QList<DeclarativeInputEngine::InputMode> inputModes(const QString &locale);
+ bool setInputMode(const QString &locale, DeclarativeInputEngine::InputMode inputMode);
+ bool setTextCase(DeclarativeInputEngine::TextCase textCase);
+
+ bool keyEvent(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers);
+
+ QList<DeclarativeSelectionListModel::Type> selectionLists();
+ int selectionListItemCount(DeclarativeSelectionListModel::Type type);
+ QVariant selectionListData(DeclarativeSelectionListModel::Type type, int index, int role);
+ void selectionListItemSelected(DeclarativeSelectionListModel::Type type, int index);
+
+ void reset();
+ void update();
+};
+
+#endif // DECLARATIVEINPUTMETHOD_H
diff --git a/src/virtualkeyboard/declarativeselectionlistmodel.cpp b/src/virtualkeyboard/declarativeselectionlistmodel.cpp
new file mode 100644
index 00000000..e0ef1f05
--- /dev/null
+++ b/src/virtualkeyboard/declarativeselectionlistmodel.cpp
@@ -0,0 +1,223 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "declarativeselectionlistmodel.h"
+#include "abstractinputmethod.h"
+
+class DeclarativeSelectionListModelPrivate
+{
+public:
+ QHash<int, QByteArray> roles;
+ AbstractInputMethod *dataSource;
+ DeclarativeSelectionListModel::Type type;
+ int rowCount;
+};
+
+/*!
+ \qmltype SelectionListModel
+ \instantiates DeclarativeSelectionListModel
+ \inqmlmodule QtQuick.Enterprise.VirtualKeyboard 1.0
+ \brief Provides a data model for the selection lists.
+
+ This type acts as a bridge between the UI and the
+ input method that provides the data for selection
+ lists.
+
+ An instance of this type can be assigned to a
+ ListView::model.
+
+ The following data is made available for the list
+ delegate:
+ \list
+ \li \c "display" Display text for item
+ \li \c "wordCompletionLength" Word completion length for item
+ \endlist
+
+ The UI must bind to the SelectionListModel::activeItemChanged
+ signal and update the highlighted item in the view.
+
+ When the user selects an item from the list, the UI must invoke the
+ SelectionListModel::itemSelected() method.
+*/
+
+/*!
+ \class DeclarativeSelectionListModel
+
+ \inmodule InputFramework
+
+ \brief List model for selection lists.
+
+ This class acts as a bridge between the UI and the
+ input method that provides the data for selection
+ lists.
+*/
+
+/*!
+ \enum DeclarativeSelectionListModel::Type
+
+ This enum specifies the type of selection list.
+
+ \value WordCandidateList
+ Shows list of word candidates
+*/
+
+/*!
+ \enum DeclarativeSelectionListModel::Role
+
+ This enum specifies a role of the data requested.
+
+ \value DisplayRole
+ The data to be rendered in form of text.
+ \value WordCompletionLengthRole
+ An integer specifying the length of the word
+ the completion part expressed as the
+ number of characters counted from the
+ end of the string.
+*/
+
+DeclarativeSelectionListModel::DeclarativeSelectionListModel(QObject *parent) :
+ QAbstractListModel(parent),
+ d_ptr(new DeclarativeSelectionListModelPrivate())
+{
+ Q_D(DeclarativeSelectionListModel);
+ d->roles[DisplayRole] = "display";
+ d->roles[WordCompletionLengthRole] = "wordCompletionLength";
+}
+
+/*!
+ \internal
+*/
+DeclarativeSelectionListModel::~DeclarativeSelectionListModel()
+{
+}
+
+/*!
+ \internal
+*/
+void DeclarativeSelectionListModel::setDataSource(AbstractInputMethod *dataSource, Type type)
+{
+ Q_D(DeclarativeSelectionListModel);
+ if (d->dataSource) {
+ disconnect(this, SLOT(selectionListChanged(int)));
+ disconnect(this, SLOT(selectionListActiveItemChanged(int, int)));
+ }
+ d->dataSource = dataSource;
+ d->type = type;
+ if (d->dataSource) {
+ connect(d->dataSource, SIGNAL(selectionListChanged(int)), SLOT(selectionListChanged(int)));
+ connect(d->dataSource, SIGNAL(selectionListActiveItemChanged(int, int)), SLOT(selectionListActiveItemChanged(int, int)));
+ }
+}
+
+/*!
+ \internal
+*/
+AbstractInputMethod *DeclarativeSelectionListModel::dataSource() const
+{
+ Q_D(const DeclarativeSelectionListModel);
+ return d->dataSource;
+}
+
+/*!
+ \internal
+*/
+int DeclarativeSelectionListModel::rowCount(const QModelIndex &parent) const
+{
+ Q_D(const DeclarativeSelectionListModel);
+ Q_UNUSED(parent)
+ return d->rowCount;
+}
+
+/*!
+ \internal
+*/
+QVariant DeclarativeSelectionListModel::data(const QModelIndex &index, int role) const
+{
+ Q_D(const DeclarativeSelectionListModel);
+ return d->dataSource ? d->dataSource->selectionListData(d->type, index.row(), role) : QVariant();
+}
+
+/*!
+ \internal
+*/
+QHash<int,QByteArray> DeclarativeSelectionListModel::roleNames() const
+{
+ Q_D(const DeclarativeSelectionListModel);
+ return d->roles;
+}
+
+/*!
+ The UI invokes this method when user selects an item
+ identified by \a index from the selection list.
+*/
+void DeclarativeSelectionListModel::itemSelected(int index)
+{
+ Q_D(DeclarativeSelectionListModel);
+ if (d->dataSource) {
+ d->dataSource->selectionListItemSelected(d->type, index);
+ }
+}
+
+/*!
+ \internal
+*/
+void DeclarativeSelectionListModel::selectionListChanged(int type)
+{
+ Q_D(DeclarativeSelectionListModel);
+ if (static_cast<Type>(type) == d->type) {
+ int oldCount = d->rowCount;
+ int newCount = d->dataSource ? d->dataSource->selectionListItemCount(d->type) : 0;
+ if (newCount) {
+ int changedCount = qMin(oldCount, newCount);
+ if (changedCount)
+ dataChanged(index(0), index(changedCount - 1));
+ if (oldCount > newCount) {
+ beginRemoveRows(QModelIndex(), newCount, oldCount - 1);
+ d->rowCount = newCount;
+ endRemoveRows();
+ } else if (oldCount < newCount) {
+ beginInsertRows(QModelIndex(), oldCount, newCount - 1);
+ d->rowCount = newCount;
+ endInsertRows();
+ }
+ } else {
+ beginResetModel();
+ d->rowCount = 0;
+ endResetModel();
+ }
+ }
+}
+
+/*!
+ \internal
+*/
+void DeclarativeSelectionListModel::selectionListActiveItemChanged(int type, int index)
+{
+ Q_D(DeclarativeSelectionListModel);
+ if (static_cast<Type>(type) == d->type) {
+ emit activeItemChanged(index);
+ }
+}
+
+/*!
+ \fn void DeclarativeSelectionListModel::activeItemChanged(int index)
+
+ This signal is emitted when the active item in the list changes. The
+ UI should react to this signal by highlighting the item at \a index in
+ the list.
+*/
diff --git a/src/virtualkeyboard/declarativeselectionlistmodel.h b/src/virtualkeyboard/declarativeselectionlistmodel.h
new file mode 100644
index 00000000..df0dbcf0
--- /dev/null
+++ b/src/virtualkeyboard/declarativeselectionlistmodel.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef DECLARATIVESELECTIONLISTMODEL_H
+#define DECLARATIVESELECTIONLISTMODEL_H
+
+#include <QAbstractListModel>
+
+class AbstractInputMethod;
+class DeclarativeInputEngine;
+class DeclarativeSelectionListModelPrivate;
+
+class DeclarativeSelectionListModel : public QAbstractListModel
+{
+ Q_OBJECT
+ Q_ENUMS(Type)
+ Q_ENUMS(Role)
+ Q_DECLARE_PRIVATE(DeclarativeSelectionListModel)
+
+ explicit DeclarativeSelectionListModel(QObject *parent = 0);
+
+public:
+ enum Type
+ {
+ WordCandidateList = 0
+ };
+ enum Role
+ {
+ DisplayRole = Qt::DisplayRole,
+ WordCompletionLengthRole = Qt::UserRole + 1
+ };
+
+ ~DeclarativeSelectionListModel();
+ void setDataSource(AbstractInputMethod *dataSource, Type type);
+ AbstractInputMethod *dataSource() const;
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ QHash<int,QByteArray> roleNames() const;
+
+ Q_INVOKABLE void itemSelected(int index);
+
+signals:
+ void activeItemChanged(int index);
+
+protected slots:
+ void selectionListChanged(int type);
+ void selectionListActiveItemChanged(int type, int index);
+
+private:
+ friend class DeclarativeInputEngine;
+ QScopedPointer<DeclarativeSelectionListModelPrivate> d_ptr;
+};
+
+Q_DECLARE_METATYPE(DeclarativeSelectionListModel::Type)
+Q_DECLARE_METATYPE(DeclarativeSelectionListModel::Role)
+
+#endif // DECLARATIVESELECTIONLISTMODEL_H
diff --git a/src/virtualkeyboard/declarativeshifthandler.cpp b/src/virtualkeyboard/declarativeshifthandler.cpp
new file mode 100644
index 00000000..d7ce7048
--- /dev/null
+++ b/src/virtualkeyboard/declarativeshifthandler.cpp
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "declarativeshifthandler.h"
+#include "declarativeinputcontext.h"
+
+class DeclarativeShiftHandlerPrivate
+{
+public:
+ DeclarativeInputContext *inputContext;
+ QString sentenceEndingCharacters;
+};
+
+/*!
+ \qmltype ShiftHandler
+ \inqmlmodule QtQuick.Enterprise.VirtualKeyboard 1.0
+ \instantiates DeclarativeShiftHandler
+ \brief Manages the shift state.
+*/
+
+/*!
+ \class DeclarativeShiftHandler
+ \inmodule InputFramework
+ \brief Manages the shift state.
+*/
+
+DeclarativeShiftHandler::DeclarativeShiftHandler(DeclarativeInputContext *parent) :
+ QObject(parent),
+ d_ptr(new DeclarativeShiftHandlerPrivate())
+{
+ Q_D(DeclarativeShiftHandler);
+ d->inputContext = parent;
+ if (d->inputContext) {
+ connect(d->inputContext, SIGNAL(inputMethodHintsChanged()), SLOT(restart()));
+ connect(d->inputContext, SIGNAL(focusEditorChanged()), SLOT(restart()));
+ connect(d->inputContext, SIGNAL(preeditTextChanged()), SLOT(autoCapitalize()));
+ connect(d->inputContext, SIGNAL(cursorPositionChanged()), SLOT(autoCapitalize()));
+ }
+ d->sentenceEndingCharacters = ".!?";
+}
+
+/*!
+ \internal
+*/
+DeclarativeShiftHandler::~DeclarativeShiftHandler()
+{
+
+}
+
+QString DeclarativeShiftHandler::sentenceEndingCharacters() const
+{
+ Q_D(const DeclarativeShiftHandler);
+ return d->sentenceEndingCharacters;
+}
+
+void DeclarativeShiftHandler::setSentenceEndingCharacters(const QString &value)
+{
+ Q_D(DeclarativeShiftHandler);
+ if (d->sentenceEndingCharacters != value) {
+ d->sentenceEndingCharacters = value;
+ autoCapitalize();
+ emit sentenceEndingCharactersChanged();
+ }
+}
+
+void DeclarativeShiftHandler::reset()
+{
+ Q_D(DeclarativeShiftHandler);
+ if (d->inputContext->inputItem()) {
+ bool preferUpperCase = (d->inputContext->inputMethodHints() & Qt::ImhPreferUppercase);
+ d->inputContext->setShift(preferUpperCase);
+ d->inputContext->setCapsLock(preferUpperCase);
+ }
+}
+
+void DeclarativeShiftHandler::autoCapitalize()
+{
+ Q_D(DeclarativeShiftHandler);
+ if (!isEnabled() || d->inputContext->capsLock())
+ return;
+ if (!d->inputContext->preeditText().isEmpty()) {
+ if (isEnabled() && !d->inputContext->capsLock()) {
+ d->inputContext->setShift(false);
+ }
+ } else {
+ int cursorPosition = d->inputContext->cursorPosition();
+ bool preferLowerCase = d->inputContext->inputMethodHints() & Qt::ImhPreferLowercase;
+ if (cursorPosition == 0) {
+ d->inputContext->setShift(!preferLowerCase);
+ } else {
+ QString text = d->inputContext->surroundingText();
+ text.truncate(cursorPosition);
+ text = text.trimmed();
+ if (text.length() == 0)
+ d->inputContext->setShift(!preferLowerCase);
+ else if (text.length() > 0 && d->sentenceEndingCharacters.indexOf(text[text.length() - 1]) >= 0)
+ d->inputContext->setShift(!preferLowerCase);
+ else
+ d->inputContext->setShift(false);
+ }
+ }
+}
+
+void DeclarativeShiftHandler::restart()
+{
+ reset();
+ autoCapitalize();
+}
+
+bool DeclarativeShiftHandler::isEnabled() const
+{
+ static const Qt::InputMethodHints disallowFlags = (Qt::ImhNoAutoUppercase | Qt::ImhUppercaseOnly| Qt::ImhLowercaseOnly |
+ Qt::ImhEmailCharactersOnly | Qt::ImhUrlCharactersOnly | Qt::ImhDialableCharactersOnly |
+ Qt::ImhFormattedNumbersOnly | Qt::ImhDigitsOnly);
+ Q_D(const DeclarativeShiftHandler);
+ return !(d->inputContext->inputMethodHints() & disallowFlags);
+}
+
+/*!
+ \property DeclarativeShiftHandler::sentenceEndingCharacters
+
+ This property specifies the sentence ending characters which
+ will cause shift state change.
+
+ By default, the property is initialized to sentence
+ ending characters found in the ASCII range (i.e. ".!?").
+*/
+
+/*!
+ \qmlproperty string ShiftHandler::sentenceEndingCharacters
+
+ This property specifies the sentence ending characters which
+ will cause shift state change.
+
+ By default, the property is initialized to sentence
+ ending characters found in the ASCII range (i.e. ".!?").
+*/
diff --git a/src/virtualkeyboard/declarativeshifthandler.h b/src/virtualkeyboard/declarativeshifthandler.h
new file mode 100644
index 00000000..f1b7a99c
--- /dev/null
+++ b/src/virtualkeyboard/declarativeshifthandler.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef AUTOSHIFTHANDLER_H
+#define AUTOSHIFTHANDLER_H
+
+#include <QObject>
+#include <QScopedPointer>
+
+class DeclarativeInputContext;
+class DeclarativeShiftHandlerPrivate;
+
+class DeclarativeShiftHandler : public QObject
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(DeclarativeShiftHandler)
+ Q_DECLARE_PRIVATE(DeclarativeShiftHandler)
+ Q_PROPERTY(QString sentenceEndingCharacters READ sentenceEndingCharacters WRITE setSentenceEndingCharacters NOTIFY sentenceEndingCharactersChanged)
+
+ explicit DeclarativeShiftHandler(DeclarativeInputContext *parent = 0);
+
+public:
+ ~DeclarativeShiftHandler();
+
+ QString sentenceEndingCharacters() const;
+ void setSentenceEndingCharacters(const QString &value);
+
+signals:
+ void sentenceEndingCharactersChanged();
+
+private slots:
+ void reset();
+ void autoCapitalize();
+ void restart();
+
+private:
+ bool isEnabled() const;
+
+private:
+ friend class DeclarativeInputContext;
+ QScopedPointer<DeclarativeShiftHandlerPrivate> d_ptr;
+};
+
+#endif // AUTOSHIFTHANDLER_H
diff --git a/src/virtualkeyboard/defaultinputmethod.cpp b/src/virtualkeyboard/defaultinputmethod.cpp
new file mode 100644
index 00000000..fb8df9d1
--- /dev/null
+++ b/src/virtualkeyboard/defaultinputmethod.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "defaultinputmethod.h"
+#include "declarativeinputcontext.h"
+
+DefaultInputMethod::DefaultInputMethod(QObject *parent) :
+ AbstractInputMethod(parent)
+{
+}
+
+QList<DeclarativeInputEngine::InputMode> DefaultInputMethod::inputModes(const QString &locale)
+{
+ Q_UNUSED(locale)
+ return QList<DeclarativeInputEngine::InputMode>();
+}
+
+bool DefaultInputMethod::setInputMode(const QString &locale, DeclarativeInputEngine::InputMode inputMode)
+{
+ Q_UNUSED(locale)
+ Q_UNUSED(inputMode)
+ return true;
+}
+
+bool DefaultInputMethod::setTextCase(DeclarativeInputEngine::TextCase textCase)
+{
+ Q_UNUSED(textCase)
+ return true;
+}
+
+bool DefaultInputMethod::keyEvent(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers)
+{
+ inputContext()->sendKeyClick(key, text, modifiers);
+ return true;
+}
+
+void DefaultInputMethod::reset()
+{
+}
+
+void DefaultInputMethod::update()
+{
+}
diff --git a/src/virtualkeyboard/defaultinputmethod.h b/src/virtualkeyboard/defaultinputmethod.h
new file mode 100644
index 00000000..7316763c
--- /dev/null
+++ b/src/virtualkeyboard/defaultinputmethod.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef DEFAULTINPUTMETHOD_H
+#define DEFAULTINPUTMETHOD_H
+
+#include "abstractinputmethod.h"
+
+class DefaultInputMethod : public AbstractInputMethod
+{
+ Q_OBJECT
+
+public:
+ explicit DefaultInputMethod(QObject *parent = 0);
+
+ QList<DeclarativeInputEngine::InputMode> inputModes(const QString &locale);
+ bool setInputMode(const QString &locale, DeclarativeInputEngine::InputMode inputMode);
+ bool setTextCase(DeclarativeInputEngine::TextCase textCase);
+
+ bool keyEvent(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers);
+
+ void reset();
+ void update();
+};
+
+#endif // DEFAULTINPUTMETHOD_H
diff --git a/src/virtualkeyboard/doc/doc.pri b/src/virtualkeyboard/doc/doc.pri
new file mode 100644
index 00000000..5f94546b
--- /dev/null
+++ b/src/virtualkeyboard/doc/doc.pri
@@ -0,0 +1,7 @@
+OTHER_FILES += \
+ $$PWD/qtvirtualkeyboard.qdocconf \
+ $$PWD/src/index.qdoc \
+ $$PWD/src/deployment-guide.qdoc \
+ $$PWD/src/technical-guide.qdoc \
+ $$PWD/src/build.qdoc \
+ $$PWD/src/snippets/CustomInputMethod.qml
diff --git a/src/virtualkeyboard/doc/images/virtualkeyboard-demo.png b/src/virtualkeyboard/doc/images/virtualkeyboard-demo.png
new file mode 100644
index 00000000..62099d19
--- /dev/null
+++ b/src/virtualkeyboard/doc/images/virtualkeyboard-demo.png
Binary files differ
diff --git a/src/virtualkeyboard/doc/qtvirtualkeyboard.qdocconf b/src/virtualkeyboard/doc/qtvirtualkeyboard.qdocconf
new file mode 100644
index 00000000..d30c77fe
--- /dev/null
+++ b/src/virtualkeyboard/doc/qtvirtualkeyboard.qdocconf
@@ -0,0 +1,68 @@
+project = QtVirtualKeyboard
+description = Qt Virtual Keyboard
+
+headerdirs += .. \
+ ../content
+sourcedirs += .. \
+ ../content
+
+# Specify the install path under QT_INSTALL_EXAMPLES
+# Examples will be installed under quick/enterprise/virtualkeyboard -
+# 'enterprise/virtualkeyboard' subdirectory is given as part of \example commands
+exampledirs += ../../../examples/quick/enterprise/virtualkeyboard \
+ src/snippets
+examplesinstallpath = quick/enterprise/virtualkeyboard
+imagedirs += images
+
+Cpp.ignoredirectives = Q_DECLARE_PRIVATE \
+ Q_DISABLE_COPY \
+ Q_ENUMS
+Cpp.ignoretokens = Q_INVOKABLE
+
+spurious = "Can't link to 'All Modules'"
+
+sources.fileextensions = "*.cpp *.qdoc *.mm *.qml"
+headers.fileextensions = "*.h *.ch *.h++ *.hh *.hpp *.hxx"
+examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp *.qml"
+examples.imageextensions = "*.png *.jpeg *.jpg *.gif *.mng"
+
+outputdir = html
+outputformats = HTML
+
+HTML.nobreadcrumbs = "true"
+HTML.nonavigationbar = "true"
+
+HTML.stylesheets = style/style.css
+
+HTML.headerstyles = " <link rel=\"stylesheet\" type=\"text/css\" href=\"style/style.css\" />\n"
+
+HTML.postheader = \
+ " <div class=\"header\">\n" \
+ " <div id=\"nav-logo\">\n" \
+ " <a href=\"index.html\">Qt Virtual Keyboard Reference</a>" \
+ " </div>\n" \
+ " </div>\n" \
+ " <ul>\n"
+
+HTML.postpostheader = \
+ " </ul>\n"
+
+qhp.projects = QtVirtualKeyboard
+
+qhp.QtVirtualKeyboard.file = qtvirtualkeyboard.qhp
+qhp.QtVirtualKeyboard.namespace = com.digia.qtvirtualkeyboard.100
+qhp.QtVirtualKeyboard.virtualFolder = qtvirtualkeyboard
+qhp.QtVirtualKeyboard.indexTitle = Qt Virtual Keyboard Reference
+qhp.QtVirtualKeyboard.indexRoot =
+qhp.QtVirtualKeyboard.extraFiles = style/style.css
+
+qhp.QtVirtualKeyboard.filterAttributes = qtvirtualkeyboard 1.0 qtrefdoc
+qhp.QtVirtualKeyboard.customFilters.Qt.name = QtVirtualKeyboard 1.0
+qhp.QtVirtualKeyboard.customFilters.Qt.filterAttributes = qtvirtualkeyboard 1.0
+
+#qhp.QtVirtualKeyboard.subprojects = qtvirtualkeyboardqmltypes
+
+#qhp.QtVirtualKeyboard.subprojects.qtvirtualkeyboardqmltypes.title = Controls QML Types
+#qhp.QtVirtualKeyboard.subprojects.qtvirtualkeyboardqmltypes.indexTitle = Qt Virtual Keyboard QML Types
+#qhp.QtVirtualKeyboard.subprojects.qtvirtualkeyboardqmltypes.selectors = fake:qmlclass # cannot choose qmltypes from a specific group QTBUG-32985
+#qhp.QtVirtualKeyboard.subprojects.qtvirtualkeyboardqmltypes.sortPages = true
diff --git a/src/virtualkeyboard/doc/src/build.qdoc b/src/virtualkeyboard/doc/src/build.qdoc
new file mode 100644
index 00000000..602535b8
--- /dev/null
+++ b/src/virtualkeyboard/doc/src/build.qdoc
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+/*!
+
+\page build.html
+\contentspage {Building Qt Virtual Keyboard} {Contents}
+
+\title Building Qt Virtual Keyboard
+
+\section1 Overview
+
+This document describes how to build the Qt Virtual Keyboard plugin.
+
+The project is split into the following subprojects:
+- \e examples/quick/enterprise/virtualkeyboard/virtualkeyboard/virtualkeyboard.pro
+ Qt Virtual Keyboard Demo application
+- \e src/virtualkeyboard/virtualkeyboard.pro Qt Virtual Keyboard C++ backend
+ for input engine and QPlatformInputContext integration
+- \e src/virtualkeyboard/styles/styles.pro Qt Virtual Keyboard Style plugin
+ that enables style decorations for the keyboard
+
+The input methods are implemented either in C++ or QML.
+Qt Virtual Keyboard provides implementations of PlainInputMethod,
+MultitapInputMethod and HunspellInputMethod.
+The MultitapInputMethod is implemented in QML while the others are implemented
+in C++.
+
+\section1 Build instructions
+
+The Qt Virtual Keyboard can be built for Linux Desktop/X11 or Boot2Qt targets.
+The target is automatically detected by QMAKE and requires no special
+configuration parameters.
+
+QtCreator is the preferred build environment for Qt Virtual Keyboard as you can
+then leverage the shadow build functionality and rapidly switch between build
+targets.
+
+\section2 Configuration options
+
+- \e CONFIG+=disable-xcb Disables X11 integration
+- \e CONFIG+=disable-hunspell Disables Hunspell integration
+- \e CONFIG+=retro-style Enables Retro style
+
+\section2 Extra targets
+
+- \e docs Generates documentation
+
+\section2 Hunspell integration
+
+By default, HunspellInputMethod will not be available unless the Hunspell
+library and development headers are found. For Linux/X11 targets, the Hunspell
+library can be provided by installing the libhunspell-dev package.
+Alternatively, the Hunspell sources can be extracted into the
+\e src/virtualkeyboard/hunspell directory. If Hunspell sources are used,
+then the dictionary files must also be copied into the
+\e src/virtualkeyboard/hunspell/data directory. Furthermore, if Hunspell
+sources are used, \e hunspell.pro will be used for all targets.
+
+\section1 Deployment instructions
+
+\section2 Linux/X11
+
+Add a Deploy Step that executes the \e {make install} command, then deploy using
+the \e {Deploy All} command.
+
+\section2 Boot2Qt
+
+Remount target file system as read-write before deployment.
+
+ \e {adb -s <deviceid> remount}
+
+Deploy using the \e {Deploy All} command.
+
+*/
diff --git a/src/virtualkeyboard/doc/src/deployment-guide.qdoc b/src/virtualkeyboard/doc/src/deployment-guide.qdoc
new file mode 100644
index 00000000..b1ec6ed8
--- /dev/null
+++ b/src/virtualkeyboard/doc/src/deployment-guide.qdoc
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+/*!
+
+\page deployment-guide.html
+\contentspage {Deployment Guide} {Contents}
+
+\title Deployment Guide
+
+\section1 Overview
+
+This document describes how to deploy and use the Qt Virtual Keyboard plugin
+with Qt 5 applications.
+
+\section1 Deployment
+
+The Qt Virtual Keyboard plugin must be properly deployed before it can be used.
+The easiest approach to deployment is to add a deployment step
+in Qt Creator that executes the \c {make install} command.
+
+\c {make install} deploys the files in the following locations:
+
+\table
+\header
+ \li Item
+ \li Desktop install path
+ \li Boot2Qt install path
+\row
+ \li qtvirtualkeyboardplugin
+ \li \c $$[QT_INSTALL_PLUGINS]/platforminputcontexts
+ \li \c /system/plugins/platforminputcontexts
+\row
+ \li qtvirtualkeyboardplugin QML files
+ \li \c $$[QT_INSTALL_QML]/QtQuick/Enterprise/VirtualKeyboard
+ \li \c /system/qml/QtQuick/Enterprise/VirtualKeyboard
+\row
+ \li qtvirtualkeyboardstylesplugin
+ \li \c $$[QT_INSTALL_QML]/QtQuick/Enterprise/VirtualKeyboard/Styles
+ \li \c /system/qml/QtQuick/Enterprise/VirtualKeyboard/Styles
+\endtable
+
+\section1 Integration Method
+
+Qt Virtual Keyboard currently supports two alternative integration methods
+for using the plugin:
+
+\list
+ \li \c Desktop: Qt Virtual Keyboard is integrated with Qt 5 and requires no
+ changes to existing applications. The Qt Virtual Keyboard input method
+ is available to all of the Qt 5 applications in the system.
+ \li \c Application: Qt Virtual Keyboard is integrated with Qt 5, but
+ requires changes to particular applications using Qt Virtual Keyboard.
+ This method is mandatory in a Boot2Qt environment, but can be used in
+ desktop applications too.
+\endlist
+
+The integration method is automatically selected by the project files.
+However, in desktop environments, it is possible to override the desktop
+integration method and use the application integration method instead.
+This happens by adding the \c CONFIG+=disable-xcb option to the \c qmake
+command line.
+
+\note The desktop integration method is not currently available in Boot2Qt
+environments.
+
+\section1 Loading the Plugin
+
+In both integration methods, the application must use the \c QT_IM_MODULE
+environment variable to load the plugin. For example:
+
+\code
+$ QT_IM_MODULE=qtvirtualkeyboard myapp
+\endcode
+
+or in the main() function:
+
+\code
+qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
+\endcode
+
+In the desktop integration method, this step is all that is required to
+use Qt Virtual Keyboard. In the application integration method, the application
+is required to create an instance of InputPanel as explained in the
+following chapter.
+
+\section1 Creating InputPanel
+
+The following example shows how to create an InputPanel and how to
+divide the screen area with the application container.
+
+\code
+import QtQuick 2.0
+import QtQuick.Enterprise.VirtualKeyboard 1.0
+
+Item {
+ id: root
+ Item {
+ id: appContainer
+ anchors.left: parent.left
+ anchors.top: parent.top
+ anchors.right: parent.right
+ anchors.bottom: inputPanel.top
+ ...
+ }
+ InputPanel {
+ id: inputPanel
+ y: Qt.inputMethod.visible ? appContainer.height - inputPanel.height : appContainer.height
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ }
+}
+\endcode
+
+The input panel must be a sibling element next to the application container.
+It is important not to put the input panel within the application container,
+as it would then overlap with the contents of the application. Also, the
+input panel height will be automatically updated according to the available
+width; the aspect ratio of the input panel is constant.
+
+If the application contains Flickable elements, they will be automatically
+scrolled to the focused element.
+
+*/
diff --git a/src/virtualkeyboard/doc/src/qtvirtualkeyboard-examples.qdoc b/src/virtualkeyboard/doc/src/qtvirtualkeyboard-examples.qdoc
new file mode 100644
index 00000000..2af96bcf
--- /dev/null
+++ b/src/virtualkeyboard/doc/src/qtvirtualkeyboard-examples.qdoc
@@ -0,0 +1,35 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+/*!
+ \group qtvirtualkeyboard-examples
+ \brief Examples for Qt Virtual Keyboard
+ \title Qt Virtual Keyboard Examples
+*/
+
+/*!
+ \title QML Demo - Virtual Keyboard
+ \example virtualkeyboard
+ \brief This is an example virtual keyboard written in QML.
+ \ingroup qtvirtualkeyboard-examples
+ \image virtualkeyboard-demo.png
+
+ The example shows how to build a virtual keyboard UI with support for
+ multiple keyboard layouts using QML, and a QPlatformInputContext bridge
+ for communicating between the keyboard and focused text editor in C++.
+*/
diff --git a/src/virtualkeyboard/doc/src/qtvirtualkeyboard-index.qdoc b/src/virtualkeyboard/doc/src/qtvirtualkeyboard-index.qdoc
new file mode 100644
index 00000000..62851427
--- /dev/null
+++ b/src/virtualkeyboard/doc/src/qtvirtualkeyboard-index.qdoc
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+/*!
+ \title QtVKB Reference
+ \page index.html
+
+ The QtVKB project provides an input framework and reference
+ keyboard frontend for Qt 5.
+
+ The input framework makes it easy to write custom input methods or to
+ integrate 3rd party input engines. The input methods can be implemented
+ in C++ or QML.
+
+ \section1 Guides
+
+ \list
+ \li \l {Building Qt Virtual Keyboard}
+ \li \l {Deployment Guide}
+ \li \l {Technical Guide}
+ \endlist
+
+ \section1 Modules
+
+ \generatelist module
+
+ \section1 C++ Classes
+
+ \generatelist annotatedclasses
+
+ \section1 QML Elements
+
+ \generatelist qmltypes
+
+ \section1 Examples
+
+ \list
+ \li \l{Qt Virtual Keyboard Examples}
+ \endlist
+*/
diff --git a/src/virtualkeyboard/doc/src/snippets/CustomInputMethod.qml b/src/virtualkeyboard/doc/src/snippets/CustomInputMethod.qml
new file mode 100644
index 00000000..e333ca9c
--- /dev/null
+++ b/src/virtualkeyboard/doc/src/snippets/CustomInputMethod.qml
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtVkb 1.0
+
+// file: CustomInputMethod.qml
+
+InputMethod {
+ function inputModes(locale) {
+ return [InputEngine.Latin];
+ }
+
+ function setInputMode(locale, inputMode) {
+ return true
+ }
+
+ function setTextCase(textCase) {
+ return true
+ }
+
+ function reset() {
+ // TODO: reset the input method without modifying input context
+ }
+
+ function update() {
+ // TODO: commit current state and update the input method
+ }
+
+ function keyEvent(key, text, modifiers) {
+ var accept = false
+ // TODO: Handle key and set accept or fallback to default processing
+ return accept;
+ }
+}
diff --git a/src/virtualkeyboard/doc/src/technical-guide.qdoc b/src/virtualkeyboard/doc/src/technical-guide.qdoc
new file mode 100644
index 00000000..b0687aec
--- /dev/null
+++ b/src/virtualkeyboard/doc/src/technical-guide.qdoc
@@ -0,0 +1,244 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+/*!
+
+\page technical-guide.html
+\contentspage {Technical Guide} {Contents}
+
+\title Technical Guide
+
+\section1 Overview
+
+This document provides a technical overview of the Qt Virtual Keyboard plugin.
+
+\section1 Basic Concepts
+
+The Qt Virtual Keyboard project is a Qt 5 input context plugin which implements
+QPlatformInputContextPlugin and QPlatformInputContext interfaces.
+These interfaces allow the plugin to be used as a platform input
+context plugin in Qt 5 applications.
+
+The plugin itself provides an input framework supporting multiple
+input methods as well as a QML UI for the virtual keyboard.
+
+The input framework provides the following main interfaces:
+
+\list
+ \li InputContext: provides contextual information for the virtual keyboard
+ and other input components.
+ \li InputEngine: exposes an API to integrate user input events (key
+ presses, etc.) and acts as a host for input methods.
+ \li InputMethod: a base type for QML based input methods.
+ \li AbstractInputMethod: a base type for C++ based input methods.
+\endlist
+
+\section1 The Input Context
+
+The input context is used by the keyboard as well as concrete input methods.
+
+\section2 Contextual Information
+
+The input context provides access to contextual information that originates
+from the application. This information includes, but is not limited to:
+
+\list
+ \li InputContext::cursorPosition
+ \li InputContext::cursorRectangle
+ \li InputContext::inputMethodHints
+ \li InputContext::preeditText
+ \li InputContext::selectedText
+ \li InputContext::surroundingText
+\endlist
+
+\section2 Locale
+
+When a keyboard layout is activated, the keyboard should set a matching locale
+for the input context. This can be done with the InputContext::locale property.
+Once the locale is set, it is reflected to the current input method and the
+underlying application (through QPlatformInputContext).
+
+\section2 UI Animations
+
+The keyboard should notify the input context about UI transitions and
+animations. The InputContext::animating property sets the animating property of
+the input context.
+
+\section1 The Input Engine
+
+The input engine object is owned by InputContext. The input engine contains
+API functions which the keyboard can use to map user interactions such as key
+press and key release events.
+
+The input events are mapped through the following methods:
+
+\list
+ \li InputEngine::virtualKeyPress
+ \li InputEngine::virtualKeyRelease
+\endlist
+
+The above-mentioned methods are intended for the integration of the virtual
+keyboard, hence the word "virtual" in the methods' names. This also means that
+the methods are not suitable for mapping the physical keystrokes. This is a
+consequence of the fact that the actual action is performed only when the key
+is released.
+
+If the user releases the key without having to perform the actual action, the
+key can be interrupted by using the InputEngine::virtualKeyCancel method.
+
+\section2 Activating an Input Method
+
+Activating an input method is straightforward. The required steps are:
+
+\list
+ \li Instantiate a concrete implementation of InputMethod or
+ AbstractInputMethod
+ \li Assign the instance to InputEngine::inputMethod
+ \li Set the proper input mode with InputEngine::inputMode
+\endlist
+
+When the input method is active, it receives key events from the input engine
+and can produce text.
+
+\section1 Implementing a Custom Input Method
+
+The implementation of input methods starts by deciding which interface is used;
+QML or C++. In this example the QML interface is used.
+
+The following example shows the minimum functionality that is required
+from an input method:
+
+\quotefile CustomInputMethod.qml
+
+The InputMethod::inputModes() method is called by the input engine before
+an input mode is set. The method returns a list of input modes available in
+the given locale.
+
+An input method is initialized in InputMethod::setInputMode() method with
+a locale and input mode. After setting the locale and input mode, the input
+method should be ready for use.
+
+InputMethod::reset() is called when an input method needs to be reset. The reset
+must only reset the internal state of the input method, and not the user text.
+
+InputMethod::update() is called when the input context is updated and
+the input state is possibly out of sync. The input method should commit
+the current text.
+
+The keystorke events are handled in InputMethod::keyEvent(). This method handles
+a single keystroke event and returns \c true if the event was processed.
+Otherwise the keystroke is handled by the default input method.
+
+\section2 Selection Lists
+
+Selection lists are an optional feature that can be integrated into the input
+method. The input framework supports various types of lists, such as the word
+candidate list. Responsibilities in implementing the lists are handled such
+that the input method is responsible for the content and activities, such as the
+click behavior. The input framework is responsible for maintaining the list
+model and delivery to the user interface.
+
+\section3 Allocating the Selection Lists
+
+Selection lists are allocated when the input method is activated. The
+InputMethod::selectionLists() method returns a list of the required selection
+list types:
+
+\code
+function selectionLists() {
+ return [SelectionListModel.WordCandidateList];
+}
+\endcode
+
+In the above example, the input method allocates the word candidate list for its
+use.
+
+\section3 Updating the Selection Lists
+
+When the input method requires the UI to update the contents of a selection
+list, it will emit the InputMethod::selectionListChanged signal. Likewise, if
+the input method requires the UI to highlight an item in the list, it will emit
+the InputMethod::selectionListActiveItemChanged signal.
+
+\code
+selectionListChanged(SelectionListModel.WordCandidateList)
+selectionListActiveItemChanged(SelectionListModel.WordCandidateList, wordIndex)
+\endcode
+
+\section3 Populating Items in the Selection Lists
+
+The items are populated with method callbacks which will provide the number of
+items in a list as well as the data for individual items.
+
+The InputMethod::selectionListItemCount callback requests the number of
+items in the list identified by the given type.
+
+\code
+function selectionListItemCount(type) {
+ if (type == SelectionListModel.WordCandidateList) {
+ return wordList.length
+ }
+ return 0
+}
+\endcode
+
+The InputMethod::selectionListData callback requests the data for items.
+
+\code
+function selectionListData(type, index, role) {
+ var result = null
+ if (type == SelectionListModel.WordCandidateList) {
+ switch (role) {
+ case SelectionListModel.DisplayRole:
+ result = wordList[index]
+ break
+ default:
+ break
+ }
+ }
+ return result
+}
+\endcode
+
+The \a role parameter identifies which data is requested for an item. For
+example, the SelectionListModel.DisplayRole requests the display text data.
+
+\section3 Responding to User Actions
+
+When the user selects an item in the list, the input method responds to the
+event in the InputMethod::selectionListItemSelected method callback.
+
+\code
+function selectionListItemSelected(type, index) {
+ if (type == SelectionListModel.WordCandidateList) {
+ inputContext.commit(wordlist[index])
+ update()
+ }
+}
+\endcode
+
+\section1 Integrating Selection Lists into the UI
+
+The input engine provides a list model for each selection list type.
+The model is null while the list is not allocated, allowing the UI
+to hide the list if necessary.
+
+The list model's word candidate list is provided by the
+InputEngine::wordCandidateListModel property.
+
+*/
diff --git a/src/virtualkeyboard/doc/style/style.css b/src/virtualkeyboard/doc/style/style.css
new file mode 100644
index 00000000..5d58c91c
--- /dev/null
+++ b/src/virtualkeyboard/doc/style/style.css
@@ -0,0 +1,150 @@
+a:link, a:visited {
+ color: #00732F;
+ text-decoration: none;
+ font-weight: bold;
+}
+
+body {
+ font: normal 400 14px/1.2 Arial;
+# margin-top: 85px;
+}
+
+h1 {
+ margin: 0;
+}
+
+h2 {
+ font: 500 20px/1.2 Arial;
+}
+
+h3.fn, span.fn {
+ -moz-border-radius: 7px 7px 7px 7px;
+ -webkit-border-radius: 7px 7px 7px 7px;
+ border-radius: 7px 7px 7px 7px;
+ background-color: #F6F6F6;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #E6E6E6;
+ word-spacing: 3px;
+ padding: 3px 5px;
+}
+
+table, pre {
+ -moz-border-radius: 7px 7px 7px 7px;
+ -webkit-border-radius: 7px 7px 7px 7px;
+ border-radius: 7px 7px 7px 7px;
+ background-color: #F6F6F6;
+ border: 1px solid #E6E6E6;
+ border-collapse: separate;
+ font-size: 12px;
+ line-height: 1.2;
+ margin-bottom: 25px;
+ margin-left: 15px;
+}
+
+table td {
+ padding: 3px 15px 3px 20px;
+}
+
+table tr.even {
+ background-color: white;
+ color: #66666E;
+}
+
+table tr.odd {
+ background-color: #F6F6F6;
+ color: #66666E;
+}
+
+li {
+ margin-bottom: 10px;
+ padding-left: 12px;
+}
+
+.cpp {
+ display: block;
+ margin: 10;
+ overflow: hidden;
+ overflow-x: hidden;
+ overflow-y: hidden;
+ padding: 20px 0 20px 0;
+}
+
+.footer {
+ margin-top: 50px;
+}
+
+.memItemLeft {
+ padding-right: 3px;
+}
+
+.memItemRight {
+ padding: 3px 15px 3px 0;
+}
+
+.qml {
+ display: block;
+ margin: 10;
+ overflow: hidden;
+ overflow-x: hidden;
+ overflow-y: hidden;
+ padding: 20px 0 20px 0;
+}
+
+.qmldefault {
+ padding-left: 5px;
+ float: right;
+ color: red;
+}
+
+.qmlreadonly {
+ padding-left: 5px;
+ float: right;
+ color: #254117;
+}
+
+.rightAlign {
+ padding: 3px 5px 3px 10px;
+ text-align: right;
+}
+
+.header {
+ background-color: #F6F6F6;
+ border: 1px solid #DDD;
+ padding: 5px 5px;
+ margin: 5px 5px;
+ -moz-border-radius: 7px 7px 7px 7px;
+ -webkit-border-radius: 7px 7px 7px 7px;
+}
+
+.title {
+ background-color: white;
+ color: #44A51C;
+ font-family: Verdana;
+ font-size: 35px;
+ font-weight: normal;
+ left: 0;
+ padding-bottom: 5px;
+ padding-left: 16px;
+ padding-top: 5px;
+# position: absolute;
+ right: 0;
+ top: 0;
+}
+
+.toc {
+ float: right;
+ -moz-border-radius: 7px 7px 7px 7px;
+ -webkit-border-radius: 7px 7px 7px 7px;
+ border-radius: 7px 7px 7px 7px;
+ background-color: #F6F6F6;
+ border: 1px solid #DDD;
+ margin: 0 20px 10px 10px;
+ padding: 20px 15px 20px 20px;
+ height: auto;
+ width: 200px;
+}
+
+#buildversion {
+ display: none;
+}
diff --git a/src/virtualkeyboard/hunspell/config.h b/src/virtualkeyboard/hunspell/config.h
new file mode 100644
index 00000000..e3c8583c
--- /dev/null
+++ b/src/virtualkeyboard/hunspell/config.h
@@ -0,0 +1,2 @@
+/* Version number of package */
+#define VERSION "1.3.2"
diff --git a/src/virtualkeyboard/hunspell/hunspell.pro b/src/virtualkeyboard/hunspell/hunspell.pro
new file mode 100644
index 00000000..632d930b
--- /dev/null
+++ b/src/virtualkeyboard/hunspell/hunspell.pro
@@ -0,0 +1,74 @@
+TEMPLATE = lib
+QT -= core gui
+TARGET = hunspell
+VERSION = 1.3.2
+DEFINES += BUILDING_LIBHUNSPELL
+CONFIG += dll
+#CONFIG += staticlib
+CONFIG += precompile_header warn_off
+debug {
+ DEFINES += HUNSPELL_WARNING_ON
+}
+dll {
+ android-no-sdk {
+ target.path = /system/lib
+ } else:!isEmpty(CROSS_COMPILE) {
+ target.path = /usr/local/Qt-$$[QT_VERSION]/lib
+ } else {
+ target.path = $$[QT_INSTALL_LIBS]
+ }
+ INSTALLS += target
+}
+
+INCLUDEPATH += \
+ ./ \
+ src/hunspell \
+ src/parsers
+
+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 \
+ src/hunspell/hunzip.cxx \
+ src/hunspell/phonet.cxx \
+ src/hunspell/replist.cxx \
+ src/hunspell/suggestmgr.cxx \
+ src/parsers/firstparser.cxx \
+ src/parsers/htmlparser.cxx \
+ src/parsers/latexparser.cxx \
+ src/parsers/manparser.cxx \
+ src/parsers/testparser.cxx \
+ src/parsers/textparser.cxx
+
+HEADERS += \
+ config.h \
+ src/hunspell/affentry.hxx \
+ src/hunspell/affixmgr.hxx \
+ 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 \
+ src/hunspell/hunspell.hxx \
+ src/hunspell/hunzip.hxx \
+ src/hunspell/langnum.hxx \
+ src/hunspell/phonet.hxx \
+ src/hunspell/replist.hxx \
+ src/hunspell/suggestmgr.hxx \
+ src/hunspell/w_char.hxx \
+ src/parsers/firstparser.hxx \
+ src/parsers/htmlparser.hxx \
+ src/parsers/latexparser.hxx \
+ src/parsers/manparser.hxx \
+ src/parsers/textparser.hxx
+
+OTHER_FILES +=\
+ src/hunspell/license.hunspell \
+ src/hunspell/license.myspell \
+ src/hunspell/utf_info.cxx
diff --git a/src/virtualkeyboard/hunspellinputmethod.cpp b/src/virtualkeyboard/hunspellinputmethod.cpp
new file mode 100644
index 00000000..bbafba81
--- /dev/null
+++ b/src/virtualkeyboard/hunspellinputmethod.cpp
@@ -0,0 +1,305 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "hunspellinputmethod.h"
+#include "hunspellworker.h"
+#include "declarativeinputcontext.h"
+#include <hunspell/hunspell.h>
+#include <QStringList>
+#include <QFileInfo>
+#include "virtualkeyboarddebug.h"
+
+class HunspellInputMethodPrivate : public AbstractInputMethodPrivate
+{
+ Q_DECLARE_PUBLIC(HunspellInputMethod)
+
+public:
+ HunspellInputMethodPrivate(HunspellInputMethod *q_ptr) :
+ AbstractInputMethodPrivate(),
+ q_ptr(q_ptr),
+ hunspellWorker(0),
+ locale(),
+ word(),
+ wordCandidates(),
+ activeWordIndex(-1),
+ wordCompletionPoint(2)
+ {
+ }
+
+ ~HunspellInputMethodPrivate()
+ {
+ }
+
+ bool createHunspell(const QString &locale)
+ {
+ if (this->locale != locale) {
+ hunspellWorker.reset(0);
+ Hunhandle *hunspell = 0;
+ QString hunspellDataPath(QString::fromLatin1(qgetenv("QT_VIRTUALKEYBOARD_HUNSPELL_DATA_PATH").constData()));
+ if (hunspellDataPath.isEmpty())
+ hunspellDataPath = QT_VIRTUALKEYBOARD_HUNSPELL_DATA_PATH;
+ QStringList searchPaths(hunspellDataPath.split(":"));
+ foreach (const QString &searchPath, searchPaths) {
+ QByteArray affpath(QString("%1/%2.aff").arg(searchPath).arg(locale).toUtf8());
+ QByteArray dpath(QString("%1/%2.dic").arg(searchPath).arg(locale).toUtf8());
+ if (QFileInfo(dpath).exists()) {
+ hunspell = Hunspell_create(affpath.constData(), dpath.constData());
+ if (hunspell)
+ break;
+ }
+ }
+ if (!hunspell) {
+ qWarning() << "Missing Hunspell dictionary for locale" << locale << "in" << searchPaths;
+ this->locale.clear();
+ return false;
+ }
+ this->locale = locale;
+ hunspellWorker.reset(new HunspellWorker(hunspell));
+ if (!hunspellWorker) {
+ Hunspell_destroy(hunspell);
+ this->locale.clear();
+ return false;
+ }
+ hunspellWorker->start();
+ }
+ return true;
+ }
+
+ bool updateSuggestions()
+ {
+ bool wordCandidateListChanged = false;
+ if (!word.isEmpty()) {
+ if (hunspellWorker)
+ hunspellWorker->removeAllTasks();
+ if (wordCandidates.isEmpty()) {
+ wordCandidates.append(word);
+ activeWordIndex = 0;
+ wordCandidateListChanged = true;
+ } else if (wordCandidates.at(0) != word) {
+ wordCandidates.replace(0, word);
+ activeWordIndex = 0;
+ wordCandidateListChanged = true;
+ }
+ if (word.length() >= wordCompletionPoint) {
+ if (hunspellWorker) {
+ QSharedPointer<HunspellWordList> wordList(new HunspellWordList());
+ QSharedPointer<HunspellBuildSuggestionsTask> buildSuggestionsTask(new HunspellBuildSuggestionsTask());
+ buildSuggestionsTask->word = word;
+ buildSuggestionsTask->wordList = wordList;
+ hunspellWorker->addTask(buildSuggestionsTask);
+ QSharedPointer<HunspellUpdateSuggestionsTask> updateSuggestionsTask(new HunspellUpdateSuggestionsTask());
+ updateSuggestionsTask->wordList = wordList;
+ Q_Q(HunspellInputMethod);
+ q->connect(updateSuggestionsTask.data(), SIGNAL(updateSuggestions(QStringList, int)), SLOT(updateSuggestions(QStringList, int)));
+ hunspellWorker->addTask(updateSuggestionsTask);
+ }
+ } else if (wordCandidates.length() > 1) {
+ wordCandidates.clear();
+ wordCandidates.append(word);
+ activeWordIndex = 0;
+ wordCandidateListChanged = true;
+ }
+ } else {
+ wordCandidateListChanged = clearSuggestions();
+ }
+ return wordCandidateListChanged;
+ }
+
+ bool clearSuggestions()
+ {
+ if (hunspellWorker)
+ hunspellWorker->removeAllTasks();
+ if (wordCandidates.isEmpty())
+ return false;
+ wordCandidates.clear();
+ activeWordIndex = -1;
+ return true;
+ }
+
+ bool hasSuggestions() const
+ {
+ return !wordCandidates.isEmpty();
+ }
+
+ HunspellInputMethod *q_ptr;
+ QScopedPointer<HunspellWorker> hunspellWorker;
+ QString locale;
+ QString word;
+ QStringList wordCandidates;
+ int activeWordIndex;
+ int wordCompletionPoint;
+};
+
+HunspellInputMethod::HunspellInputMethod(QObject *parent) :
+ AbstractInputMethod(new HunspellInputMethodPrivate(this), parent)
+{
+}
+
+HunspellInputMethod::~HunspellInputMethod()
+{
+}
+
+QList<DeclarativeInputEngine::InputMode> HunspellInputMethod::inputModes(const QString &locale)
+{
+ Q_UNUSED(locale)
+ return QList<DeclarativeInputEngine::InputMode>() << DeclarativeInputEngine::Latin << DeclarativeInputEngine::Numeric;
+}
+
+bool HunspellInputMethod::setInputMode(const QString &locale, DeclarativeInputEngine::InputMode inputMode)
+{
+ Q_UNUSED(inputMode)
+ Q_D(HunspellInputMethod);
+ return d->createHunspell(locale);
+}
+
+bool HunspellInputMethod::setTextCase(DeclarativeInputEngine::TextCase textCase)
+{
+ Q_UNUSED(textCase)
+ return true;
+}
+
+bool HunspellInputMethod::keyEvent(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers)
+{
+ Q_UNUSED(modifiers)
+ Q_D(HunspellInputMethod);
+ bool accept = false;
+ switch (key) {
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ case Qt::Key_Tab:
+ case Qt::Key_Space:
+ update();
+ break;
+ case Qt::Key_Backspace:
+ if (!d->word.isEmpty()) {
+ d->word.remove(d->word.length() - 1, 1);
+ inputContext()->setPreeditText(d->word);
+ if (d->updateSuggestions()) {
+ emit selectionListChanged(DeclarativeSelectionListModel::WordCandidateList);
+ emit selectionListActiveItemChanged(DeclarativeSelectionListModel::WordCandidateList, d->activeWordIndex);
+ }
+ accept = true;
+ }
+ break;
+ default:
+ if (text.length() == 1) {
+ QChar c = text.at(0);
+ bool addToWord = !c.isPunct() && !c.isSymbol();
+ if (!addToWord) {
+ if (!d->word.isEmpty()) {
+ if (c == Qt::Key_Apostrophe || c == Qt::Key_hyphen)
+ addToWord = true;
+ }
+ }
+ if (addToWord) {
+ d->word.append(text);
+ inputContext()->setPreeditText(d->word);
+ if (d->updateSuggestions()) {
+ emit selectionListChanged(DeclarativeSelectionListModel::WordCandidateList);
+ emit selectionListActiveItemChanged(DeclarativeSelectionListModel::WordCandidateList, d->activeWordIndex);
+ }
+ accept = true;
+ } else {
+ update();
+ }
+ } else if (text.length() > 1) {
+ update();
+ inputContext()->commit(text);
+ accept = true;
+ }
+ break;
+ }
+ return accept;
+}
+
+QList<DeclarativeSelectionListModel::Type> HunspellInputMethod::selectionLists()
+{
+ return QList<DeclarativeSelectionListModel::Type>() << DeclarativeSelectionListModel::WordCandidateList;
+}
+
+int HunspellInputMethod::selectionListItemCount(DeclarativeSelectionListModel::Type type)
+{
+ Q_UNUSED(type)
+ Q_D(HunspellInputMethod);
+ return d->wordCandidates.count();
+}
+
+QVariant HunspellInputMethod::selectionListData(DeclarativeSelectionListModel::Type type, int index, int role)
+{
+ QVariant result;
+ Q_UNUSED(type)
+ Q_D(HunspellInputMethod);
+ switch (role) {
+ case DeclarativeSelectionListModel::DisplayRole:
+ result = QVariant(d->wordCandidates.at(index));
+ break;
+ case DeclarativeSelectionListModel::WordCompletionLengthRole:
+ {
+ const QString wordCandidate(d->wordCandidates.at(index));
+ int wordCompletionLength = wordCandidate.length() - d->word.length();
+ result.setValue((wordCompletionLength > 0 && wordCandidate.startsWith(d->word)) ? wordCompletionLength : 0);
+ break;
+ }
+ default:
+ result = AbstractInputMethod::selectionListData(type, index, role);
+ break;
+ }
+ return result;
+}
+
+void HunspellInputMethod::selectionListItemSelected(DeclarativeSelectionListModel::Type type, int index)
+{
+ Q_UNUSED(type)
+ Q_D(HunspellInputMethod);
+ QString finalWord = d->wordCandidates.at(index);
+ reset();
+ inputContext()->commit(finalWord);
+ inputContext()->commit(" ");
+}
+
+void HunspellInputMethod::reset()
+{
+ Q_D(HunspellInputMethod);
+ if (d->clearSuggestions()) {
+ emit selectionListChanged(DeclarativeSelectionListModel::WordCandidateList);
+ emit selectionListActiveItemChanged(DeclarativeSelectionListModel::WordCandidateList, d->activeWordIndex);
+ }
+ d->word.clear();
+}
+
+void HunspellInputMethod::update()
+{
+ Q_D(HunspellInputMethod);
+ if (!d->word.isEmpty()) {
+ if (d->hasSuggestions())
+ inputContext()->commit(d->wordCandidates.at(d->activeWordIndex));
+ else if (!d->word.isEmpty())
+ inputContext()->commit(d->word);
+ }
+ reset();
+}
+
+void HunspellInputMethod::updateSuggestions(const QStringList &wordList, int activeWordIndex)
+{
+ Q_D(HunspellInputMethod);
+ d->wordCandidates.clear();
+ d->wordCandidates.append(wordList);
+ d->activeWordIndex = activeWordIndex;
+ emit selectionListChanged(DeclarativeSelectionListModel::WordCandidateList);
+ emit selectionListActiveItemChanged(DeclarativeSelectionListModel::WordCandidateList, d->activeWordIndex);
+}
diff --git a/src/virtualkeyboard/hunspellinputmethod.h b/src/virtualkeyboard/hunspellinputmethod.h
new file mode 100644
index 00000000..1820dd12
--- /dev/null
+++ b/src/virtualkeyboard/hunspellinputmethod.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef HUNSPELLINPUTMETHOD_H
+#define HUNSPELLINPUTMETHOD_H
+
+#include "abstractinputmethod.h"
+
+class HunspellInputMethodPrivate;
+
+class HunspellInputMethod : public AbstractInputMethod
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(HunspellInputMethod)
+public:
+ explicit HunspellInputMethod(QObject *parent = 0);
+ ~HunspellInputMethod();
+
+ QList<DeclarativeInputEngine::InputMode> inputModes(const QString &locale);
+ bool setInputMode(const QString &locale, DeclarativeInputEngine::InputMode inputMode);
+ bool setTextCase(DeclarativeInputEngine::TextCase textCase);
+
+ bool keyEvent(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers);
+
+ QList<DeclarativeSelectionListModel::Type> selectionLists();
+ int selectionListItemCount(DeclarativeSelectionListModel::Type type);
+ QVariant selectionListData(DeclarativeSelectionListModel::Type type, int index, int role);
+ void selectionListItemSelected(DeclarativeSelectionListModel::Type type, int index);
+
+ void reset();
+ void update();
+
+protected slots:
+ void updateSuggestions(const QStringList &wordList, int activeWordIndex);
+};
+
+#endif // HUNSPELLINPUTMETHOD_H
diff --git a/src/virtualkeyboard/hunspellworker.cpp b/src/virtualkeyboard/hunspellworker.cpp
new file mode 100644
index 00000000..c43a6ca0
--- /dev/null
+++ b/src/virtualkeyboard/hunspellworker.cpp
@@ -0,0 +1,162 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "hunspellworker.h"
+#include <QVector>
+
+void HunspellBuildSuggestionsTask::run()
+{
+ wordList->list.append(word);
+ wordList->index = 0;
+ char **slst = 0;
+ int n = Hunspell_suggest(hunspell, &slst, word.toUtf8().constData());
+ if (n > 0) {
+ /* Collect word candidates from the Hunspell suggestions.
+ Insert word completions in the beginning of the list.
+ */
+ const int firstWordCompletionIndex = wordList->list.length();
+ int lastWordCompletionIndex = firstWordCompletionIndex;
+ for (int i = 0; i < n; i++) {
+ QString wordCandidate(QString::fromUtf8(slst[i]));
+ wordCandidate.replace(QChar(0x2019), '\'');
+ if (wordCandidate.compare(word) != 0) {
+ if (wordCandidate.startsWith(word) ||
+ wordCandidate.contains(QChar('\''))) {
+ wordList->list.insert(lastWordCompletionIndex++, wordCandidate);
+ } else {
+ wordList->list.append(wordCandidate);
+ }
+ }
+ }
+ /* Prioritize words with missing spaces next to word completions.
+ */
+ for (int i = lastWordCompletionIndex + 1; i < wordList->list.length();) {
+ if (QString(wordList->list.at(i)).replace(" ", "").compare(word) == 0) {
+ wordList->list.move(i, lastWordCompletionIndex++);
+ } else {
+ i++;
+ }
+ }
+ /* Do spell checking and suggest the first candidate, if:
+ - the word matches partly the suggested word; or
+ - the quality of the suggested word is good enough.
+
+ The quality is measured here using the Levenshtein Distance,
+ which may be suboptimal for the purpose, but gives some clue
+ how much the suggested word differs from the given word.
+ */
+ if (wordList->list.length() > 1 && !spellCheck(word)) {
+ if (lastWordCompletionIndex > firstWordCompletionIndex || levenshteinDistance(word, wordList->list.at(firstWordCompletionIndex)) < 3)
+ wordList->index = firstWordCompletionIndex;
+ }
+ }
+ Hunspell_free_list(hunspell, &slst, n);
+}
+
+bool HunspellBuildSuggestionsTask::spellCheck(const QString &word)
+{
+ if (!hunspell)
+ return false;
+ if (word.contains(QRegExp("[0-9]")))
+ return true;
+ return Hunspell_spell(hunspell, word.toUtf8().constData()) != 0;
+}
+
+// source: http://en.wikipedia.org/wiki/Levenshtein_distance
+int HunspellBuildSuggestionsTask::levenshteinDistance(const QString &s, const QString &t)
+{
+ if (s == t)
+ return 0;
+ if (s.length() == 0)
+ return t.length();
+ if (t.length() == 0)
+ return s.length();
+ QVector<int> v0(t.length() + 1);
+ QVector<int> v1(t.length() + 1);
+ for (int i = 0; i < v0.size(); i++)
+ v0[i] = i;
+ for (int i = 0; i < s.size(); i++) {
+ v1[0] = i + 1;
+ for (int j = 0; j < t.length(); j++) {
+ int cost = (s[i].toLower() == t[j].toLower()) ? 0 : 1;
+ v1[j + 1] = qMin(qMin(v1[j] + 1, v0[j + 1] + 1), v0[j] + cost);
+ }
+ for (int j = 0; j < v0.size(); j++)
+ v0[j] = v1[j];
+ }
+ return v1[t.length()];
+}
+
+void HunspellUpdateSuggestionsTask::run()
+{
+ emit updateSuggestions(wordList->list, wordList->index);
+}
+
+HunspellWorker::HunspellWorker(Hunhandle *hunspell, QObject *parent) :
+ QThread(parent),
+ taskSema(),
+ taskLock(),
+ hunspell(hunspell),
+ abort(false)
+{
+}
+
+HunspellWorker::~HunspellWorker()
+{
+ abort = true;
+ taskSema.release(1);
+ wait();
+ if (hunspell) {
+ Hunspell_destroy(hunspell);
+ hunspell = 0;
+ }
+}
+
+void HunspellWorker::addTask(QSharedPointer<HunspellTask> task)
+{
+ if (task) {
+ QMutexLocker guard(&taskLock);
+ taskList.append(task);
+ taskSema.release();
+ }
+}
+
+void HunspellWorker::removeAllTasks()
+{
+ QMutexLocker guard(&taskLock);
+ taskList.clear();
+ if (taskSema.available())
+ taskSema.acquire(taskSema.available());
+}
+
+void HunspellWorker::run()
+{
+ while (!abort) {
+ taskSema.acquire();
+ if (abort)
+ break;
+ QSharedPointer<HunspellTask> currentTask;
+ {
+ QMutexLocker guard(&taskLock);
+ currentTask = taskList.front();
+ taskList.pop_front();
+ }
+ currentTask->hunspell = hunspell;
+ currentTask->run();
+ }
+}
diff --git a/src/virtualkeyboard/hunspellworker.h b/src/virtualkeyboard/hunspellworker.h
new file mode 100644
index 00000000..276269e6
--- /dev/null
+++ b/src/virtualkeyboard/hunspellworker.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef HUNSPELLWORKER_H
+#define HUNSPELLWORKER_H
+
+#include <QThread>
+#include <QSemaphore>
+#include <QMutex>
+#include <QStringList>
+#include <QSharedPointer>
+#include <hunspell/hunspell.h>
+
+class HunspellTask : public QObject
+{
+ Q_OBJECT
+public:
+ explicit HunspellTask(QObject *parent = 0) :
+ QObject(parent),
+ hunspell(0)
+ {}
+
+ virtual void run() = 0;
+
+ Hunhandle *hunspell;
+};
+
+class HunspellWordList
+{
+public:
+ HunspellWordList() :
+ list(),
+ index(-1)
+ {}
+
+ QStringList list;
+ int index;
+};
+
+class HunspellBuildSuggestionsTask : public HunspellTask
+{
+ Q_OBJECT
+public:
+ QString word;
+ QSharedPointer<HunspellWordList> wordList;
+
+ void run();
+ bool spellCheck(const QString &word);
+ int levenshteinDistance(const QString &s, const QString &t);
+};
+
+class HunspellUpdateSuggestionsTask : public HunspellTask
+{
+ Q_OBJECT
+public:
+ QSharedPointer<HunspellWordList> wordList;
+
+ void run();
+
+signals:
+ void updateSuggestions(const QStringList &wordList, int activeWordIndex);
+};
+
+class HunspellWorker : public QThread
+{
+ Q_OBJECT
+public:
+ explicit HunspellWorker(Hunhandle *hunspell, QObject *parent = 0);
+ ~HunspellWorker();
+
+ void addTask(QSharedPointer<HunspellTask> task);
+ void removeAllTasks();
+
+protected:
+ void run();
+
+private:
+ QList<QSharedPointer<HunspellTask> > taskList;
+ QSemaphore taskSema;
+ QMutex taskLock;
+ Hunhandle *hunspell;
+ bool abort;
+};
+
+#endif // HUNSPELLWORKER_H
diff --git a/src/virtualkeyboard/inputview.cpp b/src/virtualkeyboard/inputview.cpp
new file mode 100644
index 00000000..89196436
--- /dev/null
+++ b/src/virtualkeyboard/inputview.cpp
@@ -0,0 +1,30 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "inputview.h"
+
+InputView::InputView(QWindow *parent) :
+ QQuickView(parent)
+{
+}
+
+void InputView::resizeEvent(QResizeEvent *event)
+{
+ QQuickWindow::resizeEvent(event);
+ emit sizeChanged();
+}
diff --git a/src/virtualkeyboard/inputview.h b/src/virtualkeyboard/inputview.h
new file mode 100644
index 00000000..e9f0af3d
--- /dev/null
+++ b/src/virtualkeyboard/inputview.h
@@ -0,0 +1,37 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef INPUTVIEW_H
+#define INPUTVIEW_H
+
+#include <QQuickView>
+
+class InputView : public QQuickView
+{
+ Q_OBJECT
+public:
+ explicit InputView(QWindow *parent = 0);
+
+signals:
+ void sizeChanged();
+
+protected:
+ void resizeEvent(QResizeEvent *event);
+};
+
+#endif // INPUTVIEW_H
diff --git a/src/virtualkeyboard/plaininputmethod.cpp b/src/virtualkeyboard/plaininputmethod.cpp
new file mode 100644
index 00000000..3c433198
--- /dev/null
+++ b/src/virtualkeyboard/plaininputmethod.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "plaininputmethod.h"
+#include "declarativeinputengine.h"
+#include "declarativeinputcontext.h"
+
+PlainInputMethod::PlainInputMethod(QObject *parent) :
+ AbstractInputMethod(parent)
+{
+}
+
+PlainInputMethod::~PlainInputMethod()
+{
+}
+
+QList<DeclarativeInputEngine::InputMode> PlainInputMethod::inputModes(const QString &locale)
+{
+ Q_UNUSED(locale)
+ return QList<DeclarativeInputEngine::InputMode>() << DeclarativeInputEngine::Latin << DeclarativeInputEngine::Numeric;
+}
+
+bool PlainInputMethod::setInputMode(const QString &locale, DeclarativeInputEngine::InputMode inputMode)
+{
+ Q_UNUSED(locale)
+ Q_UNUSED(inputMode)
+ return true;
+}
+
+bool PlainInputMethod::setTextCase(DeclarativeInputEngine::TextCase textCase)
+{
+ Q_UNUSED(textCase)
+ return true;
+}
+
+bool PlainInputMethod::keyEvent(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers)
+{
+ Q_UNUSED(key)
+ Q_UNUSED(text)
+ Q_UNUSED(modifiers)
+ bool accept = false;
+ return accept;
+}
+
+void PlainInputMethod::reset()
+{
+}
+
+void PlainInputMethod::update()
+{
+}
diff --git a/src/virtualkeyboard/plaininputmethod.h b/src/virtualkeyboard/plaininputmethod.h
new file mode 100644
index 00000000..989cf6fc
--- /dev/null
+++ b/src/virtualkeyboard/plaininputmethod.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef PLAININPUTMETHOD_H
+#define PLAININPUTMETHOD_H
+
+#include "abstractinputmethod.h"
+
+class PlainInputMethod : public AbstractInputMethod
+{
+ Q_OBJECT
+
+public:
+ explicit PlainInputMethod(QObject *parent = 0);
+ ~PlainInputMethod();
+
+ QList<DeclarativeInputEngine::InputMode> inputModes(const QString &locale);
+ bool setInputMode(const QString &locale, DeclarativeInputEngine::InputMode inputMode);
+ bool setTextCase(DeclarativeInputEngine::TextCase textCase);
+
+ bool keyEvent(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers);
+
+ void reset();
+ void update();
+};
+
+#endif
diff --git a/src/virtualkeyboard/platforminputcontext.cpp b/src/virtualkeyboard/platforminputcontext.cpp
new file mode 100644
index 00000000..408ddf08
--- /dev/null
+++ b/src/virtualkeyboard/platforminputcontext.cpp
@@ -0,0 +1,217 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "platforminputcontext.h"
+#include "declarativeinputcontext.h"
+#include "abstractinputpanel.h"
+#ifdef HAVE_XCB
+#include "xcbinputpanel.h"
+#else
+#include "appinputpanel.h"
+#endif
+#include "virtualkeyboarddebug.h"
+
+#include <QWindow>
+#include <QGuiApplication>
+
+PlatformInputContext::PlatformInputContext() :
+ m_declarativeContext(0),
+#ifdef HAVE_XCB
+ m_inputPanel(new XcbInputPanel(this)),
+#else
+ m_inputPanel(new AppInputPanel(this)),
+#endif
+ m_inputPanelCreated(false),
+ m_focusObject(0),
+ m_locale("en_GB"),
+ m_inputDirection(Qt::LeftToRight)
+{
+}
+
+PlatformInputContext::~PlatformInputContext()
+{
+}
+
+bool PlatformInputContext::isValid() const
+{
+ return true;
+}
+
+void PlatformInputContext::reset()
+{
+ VIRTUALKEYBOARD_DEBUG() << "PlatformInputContext::reset()";
+ if (m_declarativeContext)
+ m_declarativeContext->reset();
+}
+
+void PlatformInputContext::commit()
+{
+ VIRTUALKEYBOARD_DEBUG() << "PlatformInputContext::commit()";
+ if (m_declarativeContext)
+ m_declarativeContext->externalCommit();
+}
+
+void PlatformInputContext::update(Qt::InputMethodQueries queries)
+{
+ VIRTUALKEYBOARD_DEBUG() << "PlatformInputContext::update():" << queries;
+ if (m_declarativeContext)
+ m_declarativeContext->update(queries);
+}
+
+void PlatformInputContext::invokeAction(QInputMethod::Action action, int cursorPosition)
+{
+ VIRTUALKEYBOARD_DEBUG() << "PlatformInputContext::invokeAction():" << action << cursorPosition;
+}
+
+bool PlatformInputContext::filterEvent(const QEvent *event)
+{
+ return QPlatformInputContext::filterEvent(event);
+}
+
+QRectF PlatformInputContext::keyboardRect() const
+{
+ return m_declarativeContext ? m_declarativeContext->keyboardRectangle() : QRectF();
+}
+
+bool PlatformInputContext::isAnimating() const
+{
+ return m_declarativeContext ? m_declarativeContext->animating() : false;
+}
+
+void PlatformInputContext::showInputPanel()
+{
+ if (!m_inputPanelCreated) {
+ m_inputPanel->createView();
+ m_inputPanelCreated = true;
+ }
+ if (m_inputPanel->isVisible())
+ return;
+ m_inputPanel->show();
+ emitInputPanelVisibleChanged();
+}
+
+void PlatformInputContext::hideInputPanel()
+{
+ if (!m_inputPanel->isVisible())
+ return;
+ m_inputPanel->hide();
+ emitInputPanelVisibleChanged();
+}
+
+bool PlatformInputContext::isInputPanelVisible() const
+{
+ return m_inputPanel->isVisible();
+}
+
+QLocale PlatformInputContext::locale() const
+{
+ return m_locale;
+}
+
+void PlatformInputContext::setLocale(QLocale locale)
+{
+ if (m_locale != locale) {
+ m_locale = locale;
+ emitLocaleChanged();
+ }
+}
+
+Qt::LayoutDirection PlatformInputContext::inputDirection() const
+{
+ return m_inputDirection;
+}
+
+void PlatformInputContext::setInputDirection(Qt::LayoutDirection direction)
+{
+ if (m_inputDirection != direction) {
+ m_inputDirection = direction;
+ emitInputDirectionChanged(m_inputDirection);
+ }
+}
+
+QObject *PlatformInputContext::focusObject()
+{
+ return m_focusObject;
+}
+
+void PlatformInputContext::setFocusObject(QObject *object)
+{
+ VIRTUALKEYBOARD_DEBUG() << "PlatformInputContext::setFocusObject():" << object;
+ if (m_focusObject == object)
+ return;
+ m_focusObject = object;
+ emit focusObjectChanged();
+ bool enabled;
+ if (m_focusObject) {
+ QInputMethodQueryEvent event(Qt::ImEnabled);
+ sendEvent(&event);
+ enabled = event.value(Qt::ImEnabled).toBool();
+ } else {
+ enabled = false;
+ }
+ if (m_declarativeContext) {
+ bool focus = (object != 0 && enabled);
+ m_declarativeContext->setFocus(focus);
+ if (focus)
+ m_declarativeContext->update(Qt::ImQueryAll);
+ else
+ hideInputPanel();
+ }
+}
+
+DeclarativeInputContext *PlatformInputContext::declarativeInputContext() const
+{
+ return m_declarativeContext;
+}
+
+void PlatformInputContext::sendEvent(QEvent *event)
+{
+ if (m_focusObject)
+ QGuiApplication::sendEvent(m_focusObject, event);
+}
+
+void PlatformInputContext::sendKeyEvent(QKeyEvent *event)
+{
+ const QGuiApplication *app = qApp;
+ QWindow *focusWindow = app ? app->focusWindow() : 0;
+ if (focusWindow)
+ QGuiApplication::sendEvent(focusWindow, event);
+}
+
+QVariant PlatformInputContext::inputMethodQuery(Qt::InputMethodQuery query)
+{
+ QInputMethodQueryEvent event(query);
+ sendEvent(&event);
+ return event.value(query);
+}
+
+void PlatformInputContext::setDeclarativeContext(DeclarativeInputContext *context)
+{
+ if (m_declarativeContext) {
+ disconnect(this, SLOT(keyboardRectangleChanged()));
+ }
+ m_declarativeContext = context;
+ if (m_declarativeContext) {
+ connect(m_declarativeContext, SIGNAL(keyboardRectangleChanged()), SLOT(keyboardRectangleChanged()));
+ }
+}
+
+void PlatformInputContext::keyboardRectangleChanged()
+{
+ m_inputPanel->setInputRect(m_declarativeContext->keyboardRectangle().toRect());
+}
diff --git a/src/virtualkeyboard/platforminputcontext.h b/src/virtualkeyboard/platforminputcontext.h
new file mode 100644
index 00000000..b3fa4a74
--- /dev/null
+++ b/src/virtualkeyboard/platforminputcontext.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef PLATFORMINPUTCONTEXT_H
+#define PLATFORMINPUTCONTEXT_H
+
+#include <qevent.h>
+#include <qpa/qplatforminputcontext.h>
+#include <QPointer>
+#include <QLocale>
+
+class DeclarativeInputContext;
+class AbstractInputPanel;
+class PlatformInputContext : public QPlatformInputContext
+{
+ Q_OBJECT
+public:
+ explicit PlatformInputContext();
+ ~PlatformInputContext();
+
+ virtual bool isValid() const;
+
+ virtual void reset();
+ virtual void commit();
+ virtual void update(Qt::InputMethodQueries queries);
+ virtual void invokeAction(QInputMethod::Action action, int cursorPosition);
+ virtual bool filterEvent(const QEvent *event);
+ virtual QRectF keyboardRect() const;
+
+ virtual bool isAnimating() const;
+
+ virtual void showInputPanel();
+ virtual void hideInputPanel();
+ virtual bool isInputPanelVisible() const;
+
+ virtual QLocale locale() const;
+ void setLocale(QLocale locale);
+ virtual Qt::LayoutDirection inputDirection() const;
+ void setInputDirection(Qt::LayoutDirection direction);
+
+ QObject *focusObject();
+ virtual void setFocusObject(QObject *object);
+
+ DeclarativeInputContext *declarativeInputContext() const;
+
+signals:
+ void focusObjectChanged();
+
+protected:
+ void sendEvent(QEvent *event);
+ void sendKeyEvent(QKeyEvent *event);
+ QVariant inputMethodQuery(Qt::InputMethodQuery query);
+ void setDeclarativeContext(DeclarativeInputContext *context);
+
+private slots:
+ void keyboardRectangleChanged();
+
+private:
+ friend class DeclarativeInputContext;
+ DeclarativeInputContext *m_declarativeContext;
+ AbstractInputPanel *m_inputPanel;
+ bool m_inputPanelCreated;
+ QPointer<QObject> m_focusObject;
+ QLocale m_locale;
+ Qt::LayoutDirection m_inputDirection;
+};
+
+#endif
diff --git a/src/virtualkeyboard/plugin.cpp b/src/virtualkeyboard/plugin.cpp
new file mode 100644
index 00000000..9b91d60c
--- /dev/null
+++ b/src/virtualkeyboard/plugin.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include <QtQml>
+#include <QStringList>
+#include <qpa/qplatforminputcontextplugin_p.h>
+
+#include "platforminputcontext.h"
+#include "declarativeinputcontext.h"
+#include "declarativeinputengine.h"
+#include "declarativeshifthandler.h"
+#include "plaininputmethod.h"
+#ifdef HAVE_HUNSPELL
+#include "hunspellinputmethod.h"
+#endif
+#include "declarativeinputmethod.h"
+#include "declarativeselectionlistmodel.h"
+
+static QPointer<PlatformInputContext> platformInputContext;
+
+static QObject *createInputContextModule(QQmlEngine *engine, QJSEngine *scriptEngine)
+{
+ Q_UNUSED(engine);
+ Q_UNUSED(scriptEngine);
+ return new DeclarativeInputContext(platformInputContext);
+}
+
+class PlatformInputContextPlugin : public QPlatformInputContextPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPlatformInputContextFactoryInterface" FILE "qtvirtualkeyboard.json")
+
+public:
+ QStringList keys() const;
+ QPlatformInputContext *create(const QString&, const QStringList&);
+};
+
+QStringList PlatformInputContextPlugin::keys() const
+{
+ return QStringList(QStringLiteral("qtvirtualkeyboard"));
+}
+
+QPlatformInputContext *PlatformInputContextPlugin::create(const QString &system, const QStringList &paramList)
+{
+ Q_UNUSED(paramList);
+
+ qmlRegisterSingletonType<DeclarativeInputContext>("QtQuick.Enterprise.VirtualKeyboard", 1, 0, "InputContext", createInputContextModule);
+ qmlRegisterUncreatableType<DeclarativeInputEngine>("QtQuick.Enterprise.VirtualKeyboard", 1, 0, "InputEngine", "Cannot create input method engine");
+ qmlRegisterUncreatableType<DeclarativeShiftHandler>("QtQuick.Enterprise.VirtualKeyboard", 1, 0, "ShiftHandler", "Cannot create shift handler");
+ qmlRegisterUncreatableType<DeclarativeSelectionListModel>("QtQuick.Enterprise.VirtualKeyboard", 1, 0, "SelectionListModel", "Cannot create selection list model");
+ qmlRegisterUncreatableType<AbstractInputMethod>("QtQuick.Enterprise.VirtualKeyboard", 1, 0, "AbstractInputMethod", "Cannot create abstract input method");
+ qmlRegisterType<PlainInputMethod>("QtQuick.Enterprise.VirtualKeyboard", 1, 0, "PlainInputMethod");
+ qmlRegisterType<DeclarativeInputMethod>("QtQuick.Enterprise.VirtualKeyboard", 1, 0, "InputMethod");
+#ifdef HAVE_HUNSPELL
+ qmlRegisterType<HunspellInputMethod>("QtQuick.Enterprise.VirtualKeyboard", 1, 0, "HunspellInputMethod");
+#endif
+
+ if (system.compare(system, QStringLiteral("qtvirtualkeyboard"), Qt::CaseInsensitive) == 0) {
+ platformInputContext = new PlatformInputContext();
+ }
+ return platformInputContext;
+}
+
+#include "plugin.moc"
diff --git a/src/virtualkeyboard/qtvirtualkeyboard.json b/src/virtualkeyboard/qtvirtualkeyboard.json
new file mode 100644
index 00000000..76d17069
--- /dev/null
+++ b/src/virtualkeyboard/qtvirtualkeyboard.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "qtvirtualkeyboard" ]
+}
diff --git a/src/virtualkeyboard/styles/KeyIcon.qml b/src/virtualkeyboard/styles/KeyIcon.qml
new file mode 100644
index 00000000..db7deb04
--- /dev/null
+++ b/src/virtualkeyboard/styles/KeyIcon.qml
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+/*!
+ \qmltype KeyIcon
+ \inqmlmodule QtQuick.Enterprise.VirtualKeyboard.Styles
+ \brief Key icon with adjustable color.
+
+ The KeyIcon item displays an icon with adjustable color.
+*/
+
+Item {
+ /*! The icon color. */
+ property alias color: overlay.color
+ /*! The source image. */
+ property alias source: icon.source
+ Image {
+ id: icon
+ sourceSize.height: parent.height
+ anchors.horizontalCenter: parent.horizontalCenter
+ visible: false
+ }
+ ShaderEffect {
+ id: overlay
+ property color color
+ property variant texture: icon
+ anchors.fill: icon
+ fragmentShader: "
+ uniform lowp vec4 color;
+ uniform lowp float qt_Opacity;
+ uniform lowp sampler2D texture;
+ varying highp vec2 qt_TexCoord0;
+ void main() {
+ highp vec4 sample = texture2D(texture, qt_TexCoord0) * qt_Opacity;
+ gl_FragColor = vec4(color.rgb, 1.0) * sample.a;
+ }
+ "
+ }
+}
diff --git a/src/virtualkeyboard/styles/KeyPanel.qml b/src/virtualkeyboard/styles/KeyPanel.qml
new file mode 100644
index 00000000..d81521be
--- /dev/null
+++ b/src/virtualkeyboard/styles/KeyPanel.qml
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+/*!
+ \qmltype KeyPanel
+ \inqmlmodule QtQuick.Enterprise.VirtualKeyboard.Styles
+ \brief A base type of the styled keys.
+
+ All the key delegates provided by the style should be based on this type.
+*/
+
+Item {
+ /*! Provides access to properties in key control.
+
+ A list of available properties in control:
+ \list
+ \li \c control.key Unicode code of the key.
+ \li \c control.text Unicode text of the key.
+ \li \c control.displayText Display text of the key.
+ \li \c control.alternativeKeys List of alternative key sequences.
+ \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.
+ \endlist
+ */
+ property Item control
+ // Uncomment the following to reveal the key sizes
+ /*
+ Rectangle {
+ id: root
+ z: 1
+ color: "transparent"
+ border.color: "white"
+ anchors.fill: parent
+ Rectangle {
+ color: "black"
+ opacity: 0.6
+ anchors.top: parent.top
+ anchors.topMargin: 1
+ anchors.left: parent.left
+ anchors.leftMargin: 1
+ implicitWidth: keyPanelInfoText.width + 4
+ implicitHeight: keyPanelInfoText.height + 4
+ Text {
+ id: keyPanelInfoText
+ text: root.parent.width + "x" + root.parent.height
+ font.pixelSize: 12
+ color: "white"
+ anchors.centerIn: parent
+ }
+ }
+ }
+ */
+}
diff --git a/src/virtualkeyboard/styles/KeyboardStyle.qml b/src/virtualkeyboard/styles/KeyboardStyle.qml
new file mode 100644
index 00000000..1eefb28f
--- /dev/null
+++ b/src/virtualkeyboard/styles/KeyboardStyle.qml
@@ -0,0 +1,233 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+/*!
+ \qmltype KeyboardStyle
+ \inqmlmodule QtQuick.Enterprise.VirtualKeyboard.Styles
+ \brief Provides the style definitions for the Virtual Keyboard.
+
+ The style type provides the style definitions which are used by
+ the InputPanel to decorate the virtual keyboard.
+
+ The design size specifies the aspect ratio of the virtual keyboard.
+ Styles are scalable according to KeyboardStyle.scaleHint, which is
+ calculated from the actual height and the keyboard design height.
+*/
+
+QtObject {
+ /*! The current size of the keyboard. */
+ property real keyboardHeight
+
+ /*! The design width of the keyboard. */
+ property real keyboardDesignWidth
+
+ /*! 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
+ dimensions must be proportional to this value.
+ */
+ readonly property real scaleHint: keyboardHeight / keyboardDesignHeight
+
+ /*! Left margin for keyboard.
+ This value is proportional to keyboard width.
+ */
+ property real keyboardRelativeLeftMargin: 0
+
+ /*! Right margin for keyboard.
+ This value is proportional to keyboard width.
+ */
+ property real keyboardRelativeRightMargin: 0
+
+ /*! Top margin for keyboard.
+ This value is proportional to keyboard height.
+ */
+ property real keyboardRelativeTopMargin: 0
+
+ /*! Bottom margin for keyboard.
+ This value is proportional to keyboard height.
+ */
+ property real keyboardRelativeBottomMargin: 0
+
+ /*! Template for the keyboard background.
+
+ Example:
+ \code
+ keyboardBackground: Rectangle {
+ color: "black"
+ }
+ \endcode
+ */
+ property Component keyboardBackground: null
+
+ /*! Template for the regular keys.
+
+ \note The delegate must be based on KeyPanel type.
+
+ Example:
+ \code
+ keyPanel: KeyPanel {
+ Rectangle {
+ anchors.fill: parent
+ ...
+ Text {
+ anchors.fill: parent
+ text: control.displayText
+ ...
+ }
+ }
+ }
+ \endcode
+ */
+ property Component keyPanel: null
+
+ /*! Template for the backspace key.
+
+ \note The delegate must be based on KeyPanel type.
+ */
+ property Component backspaceKeyPanel: null
+
+ /*! Template for the language key.
+
+ \note The delegate must be based on KeyPanel type.
+ */
+ property Component languageKeyPanel: null
+
+ /*! Template for the enter key.
+
+ \note The delegate must be based on KeyPanel type.
+ */
+ property Component enterKeyPanel: null
+
+ /*! Template for the hide key.
+
+ \note The delegate must be based on KeyPanel type.
+ */
+ property Component hideKeyPanel: null
+
+ /*! Template for the shift key.
+
+ \note The delegate must be based on KeyPanel type.
+ */
+ property Component shiftKeyPanel: null
+
+ /*! Template for the space key.
+
+ \note The delegate must be based on KeyPanel type.
+ */
+ property Component spaceKeyPanel: null
+
+ /*! Template for the symbol mode key.
+
+ \note The delegate must be based on KeyPanel type.
+ */
+ property Component symbolKeyPanel: null
+
+ /*! Number of pixels between the key top and the characterPreviewDelegate bottom. */
+ property real characterPreviewMargin: 0
+
+ /*! Template for the character preview popup.
+
+ If the delegate contains \c text property, the property is updated
+ with the display text when the component becomes active.
+
+ \code
+ property string text
+ \endcode
+
+ Example:
+ \code
+ characterPreviewDelegate: Item {
+ property string text
+ id: characterPreview
+ Rectangle {
+ id: characterPreviewBackground
+ anchors.fill: parent
+ ...
+ Text {
+ text: characterPreview.text
+ anchors.fill: parent
+ ...
+ }
+ }
+ }
+ \endcode
+ */
+ property Component characterPreviewDelegate: null
+
+ /*! Width of the alternate keys list item. */
+ property real alternateKeysListItemWidth: 0
+
+ /*! Height of the alternate keys list item. */
+ property real alternateKeysListItemHeight: 0
+
+ /*! Top margin for the alternate keys list panel. */
+ property real alternateKeysListTopMargin: 0
+
+ /*! Bottom margin for the alternate keys list panel. */
+ property real alternateKeysListBottomMargin: 0
+
+ /*! Left margin for the alternate keys list panel. */
+ property real alternateKeysListLeftMargin: 0
+
+ /*! Right margin for the alternate keys list panel. */
+ property real alternateKeysListRightMargin: 0
+
+ /*! Template for the alternative keys list item.
+
+ \note The delegate is used as \c ListView.delegate.
+ */
+ property Component alternateKeysListDelegate: null
+
+ /*! Template for the alternative keys list highlight.
+
+ \note The delegate is used as \c ListView.highlight.
+ */
+ property Component alternateKeysListHighlight: null
+
+ /*! Template for the alternative keys list background. */
+ property Component alternateKeysListBackground: null
+
+ /*! Selection list height. */
+ property real selectionListHeight: 0
+
+ /*! Template for the selection list item.
+
+ \note The delegate is used as \c ListView.delegate.
+ \note The delegate must be based on SelectionListItem type.
+
+ The following attached properties are available to the item:
+ \list
+ \li \c display Display text for current item.
+ \li \c wordCompletionLength Word completion length measured from the end of the display text.
+ \endlist
+ */
+ property Component selectionListDelegate: null
+
+ /*! Template for the selection list highlight.
+
+ \note The delegate is used as \c ListView.highlight.
+ */
+ property Component selectionListHighlight: null
+
+ /*! Template for the selection list background. */
+ property Component selectionListBackground: null
+}
diff --git a/src/virtualkeyboard/styles/SelectionListItem.qml b/src/virtualkeyboard/styles/SelectionListItem.qml
new file mode 100644
index 00000000..58f10f38
--- /dev/null
+++ b/src/virtualkeyboard/styles/SelectionListItem.qml
@@ -0,0 +1,39 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+/*!
+ \qmltype SelectionListItem
+ \inqmlmodule QtQuick.Enterprise.VirtualKeyboard.Styles
+ \brief A base type for selection list item delegates.
+
+ The SelectionListItem enables mouse handling for the selection list item
+ delegates.
+*/
+
+Item {
+ id: selectionListItem
+ height: parent.height
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ hoverEnabled: true
+ onClicked: selectionListItem.ListView.view.model.itemSelected(index)
+ }
+}
diff --git a/src/virtualkeyboard/styles/plugins.qmltypes b/src/virtualkeyboard/styles/plugins.qmltypes
new file mode 100644
index 00000000..3ef80efb
--- /dev/null
+++ b/src/virtualkeyboard/styles/plugins.qmltypes
@@ -0,0 +1,4 @@
+import QtQuick.tooling 1.1
+
+Module {
+}
diff --git a/src/virtualkeyboard/styles/qmldir b/src/virtualkeyboard/styles/qmldir
new file mode 100644
index 00000000..322ae1f4
--- /dev/null
+++ b/src/virtualkeyboard/styles/qmldir
@@ -0,0 +1,6 @@
+module QtQuick.Enterprise.VirtualKeyboard.Styles
+plugin qtvirtualkeyboardstylesplugin
+KeyboardStyle 1.0 KeyboardStyle.qml
+KeyPanel 1.0 KeyPanel.qml
+KeyIcon 1.0 KeyIcon.qml
+SelectionListItem 1.0 SelectionListItem.qml
diff --git a/src/virtualkeyboard/styles/styles.pro b/src/virtualkeyboard/styles/styles.pro
new file mode 100644
index 00000000..a3a625a7
--- /dev/null
+++ b/src/virtualkeyboard/styles/styles.pro
@@ -0,0 +1,32 @@
+TEMPLATE = lib
+TARGET = qtvirtualkeyboardstylesplugin
+android-no-sdk {
+ TARGETPATH = /system/qml/QtQuick/Enterprise/VirtualKeyboard/Styles
+} else:!isEmpty(CROSS_COMPILE) {
+ TARGETPATH = /usr/local/Qt-$$[QT_VERSION]/qml/QtQuick/Enterprise/VirtualKeyboard/Styles
+} else {
+ TARGETPATH = $$[QT_INSTALL_QML]/QtQuick/Enterprise/VirtualKeyboard/Styles
+}
+QT += qml quick
+CONFIG += qt plugin
+
+target.path = $$TARGETPATH
+INSTALLS += target
+
+SOURCES += \
+ styles_plugin.cpp
+
+HEADERS += \
+ styles_plugin.h
+
+OTHER_FILES += \
+ KeyboardStyle.qml \
+ KeyPanel.qml \
+ KeyIcon.qml \
+ SelectionListItem.qml \
+ qmldir \
+ plugins.qmltypes
+
+other.files = $$OTHER_FILES
+other.path = $$TARGETPATH
+INSTALLS += other
diff --git a/src/virtualkeyboard/styles/styles_plugin.cpp b/src/virtualkeyboard/styles/styles_plugin.cpp
new file mode 100644
index 00000000..6dcecf21
--- /dev/null
+++ b/src/virtualkeyboard/styles/styles_plugin.cpp
@@ -0,0 +1,32 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "styles_plugin.h"
+
+#include <qqml.h>
+
+/*!
+ \qmlmodule QtQuick.Enterprise.VirtualKeyboard.Styles 1.0
+
+ This module provides styling components for the Qt Virtual Keyboard.
+*/
+
+void StylesPlugin::registerTypes(const char *uri)
+{
+ Q_UNUSED(uri)
+}
diff --git a/src/virtualkeyboard/styles/styles_plugin.h b/src/virtualkeyboard/styles/styles_plugin.h
new file mode 100644
index 00000000..aeaa287c
--- /dev/null
+++ b/src/virtualkeyboard/styles/styles_plugin.h
@@ -0,0 +1,34 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef STYLES_PLUGIN_H
+#define STYLES_PLUGIN_H
+
+#include <QQmlExtensionPlugin>
+
+class StylesPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0")
+
+public:
+ void registerTypes(const char *uri);
+};
+
+#endif // STYLES_PLUGIN_H
+
diff --git a/src/virtualkeyboard/virtualkeyboard.pro b/src/virtualkeyboard/virtualkeyboard.pro
new file mode 100644
index 00000000..a3aca8a8
--- /dev/null
+++ b/src/virtualkeyboard/virtualkeyboard.pro
@@ -0,0 +1,112 @@
+TEMPLATE = lib
+TARGET = qtvirtualkeyboardplugin
+android-no-sdk {
+ TARGETPATH = /system/plugins/platforminputcontexts
+ QMLPATH = /system/qml/QtQuick/Enterprise/VirtualKeyboard
+} else:!isEmpty(CROSS_COMPILE) {
+ TARGETPATH = /usr/local/Qt-$$[QT_VERSION]/plugins/platforminputcontexts
+ QMLPATH = /usr/local/Qt-$$[QT_VERSION]/qml/QtQuick/Enterprise/VirtualKeyboard
+} else {
+ TARGETPATH = $$[QT_INSTALL_PLUGINS]/platforminputcontexts
+ QMLPATH = $$[QT_INSTALL_QML]/QtQuick/Enterprise/VirtualKeyboard
+}
+
+QMAKE_DOCS = $$PWD/doc/qtvirtualkeyboard.qdocconf
+include(doc/doc.pri)
+
+target.path = $$TARGETPATH
+INSTALLS += target
+
+QT += quick gui gui-private
+
+CONFIG += plugin
+CONFIG += link_pkgconfig
+
+SOURCES += platforminputcontext.cpp \
+ declarativeinputcontext.cpp \
+ abstractinputmethod.cpp \
+ plaininputmethod.cpp \
+ declarativeinputengine.cpp \
+ declarativeshifthandler.cpp \
+ plugin.cpp \
+ declarativeinputmethod.cpp \
+ declarativeselectionlistmodel.cpp \
+ defaultinputmethod.cpp \
+ abstractinputpanel.cpp
+
+HEADERS += platforminputcontext.h \
+ declarativeinputcontext.h \
+ abstractinputmethod.h \
+ plaininputmethod.h \
+ declarativeinputengine.h \
+ declarativeshifthandler.h \
+ declarativeinputmethod.h \
+ declarativeselectionlistmodel.h \
+ defaultinputmethod.h \
+ abstractinputpanel.h \
+ virtualkeyboarddebug.h
+
+retro-style {
+ RESOURCES += content/styles/retro/style.qrc
+} else {
+ RESOURCES += content/styles/default/style.qrc
+}
+
+OTHER_FILES += content/InputPanel.qml \
+ content/qmldir \
+ content/components/*.qml \
+ content/layouts/*.qml \
+ content/styles/default/*.qml \
+ content/styles/retro/*.qml
+
+OTHER += qtvirtualkeyboard.json
+
+!disable-xcb:isEmpty(CROSS_COMPILE):packagesExist(xcb) {
+ PKGCONFIG += xcb xcb-xfixes
+ SOURCES += xcbinputpanel.cpp inputview.cpp
+ HEADERS += xcbinputpanel.h inputview.h
+ DEFINES += HAVE_XCB
+} else {
+ SOURCES += appinputpanel.cpp
+ HEADERS += appinputpanel.h
+}
+
+DEFINES += QT_VIRTUALKEYBOARD_IMPORT_PATH=\\\"$$QMLPATH\\\"
+qml.files = content/*.qml \
+ content/qmldir \
+ content/components \
+ content/layouts
+qml.path = $$QMLPATH
+INSTALLS += qml
+
+!disable-hunspell {
+ exists(hunspell/src/hunspell/hunspell.h) {
+ message(Found Hunspell library!)
+ SOURCES += hunspellinputmethod.cpp hunspellworker.cpp
+ HEADERS += hunspellinputmethod.h hunspellworker.h
+ DEFINES += HAVE_HUNSPELL
+ depends += hunspell
+ INCLUDEPATH += hunspell/src
+ LIBS += -Lhunspell -lhunspell
+ POST_TARGETDEPS += hunspell
+ isEmpty(hunspell_search_paths) hunspell_search_paths=$$QMLPATH/hunspell
+ DEFINES += QT_VIRTUALKEYBOARD_HUNSPELL_DATA_PATH=\\\"$$join(hunspell_search_paths, :)\\\"
+ exists(hunspell/data) {
+ hunspell_data.files = hunspell/data/*
+ hunspell_data.path = $$QMLPATH/hunspell
+ INSTALLS += hunspell_data
+ } else {
+ error(Hunspell dictionaries are missing! Please copy .dic and .aff files to src/virtualkeyboard/hunspell/data directory.)
+ }
+ } else:isEmpty(CROSS_COMPILE):packagesExist(hunspell) {
+ message(Found Hunspell package from pkg-config!)
+ SOURCES += hunspellinputmethod.cpp hunspellworker.cpp
+ HEADERS += hunspellinputmethod.h hunspellworker.h
+ DEFINES += HAVE_HUNSPELL
+ PKGCONFIG += hunspell
+ isEmpty(hunspell_search_paths) hunspell_search_paths=/usr/share/hunspell /usr/share/myspell
+ DEFINES += QT_VIRTUALKEYBOARD_HUNSPELL_DATA_PATH=\\\"$$join(hunspell_search_paths, :)\\\"
+ } else {
+ message(Hunspell not found! Spell correction will not be available.)
+ }
+}
diff --git a/src/virtualkeyboard/virtualkeyboarddebug.h b/src/virtualkeyboard/virtualkeyboarddebug.h
new file mode 100644
index 00000000..dbf7b4d0
--- /dev/null
+++ b/src/virtualkeyboard/virtualkeyboarddebug.h
@@ -0,0 +1,31 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef VIRTUALKEYBOARDDEBUG_H
+#define VIRTUALKEYBOARDDEBUG_H
+
+#include <QDebug>
+
+//#define QT_VIRTUALKEYBOARD_DEBUG
+#ifdef QT_VIRTUALKEYBOARD_DEBUG
+# define VIRTUALKEYBOARD_DEBUG qDebug
+#else
+# define VIRTUALKEYBOARD_DEBUG if (false) qDebug
+#endif
+
+#endif // VIRTUALKEYBOARDDEBUG_H
diff --git a/src/virtualkeyboard/xcbinputpanel.cpp b/src/virtualkeyboard/xcbinputpanel.cpp
new file mode 100644
index 00000000..240f74bc
--- /dev/null
+++ b/src/virtualkeyboard/xcbinputpanel.cpp
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "xcbinputpanel.h"
+#include "inputview.h"
+#include "platforminputcontext.h"
+#include "declarativeinputcontext.h"
+#include <QGuiApplication>
+#include <QQmlEngine>
+#include <QScreen>
+#include "virtualkeyboarddebug.h"
+#include <xcb/xcb.h>
+#include <xcb/xfixes.h>
+#include <qpa/qplatformnativeinterface.h>
+
+class XcbInputPanelPrivate
+{
+public:
+ QScopedPointer<InputView> view;
+};
+
+XcbInputPanel::XcbInputPanel(QObject *parent) :
+ AbstractInputPanel(parent),
+ d_ptr(new XcbInputPanelPrivate())
+{
+ /* Activate the alpha buffer for this application.
+ */
+ QQuickWindow::setDefaultAlphaBuffer(true);
+ QScreen *screen = QGuiApplication::primaryScreen();
+ connect(screen, SIGNAL(virtualGeometryChanged(QRect)), SLOT(repositionView(QRect)));
+}
+
+XcbInputPanel::~XcbInputPanel()
+{
+}
+
+void XcbInputPanel::show()
+{
+ Q_D(XcbInputPanel);
+ repositionView(QGuiApplication::primaryScreen()->availableGeometry());
+ d->view->show();
+}
+
+void XcbInputPanel::hide()
+{
+ Q_D(XcbInputPanel);
+ if (d->view) {
+ d->view->hide();
+ }
+}
+
+bool XcbInputPanel::isVisible() const
+{
+ Q_D(const XcbInputPanel);
+ return d->view && d->view->isVisible();
+}
+
+void XcbInputPanel::setInputRect(const QRect &inputRect)
+{
+ VIRTUALKEYBOARD_DEBUG() << "XcbInputPanel::setInputRect():" << inputRect;
+ /* Set input region using platform specific code.
+ In optimal case there should be generic way to
+ do this, but currenly none is available.
+ */
+ Q_D(XcbInputPanel);
+ QWindow *window = d->view.data();
+ if (!window) {
+ return;
+ }
+ QPlatformNativeInterface *platformNativeInterface = QGuiApplication::platformNativeInterface();
+ xcb_connection_t *xbcConnection = static_cast<xcb_connection_t *>(platformNativeInterface->nativeResourceForWindow("connection", window));
+ xcb_xfixes_region_t xbcRegion = xcb_generate_id(xbcConnection);
+ const xcb_rectangle_t xbcInputRect = {
+ static_cast<int16_t>(inputRect.x()),
+ static_cast<int16_t>(inputRect.y()),
+ static_cast<uint16_t>(inputRect.width()),
+ static_cast<uint16_t>(inputRect.height())
+ };
+ xcb_xfixes_create_region(xbcConnection, xbcRegion, 1, &xbcInputRect);
+ xcb_xfixes_set_window_shape_region(xbcConnection, window->winId(), XCB_SHAPE_SK_INPUT, 0, 0, xbcRegion);
+ xcb_xfixes_destroy_region(xbcConnection, xbcRegion);
+}
+
+void XcbInputPanel::createView()
+{
+ Q_D(XcbInputPanel);
+ if (!d->view) {
+ if (qGuiApp) {
+ connect(qGuiApp, SIGNAL(focusWindowChanged(QWindow*)), SLOT(focusWindowChanged(QWindow*)));
+ focusWindowChanged(qGuiApp->focusWindow());
+ }
+ d->view.reset(new InputView());
+ d->view->setFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::WindowDoesNotAcceptFocus | Qt::BypassWindowManagerHint);
+ d->view->setColor(QColor(Qt::transparent));
+ const QString virtualKeyboardImportPath(QT_VIRTUALKEYBOARD_IMPORT_PATH);
+ d->view->engine()->addImportPath(virtualKeyboardImportPath);
+ d->view->setSource(QUrl::fromLocalFile(virtualKeyboardImportPath+"/InputPanel.qml"));
+ /* Destroy the view along with the last window in application. */
+ connect(qGuiApp, SIGNAL(lastWindowClosed()), SLOT(destroyView()));
+ }
+}
+
+void XcbInputPanel::destroyView()
+{
+ Q_D(XcbInputPanel);
+ d->view.reset();
+}
+
+void XcbInputPanel::repositionView(const QRect &rect)
+{
+ Q_D(XcbInputPanel);
+ VIRTUALKEYBOARD_DEBUG() << "XcbInputPanel::repositionView():" << rect;
+ if (d->view && d->view->geometry() != rect) {
+ DeclarativeInputContext *inputContext = qobject_cast<PlatformInputContext *>(parent())->declarativeInputContext();
+ if (inputContext)
+ inputContext->setAnimating(true);
+ d->view->setResizeMode(QQuickView::SizeViewToRootObject);
+ setInputRect(QRect());
+ d->view->setGeometry(rect);
+ d->view->setResizeMode(QQuickView::SizeRootObjectToView);
+ if (inputContext)
+ inputContext->setAnimating(false);
+ }
+}
+
+void XcbInputPanel::focusWindowChanged(QWindow *focusWindow)
+{
+ disconnect(this, SLOT(focusWindowVisibleChanged(bool)));
+ if (focusWindow)
+ connect(focusWindow, SIGNAL(visibleChanged(bool)), SLOT(focusWindowVisibleChanged(bool)));
+}
+
+void XcbInputPanel::focusWindowVisibleChanged(bool visible)
+{
+ if (!visible) {
+ DeclarativeInputContext *inputContext = qobject_cast<PlatformInputContext *>(parent())->declarativeInputContext();
+ if (inputContext)
+ inputContext->hideInputPanel();
+ }
+}
diff --git a/src/virtualkeyboard/xcbinputpanel.h b/src/virtualkeyboard/xcbinputpanel.h
new file mode 100644
index 00000000..b9a091f2
--- /dev/null
+++ b/src/virtualkeyboard/xcbinputpanel.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Quick Enterprise Controls add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef INPUTPANEL_H
+#define INPUTPANEL_H
+
+#include "abstractinputpanel.h"
+
+class QWindow;
+class XcbInputPanelPrivate;
+
+class XcbInputPanel : public AbstractInputPanel
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(XcbInputPanel)
+public:
+ explicit XcbInputPanel(QObject *parent = 0);
+ ~XcbInputPanel();
+
+ void show();
+ void hide();
+ bool isVisible() const;
+
+ void setInputRect(const QRect &inputRect);
+
+public slots:
+ void createView();
+ void destroyView();
+
+protected slots:
+ void repositionView(const QRect &rect);
+ void focusWindowChanged(QWindow *focusWindow);
+ void focusWindowVisibleChanged(bool visible);
+
+private:
+ QScopedPointer<XcbInputPanelPrivate> d_ptr;
+};
+
+#endif // INPUTPANEL_H