sc/sdi/docsh.sdi                 |    1 
 sc/sdi/editsh.sdi                |    1 
 sc/source/ui/docshell/docsh4.cxx |   48 +++++++++++++++++++++++++++++++++++
 sc/source/ui/inc/gridwin.hxx     |    9 ++++++
 sc/source/ui/view/editsh.cxx     |   10 -------
 sc/source/ui/view/gridwin.cxx    |   53 +++++++++++++++++++++++++++++++++++++++
 6 files changed, 111 insertions(+), 11 deletions(-)

New commits:
commit 14396a5361ef72afc99033d4cac29aaeb1ffa2d8
Author:     Sahil Gautam <[email protected]>
AuthorDate: Sun Mar 24 00:48:22 2024 +0530
Commit:     Michael Weghorn <[email protected]>
CommitDate: Thu Mar 28 21:41:51 2024 +0100

    tdf#123159 Make Hyperlinks keyboard accessible
    
    Extend .uno:OpenHyperlinkOnCursor to open all hyperlinks
    in a cell, when not in edit mode.
    
    The UNO command can be assigned to a keyboard shortcut from
    `Tools > Customize > Keyboard`. If the active cell is not in
    edit mode, then pressing the shortcut opens all the hyperlinks
    in the cell. If in edit mode, pressing the shortcut opens the
    hyperlink under the caret "|".
    
    Change-Id: I7ffdab54fa31b9f7f614e04cc3158d8be217825e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157666
    Reviewed-by: Michael Weghorn <[email protected]>
    Tested-by: Jenkins

diff --git a/sc/sdi/docsh.sdi b/sc/sdi/docsh.sdi
index b4a8a04326d8..380ddb08e620 100644
--- a/sc/sdi/docsh.sdi
+++ b/sc/sdi/docsh.sdi
@@ -58,6 +58,7 @@ interface TableDocument
     SID_CHART_ADDSOURCE [ ExecMethod = Execute; ]
     FID_AUTO_CALC   [ ExecMethod = Execute; StateMethod = GetState; ]
     FID_RECALC      [ ExecMethod = Execute; StateMethod = GetState; ]
+    SID_OPEN_HYPERLINK    [ ExecMethod = Execute; StateMethod = GetState; ]
     FID_HARD_RECALC [ ExecMethod = Execute; StateMethod = GetState; ]
     SID_UPDATETABLINKS      [ ExecMethod = Execute; ]
     SID_REIMPORT_AFTER_LOAD [ ExecMethod = Execute; ]
diff --git a/sc/sdi/editsh.sdi b/sc/sdi/editsh.sdi
index 3dd0219948ab..5dd18e81f3a4 100644
--- a/sc/sdi/editsh.sdi
+++ b/sc/sdi/editsh.sdi
@@ -74,7 +74,6 @@ interface TableText
 
     SID_HYPERLINK_SETLINK   [ ExecMethod = Execute; ]
     SID_HYPERLINK_GETLINK   [ StateMethod = GetState; ]
-    SID_OPEN_HYPERLINK      [ ExecMethod = Execute; StateMethod = GetState; ]
     SID_EDIT_HYPERLINK      [ ExecMethod = Execute; StateMethod = GetState; ]
     SID_COPY_HYPERLINK_LOCATION [ ExecMethod = Execute; StateMethod = 
GetState; ]
     SID_REMOVE_HYPERLINK      [ ExecMethod = Execute; StateMethod = GetState; ]
diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx
index 741d60cd5c47..0348ce5174be 100644
--- a/sc/source/ui/docshell/docsh4.cxx
+++ b/sc/source/ui/docshell/docsh4.cxx
@@ -401,6 +401,54 @@ void ScDocShell::Execute( SfxRequest& rReq )
                 rReq.Done();
             }
             break;
+        case SID_OPEN_HYPERLINK:
+            {
+                ScViewData* pViewData = GetViewData();
+                if ( !pViewData )
+                {
+                    rReq.Ignore();
+                    break;
+                }
+
+                if (SC_MOD()->IsEditMode())
+                {
+                    if (EditView* pEditView = 
pViewData->GetEditView(pViewData->GetActivePart()))
+                    {
+                        const SvxFieldItem* pFieldItem = 
pEditView->GetFieldAtSelection(/*bAlsoCheckBeforeCursor=*/true);
+                        const SvxFieldData* pField = pFieldItem ? 
pFieldItem->GetField() : nullptr;
+                        if (const SvxURLField* pURLField = dynamic_cast<const 
SvxURLField*>(pField))
+                        {
+                            ScGlobal::OpenURL(pURLField->GetURL(), 
pURLField->GetTargetFrame(), true);
+                            rReq.Done();
+                            break;
+                        }
+                    }
+                    rReq.Ignore();
+                    break;
+                }
+
+                ScGridWindow* pWin = pViewData->GetActiveWin();
+                if ( !pWin )
+                {
+                    rReq.Ignore();
+                    break;
+                }
+
+                ScAddress aCell {pViewData->GetCurPos()};
+                std::vector<UrlData> vUrls = pWin->GetEditUrls(aCell);
+                if (vUrls.empty())
+                {
+                    rReq.Ignore();
+                    break;
+                }
+
+                for (UrlData& data : vUrls)
+                {
+                    ScGlobal::OpenURL(data.aUrl, data.aTarget, true);
+                }
+                rReq.Done();
+            }
+            break;
         case FID_RECALC:
             DoRecalc( rReq.IsAPI() );
             rReq.Done();
diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx
index 9e91409f514c..5c548e5af824 100644
--- a/sc/source/ui/inc/gridwin.hxx
+++ b/sc/source/ui/inc/gridwin.hxx
@@ -81,6 +81,13 @@ class ScLokRTLContext;
 #define SC_PD_BREAK_H       16
 #define SC_PD_BREAK_V       32
 
+struct UrlData
+{
+    OUString aName;
+    OUString aUrl;
+    OUString aTarget;
+};
+
 // predefines
 namespace sdr::overlay { class OverlayObjectList; }
 
@@ -509,6 +516,8 @@ public:
 
     void initiatePageBreaks();
 
+    std::vector<UrlData> GetEditUrls(const ScAddress& rSelectedCell);
+
 protected:
     void ImpCreateOverlayObjects();
     void ImpDestroyOverlayObjects();
diff --git a/sc/source/ui/view/editsh.cxx b/sc/source/ui/view/editsh.cxx
index 80b11d0b9e4c..6058a6be2f17 100644
--- a/sc/source/ui/view/editsh.cxx
+++ b/sc/source/ui/view/editsh.cxx
@@ -639,15 +639,6 @@ void ScEditShell::Execute( SfxRequest& rReq )
                 }
             }
             break;
-        case SID_OPEN_HYPERLINK:
-            {
-                const SvxFieldItem* pFieldItem
-                    = 
pEditView->GetFieldAtSelection(/*AlsoCheckBeforeCursor=*/true);
-                const SvxFieldData* pField = pFieldItem ? 
pFieldItem->GetField() : nullptr;
-                if (const SvxURLField* pURLField = dynamic_cast<const 
SvxURLField*>(pField))
-                    ScGlobal::OpenURL( pURLField->GetURL(), 
pURLField->GetTargetFrame(), true );
-                return;
-            }
         case SID_EDIT_HYPERLINK:
             {
                 // Ensure the field is selected first
@@ -832,7 +823,6 @@ void ScEditShell::GetState( SfxItemSet& rSet )
                 }
                 break;
 
-            case SID_OPEN_HYPERLINK:
             case SID_EDIT_HYPERLINK:
             case SID_COPY_HYPERLINK_LOCATION:
             case SID_REMOVE_HYPERLINK:
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index 07d2d3a71b63..541642241eb4 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -5798,6 +5798,59 @@ static void lcl_SetEngineTextKeepingDefaults(const 
std::shared_ptr<ScFieldEditEn
     }
 }
 
+static std::vector<std::unique_ptr<SvxFieldItem>> 
lcl_GetEditEngineFields(std::shared_ptr<ScFieldEditEngine> pEditEngine)
+{
+    std::vector<std::unique_ptr<SvxFieldItem>> vFieldVect;
+
+    sal_Int32 nPara = pEditEngine->GetParagraphCount();
+    for (sal_Int32 nCurrPara = 0; nCurrPara < nPara; ++nCurrPara)
+    {
+        sal_Int16 nField = pEditEngine->GetFieldCount(nCurrPara);
+        for (sal_Int16 nCurrField = 0; nCurrField < nField; ++nCurrField)
+        {
+            EFieldInfo aFieldInfo = pEditEngine->GetFieldInfo(nCurrPara, 
nCurrField);
+            vFieldVect.push_back(std::move(aFieldInfo.pFieldItem));
+        }
+    }
+    return vFieldVect;
+}
+
+
+std::vector<UrlData> ScGridWindow::GetEditUrls(const ScAddress& rSelectedCell)
+{
+    ScDocShell* pDocSh = mrViewData.GetDocShell();
+    ScDocument& rDoc = pDocSh->GetDocument();
+
+    SCCOL nPosX = rSelectedCell.Col();
+    SCROW nPosY = rSelectedCell.Row();
+    SCTAB nTab  = rSelectedCell.Tab();
+
+    OUString sURL;
+    ScRefCellValue aCell;
+    std::vector<UrlData> vUrls;
+    if (!lcl_GetHyperlinkCell(rDoc, nPosX, nPosY, nTab, aCell, sURL))
+        return vUrls;
+
+    if (nPosX != rSelectedCell.Col())
+        return vUrls;
+
+    const ScPatternAttr* pPattern = rDoc.GetPattern( nPosX, nPosY, nTab );
+
+    std::shared_ptr<ScFieldEditEngine> pEngine = createEditEngine(pDocSh, 
*pPattern);
+
+    lcl_SetEngineTextKeepingDefaults(pEngine, rDoc, aCell, sURL);
+
+    std::vector<std::unique_ptr<SvxFieldItem>> vFieldItems = 
lcl_GetEditEngineFields(pEngine);
+    for (auto& pFieldItem : vFieldItems)
+    {
+        UrlData aData;
+        bool bIsUrl = extractURLInfo(pFieldItem.get(), &aData.aName, 
&aData.aUrl, &aData.aTarget);
+        if (bIsUrl && !aData.aUrl.isEmpty())
+            vUrls.push_back(aData);
+    }
+    return vUrls;
+}
+
 bool ScGridWindow::GetEditUrl( const Point& rPos,
                                OUString* pName, OUString* pUrl, OUString* 
pTarget )
 {

Reply via email to