LibreOffice Module sw (master) 1
vbaformfielddropdownlistentries.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
9
10#include <xmloff/odffields.hxx>
11
13
14using namespace ::ooo::vba;
15using namespace ::com::sun::star;
16
17static uno::Sequence<OUString> lcl_getListEntries(sw::mark::IDropdownFieldmark& rDropDown)
18{
19 uno::Sequence<OUString> aSeq;
20 (*rDropDown.GetParameters())[ODF_FORMDROPDOWN_LISTENTRY] >>= aSeq;
21 return aSeq;
22}
23
24namespace
25{
26class ListEntriesEnumWrapper : public EnumerationHelper_BASE
27{
28 uno::Reference<container::XIndexAccess> mxIndexAccess;
29 sal_Int32 mnIndex;
30
31public:
32 explicit ListEntriesEnumWrapper(uno::Reference<container::XIndexAccess> xIndexAccess)
33 : mxIndexAccess(xIndexAccess)
34 , mnIndex(0)
35 {
36 }
37
38 sal_Bool SAL_CALL hasMoreElements() override { return (mnIndex < mxIndexAccess->getCount()); }
39
40 uno::Any SAL_CALL nextElement() override
41 {
42 if (mnIndex < mxIndexAccess->getCount())
43 {
44 return mxIndexAccess->getByIndex(mnIndex++);
45 }
46 throw container::NoSuchElementException();
47 }
48};
49
50class ListEntryCollectionHelper
51 : public ::cppu::WeakImplHelper<container::XIndexAccess, container::XEnumerationAccess>
52{
53private:
54 uno::Reference<XHelperInterface> mxParent;
55 uno::Reference<uno::XComponentContext> mxContext;
57
58public:
60 ListEntryCollectionHelper(uno::Reference<ov::XHelperInterface> xParent,
61 uno::Reference<uno::XComponentContext> xContext,
63 : mxParent(xParent)
64 , mxContext(xContext)
65 , m_rDropDown(rFormField)
66 {
67 }
68
69 sal_Int32 SAL_CALL getCount() override { return lcl_getListEntries(m_rDropDown).getLength(); }
70
71 uno::Any SAL_CALL getByIndex(sal_Int32 Index) override
72 {
73 if (Index < 0 || Index >= getCount())
74 throw lang::IndexOutOfBoundsException();
75
76 return uno::Any(uno::Reference<word::XListEntry>(
77 new SwVbaFormFieldDropDownListEntry(mxParent, mxContext, m_rDropDown, Index)));
78 }
79
80 uno::Type SAL_CALL getElementType() override { return cppu::UnoType<word::XListEntry>::get(); }
81
82 sal_Bool SAL_CALL hasElements() override { return getCount() != 0; }
83
84 // XEnumerationAccess
85 uno::Reference<container::XEnumeration> SAL_CALL createEnumeration() override
86 {
87 return new ListEntriesEnumWrapper(this);
88 }
89};
90}
91
93 const uno::Reference<XHelperInterface>& xParent,
94 const uno::Reference<uno::XComponentContext>& xContext,
97 xParent, xContext,
98 uno::Reference<container::XIndexAccess>(
99 new ListEntryCollectionHelper(xParent, xContext, rFormField)))
100 , m_rDropDown(rFormField)
101{
102}
103
104// XListEntries
105uno::Reference<word::XListEntry> SwVbaFormFieldDropDownListEntries::Add(const OUString& rName,
106 const uno::Any& rIndex)
107{
108 sal_Int32 nZIndex = 0;
109 rIndex >>= nZIndex;
110 // rIndex is 1-based, nZIndex is 0-based. If rIndex is not given, then add as the last choice.
111
112 // In testing with Word 2010, this gives a compile error: 'ListEntries.Add("Name", 2)'
113 // This compiles, but gets an unsupported runtime error: 'ListEntries.Add("Name", 2) = "Choice'
114 // So the only thing that actually works is to simply append: 'ListEntires.Add("Name")'
115 // but I'll still keep the expected implementation for the broken case.
116 if (!nZIndex)
117 nZIndex = SAL_MAX_INT32;
118 else
119 --nZIndex;
120 m_rDropDown.AddContent(rName + "__allowDuplicates", &nZIndex);
121 m_rDropDown.ReplaceContent(&rName, &nZIndex);
122
123 return uno::Reference<word::XListEntry>(
125}
126
128
130{
131 return lcl_getListEntries(m_rDropDown).getLength();
132}
133
134// XEnumerationAccess
136{
138}
139
140uno::Reference<container::XEnumeration> SwVbaFormFieldDropDownListEntries::createEnumeration()
141{
142 return new ListEntriesEnumWrapper(m_xIndexAccess);
143}
144
145// SwVbadropDownListEntries_BASE
147{
148 return aSource;
149}
150
152{
153 return "SwVbaFormFieldDropDownListEntries";
154}
155
157{
158 static uno::Sequence<OUString> const sNames{ "ooo.vba.word.ListEntries" };
159 return sNames;
160}
161
162/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
struct _ADOIndex Index
unotools::WeakReference< AnimationNode > mxParent
css::uno::Reference< css::uno::XComponentContext > mxContext
css::uno::WeakReference< ov::XHelperInterface > mxParent
css::uno::Reference< css::container::XIndexAccess > m_xIndexAccess
css::uno::Reference< ooo::vba::word::XListEntry > SAL_CALL Add(const OUString &rName, const css::uno::Any &rIndex) override
css::uno::Any createCollectionObject(const css::uno::Any &aSource) override
css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override
SwVbaFormFieldDropDownListEntries(const css::uno::Reference< ov::XHelperInterface > &xParent, const css::uno::Reference< css::uno::XComponentContext > &xContext, sw::mark::IDropdownFieldmark &m_rDropDown)
css::uno::Type SAL_CALL getElementType() override
css::uno::Sequence< OUString > getServiceNames() override
css::uno::Type const & get()
virtual void DelContent(sal_Int32 nDelIndex=-1)=0
virtual void ReplaceContent(const OUString *pText, sal_Int32 *pIndex)=0
virtual void AddContent(const OUString &rText, sal_Int32 *pIndex=nullptr)=0
uno::Reference< uno::XComponentContext > mxContext
Sequence< sal_Int8 > aSeq
Reference
constexpr OUStringLiteral ODF_FORMDROPDOWN_LISTENTRY
sal_uInt32 mnIndex
#define SAL_MAX_INT32
unsigned char sal_Bool
::cppu::WeakImplHelper< css::container::XEnumeration > EnumerationHelper_BASE
static uno::Sequence< OUString > lcl_getListEntries(sw::mark::IDropdownFieldmark &rDropDown)