sw bibliography, relative URLs: switch to absolute URLs in the doc model

Interestingly at least on Linux, our click handler doesn't know how to
open "test.pdf", but "test.pdf#page=2" works. If these URLs are normal
hyperlinks (and not biblio source URLs) then both work.

It turns out the hyperlink case works because the doc model deals with
absolute URLs and only ODF import/export converts to relative ones. Do
the same for

<text:bibliography-mark text:url="...">

and that way the click handler gets an absolute URL even for "test.pdf",
which then works.

Change-Id: If8282f444d0f6e6defe4282e2753ae8b37b5b09a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114266
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
diff --git a/sw/source/ui/index/swuiidxmrk.cxx b/sw/source/ui/index/swuiidxmrk.cxx
index a8c8df6..c16eacf 100644
--- a/sw/source/ui/index/swuiidxmrk.cxx
+++ b/sw/source/ui/index/swuiidxmrk.cxx
@@ -51,8 +51,6 @@
#include <svl/cjkoptions.hxx>
#include <comphelper/fileurl.hxx>
#include <sfx2/filedlghelper.hxx>
#include <officecfg/Office/Common.hxx>
#include <tools/urlobj.hxx>
#include <ndtxt.hxx>
#include <SwRewriter.hxx>
#include <doc.hxx>
@@ -72,20 +70,6 @@ using namespace com::sun::star::lang;
using namespace com::sun::star::util;
using namespace ::comphelper;

namespace
{
/// Similar to comphelper::isFileUrl(), but handles relative URLs as well.
bool IsFileUrl(SwWrtShell& rWrtSh, const OUString& rUrl)
{
    SwDocShell* pDocShell = rWrtSh.GetDoc()->GetDocShell();
    OUString aBaseUrl = pDocShell->getDocumentBaseURL();
    OUString aAbs = INetURLObject::GetAbsURL(aBaseUrl, rUrl,
            INetURLObject::EncodeMechanism::WasEncoded,
            INetURLObject::DecodeMechanism::WithCharset);
    return comphelper::isFileUrl(aAbs);
}
}

// dialog to insert a directory selection
SwIndexMarkPane::SwIndexMarkPane(const std::shared_ptr<weld::Dialog>& rDialog, weld::Builder& rBuilder, bool bNewDlg,
    SwWrtShell* pWrtShell)
@@ -1571,7 +1555,7 @@ SwCreateAuthEntryDlg_Impl::SwCreateAuthEntryDlg_Impl(weld::Window* pParent,
            if(!pFields[aCurInfo.nToxField].isEmpty())
            {
                int nPos = pFields[aCurInfo.nToxField].toInt32();
                if (nPos == AUTH_TYPE_WWW && IsFileUrl(rWrtSh, pFields[AUTH_FIELD_URL]))
                if (nPos == AUTH_TYPE_WWW && comphelper::isFileUrl(pFields[AUTH_FIELD_URL]))
                {
                    // Map file URL to local file.
                    nPos = AUTH_TYPE_END;
@@ -1645,7 +1629,7 @@ SwCreateAuthEntryDlg_Impl::SwCreateAuthEntryDlg_Impl(weld::Window* pParent,
                }
            }
            else if (aCurInfo.nToxField == AUTH_FIELD_URL
                     && IsFileUrl(rWrtSh, pFields[aCurInfo.nToxField]))
                     && comphelper::isFileUrl(pFields[aCurInfo.nToxField]))
            {
                m_xBrowseButton->show();
            }
@@ -1751,18 +1735,8 @@ IMPL_LINK_NOARG(SwCreateAuthEntryDlg_Impl, BrowseHdl, weld::Button&, void)
    sfx2::FileDialogHelper aFileDlg(ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE,
                                    FileDialogFlags::NONE, getDialog());
    OUString aPath = GetEntryText(AUTH_FIELD_URL);
    bool bSaveRelFSys = officecfg::Office::Common::Save::URL::FileSystem::get();
    if (!aPath.isEmpty())
    {
        if (bSaveRelFSys && !IsFileUrl(rWrtSh, aPath))
        {
            SwDocShell* pDocShell = rWrtSh.GetDoc()->GetDocShell();
            OUString aBasePath = pDocShell->getDocumentBaseURL();
            aPath = INetURLObject::GetAbsURL(aBasePath, aPath,
                                             INetURLObject::EncodeMechanism::WasEncoded,
                                             INetURLObject::DecodeMechanism::WithCharset);
        }

        aFileDlg.SetDisplayDirectory(aPath);
    }

@@ -1772,14 +1746,6 @@ IMPL_LINK_NOARG(SwCreateAuthEntryDlg_Impl, BrowseHdl, weld::Button&, void)
    }

    aPath = aFileDlg.GetPath();
    if (bSaveRelFSys)
    {
        SwDocShell* pDocShell = rWrtSh.GetDoc()->GetDocShell();
        OUString aBasePath = pDocShell->getDocumentBaseURL();
        aPath
            = INetURLObject::GetRelURL(aBasePath, aPath, INetURLObject::EncodeMechanism::WasEncoded,
                                       INetURLObject::DecodeMechanism::WithCharset);
    }

    for (int nIndex = 0; nIndex < AUTH_FIELD_END; nIndex++)
    {
diff --git a/xmloff/source/text/txtflde.cxx b/xmloff/source/text/txtflde.cxx
index 50d072b..111df2f 100644
--- a/xmloff/source/text/txtflde.cxx
+++ b/xmloff/source/text/txtflde.cxx
@@ -2731,8 +2731,13 @@ void XMLTextFieldExport::ProcessBibliographyData(

            if (!sStr.isEmpty())
            {
                XMLTokenEnum eElement = MapBibliographyFieldName(rProp.Name);
                if (eElement == XML_URL)
                {
                    sStr = GetExport().GetRelativeReference(sStr);
                }
                rExport.AddAttribute(XML_NAMESPACE_TEXT,
                                     MapBibliographyFieldName(rProp.Name),
                                     eElement,
                                     sStr);
            }
        }
diff --git a/xmloff/source/text/txtfldi.cxx b/xmloff/source/text/txtfldi.cxx
index 3e8e660..b3ab45c 100644
--- a/xmloff/source/text/txtfldi.cxx
+++ b/xmloff/source/text/txtfldi.cxx
@@ -2974,7 +2974,12 @@ void XMLBibliographyFieldImportContext::startFastElement(
            }
            else
            {
                aAny <<= aIter.toString();
                OUString aStringValue = aIter.toString();
                if (nToken == XML_URL)
                {
                    aStringValue = GetImport().GetAbsoluteReference(aStringValue);
                }
                aAny <<= aStringValue;
                aValue.Value = aAny;

                aValues.push_back(aValue);