summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2021-04-13 17:22:10 +0200
committerMiklos Vajna <vmiklos@collabora.com>2021-04-13 18:06:40 +0200
commitaa818a0b977084af21667fb68d1728bd5f300c4b (patch)
tree79a88baf44132463fe72ec6fa9c5dfde4372353e /sw
parent739b63ea2b11b3c82939c5ea4e8ac682585ac1ec (diff)
sw bibliography, refer to a page: fix biblio field relative URLs
Clicking always requires an absolute URL, so add functionality to get the absolute URL (even if the field has a relative one) and use that when handling a click. Change-Id: I05f8b11937eac7b6032750557f4066181c6e4520 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114059 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
Diffstat (limited to 'sw')
-rw-r--r--sw/inc/authfld.hxx1
-rw-r--r--sw/qa/core/tox/tox.cxx45
-rw-r--r--sw/source/core/fields/authfld.cxx12
-rw-r--r--sw/source/uibase/wrtsh/wrtsh2.cxx2
4 files changed, 59 insertions, 1 deletions
diff --git a/sw/inc/authfld.hxx b/sw/inc/authfld.hxx
index c9c7fd880b7b..681f95eddc31 100644
--- a/sw/inc/authfld.hxx
+++ b/sw/inc/authfld.hxx
@@ -186,6 +186,7 @@ public:
OUString GetAuthority(const SwTextAttr* pTextAttr, const SwRootFrame* pLayout) const;
bool HasURL() const;
+ OUString GetAbsoluteURL() const;
void dumpAsXml(xmlTextWriterPtr pWriter) const override;
};
diff --git a/sw/qa/core/tox/tox.cxx b/sw/qa/core/tox/tox.cxx
index 0862b6403638..1ac8764a0574 100644
--- a/sw/qa/core/tox/tox.cxx
+++ b/sw/qa/core/tox/tox.cxx
@@ -9,6 +9,7 @@
#include <swmodeltestbase.hxx>
+#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/text/BibliographyDataType.hpp>
#include <com/sun/star/text/ControlCharacter.hpp>
#include <com/sun/star/text/XDocumentIndex.hpp>
@@ -17,6 +18,7 @@
#include <comphelper/propertyvalue.hxx>
#include <IDocumentFieldsAccess.hxx>
+#include <authfld.hxx>
#include <fmtfld.hxx>
namespace
@@ -154,6 +156,49 @@ CPPUNIT_TEST_FIXTURE(Test, testAuthorityTableEntryClick)
CPPUNIT_ASSERT(pField->HasClickHdl());
}
+CPPUNIT_TEST_FIXTURE(Test, testAuthorityTableEntryRelClick)
+{
+ // Given an empty document with a file:// base URL:
+ SwDoc* pDoc = createSwDoc();
+ uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+ uno::Sequence<beans::PropertyValue> aArgs = {
+ comphelper::makePropertyValue("FilterName", OUString("writer8")),
+ };
+ xStorable->storeAsURL(maTempFile.GetURL(), aArgs);
+
+ // When inserting a biblio entry field with a relative URL:
+ 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("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);
+
+ // Then make sure that the field is clickable:
+ const SwFieldTypes* pTypes = pDoc->getIDocumentFieldsAccess().GetFieldTypes();
+ auto it = std::find_if(pTypes->begin(), pTypes->end(),
+ [](const std::unique_ptr<SwFieldType>& pType) {
+ return pType->Which() == SwFieldIds::TableOfAuthorities;
+ });
+ CPPUNIT_ASSERT(it != pTypes->end());
+ const SwFieldType* pType = it->get();
+ std::vector<SwFormatField*> aFormatFields;
+ pType->GatherFields(aFormatFields);
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aFormatFields.size());
+ auto pField = static_cast<SwAuthorityField*>(aFormatFields[0]->GetField());
+ CPPUNIT_ASSERT(pField->GetAbsoluteURL().startsWith("file://"));
+}
+
CPPUNIT_TEST_FIXTURE(Test, testAuthorityTableURLDeduplication)
{
// Given a document with 3 bibliography references (of type WWW) in it:
diff --git a/sw/source/core/fields/authfld.cxx b/sw/source/core/fields/authfld.cxx
index f57603509fd2..934f06f1243b 100644
--- a/sw/source/core/fields/authfld.cxx
+++ b/sw/source/core/fields/authfld.cxx
@@ -25,6 +25,7 @@
#include <i18nlangtag/languagetag.hxx>
#include <o3tl/any.hxx>
#include <osl/diagnose.h>
+#include <tools/urlobj.hxx>
#include <swtypes.hxx>
#include <strings.hrc>
#include <authfld.hxx>
@@ -42,6 +43,7 @@
#include <IDocumentLayoutAccess.hxx>
#include <unofldmid.h>
#include <unoprnms.hxx>
+#include <docsh.hxx>
#include <com/sun/star/beans/PropertyValues.hpp>
@@ -610,6 +612,16 @@ bool SwAuthorityField::HasURL() const
return !rURL.isEmpty();
}
+OUString SwAuthorityField::GetAbsoluteURL() const
+{
+ const OUString& rURL = GetAuthEntry()->GetAuthorField(AUTH_FIELD_URL);
+ SwDoc* pDoc = static_cast<SwAuthorityFieldType*>(GetTyp())->GetDoc();
+ SwDocShell* pDocShell = pDoc->GetDocShell();
+ OUString aBasePath = pDocShell->getDocumentBaseURL();
+ return INetURLObject::GetAbsURL(aBasePath, rURL, INetURLObject::EncodeMechanism::WasEncoded,
+ INetURLObject::DecodeMechanism::WithCharset);
+}
+
void SwAuthorityField::dumpAsXml(xmlTextWriterPtr pWriter) const
{
(void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwAuthorityField"));
diff --git a/sw/source/uibase/wrtsh/wrtsh2.cxx b/sw/source/uibase/wrtsh/wrtsh2.cxx
index 66b38c3d84ea..90f08fd33a81 100644
--- a/sw/source/uibase/wrtsh/wrtsh2.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh2.cxx
@@ -411,7 +411,7 @@ void SwWrtShell::ClickToField(const SwField& rField, bool bExecHyperlinks)
break;
}
- const OUString& rURL = pField->GetAuthEntry()->GetAuthorField(AUTH_FIELD_URL);
+ const OUString& rURL = pField->GetAbsoluteURL();
::LoadURL(*this, rURL, LoadUrlFlags::NewView, /*rTargetFrameName=*/OUString());
}
break;