diff options
-rw-r--r-- | sw/inc/formatcontentcontrol.hxx | 10 | ||||
-rw-r--r-- | sw/qa/core/crsr/crsr.cxx | 28 | ||||
-rw-r--r-- | sw/source/core/crsr/pam.cxx | 26 | ||||
-rw-r--r-- | sw/source/uibase/wrtsh/wrtsh3.cxx | 2 |
4 files changed, 66 insertions, 0 deletions
diff --git a/sw/inc/formatcontentcontrol.hxx b/sw/inc/formatcontentcontrol.hxx index 17ff97cd1fa6..82f4fca9e2be 100644 --- a/sw/inc/formatcontentcontrol.hxx +++ b/sw/inc/formatcontentcontrol.hxx @@ -160,6 +160,12 @@ class SW_DLLPUBLIC SwContentControl : public sw::BroadcastingModify /// Stores a date timestamp, in case the doc model is not yet updated. std::optional<double> m_oSelectedDate; + /** + * E.g. checkbox is read-only by default, but we still update contents on interaction + * internally. This flag is true for the duration of that interaction. + */ + bool m_bReadWrite = false; + public: SwTextContentControl* GetTextAttr() const; @@ -292,6 +298,10 @@ public: void SetColor(const OUString& rColor) { m_aColor = rColor; } OUString GetColor() const { return m_aColor; } + + void SetReadWrite(bool bReadWrite) { m_bReadWrite = bReadWrite; } + + bool GetReadWrite() const { return m_bReadWrite; } }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/qa/core/crsr/crsr.cxx b/sw/qa/core/crsr/crsr.cxx index 882f9b6bcbab..8f8d9963a285 100644 --- a/sw/qa/core/crsr/crsr.cxx +++ b/sw/qa/core/crsr/crsr.cxx @@ -136,6 +136,34 @@ CPPUNIT_TEST_FIXTURE(SwCoreCrsrTest, testContentControlLineBreak) CPPUNIT_ASSERT_EQUAL(OUString("t\nest"), pTextNode->GetExpandText(pWrtShell->GetLayout())); } +CPPUNIT_TEST_FIXTURE(SwCoreCrsrTest, testContentControlReadOnly) +{ + // Given a document with a checkbox 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, 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::Any(true)); + xText->insertTextContent(xCursor, xContentControl, /*bAbsorb=*/true); + + // When entering the content control: + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + pWrtShell->SttEndDoc(/*bStt=*/true); + pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/false, 1, /*bBasicCall=*/false); + + // Then make sure that the cursor is read-only: + // Without the accompanying fix in place, this test would have failed, it was possible to type + // into the checkbox content control, just to loose the typed content on the next click. + CPPUNIT_ASSERT(pWrtShell->HasReadonlySel()); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/crsr/pam.cxx b/sw/source/core/crsr/pam.cxx index c54d500cb15d..f771e09f5739 100644 --- a/sw/source/core/crsr/pam.cxx +++ b/sw/source/core/crsr/pam.cxx @@ -49,6 +49,7 @@ #include <rtl/ustrbuf.hxx> #include <editsh.hxx> +#include <textcontentcontrol.hxx> // for the dump "MSC-" compiler static sal_Int32 GetSttOrEnd( bool bCondition, const SwContentNode& rNd ) @@ -811,6 +812,31 @@ bool SwPaM::HasReadonlySel( bool bFormView ) const } } + if (!bRet) + { + // See if we're inside a read-only content control. + const SwPosition* pStart = 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); + auto pTextContentControl = static_txtattr_cast<SwTextContentControl*>(pAttr); + if (pTextContentControl) + { + const SwFormatContentControl& rFormatContentControl + = pTextContentControl->GetContentControl(); + std::shared_ptr<SwContentControl> pContentControl + = rFormatContentControl.GetContentControl(); + if (pContentControl && !pContentControl->GetReadWrite()) + { + bRet = pContentControl->GetCheckbox() || pContentControl->GetPicture(); + } + } + } + } + return bRet; } diff --git a/sw/source/uibase/wrtsh/wrtsh3.cxx b/sw/source/uibase/wrtsh/wrtsh3.cxx index e4b594770282..27ca0353bac1 100644 --- a/sw/source/uibase/wrtsh/wrtsh3.cxx +++ b/sw/source/uibase/wrtsh/wrtsh3.cxx @@ -148,9 +148,11 @@ bool SwWrtShell::GotoContentControl(const SwFormatContentControl& rContentContro GetIDocumentUndoRedo().StartUndo(SwUndoId::REPLACE, &aRewriter); // Toggle the state. + pContentControl->SetReadWrite(true); DelLeft(); pContentControl->SetChecked(!pContentControl->GetChecked()); Insert(aNewState); + pContentControl->SetReadWrite(false); GetIDocumentUndoRedo().EndUndo(SwUndoId::REPLACE, &aRewriter); LockView(/*bViewLocked=*/false); |