sw/inc/textcontentcontrol.hxx                   |    1 
 sw/source/core/txtnode/attrcontentcontrol.cxx   |   37 +++++++++++++++++++++++-
 sw/source/ui/vba/vbacontentcontrol.cxx          |   20 +++++-------
 sw/source/ui/vba/vbacontentcontrollistentry.cxx |    4 +-
 4 files changed, 47 insertions(+), 15 deletions(-)

New commits:
commit c74ff490903ee04725e9dfee6fdc3598a3a61190
Author:     Justin Luth <justin.l...@collabora.com>
AuthorDate: Wed Nov 23 08:15:15 2022 -0500
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon Nov 28 09:33:17 2022 +0100

    tdf#151548 ContentControls: Add Invalidate()
    
    Up until now, all changes made to a content control
    have been triggered by the UI.
    However, VBA makes changes by code,
    and those property changes were just being ignored
    until the control received the focus.
    
    Change-Id: Ife865dd493f7eae4d4e95096071f05b8c27d51db
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143194
    Reviewed-by: Justin Luth <jl...@mail.com>
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/sw/inc/textcontentcontrol.hxx b/sw/inc/textcontentcontrol.hxx
index 78a4d5120b1b..156b44804195 100644
--- a/sw/inc/textcontentcontrol.hxx
+++ b/sw/inc/textcontentcontrol.hxx
@@ -42,6 +42,7 @@ public:
     void ChgTextNode(SwTextNode* pNode);
 
     SwTextNode* GetTextNode() const;
+    void Invalidate(bool bKeepPlaceholderStatus = true);
 
     void dumpAsXml(xmlTextWriterPtr pWriter) const override;
 };
diff --git a/sw/source/core/txtnode/attrcontentcontrol.cxx 
b/sw/source/core/txtnode/attrcontentcontrol.cxx
index 118d60258f27..b4e060e75ffc 100644
--- a/sw/source/core/txtnode/attrcontentcontrol.cxx
+++ b/sw/source/core/txtnode/attrcontentcontrol.cxx
@@ -31,6 +31,7 @@
 #include <textcontentcontrol.hxx>
 #include <doc.hxx>
 #include <unocontentcontrol.hxx>
+#include <wrtsh.hxx>
 
 using namespace com::sun::star;
 
@@ -279,7 +280,8 @@ void SwContentControl::DeleteListItem(size_t nZIndex)
         if (*oSelected == nZIndex)
         {
             SetSelectedListItem(std::nullopt);
-            //Invalidate();
+            if (m_bDropDown && GetTextAttr())
+                GetTextAttr()->Invalidate();
         }
         else if (*oSelected < nZIndex)
             SetSelectedListItem(*oSelected - 1);
@@ -295,6 +297,8 @@ void SwContentControl::ClearListItems()
 {
     SetSelectedListItem(std::nullopt);
     SetListItems(std::vector<SwContentControlListItem>());
+    if (m_bDropDown && GetTextAttr())
+        GetTextAttr()->Invalidate();
 }
 
 OUString SwContentControl::GetDateString() const
@@ -658,6 +662,37 @@ SwTextNode* SwTextContentControl::GetTextNode() const
     return rFormatContentControl.GetTextNode();
 }
 
+void SwTextContentControl::Invalidate(bool bKeepPlaceholderStatus)
+{
+    SwDocShell* pDocShell = GetTextNode() ? 
GetTextNode()->GetDoc().GetDocShell() : nullptr;
+    if (!pDocShell || !pDocShell->GetWrtShell())
+        return;
+
+    // save the cursor
+    pDocShell->GetWrtShell()->Push();
+
+    // visit the control in the text (which makes any necessary visual changes)
+    // NOTE: simply going to a control indicates cancelling 
m_bShowingPlaceHolder
+    auto& rFormatContentControl = 
static_cast<SwFormatContentControl&>(GetAttr());
+    std::shared_ptr<SwContentControl> pCC = 
rFormatContentControl.GetContentControl();
+    bKeepPlaceholderStatus = bKeepPlaceholderStatus && pCC && 
pCC->GetShowingPlaceHolder();
+
+    // NOTE: simply going to a checkbox causes a toggle
+    const bool bSaveChecked = pCC && pCC->GetChecked();
+    if (pCC && pCC->GetCheckbox())
+        pCC->SetChecked(!bSaveChecked); //do a double-toggle to keep the same 
value!
+
+    pDocShell->GetWrtShell()->GotoContentControl(rFormatContentControl);
+
+    assert((!pCC || !pCC->GetCheckbox() || bSaveChecked == pCC->GetChecked())
+           && "invalidation implementation changed");
+
+    if (bKeepPlaceholderStatus)
+        pCC->SetShowingPlaceHolder(true);
+
+    pDocShell->GetWrtShell()->Pop(SwCursorShell::PopMode::DeleteCurrent);
+}
+
 void SwTextContentControl::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
     (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwTextContentControl"));
diff --git a/sw/source/ui/vba/vbacontentcontrol.cxx 
b/sw/source/ui/vba/vbacontentcontrol.cxx
index 62ee4a4f7be6..66d104c567e6 100644
--- a/sw/source/ui/vba/vbacontentcontrol.cxx
+++ b/sw/source/ui/vba/vbacontentcontrol.cxx
@@ -99,7 +99,7 @@ void SwVbaContentControl::setChecked(sal_Bool bSet)
     if (pCC->GetCheckbox() && pCC->GetChecked() != static_cast<bool>(bSet))
     {
         pCC->SetChecked(bSet);
-        //pCC->Invalidate();
+        m_rCC.Invalidate(/*bKeepPlaceholderStatus=*/false);
     }
 }
 
