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 ) {
