desktop/CppunitTest_desktop_app.mk | 1 desktop/inc/lib/init.hxx | 5 + desktop/qa/desktop_lib/test_desktop_lib.cxx | 30 +++++++++ desktop/source/lib/init.cxx | 60 ++++++++++++++++++ include/LibreOfficeKit/LibreOfficeKit.hxx | 3 libreofficekit/qa/unit/tiledrendering.cxx | 89 ++++++++++++++++++++++++++++ vcl/source/app/svapp.cxx | 8 ++ 7 files changed, 195 insertions(+), 1 deletion(-)
New commits: commit 74acf925171dacdc4c0ad58a6d8edabb1e6c3144 Author: Jan Holesovsky <ke...@collabora.com> Date: Fri Mar 24 16:23:02 2017 +0100 lok: Unit test for setting of the language during load of the document. Change-Id: Idf4d3ba6b55be1f885f9d8fc89157e7e498d4e42 diff --git a/libreofficekit/qa/unit/tiledrendering.cxx b/libreofficekit/qa/unit/tiledrendering.cxx index f201f766ca7b..565eea040a93 100644 --- a/libreofficekit/qa/unit/tiledrendering.cxx +++ b/libreofficekit/qa/unit/tiledrendering.cxx @@ -73,6 +73,7 @@ public: void testImpressSlideNames( Office* pOffice ); void testCalcSheetNames( Office* pOffice ); void testPaintPartTile( Office* pOffice ); + void testDocumentLoadLanguage(Office* pOffice); #if 0 void testOverlay( Office* pOffice ); #endif @@ -100,6 +101,7 @@ void TiledRenderingTest::runAllTests() testImpressSlideNames( pOffice.get() ); testCalcSheetNames( pOffice.get() ); testPaintPartTile( pOffice.get() ); + testDocumentLoadLanguage(pOffice.get()); #if 0 testOverlay( pOffice.get() ); #endif @@ -218,6 +220,93 @@ void TiledRenderingTest::testPaintPartTile(Office* pOffice) pDocument->paintPartTile(aBuffer.data(), /*nPart=*/0, nCanvasWidth, nCanvasHeight, /*nTilePosX=*/0, /*nTilePosY=*/0, /*nTileWidth=*/3840, /*nTileHeight=*/3840); } +namespace { + +void processEventsToIdle() +{ + typedef void (ProcessEventsToIdleFn)(void); + static ProcessEventsToIdleFn *processFn = nullptr; + if (!processFn) + { + void *me = dlopen(nullptr, RTLD_NOW); + processFn = reinterpret_cast<ProcessEventsToIdleFn *>(dlsym(me, "unit_lok_process_events_to_idle")); + } + + CPPUNIT_ASSERT(processFn); + + (*processFn)(); +} + +void insertString(Document& rDocument, const std::string& s) +{ + for (const char c : s) + { + rDocument.postKeyEvent(LOK_KEYEVENT_KEYINPUT, c, 0); + rDocument.postKeyEvent(LOK_KEYEVENT_KEYUP, c, 0); + } + processEventsToIdle(); +} + +} + +void TiledRenderingTest::testDocumentLoadLanguage(Office* pOffice) +{ + const string sDocPath = m_sSrcRoot + "/libreofficekit/qa/data/empty.ods"; + const string sLockFile = m_sSrcRoot +"/libreofficekit/qa/data/.~lock.empty.ods#"; + + // FIXME: LOK will fail when trying to open a locked file + remove(sLockFile.c_str()); + + // first try with the en-US locale + std::unique_ptr<Document> pDocument(pOffice->documentLoad(sDocPath.c_str(), "Language=en-US")); + + // assert that '.' is the decimal separator + insertString(*pDocument, "1.5"); + + pDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, 1027); // right arrow + pDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, 1027); + processEventsToIdle(); + + insertString(*pDocument, "=2*A1"); + + pDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, 1280); // enter + pDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, 1280); + pDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, 1025); // up arrow + pDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, 1025); + processEventsToIdle(); + + // we've got a meaningful result + OString aResult = pDocument->getTextSelection("text/plain;charset=utf-8"); + CPPUNIT_ASSERT_EQUAL(OString("3\n"), aResult); + + pDocument.reset(nullptr); + + // FIXME: LOK will fail when trying to open a locked file + remove(sLockFile.c_str()); + + // load the file again, now in another language + pDocument.reset(pOffice->documentLoad(sDocPath.c_str(), "Language=cs-CZ")); + + // with cs-CZ, the decimal separator is ',' instead, assert that + insertString(*pDocument, "1,5"); + + pDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, 1027); // right arrow + pDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, 1027); + processEventsToIdle(); + + insertString(*pDocument, "=2*A1"); + + pDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, 1280); // enter + pDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, 1280); + pDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, 1025); // up arrow + pDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, 1025); + processEventsToIdle(); + + // we've got a meaningful result + aResult = pDocument->getTextSelection("text/plain;charset=utf-8"); + CPPUNIT_ASSERT_EQUAL(OString("3\n"), aResult); +} + #if 0 static void dumpRGBABitmap( const OUString& rPath, const unsigned char* pBuffer, const int nWidth, const int nHeight ) diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx index 2efd08f451e9..f94e9094ae44 100644 --- a/vcl/source/app/svapp.cxx +++ b/vcl/source/app/svapp.cxx @@ -547,6 +547,14 @@ void Scheduler::ProcessEventsToIdle() } } +extern "C" { +/// used by unit tests that test only via the LOK API +SAL_DLLPUBLIC_EXPORT void unit_lok_process_events_to_idle() +{ + Scheduler::ProcessEventsToIdle(); +} +} + void Application::Yield() { ImplYield(true, false, 0); commit c68a71026341b586e594048b42d18e2a94ad52d2 Author: Jan Holesovsky <ke...@collabora.com> Date: Thu Mar 23 21:27:18 2017 +0100 lok: Allow setting of the language during load. Change-Id: I9dbb62950e639376c26122ceb9fcec2982b3ca82 diff --git a/desktop/CppunitTest_desktop_app.mk b/desktop/CppunitTest_desktop_app.mk index b809b6a7e8c6..1e7e3e0813c5 100644 --- a/desktop/CppunitTest_desktop_app.mk +++ b/desktop/CppunitTest_desktop_app.mk @@ -34,6 +34,7 @@ $(eval $(call gb_CppunitTest_use_libraries,desktop_app, \ salhelper \ sb \ sfx \ + sofficeapp \ svl \ svx \ svxcore \ diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx index bfe9954c3308..2dd4b51c8942 100644 --- a/desktop/inc/lib/init.hxx +++ b/desktop/inc/lib/init.hxx @@ -98,6 +98,11 @@ namespace desktop { return (mOptionalFeatures & feature) != 0; } }; + + /// Helper function to extract the value from parameters delimited by + /// comma, like: Name1=Value1,Name2=Value2,Name3=Value3. + /// @param rOptions When exctacted, the Param=Value is removed from it. + DESKTOP_DLLPUBLIC OUString extractParameter(OUString& aOptions, const OUString& rName); } #endif diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx index 0f2d41c7f03f..20958267a291 100644 --- a/desktop/qa/desktop_lib/test_desktop_lib.cxx +++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx @@ -113,6 +113,7 @@ public: void testCommentsImpress(); void testCommentsCallbacksWriter(); void testRunMacro(); + void testExtractParameter(); CPPUNIT_TEST_SUITE(DesktopLOKTest); CPPUNIT_TEST(testGetStyles); @@ -153,6 +154,7 @@ public: CPPUNIT_TEST(testCommentsImpress); CPPUNIT_TEST(testCommentsCallbacksWriter); CPPUNIT_TEST(testRunMacro); + CPPUNIT_TEST(testExtractParameter); CPPUNIT_TEST_SUITE_END(); uno::Reference<lang::XComponent> mxComponent; @@ -2160,6 +2162,34 @@ void DesktopLOKTest::testRunMacro() CPPUNIT_ASSERT(!bNonExistentMacro); } +void DesktopLOKTest::testExtractParameter() +{ + OUString aOptions("Language=de-DE"); + OUString aValue = extractParameter(aOptions, "Language"); + CPPUNIT_ASSERT_EQUAL(OUString("de-DE"), aValue); + CPPUNIT_ASSERT_EQUAL(OUString(), aOptions); + + aOptions = "Language=en-US,Something"; + aValue = extractParameter(aOptions, "Language"); + CPPUNIT_ASSERT_EQUAL(OUString("en-US"), aValue); + CPPUNIT_ASSERT_EQUAL(OUString("Something"), aOptions); + + aOptions = "SomethingElse,Language=cs-CZ"; + aValue = extractParameter(aOptions, "Language"); + CPPUNIT_ASSERT_EQUAL(OUString("cs-CZ"), aValue); + CPPUNIT_ASSERT_EQUAL(OUString("SomethingElse"), aOptions); + + aOptions = "Something1,Language=hu-HU,Something2"; + aValue = extractParameter(aOptions, "Language"); + CPPUNIT_ASSERT_EQUAL(OUString("hu-HU"), aValue); + CPPUNIT_ASSERT_EQUAL(OUString("Something1,Something2"), aOptions); + + aOptions = "Something1,Something2=blah,Something3"; + aValue = extractParameter(aOptions, "Language"); + CPPUNIT_ASSERT_EQUAL(OUString(), aValue); + CPPUNIT_ASSERT_EQUAL(OUString("Something1,Something2=blah,Something3"), aOptions); +} + CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 3500d2b7673e..9fcea7a1c5a5 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -472,6 +472,50 @@ int lcl_getViewId(const std::string& payload) } // end anonymous namespace +// Could be anonymous in principle, but for the unit testing purposes, we +// declare it in init.hxx. +OUString desktop::extractParameter(OUString& rOptions, const OUString& rName) +{ + OUString aValue; + + OUString aNameEquals(rName + "="); + OUString aCommaNameEquals("," + rName + "="); + + int nIndex = -1; + if (rOptions.startsWith(aNameEquals)) + { + size_t nLen = aNameEquals.getLength(); + int nComma = rOptions.indexOf(",", nLen); + if (nComma >= 0) + { + aValue = rOptions.copy(nLen, nComma - nLen); + rOptions = rOptions.copy(nComma + 1); + } + else + { + aValue = rOptions.copy(nLen); + rOptions.clear(); + } + } + else if ((nIndex = rOptions.indexOf(aCommaNameEquals)) >= 0) + { + size_t nLen = aCommaNameEquals.getLength(); + int nComma = rOptions.indexOf(",", nIndex + nLen); + if (nComma >= 0) + { + aValue = rOptions.copy(nIndex + nLen, nComma - nIndex - nLen); + rOptions = rOptions.copy(0, nIndex) + rOptions.copy(nComma); + } + else + { + aValue = rOptions.copy(nIndex + nLen); + rOptions = rOptions.copy(0, nIndex); + } + } + + return aValue; +} + extern "C" { @@ -1164,10 +1208,24 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis, try { + // 'Language=...' is an option that LOK consumes by itself, and does + // not pass it as a parameter to the filter + OUString aOptions = getUString(pOptions); + OUString aLanguage = extractParameter(aOptions, "Language"); + + if (!aLanguage.isEmpty()) + { + // use with care - it sets it for the entire core, not just the + // document + SvtSysLocaleOptions aSysLocaleOptions; + aSysLocaleOptions.SetLocaleConfigString(aLanguage); + aSysLocaleOptions.SetUILocaleConfigString(aLanguage); + } + uno::Sequence<css::beans::PropertyValue> aFilterOptions(2); aFilterOptions[0] = css::beans::PropertyValue( OUString("FilterOptions"), 0, - uno::makeAny(OUString::createFromAscii(pOptions)), + uno::makeAny(aOptions), beans::PropertyState_DIRECT_VALUE); rtl::Reference<LOKInteractionHandler> const pInteraction( diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx index 12c042886f97..72fb7c2b3882 100644 --- a/include/LibreOfficeKit/LibreOfficeKit.hxx +++ b/include/LibreOfficeKit/LibreOfficeKit.hxx @@ -487,6 +487,9 @@ public: * * @param pUrl the URL of the document to load * @param pFilterOptions options for the import filter, e.g. SkipImages. + * Another useful FilterOption is "Language=...". It is consumed + * by the documentLoad() itself, and when provided, LibreOfficeKit + * switches the language accordingly first. * @since pFilterOptions argument added in LibreOffice 5.0 */ inline Document* documentLoad(const char* pUrl, const char* pFilterOptions = NULL) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits