1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
10 #include <comphelper/sequence.hxx>
11 #include <sal/log.hxx>
15 #include <IDocumentMarkAccess.hxx>
17 #include "vbaformfield.hxx"
18 #include "vbaformfields.hxx"
19 #include "wordvbahelper.hxx"
20 #include <unotxdoc.hxx>
22 using namespace ::ooo::vba
;
23 using namespace ::com::sun::star
;
25 // Helper function to access the fieldmarks
26 // @param rIndex serves multiple purposes
27 // [in] -1 to indicate searching using the provided name, SAL_MAX_INT32 for totals
28 // [out] rIndex indicates the found index, or the total number of fieldmarks
29 static sw::mark::Fieldmark
* lcl_getFieldmark(std::string_view rName
, sal_Int32
& rIndex
,
30 const rtl::Reference
<SwXTextDocument
>& xModel
,
31 uno::Sequence
<OUString
>* pElementNames
= nullptr)
34 SwDoc
* pDoc
= xModel
->GetDocShell()->GetDoc();
38 IDocumentMarkAccess
* pMarkAccess
= pDoc
->getIDocumentMarkAccess();
42 sal_Int32 nCounter
= 0;
43 std::vector
<OUString
> vElementNames
;
44 auto aIter
= pMarkAccess
->getFieldmarksBegin();
45 while (aIter
!= pMarkAccess
->getFieldmarksEnd())
47 switch (IDocumentMarkAccess::GetType(**aIter
))
49 case IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK
:
50 case IDocumentMarkAccess::MarkType::DROPDOWN_FIELDMARK
:
51 case IDocumentMarkAccess::MarkType::TEXT_FIELDMARK
:
54 && (*aIter
)->GetName().equalsIgnoreAsciiCase(OUString::fromUtf8(rName
)))
59 else if (rIndex
== nCounter
)
64 vElementNames
.push_back((*aIter
)->GetName());
73 *pElementNames
= comphelper::containerToSequence(vElementNames
);
79 class FormFieldsEnumWrapper
: public EnumerationHelper_BASE
81 uno::Reference
<container::XIndexAccess
> mxIndexAccess
;
85 explicit FormFieldsEnumWrapper(const uno::Reference
<container::XIndexAccess
>& xIndexAccess
)
86 : mxIndexAccess(xIndexAccess
)
90 sal_Bool SAL_CALL
hasMoreElements() override
{ return (mnIndex
< mxIndexAccess
->getCount()); }
92 uno::Any SAL_CALL
nextElement() override
94 if (mnIndex
< mxIndexAccess
->getCount())
96 return mxIndexAccess
->getByIndex(mnIndex
++);
98 throw container::NoSuchElementException();
102 class FormFieldCollectionHelper
103 : public ::cppu::WeakImplHelper
<container::XNameAccess
, container::XIndexAccess
,
104 container::XEnumerationAccess
>
107 uno::Reference
<XHelperInterface
> mxParent
;
108 uno::Reference
<uno::XComponentContext
> mxContext
;
109 rtl::Reference
<SwXTextDocument
> mxTextDocument
;
110 sw::mark::Fieldmark
* m_pCache
;
113 /// @throws css::uno::RuntimeException
114 FormFieldCollectionHelper(uno::Reference
<ov::XHelperInterface
> xParent
,
115 uno::Reference
<uno::XComponentContext
> xContext
,
116 rtl::Reference
<SwXTextDocument
> xTextDocument
)
117 : mxParent(std::move(xParent
))
118 , mxContext(std::move(xContext
))
119 , mxTextDocument(std::move(xTextDocument
))
125 sal_Int32 SAL_CALL
getCount() override
127 sal_Int32 nCount
= SAL_MAX_INT32
;
128 lcl_getFieldmark("", nCount
, mxTextDocument
);
129 return nCount
== SAL_MAX_INT32
? 0 : nCount
;
132 uno::Any SAL_CALL
getByIndex(sal_Int32 Index
) override
134 m_pCache
= lcl_getFieldmark("", Index
, mxTextDocument
);
136 throw lang::IndexOutOfBoundsException();
138 return uno::Any(uno::Reference
<word::XFormField
>(
139 new SwVbaFormField(mxParent
, mxContext
, mxTextDocument
, *m_pCache
)));
143 uno::Sequence
<OUString
> SAL_CALL
getElementNames() override
145 sal_Int32 nCount
= SAL_MAX_INT32
;
146 uno::Sequence
<OUString
> aSeq
;
147 lcl_getFieldmark("", nCount
, mxTextDocument
, &aSeq
);
151 uno::Any SAL_CALL
getByName(const OUString
& aName
) override
153 if (!hasByName(aName
))
154 throw container::NoSuchElementException();
156 return uno::Any(uno::Reference
<word::XFormField
>(
157 new SwVbaFormField(mxParent
, mxContext
, mxTextDocument
, *m_pCache
)));
160 sal_Bool SAL_CALL
hasByName(const OUString
& aName
) override
162 sal_Int32 nCount
= -1;
163 m_pCache
= lcl_getFieldmark(aName
.toUtf8(), nCount
, mxTextDocument
);
164 return m_pCache
!= nullptr;
168 uno::Type SAL_CALL
getElementType() override
{ return cppu::UnoType
<word::XFormField
>::get(); }
170 sal_Bool SAL_CALL
hasElements() override
{ return getCount() != 0; }
172 // XEnumerationAccess
173 uno::Reference
<container::XEnumeration
> SAL_CALL
createEnumeration() override
175 return new FormFieldsEnumWrapper(this);
180 SwVbaFormFields::SwVbaFormFields(const uno::Reference
<XHelperInterface
>& xParent
,
181 const uno::Reference
<uno::XComponentContext
>& xContext
,
182 const rtl::Reference
<SwXTextDocument
>& xTextDocument
)
183 : SwVbaFormFields_BASE(xParent
, xContext
,
184 uno::Reference
<container::XIndexAccess
>(
185 new FormFieldCollectionHelper(xParent
, xContext
, xTextDocument
)))
189 sal_Bool
SwVbaFormFields::getShaded()
191 SAL_INFO("sw.vba", "SwVbaFormFields::getShaded stub");
195 void SwVbaFormFields::setShaded(sal_Bool
/*bSet*/)
197 SAL_INFO("sw.vba", "SwVbaFormFields::setShaded stub");
200 // uno::Reference<ooo::vba::word::XFormField> SwVbaFormFields::Add(const uno::Any& Range,
203 // sw::mark::Fieldmark* pFieldmark = nullptr;
206 // case ooo::vba::word::WdFieldType::wdFieldFormCheckBox:
208 // case ooo::vba::word::WdFieldType::wdFieldFormDropDown:
210 // case ooo::vba::word::WdFieldType::wdFieldFormTextInput:
214 // return uno::Reference<ooo::vba::word::XFormField>(
215 // new SwVbaFormField(mxParent, mxContext, m_xTextDocument, *pFieldmark));
218 // XEnumerationAccess
219 uno::Type
SwVbaFormFields::getElementType() { return cppu::UnoType
<word::XFormField
>::get(); }
221 uno::Reference
<container::XEnumeration
> SwVbaFormFields::createEnumeration()
223 return new FormFieldsEnumWrapper(m_xIndexAccess
);
226 uno::Any
SwVbaFormFields::createCollectionObject(const uno::Any
& aSource
) { return aSource
; }
228 OUString
SwVbaFormFields::getServiceImplName() { return u
"SwVbaFormFields"_ustr
; }
230 uno::Sequence
<OUString
> SwVbaFormFields::getServiceNames()
232 static uno::Sequence
<OUString
> const sNames
{ u
"ooo.vba.word.FormFields"_ustr
};
236 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */