desktop/qa/desktop_lib/test_desktop_lib.cxx    |    3 +
 desktop/source/lib/init.cxx                    |   19 +++++++++++
 include/LibreOfficeKit/LibreOfficeKit.h        |    5 ++
 include/LibreOfficeKit/LibreOfficeKit.hxx      |   11 ++++++
 include/LibreOfficeKit/LibreOfficeKitEnums.h   |   11 ++++++
 include/vcl/ITiledRenderable.hxx               |    7 ++++
 include/vcl/vclevent.hxx                       |    2 +
 include/vcl/window.hxx                         |    1 
 sc/inc/docuno.hxx                              |    3 +
 sc/qa/unit/tiledrendering/tiledrendering.cxx   |   35 ++++++++++++++++++++
 sc/source/ui/unoobj/docuno.cxx                 |   25 ++++++++++++++
 sd/qa/unit/tiledrendering/tiledrendering.cxx   |   42 +++++++++++++++++++++++++
 sd/source/ui/inc/unomodel.hxx                  |    2 +
 sd/source/ui/unoidl/unomodel.cxx               |   27 ++++++++++++++++
 sw/inc/unotxdoc.hxx                            |    2 +
 sw/qa/extras/tiledrendering/tiledrendering.cxx |   33 +++++++++++++++++++
 sw/source/uibase/uno/unotxdoc.cxx              |   22 +++++++++++++
 vcl/source/window/window.cxx                   |   20 +++++++++++
 18 files changed, 268 insertions(+), 2 deletions(-)

New commits:
commit 5f84c096edff526d8c5f0c603c1f5344d4d45525
Author: Pranav Kant <pran...@collabora.co.uk>
Date:   Wed Feb 7 21:23:42 2018 +0530

    sd, sc lok: IME support + unit tests
    
    Change-Id: I710ba4347977641102b89fd274a159d34bc29e72
    Reviewed-on: https://gerrit.libreoffice.org/49385
    Tested-by: Jenkins <c...@libreoffice.org>
    Reviewed-by: pranavk <pran...@collabora.co.uk>
    (cherry picked from commit b746577d27437f9298fa111512d083eaccd4fbed)
    Reviewed-on: https://gerrit.libreoffice.org/49624
    Tested-by: pranavk <pran...@collabora.co.uk>

diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx
index d9d887a3c23b..96d021935745 100644
--- a/include/vcl/ITiledRenderable.hxx
+++ b/include/vcl/ITiledRenderable.hxx
@@ -114,7 +114,7 @@ public:
      *
      * @see lok::Document::postExtTextInputEvent().
      */
