[Libreoffice-commits] core.git: sw/CppunitTest_sw_core_text.mk sw/inc sw/qa sw/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Wed Mar 24 15:36:21 UTC 2021


 sw/CppunitTest_sw_core_text.mk                  |    1 
 sw/inc/EnhancedPDFExportHelper.hxx              |    4 +
 sw/qa/core/text/text.cxx                        |   52 ++++++++++++++++++++
 sw/source/core/text/EnhancedPDFExportHelper.cxx |   62 ++++++++++++++++++++++++
 4 files changed, 119 insertions(+)

New commits:
commit fb20b6182807885f9fa9b95baa69fed0091fec7d
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Wed Mar 24 13:36:59 2021 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Wed Mar 24 16:35:40 2021 +0100

    sw bibliography, refer to a page: add PDF export links
    
    This is similar to hyperlinks or footnote references, but the source
    rectangle is a field here and still the links are always external.
    
    With this, the UI and the PDF export result is consistent, it doesn't
    happen that you can click on biblio entry fields on the UI, but not in
    the PDF export result.
    
    Change-Id: I655ef6d5f79a7e372cdc8448ddc10af9ca488ac5
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113035
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins

diff --git a/sw/CppunitTest_sw_core_text.mk b/sw/CppunitTest_sw_core_text.mk
index b0c4d03fac38..cb4801accac9 100644
--- a/sw/CppunitTest_sw_core_text.mk
+++ b/sw/CppunitTest_sw_core_text.mk
@@ -26,6 +26,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sw_core_text, \
     sw \
 	swqahelper \
     test \
+    tl \
     unotest \
     utl \
     vcl \
diff --git a/sw/inc/EnhancedPDFExportHelper.hxx b/sw/inc/EnhancedPDFExportHelper.hxx
index 8273cf29ad85..eb813773abb3 100644
--- a/sw/inc/EnhancedPDFExportHelper.hxx
+++ b/sw/inc/EnhancedPDFExportHelper.hxx
@@ -219,6 +219,10 @@ class SwEnhancedPDFExportHelper
     static LanguageType s_eLanguageDefault;
 
     void EnhancedPDFExport();
+
+    /// Exports bibliography entry links.
+    void ExportAuthorityEntryLinks();
+
     sal_Int32 CalcOutputPageNum( const SwRect& rRect ) const;
     std::vector< sal_Int32 > CalcOutputPageNums( const SwRect& rRect ) const;
 
diff --git a/sw/qa/core/text/text.cxx b/sw/qa/core/text/text.cxx
index 8b4c6ae336bb..f3a4b458b3ae 100644
--- a/sw/qa/core/text/text.cxx
+++ b/sw/qa/core/text/text.cxx
@@ -9,7 +9,14 @@
 
 #include <swmodeltestbase.hxx>
 
+#include <memory>
+
+#include <com/sun/star/text/BibliographyDataType.hpp>
+
 #include <vcl/gdimtf.hxx>
+#include <vcl/filter/PDFiumLibrary.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <unotools/mediadescriptor.hxx>
 
 #include <docsh.hxx>
 #include <unotxdoc.hxx>
@@ -69,6 +76,51 @@ CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testSemiTransparentText)
     assertXPath(pXmlDoc, "//floattransparent");
 }
 
+CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testBibliographyUrlPdfExport)
+{
+    // Given a document with a bibliography entry field:
+    std::shared_ptr<vcl::pdf::PDFium> pPDFium = vcl::pdf::PDFiumLibrary::get();
+    if (!pPDFium)
+    {
+        return;
+    }
+    createSwDoc();
+    uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
+    uno::Reference<beans::XPropertySet> xField(
+        xFactory->createInstance("com.sun.star.text.TextField.Bibliography"), uno::UNO_QUERY);
+    uno::Sequence<beans::PropertyValue> aFields = {
+        comphelper::makePropertyValue("BibiliographicType", text::BibliographyDataType::WWW),
+        comphelper::makePropertyValue("Identifier", OUString("AT")),
+        comphelper::makePropertyValue("Author", OUString("Author")),
+        comphelper::makePropertyValue("Title", OUString("Title")),
+        comphelper::makePropertyValue("URL", OUString("http://www.example.com/test.pdf#page=1")),
+    };
+    xField->setPropertyValue("Fields", uno::makeAny(aFields));
+    uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+    uno::Reference<text::XText> xText = xTextDocument->getText();
+    uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor();
+    uno::Reference<text::XTextContent> xContent(xField, uno::UNO_QUERY);
+    xText->insertTextContent(xCursor, xContent, /*bAbsorb=*/false);
+
+    // When exporting to PDF:
+    uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+    utl::MediaDescriptor aMediaDescriptor;
+    aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export");
+    xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
+
+    // Then make sure the field links the source.
+    SvFileStream aFile(maTempFile.GetURL(), StreamMode::READ);
+    SvMemoryStream aMemory;
+    aMemory.WriteStream(aFile);
+    std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument
+        = pPDFium->openDocument(aMemory.GetData(), aMemory.GetSize());
+    CPPUNIT_ASSERT(pPdfDocument);
+    std::unique_ptr<vcl::pdf::PDFiumPage> pPdfPage = pPdfDocument->openPage(/*nIndex=*/0);
+    // Without the accompanying fix in place, this test would have failed, the field was not
+    // clickable (while it was clickable on the UI).
+    CPPUNIT_ASSERT(pPdfPage->hasLinks());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx b/sw/source/core/text/EnhancedPDFExportHelper.cxx
index 29719590dc4c..51785be1a1c4 100644
--- a/sw/source/core/text/EnhancedPDFExportHelper.cxx
+++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx
@@ -79,6 +79,7 @@
 #include <frmtool.hxx>
 #include <strings.hrc>
 #include <frameformats.hxx>
+#include <authfld.hxx>
 
 #include <tools/globname.hxx>
 #include <svx/svdobj.hxx>
@@ -1923,6 +1924,8 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()
             mrSh.SwCursorShell::ClearMark();
         }
 
+        ExportAuthorityEntryLinks();
+
         // FOOTNOTES
 
         const size_t nFootnoteCount = pDoc->GetFootnoteIdxs().size();
@@ -2162,6 +2165,65 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()
     mrOut.Pop();
 }
 
+void SwEnhancedPDFExportHelper::ExportAuthorityEntryLinks()
+{
+    auto pPDFExtOutDevData = dynamic_cast<vcl::PDFExtOutDevData*>(mrOut.GetExtOutDevData());
+    if (!pPDFExtOutDevData)
+    {
+        return;
+    }
+
+    std::vector<SwFormatField*> aFields;
+    SwFieldType* pType = mrSh.GetFieldType(SwFieldIds::TableOfAuthorities, OUString());
+    if (!pType)
+    {
+        return;
+    }
+
+    pType->GatherFields(aFields);
+    const auto pPageFrame = static_cast<const SwPageFrame*>(mrSh.GetLayout()->Lower());
+    for (const auto pFormatField : aFields)
+    {
+        if (!pFormatField->GetTextField() || !pFormatField->IsFieldInDoc())
+        {
+            continue;
+        }
+
+        const auto& rAuthorityField
+            = *static_cast<const SwAuthorityField*>(pFormatField->GetField());
+        if (!rAuthorityField.HasURL())
+        {
+            continue;
+        }
+
+        const OUString& rURL = rAuthorityField.GetAuthEntry()->GetAuthorField(AUTH_FIELD_URL);
+        const SwTextNode& rTextNode = pFormatField->GetTextField()->GetTextNode();
+        if (!lcl_TryMoveToNonHiddenField(mrSh, rTextNode, *pFormatField))
+        {
+            continue;
+        }
+
+        // Select the field.
+        mrSh.SwCursorShell::SetMark();
+        mrSh.SwCursorShell::Right(1, CRSR_SKIP_CHARS);
+
+        // Create the links.
+        for (const auto& rLinkRect : *mrSh.SwCursorShell::GetCursor_())
+        {
+            for (const auto& rLinkPageNum : CalcOutputPageNums(rLinkRect))
+            {
+                tools::Rectangle aRect(SwRectToPDFRect(pPageFrame, rLinkRect.SVRect()));
+                sal_Int32 nLinkId = pPDFExtOutDevData->CreateLink(aRect, rLinkPageNum);
+                IdMapEntry aLinkEntry(rLinkRect, nLinkId);
+                s_aLinkIdMap.push_back(aLinkEntry);
+                pPDFExtOutDevData->SetLinkURL(nLinkId, rURL);
+            }
+        }
+
+        mrSh.SwCursorShell::ClearMark();
+    }
+}
+
 // Returns the page number in the output pdf on which the given rect is located.
 // If this page is duplicated, method will return first occurrence of it.
 sal_Int32 SwEnhancedPDFExportHelper::CalcOutputPageNum( const SwRect& rRect ) const


More information about the Libreoffice-commits mailing list