sw/qa/core/txtnode/txtnode.cxx | 27 +++++++++++++++++++++ sw/source/core/txtnode/attrcontentcontrol.cxx | 5 ++++ sw/source/uibase/docvw/edtwin.cxx | 32 ++++++++++++++++++++++++++ 3 files changed, 64 insertions(+)
New commits: commit fe072bf9e52ab4c0bd7b692940092ca296edfe59 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Mon Jul 18 11:18:28 2022 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Mon Jul 18 15:22:59 2022 +0200 sw content control, picture: allow replacing via the keyboard It was not possible to replace a picture placeholder with an actual bitmap without using the mouse, which breaks accessibility. The mouse handling code was added in commit b213abcb77e19fa5d22af45c7ecd17c8a63af554 (sw content controls, picture: replace placeholder image on click, 2022-05-18), which already split the functionality between SwEditWin::MouseButtonUp() and SwWrtShell::GotoContentControl(). Fix the problem by reusing the shared SwWrtShell::GotoContentControl() and extending SwEditWin::KeyInput() to allow doing the same with the keyboard. This way the scenario when Shift-F4 selects the frame and the user presses Enter now triggers the filepicker. A possible future improvement would be to also handle Enter similarly when the text cursor is inside a picture content control, but that's not implemented here. (cherry picked from commit aaebfb9baf53e4ed221a9bb8e1772fcbb7b921ab) Change-Id: I756395d3811e3f4dfdce698751c4de13a0d49729 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137197 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/sw/qa/core/txtnode/txtnode.cxx b/sw/qa/core/txtnode/txtnode.cxx index 7791cf82bbc3..15d2188a8cb6 100644 --- a/sw/qa/core/txtnode/txtnode.cxx +++ b/sw/qa/core/txtnode/txtnode.cxx @@ -270,6 +270,33 @@ CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, testDropdownContentControlKeyboard) CPPUNIT_ASSERT(bShouldOpen); } +CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, testPicutreContentControlKeyboard) +{ + // Given an already selected picture content control: + SwDoc* pDoc = createSwDoc(); + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + pWrtShell->InsertContentControl(SwContentControlType::PICTURE); + pWrtShell->GotoObj(/*bNext=*/true, GotoObjFlags::Any); + + // When checking if enter should trigger the file picker: + const SwFrameFormat* pFlyFormat = pWrtShell->GetFlyFrameFormat(); + const SwFormatAnchor& rFormatAnchor = pFlyFormat->GetAnchor(); + const SwPosition* pAnchorPos = rFormatAnchor.GetContentAnchor(); + SwTextNode* pTextNode = pAnchorPos->nNode.GetNode().GetTextNode(); + SwTextAttr* pAttr = pTextNode->GetTextAttrAt(pAnchorPos->nContent.GetIndex(), + RES_TXTATR_CONTENTCONTROL, SwTextNode::PARENT); + auto pTextContentControl = static_txtattr_cast<SwTextContentControl*>(pAttr); + auto& rFormatContentControl + = static_cast<SwFormatContentControl&>(pTextContentControl->GetAttr()); + std::shared_ptr<SwContentControl> pContentControl = rFormatContentControl.GetContentControl(); + bool bIsInteracting = pContentControl->IsInteractingCharacter('\r'); + + // Then make sure that the answer is yes for pictures: + // Without the accompanying fix in place, this test would have failed, the picture replacement + // file-picker was mouse-only. + CPPUNIT_ASSERT(bIsInteracting); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/txtnode/attrcontentcontrol.cxx b/sw/source/core/txtnode/attrcontentcontrol.cxx index 2f4552f2f758..c917de926296 100644 --- a/sw/source/core/txtnode/attrcontentcontrol.cxx +++ b/sw/source/core/txtnode/attrcontentcontrol.cxx @@ -309,6 +309,11 @@ bool SwContentControl::IsInteractingCharacter(sal_Unicode cCh) return cCh == ' '; } + if (GetPicture()) + { + return cCh == '\r'; + } + return false; } diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx index c765e3b42d7e..bca062c9bcc6 100644 --- a/sw/source/uibase/docvw/edtwin.cxx +++ b/sw/source/uibase/docvw/edtwin.cxx @@ -1540,6 +1540,38 @@ void SwEditWin::KeyInput(const KeyEvent &rKEvt) } const SwFrameFormat* pFlyFormat = rSh.GetFlyFrameFormat(); + + if (pFlyFormat) + { + // See if the fly frame's anchor is in a content control. If so, + // try to interact with it. + const SwFormatAnchor& rFormatAnchor = pFlyFormat->GetAnchor(); + const SwPosition* pAnchorPos = rFormatAnchor.GetContentAnchor(); + if (pAnchorPos) + { + SwTextNode* pTextNode = pAnchorPos->nNode.GetNode().GetTextNode(); + if (pTextNode) + { + SwTextAttr* pAttr = pTextNode->GetTextAttrAt( + pAnchorPos->nContent.GetIndex(), RES_TXTATR_CONTENTCONTROL, SwTextNode::PARENT); + if (pAttr) + { + SwTextContentControl* pTextContentControl + = static_txtattr_cast<SwTextContentControl*>(pAttr); + const SwFormatContentControl& rFormatContentControl + = pTextContentControl->GetContentControl(); + std::shared_ptr<SwContentControl> pContentControl + = rFormatContentControl.GetContentControl(); + if (pContentControl->IsInteractingCharacter(aCh)) + { + rSh.GotoContentControl(rFormatContentControl); + return; + } + } + } + } + } + if( pFlyFormat ) { SvMacroItemId nEvent;