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"
21 using namespace ::ooo::vba
;
22 using namespace ::com::sun::star
;
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
28 static 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)
33 SwDoc
* pDoc
= word::getDocShell(xModel
)->GetDoc();
37 IDocumentMarkAccess
* pMarkAccess
= pDoc
->getIDocumentMarkAccess();
41 sal_Int32 nCounter
= 0;
42 std::vector
<OUString
> vElementNames
;
43 IDocumentMarkAccess::iterator aIter
= pMarkAccess
->getFieldmarksBegin();
44 while (aIter
!= pMarkAccess
->getFieldmarksEnd())
46 switch (IDocumentMarkAccess::GetType(**aIter
))
48 case IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK
:
49 case IDocumentMarkAccess::MarkType::DROPDOWN_FIELDMARK
:
50 case IDocumentMarkAccess::MarkType::TEXT_FIELDMARK
:
53 && (*aIter
)->GetName().equalsIgnoreAsciiCase(OUString::fromUtf8(rName
)))
56 return dynamic_cast<sw::mark::IFieldmark
*>(*aIter
);
58 else if (rIndex
== nCounter
)
59 return dynamic_cast<sw::mark::IFieldmark
*>(*aIter
);
63 vElementNames
.push_back((*aIter
)->GetName());
72 *pElementNames
= comphelper::containerToSequence(vElementNames
);
78 class FormFieldsEnumWrapper
: public EnumerationHelper_BASE
80 uno::Reference
<container::XIndexAccess
> mxIndexAccess
;
84 explicit FormFieldsEnumWrapper(uno::Reference
<container::XIndexAccess
> xIndexAccess
)
85 : mxIndexAccess(xIndexAccess
)
89 sal_Bool SAL_CALL
hasMoreElements() override
{ return (mnIndex
< mxIndexAccess
->getCount()); }
91 uno::Any SAL_CALL
nextElement() override
93 if (mnIndex
< mxIndexAccess
->getCount())
95 return mxIndexAccess
->getByIndex(mnIndex
++);
97 throw container::NoSuchElementException();
101 class FormFieldCollectionHelper
102 : public ::cppu::WeakImplHelper
<container::XNameAccess
, container::XIndexAccess
,
103 container::XEnumerationAccess
>
106 uno::Reference
<XHelperInterface
> mxParent
;
107 uno::Reference
<uno::XComponentContext
> mxContext
;
108 uno::Reference
<text::XTextDocument
> mxTextDocument
;
109 sw::mark::IFieldmark
* m_pCache
;
112 /// @throws css::uno::RuntimeException
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
))
124 sal_Int32 SAL_CALL
getCount() override
126 sal_Int32 nCount
= SAL_MAX_INT32
;
127 lcl_getFieldmark("", nCount
, mxTextDocument
);
128 return nCount
== SAL_MAX_INT32
? 0 : nCount
;
131 uno::Any SAL_CALL
getByIndex(sal_Int32 Index
) override
133 m_pCache
= lcl_getFieldmark("", Index
, mxTextDocument
);
135 throw lang::IndexOutOfBoundsException();
137 return uno::Any(uno::Reference
<word::XFormField
>(
138 new SwVbaFormField(mxParent
, mxContext
, mxTextDocument
, *m_pCache
)));
142 uno::Sequence
<OUString
> SAL_CALL
getElementNames() override
144 sal_Int32 nCount
= SAL_MAX_INT32
;
145 uno::Sequence
<OUString
> aSeq
;
146 lcl_getFieldmark("", nCount
, mxTextDocument
, &aSeq
);
150 uno::Any SAL_CALL
getByName(const OUString
& aName
) override
152 if (!hasByName(aName
))
153 throw container::NoSuchElementException();
155 return uno::Any(uno::Reference
<word::XFormField
>(
156 new SwVbaFormField(mxParent
, mxContext
, mxTextDocument
, *m_pCache
)));
159 sal_Bool SAL_CALL
hasByName(const OUString
& aName
) override
161 sal_Int32 nCount
= -1;
162 m_pCache
= lcl_getFieldmark(aName
.toUtf8(), nCount
, mxTextDocument
);
163 return m_pCache
!= nullptr;
167 uno::Type SAL_CALL
getElementType() override
{ return cppu::UnoType
<word::XFormField
>::get(); }
169 sal_Bool SAL_CALL
hasElements() override
{ return getCount() != 0; }
171 // XEnumerationAccess
172 uno::Reference
<container::XEnumeration
> SAL_CALL
createEnumeration() override
174 return new FormFieldsEnumWrapper(this);
179 SwVbaFormFields::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
)))
188 sal_Bool
SwVbaFormFields::getShaded()
190 SAL_INFO("sw.vba", "SwVbaFormFields::getShaded stub");
194 void SwVbaFormFields::setShaded(sal_Bool
/*bSet*/)
196 SAL_INFO("sw.vba", "SwVbaFormFields::setShaded stub");
199 // uno::Reference<ooo::vba::word::XFormField> SwVbaFormFields::Add(const uno::Any& Range,
202 // sw::mark::IFieldmark* pFieldmark = nullptr;
205 // case ooo::vba::word::WdFieldType::wdFieldFormCheckBox:
207 // case ooo::vba::word::WdFieldType::wdFieldFormDropDown:
209 // case ooo::vba::word::WdFieldType::wdFieldFormTextInput:
213 // return uno::Reference<ooo::vba::word::XFormField>(
214 // new SwVbaFormField(mxParent, mxContext, m_xTextDocument, *pFieldmark));
217 // XEnumerationAccess
218 uno::Type
SwVbaFormFields::getElementType() { return cppu::UnoType
<word::XFormField
>::get(); }
220 uno::Reference
<container::XEnumeration
> SwVbaFormFields::createEnumeration()
222 return new FormFieldsEnumWrapper(m_xIndexAccess
);
225 uno::Any
SwVbaFormFields::createCollectionObject(const uno::Any
& aSource
) { return aSource
; }
227 OUString
SwVbaFormFields::getServiceImplName() { return "SwVbaFormFields"; }
229 uno::Sequence
<OUString
> SwVbaFormFields::getServiceNames()
231 static uno::Sequence
<OUString
> const sNames
{ "ooo.vba.word.FormFields" };
235 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */