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 0f25676a07131b60f5ff7881b39379c33b3e9f54
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue May 17 08:18:34 2022 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Tue May 17 09:17:34 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.
    
    Change-Id: Ibbd3720fc94d0f17654ec813821d218166c76424
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134457
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/inc/formatcontentcontrol.hxx b/sw/inc/formatcontentcontrol.hxx
index da7cc89d591e..be9fa682a847 100644
--- a/sw/inc/formatcontentcontrol.hxx
+++ b/sw/inc/formatcontentcontrol.hxx
@@ -39,6 +39,7 @@ enum class SwContentControlType
     RICH_TEXT,
     CHECKBOX,
     DROP_DOWN_LIST,
+    PICTURE,
 };
 
 /// SfxPoolItem subclass that wraps an SwContentControl.
@@ -124,6 +125,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;
 
@@ -186,6 +189,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 187491905d77..78a4d212110e 100644
--- a/sw/inc/unoprnms.hxx
+++ b/sw/inc/unoprnms.hxx
@@ -877,6 +877,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 b4fd42352e80..c9ea6f833c12 100644
--- a/sw/qa/core/unocore/unocore.cxx
+++ b/sw/qa/core/unocore/unocore.cxx
@@ -543,6 +543,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 5c01ae826acf..1f8b6c602870 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)
         {
@@ -519,6 +521,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
@@ -758,6 +761,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();
@@ -837,6 +855,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 e7639b088f3a..5c480b2619b7 100644
--- a/sw/source/core/unocore/unolinebreak.cxx
+++ b/sw/source/core/unocore/unolinebreak.cxx
@@ -37,6 +37,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 b580ed2cc982..6af69d52671d 100644
--- a/sw/source/core/unocore/unomap1.cxx
+++ b/sw/source/core/unocore/unomap1.cxx
@@ -1028,6 +1028,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 ebdefe75971b..965a0e309cb5 100644
--- a/sw/source/uibase/wrtsh/wrtsh1.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh1.cxx
@@ -1030,6 +1030,7 @@ void 
SwWrtShell::InsertContentControl(SwContentControlType eType)
     switch (eType)
     {
         case SwContentControlType::RICH_TEXT:
+        case SwContentControlType::PICTURE:
         {
             pContentControl->SetShowingPlaceHolder(true);
             if (!HasSelection())

Reply via email to