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;

Reply via email to