-    virtual void postExtTextInputEvent(int /*nType*/, const OUString& 
/*rText*/) {}
+    virtual void postExtTextInputEvent(int nType, const OUString& rText) = 0;
 
     /**
      * Posts a mouse event on the document.
diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx
index e37f11a9ba49..4c4e74583023 100644
--- a/sc/inc/docuno.hxx
+++ b/sc/inc/docuno.hxx
@@ -385,6 +385,9 @@ public:
     /// @see vcl::ITiledRenderable::postKeyEvent().
     virtual void postKeyEvent(int nType, int nCharCode, int nKeyCode) override;
 
+    /// @see vcl::ITiledRenderable::postExtTextInputEvent().
+    virtual void postExtTextInputEvent(int nType, const OUString& rText) 
override;
+
     /// @see vcl::ITiledRenderable::postMouseEvent().
     virtual void postMouseEvent(int nType, int nX, int nY, int nCount, int 
nButtons, int nModifier) override;
 
diff --git a/sc/qa/unit/tiledrendering/tiledrendering.cxx 
b/sc/qa/unit/tiledrendering/tiledrendering.cxx
index f8357435f0e3..801f7ad55288 100644
--- a/sc/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sc/qa/unit/tiledrendering/tiledrendering.cxx
@@ -81,6 +81,7 @@ public:
     void testDocumentRepair();
     void testLanguageStatus();
     void testMultiViewCopyPaste();
+    void testIMESupport();
 
     CPPUNIT_TEST_SUITE(ScTiledRenderingTest);
     CPPUNIT_TEST(testRowColumnSelections);
@@ -111,6 +112,7 @@ public:
     CPPUNIT_TEST(testDocumentRepair);
     CPPUNIT_TEST(testLanguageStatus);
     CPPUNIT_TEST(testMultiViewCopyPaste);
+    CPPUNIT_TEST(testIMESupport);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -1559,6 +1561,39 @@ void ScTiledRenderingTest::testMultiViewCopyPaste()
     comphelper::LibreOfficeKit::setActive(false);
 }
 
+void ScTiledRenderingTest::testIMESupport()
+{
+    comphelper::LibreOfficeKit::setActive();
+
+    ScModelObj* pModelObj = createDoc("empty.ods");
+    ScDocument* pDoc = pModelObj->GetDocument();
+
+    ScTabViewShell* pView = 
dynamic_cast<ScTabViewShell*>(SfxViewShell::Current());
+    CPPUNIT_ASSERT(pView);
+
+    pView->SetCursor(0, 0);
+    // sequence of chineese IME compositions when 'nihao' is typed in an IME
+    const std::vector<OString> aUtf8Inputs{ "年", "你", "你好", "你哈", "你好", "你好" };
+    std::vector<OUString> aInputs;
+    std::transform(aUtf8Inputs.begin(), aUtf8Inputs.end(),
+                   std::back_inserter(aInputs), [](OString aInput) {
+                       return OUString::fromUtf8(aInput);
+                   });
+    for (const auto& aInput: aInputs)
+    {
+        pModelObj->postExtTextInputEvent(LOK_EXT_TEXTINPUT, aInput);
+    }
+    pModelObj->postExtTextInputEvent(LOK_EXT_TEXTINPUT_END, "");
+
+    // commit the string to the cell
+    pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::RETURN);
+    pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::RETURN);
+
+    CPPUNIT_ASSERT_EQUAL(aInputs[aInputs.size() - 1], 
pDoc->GetString(ScAddress(0, 0, 0)));
+
+    comphelper::LibreOfficeKit::setActive(false);
+}
+
 }
 
 CPPUNIT_TEST_SUITE_REGISTRATION(ScTiledRenderingTest);
diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx
index dbd63f6ad14b..fafd3b466102 100644
--- a/sc/source/ui/unoobj/docuno.cxx
+++ b/sc/source/ui/unoobj/docuno.cxx
@@ -42,6 +42,7 @@
 #include <sfx2/printer.hxx>
 #include <sfx2/bindings.hxx>
 #include <sfx2/dispatch.hxx>
+#include <vcl/commandevent.hxx>
 #include <vcl/pdfextoutdevdata.hxx>
 #include <vcl/waitobj.hxx>
 #include <unotools/charclass.hxx>
@@ -615,6 +616,30 @@ void ScModelObj::postKeyEvent(int nType, int nCharCode, 
int nKeyCode)
     }
 }
 
+void ScModelObj::postExtTextInputEvent(int nType, const OUString& rText)
+{
+    SolarMutexGuard aGuard;
+
+    ScViewData* pViewData = ScDocShell::GetViewData();
+    vcl::Window* pWindow = pViewData->GetActiveWin();
+
+    if (!pWindow)
+        return;
+
+    CommandExtTextInputData aTextInputData(rText, nullptr, 0, 0, false);
+    switch (nType)
+    {
+    case LOK_EXT_TEXTINPUT:
+        pWindow->PostExtTextInputEvent(VclEventId::ExtTextInput, rText);
+        break;
+    case LOK_EXT_TEXTINPUT_END:
+        pWindow->PostExtTextInputEvent(VclEventId::EndExtTextInput, "");
+        break;
+    default:
+        assert(false && "Unhandled External Text input event!");
+    }
+}
+
 void ScModelObj::postMouseEvent(int nType, int nX, int nY, int nCount, int 
nButtons, int nModifier)
 {
     SolarMutexGuard aGuard;
diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx 
b/sd/qa/unit/tiledrendering/tiledrendering.cxx
index 8d624dc70c48..4cdec1234c8e 100644
--- a/sd/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx
@@ -101,6 +101,7 @@ public:
     void testDocumentRepair();
     void testLanguageStatus();
     void testDefaultView();
+    void testIMESupport();
 
     CPPUNIT_TEST_SUITE(SdTiledRenderingTest);
     CPPUNIT_TEST(testRegisterCallback);
@@ -141,6 +142,7 @@ public:
     CPPUNIT_TEST(testDocumentRepair);
     CPPUNIT_TEST(testLanguageStatus);
     CPPUNIT_TEST(testDefaultView);
+    CPPUNIT_TEST(testIMESupport);
 
     CPPUNIT_TEST_SUITE_END();
 
@@ -1918,6 +1920,46 @@ void SdTiledRenderingTest::testDefaultView()
     comphelper::LibreOfficeKit::setActive(false);
 }
 
+void SdTiledRenderingTest::testIMESupport()
+{
+    // Load the document with notes view.
+    comphelper::LibreOfficeKit::setActive();
+
+    SdXImpressDocument* pXImpressDocument = createDoc("dummy.odp");
+    sd::ViewShell* pViewShell = 
pXImpressDocument->GetDocShell()->GetViewShell();
+    SdrObject* pObject = pViewShell->GetActualPage()->GetObj(0);
+    SdrTextObj* pTextObj = static_cast<SdrTextObj*>(pObject);
+    SdrView* pView = pViewShell->GetView();
+    pView->MarkObj(pTextObj, pView->GetSdrPageView());
+    SfxStringItem aInputString(SID_ATTR_CHAR, "x");
+    pViewShell->GetViewFrame()->GetDispatcher()->ExecuteList(SID_ATTR_CHAR,
+                                                             
SfxCallMode::SYNCHRON, { &aInputString });
+
+    // sequence of chineese IME compositions when 'nihao' is typed in an IME
+    const std::vector<OString> aUtf8Inputs{ "年", "你", "你好", "你哈", "你好", "你好" };
+    std::vector<OUString> aInputs;
+    std::transform(aUtf8Inputs.begin(), aUtf8Inputs.end(),
+                   std::back_inserter(aInputs), [](OString aInput) {
+                       return OUString::fromUtf8(aInput);
+                   });
+    for (const auto& aInput: aInputs)
+    {
+        pXImpressDocument->postExtTextInputEvent(LOK_EXT_TEXTINPUT, aInput);
+    }
+    pXImpressDocument->postExtTextInputEvent(LOK_EXT_TEXTINPUT_END, "");
+
+    // the cursor should be at position 3rd
+    EditView& rEditView = pView->GetTextEditOutlinerView()->GetEditView();
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), 
rEditView.GetSelection().nStartPos);
+
+    ESelection aWordSelection(0, 0, 0, 3); // start para, start char, end 
para, end char.
+    rEditView.SetSelection(aWordSelection);
+    // content contains only the last IME composition, not all
+    CPPUNIT_ASSERT_EQUAL(OUString("x").concat(aInputs[aInputs.size() - 1]), 
rEditView.GetSelected());
+
+    comphelper::LibreOfficeKit::setActive(false);
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SdTiledRenderingTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sd/source/ui/inc/unomodel.hxx b/sd/source/ui/inc/unomodel.hxx
index 087fa521ca9e..1e4bbcbab7a8 100644
--- a/sd/source/ui/inc/unomodel.hxx
+++ b/sd/source/ui/inc/unomodel.hxx
@@ -249,6 +249,8 @@ public:
     virtual void initializeForTiledRendering(const 
css::uno::Sequence<css::beans::PropertyValue>& rArguments) override;
     /// @see vcl::ITiledRenderable::postKeyEvent().
     virtual void postKeyEvent(int nType, int nCharCode, int nKeyCode) override;
+    /// @see vcl::ITiledRenderable::postExtTextInputEvent().
+    virtual void postExtTextInputEvent(int nType, const OUString& rText) 
override;
     /// @see vcl::ITiledRenderable::postMouseEvent().
     virtual void postMouseEvent(int nType, int nX, int nY, int nCount, int 
nButtons, int nModifier) override;
     /// @see vcl::ITiledRenderable::setTextSelection().
diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx
index 3da40797d75e..296dddba6439 100644
--- a/sd/source/ui/unoidl/unomodel.cxx
+++ b/sd/source/ui/unoidl/unomodel.cxx
@@ -43,6 +43,7 @@
 #include <unopool.hxx>
 #include <sfx2/dispatch.hxx>
 #include <sfx2/bindings.hxx>
+#include <vcl/commandevent.hxx>
 #include <vcl/svapp.hxx>
 #include <vcl/settings.hxx>
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
@@ -2516,6 +2517,32 @@ void SdXImpressDocument::postKeyEvent(int nType, int 
nCharCode, int nKeyCode)
     }
 }
 
+void SdXImpressDocument::postExtTextInputEvent(int nType, const OUString& 
rText)
+{
+    SolarMutexGuard aGuard;
+
+    DrawViewShell* pViewShell = GetViewShell();
+    if (!pViewShell)
+        return;
+
+    vcl::Window* pWindow = pViewShell->GetActiveWindow();
+    if (!pWindow)
+        return;
+
+    CommandExtTextInputData aTextInputData(rText, nullptr, 0, 0, false);
+    switch (nType)
+    {
+    case LOK_EXT_TEXTINPUT:
+        pWindow->PostExtTextInputEvent(VclEventId::ExtTextInput, rText);
+        break;
+    case LOK_EXT_TEXTINPUT_END:
+        pWindow->PostExtTextInputEvent(VclEventId::EndExtTextInput, "");
+        break;
+    default:
+        assert(false && "Unhandled External Text input event!");
+    }
+}
+
 void SdXImpressDocument::postMouseEvent(int nType, int nX, int nY, int nCount, 
int nButtons, int nModifier)
 {
     SolarMutexGuard aGuard;
commit 758eafa1e2dd342ed47552c2b1cf13cc6d88b7ba
Author: Pranav Kant <pran...@collabora.co.uk>
Date:   Wed Feb 7 17:19:58 2018 +0530

    sw lok: IME support + unit test
    
    Change-Id: I557493db23dfa3529606050c86161628dbd722e7
    Reviewed-on: https://gerrit.libreoffice.org/49354
    Reviewed-by: pranavk <pran...@collabora.co.uk>
    Tested-by: pranavk <pran...@collabora.co.uk>
    (cherry picked from commit 7f9f58f3a304733f7089719a5a65eef8c68c2b8d)
    Reviewed-on: https://gerrit.libreoffice.org/49623

diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx 
b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index 163db824c32d..7524c34637d5 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -2211,10 +2211,11 @@ void DesktopLOKTest::testABI()
     CPPUNIT_ASSERT_EQUAL(documentClassOffset(37), offsetof(struct 
_LibreOfficeKitDocumentClass, postWindowKeyEvent));
     CPPUNIT_ASSERT_EQUAL(documentClassOffset(38), offsetof(struct 
_LibreOfficeKitDocumentClass, postWindowMouseEvent));
     CPPUNIT_ASSERT_EQUAL(documentClassOffset(39), offsetof(struct 
_LibreOfficeKitDocumentClass, setViewLanguage));
+    CPPUNIT_ASSERT_EQUAL(documentClassOffset(40), offsetof(struct 
_LibreOfficeKitDocumentClass, postExtTextInputEvent));
 
     // Extending is fine, update this, and add new assert for the offsetof the
     // new method
-    CPPUNIT_ASSERT_EQUAL(documentClassOffset(40), sizeof(struct 
_LibreOfficeKitDocumentClass));
+    CPPUNIT_ASSERT_EQUAL(documentClassOffset(41), sizeof(struct 
_LibreOfficeKitDocumentClass));
 }
 
 CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest);
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 0c20f6936a28..2598da695e0a 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -568,6 +568,9 @@ static void doc_postKeyEvent(LibreOfficeKitDocument* pThis,
                              int nType,
                              int nCharCode,
                              int nKeyCode);
+static void doc_postExtTextInputEvent(LibreOfficeKitDocument* pThis,
+                                      int nType,
+                                      const char* pText);
 static void doc_postWindowKeyEvent(LibreOfficeKitDocument* pThis,
                                    unsigned nLOKWindowId,
                                    int nType,
@@ -661,6 +664,7 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference 
<css::lang::XCompone
         m_pDocumentClass->initializeForRendering = doc_initializeForRendering;
         m_pDocumentClass->registerCallback = doc_registerCallback;
         m_pDocumentClass->postKeyEvent = doc_postKeyEvent;
+        m_pDocumentClass->postExtTextInputEvent = doc_postExtTextInputEvent;
         m_pDocumentClass->postWindowKeyEvent = doc_postWindowKeyEvent;
         m_pDocumentClass->postMouseEvent = doc_postMouseEvent;
         m_pDocumentClass->postWindowMouseEvent = doc_postWindowMouseEvent;
@@ -2277,9 +2281,24 @@ static void doc_postKeyEvent(LibreOfficeKitDocument* 
pThis, int nType, int nChar
         gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
         return;
     }
+
     pDoc->postKeyEvent(nType, nCharCode, nKeyCode);
 }
 
+static void doc_postExtTextInputEvent(LibreOfficeKitDocument* pThis, int 
nType, const char* pText)
+{
+    SolarMutexGuard aGuard;
+
+    ITiledRenderable* pDoc = getTiledRenderable(pThis);
+    if (!pDoc)
+    {
+        gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
+        return;
+    }
+
+    pDoc->postExtTextInputEvent(nType, OUString::fromUtf8(OString(pText, 
strlen(pText))));
+}
+
 static void doc_postWindowKeyEvent(LibreOfficeKitDocument* /*pThis*/, unsigned 
nLOKWindowId, int nType, int nCharCode, int nKeyCode)
 {
     SolarMutexGuard aGuard;
diff --git a/include/LibreOfficeKit/LibreOfficeKit.h 
b/include/LibreOfficeKit/LibreOfficeKit.h
index 8ac97371c6c4..bb99e04abe17 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -289,6 +289,11 @@ struct _LibreOfficeKitDocumentClass
     /// @see lok::Document::setViewLanguage().
     void (*setViewLanguage) (LibreOfficeKitDocument* pThis, int nId, const 
char* language);
 
+    /// @see lok::Document::postExtTextInputEvent
+    void (*postExtTextInputEvent) (LibreOfficeKitDocument* pThis,
+                                   int nType,
+                                   const char* pText);
+
 #endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
 };
 
diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx 
b/include/LibreOfficeKit/LibreOfficeKit.hxx
index d7fa22b70ede..c076c0f0b58f 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.hxx
+++ b/include/LibreOfficeKit/LibreOfficeKit.hxx
@@ -536,6 +536,17 @@ public:
         mpDoc->pClass->setViewLanguage(mpDoc, nId, language);
     }
 
+    /**
+     * Post the text input from external input window, like IME
+     *
+     * @param nType see LibreOfficeKitExtTextInputType
+     * @param pText Text for LOK_EXT_TEXTINPUT
+     */
+    void postExtTextInputEvent(int nType, const char* pText)
+    {
+        mpDoc->pClass->postExtTextInputEvent(mpDoc, nType, pText);
+    }
+
 #endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
 };
 
diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h 
b/include/LibreOfficeKit/LibreOfficeKitEnums.h
index 46be3f25fea8..ccbc3b96b065 100644
--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -582,6 +582,17 @@ LibreOfficeKitKeyEventType;
 
 typedef enum
 {
+    /// cf. SalEvent::ExtTextInput
+    LOK_EXT_TEXTINPUT,
+    /// cf. SalEvent::ExtTextInputPos
+    LOK_EXT_TEXTINPUT_POS,
+    /// cf. SalEvent::EndExtTextInput
+    LOK_EXT_TEXTINPUT_END
+}
+LibreOfficeKitExtTextInputType;
+
+typedef enum
+{
     /// A pressed gesture has started.
     LOK_MOUSEEVENT_MOUSEBUTTONDOWN,
     /// A pressed gesture has finished.
diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx
index b04b10eb404b..d9d887a3c23b 100644
--- a/include/vcl/ITiledRenderable.hxx
+++ b/include/vcl/ITiledRenderable.hxx
@@ -110,6 +110,13 @@ public:
     virtual void postKeyEvent(int nType, int nCharCode, int nKeyCode) = 0;
 
     /**
+     * Posts an external text input event
+     *
+     * @see lok::Document::postExtTextInputEvent().
+     */
+    virtual void postExtTextInputEvent(int /*nType*/, const OUString& 
/*rText*/) {}
+
+    /**
      * Posts a mouse event on the document.
      *
      * @see lok::Document::postMouseEvent().
diff --git a/include/vcl/vclevent.hxx b/include/vcl/vclevent.hxx
index a1c9a9724bdb..c5a972c2ddfd 100644
--- a/include/vcl/vclevent.hxx
+++ b/include/vcl/vclevent.hxx
@@ -65,6 +65,8 @@ namespace com { namespace sun { namespace star {
 #define VCLEVENT_WINDOW_DATACHANGED         1022    // pData = 
DataChangedEvent*
 #define VCLEVENT_WINDOW_ZOOM                1023    // pData = ZoomEvent*
 #define VCLEVENT_WINDOW_SCROLL              1024    // pData = ScrollEvent*
+#define VCLEVENT_WINDOW_EXTTEXTINPUT        1025
+#define VCLEVENT_WINDOW_ENDEXTTEXTINPUT     1026
 
 // VclWindowEvent
 #define VCLEVENT_CONTROL_GETFOCUS           1100
diff --git a/include/vcl/window.hxx b/include/vcl/window.hxx
index 7f15b5dac267..243335885087 100644
--- a/include/vcl/window.hxx
+++ b/include/vcl/window.hxx
@@ -886,6 +886,7 @@ public:
 
     void                                SetInputContext( const InputContext& 
rInputContext );
     const InputContext&                 GetInputContext() const;
+    void                                PostExtTextInputEvent(VclEventId 
nType, const OUString& rText);
     void                                EndExtTextInput();
     void                                SetCursorRect( const Rectangle* pRect 
= nullptr, long nExtTextInputWidth = 0 );
     const Rectangle*                    GetCursorRect() const;
diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx
index 1de906c338b5..a0cbcb0d63de 100644
--- a/sw/inc/unotxdoc.hxx
+++ b/sw/inc/unotxdoc.hxx
@@ -419,6 +419,8 @@ public:
     virtual void initializeForTiledRendering(const 
css::uno::Sequence<css::beans::PropertyValue>& rArguments) override;
     /// @see vcl::ITiledRenderable::postKeyEvent().
     virtual void postKeyEvent(int nType, int nCharCode, int nKeyCode) override;
+    /// @see vcl::ITiledRenderable::postExtTextInputEvent().
+    virtual void postExtTextInputEvent(int nType, const OUString& rText) 
override;
     /// @see vcl::ITiledRenderable::postMouseEvent().
     virtual void postMouseEvent(int nType, int nX, int nY, int nCount, int 
nButtons, int nModifier) override;
     /// @see vcl::ITiledRenderable::setTextSelection().
diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx 
b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index 089537b6dc0c..05c352926d73 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -95,6 +95,7 @@ public:
     void testPageHeader();
     void testPageFooter();
     void testRedlineField();
+    void testIMESupport();
 
     CPPUNIT_TEST_SUITE(SwTiledRenderingTest);
     CPPUNIT_TEST(testRegisterCallback);
@@ -145,6 +146,7 @@ public:
     CPPUNIT_TEST(testPageHeader);
     CPPUNIT_TEST(testPageFooter);
     CPPUNIT_TEST(testRedlineField);
+    CPPUNIT_TEST(testIMESupport);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -2036,6 +2038,37 @@ void SwTiledRenderingTest::testRedlineField()
     comphelper::LibreOfficeKit::setActive(false);
 }
 
+void SwTiledRenderingTest::testIMESupport()
+{
+    comphelper::LibreOfficeKit::setActive();
+    SwXTextDocument* pXTextDocument = createDoc("dummy.fodt");
+
+    SwView* pView = dynamic_cast<SwView*>(SfxViewShell::Current());
+    SwWrtShell* pWrtShell = pView->GetWrtShellPtr();
+
+    // sequence of chineese IME compositions when 'nihao' is typed in an IME
+    const std::vector<OString> aUtf8Inputs{ "年", "你", "你好", "你哈", "你好", "你好" };
+    std::vector<OUString> aInputs;
+    std::transform(aUtf8Inputs.begin(), aUtf8Inputs.end(),
+                   std::back_inserter(aInputs), [](OString aInput) {
+                       return OUString::fromUtf8(aInput);
+                   });
+    for (const auto& aInput: aInputs)
+    {
+        pXTextDocument->postExtTextInputEvent(LOK_EXT_TEXTINPUT, aInput);
+    }
+    pXTextDocument->postExtTextInputEvent(LOK_EXT_TEXTINPUT_END, "");
+
+    // the cursor should be at position 2nd
+    SwShellCursor* pShellCursor = pWrtShell->getShellCursor(false);
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), 
pShellCursor->GetPoint()->nContent.GetIndex());
+
+    // content contains only the last IME composition, not all
+    CPPUNIT_ASSERT_EQUAL(aInputs[aInputs.size() - 1].concat("Aaa bbb."), 
pShellCursor->GetPoint()->nNode.GetNode().GetTextNode()->GetText());
+
+    comphelper::LibreOfficeKit::setActive(false);
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SwTiledRenderingTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/uibase/uno/unotxdoc.cxx 
b/sw/source/uibase/uno/unotxdoc.cxx
index ea9b58c024b9..85a3ef5cab95 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -25,7 +25,9 @@
 #include <AnnotationWin.hxx>
 #include <o3tl/any.hxx>
 #include <osl/mutex.hxx>
+#include <vcl/commandevent.hxx>
 #include <vcl/image.hxx>
+#include <vcl/vclevent.hxx>
 #include <vcl/virdev.hxx>
 #include <vcl/sysdata.hxx>
 #include <vcl/svapp.hxx>
@@ -3499,6 +3501,26 @@ void SwXTextDocument::postKeyEvent(int nType, int 
nCharCode, int nKeyCode)
     }
 }
 
+void SwXTextDocument::postExtTextInputEvent(int nType, const OUString& rText)
+{
+    SolarMutexGuard aGuard;
+
+    vcl::Window* pWindow = &(pDocShell->GetView()->GetEditWin());
+
+    CommandExtTextInputData aTextInputData(rText, nullptr, 0, 0, false);
+    switch (nType)
+    {
+    case LOK_EXT_TEXTINPUT:
+        pWindow->PostExtTextInputEvent(VclEventId::ExtTextInput, rText);
+        break;
+    case LOK_EXT_TEXTINPUT_END:
+        pWindow->PostExtTextInputEvent(VclEventId::EndExtTextInput, "");
+        break;
+    default:
+        assert(false && "Unhandled External Text input event!");
+    }
+}
+
 void SwXTextDocument::postMouseEvent(int nType, int nX, int nY, int nCount, 
int nButtons, int nModifier)
 {
     SolarMutexGuard aGuard;
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 4b3384f02756..4e68e6ab00d9 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -27,6 +27,7 @@
 #include <vcl/help.hxx>
 #include <vcl/cursor.hxx>
 #include <vcl/svapp.hxx>
+#include <vcl/vclevent.hxx>
 #include <vcl/window.hxx>
 #include <vcl/syswin.hxx>
 #include <vcl/syschild.hxx>
@@ -2102,9 +2103,26 @@ void Window::SetInputContext( const InputContext& 
rInputContext )
         ImplNewInputContext();
 }
 
-void Window::EndExtTextInput()
+void Window::PostExtTextInputEvent(VclEventId nType, const OUString& rText)
 {
+    switch (nType)
+    {
+    case VclEventId::ExtTextInput:
+    {
+        SalExtTextInputEvent aEvent { rText, nullptr, rText.getLength(), 0 };
+        ImplWindowFrameProc(this, SalEvent::ExtTextInput, &aEvent);
+    }
+    break;
+    case VclEventId::EndExtTextInput:
+        ImplWindowFrameProc(this, SalEvent::EndExtTextInput, nullptr);
+        break;
+    default:
+        assert(false);
+    }
+}
 
+void Window::EndExtTextInput()
+{
     if ( mpWindowImpl->mbExtTextInput )
         ImplGetFrame()->EndExtTextInput( EndExtTextInputFlags::Complete );
 }
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to