summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Luth <justin.luth@collabora.com>2022-11-21 19:57:15 -0500
committerJustin Luth <jluth@mail.com>2022-11-25 18:09:32 +0100
commit432e5e6e33c3687cdb67ee0a64d57169a82e641d (patch)
tree1450a8babe1911aebb35ae18f302058f0d3a0ee1
parent1e83197fdd4263ca4817a6ac16f274aaee3e66fd (diff)
tdf#151548 vba ContentControls: Add word::XContentControlListEntry
make CppunitTest_sw_macros_test CPPUNIT_TEST_NAME=testVba This now allows MS Word's modern content control list boxes (combobox and dropbox) to be controlled by VBA basic. -allows getting and setting the selected list entry -allows adding/deleting/renaming/moving list entries If .DropdownListEntries.Count <> 3 Then GoTo errorhandler: .DropdownListEntries.Item(2).Select .DropdownListEntries.Item(2).Delete If .DropdownListEntries.Item(2).Text <> "infinity" If .DropdownListEntries.Item(2).Value <> "infinity and beyond" 'With .DropdownListEntries.Add("third", "3rd", 2) Dim LE As ContentControlListEntry Set LE = .DropdownListEntries.Add("third", "3rd", 2) With LE If LE.Index <> 2 Then GoTo errorhandler: If LE.Value <> "3rd" Then GoTo errorhandler: .MoveUp .MoveUp .MoveUp If .Index <> 1 Then GoTo errorhandler: .MoveDown .MoveDown If .Index <> 3 Then GoTo errorhandler: End With 'LE If .DropdownListEntries.Item(3).Text <> "third" Then GoTo errorhandler: End With 'Item 1 runOnceDropDown: With ActiveDocument.ContentControls.Item(4) If .Type <> wdContentControlComboBox Then GoTo errorhandler: .DropdownListEntries.Clear End With Change-Id: Iffebb2bd69abec1cbcfaed05b58f940664852eae Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143082 Tested-by: Jenkins Reviewed-by: Justin Luth <jluth@mail.com> Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
-rw-r--r--oovbaapi/UnoApi_oovbaapi.mk2
-rw-r--r--oovbaapi/ooo/vba/word/XContentControlListEntries.idl30
-rw-r--r--oovbaapi/ooo/vba/word/XContentControlListEntry.idl43
-rw-r--r--sw/Library_vbaswobj.mk2
-rw-r--r--sw/inc/formatcontentcontrol.hxx4
-rw-r--r--sw/qa/core/data/docm/testModernVBA.docmbin31069 -> 31991 bytes
-rw-r--r--sw/source/core/txtnode/attrcontentcontrol.cxx66
-rw-r--r--sw/source/ui/vba/vbacontentcontrol.cxx12
-rw-r--r--sw/source/ui/vba/vbacontentcontrollistentries.cxx176
-rw-r--r--sw/source/ui/vba/vbacontentcontrollistentries.hxx51
-rw-r--r--sw/source/ui/vba/vbacontentcontrollistentry.cxx156
-rw-r--r--sw/source/ui/vba/vbacontentcontrollistentry.hxx54
12 files changed, 590 insertions, 6 deletions
diff --git a/oovbaapi/UnoApi_oovbaapi.mk b/oovbaapi/UnoApi_oovbaapi.mk
index 063700762e46..dcd514f7ea3e 100644
--- a/oovbaapi/UnoApi_oovbaapi.mk
+++ b/oovbaapi/UnoApi_oovbaapi.mk
@@ -1060,6 +1060,8 @@ $(eval $(call gb_UnoApi_add_idlfiles,oovbaapi,ooo/vba/word,\
XFont \
XContentControl \
XContentControls \
+ XContentControlListEntry \
+ XContentControlListEntries \
XFormField \
XFormFields \
XFrame \
diff --git a/oovbaapi/ooo/vba/word/XContentControlListEntries.idl b/oovbaapi/ooo/vba/word/XContentControlListEntries.idl
new file mode 100644
index 000000000000..fddf2318afe0
--- /dev/null
+++ b/oovbaapi/ooo/vba/word/XContentControlListEntries.idl
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+module ooo { module vba { module word {
+
+interface XContentControlListEntry;
+interface XContentControlListEntries
+{
+ interface ooo::vba::XCollection;
+
+ /// Adds a new list item to a drop-down list or combo box content control
+ /// and returns a ContentControlListEntry object.
+ /// Entries must have a unique display Name,
+ /// Value is optional - uses Name if not specified.
+ /// Index is optional. It inserts at the end if not specified, otherwise inserted into list.
+ XContentControlListEntry Add( [in] string Name, [in] /*optional*/ any Value, [in] /*optional*/ any Index );
+
+ /// Remove all items from the dropdown list
+ void Clear();
+};
+
+}; }; };
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oovbaapi/ooo/vba/word/XContentControlListEntry.idl b/oovbaapi/ooo/vba/word/XContentControlListEntry.idl
new file mode 100644
index 000000000000..15b52a774cc1
--- /dev/null
+++ b/oovbaapi/ooo/vba/word/XContentControlListEntry.idl
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+module ooo { module vba { module word {
+
+interface XContentControlListEntry
+{
+ interface ooo::vba::XHelperInterface;
+
+ /// Returns or sets the ordinal position of a list item in the collection of list items.
+ [attribute] long Index;
+
+ /// Returns or sets a String that represents the display text of the list item.
+ [attribute] string Text;
+
+ /// Returns or sets a String that represents the programmatic value of the list item.
+ [attribute] string Value;
+
+ /// Deletes the specified item in a combo box or drop-down list content control.
+ void Delete();
+
+ /// Moves an item in a drop-down list or combo box content control down one item,
+ /// so that it is after the item that originally followed it.
+ void MoveDown();
+
+ /// Moves an item in a drop-down list or combo box content control up one item,
+ /// so that it is before the item that originally preceded it.
+ void MoveUp();
+
+ /// Selects the list entry in a drop-down list or combo box content control
+ /// and sets the text of the content control to the value of the item.
+ void Select();
+};
+
+}; }; };
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/Library_vbaswobj.mk b/sw/Library_vbaswobj.mk
index e6b45b4e2f37..efb2e35d9677 100644
--- a/sw/Library_vbaswobj.mk
+++ b/sw/Library_vbaswobj.mk
@@ -74,6 +74,8 @@ $(eval $(call gb_Library_add_exception_objects,vbaswobj,\
sw/source/ui/vba/vbacolumns \
sw/source/ui/vba/vbacontentcontrol \
sw/source/ui/vba/vbacontentcontrols \
+ sw/source/ui/vba/vbacontentcontrollistentry \
+ sw/source/ui/vba/vbacontentcontrollistentries \
sw/source/ui/vba/vbaformfield \
sw/source/ui/vba/vbaformfields \
sw/source/ui/vba/vbaformfieldcheckbox \
diff --git a/sw/inc/formatcontentcontrol.hxx b/sw/inc/formatcontentcontrol.hxx
index 3ac6848e388f..415132409e10 100644
--- a/sw/inc/formatcontentcontrol.hxx
+++ b/sw/inc/formatcontentcontrol.hxx
@@ -245,6 +245,10 @@ public:
m_aListItems = rListItems;
}
+ bool AddListItem(size_t nZIndex, const OUString& rDisplayText, const OUString& rValue);
+ void DeleteListItem(size_t nZIndex);
+ void ClearListItems();
+
void SetPicture(bool bPicture) { m_bPicture = bPicture; }
bool GetPicture() const { return m_bPicture; }
diff --git a/sw/qa/core/data/docm/testModernVBA.docm b/sw/qa/core/data/docm/testModernVBA.docm
index faa85768884b..dd96686659ca 100644
--- a/sw/qa/core/data/docm/testModernVBA.docm
+++ b/sw/qa/core/data/docm/testModernVBA.docm
Binary files differ
diff --git a/sw/source/core/txtnode/attrcontentcontrol.cxx b/sw/source/core/txtnode/attrcontentcontrol.cxx
index 33ee4faa1e07..118d60258f27 100644
--- a/sw/source/core/txtnode/attrcontentcontrol.cxx
+++ b/sw/source/core/txtnode/attrcontentcontrol.cxx
@@ -231,6 +231,72 @@ void SwContentControl::SwClientNotify(const SwModify&, const SfxHint& rHint)
}
}
+bool SwContentControl::AddListItem(size_t nZIndex, const OUString& rDisplayText,
+ const OUString& rValue)
+{
+ SwContentControlListItem aListItem;
+ if (rValue.isEmpty())
+ {
+ if (rDisplayText.isEmpty())
+ return false;
+ aListItem.m_aValue = rDisplayText;
+ }
+ else
+ {
+ aListItem.m_aValue = rValue;
+ aListItem.m_aDisplayText = rDisplayText;
+ }
+
+ // Avoid adding duplicates
+ for (auto& rListItem : GetListItems())
+ {
+ if (rListItem == aListItem)
+ return false;
+ }
+
+ const size_t nLen = GetListItems().size();
+ nZIndex = std::min(nZIndex, nLen);
+ const std::optional<size_t> oSelected = GetSelectedListItem();
+ if (oSelected && *oSelected >= nZIndex)
+ {
+ if (*oSelected < nLen)
+ SetSelectedListItem(*oSelected + 1);
+ }
+ std::vector<SwContentControlListItem> vListItems = GetListItems();
+ vListItems.insert(vListItems.begin() + nZIndex, aListItem);
+ SetListItems(vListItems);
+ return true;
+}
+
+void SwContentControl::DeleteListItem(size_t nZIndex)
+{
+ if (nZIndex >= GetListItems().size())
+ return;
+
+ const std::optional<size_t> oSelected = GetSelectedListItem();
+ if (oSelected)
+ {
+ if (*oSelected == nZIndex)
+ {
+ SetSelectedListItem(std::nullopt);
+ //Invalidate();
+ }
+ else if (*oSelected < nZIndex)
+ SetSelectedListItem(*oSelected - 1);
+ }
+
+ std::vector<SwContentControlListItem> vListItems = GetListItems();
+ vListItems.erase(vListItems.begin() + nZIndex);
+ SetListItems(vListItems);
+ return;
+}
+
+void SwContentControl::ClearListItems()
+{
+ SetSelectedListItem(std::nullopt);
+ SetListItems(std::vector<SwContentControlListItem>());
+}
+
OUString SwContentControl::GetDateString() const
{
SwDoc& rDoc = m_pTextNode->GetDoc();
diff --git a/sw/source/ui/vba/vbacontentcontrol.cxx b/sw/source/ui/vba/vbacontentcontrol.cxx
index 3d51d8bd4448..62ee4a4f7be6 100644
--- a/sw/source/ui/vba/vbacontentcontrol.cxx
+++ b/sw/source/ui/vba/vbacontentcontrol.cxx
@@ -17,7 +17,7 @@
#include <ndtxt.hxx>
#include "vbacontentcontrol.hxx"
-//#include "vbacontentcontroldropdownlistentries.hxx"
+#include "vbacontentcontrollistentries.hxx"
using namespace ::ooo::vba;
using namespace ::com::sun::star;
@@ -463,11 +463,11 @@ sal_Int32 SwVbaContentControl::getDateDisplayLocale()
uno::Any SwVbaContentControl::getDropdownListEntries()
{
std::shared_ptr<SwContentControl> pCC = m_rCC.GetContentControl().GetContentControl();
- //if (!pCC->GetDropDown() && !pCC->GetComboBox())
- // return uno::Any();
- //return uno::Any(uno::Reference<XCollection>(
- // new SwVbaContentControlDropDownListEntries(this, mxContext, m_rCC)));
- return uno::Any();
+ if (!pCC->GetDropDown() && !pCC->GetComboBox())
+ return uno::Any();
+
+ return uno::Any(
+ uno::Reference<XCollection>(new SwVbaContentControlListEntries(this, mxContext, m_rCC)));
}
OUString SwVbaContentControl::getID()
diff --git a/sw/source/ui/vba/vbacontentcontrollistentries.cxx b/sw/source/ui/vba/vbacontentcontrollistentries.cxx
new file mode 100644
index 000000000000..a96d6b3ad3dd
--- /dev/null
+++ b/sw/source/ui/vba/vbacontentcontrollistentries.cxx
@@ -0,0 +1,176 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "vbacontentcontrollistentries.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+namespace
+{
+class ContentControlListEntriesEnumWrapper : public EnumerationHelper_BASE
+{
+ uno::Reference<container::XIndexAccess> mxIndexAccess;
+ sal_Int32 nIndex;
+
+public:
+ explicit ContentControlListEntriesEnumWrapper(
+ uno::Reference<container::XIndexAccess> xIndexAccess)
+ : mxIndexAccess(xIndexAccess)
+ , nIndex(0)
+ {
+ }
+
+ virtual sal_Bool SAL_CALL hasMoreElements() override
+ {
+ return (nIndex < mxIndexAccess->getCount());
+ }
+
+ virtual uno::Any SAL_CALL nextElement() override
+ {
+ if (nIndex < mxIndexAccess->getCount())
+ {
+ return mxIndexAccess->getByIndex(nIndex++);
+ }
+ throw container::NoSuchElementException();
+ }
+};
+
+class ContentControlListEntryCollectionHelper
+ : public ::cppu::WeakImplHelper<container::XIndexAccess, container::XEnumerationAccess>
+{
+private:
+ uno::Reference<XHelperInterface> mxParent;
+ uno::Reference<uno::XComponentContext> mxContext;
+ SwTextContentControl& m_rCC;
+
+public:
+ /// @throws css::uno::RuntimeException
+ ContentControlListEntryCollectionHelper(uno::Reference<ov::XHelperInterface> xParent,
+ uno::Reference<uno::XComponentContext> xContext,
+ SwTextContentControl& rCC)
+ : mxParent(xParent)
+ , mxContext(xContext)
+ , m_rCC(rCC)
+ {
+ }
+
+ sal_Int32 SAL_CALL getCount() override
+ {
+ return m_rCC.GetContentControl().GetContentControl()->GetListItems().size();
+ }
+
+ uno::Any SAL_CALL getByIndex(sal_Int32 Index) override
+ {
+ if (Index < 0 || Index >= getCount())
+ throw lang::IndexOutOfBoundsException();
+
+ return uno::Any(uno::Reference<word::XContentControlListEntry>(
+ new SwVbaContentControlListEntry(mxParent, mxContext, m_rCC, Index)));
+ }
+
+ uno::Type SAL_CALL getElementType() override
+ {
+ return cppu::UnoType<word::XContentControlListEntry>::get();
+ }
+
+ sal_Bool SAL_CALL hasElements() override { return getCount() != 0; }
+
+ // XEnumerationAccess
+ uno::Reference<container::XEnumeration> SAL_CALL createEnumeration() override
+ {
+ return new ContentControlListEntriesEnumWrapper(this);
+ }
+};
+}
+
+/**
+ * DropDownLists and ComboBoxes contain a list of name/value pairs to chose from.
+ * Use of DropDownListEntries from any other control is invalid.
+ */
+SwVbaContentControlListEntries::SwVbaContentControlListEntries(
+ const uno::Reference<XHelperInterface>& xParent,
+ const uno::Reference<uno::XComponentContext>& xContext, SwTextContentControl& rCC)
+ : SwVbaContentControlListEntries_BASE(
+ xParent, xContext,
+ uno::Reference<container::XIndexAccess>(
+ new ContentControlListEntryCollectionHelper(xParent, xContext, rCC)))
+ , m_rCC(rCC)
+{
+}
+
+uno::Reference<word::XContentControlListEntry>
+SwVbaContentControlListEntries::Add(const OUString& rName, const uno::Any& rValue,
+ const uno::Any& rIndex)
+{
+ // No duplicate Names allowed in VBA
+ std::shared_ptr<SwContentControl> pCC = m_rCC.GetContentControl().GetContentControl();
+ for (auto& rListItem : pCC->GetListItems())
+ {
+ if (rListItem.ToString() == rName)
+ return uno::Reference<word::XContentControlListEntry>();
+ }
+
+ sal_Int32 nZIndex = SAL_MAX_INT32;
+ rIndex >>= nZIndex;
+ // rIndex is 1-based, nZIndex is 0-based. If rIndex is not given, then add as the last choice.
+ assert(nZIndex > 0);
+ --nZIndex;
+ nZIndex = std::min(static_cast<size_t>(nZIndex), pCC->GetListItems().size());
+
+ OUString sValue;
+ rValue >>= sValue;
+ if (pCC->AddListItem(nZIndex, rName, sValue))
+ {
+ return uno::Reference<word::XContentControlListEntry>(
+ new SwVbaContentControlListEntry(mxParent, mxContext, m_rCC, nZIndex));
+ }
+
+ return uno::Reference<word::XContentControlListEntry>();
+}
+
+void SwVbaContentControlListEntries::Clear()
+{
+ m_rCC.GetContentControl().GetContentControl()->ClearListItems();
+}
+
+sal_Int32 SwVbaContentControlListEntries::getCount()
+{
+ return m_rCC.GetContentControl().GetContentControl()->GetListItems().size();
+}
+
+// XEnumerationAccess
+uno::Type SwVbaContentControlListEntries::getElementType()
+{
+ return cppu::UnoType<word::XContentControlListEntry>::get();
+}
+
+uno::Reference<container::XEnumeration> SwVbaContentControlListEntries::createEnumeration()
+{
+ return new ContentControlListEntriesEnumWrapper(m_xIndexAccess);
+}
+
+// SwVbaContentControlListEntries_BASE
+uno::Any SwVbaContentControlListEntries::createCollectionObject(const uno::Any& aSource)
+{
+ return aSource;
+}
+
+OUString SwVbaContentControlListEntries::getServiceImplName()
+{
+ return "SwVbaContentControlListEntries";
+}
+
+uno::Sequence<OUString> SwVbaContentControlListEntries::getServiceNames()
+{
+ static uno::Sequence<OUString> const sNames{ "ooo.vba.word.ContentControlListEntries" };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbacontentcontrollistentries.hxx b/sw/source/ui/vba/vbacontentcontrollistentries.hxx
new file mode 100644
index 000000000000..65ee6ac814a9
--- /dev/null
+++ b/sw/source/ui/vba/vbacontentcontrollistentries.hxx
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#pragma once
+
+#include <ooo/vba/word/XContentControlListEntries.hpp>
+#include <ooo/vba/word/XContentControlListEntry.hpp>
+
+#include <vbahelper/vbacollectionimpl.hxx>
+
+#include <textcontentcontrol.hxx>
+
+#include "vbacontentcontrollistentries.hxx"
+#include "vbacontentcontrollistentry.hxx"
+
+typedef CollTestImplHelper<ooo::vba::word::XContentControlListEntries>
+ SwVbaContentControlListEntries_BASE;
+
+class SwVbaContentControlListEntries : public SwVbaContentControlListEntries_BASE
+{
+private:
+ SwTextContentControl& m_rCC;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaContentControlListEntries(const css::uno::Reference<ov::XHelperInterface>& xParent,
+ const css::uno::Reference<css::uno::XComponentContext>& xContext,
+ SwTextContentControl& rCC);
+
+ // XContentControlListEntries
+ css::uno::Reference<ooo::vba::word::XContentControlListEntry> SAL_CALL
+ Add(const OUString& rName, const css::uno::Any& rValue, const css::uno::Any& rIndex) override;
+ void SAL_CALL Clear() override;
+ sal_Int32 SAL_CALL getCount() override;
+
+ // XEnumerationAccess
+ css::uno::Type SAL_CALL getElementType() override;
+ css::uno::Reference<css::container::XEnumeration> SAL_CALL createEnumeration() override;
+
+ // SwVbaContentControlListEntries_BASE
+ css::uno::Any createCollectionObject(const css::uno::Any& aSource) override;
+ OUString getServiceImplName() override;
+ css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbacontentcontrollistentry.cxx b/sw/source/ui/vba/vbacontentcontrollistentry.cxx
new file mode 100644
index 000000000000..7be9c758f19d
--- /dev/null
+++ b/sw/source/ui/vba/vbacontentcontrollistentry.cxx
@@ -0,0 +1,156 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "vbacontentcontrollistentry.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaContentControlListEntry::SwVbaContentControlListEntry(
+ const uno::Reference<ooo::vba::XHelperInterface>& rParent,
+ const uno::Reference<uno::XComponentContext>& rContext, SwTextContentControl& rCC,
+ size_t nZIndex)
+ : SwVbaContentControlListEntry_BASE(rParent, rContext)
+ , m_rCC(rCC)
+ , m_nZIndex(nZIndex)
+{
+}
+
+SwVbaContentControlListEntry::~SwVbaContentControlListEntry() {}
+
+sal_Int32 SwVbaContentControlListEntry::getIndex() { return m_nZIndex + 1; }
+
+void SwVbaContentControlListEntry::setIndex(sal_Int32 nSet)
+{
+ if (nSet < 1 || static_cast<size_t>(nSet) == m_nZIndex + 1)
+ return;
+
+ std::shared_ptr<SwContentControl> pCC = m_rCC.GetContentControl().GetContentControl();
+ // Given a one-based index to set to
+ size_t nIndex = std::min(static_cast<size_t>(nSet), pCC->GetListItems().size());
+ // change to zero-based index
+ --nIndex;
+ while (nIndex < m_nZIndex)
+ MoveUp();
+ while (m_nZIndex < nIndex)
+ MoveDown();
+}
+
+OUString SwVbaContentControlListEntry::getText()
+{
+ const std::shared_ptr<SwContentControl> pCC = m_rCC.GetContentControl().GetContentControl();
+ assert(m_nZIndex < pCC->GetListItems().size());
+ const SwContentControlListItem& rListItem = pCC->GetListItems()[m_nZIndex];
+ return rListItem.ToString();
+}
+
+void SwVbaContentControlListEntry::setText(const OUString& rSet)
+{
+ const std::shared_ptr<SwContentControl> pCC = m_rCC.GetContentControl().GetContentControl();
+ std::vector<SwContentControlListItem> vListItems = pCC->GetListItems();
+ assert(m_nZIndex < vListItems.size());
+
+ // prevent duplicates
+ for (size_t i = 0; i < vListItems.size(); ++i)
+ {
+ if (vListItems[i].ToString() == rSet)
+ return;
+ }
+ vListItems[m_nZIndex].m_aDisplayText = rSet;
+ pCC->SetListItems(vListItems);
+ //pCC->Invalidate();
+}
+
+OUString SwVbaContentControlListEntry::getValue()
+{
+ const std::shared_ptr<SwContentControl> pCC = m_rCC.GetContentControl().GetContentControl();
+ assert(m_nZIndex < pCC->GetListItems().size());
+ const SwContentControlListItem& rListItem = pCC->GetListItems()[m_nZIndex];
+
+ return rListItem.m_aValue;
+}
+
+void SwVbaContentControlListEntry::setValue(const OUString& rSet)
+{
+ const std::shared_ptr<SwContentControl> pCC = m_rCC.GetContentControl().GetContentControl();
+ assert(m_nZIndex < pCC->GetListItems().size());
+ std::vector<SwContentControlListItem> vListItems = pCC->GetListItems();
+ vListItems[m_nZIndex].m_aValue = rSet;
+ pCC->SetListItems(vListItems);
+}
+
+void SwVbaContentControlListEntry::Delete()
+{
+ std::shared_ptr<SwContentControl> pCC = m_rCC.GetContentControl().GetContentControl();
+ pCC->DeleteListItem(m_nZIndex);
+}
+
+void SwVbaContentControlListEntry::MoveDown()
+{
+ std::shared_ptr<SwContentControl> pCC = m_rCC.GetContentControl().GetContentControl();
+ // if already at last positin, can't move down
+ if (m_nZIndex >= pCC->GetListItems().size() - 1)
+ return;
+
+ const std::optional<size_t>& oSelected = pCC->GetSelectedListItem();
+ if (oSelected)
+ {
+ if (*oSelected == m_nZIndex)
+ pCC->SetSelectedListItem(m_nZIndex + 1);
+ else if (*oSelected == m_nZIndex + 1)
+ pCC->SetSelectedListItem(*oSelected - 1);
+ }
+ std::vector<SwContentControlListItem> vListItems = pCC->GetListItems();
+ std::swap(vListItems[m_nZIndex], vListItems[m_nZIndex + 1]);
+ pCC->SetListItems(vListItems);
+ ++m_nZIndex;
+}
+
+void SwVbaContentControlListEntry::MoveUp()
+{
+ std::shared_ptr<SwContentControl> pCC = m_rCC.GetContentControl().GetContentControl();
+ // if already at position 0, can't move up
+ if (!m_nZIndex || m_nZIndex >= pCC->GetListItems().size())
+ return;
+
+ const std::optional<size_t>& oSelected = pCC->GetSelectedListItem();
+ if (oSelected)
+ {
+ if (*oSelected == m_nZIndex)
+ pCC->SetSelectedListItem(m_nZIndex - 1);
+ else if (*oSelected == m_nZIndex - 1)
+ pCC->SetSelectedListItem(*oSelected + 1);
+ }
+ std::vector<SwContentControlListItem> vListItems = pCC->GetListItems();
+ std::swap(vListItems[m_nZIndex], vListItems[m_nZIndex - 1]);
+ pCC->SetListItems(vListItems);
+ --m_nZIndex;
+}
+
+void SwVbaContentControlListEntry::Select()
+{
+ std::shared_ptr<SwContentControl> pCC = m_rCC.GetContentControl().GetContentControl();
+ assert(m_nZIndex < pCC->GetListItems().size());
+ pCC->SetSelectedListItem(m_nZIndex);
+ //pCC->Invalidate();
+}
+
+// XHelperInterface
+OUString SwVbaContentControlListEntry::getServiceImplName()
+{
+ return "SwVbaContentControlListEntry";
+}
+
+uno::Sequence<OUString> SwVbaContentControlListEntry::getServiceNames()
+{
+ static uno::Sequence<OUString> const aServiceNames{ "ooo.vba.word.ContentControlListEntry" };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbacontentcontrollistentry.hxx b/sw/source/ui/vba/vbacontentcontrollistentry.hxx
new file mode 100644
index 000000000000..e6e3c341afe0
--- /dev/null
+++ b/sw/source/ui/vba/vbacontentcontrollistentry.hxx
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#pragma once
+
+#include <ooo/vba/word/XContentControlListEntry.hpp>
+
+#include <vbahelper/vbahelperinterface.hxx>
+
+#include <textcontentcontrol.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XContentControlListEntry>
+ SwVbaContentControlListEntry_BASE;
+
+class SwVbaContentControlListEntry : public SwVbaContentControlListEntry_BASE
+{
+private:
+ SwTextContentControl& m_rCC;
+ // All LO and internal UNO functions are 0-based. Convert to 1-based when sending to VBA
+ size_t m_nZIndex;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaContentControlListEntry(const css::uno::Reference<ooo::vba::XHelperInterface>& rParent,
+ const css::uno::Reference<css::uno::XComponentContext>& rContext,
+ SwTextContentControl& rCC, size_t nZIndex);
+ ~SwVbaContentControlListEntry() override;
+
+ // XContentControlListEntry
+ sal_Int32 SAL_CALL getIndex() override;
+ void SAL_CALL setIndex(sal_Int32 nSet) override;
+
+ OUString SAL_CALL getText() override;
+ void SAL_CALL setText(const OUString& sSet) override;
+
+ OUString SAL_CALL getValue() override;
+ void SAL_CALL setValue(const OUString& sSet) override;
+
+ void SAL_CALL Delete() override;
+ void SAL_CALL MoveDown() override;
+ void SAL_CALL MoveUp() override;
+ void SAL_CALL Select() override;
+
+ // XHelperInterface
+ OUString getServiceImplName() override;
+ css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */