diff options
author | Justin Luth <justin.luth@collabora.com> | 2022-11-21 19:57:15 -0500 |
---|---|---|
committer | Justin Luth <jluth@mail.com> | 2022-11-25 18:09:32 +0100 |
commit | 432e5e6e33c3687cdb67ee0a64d57169a82e641d (patch) | |
tree | 1450a8babe1911aebb35ae18f302058f0d3a0ee1 | |
parent | 1e83197fdd4263ca4817a6ac16f274aaee3e66fd (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.mk | 2 | ||||
-rw-r--r-- | oovbaapi/ooo/vba/word/XContentControlListEntries.idl | 30 | ||||
-rw-r--r-- | oovbaapi/ooo/vba/word/XContentControlListEntry.idl | 43 | ||||
-rw-r--r-- | sw/Library_vbaswobj.mk | 2 | ||||
-rw-r--r-- | sw/inc/formatcontentcontrol.hxx | 4 | ||||
-rw-r--r-- | sw/qa/core/data/docm/testModernVBA.docm | bin | 31069 -> 31991 bytes | |||
-rw-r--r-- | sw/source/core/txtnode/attrcontentcontrol.cxx | 66 | ||||
-rw-r--r-- | sw/source/ui/vba/vbacontentcontrol.cxx | 12 | ||||
-rw-r--r-- | sw/source/ui/vba/vbacontentcontrollistentries.cxx | 176 | ||||
-rw-r--r-- | sw/source/ui/vba/vbacontentcontrollistentries.hxx | 51 | ||||
-rw-r--r-- | sw/source/ui/vba/vbacontentcontrollistentry.cxx | 156 | ||||
-rw-r--r-- | sw/source/ui/vba/vbacontentcontrollistentry.hxx | 54 |
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 Binary files differindex faa85768884b..dd96686659ca 100644 --- a/sw/qa/core/data/docm/testModernVBA.docm +++ b/sw/qa/core/data/docm/testModernVBA.docm 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: */ |