sw/inc/formatcontentcontrol.hxx | 19 +++++ sw/inc/unoprnms.hxx | 2 sw/qa/core/unocore/unocore.cxx | 41 ++++++++++++ sw/source/core/txtnode/attrcontentcontrol.cxx | 6 + sw/source/core/unocore/unocontentcontrol.cxx | 85 ++++++++++++++++++++++++++ sw/source/core/unocore/unomap1.cxx | 3 sw/source/uibase/wrtsh/wrtsh1.cxx | 1 7 files changed, 157 insertions(+)
New commits: commit b95278f71ed3ca27f5ef370e11f6a30b87148d5c Author: Miklos Vajna <[email protected]> AuthorDate: Tue May 24 08:16:57 2022 +0200 Commit: Miklos Vajna <[email protected]> CommitDate: Mon May 30 14:25:26 2022 +0200 sw content controls, date: add doc model & UNO API This is meant to be a content control (providing rich text), which also has a dropdown-like date picker button. Add a new Date property to track this type, together with date format and date language. This should be enough for the UI to generate a correct date string when the file picker is used. (cherry picked from commit af353743dfe161e5289a7786a46bf3e8b1de43e3) Change-Id: If5d46a804d771e903a688fd73cfaf2d2809b7ab9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135115 Tested-by: Miklos Vajna <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> diff --git a/sw/inc/formatcontentcontrol.hxx b/sw/inc/formatcontentcontrol.hxx index 2c438715ee32..b4737c71ae90 100644 --- a/sw/inc/formatcontentcontrol.hxx +++ b/sw/inc/formatcontentcontrol.hxx @@ -39,6 +39,7 @@ enum class SwContentControlType CHECKBOX, DROP_DOWN_LIST, PICTURE, + DATE, }; /// SfxPoolItem subclass that wraps an SwContentControl. @@ -126,6 +127,12 @@ class SW_DLLPUBLIC SwContentControl : public sw::BroadcastingModify bool m_bPicture = false; + bool m_bDate = false; + + OUString m_aDateFormat; + + OUString m_aDateLanguage; + /// Stores a list item index, in case the doc model is not yet updated. std::optional<size_t> m_oSelectedListItem; @@ -192,6 +199,18 @@ public: bool GetPicture() const { return m_bPicture; } + void SetDate(bool bDate) { m_bDate = bDate; } + + bool GetDate() const { return m_bDate; } + + void SetDateFormat(const OUString& rDateFormat) { m_aDateFormat = rDateFormat; } + + OUString GetDateFormat() const { return m_aDateFormat; } + + void SetDateLanguage(const OUString& rDateLanguage) { m_aDateLanguage = rDateLanguage; } + + OUString GetDateLanguage() const { return m_aDateLanguage; } + void SetSelectedListItem(std::optional<size_t> oSelectedListItem) { m_oSelectedListItem = oSelectedListItem; diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx index a20b345d6640..4ac4aa7d0dca 100644 --- a/sw/inc/unoprnms.hxx +++ b/sw/inc/unoprnms.hxx @@ -877,6 +877,8 @@ #define UNO_NAME_UNCHECKED_STATE "UncheckedState" #define UNO_NAME_LIST_ITEMS "ListItems" #define UNO_NAME_PICTURE "Picture" +#define UNO_NAME_DATE_FORMAT "DateFormat" +#define UNO_NAME_DATE_LANGUAGE "DateLanguage" #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 83d2698b3353..998c4d285adc 100644 --- a/sw/qa/core/unocore/unocore.cxx +++ b/sw/qa/core/unocore/unocore.cxx @@ -528,6 +528,47 @@ CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, testContentControlPicture) CPPUNIT_ASSERT(pContentControl->GetPicture()); } +CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, testContentControlDate) +{ + // Given an empty document: + SwDoc* pDoc = createSwDoc(); + + // When inserting a date 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(); + uno::Reference<beans::XPropertySet> xTextGraphic( + xMSF->createInstance("com.sun.star.text.TextGraphicObject"), uno::UNO_QUERY); + xTextGraphic->setPropertyValue("AnchorType", + uno::Any(text::TextContentAnchorType_AS_CHARACTER)); + uno::Reference<text::XTextContent> xTextContent(xTextGraphic, uno::UNO_QUERY); + xText->insertTextContent(xCursor, xTextContent, 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("Date", uno::Any(true)); + xContentControlProps->setPropertyValue("DateFormat", uno::Any(OUString("M/d/yyyy"))); + xContentControlProps->setPropertyValue("DateLanguage", uno::Any(OUString("en-US"))); + 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()); + std::shared_ptr<SwContentControl> pContentControl = rFormatContentControl.GetContentControl(); + CPPUNIT_ASSERT(pContentControl->GetDate()); + CPPUNIT_ASSERT_EQUAL(OUString("M/d/yyyy"), pContentControl->GetDateFormat()); + CPPUNIT_ASSERT_EQUAL(OUString("en-US"), pContentControl->GetDateLanguage()); +} + 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 24e50d5b72af..7eb39907ce0c 100644 --- a/sw/source/core/txtnode/attrcontentcontrol.cxx +++ b/sw/source/core/txtnode/attrcontentcontrol.cxx @@ -224,6 +224,12 @@ void SwContentControl::dumpAsXml(xmlTextWriterPtr pWriter) const BAD_CAST(m_aUncheckedState.toUtf8().getStr())); (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("picture"), BAD_CAST(OString::boolean(m_bPicture).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("date"), + BAD_CAST(OString::boolean(m_bDate).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("date-format"), + BAD_CAST(m_aDateFormat.toUtf8().getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("date-language"), + BAD_CAST(m_aDateLanguage.toUtf8().getStr())); if (!m_aListItems.empty()) { diff --git a/sw/source/core/unocore/unocontentcontrol.cxx b/sw/source/core/unocore/unocontentcontrol.cxx index d81dfd4e504b..ef6959866b4c 100644 --- a/sw/source/core/unocore/unocontentcontrol.cxx +++ b/sw/source/core/unocore/unocontentcontrol.cxx @@ -162,6 +162,9 @@ public: OUString m_aUncheckedState; std::vector<SwContentControlListItem> m_aListItems; bool m_bPicture; + bool m_bDate; + OUString m_aDateFormat; + OUString m_aDateLanguage; Impl(SwXContentControl& rThis, SwDoc& rDoc, SwContentControl* pContentControl, const uno::Reference<text::XText>& xParentText, @@ -176,6 +179,7 @@ public: , m_bCheckbox(false) , m_bChecked(false) , m_bPicture(false) + , m_bDate(false) { if (m_pContentControl) { @@ -520,6 +524,9 @@ void SwXContentControl::AttachImpl(const uno::Reference<text::XTextRange>& xText pContentControl->SetUncheckedState(m_pImpl->m_aUncheckedState); pContentControl->SetListItems(m_pImpl->m_aListItems); pContentControl->SetPicture(m_pImpl->m_bPicture); + pContentControl->SetDate(m_pImpl->m_bDate); + pContentControl->SetDateFormat(m_pImpl->m_aDateFormat); + pContentControl->SetDateLanguage(m_pImpl->m_aDateLanguage); SwFormatContentControl aContentControl(pContentControl, nWhich); bool bSuccess @@ -774,6 +781,51 @@ void SAL_CALL SwXContentControl::setPropertyValue(const OUString& rPropertyName, } } } + else if (rPropertyName == UNO_NAME_DATE) + { + bool bValue; + if (rValue >>= bValue) + { + if (m_pImpl->m_bIsDescriptor) + { + m_pImpl->m_bDate = bValue; + } + else + { + m_pImpl->m_pContentControl->SetDate(bValue); + } + } + } + else if (rPropertyName == UNO_NAME_DATE_FORMAT) + { + OUString aValue; + if (rValue >>= aValue) + { + if (m_pImpl->m_bIsDescriptor) + { + m_pImpl->m_aDateFormat = aValue; + } + else + { + m_pImpl->m_pContentControl->SetDateFormat(aValue); + } + } + } + else if (rPropertyName == UNO_NAME_DATE_LANGUAGE) + { + OUString aValue; + if (rValue >>= aValue) + { + if (m_pImpl->m_bIsDescriptor) + { + m_pImpl->m_aDateLanguage = aValue; + } + else + { + m_pImpl->m_pContentControl->SetDateLanguage(aValue); + } + } + } else { throw beans::UnknownPropertyException(); @@ -864,6 +916,39 @@ uno::Any SAL_CALL SwXContentControl::getPropertyValue(const OUString& rPropertyN aRet <<= m_pImpl->m_pContentControl->GetPicture(); } } + else if (rPropertyName == UNO_NAME_DATE) + { + if (m_pImpl->m_bIsDescriptor) + { + aRet <<= m_pImpl->m_bDate; + } + else + { + aRet <<= m_pImpl->m_pContentControl->GetDate(); + } + } + else if (rPropertyName == UNO_NAME_DATE_FORMAT) + { + if (m_pImpl->m_bIsDescriptor) + { + aRet <<= m_pImpl->m_aDateFormat; + } + else + { + aRet <<= m_pImpl->m_pContentControl->GetDateFormat(); + } + } + else if (rPropertyName == UNO_NAME_DATE_LANGUAGE) + { + if (m_pImpl->m_bIsDescriptor) + { + aRet <<= m_pImpl->m_aDateLanguage; + } + else + { + aRet <<= m_pImpl->m_pContentControl->GetDateLanguage(); + } + } else { throw beans::UnknownPropertyException(); diff --git a/sw/source/core/unocore/unomap1.cxx b/sw/source/core/unocore/unomap1.cxx index f1d9694670d9..70e6fc0e5fc7 100644 --- a/sw/source/core/unocore/unomap1.cxx +++ b/sw/source/core/unocore/unomap1.cxx @@ -1033,6 +1033,9 @@ const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetContentControlProper { u"" UNO_NAME_UNCHECKED_STATE, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 }, { u"" UNO_NAME_LIST_ITEMS, 0, cppu::UnoType<uno::Sequence<uno::Sequence<beans::PropertyValue>>>::get(), PROPERTY_NONE, 0 }, { u"" UNO_NAME_PICTURE, 0, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 }, + { u"" UNO_NAME_DATE, 0, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 }, + { u"" UNO_NAME_DATE_FORMAT, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 }, + { u"" UNO_NAME_DATE_LANGUAGE, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 }, { u"", 0, css::uno::Type(), 0, 0 } }; diff --git a/sw/source/uibase/wrtsh/wrtsh1.cxx b/sw/source/uibase/wrtsh/wrtsh1.cxx index 07147f9f3a37..d2c8815c305c 100644 --- a/sw/source/uibase/wrtsh/wrtsh1.cxx +++ b/sw/source/uibase/wrtsh/wrtsh1.cxx @@ -1026,6 +1026,7 @@ void SwWrtShell::InsertContentControl(SwContentControlType eType) switch (eType) { case SwContentControlType::RICH_TEXT: + case SwContentControlType::DATE: { pContentControl->SetShowingPlaceHolder(true); if (!HasSelection())
