summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2022-07-14 15:52:37 +0200
committerMiklos Vajna <vmiklos@collabora.com>2022-07-14 19:05:27 +0200
commitc6eb8713438d1ba791fc858c8dc6e3d4d6583e0a (patch)
treef8aed8e3aa28e351ee1dea5d69416e0a79a10e1c
parentbcb1620b3e4929df1d06d57b4769650422fff16e (diff)
sw content control, checkbox: allow toggling via the keyboard
Toggling a checkbox content control was only possible by clicking on it with the mouse, which breaks accessiblity. Trying to type into a checkbox content control triggered the read-only popup (which is good), but there was no special handling for the space character, which is meant to toggle the checkbox. Fix the problem by adding a way to query if the current keycode is meant to interact with the content control, and if so, invoke GotoContentControl() from SwEditWin::KeyInput(), similar to how the click handler already did this already. This only handles checkboxes, but other types can be addressed in a follow-up commits similarly. Change-Id: I5c88f2e2f1c2d0f4b28f2ce0b6b1c75b14b7d67c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137082 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
-rw-r--r--sw/inc/formatcontentcontrol.hxx3
-rw-r--r--sw/qa/core/txtnode/txtnode.cxx29
-rw-r--r--sw/source/core/txtnode/attrcontentcontrol.cxx10
-rw-r--r--sw/source/uibase/docvw/edtwin.cxx23
4 files changed, 65 insertions, 0 deletions
diff --git a/sw/inc/formatcontentcontrol.hxx b/sw/inc/formatcontentcontrol.hxx
index 82f4fca9e2be..839a7919ee6b 100644
--- a/sw/inc/formatcontentcontrol.hxx
+++ b/sw/inc/formatcontentcontrol.hxx
@@ -272,6 +272,9 @@ public:
std::optional<double> GetSelectedDate() const { return m_oSelectedDate; }
+ /// Should this character (during key input) interact with the content control?
+ bool IsInteractingCharacter(sal_Unicode cCh);
+
void dumpAsXml(xmlTextWriterPtr pWriter) const;
void SetDataBindingPrefixMappings(const OUString& rDataBindingPrefixMappings)
diff --git a/sw/qa/core/txtnode/txtnode.cxx b/sw/qa/core/txtnode/txtnode.cxx
index ad44a12f7c9b..55fece606c4c 100644
--- a/sw/qa/core/txtnode/txtnode.cxx
+++ b/sw/qa/core/txtnode/txtnode.cxx
@@ -25,6 +25,11 @@
#include <unotxdoc.hxx>
#include <docsh.hxx>
#include <formatcontentcontrol.hxx>
+#include <view.hxx>
+#include <edtwin.hxx>
+#include <txatbase.hxx>
+#include <ndtxt.hxx>
+#include <textcontentcontrol.hxx>
constexpr OUStringLiteral DATA_DIRECTORY = u"/sw/qa/core/txtnode/data/";
@@ -220,6 +225,30 @@ CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, testInsertDropDownContentControlTwice)
pWrtShell->InsertContentControl(SwContentControlType::DROP_DOWN_LIST);
}
+CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, testCheckboxContentControlKeyboard)
+{
+ // Given an already selected checkbox content control:
+ SwDoc* pDoc = createSwDoc();
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ pWrtShell->InsertContentControl(SwContentControlType::CHECKBOX);
+ SwEditWin& rEditWin = pWrtShell->GetView().GetEditWin();
+
+ // When pressing space on the keyboard:
+ KeyEvent aKeyEvent(' ', KEY_SPACE);
+ rEditWin.KeyInput(aKeyEvent);
+
+ // Then make sure the state is toggled:
+ SwTextNode* pTextNode = pWrtShell->GetCursor()->GetNode().GetTextNode();
+ SwTextAttr* pAttr = pTextNode->GetTextAttrForCharAt(0, RES_TXTATR_CONTENTCONTROL);
+ auto pTextContentControl = static_txtattr_cast<SwTextContentControl*>(pAttr);
+ auto& rFormatContentControl
+ = static_cast<SwFormatContentControl&>(pTextContentControl->GetAttr());
+ std::shared_ptr<SwContentControl> pContentControl = rFormatContentControl.GetContentControl();
+ // Without the accompanying fix in place, this test would have failed, because the state
+ // remained unchanged.
+ CPPUNIT_ASSERT(pContentControl->GetChecked());
+}
+
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 4b5ff4554f15..1f3d26f6c2b6 100644
--- a/sw/source/core/txtnode/attrcontentcontrol.cxx
+++ b/sw/source/core/txtnode/attrcontentcontrol.cxx
@@ -301,6 +301,16 @@ double SwContentControl::GetCurrentDateValue() const
return dCurrentDate;
}
+bool SwContentControl::IsInteractingCharacter(sal_Unicode cCh)
+{
+ if (GetCheckbox())
+ {
+ return cCh == ' ';
+ }
+
+ return false;
+}
+
void SwContentControl::dumpAsXml(xmlTextWriterPtr pWriter) const
{
(void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwContentControl"));
diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx
index 420da9d0b295..b81ac632a0e5 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -2414,6 +2414,29 @@ KEYINPUT_CHECKTABLE_INSDEL:
aCh = '\t';
[[fallthrough]];
case SwKeyState::InsChar:
+ if (rSh.CursorInsideContentControl())
+ {
+ const SwPosition* pStart = rSh.GetCursor()->Start();
+ SwTextNode* pTextNode = pStart->nNode.GetNode().GetTextNode();
+ if (pTextNode)
+ {
+ sal_Int32 nIndex = pStart->nContent.GetIndex();
+ SwTextAttr* pAttr = pTextNode->GetTextAttrAt(nIndex, RES_TXTATR_CONTENTCONTROL, SwTextNode::PARENT);
+ if (pAttr)
+ {
+ auto 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);
+ eKeyState = SwKeyState::End;
+ break;
+ }
+ }
+ }
+ }
+
if (rSh.GetChar(false)==CH_TXT_ATR_FORMELEMENT)
{
::sw::mark::ICheckboxFieldmark* pFieldmark =