sw/inc/authfld.hxx | 19 +++++- sw/qa/core/fields/fields.cxx | 4 - sw/source/core/fields/authfld.cxx | 111 ++++++++++++++++++++++++++++++------- sw/source/core/inc/txmsrt.hxx | 2 sw/source/core/tox/txmsrt.cxx | 2 sw/source/uibase/docvw/edtwin2.cxx | 11 +-- 6 files changed, 115 insertions(+), 34 deletions(-)
New commits: commit a3a151ccfbb7560f7e96523efa350b174888f359 Author: Vojtěch Doležal <[email protected]> AuthorDate: Mon Feb 13 00:51:59 2023 +0100 Commit: Mike Kaganski <[email protected]> CommitDate: Wed Feb 15 07:19:08 2023 +0000 Refactored SwAuthorityField::GetAuthority The current version takes pointer to too complex of a structure, does some insane (and completely pointless) const_casting with it, and isn't very practically usable due to only supporting calculation for format of a default TOX. This refactor solves all these issues. Change-Id: I582be2ecdbd83650c0c30ee9df786feffdc6cb99 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147000 Tested-by: Jenkins Reviewed-by: Miklos Vajna <[email protected]> Reviewed-by: Mike Kaganski <[email protected]> diff --git a/sw/inc/authfld.hxx b/sw/inc/authfld.hxx index 764aa42190b6..f708457748d9 100644 --- a/sw/inc/authfld.hxx +++ b/sw/inc/authfld.hxx @@ -19,6 +19,8 @@ #ifndef INCLUDED_SW_INC_AUTHFLD_HXX #define INCLUDED_SW_INC_AUTHFLD_HXX +#include <sal/config.h> + #include "swdllapi.h" #include "fldbas.hxx" #include "toxe.hxx" @@ -31,6 +33,7 @@ class SwTOXInternational; class SwTextAttr; +class SwForm; class SwAuthEntry final : public salhelper::SimpleReferenceObject { @@ -186,11 +189,23 @@ public: virtual OUString GetDescription() const override; - /// Returns the line matching the source's default row in the ToX. - OUString GetAuthority(const SwTextAttr* pTextAttr, const SwRootFrame* pLayout) const; + /** + * Returns the line matching the source's default row in the ToX. + * + * \param pLayout layout to be used + * \param pTOX bibliography table to take the format of the string from + * \return entry formated as the appropriate authority type in the table + */ + OUString GetAuthority(const SwRootFrame *pLayout, + const SwForm *pTOX = nullptr) const; bool HasURL() const; OUString GetAbsoluteURL() const; + /** + * Returns full URI for the URL, relative if specified + * \param bRelative whether the path should be relative (when dealing with local files) + */ + OUString GetURI(bool bRelative) const; void dumpAsXml(xmlTextWriterPtr pWriter) const override; }; diff --git a/sw/qa/core/fields/fields.cxx b/sw/qa/core/fields/fields.cxx index 6f1fd79ee582..7282d2027088 100644 --- a/sw/qa/core/fields/fields.cxx +++ b/sw/qa/core/fields/fields.cxx @@ -61,10 +61,8 @@ CPPUNIT_TEST_FIXTURE(Test, testAuthorityTooltip) auto pField = dynamic_cast<SwAuthorityField*>( SwCursorShell::GetFieldAtCursor(pCursor, /*bIncludeInputFieldAtStart=*/true)); CPPUNIT_ASSERT(pField); - SwTextNode* pTextNode = pCursor->GetPointNode().GetTextNode(); - const SwTextAttr* pTextAttr = pTextNode->GetSwpHints().Get(0); const SwRootFrame* pLayout = pWrtShell->GetLayout(); - OUString aTooltip = pField->GetAuthority(pTextAttr, pLayout); + OUString aTooltip = pField->GetAuthority(pLayout); // Without the accompanying fix in place, generating this tooltip text was not possible without // first inserting an empty bibliography table into the document. diff --git a/sw/source/core/fields/authfld.cxx b/sw/source/core/fields/authfld.cxx index 8a6212e22738..44d1e39dd3ae 100644 --- a/sw/source/core/fields/authfld.cxx +++ b/sw/source/core/fields/authfld.cxx @@ -17,14 +17,18 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <sal/config.h> + #include <memory> #include <libxml/xmlwriter.h> +#include <comphelper/processfactory.hxx> #include <comphelper/string.hxx> #include <i18nlangtag/languagetag.hxx> #include <o3tl/any.hxx> #include <o3tl/string_view.hxx> +#include <officecfg/Office/Common.hxx> #include <osl/diagnose.h> #include <tools/urlobj.hxx> #include <swtypes.hxx> @@ -47,6 +51,7 @@ #include <docsh.hxx> #include <com/sun/star/beans/PropertyValues.hpp> +#include <com/sun/star/uri/UriReferenceFactory.hpp> using namespace ::com::sun::star::uno; using namespace ::com::sun::star::beans; @@ -559,31 +564,31 @@ OUString SwAuthorityField::GetDescription() const return SwResId(STR_AUTHORITY_ENTRY); } -OUString SwAuthorityField::GetAuthority(const SwTextAttr* pTextAttr, - const SwRootFrame* pLayout) const +OUString SwAuthorityField::GetAuthority(const SwRootFrame* pLayout, const SwForm* pTOX) const { OUString aText; - SwForm aForm(TOX_AUTHORITIES); - if (!pTextAttr) + std::unique_ptr<SwForm> pDefaultTOX; + if (!pTOX) { - return aText; + pDefaultTOX = std::make_unique<SwForm>(TOX_AUTHORITIES); + pTOX = pDefaultTOX.get(); } - auto& rFormatField = const_cast<SwFormatField&>(pTextAttr->GetFormatField()); - SwTextField* pTextField = rFormatField.GetTextField(); - if (!pTextField) - { - return aText; - } - - const SwTextNode& rNode = pTextField->GetTextNode(); - const auto pFieldType = static_cast<const SwAuthorityFieldType*>(GetTyp()); + SwAuthorityFieldType* pFieldType = static_cast<SwAuthorityFieldType*>(GetTyp()); std::unique_ptr<SwTOXInternational> pIntl(pFieldType->CreateTOXInternational()); - SwTOXAuthority aAuthority(rNode, rFormatField, *pIntl); - sal_uInt16 nLevel = aAuthority.GetLevel(); - SwFormTokens aPattern = aForm.GetPattern(nLevel); - aAuthority.InitText(pLayout); + + // This is based on SwTOXAuthority::GetLevel() + OUString sText = GetFieldText(AUTH_FIELD_AUTHORITY_TYPE); + ToxAuthorityType nAuthorityKind = AUTH_TYPE_ARTICLE; + if (pIntl->IsNumeric(sText)) + nAuthorityKind = static_cast<ToxAuthorityType>(sText.toUInt32()); + if (nAuthorityKind > AUTH_TYPE_END) + nAuthorityKind = AUTH_TYPE_ARTICLE; + + // Must be incremented by 1, since the pattern 0 is for the heading + const SwFormTokens& aPattern = pTOX->GetPattern(static_cast<int>(nAuthorityKind) + 1); + for (const auto& rToken : aPattern) { switch (rToken.eTokenType) @@ -595,8 +600,30 @@ OUString SwAuthorityField::GetAuthority(const SwTextAttr* pTextAttr, } case TOKEN_AUTHORITY: { - sal_uInt16 eField = rToken.nAuthorityField; - aText += aAuthority.GetText(eField, pLayout); + ToxAuthorityField eField = static_cast<ToxAuthorityField>(rToken.nAuthorityField); + + if (AUTH_FIELD_IDENTIFIER == eField) + { + // Why isn't there a way to get the identifier without parentheses??? + OUString sTmp = ExpandField(true, pLayout); + if (sal_Unicode cPref = pFieldType->GetPrefix(); cPref && cPref != ' ') + sTmp = sTmp.copy(1); + if (sal_Unicode cSuff = pFieldType->GetSuffix(); cSuff && cSuff != ' ') + sTmp = sTmp.copy(0, sTmp.getLength() - 1); + aText += sTmp; + } + else if (AUTH_FIELD_AUTHORITY_TYPE == eField) + { + aText += SwAuthorityFieldType::GetAuthTypeName(nAuthorityKind); + } + else if (AUTH_FIELD_URL == eField) + { + aText += GetURI(true); + } + else + { + aText += GetFieldText(eField); + } break; } default: @@ -623,6 +650,50 @@ OUString SwAuthorityField::GetAbsoluteURL() const INetURLObject::DecodeMechanism::WithCharset); } +OUString SwAuthorityField::GetURI(bool bRelative) const +{ + OUString sTmp = GetFieldText(AUTH_FIELD_URL); + + SwDoc* pDoc = static_cast<SwAuthorityFieldType*>(GetTyp())->GetDoc(); + SwDocShell* pDocShell = pDoc->GetDocShell(); + const OUString aBaseURL = pDocShell->getDocumentBaseURL(); + std::u16string_view aBaseURIScheme; + sal_Int32 nSep = aBaseURL.indexOf(':'); + if (nSep != -1) + { + aBaseURIScheme = aBaseURL.subView(0, nSep); + } + + uno::Reference<uri::XUriReferenceFactory> xUriReferenceFactory + = uri::UriReferenceFactory::create(comphelper::getProcessComponentContext()); + uno::Reference<uri::XUriReference> xUriRef; + try + { + xUriRef = xUriReferenceFactory->parse(sTmp); + } + catch (const uno::Exception& rException) + { + SAL_WARN("sw.core", + "SwTOXAuthority::GetSourceURL: failed to parse url: " << rException.Message); + } + if (xUriRef.is() && xUriRef->getFragment().startsWith("page=")) + { + xUriRef->clearFragment(); + sTmp = xUriRef->getUriReference(); + } + + // If the URI is not supposed to be relative, we return here the full URI + if (!bRelative) + return sTmp; + + bool bSaveRelFSys = officecfg::Office::Common::Save::URL::FileSystem::get(); + if (xUriRef.is() && bSaveRelFSys && xUriRef->getScheme() == aBaseURIScheme) + { + sTmp = INetURLObject::GetRelURL(aBaseURL, sTmp); + } + return sTmp; +} + void SwAuthorityField::dumpAsXml(xmlTextWriterPtr pWriter) const { (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwAuthorityField")); diff --git a/sw/source/core/inc/txmsrt.hxx b/sw/source/core/inc/txmsrt.hxx index ff592655f445..018457a06e94 100644 --- a/sw/source/core/inc/txmsrt.hxx +++ b/sw/source/core/inc/txmsrt.hxx @@ -113,7 +113,7 @@ public: OUString GetFollowingText( bool bMorePages ) const; OUString ToUpper( const OUString& rStr, sal_Int32 nPos ) const; - inline bool IsNumeric( const OUString& rStr ) const; + bool IsNumeric( const OUString& rStr ) const; }; /** diff --git a/sw/source/core/tox/txmsrt.cxx b/sw/source/core/tox/txmsrt.cxx index 5205b580aaeb..de3ff3949912 100644 --- a/sw/source/core/tox/txmsrt.cxx +++ b/sw/source/core/tox/txmsrt.cxx @@ -106,7 +106,7 @@ OUString SwTOXInternational::ToUpper( const OUString& rStr, sal_Int32 nPos ) con return m_pCharClass->uppercase( rStr, nPos, 1 ); } -inline bool SwTOXInternational::IsNumeric( const OUString& rStr ) const +bool SwTOXInternational::IsNumeric( const OUString& rStr ) const { return m_pCharClass->isNumeric( rStr ); } diff --git a/sw/source/uibase/docvw/edtwin2.cxx b/sw/source/uibase/docvw/edtwin2.cxx index 3c4802b84f79..8382e542b32a 100644 --- a/sw/source/uibase/docvw/edtwin2.cxx +++ b/sw/source/uibase/docvw/edtwin2.cxx @@ -372,15 +372,12 @@ void SwEditWin::RequestHelp(const HelpEvent &rEvt) } case SwFieldIds::TableOfAuthorities: { - const auto pAuthorityField - = static_cast<const SwAuthorityField*>(pField); - sText = pAuthorityField->GetAuthority(aContentAtPos.pFndTextAttr, - rSh.GetLayout()); + const auto pAuthorityField = static_cast<const SwAuthorityField*>(pField); + sText = pAuthorityField->GetAuthority(rSh.GetLayout()); + if (pAuthorityField->HasURL()) { - const OUString& rURL - = pAuthorityField->GetAuthEntry()->GetAuthorField( - AUTH_FIELD_URL); + const OUString& rURL = pAuthorityField->GetURI(false); sText += "\n" + SfxHelp::GetURLHelpText(rURL); } break;
