diff options
author | Ashod Nakashian <ashod.nakashian@collabora.co.uk> | 2019-07-19 23:51:16 +0100 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2019-08-02 11:41:47 -0400 |
commit | 7e174f327a3cf16a09e4b2f8e2ffba2225c21901 (patch) | |
tree | 934ba482dafdd9b5fe7a9a68e579d40e990713c4 | |
parent | dc4e514f17d1923c19d2b61f733b196e5acf7dec (diff) |
LOK: Support detecting complex selections
Includes unit-test, but is otherwise not complete
implementation.
Change-Id: I5fdcd543358caab1858f6351238c21312665839c
-rw-r--r-- | desktop/qa/desktop_lib/test_desktop_lib.cxx | 50 | ||||
-rw-r--r-- | desktop/source/lib/init.cxx | 36 | ||||
-rw-r--r-- | include/LibreOfficeKit/LibreOfficeKit.h | 3 | ||||
-rw-r--r-- | include/LibreOfficeKit/LibreOfficeKit.hxx | 10 | ||||
-rw-r--r-- | include/LibreOfficeKit/LibreOfficeKitEnums.h | 9 | ||||
-rw-r--r-- | include/vcl/transfer.hxx | 1 | ||||
-rw-r--r-- | offapi/com/sun/star/datatransfer/XTransferable2.idl | 5 | ||||
-rw-r--r-- | sw/source/filter/html/wrthtml.cxx | 7 | ||||
-rw-r--r-- | vcl/source/treelist/transfer.cxx | 5 |
9 files changed, 125 insertions, 1 deletions
diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx index 36e7d727efb0..4ebb21cdfe0a 100644 --- a/desktop/qa/desktop_lib/test_desktop_lib.cxx +++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx @@ -139,6 +139,7 @@ public: void testInsertCertificate_PEM_DOCX(); void testSignDocument_PEM_PDF(); void testTextSelectionHandles(); + void testComplexSelection(); void testDialogPaste(); void testShowHideDialog(); void testABI(); @@ -193,6 +194,7 @@ public: CPPUNIT_TEST(testSignDocument_PEM_PDF); #endif CPPUNIT_TEST(testTextSelectionHandles); + CPPUNIT_TEST(testComplexSelection); CPPUNIT_TEST(testDialogPaste); CPPUNIT_TEST(testShowHideDialog); CPPUNIT_TEST(testABI); @@ -586,7 +588,7 @@ void DesktopLOKTest::testPasteWriter() free(pText); // textt/plain should be rejected. - CPPUNIT_ASSERT(!pDocument->pClass->paste(pDocument, "textt/plain;charset=utf-8", aText.getStr(), aText.getLength())); + CPPUNIT_ASSERT(!pDocument->pClass->paste(pDocument, "text/plain;charset=utf-8", aText.getStr(), aText.getLength())); // Writer is expected to support text/html. CPPUNIT_ASSERT(pDocument->pClass->paste(pDocument, "text/html", aText.getStr(), aText.getLength())); @@ -2637,6 +2639,52 @@ void DesktopLOKTest::testShowHideDialog() CPPUNIT_ASSERT_EQUAL(std::string("invalidate"), aView.m_aCallbackWindowResult.get<std::string>("action")); } +void DesktopLOKTest::testComplexSelection() +{ + // Start with a blank text file and add contents. + LibLODocument_Impl* pDocument = loadDoc("blank_text.odt"); + // LibLODocument_Impl* pDocument = loadDoc("sheet_with_image.ods"); + static const OString aText("hello world"); + + // Paste text. + CPPUNIT_ASSERT(pDocument->pClass->paste(pDocument, "text/plain;charset=utf-8", aText.getStr(), aText.getLength())); + + // Paste an image. + OUString aFileURL; + createFileURL("paste.jpg", aFileURL); + std::ifstream aImageStream(aFileURL.toUtf8().copy(strlen("file://")).getStr()); + std::vector<char> aImageContents((std::istreambuf_iterator<char>(aImageStream)), std::istreambuf_iterator<char>()); + CPPUNIT_ASSERT(pDocument->pClass->paste(pDocument, "image/jpeg", aImageContents.data(), aImageContents.size())); + + // Now select-all. + pDocument->pClass->postUnoCommand(pDocument, ".uno:SelectAll", nullptr, false); + Scheduler::ProcessEventsToIdle(); + + // We expect this to be complex. + const int type = pDocument->pClass->getSelectionType(pDocument); + CPPUNIT_ASSERT_EQUAL((int)LOK_SELTYPE_COMPLEX, type); + + // Export as plain text, we should get only the text part "hello". + char* pText = pDocument->pClass->getTextSelection(pDocument, "text/plain;charset=utf-8", nullptr); + CPPUNIT_ASSERT(pText != nullptr); + CPPUNIT_ASSERT_EQUAL(aText, OString(pText)); + free(pText); + + // Export as rtf, we should also get the image. + pText = pDocument->pClass->getTextSelection(pDocument, "text/rtf", nullptr); + CPPUNIT_ASSERT(pText != nullptr); + CPPUNIT_ASSERT(std::string(pText).find(aText.getStr()) != std::string::npos); // Must have the text. + CPPUNIT_ASSERT(std::string(pText).find("pict{") != std::string::npos); // Must have the image as well. + free(pText); + + // Export as html, we should also get the image. + pText = pDocument->pClass->getTextSelection(pDocument, "text/html", nullptr); + CPPUNIT_ASSERT(pText != nullptr); + CPPUNIT_ASSERT(std::string(pText).find(aText.getStr()) != std::string::npos); // Must have the text. + // CPPUNIT_ASSERT(std::string(pText).find("<img") != std::string::npos); // Must have the image as well. + free(pText); +} + namespace { constexpr size_t classOffset(int i) diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 3b835c0d66b8..eb9c7854bc13 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -78,6 +78,7 @@ #include <com/sun/star/util/URLTransformer.hpp> #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp> #include <com/sun/star/datatransfer/UnsupportedFlavorException.hpp> +#include <com/sun/star/datatransfer/XTransferable2.hpp> #include <com/sun/star/text/TextContentAnchorType.hpp> #include <com/sun/star/document/XRedlinesSupplier.hpp> #include <com/sun/star/ui/GlobalAcceleratorConfiguration.hpp> @@ -788,6 +789,7 @@ static void doc_setTextSelection (LibreOfficeKitDocument* pThis, static char* doc_getTextSelection(LibreOfficeKitDocument* pThis, const char* pMimeType, char** pUsedMimeType); +static int doc_getSelectionType(LibreOfficeKitDocument* pThis); static int doc_getSelection (LibreOfficeKitDocument* pThis, const char **pMimeTypes, size_t *pOutCount, @@ -898,6 +900,7 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference <css::lang::XCompone m_pDocumentClass->postUnoCommand = doc_postUnoCommand; m_pDocumentClass->setTextSelection = doc_setTextSelection; m_pDocumentClass->getTextSelection = doc_getTextSelection; + m_pDocumentClass->getSelectionType = doc_getSelectionType; m_pDocumentClass->getSelection = doc_getSelection; m_pDocumentClass->setClipboard = doc_setClipboard; m_pDocumentClass->paste = doc_paste; @@ -3499,6 +3502,39 @@ static char* doc_getTextSelection(LibreOfficeKitDocument* pThis, const char* pMi return convertOString(aRet); } +static int doc_getSelectionType(LibreOfficeKitDocument* pThis) +{ + 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; + + OString aRet; + bool bSuccess = getFromTransferrable(xTransferable, OString("text/plain;charset=utf-8"), aRet); + if (!bSuccess) + return LOK_SELTYPE_NONE; + + if (aRet.getLength() > 1000) // About 2 paragraphs. + return LOK_SELTYPE_COMPLEX; + + return aRet.getLength() ? LOK_SELTYPE_TEXT : LOK_SELTYPE_NONE; +} + static int doc_getSelection(LibreOfficeKitDocument* pThis, const char **pMimeTypes, size_t *pOutCount, diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h index 14b7bb995b10..abdc9863c1f0 100644 --- a/include/LibreOfficeKit/LibreOfficeKit.h +++ b/include/LibreOfficeKit/LibreOfficeKit.h @@ -405,6 +405,9 @@ struct _LibreOfficeKitDocumentClass const size_t *pInSizes, const char **pInStreams); + /// @see lok::Document::getSelectionType + int (*getSelectionType) (LibreOfficeKitDocument* pThis); + #endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY }; diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx index cb1ca1e4c2d3..ca0287a6b584 100644 --- a/include/LibreOfficeKit/LibreOfficeKit.hxx +++ b/include/LibreOfficeKit/LibreOfficeKit.hxx @@ -352,6 +352,16 @@ public: } /** + * Gets the type of the selected content. + * + * @return an element of the LibreOfficeKitSelectionType enum. + */ + int getSelectionType(LibreOfficeKitDocument* pThis) + { + return mpDoc->pClass->getSelectionType(mpDoc); + } + + /** * Gets the selected content for the current view as a series of binary streams. * * NB. returns a complete set of possible selection types if nullptr is passed for pMimeTypes. diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h index 4277adbe6dbc..0680c7e6c44f 100644 --- a/include/LibreOfficeKit/LibreOfficeKitEnums.h +++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h @@ -47,6 +47,15 @@ typedef enum } LibreOfficeKitWindowAction; +typedef enum +{ + LOK_SELTYPE_NONE, + LOK_SELTYPE_TEXT, + LOK_SELTYPE_LARGE_TEXT, + LOK_SELTYPE_COMPLEX +} +LibreOfficeKitSelectionType; + /** Optional features of LibreOfficeKit, in particular callbacks that block * LibreOfficeKit until the corresponding reply is received, which would * deadlock if the client does not support the feature. diff --git a/include/vcl/transfer.hxx b/include/vcl/transfer.hxx index 888fe254e115..722d3f26b42b 100644 --- a/include/vcl/transfer.hxx +++ b/include/vcl/transfer.hxx @@ -184,6 +184,7 @@ private: // Transferable2 virtual css::uno::Any SAL_CALL getTransferData2( const css::datatransfer::DataFlavor& rFlavor, const OUString& rDestDoc ) override; + virtual sal_Bool SAL_CALL isComplex() override; // XEventListener virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; diff --git a/offapi/com/sun/star/datatransfer/XTransferable2.idl b/offapi/com/sun/star/datatransfer/XTransferable2.idl index f792a969ded8..a6b53f0671e2 100644 --- a/offapi/com/sun/star/datatransfer/XTransferable2.idl +++ b/offapi/com/sun/star/datatransfer/XTransferable2.idl @@ -31,6 +31,11 @@ interface XTransferable2 : com::sun::star::datatransfer::XTransferable */ any getTransferData2( [in] DataFlavor aFlavor, [in] string aDestShellID ) raises ( UnsupportedFlavorException, com::sun::star::io::IOException ); + + /** + * Returns true if the selection contains embedded objects or is a large text blob. + */ + boolean isComplex(); }; }; }; }; }; diff --git a/sw/source/filter/html/wrthtml.cxx b/sw/source/filter/html/wrthtml.cxx index 51b7317f64e3..bba11082b6db 100644 --- a/sw/source/filter/html/wrthtml.cxx +++ b/sw/source/filter/html/wrthtml.cxx @@ -822,6 +822,13 @@ void SwHTMLWriter::Out_SwDoc( SwPaM* pPam ) OutHTML_Section( *this, *rNd.GetSectionNode() ); m_nBkmkTabPos = m_bWriteAll ? FindPos_Bkmk( *m_pCurrentPam->GetPoint() ) : -1; } + else if( rNd.IsGrfNode() ) + { + SwGrfNode* pGrfNd = rNd.GetGrfNode(); + assert(pGrfNd && !"FIXME: Implement Graphic copy as HTML."); + // if (pGrfNd) + // OutHTML_SwGrfNode( *this, *pGrfNd ); + } else if( &rNd == &m_pDoc->GetNodes().GetEndOfContent() ) break; diff --git a/vcl/source/treelist/transfer.cxx b/vcl/source/treelist/transfer.cxx index a33c719f86ee..67e71396e8dc 100644 --- a/vcl/source/treelist/transfer.cxx +++ b/vcl/source/treelist/transfer.cxx @@ -388,6 +388,11 @@ Any SAL_CALL TransferableHelper::getTransferData2( const DataFlavor& rFlavor, co return maAny; } +sal_Bool SAL_CALL TransferableHelper::isComplex() +{ + //FIXME: get from each document. + return sal_True; +} Sequence< DataFlavor > SAL_CALL TransferableHelper::getTransferDataFlavors() { |