summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/CppunitTest_sw_core_text.mk1
-rw-r--r--sw/inc/EnhancedPDFExportHelper.hxx4
-rw-r--r--sw/qa/core/text/text.cxx52
-rw-r--r--sw/source/core/text/EnhancedPDFExportHelper.cxx62
4 files changed, 119 insertions, 0 deletions
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