summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2022-09-21 08:24:17 +0200
committerMiklos Vajna <vmiklos@collabora.com>2022-09-21 12:07:35 +0200
commit276f3a3ce52ca422bf5ebccfa2c926d3e87d5eab (patch)
tree55d0af1c833c309e22d16c2686d4ba91dc8c9463 /sw
parenta6541eb454644cd781f6f4345a34ee422d1a4520 (diff)
sw content controls, combo box: add doc model & UNO API
This is similar to dropdowns, but combo box allow free-form user input, while dropdown is meant to enforce that the content is one of the list items. Change-Id: I4ae226c55f70b2b3237021348e21b7d184e8a5ab Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140302 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
Diffstat (limited to 'sw')
-rw-r--r--sw/inc/formatcontentcontrol.hxx8
-rw-r--r--sw/inc/unoprnms.hxx1
-rw-r--r--sw/qa/core/unocore/unocore.cxx53
-rw-r--r--sw/source/core/txtnode/attrcontentcontrol.cxx7
-rw-r--r--sw/source/core/unocore/unocontentcontrol.cxx29
-rw-r--r--sw/source/core/unocore/unomap1.cxx1
-rw-r--r--sw/source/uibase/wrtsh/wrtsh1.cxx5
7 files changed, 104 insertions, 0 deletions
diff --git a/sw/inc/formatcontentcontrol.hxx b/sw/inc/formatcontentcontrol.hxx
index fa7c237acaf7..41d35fd10fb8 100644
--- a/sw/inc/formatcontentcontrol.hxx
+++ b/sw/inc/formatcontentcontrol.hxx
@@ -47,6 +47,7 @@ enum class SwContentControlType
PICTURE,
DATE,
PLAIN_TEXT,
+ COMBO_BOX,
};
/// SfxPoolItem subclass that wraps an SwContentControl.
@@ -147,6 +148,9 @@ class SW_DLLPUBLIC SwContentControl : public sw::BroadcastingModify
/// Plain text, i.e. not rich text.
bool m_bPlainText = false;
+ /// Same as drop-down, but free-form input is also accepted.
+ bool m_bComboBox = false;
+
/// The placeholder's doc part: just remembered.
OUString m_aPlaceholderDocPart;
@@ -263,6 +267,10 @@ public:
bool GetPlainText() const { return m_bPlainText; }
+ void SetComboBox(bool bComboBox) { m_bComboBox = bComboBox; }
+
+ bool GetComboBox() const { return m_bComboBox; }
+
void SetPlaceholderDocPart(const OUString& rPlaceholderDocPart)
{
m_aPlaceholderDocPart = rPlaceholderDocPart;
diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx
index 4f95a99c3a1f..bb82bf3a1eef 100644
--- a/sw/inc/unoprnms.hxx
+++ b/sw/inc/unoprnms.hxx
@@ -884,6 +884,7 @@
#define UNO_NAME_DATE_LANGUAGE "DateLanguage"
#define UNO_NAME_CURRENT_DATE "CurrentDate"
#define UNO_NAME_PLAIN_TEXT "PlainText"
+#define UNO_NAME_COMBO_BOX "ComboBox"
#define UNO_NAME_PLACEHOLDER_DOC_PART "PlaceholderDocPart"
#define UNO_NAME_DATA_BINDING_PREFIX_MAPPINGS "DataBindingPrefixMappings"
#define UNO_NAME_DATA_BINDING_XPATH "DataBindingXpath"
diff --git a/sw/qa/core/unocore/unocore.cxx b/sw/qa/core/unocore/unocore.cxx
index 86683e4e9506..83efc0f9e5c2 100644
--- a/sw/qa/core/unocore/unocore.cxx
+++ b/sw/qa/core/unocore/unocore.cxx
@@ -741,6 +741,59 @@ CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, testContentControlPlainText)
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(6), *pAttr->End());
}
+CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, testContentControlComboBox)
+{
+ // Given an empty document:
+ SwDoc* pDoc = createSwDoc();
+
+ // When inserting a combobox 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);
+ {
+ uno::Sequence<beans::PropertyValues> aListItems = {
+ {
+ comphelper::makePropertyValue("DisplayText", uno::Any(OUString("red"))),
+ comphelper::makePropertyValue("Value", uno::Any(OUString("R"))),
+ },
+ {
+ comphelper::makePropertyValue("DisplayText", uno::Any(OUString("green"))),
+ comphelper::makePropertyValue("Value", uno::Any(OUString("G"))),
+ },
+ {
+ comphelper::makePropertyValue("DisplayText", uno::Any(OUString("blue"))),
+ comphelper::makePropertyValue("Value", uno::Any(OUString("B"))),
+ },
+ };
+ xContentControlProps->setPropertyValue("ListItems", uno::Any(aListItems));
+ // Without the accompanying fix in place, this test would have failed with:
+ // An uncaught exception of type com.sun.star.beans.UnknownPropertyException
+ xContentControlProps->setPropertyValue("ComboBox", uno::Any(true));
+ }
+ xText->insertTextContent(xCursor, xContentControl, /*bAbsorb=*/true);
+
+ // Then make sure that the specified properties are set:
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ SwTextNode* pTextNode = pWrtShell->GetCursor()->GetPointNode().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();
+ std::vector<SwContentControlListItem> aListItems = pContentControl->GetListItems();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), aListItems.size());
+ CPPUNIT_ASSERT_EQUAL(OUString("red"), aListItems[0].m_aDisplayText);
+ CPPUNIT_ASSERT_EQUAL(OUString("R"), aListItems[0].m_aValue);
+ CPPUNIT_ASSERT(pContentControl->GetComboBox());
+}
+
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 5582b3409b30..89b12d9b7ea0 100644
--- a/sw/source/core/txtnode/attrcontentcontrol.cxx
+++ b/sw/source/core/txtnode/attrcontentcontrol.cxx
@@ -341,6 +341,11 @@ SwContentControlType SwContentControl::GetType() const
return SwContentControlType::CHECKBOX;
}
+ if (m_bComboBox)
+ {
+ return SwContentControlType::COMBO_BOX;
+ }
+
if (!m_aListItems.empty())
{
return SwContentControlType::DROP_DOWN_LIST;
@@ -391,6 +396,8 @@ void SwContentControl::dumpAsXml(xmlTextWriterPtr pWriter) const
BAD_CAST(m_aCurrentDate.toUtf8().getStr()));
(void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("plain-text"),
BAD_CAST(OString::boolean(m_bPlainText).getStr()));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("combo-box"),
+ BAD_CAST(OString::boolean(m_bComboBox).getStr()));
(void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("placeholder-doc-part"),
BAD_CAST(m_aPlaceholderDocPart.toUtf8().getStr()));
(void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("data-binding-prefix-mappings"),
diff --git a/sw/source/core/unocore/unocontentcontrol.cxx b/sw/source/core/unocore/unocontentcontrol.cxx
index be9974617566..b63725fac2f9 100644
--- a/sw/source/core/unocore/unocontentcontrol.cxx
+++ b/sw/source/core/unocore/unocontentcontrol.cxx
@@ -168,6 +168,7 @@ public:
OUString m_aDateLanguage;
OUString m_aCurrentDate;
bool m_bPlainText;
+ bool m_bComboBox;
OUString m_aPlaceholderDocPart;
OUString m_aDataBindingPrefixMappings;
OUString m_aDataBindingXpath;
@@ -188,6 +189,7 @@ public:
, m_bPicture(false)
, m_bDate(false)
, m_bPlainText(false)
+ , m_bComboBox(false)
{
if (m_pContentControl)
{
@@ -474,6 +476,7 @@ void SwXContentControl::AttachImpl(const uno::Reference<text::XTextRange>& xText
pContentControl->SetDateLanguage(m_pImpl->m_aDateLanguage);
pContentControl->SetCurrentDate(m_pImpl->m_aCurrentDate);
pContentControl->SetPlainText(m_pImpl->m_bPlainText);
+ pContentControl->SetComboBox(m_pImpl->m_bComboBox);
pContentControl->SetPlaceholderDocPart(m_pImpl->m_aPlaceholderDocPart);
pContentControl->SetDataBindingPrefixMappings(m_pImpl->m_aDataBindingPrefixMappings);
pContentControl->SetDataBindingXpath(m_pImpl->m_aDataBindingXpath);
@@ -808,6 +811,21 @@ void SAL_CALL SwXContentControl::setPropertyValue(const OUString& rPropertyName,
}
}
}
+ else if (rPropertyName == UNO_NAME_COMBO_BOX)
+ {
+ bool bValue;
+ if (rValue >>= bValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_bComboBox = bValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetComboBox(bValue);
+ }
+ }
+ }
else if (rPropertyName == UNO_NAME_PLACEHOLDER_DOC_PART)
{
OUString aValue;
@@ -1028,6 +1046,17 @@ uno::Any SAL_CALL SwXContentControl::getPropertyValue(const OUString& rPropertyN
aRet <<= m_pImpl->m_pContentControl->GetPlainText();
}
}
+ else if (rPropertyName == UNO_NAME_COMBO_BOX)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_bComboBox;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetComboBox();
+ }
+ }
else if (rPropertyName == UNO_NAME_PLACEHOLDER_DOC_PART)
{
if (m_pImpl->m_bIsDescriptor)
diff --git a/sw/source/core/unocore/unomap1.cxx b/sw/source/core/unocore/unomap1.cxx
index 4e99cc4223f0..0bf5a84a7aaa 100644
--- a/sw/source/core/unocore/unomap1.cxx
+++ b/sw/source/core/unocore/unomap1.cxx
@@ -1003,6 +1003,7 @@ o3tl::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetContentCo
{ u"" UNO_NAME_DATE_LANGUAGE, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
{ u"" UNO_NAME_CURRENT_DATE, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
{ u"" UNO_NAME_PLAIN_TEXT, 0, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ { u"" UNO_NAME_COMBO_BOX, 0, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
{ u"" UNO_NAME_PLACEHOLDER_DOC_PART, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
{ u"" UNO_NAME_DATA_BINDING_PREFIX_MAPPINGS, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
{ u"" UNO_NAME_DATA_BINDING_XPATH, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
diff --git a/sw/source/uibase/wrtsh/wrtsh1.cxx b/sw/source/uibase/wrtsh/wrtsh1.cxx
index 5b6649861a74..d9374e18a66b 100644
--- a/sw/source/uibase/wrtsh/wrtsh1.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh1.cxx
@@ -1058,6 +1058,11 @@ void SwWrtShell::InsertContentControl(SwContentControlType eType)
aPlaceholder = u"\u2610";
break;
}
+ case SwContentControlType::COMBO_BOX:
+ {
+ pContentControl->SetComboBox(true);
+ [[fallthrough]];
+ }
case SwContentControlType::DROP_DOWN_LIST:
{
pContentControl->SetShowingPlaceHolder(true);