summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2022-04-25 08:47:32 +0200
committerMiklos Vajna <vmiklos@collabora.com>2022-05-02 08:18:03 +0200
commit2da286b41edfced3c331f69445dcda6ce55b3c84 (patch)
tree7a301208ed0274ff4cbe05ff9b0d5ed6e15bd286
parent4a0f65c338f32dffc9ecc47811aa199d13205a9e (diff)
sw content controls, checkbox: add document model & UNO API
Add 4 new properties: if this is a checkbox, and is so: - if it's checked - unicode value for the checked state - unicode value for the unchecked state This should be enough for the UI to be able to update checkmark state on click. (cherry picked from commit cd2272874d1b1911dec6c6e7bf3d67861be4a015) Change-Id: I723532fd2d3377cf09a1127c69c55f9539649088 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133641 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
-rw-r--r--sw/inc/formatcontentcontrol.hxx28
-rw-r--r--sw/inc/unoprnms.hxx4
-rw-r--r--sw/qa/core/unocore/unocore.cxx38
-rw-r--r--sw/source/core/txtnode/attrcontentcontrol.cxx8
-rw-r--r--sw/source/core/unocore/unocontentcontrol.cxx114
-rw-r--r--sw/source/core/unocore/unomap1.cxx4
6 files changed, 196 insertions, 0 deletions
diff --git a/sw/inc/formatcontentcontrol.hxx b/sw/inc/formatcontentcontrol.hxx
index d50c68945f39..54804612a2b5 100644
--- a/sw/inc/formatcontentcontrol.hxx
+++ b/sw/inc/formatcontentcontrol.hxx
@@ -79,6 +79,18 @@ class SwContentControl : public sw::BroadcastingModify
/// Current content is placeholder text.
bool m_bShowingPlaceHolder = false;
+ /// Display the content control as a checkbox.
+ bool m_bCheckbox = false;
+
+ /// If m_bCheckbox is true, is the checkbox checked?
+ bool m_bChecked = false;
+
+ /// If m_bCheckbox is true, the value of a checked checkbox.
+ OUString m_aCheckedState;
+
+ /// If m_bCheckbox is true, the value of an unchecked checkbox.
+ OUString m_aUncheckedState;
+
public:
SwTextContentControl* GetTextAttr() const;
@@ -113,6 +125,22 @@ public:
bool GetShowingPlaceHolder() const { return m_bShowingPlaceHolder; }
+ void SetCheckbox(bool bCheckbox) { m_bCheckbox = bCheckbox; }
+
+ bool GetCheckbox() const { return m_bCheckbox; }
+
+ void SetChecked(bool bChecked) { m_bChecked = bChecked; }
+
+ bool GetChecked() const { return m_bChecked; }
+
+ void SetCheckedState(const OUString& rCheckedState) { m_aCheckedState = rCheckedState; }
+
+ OUString GetCheckedState() const { return m_aCheckedState; }
+
+ void SetUncheckedState(const OUString& rUncheckedState) { m_aUncheckedState = rUncheckedState; }
+
+ OUString GetUncheckedState() const { return m_aUncheckedState; }
+
virtual void dumpAsXml(xmlTextWriterPtr pWriter) const;
};
diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx
index 79a64e4109f5..239ab6a56a97 100644
--- a/sw/inc/unoprnms.hxx
+++ b/sw/inc/unoprnms.hxx
@@ -871,6 +871,10 @@
#define UNO_NAME_LINEBREAK "LineBreak"
#define UNO_NAME_CONTENT_CONTROL "ContentControl"
#define UNO_NAME_SHOWING_PLACE_HOLDER "ShowingPlaceHolder"
+#define UNO_NAME_CHECKBOX "Checkbox"
+#define UNO_NAME_CHECKED "Checked"
+#define UNO_NAME_CHECKED_STATE "CheckedState"
+#define UNO_NAME_UNCHECKED_STATE "UncheckedState"
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/core/unocore/unocore.cxx b/sw/qa/core/unocore/unocore.cxx
index 8b2f3eb5f6ec..0e3fcc9ef7c0 100644
--- a/sw/qa/core/unocore/unocore.cxx
+++ b/sw/qa/core/unocore/unocore.cxx
@@ -365,6 +365,44 @@ CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, testContentControlTextPortionEnum)
"PortionType::ContentControl");
}
+CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, testContentControlCheckbox)
+{
+ // Given an empty document:
+ SwDoc* pDoc = createSwDoc();
+
+ // When inserting a checkbox content control:
+ 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, "test", /*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);
+ // Without the accompanying fix in place, this test would have failed with:
+ // An uncaught exception of type com.sun.star.beans.UnknownPropertyException
+ 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);
+
+ // Then make sure that the specified properties are set:
+ 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());
+ SwContentControl* pContentControl = rFormatContentControl.GetContentControl();
+ CPPUNIT_ASSERT(pContentControl->GetCheckbox());
+ CPPUNIT_ASSERT(pContentControl->GetChecked());
+ CPPUNIT_ASSERT_EQUAL(OUString(u"☒"), pContentControl->GetCheckedState());
+ CPPUNIT_ASSERT_EQUAL(OUString(u"☐"), pContentControl->GetUncheckedState());
+}
+
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 066ddd0494be..e469bab96e1d 100644
--- a/sw/source/core/txtnode/attrcontentcontrol.cxx
+++ b/sw/source/core/txtnode/attrcontentcontrol.cxx
@@ -212,6 +212,14 @@ void SwContentControl::dumpAsXml(xmlTextWriterPtr pWriter) const
(void)xmlTextWriterWriteFormatAttribute(
pWriter, BAD_CAST("showing-place-holder"), "%s",
BAD_CAST(OString::boolean(m_bShowingPlaceHolder).getStr()));
+ (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("checkbox"), "%s",
+ BAD_CAST(OString::boolean(m_bCheckbox).getStr()));
+ (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("checked"), "%s",
+ BAD_CAST(OString::boolean(m_bChecked).getStr()));
+ (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("checked-state"), "%s",
+ BAD_CAST(m_aCheckedState.toUtf8().getStr()));
+ (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("unchecked-state"), "%s",
+ BAD_CAST(m_aUncheckedState.toUtf8().getStr()));
(void)xmlTextWriterEndElement(pWriter);
}
diff --git a/sw/source/core/unocore/unocontentcontrol.cxx b/sw/source/core/unocore/unocontentcontrol.cxx
index 50369181c357..90e09664f67f 100644
--- a/sw/source/core/unocore/unocontentcontrol.cxx
+++ b/sw/source/core/unocore/unocontentcontrol.cxx
@@ -156,6 +156,10 @@ public:
rtl::Reference<SwXContentControlText> m_xText;
SwContentControl* m_pContentControl;
bool m_bShowingPlaceHolder;
+ bool m_bCheckbox;
+ bool m_bChecked;
+ OUString m_aCheckedState;
+ OUString m_aUncheckedState;
Impl(SwXContentControl& rThis, SwDoc& rDoc, SwContentControl* pContentControl,
const uno::Reference<text::XText>& xParentText,
@@ -167,6 +171,8 @@ public:
, m_xText(new SwXContentControlText(rDoc, rThis))
, m_pContentControl(pContentControl)
, m_bShowingPlaceHolder(false)
+ , m_bCheckbox(false)
+ , m_bChecked(false)
{
if (m_pContentControl)
{
@@ -504,6 +510,10 @@ void SwXContentControl::AttachImpl(const uno::Reference<text::XTextRange>& xText
auto pContentControl = std::make_shared<SwContentControl>(nullptr);
pContentControl->SetShowingPlaceHolder(m_pImpl->m_bShowingPlaceHolder);
+ pContentControl->SetCheckbox(m_pImpl->m_bCheckbox);
+ pContentControl->SetChecked(m_pImpl->m_bChecked);
+ pContentControl->SetCheckedState(m_pImpl->m_aCheckedState);
+ pContentControl->SetUncheckedState(m_pImpl->m_aUncheckedState);
SwFormatContentControl aContentControl(pContentControl, nWhich);
bool bSuccess
@@ -670,6 +680,66 @@ void SAL_CALL SwXContentControl::setPropertyValue(const OUString& rPropertyName,
}
}
}
+ else if (rPropertyName == UNO_NAME_CHECKBOX)
+ {
+ bool bValue;
+ if (rValue >>= bValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_bCheckbox = bValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetCheckbox(bValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_CHECKED)
+ {
+ bool bValue;
+ if (rValue >>= bValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_bChecked = bValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetChecked(bValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_CHECKED_STATE)
+ {
+ OUString aValue;
+ if (rValue >>= aValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_aCheckedState = aValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetCheckedState(aValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_UNCHECKED_STATE)
+ {
+ OUString aValue;
+ if (rValue >>= aValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_aUncheckedState = aValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetUncheckedState(aValue);
+ }
+ }
+ }
else
{
throw beans::UnknownPropertyException();
@@ -692,6 +762,50 @@ uno::Any SAL_CALL SwXContentControl::getPropertyValue(const OUString& rPropertyN
aRet <<= m_pImpl->m_pContentControl->GetShowingPlaceHolder();
}
}
+ else if (rPropertyName == UNO_NAME_CHECKBOX)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_bCheckbox;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetCheckbox();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_CHECKED)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_bChecked;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetChecked();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_CHECKED_STATE)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_aCheckedState;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetCheckedState();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_UNCHECKED_STATE)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_aUncheckedState;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetUncheckedState();
+ }
+ }
else
{
throw beans::UnknownPropertyException();
diff --git a/sw/source/core/unocore/unomap1.cxx b/sw/source/core/unocore/unomap1.cxx
index 7a9881f2c74c..306f3c2b42a6 100644
--- a/sw/source/core/unocore/unomap1.cxx
+++ b/sw/source/core/unocore/unomap1.cxx
@@ -1027,6 +1027,10 @@ const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetContentControlProper
static SfxItemPropertyMapEntry const aContentControlMap_Impl[] =
{
{ u"" UNO_NAME_SHOWING_PLACE_HOLDER, 0, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ { u"" UNO_NAME_CHECKBOX, 0, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ { u"" UNO_NAME_CHECKED, 0, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ { u"" UNO_NAME_CHECKED_STATE, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { u"" UNO_NAME_UNCHECKED_STATE, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
{ u"", 0, css::uno::Type(), 0, 0 }
};