sw/inc/formatcontentcontrol.hxx               |    7 +++++
 sw/inc/unoprnms.hxx                           |    1 
 sw/qa/core/unocore/unocore.cxx                |   32 ++++++++++++++++++++++++++
 sw/source/core/txtnode/attrcontentcontrol.cxx |    2 +
 sw/source/core/unocore/unocontentcontrol.cxx  |   29 +++++++++++++++++++++++
 sw/source/core/unocore/unolinebreak.cxx       |    1 
 sw/source/core/unocore/unomap1.cxx            |    1 
 sw/source/uibase/wrtsh/wrtsh1.cxx             |    1 
 8 files changed, 74 insertions(+)

New commits:
commit 668412021ba877601ed22c29f615f4a15a6a3887
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue May 17 08:18:34 2022 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri May 20 11:32:23 2022 +0200

    sw content controls, picture: add doc model & UNO API
    
    This is meant to be a content control (providing rich text), which is
    also a picture placeholder field.
    
    Add a new Picture property to track this type, this way the click
    handler will be able to present a file picker when showing the
    placeholder.
    
    (cherry picked from commit 0f25676a07131b60f5ff7881b39379c33b3e9f54)
    
    Change-Id: Ibbd3720fc94d0f17654ec813821d218166c76424
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134662
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/sw/inc/formatcontentcontrol.hxx b/sw/inc/formatcontentcontrol.hxx
index 7304a48214a9..2c438715ee32 100644
--- a/sw/inc/formatcontentcontrol.hxx
+++ b/sw/inc/formatcontentcontrol.hxx
@@ -38,6 +38,7 @@ enum class SwContentControlType
     RICH_TEXT,
     CHECKBOX,
     DROP_DOWN_LIST,
+    PICTURE,
 };
 
 /// SfxPoolItem subclass that wraps an SwContentControl.
@@ -123,6 +124,8 @@ class SW_DLLPUBLIC SwContentControl : public 
sw::BroadcastingModify
 
     std::vector<SwContentControlListItem> m_aListItems;
 
+    bool m_bPicture = false;
+
     /// Stores a list item index, in case the doc model is not yet updated.
     std::optional<size_t> m_oSelectedListItem;
 
@@ -185,6 +188,10 @@ public:
         m_aListItems = rListItems;
     }
 
+    void SetPicture(bool bPicture) { m_bPicture = bPicture; }
+
+    bool GetPicture() const { return m_bPicture; }
+
     void SetSelectedListItem(std::optional<size_t> oSelectedListItem)
     {
         m_oSelectedListItem = oSelectedListItem;
diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx
index 7a3b592a4858..a20b345d6640 100644
--- a/sw/inc/unoprnms.hxx
+++ b/sw/inc/unoprnms.hxx
@@ -876,6 +876,7 @@
 #define UNO_NAME_CHECKED_STATE "CheckedState"
 #define UNO_NAME_UNCHECKED_STATE "UncheckedState"
 #define UNO_NAME_LIST_ITEMS "ListItems"
+#define UNO_NAME_PICTURE "Picture"
 #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 1e663a7bb156..fec19e7abefe 100644
--- a/sw/qa/core/unocore/unocore.cxx
+++ b/sw/qa/core/unocore/unocore.cxx
@@ -491,6 +491,38 @@ CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, 
testInsertFileInContentControlException)
     xInsertable->insertDocumentFromURL(aURL, {});
 }
 
+CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, testContentControlPicture)
+{
+    // Given an empty document:
+    SwDoc* pDoc = createSwDoc();
+
+    // When inserting a picture 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("Picture", 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()->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->GetPicture());
+}
+
 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 c249adffd819..24e50d5b72af 100644
--- a/sw/source/core/txtnode/attrcontentcontrol.cxx
+++ b/sw/source/core/txtnode/attrcontentcontrol.cxx
@@ -222,6 +222,8 @@ void SwContentControl::dumpAsXml(xmlTextWriterPtr pWriter) 
const
                                             
