sw/qa/core/tox/tox.cxx | 51 ++++++++++++++++++++++++++++++++++++ sw/source/core/inc/txmsrt.hxx | 3 ++ sw/source/core/tox/txmsrt.cxx | 58 +++++++++++++++++++++++++++++++++++------- 3 files changed, 103 insertions(+), 9 deletions(-)
New commits: commit e9e41795e6b2bf680a5f74e5684b76af00bf677b Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Mon Mar 1 17:46:58 2021 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Tue Mar 2 00:15:01 2021 +0100 sw bibliography, refer to a page: de-duplicate bibliography table URLs If we have 2 bibliography entries which refer to the same source, just different page numbers, then have 1 row for that sources in the bibliography table, not 2 ones. Change-Id: Icb7c342d41604b36c7e269095d139ee3dd970d7c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111761 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins diff --git a/sw/qa/core/tox/tox.cxx b/sw/qa/core/tox/tox.cxx index 22c0bd3cafa1..d10a996036a2 100644 --- a/sw/qa/core/tox/tox.cxx +++ b/sw/qa/core/tox/tox.cxx @@ -107,6 +107,57 @@ CPPUNIT_TEST_FIXTURE(Test, testAuthorityTableEntryURL) // i.e. the page number was still part of the bibliography table. CPPUNIT_ASSERT_EQUAL(OUString("http://www.example.com/test.pdf"), aActual); } + +CPPUNIT_TEST_FIXTURE(Test, testAuthorityTableURLDeduplication) +{ + // Given a document with 3 bibliography references (of type WWW) in it: + static const std::initializer_list<std::u16string_view> aURLs = { + u"http://www.example.com/test.pdf#page=1", + u"http://www.example.com/test.pdf#page=2", + u"http://www.example.com/test2.pdf", + }; + createSwDoc(); + uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XText> xText = xTextDocument->getText(); + uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor(); + for (const auto& rURL : aURLs) + { + 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(rURL)), + }; + xField->setPropertyValue("Fields", uno::makeAny(aFields)); + uno::Reference<text::XTextContent> xContent(xField, uno::UNO_QUERY); + xText->insertTextContent(xCursor, xContent, /*bAbsorb=*/false); + } + // Create a bibliography table. + uno::Reference<text::XTextContent> xTable( + xFactory->createInstance("com.sun.star.text.Bibliography"), uno::UNO_QUERY); + xCursor->gotoEnd(/*bExpand=*/false); + xText->insertControlCharacter(xCursor, text::ControlCharacter::APPEND_PARAGRAPH, + /*bAbsorb=*/false); + xText->insertTextContent(xCursor, xTable, /*bAbsorb=*/false); + + // When updating that table: + uno::Reference<text::XDocumentIndex> xTableIndex(xTable, uno::UNO_QUERY); + xTableIndex->update(); + + // Then the first two fields should be merged to a single source, but not the third. + CPPUNIT_ASSERT_EQUAL(OUString("AT: Author, Title, , http://www.example.com/test.pdf"), + getParagraph(3)->getString()); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: AT: Author, Title, , http://www.example.com/test2.pdf + // - Actual : AT: Author, Title, , http://www.example.com/test.pdf + // i.e. test.pdf was mentionted twice, without deduplication. + CPPUNIT_ASSERT_EQUAL(OUString("AT: Author, Title, , http://www.example.com/test2.pdf"), + getParagraph(4)->getString()); +} } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/core/inc/txmsrt.hxx b/sw/source/core/inc/txmsrt.hxx index ad021185e317..873e683c451e 100644 --- a/sw/source/core/inc/txmsrt.hxx +++ b/sw/source/core/inc/txmsrt.hxx @@ -297,6 +297,9 @@ public: virtual bool sort_lt( const SwTOXSortTabBase& ) override; virtual sal_uInt16 GetLevel() const override; OUString GetText(sal_uInt16 nAuthField, const SwRootFrame* pLayout) const; + + /// Gets the URL of the underlying SwAuthEntry, ignoring its page number. + static OUString GetSourceURL(const OUString& rText); }; #endif // INCLUDED_SW_SOURCE_CORE_INC_TXMSRT_HXX diff --git a/sw/source/core/tox/txmsrt.cxx b/sw/source/core/tox/txmsrt.cxx index 7c2748c82bd2..881ea6e3c686 100644 --- a/sw/source/core/tox/txmsrt.cxx +++ b/sw/source/core/tox/txmsrt.cxx @@ -842,18 +842,25 @@ OUString SwTOXAuthority::GetText(sal_uInt16 nAuthField, const SwRootFrame* pLayo return sText; } +OUString SwTOXAuthority::GetSourceURL(const OUString& rText) +{ + OUString aText = rText; + INetURLObject aObject(aText); + if (aObject.GetMark().startsWith("page=")) + { + aObject.SetMark(OUString()); + aText = aObject.GetMainURL(INetURLObject::DecodeMechanism::NONE); + } + return aText; +} + void SwTOXAuthority::FillText(SwTextNode& rNd, const SwIndex& rInsPos, sal_uInt16 nAuthField, SwRootFrame const* const pLayout) const { OUString aText = GetText(nAuthField, pLayout); if (nAuthField == AUTH_FIELD_URL) { - INetURLObject aObject(aText); - if (aObject.GetMark().startsWith("page=")) - { - aObject.SetMark(OUString()); - aText = aObject.GetMainURL(INetURLObject::DecodeMechanism::NONE); - } + aText = GetSourceURL(aText); } rNd.InsertText(aText, rInsPos); @@ -861,9 +868,42 @@ void SwTOXAuthority::FillText(SwTextNode& rNd, const SwIndex& rInsPos, sal_uInt1 bool SwTOXAuthority::equivalent(const SwTOXSortTabBase& rCmp) { - return nType == rCmp.nType && - static_cast<SwAuthorityField*>(m_rField.GetField())->GetAuthEntry() == - static_cast<SwAuthorityField*>(static_cast<const SwTOXAuthority&>(rCmp).m_rField.GetField())->GetAuthEntry(); + if (nType != rCmp.nType) + { + return false; + } + + // Compare our SwAuthEntry and rCmp's SwAuthEntry, but the URL is considered equivalent, as long + // as it only differs in a page number, as that's still the same source. + const SwAuthEntry* pThis = static_cast<SwAuthorityField*>(m_rField.GetField())->GetAuthEntry(); + const SwAuthEntry* pOther = static_cast<SwAuthorityField*>( + static_cast<const SwTOXAuthority&>(rCmp).m_rField.GetField()) + ->GetAuthEntry(); + if (pThis == pOther) + { + return true; + } + + for (int i = 0; i < AUTH_FIELD_END; ++i) + { + auto eField = static_cast<ToxAuthorityField>(i); + if (eField == AUTH_FIELD_URL) + { + if (GetSourceURL(pThis->GetAuthorField(AUTH_FIELD_URL)) + != GetSourceURL(pOther->GetAuthorField(AUTH_FIELD_URL))) + { + return false; + } + continue; + } + + if (pThis->GetAuthorField(eField) != pOther->GetAuthorField(eField)) + { + return false; + } + } + + return true; } bool SwTOXAuthority::sort_lt(const SwTOXSortTabBase& rBase) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits