summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAshod Nakashian <ashod.nakashian@collabora.co.uk>2019-07-19 23:51:16 +0100
committerMichael Meeks <michael.meeks@collabora.com>2019-08-02 11:41:47 -0400
commit7e174f327a3cf16a09e4b2f8e2ffba2225c21901 (patch)
tree934ba482dafdd9b5fe7a9a68e579d40e990713c4
parentdc4e514f17d1923c19d2b61f733b196e5acf7dec (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.cxx50
-rw-r--r--desktop/source/lib/init.cxx36
-rw-r--r--include/LibreOfficeKit/LibreOfficeKit.h3
-rw-r--r--include/LibreOfficeKit/LibreOfficeKit.hxx10
-rw-r--r--include/LibreOfficeKit/LibreOfficeKitEnums.h9
-rw-r--r--include/vcl/transfer.hxx1
-rw-r--r--offapi/com/sun/star/datatransfer/XTransferable2.idl5
-rw-r--r--sw/source/filter/html/wrthtml.cxx7
-rw-r--r--vcl/source/treelist/transfer.cxx5
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()
{