ScGlobal::OpenURL: support relative references as URI references in hyperlinks
authorEike Rathke <erack@redhat.com>
Wed, 11 Jul 2018 13:44:18 +0000 (15:44 +0200)
committerBastien Roucariès <rouca@debian.org>
Fri, 29 Dec 2023 09:39:36 +0000 (09:39 +0000)
Instead of failing with "is not an absolute URL" error.

For example in the HYPERLINK() spreadsheet function where Excel
supports it, but also anywhere else that calls OpenURL(). A
relative reference is relative to the current document, or for yet
unsaved documents or if no object shell is available relative to
the work path, as usual.

Additional benefit is that "\\" UNC path names are accepted as
smb:// Samba shares and DOS \ path name separators resolved for a
proper file:// URI.

Users are asking for this, found no related tdf# bug/RFE. See
https://ask.libreoffice.org/en/question/160280/relative-and-absolute-hyperlinks/
and other linked q&a therein.

Change-Id: Ib314b71d68fbe1793ec614cbf7c0c058fad14a10
Reviewed-on: https://gerrit.libreoffice.org/57277
Reviewed-by: Eike Rathke <erack@redhat.com>
Tested-by: Jenkins
Gbp-Pq: Name 0087-ScGlobal-OpenURL-support-relative-references-as-URI-.patch

sc/source/core/data/global.cxx

index 2b703392b89889b9788fc444cf7858d514003fea..480eb1cea43e637f9edeafecc9946cc3534f94f2 100644 (file)
@@ -829,17 +829,36 @@ void ScGlobal::OpenURL(const OUString& rURL, const OUString& rTarget)
     if (!pViewFrm)
         return;
 
+    OUString aUrlName( rURL );
     SfxViewFrame* pFrame = nullptr;
+    const SfxObjectShell* pObjShell = nullptr;
     OUString aReferName;
     if ( pScActiveViewShell )
     {
         pFrame = pScActiveViewShell->GetViewFrame();
-        SfxMedium* pMed = pFrame->GetObjectShell()->GetMedium();
+        pObjShell = pFrame->GetObjectShell();
+        const SfxMedium* pMed = pObjShell->GetMedium();
         if (pMed)
             aReferName = pMed->GetName();
     }
 
-    SfxStringItem aUrl( SID_FILE_NAME, rURL );
+    // Don't fiddle with fragments pointing into current document.
+    if (!aUrlName.startsWith("#"))
+    {
+        // Any relative reference would fail with "not an absolute URL"
+        // error, try to construct an absolute URI with the path relative
+        // to the current document's path or work path, as usual for all
+        // external references.
+        // This then also, as ScGlobal::GetAbsDocName() uses
+        // INetURLObject::smartRel2Abs(), supports "\\" UNC path names as
+        // smb:// Samba shares and DOS path separators converted to proper
+        // file:// URI.
+        const OUString aNewUrlName( ScGlobal::GetAbsDocName( aUrlName, pObjShell));
+        if (!aNewUrlName.isEmpty())
+            aUrlName = aNewUrlName;
+    }
+
+    SfxStringItem aUrl( SID_FILE_NAME, aUrlName );
     SfxStringItem aTarget( SID_TARGETNAME, rTarget );
     if ( nScClickMouseModifier & KEY_SHIFT )     // control-click -> into new window
         aTarget.SetValue("_blank");