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 <m.weghorn@posteo.de> Tested-by: Jenkins
This commit is contained in:
parent
dbb0892ad1
commit
14396a5361
6 changed files with 111 additions and 11 deletions
|
@ -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; ]
|
||||
|
|
|
@ -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; ]
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue