diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2022-05-19 09:15:46 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2022-05-31 17:03:02 +0200 |
commit | e4842a4c520c68813f0567d34ad321de11c4f1c3 (patch) | |
tree | e7754f576ee9fc75c55ade0516f3116fb546ff7a /desktop | |
parent | f90239263fcabec30f04098e17dc1be9f9a928d1 (diff) |
lok: add more efficient getSelectionType() replacement
The getSelectionType() function usually needs to be followed by a call
to getTextSelection(), which means having them as two functions
leads to duplicating to a number of calls, some of which may be
somewhat expensive (pDoc->getSelection() e.g. for Calc builds
another ScDocument for the selection, and then getFromTransferrable()
converts that to the given format).
Change-Id: Ib0a8844701d80eaaff4834dcd3633c09d6b921b1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134603
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'desktop')
-rw-r--r-- | desktop/qa/desktop_lib/test_desktop_lib.cxx | 9 | ||||
-rw-r--r-- | desktop/source/lib/init.cxx | 62 |
2 files changed, 69 insertions, 2 deletions
diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx index f2fd0ab16173..54440df9266b 100644 --- a/desktop/qa/desktop_lib/test_desktop_lib.cxx +++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx @@ -3040,12 +3040,16 @@ void DesktopLOKTest::testComplexSelection() // Certainly not complex. CPPUNIT_ASSERT_EQUAL(static_cast<int>(LOK_SELTYPE_NONE), pDocument->pClass->getSelectionType(pDocument)); + CPPUNIT_ASSERT_EQUAL(static_cast<int>(LOK_SELTYPE_NONE), pDocument->pClass->getSelectionTypeAndText(pDocument, + "", nullptr, nullptr)); // Paste text. CPPUNIT_ASSERT(pDocument->pClass->paste(pDocument, "text/plain;charset=utf-8", aText.getStr(), aText.getLength())); // No selection. CPPUNIT_ASSERT_EQUAL(static_cast<int>(LOK_SELTYPE_NONE), pDocument->pClass->getSelectionType(pDocument)); + CPPUNIT_ASSERT_EQUAL(static_cast<int>(LOK_SELTYPE_NONE), pDocument->pClass->getSelectionTypeAndText(pDocument, + "", nullptr, nullptr)); // Paste an image. OUString aFileURL; @@ -3080,6 +3084,8 @@ void DesktopLOKTest::testComplexSelection() // We expect this to be complex. CPPUNIT_ASSERT_EQUAL(static_cast<int>(LOK_SELTYPE_COMPLEX), pDocument->pClass->getSelectionType(pDocument)); + CPPUNIT_ASSERT_EQUAL(static_cast<int>(LOK_SELTYPE_COMPLEX), pDocument->pClass->getSelectionTypeAndText(pDocument, + "", nullptr, nullptr)); } void DesktopLOKTest::testCalcSaveAs() @@ -3633,10 +3639,11 @@ void DesktopLOKTest::testABI() CPPUNIT_ASSERT_EQUAL(documentClassOffset(63), offsetof(struct _LibreOfficeKitDocumentClass, renderSearchResult)); CPPUNIT_ASSERT_EQUAL(documentClassOffset(64), offsetof(struct _LibreOfficeKitDocumentClass, sendContentControlEvent)); + CPPUNIT_ASSERT_EQUAL(documentClassOffset(65), offsetof(struct _LibreOfficeKitDocumentClass, getSelectionTypeAndText)); // Extending is fine, update this, and add new assert for the offsetof the // new method - CPPUNIT_ASSERT_EQUAL(documentClassOffset(65), sizeof(struct _LibreOfficeKitDocumentClass)); + CPPUNIT_ASSERT_EQUAL(documentClassOffset(66), sizeof(struct _LibreOfficeKitDocumentClass)); } CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest); diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index e8bb8b44f6bf..ec97510b40e4 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -1048,6 +1048,10 @@ static char* doc_getTextSelection(LibreOfficeKitDocument* pThis, const char* pMimeType, char** pUsedMimeType); static int doc_getSelectionType(LibreOfficeKitDocument* pThis); +static int doc_getSelectionTypeAndText(LibreOfficeKitDocument* pThis, + const char* pMimeType, + char** pText, + char** pUsedMimeType); static int doc_getClipboard (LibreOfficeKitDocument* pThis, const char **pMimeTypes, size_t *pOutCount, @@ -1242,6 +1246,7 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference <css::lang::XCompone m_pDocumentClass->setWindowTextSelection = doc_setWindowTextSelection; m_pDocumentClass->getTextSelection = doc_getTextSelection; m_pDocumentClass->getSelectionType = doc_getSelectionType; + m_pDocumentClass->getSelectionTypeAndText = doc_getSelectionTypeAndText; m_pDocumentClass->getClipboard = doc_getClipboard; m_pDocumentClass->setClipboard = doc_setClipboard; m_pDocumentClass->paste = doc_paste; @@ -4665,7 +4670,62 @@ static int doc_getSelectionType(LibreOfficeKitDocument* pThis) if (aRet.getLength() > 10000) return LOK_SELTYPE_COMPLEX; - return aRet.getLength() ? LOK_SELTYPE_TEXT : LOK_SELTYPE_NONE; + return !aRet.isEmpty() ? LOK_SELTYPE_TEXT : LOK_SELTYPE_NONE; +} + +static int doc_getSelectionTypeAndText(LibreOfficeKitDocument* pThis, const char* pMimeType, char** pText, char** pUsedMimeType) +{ + // The purpose of this function is to avoid double call to pDoc->getSelection(), + // which may be expensive. + comphelper::ProfileZone aZone("doc_getSelectionTypeAndText"); + + SolarMutexGuard aGuard; + SetLastExceptionMsg(); + + ITiledRenderable* pDoc = getTiledRenderable(pThis); + if (!pDoc) + { + SetLastExceptionMsg("Document doesn't support tiled rendering"); + return LOK_SELTYPE_NONE; + } + + css::uno::Reference<css::datatransfer::XTransferable2> xTransferable(pDoc->getSelection(), css::uno::UNO_QUERY); + if (!xTransferable) + { + SetLastExceptionMsg("No selection available"); + return LOK_SELTYPE_NONE; + } + + if (xTransferable->isComplex()) + return LOK_SELTYPE_COMPLEX; + + const char *pType = pMimeType; + if (!pType || pType[0] == '\0') + pType = "text/plain;charset=utf-8"; + + OString aRet; + bool bSuccess = getFromTransferrable(xTransferable, OString(pType), aRet); + if (!bSuccess) + return LOK_SELTYPE_NONE; + + if (aRet.getLength() > 10000) + return LOK_SELTYPE_COMPLEX; + + if (aRet.isEmpty()) + return LOK_SELTYPE_NONE; + + if (pText) + *pText = convertOString(aRet); + + if (pUsedMimeType) // legacy + { + if (pMimeType) + *pUsedMimeType = strdup(pMimeType); + else + *pUsedMimeType = nullptr; + } + + return LOK_SELTYPE_TEXT; } static int doc_getClipboard(LibreOfficeKitDocument* pThis, |