From 92740638df5b329e5f052700327ac4a1cdfead1f Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 18 Oct 2011 14:51:53 +0200 Subject: Initial support for MeeGo's input method server This platform input context plugin is based on the dbus protocol used in MeeGo 1.2 Harmattan's input method server. It supports composition, mouse-click-on-preedit as well as basic input method hints. Missing are: Copy & paste, preedit injection, key redirection as well as a bunch of other smaller MeeGoTouch specific features. Change-Id: Ic3a8741f7a5ed18b379985e316cb137f7b8f6a8e Reviewed-by: Lars Knoll Reviewed-by: Simon Hausmann Reviewed-by: Kenneth Rohde Christiansen --- .../platforminputcontexts/meego/contextadaptor.cpp | 158 ++++++ .../platforminputcontexts/meego/contextadaptor.h | 148 ++++++ src/plugins/platforminputcontexts/meego/main.cpp | 71 +++ src/plugins/platforminputcontexts/meego/meego.pro | 17 + .../meego/qmeegoplatforminputcontext.cpp | 552 +++++++++++++++++++++ .../meego/qmeegoplatforminputcontext.h | 98 ++++ .../platforminputcontexts/meego/serverproxy.cpp | 56 +++ .../platforminputcontexts/meego/serverproxy.h | 166 +++++++ .../platforminputcontexts.pro | 1 + 9 files changed, 1267 insertions(+) create mode 100644 src/plugins/platforminputcontexts/meego/contextadaptor.cpp create mode 100644 src/plugins/platforminputcontexts/meego/contextadaptor.h create mode 100644 src/plugins/platforminputcontexts/meego/main.cpp create mode 100644 src/plugins/platforminputcontexts/meego/meego.pro create mode 100644 src/plugins/platforminputcontexts/meego/qmeegoplatforminputcontext.cpp create mode 100644 src/plugins/platforminputcontexts/meego/qmeegoplatforminputcontext.h create mode 100644 src/plugins/platforminputcontexts/meego/serverproxy.cpp create mode 100644 src/plugins/platforminputcontexts/meego/serverproxy.h diff --git a/src/plugins/platforminputcontexts/meego/contextadaptor.cpp b/src/plugins/platforminputcontexts/meego/contextadaptor.cpp new file mode 100644 index 0000000000..45b1102a98 --- /dev/null +++ b/src/plugins/platforminputcontexts/meego/contextadaptor.cpp @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "contextadaptor.h" +#include +#include +#include +#include +#include +#include +#include + +#include "qmeegoplatforminputcontext.h" + +/* + * Implementation of adaptor class Inputcontext1Adaptor + */ + +Inputcontext1Adaptor::Inputcontext1Adaptor(QObject *parent) + : QDBusAbstractAdaptor(parent) +{ + // constructor + setAutoRelaySignals(true); +} + +Inputcontext1Adaptor::~Inputcontext1Adaptor() +{ + // destructor +} + +void Inputcontext1Adaptor::activationLostEvent() +{ + // handle method call com.meego.inputmethod.inputcontext1.activationLostEvent + QMetaObject::invokeMethod(parent(), "activationLostEvent"); +} + +void Inputcontext1Adaptor::commitString(const QString &in0, int in1, int in2, int in3) +{ + // handle method call com.meego.inputmethod.inputcontext1.commitString + QMetaObject::invokeMethod(parent(), "commitString", Q_ARG(QString, in0), Q_ARG(int, in1), Q_ARG(int, in2), Q_ARG(int, in3)); +} + +void Inputcontext1Adaptor::updatePreedit(const QDBusMessage &message) +{ + // handle method call com.meego.inputmethod.inputcontext1.updatePreedit + QMetaObject::invokeMethod(parent(), "updatePreedit", Q_ARG(QDBusMessage, message)); +} + +void Inputcontext1Adaptor::copy() +{ + // handle method call com.meego.inputmethod.inputcontext1.copy + QMetaObject::invokeMethod(parent(), "copy"); +} + +void Inputcontext1Adaptor::imInitiatedHide() +{ + // handle method call com.meego.inputmethod.inputcontext1.imInitiatedHide + QMetaObject::invokeMethod(parent(), "imInitiatedHide"); +} + +void Inputcontext1Adaptor::keyEvent(int in0, int in1, int in2, const QString &in3, bool in4, int in5, uchar in6) +{ + // handle method call com.meego.inputmethod.inputcontext1.keyEvent + QMetaObject::invokeMethod(parent(), "keyEvent", Q_ARG(int, in0), Q_ARG(int, in1), Q_ARG(int, in2), Q_ARG(QString, in3), Q_ARG(bool, in4), Q_ARG(int, in5), Q_ARG(uchar, in6)); +} + +void Inputcontext1Adaptor::paste() +{ + // handle method call com.meego.inputmethod.inputcontext1.paste + QMetaObject::invokeMethod(parent(), "paste"); +} + +bool Inputcontext1Adaptor::preeditRectangle(int &out1, int &out2, int &out3, int &out4) +{ + // handle method call com.meego.inputmethod.inputcontext1.preeditRectangle + return static_cast(parent())->preeditRectangle(out1, out2, out3, out4); +} + +bool Inputcontext1Adaptor::selection(QString &out1) +{ + // handle method call com.meego.inputmethod.inputcontext1.selection + return static_cast(parent())->selection(out1); +} + +void Inputcontext1Adaptor::setDetectableAutoRepeat(bool in0) +{ + // handle method call com.meego.inputmethod.inputcontext1.setDetectableAutoRepeat + QMetaObject::invokeMethod(parent(), "setDetectableAutoRepeat", Q_ARG(bool, in0)); +} + +void Inputcontext1Adaptor::setGlobalCorrectionEnabled(bool in0) +{ + // handle method call com.meego.inputmethod.inputcontext1.setGlobalCorrectionEnabled + QMetaObject::invokeMethod(parent(), "setGlobalCorrectionEnabled", Q_ARG(bool, in0)); +} + +void Inputcontext1Adaptor::setLanguage(const QString &in0) +{ + // handle method call com.meego.inputmethod.inputcontext1.setLanguage + QMetaObject::invokeMethod(parent(), "setLanguage", Q_ARG(QString, in0)); +} + +void Inputcontext1Adaptor::setRedirectKeys(bool in0) +{ + // handle method call com.meego.inputmethod.inputcontext1.setRedirectKeys + QMetaObject::invokeMethod(parent(), "setRedirectKeys", Q_ARG(bool, in0)); +} + +void Inputcontext1Adaptor::setSelection(int in0, int in1) +{ + // handle method call com.meego.inputmethod.inputcontext1.setSelection + QMetaObject::invokeMethod(parent(), "setSelection", Q_ARG(int, in0), Q_ARG(int, in1)); +} + +void Inputcontext1Adaptor::updateInputMethodArea(int in0, int in1, int in2, int in3) +{ + // handle method call com.meego.inputmethod.inputcontext1.updateInputMethodArea + QMetaObject::invokeMethod(parent(), "updateInputMethodArea", Q_ARG(int, in0), Q_ARG(int, in1), Q_ARG(int, in2), Q_ARG(int, in3)); +} + diff --git a/src/plugins/platforminputcontexts/meego/contextadaptor.h b/src/plugins/platforminputcontexts/meego/contextadaptor.h new file mode 100644 index 0000000000..8f134a5cb0 --- /dev/null +++ b/src/plugins/platforminputcontexts/meego/contextadaptor.h @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CONTEXT_H_1318935171 +#define CONTEXT_H_1318935171 + +#include +#include +class QByteArray; +template class QList; +template class QMap; +class QString; +class QStringList; +class QVariant; + +/* + * Adaptor class for interface com.meego.inputmethod.inputcontext1 + */ +class Inputcontext1Adaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.meego.inputmethod.inputcontext1") + Q_CLASSINFO("D-Bus Introspection", "" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" + "") +public: + Inputcontext1Adaptor(QObject *parent); + virtual ~Inputcontext1Adaptor(); + +public: // PROPERTIES +public Q_SLOTS: // METHODS + void activationLostEvent(); + void commitString(const QString &in0, int in1, int in2, int in3); + void updatePreedit(const QDBusMessage &message); + void copy(); + void imInitiatedHide(); + void keyEvent(int in0, int in1, int in2, const QString &in3, bool in4, int in5, uchar in6); + void paste(); + bool preeditRectangle(int &out1, int &out2, int &out3, int &out4); + bool selection(QString &out1); + void setDetectableAutoRepeat(bool in0); + void setGlobalCorrectionEnabled(bool in0); + void setLanguage(const QString &in0); + void setRedirectKeys(bool in0); + void setSelection(int in0, int in1); + void updateInputMethodArea(int in0, int in1, int in2, int in3); +Q_SIGNALS: // SIGNALS +}; + +#endif diff --git a/src/plugins/platforminputcontexts/meego/main.cpp b/src/plugins/platforminputcontexts/meego/main.cpp new file mode 100644 index 0000000000..f8558b498d --- /dev/null +++ b/src/plugins/platforminputcontexts/meego/main.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include "qmeegoplatforminputcontext.h" + +QT_BEGIN_NAMESPACE + +class QMeeGoPlatformInputContextPlugin : public QPlatformInputContextPlugin +{ +public: + QStringList keys() const; + QPlatformInputContext *create(const QString&, const QStringList&); +}; + +QStringList QMeeGoPlatformInputContextPlugin::keys() const +{ + return QStringList(QStringLiteral("meego")); +} + +QPlatformInputContext *QMeeGoPlatformInputContextPlugin::create(const QString& system, const QStringList& paramList) +{ + Q_UNUSED(paramList); + + if (system.compare(system, QStringLiteral("meego"), Qt::CaseInsensitive) == 0) + return new QMeeGoPlatformInputContext; + return 0; +} + +Q_EXPORT_PLUGIN2(meegoplatforminputcontextplugin, QMeeGoPlatformInputContextPlugin) + +QT_END_NAMESPACE diff --git a/src/plugins/platforminputcontexts/meego/meego.pro b/src/plugins/platforminputcontexts/meego/meego.pro new file mode 100644 index 0000000000..fad256e3dc --- /dev/null +++ b/src/plugins/platforminputcontexts/meego/meego.pro @@ -0,0 +1,17 @@ +TARGET = meegoplatforminputcontextplugin +load(qt_plugin) + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforminputcontexts + +QT += dbus platformsupport-private +SOURCES += $$PWD/qmeegoplatforminputcontext.cpp \ + $$PWD/serverproxy.cpp \ + $$PWD/contextadaptor.cpp \ + $$PWD/main.cpp + +HEADERS += $$PWD/qmeegoplatforminputcontext.h \ + $$PWD/serverproxy.h \ + $$PWD/contextadaptor.h + +target.path += $$[QT_INSTALL_PLUGINS]/platforminputcontexts +INSTALLS += target diff --git a/src/plugins/platforminputcontexts/meego/qmeegoplatforminputcontext.cpp b/src/plugins/platforminputcontexts/meego/qmeegoplatforminputcontext.cpp new file mode 100644 index 0000000000..2098ba806d --- /dev/null +++ b/src/plugins/platforminputcontexts/meego/qmeegoplatforminputcontext.cpp @@ -0,0 +1,552 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "qmeegoplatforminputcontext.h" + +#include +#include +#include +#include +#include +#include + +#include "serverproxy.h" +#include "contextadaptor.h" + +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +enum { debug = 1 }; + +enum InputPanelVisibility { + InputPanelHidden, + InputPanelShowRequested, + InputPanelShown +}; + +enum MaliitOrientationAngle { + Angle0 = 0, + Angle90 = 90, + Angle180 = 180, + Angle270 = 270 +}; + +static int orientationAngle(Qt::ScreenOrientation orientation) +{ + switch (orientation) { + case Qt::UnknownOrientation: // Urgh. + case Qt::PortraitOrientation: + return Angle270; + case Qt::LandscapeOrientation: + return Angle0; + case Qt::InvertedPortraitOrientation: + return Angle90; + case Qt::InvertedLandscapeOrientation: + return Angle180; + } + return Angle0; +} + +// From MTF: +//! Content type for text entries. Used at least with MTextEdit +enum TextContentType { + //! all characters allowed + FreeTextContentType, + + //! only integer numbers allowed + NumberContentType, + + //! allows numbers and certain other characters used in phone numbers + PhoneNumberContentType, + + //! allows only characters permitted in email address + EmailContentType, + + //! allows only character permitted in URL address + UrlContentType, + + //! allows content with user defined format + CustomContentType +}; +static TextContentType contentTypeFromHints(Qt::InputMethodHints hints) +{ + TextContentType type = FreeTextContentType; + hints &= Qt::ImhExclusiveInputMask; + + if (hints == Qt::ImhFormattedNumbersOnly || hints == Qt::ImhDigitsOnly) + type = NumberContentType; + else if (hints == Qt::ImhDialableCharactersOnly) + type = PhoneNumberContentType; + else if (hints == Qt::ImhEmailCharactersOnly) + type = EmailContentType; + else if (hints == Qt::ImhUrlCharactersOnly) + type = UrlContentType; + + return type; +} + +class QMeeGoPlatformInputContextPrivate +{ +public: + QMeeGoPlatformInputContextPrivate(QMeeGoPlatformInputContext *qq); + ~QMeeGoPlatformInputContextPrivate() + { + delete adaptor; + delete server; + } + + void sendStateUpdate(bool focusChanged = false); + + QDBusConnection connection; + ComMeegoInputmethodUiserver1Interface *server; + Inputcontext1Adaptor *adaptor; + + QMap imState; + + InputPanelVisibility visibility; + + bool valid; + bool active; + bool correctionEnabled; + QRect keyboardRect; + QString preedit; + QMeeGoPlatformInputContext *q; +}; + + +QMeeGoPlatformInputContext::QMeeGoPlatformInputContext() + : d(new QMeeGoPlatformInputContextPrivate(this)) +{ + if (debug) + qDebug() << "QMeeGoPlatformInputContext::QMeeGoPlatformInputContext()"; + QInputPanel *p = qApp->inputPanel(); + connect(p, SIGNAL(inputItemChanged()), this, SLOT(inputItemChanged())); +} + +QMeeGoPlatformInputContext::~QMeeGoPlatformInputContext(void) +{ + delete d; +} + +bool QMeeGoPlatformInputContext::isValid() const +{ + return d->valid; +} + +void QMeeGoPlatformInputContext::invokeAction(QInputPanel::Action action, int x) +{ + QObject *input = qApp->inputPanel()->inputItem(); + if (!input) + return; + + if (action == QInputPanel::Click) { + if (x < 0 || x >= d->preedit.length()) { + reset(); + return; + } + + d->imState["preeditClickPos"] = x; + d->sendStateUpdate(); + // The first argument is the mouse pos and the second is the + // preedit rectangle. Both are unused on the server side. + d->server->mouseClickedOnPreedit(0, 0, 0, 0, 0, 0); + } else { + QPlatformInputContext::invokeAction(action, x); + } +} + +void QMeeGoPlatformInputContext::reset() +{ + QObject *input = qApp->inputPanel()->inputItem(); + + const bool hadPreedit = !d->preedit.isEmpty(); + if (hadPreedit && input) { + // ### selection + QInputMethodEvent event; + event.setCommitString(d->preedit); + QGuiApplication::sendEvent(input, &event); + d->preedit.clear(); + } + + QDBusPendingReply reply = d->server->reset(); + if (hadPreedit) + reply.waitForFinished(); +} + +void QMeeGoPlatformInputContext::update(Qt::InputMethodQueries queries) +{ + QInputPanel *panel = qApp->inputPanel(); + QObject *input = panel->inputItem(); + if (!input) + return; + + QInputMethodQueryEvent query(queries); + QGuiApplication::sendEvent(input, &query); + + if (queries & Qt::ImSurroundingText) + d->imState["surroundingText"] = query.value(Qt::ImSurroundingText); + if (queries & Qt::ImCursorPosition) + d->imState["cursorPosition"] = query.value(Qt::ImCursorPosition); + if (queries & Qt::ImAnchorPosition) + d->imState["anchorPosition"] = query.value(Qt::ImAnchorPosition); + if (queries & Qt::ImCursorRectangle) { + QRect rect = query.value(Qt::ImCursorRectangle).toRect(); + rect = panel->inputItemTransform().mapRect(rect); + QWindow *window = panel->inputWindow(); + if (window) + d->imState["cursorRectangle"] = QRect(window->mapToGlobal(rect.topLeft()), rect.size()); + } + + if (queries & Qt::ImCurrentSelection) + d->imState["hasSelection"] = !query.value(Qt::ImCurrentSelection).toString().isEmpty(); + + if (queries & Qt::ImHints) { + Qt::InputMethodHints hints = Qt::InputMethodHints(query.value(Qt::ImHints).toUInt()); + + d->imState["predictionEnabled"] = !(hints & Qt::ImhNoPredictiveText); + d->imState["autocapitalizationEnabled"] = !(hints & Qt::ImhNoAutoUppercase); + d->imState["hiddenText"] = (hints & Qt::ImhHiddenText) != 0; + + d->imState["contentType"] = contentTypeFromHints(hints); + } + + d->sendStateUpdate(/*focusChanged*/true); +} + +QRectF QMeeGoPlatformInputContext::keyboardRect() const +{ + return d->keyboardRect; +} + +void QMeeGoPlatformInputContext::activationLostEvent() +{ + d->active = false; + d->visibility = InputPanelHidden; +} + +void QMeeGoPlatformInputContext::commitString(const QString &string, int replacementStart, int replacementLength, int cursorPos) +{ + QObject *input = qApp->inputPanel()->inputItem(); + if (!input) + return; + + d->preedit.clear(); + + if (debug) + qWarning() << "CommitString" << string; + // ### start/cursorPos + QInputMethodEvent event; + event.setCommitString(string, replacementStart, replacementLength); + QCoreApplication::sendEvent(input, &event); +} + +void QMeeGoPlatformInputContext::updatePreedit(const QDBusMessage &message) +{ + QObject *input = qApp->inputPanel()->inputItem(); + if (!input) + return; + + QList arguments = message.arguments(); + if (arguments.count() != 5) { + qWarning() << "QMeeGoPlatformInputContext::updatePreedit: Received message from input method server with wrong parameters."; + return; + } + + d->preedit = arguments[0].toString(); + + QList attributes; + + const QDBusArgument formats = arguments[1].value(); + formats.beginArray(); + while (!formats.atEnd()) { + formats.beginStructure(); + int start, length, preeditFace; + formats >> start >> length >> preeditFace; + formats.endStructure(); + + QTextCharFormat format; + + enum PreeditFace { + PreeditDefault, + PreeditNoCandidates, + PreeditKeyPress, //!< Used for displaying the hwkbd key just pressed + PreeditUnconvertible, //!< Inactive preedit region, not clickable + PreeditActive, //!< Preedit region with active suggestions + + }; + switch (PreeditFace(preeditFace)) { + case PreeditDefault: + case PreeditKeyPress: + format.setUnderlineStyle(QTextCharFormat::SingleUnderline); + format.setUnderlineColor(QColor(0, 0, 0)); + break; + case PreeditNoCandidates: + format.setUnderlineStyle(QTextCharFormat::SingleUnderline); + format.setUnderlineColor(QColor(255, 0, 0)); + break; + case PreeditUnconvertible: + format.setForeground(QBrush(QColor(128, 128, 128))); + break; + case PreeditActive: + format.setForeground(QBrush(QColor(153, 50, 204))); + format.setFontWeight(QFont::Bold); + break; + default: + break; + } + + attributes << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, start, length, format); + } + formats.endArray(); + + int replacementStart = arguments[2].toInt(); + int replacementLength = arguments[3].toInt(); + int cursorPos = arguments[4].toInt(); + + if (debug) + qWarning() << "updatePreedit" << d->preedit << replacementStart << replacementLength << cursorPos; + + if (cursorPos >= 0) + attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, cursorPos, 1, QVariant()); + + QInputMethodEvent event(d->preedit, attributes); + if (replacementStart || replacementLength) + event.setCommitString(QString(), replacementStart, replacementLength); + QCoreApplication::sendEvent(input, &event); +} + +void QMeeGoPlatformInputContext::copy() +{ + // Not supported at the moment. +} + +void QMeeGoPlatformInputContext::imInitiatedHide() +{ + d->visibility = InputPanelHidden; + emitInputPanelVisibleChanged(); + // ### clear focus +} + +void QMeeGoPlatformInputContext::keyEvent(int, int, int, const QString &, bool, int, uchar) +{ + // Not supported at the moment. +} + +void QMeeGoPlatformInputContext::paste() +{ + // Not supported at the moment. +} + +bool QMeeGoPlatformInputContext::preeditRectangle(int &x, int &y, int &width, int &height) +{ + // ### + QRect r = qApp->inputPanel()->cursorRectangle().toRect(); + if (!r.isValid()) + return false; + x = r.x(); + y = r.y(); + width = r.width(); + height = r.height(); + return true; +} + +bool QMeeGoPlatformInputContext::selection(QString &selection) +{ + selection.clear(); + + QObject *input = qApp->inputPanel()->inputItem(); + if (!input) + return false; + + QInputMethodQueryEvent query(Qt::ImCurrentSelection); + QGuiApplication::sendEvent(input, &query); + QVariant value = query.value(Qt::ImCurrentSelection); + if (!value.isValid()) + return false; + + selection = value.toString(); + return true; +} + +void QMeeGoPlatformInputContext::setDetectableAutoRepeat(bool) +{ + // Not supported. +} + +void QMeeGoPlatformInputContext::setGlobalCorrectionEnabled(bool enable) +{ + d->correctionEnabled = enable; +} + +void QMeeGoPlatformInputContext::setLanguage(const QString &) +{ + // Unused at the moment. +} + +void QMeeGoPlatformInputContext::setRedirectKeys(bool) +{ + // Not supported. +} + +void QMeeGoPlatformInputContext::setSelection(int start, int length) +{ + QObject *input = qApp->inputPanel()->inputItem(); + if (!input) + return; + + QList attributes; + attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, start, length, QVariant()); + QInputMethodEvent event(QString(), attributes); + QGuiApplication::sendEvent(input, &event); +} + +void QMeeGoPlatformInputContext::updateInputMethodArea(int x, int y, int width, int height) +{ + d->keyboardRect = QRect(x, y, width, height); + emitKeyboardRectChanged(); +} + +void QMeeGoPlatformInputContext::inputItemChanged() +{ + if (!d->valid) + return; + + QInputPanel *panel = qApp->inputPanel(); + QObject *input = panel->inputItem(); + QWindow *window = panel->inputWindow(); + + d->imState["focusState"] = input != 0; + if (input) { + if (window) + d->imState["winId"] = static_cast(window->winId()); + + if (!d->active) { + d->active = true; + d->server->activateContext(); + + // ### react to orientation changes, too + if (window) + d->server->appOrientationChanged(orientationAngle(window->screen()->currentOrientation())); + } + } + d->sendStateUpdate(/*focusChanged*/true); + if (input && window && d->visibility == InputPanelShowRequested) + showInputPanel(); +} + +// temporary function added to retain compatibility to old functionality, will be deprecated +bool QMeeGoPlatformInputContext::handlesInputPanelVisibility() const +{ + return true; +} + +void QMeeGoPlatformInputContext::showInputPanel() +{ + if (debug) + qDebug() << "showInputPanel"; + + QInputPanel *panel = qApp->inputPanel(); + if (!panel->inputItem() || !panel->inputWindow()) + d->visibility = InputPanelShowRequested; + else { + d->server->showInputMethod(); + d->visibility = InputPanelShown; + emitInputPanelVisibleChanged(); + } +} + +void QMeeGoPlatformInputContext::hideInputPanel() +{ + d->server->hideInputMethod(); + d->visibility = InputPanelHidden; + emitInputPanelVisibleChanged(); +} + +bool QMeeGoPlatformInputContext::isInputPanelVisible() const +{ + return d->visibility == InputPanelShown; +} + +QMeeGoPlatformInputContextPrivate::QMeeGoPlatformInputContextPrivate(QMeeGoPlatformInputContext* qq) + : connection(QDBusConnection::connectToPeer(QStringLiteral("unix:path=/tmp/meego-im-uiserver/imserver_dbus"), QLatin1String("MeeGoIMProxy"))) + , server(0) + , adaptor(0) + , visibility(InputPanelHidden) + , valid(false) + , active(false) + , correctionEnabled(false) + , q(qq) +{ + if (!connection.isConnected()) { + qDebug("QMeeGoPlatformInputContext: not connected."); + return; + } + + server = new ComMeegoInputmethodUiserver1Interface(QStringLiteral(""), QStringLiteral("/com/meego/inputmethod/uiserver1"), connection); + adaptor = new Inputcontext1Adaptor(qq); + connection.registerObject("/com/meego/inputmethod/inputcontext", qq); + + enum InputMethodMode { + //! Normal mode allows to use preedit and error correction + InputMethodModeNormal, + + //! Virtual keyboard sends QKeyEvent for every key press or release + InputMethodModeDirect, + + //! Used with proxy widget + InputMethodModeProxy + }; + imState["inputMethodMode"] = InputMethodModeNormal; + + imState["correctionEnabled"] = true; + + valid = true; +} + +void QMeeGoPlatformInputContextPrivate::sendStateUpdate(bool focusChanged) +{ + server->updateWidgetInformation(imState, focusChanged); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforminputcontexts/meego/qmeegoplatforminputcontext.h b/src/plugins/platforminputcontexts/meego/qmeegoplatforminputcontext.h new file mode 100644 index 0000000000..5e1ee78331 --- /dev/null +++ b/src/plugins/platforminputcontexts/meego/qmeegoplatforminputcontext.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QMEEGOPLATFORMINPUTCONTEXT_H +#define QMEEGOPLATFORMINPUTCONTEXT_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QMeeGoPlatformInputContextPrivate; +class QDBusVariant; +class QDBusMessage; + +class QMeeGoPlatformInputContext : public QPlatformInputContext +{ + Q_OBJECT +public: + QMeeGoPlatformInputContext(); + ~QMeeGoPlatformInputContext(); + + bool isValid() const; + + void invokeAction(QInputPanel::Action action, int x); + void reset(void); + void update(Qt::InputMethodQueries); + virtual QRectF keyboardRect() const; + + virtual bool handlesInputPanelVisibility() const; + + virtual void showInputPanel(); + virtual void hideInputPanel(); + virtual bool isInputPanelVisible() const; + +public Q_SLOTS: + void inputItemChanged(); + + void activationLostEvent(); + void commitString(const QString &in0, int in1, int in2, int in3); + void updatePreedit(const QDBusMessage &message); + void copy(); + void imInitiatedHide(); + void keyEvent(int , int , int , const QString &, bool , int , uchar ); + void paste(); + bool preeditRectangle(int &x, int &y, int &width, int &height); + bool selection(QString &selection); + void setDetectableAutoRepeat(bool in0); + void setGlobalCorrectionEnabled(bool enable); + void setLanguage(const QString &); + void setRedirectKeys(bool ); + void setSelection(int start, int length); + void updateInputMethodArea(int x, int y, int width, int height); + +private: + QMeeGoPlatformInputContextPrivate *d; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforminputcontexts/meego/serverproxy.cpp b/src/plugins/platforminputcontexts/meego/serverproxy.cpp new file mode 100644 index 0000000000..5715d8f19a --- /dev/null +++ b/src/plugins/platforminputcontexts/meego/serverproxy.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "serverproxy.h" + +/* + * Implementation of interface class ComMeegoInputmethodUiserver1Interface + */ + +ComMeegoInputmethodUiserver1Interface::ComMeegoInputmethodUiserver1Interface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +ComMeegoInputmethodUiserver1Interface::~ComMeegoInputmethodUiserver1Interface() +{ +} + diff --git a/src/plugins/platforminputcontexts/meego/serverproxy.h b/src/plugins/platforminputcontexts/meego/serverproxy.h new file mode 100644 index 0000000000..3ad589409c --- /dev/null +++ b/src/plugins/platforminputcontexts/meego/serverproxy.h @@ -0,0 +1,166 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SERVER_H_1318935108 +#define SERVER_H_1318935108 + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.meego.inputmethod.uiserver1 + */ +class ComMeegoInputmethodUiserver1Interface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.meego.inputmethod.uiserver1"; } + +public: + ComMeegoInputmethodUiserver1Interface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); + + ~ComMeegoInputmethodUiserver1Interface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply<> activateContext() + { + QList argumentList; + return asyncCallWithArgumentList(QLatin1String("activateContext"), argumentList); + } + + inline QDBusPendingReply<> appOrientationAboutToChange(int in0) + { + QList argumentList; + argumentList << QVariant::fromValue(in0); + return asyncCallWithArgumentList(QLatin1String("appOrientationAboutToChange"), argumentList); + } + + inline QDBusPendingReply<> appOrientationChanged(int in0) + { + QList argumentList; + argumentList << QVariant::fromValue(in0); + return asyncCallWithArgumentList(QLatin1String("appOrientationChanged"), argumentList); + } + + inline QDBusPendingReply<> hideInputMethod() + { + QList argumentList; + return asyncCallWithArgumentList(QLatin1String("hideInputMethod"), argumentList); + } + + inline QDBusPendingReply<> mouseClickedOnPreedit(int in0, int in1, int in2, int in3, int in4, int in5) + { + QList argumentList; + argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1) << QVariant::fromValue(in2) << QVariant::fromValue(in3) << QVariant::fromValue(in4) << QVariant::fromValue(in5); + return asyncCallWithArgumentList(QLatin1String("mouseClickedOnPreedit"), argumentList); + } + + inline QDBusPendingReply<> processKeyEvent(int in0, int in1, int in2, const QString &in3, bool in4, int in5, uint in6, uint in7, uint in8) + { + QList argumentList; + argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1) << QVariant::fromValue(in2) << QVariant::fromValue(in3) << QVariant::fromValue(in4) << QVariant::fromValue(in5) << QVariant::fromValue(in6) << QVariant::fromValue(in7) << QVariant::fromValue(in8); + return asyncCallWithArgumentList(QLatin1String("processKeyEvent"), argumentList); + } + + inline QDBusPendingReply<> setPreedit(const QString &in0, int in1) + { + QList argumentList; + argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1); + return asyncCallWithArgumentList(QLatin1String("setPreedit"), argumentList); + } + + inline QDBusPendingReply<> showInputMethod() + { + QList argumentList; + return asyncCallWithArgumentList(QLatin1String("showInputMethod"), argumentList); + } + + inline QDBusPendingReply<> updateWidgetInformation(const QMap &stateInformation, bool focusChanged) + { + QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(), interface(), "updateWidgetInformation"); + + QDBusArgument map; + map.beginMap(QVariant::String, qMetaTypeId()); + for (QMap::ConstIterator it = stateInformation.constBegin(), end = stateInformation.constEnd(); + it != end; ++it) { + map.beginMapEntry(); + map << it.key(); + map << QDBusVariant(it.value()); + map.endMapEntry(); + } + map.endMap(); + + QList args; + args << QVariant::fromValue(map) << QVariant(focusChanged); + msg.setArguments(args); + return connection().asyncCall(msg); + } + + inline QDBusPendingReply<> reset() + { + return asyncCall(QLatin1String("reset")); + } + + inline QDBusPendingReply<> setCopyPasteState(bool in0, bool in1) + { + QList argumentList; + argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1); + return asyncCallWithArgumentList(QLatin1String("setCopyPasteState"), argumentList); + } + +Q_SIGNALS: // SIGNALS +}; + +namespace com { + namespace meego { + namespace inputmethod { + typedef ::ComMeegoInputmethodUiserver1Interface uiserver1; + } + } +} +#endif diff --git a/src/plugins/platforminputcontexts/platforminputcontexts.pro b/src/plugins/platforminputcontexts/platforminputcontexts.pro index dd90d32772..bd27aaf721 100644 --- a/src/plugins/platforminputcontexts/platforminputcontexts.pro +++ b/src/plugins/platforminputcontexts/platforminputcontexts.pro @@ -2,3 +2,4 @@ TEMPLATE = subdirs contains(QT_CONFIG, dbus) { !macx:!win32:SUBDIRS += ibus } +linux-g++-maemo: SUBDIRS += meego -- cgit v1.2.3