diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2022-09-21 08:24:17 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2022-09-21 12:07:35 +0200 |
commit | 276f3a3ce52ca422bf5ebccfa2c926d3e87d5eab (patch) | |
tree | 55d0af1c833c309e22d16c2686d4ba91dc8c9463 /sw | |
parent | a6541eb454644cd781f6f4345a34ee422d1a4520 (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.hxx | 8 | ||||
-rw-r--r-- | sw/inc/unoprnms.hxx | 1 | ||||
-rw-r--r-- | sw/qa/core/unocore/unocore.cxx | 53 | ||||
-rw-r--r-- | sw/source/core/txtnode/attrcontentcontrol.cxx | 7 | ||||
-rw-r--r-- | sw/source/core/unocore/unocontentcontrol.cxx | 29 | ||||
-rw-r--r-- | sw/source/core/unocore/unomap1.cxx | 1 | ||||
-rw-r--r-- | sw/source/uibase/wrtsh/wrtsh1.cxx | 5 |
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); |