sw/inc/authfld.hxx | 2 + sw/qa/core/tox/tox.cxx | 46 +++++++++++++++++++++++++++++++++++++ sw/source/core/fields/authfld.cxx | 9 +++++-- sw/source/core/fields/fldbas.cxx | 9 +++++++ sw/source/uibase/docvw/edtwin.cxx | 2 - sw/source/uibase/docvw/edtwin2.cxx | 7 +++++ sw/source/uibase/inc/wrtsh.hxx | 2 - sw/source/uibase/shells/basesh.cxx | 2 - sw/source/uibase/wrtsh/wrtsh2.cxx | 21 ++++++++++++++++ 9 files changed, 94 insertions(+), 6 deletions(-)
New commits: commit 64ffabbdb2725e93de997171708bb31c33c93a55 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Fri Mar 12 17:51:07 2021 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Fri Mar 12 19:32:19 2021 +0100 sw bibliography, refer to a page: make the biblio field clickable - add support for this in SwWrtShell::ClickToField() - restrict this to ctrl-click by default (similar to hyperlinks) - ignore empty URLs - extend the tooltip to hint the URL - change pointer to hint that the field is clickable - downgrade the assert to SAL_WARN in SwAuthorityFieldType::RemoveField(), that currently fires every time a biblio field is de-selected Change-Id: I3b4a12d8a7661f7d8d41804f104505c7594debd6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112400 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins diff --git a/sw/inc/authfld.hxx b/sw/inc/authfld.hxx index cdfcf7f9f55a..c9c7fd880b7b 100644 --- a/sw/inc/authfld.hxx +++ b/sw/inc/authfld.hxx @@ -185,6 +185,8 @@ public: /// Returns the line matching the source's default row in the ToX. OUString GetAuthority(const SwTextAttr* pTextAttr, const SwRootFrame* pLayout) const; + bool HasURL() const; + void dumpAsXml(xmlTextWriterPtr pWriter) const override; }; diff --git a/sw/qa/core/tox/tox.cxx b/sw/qa/core/tox/tox.cxx index 127cb4b06e7f..0862b6403638 100644 --- a/sw/qa/core/tox/tox.cxx +++ b/sw/qa/core/tox/tox.cxx @@ -16,6 +16,9 @@ #include <comphelper/propertyvalue.hxx> +#include <IDocumentFieldsAccess.hxx> +#include <fmtfld.hxx> + namespace { /// Covers sw/source/core/tox/ fixes. @@ -108,6 +111,49 @@ CPPUNIT_TEST_FIXTURE(Test, testAuthorityTableEntryURL) CPPUNIT_ASSERT_EQUAL(OUString("http://www.example.com/test.pdf"), aActual); } +CPPUNIT_TEST_FIXTURE(Test, testAuthorityTableEntryClick) +{ + // Given an empty document: + SwDoc* pDoc = createSwDoc(); + + // When inserting a biblio entry field with an 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("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); + + // Then make sure that the field is clickable, since the page part will not be part of the + // bibliography table: + 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()); + SwField* pField = aFormatFields[0]->GetField(); + // Without the accompanying fix in place, this test would have failed, as the field was not + // clickable. + CPPUNIT_ASSERT(pField->IsClickable()); + // This is needed, so the mouse has the correct RefHand pointer style. + CPPUNIT_ASSERT(pField->HasClickHdl()); +} + 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 ad60d02db173..8812d70d2db6 100644 --- a/sw/source/core/fields/authfld.cxx +++ b/sw/source/core/fields/authfld.cxx @@ -99,8 +99,7 @@ void SwAuthorityFieldType::RemoveField(const SwAuthEntry* pEntry) return; } } - assert(false); - OSL_FAIL("Field unknown" ); + SAL_WARN("sw.core", "SwAuthorityFieldType::RemoveField: pEntry is not my field"); } SwAuthEntry* SwAuthorityFieldType::AddField(const OUString& rFieldContents) @@ -605,6 +604,12 @@ OUString SwAuthorityField::GetAuthority(const SwTextAttr* pTextAttr, return aText; } +bool SwAuthorityField::HasURL() const +{ + const OUString& rURL = GetAuthEntry()->GetAuthorField(AUTH_FIELD_URL); + return !rURL.isEmpty(); +} + void SwAuthorityField::dumpAsXml(xmlTextWriterPtr pWriter) const { xmlTextWriterStartElement(pWriter, BAD_CAST("SwAuthorityField")); diff --git a/sw/source/core/fields/fldbas.cxx b/sw/source/core/fields/fldbas.cxx index 26588ea50199..b942dd47726c 100644 --- a/sw/source/core/fields/fldbas.cxx +++ b/sw/source/core/fields/fldbas.cxx @@ -405,6 +405,14 @@ bool SwField::HasClickHdl() const case SwFieldIds::SetExp: bRet = static_cast<const SwSetExpField*>(this)->GetInputFlag(); break; + + case SwFieldIds::TableOfAuthorities: + { + const auto pAuthorityField = static_cast<const SwAuthorityField*>(this); + bRet = pAuthorityField->HasURL(); + break; + } + default: break; } return bRet; @@ -814,6 +822,7 @@ bool SwField::IsClickable() const case SwFieldIds::Input: case SwFieldIds::SetExp: case SwFieldIds::Dropdown: + case SwFieldIds::TableOfAuthorities: return true; default: break; } diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx index 1f95f9bdea31..93560ec91f3b 100644 --- a/sw/source/uibase/docvw/edtwin.cxx +++ b/sw/source/uibase/docvw/edtwin.cxx @@ -4809,7 +4809,7 @@ void SwEditWin::MouseButtonUp(const MouseEvent& rMEvt) } else { - rSh.ClickToField( *aContentAtPos.aFnd.pField ); + rSh.ClickToField(*aContentAtPos.aFnd.pField, bExecHyperlinks); // a bit of a mystery what this is good for? // in this case we assume it's valid since we // just selected a field diff --git a/sw/source/uibase/docvw/edtwin2.cxx b/sw/source/uibase/docvw/edtwin2.cxx index 645878cd855f..c3af8bd54149 100644 --- a/sw/source/uibase/docvw/edtwin2.cxx +++ b/sw/source/uibase/docvw/edtwin2.cxx @@ -347,6 +347,13 @@ void SwEditWin::RequestHelp(const HelpEvent &rEvt) = static_cast<const SwAuthorityField*>(pField); sText = pAuthorityField->GetAuthority(aContentAtPos.pFndTextAttr, rSh.GetLayout()); + if (pAuthorityField->HasURL()) + { + const OUString& rURL + = pAuthorityField->GetAuthEntry()->GetAuthorField( + AUTH_FIELD_URL); + sText += "\n" + SfxHelp::GetURLHelpText(rURL); + } break; } diff --git a/sw/source/uibase/inc/wrtsh.hxx b/sw/source/uibase/inc/wrtsh.hxx index cd50a2f3f7a9..67b626dc70bc 100644 --- a/sw/source/uibase/inc/wrtsh.hxx +++ b/sw/source/uibase/inc/wrtsh.hxx @@ -437,7 +437,7 @@ typedef bool (SwWrtShell::*FNSimpleMove)(); // a click at the given field. the cursor is on it. // execute the predefined actions. - void ClickToField( const SwField& rField ); + void ClickToField( const SwField& rField, bool bExecHyperlinks ); void ClickToINetAttr( const SwFormatINetFormat& rItem, LoadUrlFlags nFilter = LoadUrlFlags::NONE ); bool ClickToINetGrf( const Point& rDocPt, LoadUrlFlags nFilter ); inline bool IsInClickToEdit() const ; diff --git a/sw/source/uibase/shells/basesh.cxx b/sw/source/uibase/shells/basesh.cxx index 4ec9dccd3113..c91fab016851 100644 --- a/sw/source/uibase/shells/basesh.cxx +++ b/sw/source/uibase/shells/basesh.cxx @@ -773,7 +773,7 @@ void SwBaseShell::Execute(SfxRequest &rReq) bool bRet = rSh.MoveFieldType( pFieldType, nSlot == FN_GOTO_NEXT_MARK ); SwField* pCurField = bRet ? rSh.GetCurField() : nullptr; if (pCurField) - rSh.ClickToField(*pCurField); + rSh.ClickToField(*pCurField, /*bExecHyperlinks=*/false); rReq.SetReturnValue(SfxBoolItem( nSlot, bRet)); } } diff --git a/sw/source/uibase/wrtsh/wrtsh2.cxx b/sw/source/uibase/wrtsh/wrtsh2.cxx index c179383bd28a..cbda31185fed 100644 --- a/sw/source/uibase/wrtsh/wrtsh2.cxx +++ b/sw/source/uibase/wrtsh/wrtsh2.cxx @@ -46,6 +46,7 @@ #include <cmdid.h> #include <swabstdlg.hxx> #include <SwRewriter.hxx> +#include <authfld.hxx> #include <com/sun/star/document/XDocumentProperties.hpp> #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> @@ -334,7 +335,7 @@ void SwWrtShell::UpdateTableOf(const SwTOXBase& rTOX, const SfxItemSet* pSet) // handler for click on the field given as parameter. // the cursor is positioned on the field. -void SwWrtShell::ClickToField( const SwField& rField ) +void SwWrtShell::ClickToField(const SwField& rField, bool bExecHyperlinks) { // cross reference field must not be selected because it moves the cursor if (SwFieldIds::GetRef != rField.GetTyp()->Which()) @@ -396,6 +397,24 @@ void SwWrtShell::ClickToField( const SwField& rField ) } break; + case SwFieldIds::TableOfAuthorities: + { + if (!bExecHyperlinks) + { + break; + } + + auto pField = static_cast<const SwAuthorityField*>(&rField); + if (!pField->HasURL()) + { + break; + } + + const OUString& rURL = pField->GetAuthEntry()->GetAuthorField(AUTH_FIELD_URL); + ::LoadURL(*this, rURL, LoadUrlFlags::NewView, /*rTargetFrameName=*/OUString()); + } + break; + case SwFieldIds::GetRef: StartAllAction(); SwCursorShell::GotoRefMark( static_cast<const SwGetRefField&>(rField).GetSetRefName(), _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits