tdf#121161 Qt5 initial IM support

This just implements some minimal solution, since I have no idea,
how all this IM handling should actually work.

Change-Id: I0d02dfb96680891e275881927ebc17f798dc1f29
Reviewed-on: https://gerrit.libreoffice.org/65553
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
(cherry picked from commit c7ee454a35c392dfd03c9ccf8fd953ec9c98e484)
Reviewed-on: https://gerrit.libreoffice.org/65558
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
diff --git a/vcl/inc/qt5/Qt5Widget.hxx b/vcl/inc/qt5/Qt5Widget.hxx
index ad04365..26f26c8 100644
--- a/vcl/inc/qt5/Qt5Widget.hxx
+++ b/vcl/inc/qt5/Qt5Widget.hxx
@@ -22,9 +22,13 @@
#include <QtWidgets/QWidget>
#include <rtl/ustring.hxx>

#include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/accessibility/XAccessibleEditableText.hpp>

class Qt5Frame;
class Qt5Object;
class QFocusEvent;
class QInputMethodEvent;
class QKeyEvent;
class QMouseEvent;
class QMoveEvent;
@@ -32,6 +36,7 @@
class QResizeEvent;
class QShowEvent;
class QWheelEvent;
class QVariant;

class Qt5Widget : public QWidget
{
@@ -57,6 +62,9 @@
    virtual void wheelEvent(QWheelEvent*) override;
    virtual void closeEvent(QCloseEvent*) override;

    void inputMethodEvent(QInputMethodEvent*) override;
    QVariant inputMethodQuery(Qt::InputMethodQuery) const override;

    const QString m_InternalMimeType = "application/x-libreoffice-dnditem";

public slots:
diff --git a/vcl/qt5/Qt5Frame.cxx b/vcl/qt5/Qt5Frame.cxx
index 781f1c6..230c983 100644
--- a/vcl/qt5/Qt5Frame.cxx
+++ b/vcl/qt5/Qt5Frame.cxx
@@ -655,9 +655,15 @@

// do we even need it? void Qt5Frame::Flush(const tools::Rectangle& /*rRect*/) {}

void Qt5Frame::SetInputContext(SalInputContext* /*pContext*/)
void Qt5Frame::SetInputContext(SalInputContext* pContext)
{
    // TODO some IM handler setup
    if (!pContext)
        return;

    if (!(pContext->mnOptions & InputContextFlags::Text))
        return;

    m_pQWidget->setAttribute(Qt::WA_InputMethodEnabled);
}

void Qt5Frame::EndExtTextInput(EndExtTextInputFlags /*nFlags*/)
diff --git a/vcl/qt5/Qt5Widget.cxx b/vcl/qt5/Qt5Widget.cxx
index ba839a6..462f196 100644
--- a/vcl/qt5/Qt5Widget.cxx
+++ b/vcl/qt5/Qt5Widget.cxx
@@ -428,4 +428,46 @@
    setFocusPolicy(Qt::StrongFocus);
}

void Qt5Widget::inputMethodEvent(QInputMethodEvent* pEvent)
{
    SolarMutexGuard aGuard;
    SalExtTextInputEvent aInputEvent;
    aInputEvent.mpTextAttr = nullptr;
    aInputEvent.mnCursorFlags = 0;

    if (!pEvent->commitString().isEmpty())
    {
        vcl::DeletionListener aDel(m_pFrame);
        aInputEvent.maText = toOUString(pEvent->commitString());
        aInputEvent.mnCursorPos = aInputEvent.maText.getLength();
        m_pFrame->CallCallback(SalEvent::ExtTextInput, &aInputEvent);
        pEvent->accept();
        if (!aDel.isDeleted())
            m_pFrame->CallCallback(SalEvent::EndExtTextInput, nullptr);
    }
    else
    {
        aInputEvent.maText = toOUString(pEvent->preeditString());
        aInputEvent.mnCursorPos = 0;
        m_pFrame->CallCallback(SalEvent::ExtTextInput, &aInputEvent);
        pEvent->accept();
    }
}

QVariant Qt5Widget::inputMethodQuery(Qt::InputMethodQuery property) const
{
    switch (property)
    {
        case Qt::ImCursorRectangle:
        {
            SalExtTextInputPosEvent aPosEvent;
            m_pFrame->CallCallback(SalEvent::ExtTextInputPos, &aPosEvent);
            return QVariant(
                QRect(aPosEvent.mnX, aPosEvent.mnY, aPosEvent.mnWidth, aPosEvent.mnHeight));
        }
        default:
            return QWidget::inputMethodQuery(property);
    }
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */