summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/inc/formatcontentcontrol.hxx10
-rw-r--r--sw/qa/core/crsr/crsr.cxx28
-rw-r--r--sw/source/core/crsr/pam.cxx26
-rw-r--r--sw/source/uibase/wrtsh/wrtsh3.cxx2
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);