BAD_CAST(m_aCheckedState.toUtf8().getStr()));
     (void)xmlTextWriterWriteFormatAttribute(pWriter, 
BAD_CAST("unchecked-state"), "%s",
                                             
BAD_CAST(m_aUncheckedState.toUtf8().getStr()));
+    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("picture"),
+                                      
BAD_CAST(OString::boolean(m_bPicture).getStr()));
 
     if (!m_aListItems.empty())
     {
diff --git a/sw/source/core/unocore/unocontentcontrol.cxx 
b/sw/source/core/unocore/unocontentcontrol.cxx
index a7aba99f2e2e..d81dfd4e504b 100644
--- a/sw/source/core/unocore/unocontentcontrol.cxx
+++ b/sw/source/core/unocore/unocontentcontrol.cxx
@@ -161,6 +161,7 @@ public:
     OUString m_aCheckedState;
     OUString m_aUncheckedState;
     std::vector<SwContentControlListItem> m_aListItems;
+    bool m_bPicture;
 
     Impl(SwXContentControl& rThis, SwDoc& rDoc, SwContentControl* 
pContentControl,
          const uno::Reference<text::XText>& xParentText,
@@ -174,6 +175,7 @@ public:
         , m_bShowingPlaceHolder(false)
         , m_bCheckbox(false)
         , m_bChecked(false)
+        , m_bPicture(false)
     {
         if (m_pContentControl)
         {
@@ -517,6 +519,7 @@ void SwXContentControl::AttachImpl(const 
uno::Reference<text::XTextRange>& xText
     pContentControl->SetCheckedState(m_pImpl->m_aCheckedState);
     pContentControl->SetUncheckedState(m_pImpl->m_aUncheckedState);
     pContentControl->SetListItems(m_pImpl->m_aListItems);
+    pContentControl->SetPicture(m_pImpl->m_bPicture);
 
     SwFormatContentControl aContentControl(pContentControl, nWhich);
     bool bSuccess
@@ -756,6 +759,21 @@ void SAL_CALL SwXContentControl::setPropertyValue(const 
OUString& rPropertyName,
             m_pImpl->m_pContentControl->SetListItems(aItems);
         }
     }
+    else if (rPropertyName == UNO_NAME_PICTURE)
+    {
+        bool bValue;
+        if (rValue >>= bValue)
+        {
+            if (m_pImpl->m_bIsDescriptor)
+            {
+                m_pImpl->m_bPicture = bValue;
+            }
+            else
+            {
+                m_pImpl->m_pContentControl->SetPicture(bValue);
+            }
+        }
+    }
     else
     {
         throw beans::UnknownPropertyException();
@@ -835,6 +853,17 @@ uno::Any SAL_CALL 
SwXContentControl::getPropertyValue(const OUString& rPropertyN
         }
         SwContentControlListItem::ItemsToAny(aItems, aRet);
     }
+    else if (rPropertyName == UNO_NAME_PICTURE)
+    {
+        if (m_pImpl->m_bIsDescriptor)
+        {
+            aRet <<= m_pImpl->m_bPicture;
+        }
+        else
+        {
+            aRet <<= m_pImpl->m_pContentControl->GetPicture();
+        }
+    }
     else
     {
         throw beans::UnknownPropertyException();
diff --git a/sw/source/core/unocore/unolinebreak.cxx 
b/sw/source/core/unocore/unolinebreak.cxx
index 2e8ee454eccb..010be5c6c017 100644
--- a/sw/source/core/unocore/unolinebreak.cxx
+++ b/sw/source/core/unocore/unolinebreak.cxx
@@ -36,6 +36,7 @@
 
 using namespace com::sun::star;
 
+/// The inner part SwXLineBreak, which is deleted with a locked SolarMutex.
 class SwXLineBreak::Impl : public SvtListener
 {
 public:
diff --git a/sw/source/core/unocore/unomap1.cxx 
b/sw/source/core/unocore/unomap1.cxx
index c83b6b1d1fdb..f1d9694670d9 100644
--- a/sw/source/core/unocore/unomap1.cxx
+++ b/sw/source/core/unocore/unomap1.cxx
@@ -1032,6 +1032,7 @@ const SfxItemPropertyMapEntry* 
SwUnoPropertyMapProvider::GetContentControlProper
         { 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"" 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"", 0, css::uno::Type(), 0, 0 }
     };
 
diff --git a/sw/source/uibase/wrtsh/wrtsh1.cxx 
b/sw/source/uibase/wrtsh/wrtsh1.cxx
index 256115b8ddd4..51a602fec6e4 100644
--- a/sw/source/uibase/wrtsh/wrtsh1.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh1.cxx
@@ -1025,6 +1025,7 @@ void 
SwWrtShell::InsertContentControl(SwContentControlType eType)
     switch (eType)
     {
         case SwContentControlType::RICH_TEXT:
+        case SwContentControlType::PICTURE:
         {
             pContentControl->SetShowingPlaceHolder(true);
             if (!HasSelection())

Reply via email to