sw lok: IME support + unit test
Change-Id: I557493db23dfa3529606050c86161628dbd722e7 Reviewed-on: https://gerrit.libreoffice.org/49354 Reviewed-by: pranavk <pranavk@collabora.co.uk> Tested-by: pranavk <pranavk@collabora.co.uk>
This commit is contained in:
@@ -2291,10 +2291,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);
|
||||
|
@@ -540,6 +540,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,
|
||||
@@ -633,6 +636,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;
|
||||
@@ -2288,9 +2292,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;
|
||||
|
@@ -300,6 +300,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
|
||||
};
|
||||
|
||||
|
@@ -537,6 +537,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
|
||||
};
|
||||
|
||||
|
@@ -580,6 +580,17 @@ typedef enum
|
||||
}
|
||||
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.
|
||||
|
@@ -102,6 +102,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.
|
||||
*
|
||||
|
@@ -59,6 +59,8 @@ enum class VclEventId
|
||||
EditCaretChanged,
|
||||
EditModify,
|
||||
EditSelectionChanged,
|
||||
ExtTextInput,
|
||||
EndExtTextInput,
|
||||
ItemCollapsed,
|
||||
ItemExpanded,
|
||||
ListboxDoubleClick,
|
||||
|
@@ -892,6 +892,7 @@ public:
|
||||
|
||||
void SetInputContext( const InputContext& rInputContext );
|
||||
const InputContext& GetInputContext() const;
|
||||
void PostExtTextInputEvent(VclEventId nType, const OUString& rText);
|
||||
void EndExtTextInput();
|
||||
void SetCursorRect( const tools::Rectangle* pRect = nullptr, long nExtTextInputWidth = 0 );
|
||||
const tools::Rectangle* GetCursorRect() const;
|
||||
|
@@ -403,6 +403,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().
|
||||
|
@@ -102,6 +102,7 @@ public:
|
||||
void testPageFooter();
|
||||
void testTdf115088();
|
||||
void testRedlineField();
|
||||
void testIMESupport();
|
||||
|
||||
CPPUNIT_TEST_SUITE(SwTiledRenderingTest);
|
||||
CPPUNIT_TEST(testRegisterCallback);
|
||||
@@ -153,6 +154,7 @@ public:
|
||||
CPPUNIT_TEST(testPageFooter);
|
||||
CPPUNIT_TEST(testTdf115088);
|
||||
CPPUNIT_TEST(testRedlineField);
|
||||
CPPUNIT_TEST(testIMESupport);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
private:
|
||||
@@ -2088,6 +2090,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();
|
||||
|
@@ -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>
|
||||
@@ -3493,6 +3495,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;
|
||||
|
@@ -26,6 +26,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>
|
||||
@@ -2069,9 +2070,26 @@ void Window::SetInputContext( const InputContext& rInputContext )
|
||||
ImplNewInputContext();
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
|
Reference in New Issue
Block a user