android: Update app-specific/MIME type icons
[LibreOffice.git] / sw / source / ui / vba / vbaformfields.cxx
blob586393e358187575e45155639c2cf58ec27ea658
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
10 #include <comphelper/sequence.hxx>
11 #include <sal/log.hxx>
13 #include <doc.hxx>
14 #include <docsh.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();
34 if (!pDoc)
35 return nullptr;
37 IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
38 if (!pMarkAccess)
39 return nullptr;
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:
52 if (rIndex < 0
53 && (*aIter)->GetName().equalsIgnoreAsciiCase(OUString::fromUtf8(rName)))
55 rIndex = nCounter;
56 return dynamic_cast<sw::mark::IFieldmark*>(*aIter);
58 else if (rIndex == nCounter)
59 return dynamic_cast<sw::mark::IFieldmark*>(*aIter);
61 ++nCounter;
62 if (pElementNames)
63 vElementNames.push_back((*aIter)->GetName());
64 break;
66 default:;
68 aIter++;
70 rIndex = nCounter;
71 if (pElementNames)
72 *pElementNames = comphelper::containerToSequence(vElementNames);
73 return nullptr;
76 namespace
78 class FormFieldsEnumWrapper : public EnumerationHelper_BASE
80 uno::Reference<container::XIndexAccess> mxIndexAccess;
81 sal_Int32 mnIndex;
83 public:
84 explicit FormFieldsEnumWrapper(uno::Reference<container::XIndexAccess> xIndexAccess)
85 : mxIndexAccess(xIndexAccess)
86 , mnIndex(0)
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>
105 private:
106 uno::Reference<XHelperInterface> mxParent;
107 uno::Reference<uno::XComponentContext> mxContext;
108 uno::Reference<text::XTextDocument> mxTextDocument;
109 sw::mark::IFieldmark* m_pCache;
111 public:
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))
119 , m_pCache(nullptr)
123 // XIndexAccess
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);
134 if (!m_pCache)
135 throw lang::IndexOutOfBoundsException();
137 return uno::Any(uno::Reference<word::XFormField>(
138 new SwVbaFormField(mxParent, mxContext, mxTextDocument, *m_pCache)));
141 // XNameAccess
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);
147 return 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;
166 // XElementAccess
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");
191 return false;
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,
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 // }
213 // return uno::Reference<ooo::vba::word::XFormField>(
214 // new SwVbaFormField(mxParent, mxContext, m_xTextDocument, *pFieldmark));
215 // }
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" };
232 return sNames;
235 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */