tdf#35361 Add a Quick Look plugins for .od* files on macOS
[LibreOffice.git] / sw / source / ui / vba / vbaformfields.cxx
blobd647e9ea993a08bc207cc181e09830d8b8cc11be
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"
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();
35 if (!pDoc)
36 return nullptr;
38 IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
39 if (!pMarkAccess)
40 return nullptr;
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:
53 if (rIndex < 0
54 && (*aIter)->GetName().equalsIgnoreAsciiCase(OUString::fromUtf8(rName)))
56 rIndex = nCounter;
57 return *aIter;
59 else if (rIndex == nCounter)
60 return *aIter;
62 ++nCounter;
63 if (pElementNames)
64 vElementNames.push_back((*aIter)->GetName());
65 break;
67 default:;
69 aIter++;
71 rIndex = nCounter;
72 if (pElementNames)
73 *pElementNames = comphelper::containerToSequence(vElementNames);
74 return nullptr;
77 namespace
79 class FormFieldsEnumWrapper : public EnumerationHelper_BASE
81 uno::Reference<container::XIndexAccess> mxIndexAccess;
82 sal_Int32 mnIndex;
84 public:
85 explicit FormFieldsEnumWrapper(const uno::Reference<container::XIndexAccess>& xIndexAccess)
86 : mxIndexAccess(xIndexAccess)
87 , mnIndex(0)
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>
106 private:
107 uno::Reference<XHelperInterface> mxParent;
108 uno::Reference<uno::XComponentContext> mxContext;
109 rtl::Reference<SwXTextDocument> mxTextDocument;
110 sw::mark::Fieldmark* m_pCache;
112 public:
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))
120 , m_pCache(nullptr)
124 // XIndexAccess
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);
135 if (!m_pCache)
136 throw lang::IndexOutOfBoundsException();
138 return uno::Any(uno::Reference<word::XFormField>(
139 new SwVbaFormField(mxParent, mxContext, mxTextDocument, *m_pCache)));
142 // XNameAccess
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);
148 return 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;
167 // XElementAccess
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");
192 return false;
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,
201 // sal_Int32 Type)
202 // {
203 // sw::mark::Fieldmark* pFieldmark = nullptr;
204 // switch (Type)
205 // {
206 // case ooo::vba::word::WdFieldType::wdFieldFormCheckBox:
207 // break;
208 // case ooo::vba::word::WdFieldType::wdFieldFormDropDown:
209 // break;
210 // case ooo::vba::word::WdFieldType::wdFieldFormTextInput:
211 // default:;
212 // }
214 // return uno::Reference<ooo::vba::word::XFormField>(
215 // new SwVbaFormField(mxParent, mxContext, m_xTextDocument, *pFieldmark));
216 // }
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 };
233 return sNames;
236 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */