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;

Reply via email to