sw/qa/uibase/wrtsh/wrtsh.cxx | 38 ++++++++++++++++++++++++++++++++++++++ sw/source/core/crsr/crstrvl.cxx | 2 +- sw/source/uibase/wrtsh/wrtsh3.cxx | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 1 deletion(-)
New commits: commit 4a0f65c338f32dffc9ecc47811aa199d13205a9e Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Tue Apr 26 08:20:50 2022 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Mon May 2 08:14:44 2022 +0200 sw content controls, checkbox: toggle the checkbox on click Implement this by selecting the content control's text (similar to placeholders), then replacing the selection with the content control's relevant state. (cherry picked from commit 6f60a89a6be85d4cbe5840f9d0146eae98dbf543) Change-Id: I280ce45822fe3fd9615511a9a62d23dc230aa275 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133642 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/sw/qa/uibase/wrtsh/wrtsh.cxx b/sw/qa/uibase/wrtsh/wrtsh.cxx index 51489553d30f..b4d4cca09df6 100644 --- a/sw/qa/uibase/wrtsh/wrtsh.cxx +++ b/sw/qa/uibase/wrtsh/wrtsh.cxx @@ -91,6 +91,44 @@ CPPUNIT_TEST_FIXTURE(Test, testGotoContentControl) CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(5), nEnd); } +CPPUNIT_TEST_FIXTURE(Test, testTickCheckboxContentControl) +{ + // Given a document with a checkbox (checked) content control: + SwDoc* pDoc = createSwDoc(); + uno::Reference<lang::XMultiServiceFactory> xMSF(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XText> xText = xTextDocument->getText(); + uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor(); + xText->insertString(xCursor, OUString(u"☒"), /*bAbsorb=*/false); + xCursor->gotoStart(/*bExpand=*/false); + xCursor->gotoEnd(/*bExpand=*/true); + uno::Reference<text::XTextContent> xContentControl( + xMSF->createInstance("com.sun.star.text.ContentControl"), uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, uno::UNO_QUERY); + xContentControlProps->setPropertyValue("Checkbox", uno::makeAny(true)); + xContentControlProps->setPropertyValue("Checked", uno::makeAny(true)); + xContentControlProps->setPropertyValue("CheckedState", uno::makeAny(OUString(u"☒"))); + xContentControlProps->setPropertyValue("UncheckedState", uno::makeAny(OUString(u"☐"))); + xText->insertTextContent(xCursor, xContentControl, /*bAbsorb=*/true); + + // When clicking on that content control: + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + 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()); + pWrtShell->GotoContentControl(rFormatContentControl); + + // Then make sure that the checkbox is no longer checked: + // Without the accompanying fix in place, this test would have failed: + // - Expected: ☐ + // - Actual : ☒ + // i.e. the text node's text was CH_TXTATR_BREAKWORD + "Ballot Box with X", not just + // CH_TXTATR_BREAKWORD + "Ballot Box". + CPPUNIT_ASSERT_EQUAL(OUString(u"\x0001☐"), pTextNode->GetText()); +} + CPPUNIT_TEST_FIXTURE(Test, testInsertContentControl) { // Given an empty document: diff --git a/sw/source/core/crsr/crstrvl.cxx b/sw/source/core/crsr/crstrvl.cxx index e1e9aa08913f..48c10a666c7f 100644 --- a/sw/source/core/crsr/crstrvl.cxx +++ b/sw/source/core/crsr/crstrvl.cxx @@ -857,7 +857,7 @@ bool SwCursorShell::GotoFormatContentControl(const SwFormatContentControl& rCont { bool bRet = false; auto pContentControl = const_cast<SwContentControl*>(rContentControl.GetContentControl()); - if (!pContentControl->GetShowingPlaceHolder()) + if (!pContentControl->GetShowingPlaceHolder() && !pContentControl->GetCheckbox()) { return bRet; } diff --git a/sw/source/uibase/wrtsh/wrtsh3.cxx b/sw/source/uibase/wrtsh/wrtsh3.cxx index 2b0b9385467e..35d1d3bd45ee 100644 --- a/sw/source/uibase/wrtsh/wrtsh3.cxx +++ b/sw/source/uibase/wrtsh/wrtsh3.cxx @@ -33,6 +33,10 @@ #include <view.hxx> #include <IMark.hxx> #include <doc.hxx> +#include <formatcontentcontrol.hxx> +#include <IDocumentUndoRedo.hxx> +#include <SwRewriter.hxx> +#include <strings.hrc> using namespace ::com::sun::star; @@ -88,6 +92,40 @@ bool SwWrtShell::GotoContentControl(const SwFormatContentControl& rContentContro (this->*m_fnKillSel)(nullptr, false); bool bRet = SwCursorShell::GotoFormatContentControl(rContentControl); + + auto pContentControl = const_cast<SwContentControl*>(rContentControl.GetContentControl()); + if (bRet && pContentControl && pContentControl->GetCheckbox()) + { + // Checkbox: GotoFormatContentControl() selected the old state. + LockView(/*bViewLocked=*/true); + OUString aOldState; + OUString aNewState; + if (pContentControl->GetChecked()) + { + aOldState = pContentControl->GetCheckedState(); + aNewState = pContentControl->GetUncheckedState(); + } + else + { + aOldState = pContentControl->GetUncheckedState(); + aNewState = pContentControl->GetCheckedState(); + } + SwRewriter aRewriter; + aRewriter.AddRule(UndoArg1, aOldState); + aRewriter.AddRule(UndoArg2, SwResId(STR_YIELDS)); + aRewriter.AddRule(UndoArg3, aNewState); + GetIDocumentUndoRedo().StartUndo(SwUndoId::REPLACE, &aRewriter); + + // Toggle the state. + DelLeft(); + pContentControl->SetChecked(!pContentControl->GetChecked()); + Insert(aNewState); + + GetIDocumentUndoRedo().EndUndo(SwUndoId::REPLACE, &aRewriter); + LockView(/*bViewLocked=*/false); + ShowCursor(); + } + if (bRet && IsSelFrameMode()) { UnSelectFrame();