@@ -694,8 +694,9 @@ void SwVbaContentControl::SetCheckedSymbol(sal_Int32 
Character, const uno::Any&
 
     std::shared_ptr<SwContentControl> pCC = 
m_rCC.GetContentControl().GetContentControl();
     pCC->SetCheckedState(OUString(static_cast<sal_Unicode>(Character)));
-    //if (getChecked())
-    //    pCC->Invalidate();
+
+    if (pCC->GetCheckbox() && pCC->GetChecked())
+        m_rCC.Invalidate();
 }
 
 void SwVbaContentControl::SetUnCheckedSymbol(sal_Int32 Character, const 
uno::Any& Font)
@@ -706,8 +707,9 @@ void SwVbaContentControl::SetUnCheckedSymbol(sal_Int32 
Character, const uno::Any
 
     std::shared_ptr<SwContentControl> pCC = 
m_rCC.GetContentControl().GetContentControl();
     pCC->SetUncheckedState(OUString(static_cast<sal_Unicode>(Character)));
-    //if (!getChecked())
-    //    pCC->Invalidate();
+
+    if (pCC->GetCheckbox() && !pCC->GetChecked())
+        m_rCC.Invalidate();
 }
 
 void SwVbaContentControl::SetPlaceholderText(const uno::Any& BuildingBlock, 
const uno::Any& Range,
@@ -732,13 +734,7 @@ void SwVbaContentControl::SetPlaceholderText(const 
uno::Any& BuildingBlock, cons
         // Remove placeholder text.
         pCC->SetPlaceholderDocPart("");
     }
-    //if (getShowingPlaceholderText())
-    //{
-    //    if (!pCC->GetCheckbox())
-    //      pCC->Invalidate();
-    //    // Ensure that invalidation doesn't turn off showing placeholder as 
true
-    //    pCC->SetShowingPlaceHolder(true);
-    //}
+    m_rCC.Invalidate(/*bKeepPlaceholderStatus=true*/);
 }
 
 void SwVbaContentControl::Ungroup() { SAL_INFO("sw.vba", 
"SwVbaContentControl::UnGroup stub"); }
diff --git a/sw/source/ui/vba/vbacontentcontrollistentry.cxx 
b/sw/source/ui/vba/vbacontentcontrollistentry.cxx
index 44bfd161bcdf..20bcff0bdcb3 100644
--- a/sw/source/ui/vba/vbacontentcontrollistentry.cxx
+++ b/sw/source/ui/vba/vbacontentcontrollistentry.cxx
@@ -64,7 +64,7 @@ void SwVbaContentControlListEntry::setText(const OUString& 
rSet)
     }
     vListItems[m_nZIndex].m_aDisplayText = rSet;
     pCC->SetListItems(vListItems);
-    //pCC->Invalidate();
+    m_rCC.Invalidate();
 }
 
 OUString SwVbaContentControlListEntry::getValue()
@@ -138,7 +138,7 @@ void SwVbaContentControlListEntry::Select()
     std::shared_ptr<SwContentControl> pCC = 
m_rCC.GetContentControl().GetContentControl();
     assert(m_nZIndex < pCC->GetListItems().size());
     pCC->SetSelectedListItem(m_nZIndex);
-    //pCC->Invalidate();
+    m_rCC.Invalidate(/*bKeepPlaceholderStatus=*/false);
 }
 
 // XHelperInterface

Reply via email to