LibreOffice Module sw (master) 1
vbaformfields.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
11#include <sal/log.hxx>
12
13#include <doc.hxx>
14#include <docsh.hxx>
16
17#include "vbaformfield.hxx"
18#include "vbaformfields.hxx"
19#include "wordvbahelper.hxx"
20
21using namespace ::ooo::vba;
22using namespace ::com::sun::star;
23
24// Helper function to access the fieldmarks
25// @param rIndex serves multiple purposes
26// [in] -1 to indicate searching using the provided name, SAL_MAX_INT32 for totals
27// [out] rIndex indicates the found index, or the total number of fieldmarks
28static sw::mark::IFieldmark* lcl_getFieldmark(std::string_view rName, sal_Int32& rIndex,
29 const uno::Reference<frame::XModel>& xModel,
30 uno::Sequence<OUString>* pElementNames = nullptr)
31
32{
34 if (!pDoc)
35 return nullptr;
36
37 IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
38 if (!pMarkAccess)
39 return nullptr;
40
41 sal_Int32 nCounter = 0;
42 std::vector<OUString> vElementNames;
44 while (aIter != pMarkAccess->getFieldmarksEnd())
45 {
46 switch (IDocumentMarkAccess::GetType(**aIter))
47 {
51 {
52 if (rIndex < 0
53 && (*aIter)->GetName().equalsIgnoreAsciiCase(OUString::fromUtf8(rName)))
54 {
55 rIndex = nCounter;
56 return dynamic_cast<sw::mark::IFieldmark*>(*aIter);
57 }
58 else if (rIndex == nCounter)
59 return dynamic_cast<sw::mark::IFieldmark*>(*aIter);
60
61 ++nCounter;
62 if (pElementNames)
63 vElementNames.push_back((*aIter)->GetName());
64 break;
65 }
66 default:;
67 }
68 aIter++;
69 }
70 rIndex = nCounter;
71 if (pElementNames)
72 *pElementNames = comphelper::containerToSequence(vElementNames);
73 return nullptr;
74}
75
76namespace
77{
78class FormFieldsEnumWrapper : public EnumerationHelper_BASE
79{
80 uno::Reference<container::XIndexAccess> mxIndexAccess;
81 sal_Int32 mnIndex;
82
83public:
84 explicit FormFieldsEnumWrapper(uno::Reference<container::XIndexAccess> xIndexAccess)
85 : mxIndexAccess(xIndexAccess)
86 , mnIndex(0)
87 {
88 }
89 sal_Bool SAL_CALL hasMoreElements() override { return (mnIndex < mxIndexAccess->getCount()); }
90
91 uno::Any SAL_CALL nextElement() override
92 {
93 if (mnIndex < mxIndexAccess->getCount())
94 {
95 return mxIndexAccess->getByIndex(mnIndex++);
96 }
97 throw container::NoSuchElementException();
98 }
99};
100
101class FormFieldCollectionHelper
102 : public ::cppu::WeakImplHelper<container::XNameAccess, container::XIndexAccess,
103 container::XEnumerationAccess>
104{
105private:
106 uno::Reference<XHelperInterface> mxParent;
107 uno::Reference<uno::XComponentContext> mxContext;
108 uno::Reference<text::XTextDocument> mxTextDocument;
109 sw::mark::IFieldmark* m_pCache;
110
111public:
113 FormFieldCollectionHelper(uno::Reference<ov::XHelperInterface> xParent,
114 uno::Reference<uno::XComponentContext> xContext,
115 uno::Reference<text::XTextDocument> xTextDocument)
116 : mxParent(std::move(xParent))
117 , mxContext(std::move(xContext))
118 , mxTextDocument(std::move(xTextDocument))
119 , m_pCache(nullptr)
120 {
121 }
122
123 // XIndexAccess
124 sal_Int32 SAL_CALL getCount() override
125 {
126 sal_Int32 nCount = SAL_MAX_INT32;
127 lcl_getFieldmark("", nCount, mxTextDocument);
128 return nCount == SAL_MAX_INT32 ? 0 : nCount;
129 }
130
131 uno::Any SAL_CALL getByIndex(sal_Int32 Index) override
132 {
133 m_pCache = lcl_getFieldmark("", Index, mxTextDocument);
134 if (!m_pCache)
135 throw lang::IndexOutOfBoundsException();
136
137 return uno::Any(uno::Reference<word::XFormField>(
138 new SwVbaFormField(mxParent, mxContext, mxTextDocument, *m_pCache)));
139 }
140
141 // XNameAccess
142 uno::Sequence<OUString> SAL_CALL getElementNames() override
143 {
144 sal_Int32 nCount = SAL_MAX_INT32;
145 uno::Sequence<OUString> aSeq;
146 lcl_getFieldmark("", nCount, mxTextDocument, &aSeq);
147 return aSeq;
148 }
149
150 uno::Any SAL_CALL getByName(const OUString& aName) override
151 {
152 if (!hasByName(aName))
153 throw container::NoSuchElementException();
154
155 return uno::Any(uno::Reference<word::XFormField>(
156 new SwVbaFormField(mxParent, mxContext, mxTextDocument, *m_pCache)));
157 }
158
159 sal_Bool SAL_CALL hasByName(const OUString& aName) override
160 {
161 sal_Int32 nCount = -1;
162 m_pCache = lcl_getFieldmark(aName.toUtf8(), nCount, mxTextDocument);
163 return m_pCache != nullptr;
164 }
165
166 // XElementAccess
167 uno::Type SAL_CALL getElementType() override { return cppu::UnoType<word::XFormField>::get(); }
168
169 sal_Bool SAL_CALL hasElements() override { return getCount() != 0; }
170
171 // XEnumerationAccess
172 uno::Reference<container::XEnumeration> SAL_CALL createEnumeration() override
173 {
174 return new FormFieldsEnumWrapper(this);
175 }
176};
177}
178
179SwVbaFormFields::SwVbaFormFields(const uno::Reference<XHelperInterface>& xParent,
180 const uno::Reference<uno::XComponentContext>& xContext,
181 const uno::Reference<text::XTextDocument>& xTextDocument)
182 : SwVbaFormFields_BASE(xParent, xContext,
183 uno::Reference<container::XIndexAccess>(
184 new FormFieldCollectionHelper(xParent, xContext, xTextDocument)))
185{
186}
187
189{
190 SAL_INFO("sw.vba", "SwVbaFormFields::getShaded stub");
191 return false;
192}
193
195{
196 SAL_INFO("sw.vba", "SwVbaFormFields::setShaded stub");
197}
198
199// uno::Reference<ooo::vba::word::XFormField> SwVbaFormFields::Add(const uno::Any& Range,
200// sal_Int32 Type)
201// {
202// sw::mark::IFieldmark* pFieldmark = nullptr;
203// switch (Type)
204// {
205// case ooo::vba::word::WdFieldType::wdFieldFormCheckBox:
206// break;
207// case ooo::vba::word::WdFieldType::wdFieldFormDropDown:
208// break;
209// case ooo::vba::word::WdFieldType::wdFieldFormTextInput:
210// default:;
211// }
212//
213// return uno::Reference<ooo::vba::word::XFormField>(
214// new SwVbaFormField(mxParent, mxContext, m_xTextDocument, *pFieldmark));
215// }
216
217// XEnumerationAccess
219
220uno::Reference<container::XEnumeration> SwVbaFormFields::createEnumeration()
221{
222 return new FormFieldsEnumWrapper(m_xIndexAccess);
223}
224
226
227OUString SwVbaFormFields::getServiceImplName() { return "SwVbaFormFields"; }
228
229uno::Sequence<OUString> SwVbaFormFields::getServiceNames()
230{
231 static uno::Sequence<OUString> const sNames{ "ooo.vba.word.FormFields" };
232 return sNames;
233}
234
235/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
struct _ADOIndex Index
unotools::WeakReference< AnimationNode > mxParent
wrapper iterator: wraps iterator of implementation while hiding MarkBase class; only IMark instances ...
Provides access to the marks of a document.
virtual const_iterator_t getFieldmarksBegin() const =0
returns a STL-like random access iterator to the begin of the sequence of fieldmarks.
virtual const_iterator_t getFieldmarksEnd() const =0
returns a STL-like random access iterator to the end of the sequence of fieldmarks.
static SW_DLLPUBLIC MarkType GetType(const ::sw::mark::IMark &rMark)
Returns the MarkType used to create the mark.
Definition: docbm.cxx:502
css::uno::Reference< css::container::XIndexAccess > m_xIndexAccess
SwDoc * GetDoc()
returns Doc. But be careful!
Definition: docsh.hxx:204
Definition: doc.hxx:197
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1890
SwVbaFormFields(const css::uno::Reference< ov::XHelperInterface > &xParent, const css::uno::Reference< css::uno::XComponentContext > &xContext, const css::uno::Reference< css::text::XTextDocument > &xTextDocument)
css::uno::Any createCollectionObject(const css::uno::Any &aSource) override
OUString getServiceImplName() override
css::uno::Sequence< OUString > getServiceNames() override
void SAL_CALL setShaded(sal_Bool bSet) override
sal_Bool SAL_CALL getShaded() override
css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override
css::uno::Type SAL_CALL getElementType() override
css::uno::Type const & get()
int nCount
uno::Reference< uno::XComponentContext > mxContext
FilterCache * m_pCache
OUString aName
Sequence< sal_Int8 > aSeq
#define SAL_INFO(area, stream)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
Reference
SwDocShell * getDocShell(const uno::Reference< frame::XModel > &xModel)
Reference< XModel > xModel
sal_uInt32 mnIndex
#define SAL_MAX_INT32
unsigned char sal_Bool
::cppu::WeakImplHelper< css::container::XEnumeration > EnumerationHelper_BASE
static sw::mark::IFieldmark * lcl_getFieldmark(std::string_view rName, sal_Int32 &rIndex, const uno::Reference< frame::XModel > &xModel, uno::Sequence< OUString > *pElementNames=nullptr)