diff options
author | Justin Luth <justin.luth@collabora.com> | 2022-11-09 17:02:03 -0500 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2022-11-10 08:59:24 +0100 |
commit | 2a26f136a36791c06caa895d5a25f4633fd10651 (patch) | |
tree | e5a98514cfeb7f8f4d9ecb779ccc180ed5b8f6fe | |
parent | e2f8558324091bddba0637942f4f000a24e673a7 (diff) |
tdf#151548 vba FormFields: Add basic word::XFormField support
Unit tests will come in the following commits that represent
actual FormFields that have content/results.
This lays the foundation for adding
Checkboxes, Textinputs, and Dropdowns.
Change-Id: If85ae25f881198d5a0699b3350a7eb20b1735c45
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142507
Reviewed-by: Justin Luth <jluth@mail.com>
Tested-by: Jenkins
Reviewed-by: Tor Lillqvist <tml@collabora.com>
-rw-r--r-- | oovbaapi/ooo/vba/word/XFormField.idl | 50 | ||||
-rw-r--r-- | oovbaapi/ooo/vba/word/XFormFields.idl | 7 | ||||
-rw-r--r-- | sw/Library_vbaswobj.mk | 2 | ||||
-rw-r--r-- | sw/inc/IMark.hxx | 8 | ||||
-rw-r--r-- | sw/source/ui/vba/vbadocument.cxx | 10 | ||||
-rw-r--r-- | sw/source/ui/vba/vbaformfield.cxx | 255 | ||||
-rw-r--r-- | sw/source/ui/vba/vbaformfield.hxx | 98 | ||||
-rw-r--r-- | sw/source/ui/vba/vbaformfields.cxx | 250 | ||||
-rw-r--r-- | sw/source/ui/vba/vbaformfields.hxx | 56 |
9 files changed, 728 insertions, 8 deletions
diff --git a/oovbaapi/ooo/vba/word/XFormField.idl b/oovbaapi/ooo/vba/word/XFormField.idl index 3131fda872f5..3d51fcd263cd 100644 --- a/oovbaapi/ooo/vba/word/XFormField.idl +++ b/oovbaapi/ooo/vba/word/XFormField.idl @@ -22,12 +22,60 @@ module ooo { module vba { module word { interface XFormField { interface ooo::vba::XHelperInterface; + interface com::sun::star::script::XDefaultProperty; + /// Default member: returns the field type from WdFieldType + [attribute, readonly] long Type; + + /** + * Returns or sets true if references to the specified form field + * are automatically updated whenever the field is exited. + */ + [attribute] boolean CalculateOnExit; + /// Returns or sets a string that represents the result of the specified form field [attribute] string Result; + /// Returns or sets true if a form field is enabled [attribute] boolean Enabled; + /// Returns or sets the macro name that runs on keyboard (tab) navigation into the field + [attribute] string EntryMacro; + /// Returns or sets an exit macro name that runs on keyboard (tab) navigation out of the field + [attribute] string ExitMacro; + /** + * Returns or sets the text that's displayed in a message box + * when the form field has the focus and the user presses F1. + * + * When OwnHelp is False, HelpText specifies the name of an AutoText entry + * that contains help text for the form field + */ + [attribute] string HelpText; + /** + * Returns or sets the specifies the source of the F1 text that's displayed in a message box + * If True, the text specified by the HelpText property is displayed. + * If False, the text in the AutoText entry specified by the HelpText property is displayed. + */ + [attribute] boolean OwnHelp; + /// returns or sets the name of the specified object. + [attribute] string Name; + /// Returns or sets the text that is displayed in the status bar when a form field has the focus + [attribute] string StatusText; + /** OwnStatus: + * If True, the text specified by the StatusText property is displayed. + * If False, the text of the AutoText entry specified by the StatusText property is displayed. + */ + [attribute] boolean OwnStatus; any CheckBox(); - + any DropDown(); + any TextInput(); + /// Returns the next form field in the collection. + any Next(); + /// returns the previous form field in the collection. + any Previous(); + /** + * Represents a contiguous area in a document. + * Each Range object is defined by a starting and ending character position. + */ + any Range(); }; }; }; }; diff --git a/oovbaapi/ooo/vba/word/XFormFields.idl b/oovbaapi/ooo/vba/word/XFormFields.idl index bef2aa9d919b..8b98c6381681 100644 --- a/oovbaapi/ooo/vba/word/XFormFields.idl +++ b/oovbaapi/ooo/vba/word/XFormFields.idl @@ -23,10 +23,15 @@ module ooo { module vba { module word { - +interface XFormField; interface XFormFields { interface ::ooo::vba::XCollection; + + ///Returns and sets if shading is applied to form XFormFields + [attribute] boolean Shaded; + /// Resturns a FormField object that representa new WdFieldType added at a range + //XFormField Add( [in] any Range, [in] long Type ) raises ( com::sun::star::script::BasicErrorException ); }; }; }; }; diff --git a/sw/Library_vbaswobj.mk b/sw/Library_vbaswobj.mk index 6e9f3539c816..752f682f2461 100644 --- a/sw/Library_vbaswobj.mk +++ b/sw/Library_vbaswobj.mk @@ -72,6 +72,8 @@ $(eval $(call gb_Library_add_exception_objects,vbaswobj,\ sw/source/ui/vba/vbacells \ sw/source/ui/vba/vbacolumn \ sw/source/ui/vba/vbacolumns \ + sw/source/ui/vba/vbaformfield \ + sw/source/ui/vba/vbaformfields \ sw/source/ui/vba/vbaframe \ sw/source/ui/vba/vbaframes \ sw/source/ui/vba/vbalistformat \ diff --git a/sw/inc/IMark.hxx b/sw/inc/IMark.hxx index 151c9a9333fb..776d35c2f4e3 100644 --- a/sw/inc/IMark.hxx +++ b/sw/inc/IMark.hxx @@ -102,6 +102,10 @@ namespace sw::mark virtual void SetFieldname(const OUString& rFieldname) =0; virtual void SetFieldHelptext(const OUString& rFieldHelptext) =0; virtual void Invalidate() = 0; + + virtual OUString GetContent() const { return OUString(); } + virtual void ReplaceContent(const OUString& /*sNewContent*/) {} + private: IFieldmark(IFieldmark const &) = delete; IFieldmark &operator =(IFieldmark const&) = delete; @@ -128,8 +132,8 @@ namespace sw::mark IDateFieldmark() = default; public: - virtual OUString GetContent() const = 0; - virtual void ReplaceContent(const OUString& sNewContent) = 0; + virtual OUString GetContent() const override = 0; + virtual void ReplaceContent(const OUString& sNewContent) override = 0; virtual std::pair<bool, double> GetCurrentDate() const = 0; virtual void SetCurrentDate(double fDate) = 0; diff --git a/sw/source/ui/vba/vbadocument.cxx b/sw/source/ui/vba/vbadocument.cxx index 969b893e5130..6dcbdbf5c0b4 100644 --- a/sw/source/ui/vba/vbadocument.cxx +++ b/sw/source/ui/vba/vbadocument.cxx @@ -22,6 +22,7 @@ #include "vbafilterpropsfromformat.hxx" #include "vbadocument.hxx" +#include "vbaformfields.hxx" #include "vbarange.hxx" #include "vbarangehelper.hxx" #include "vbadocumentproperties.hxx" @@ -296,11 +297,12 @@ SwVbaDocument::TablesOfContents( const uno::Any& index ) return uno::Any( xCol ); } -uno::Any SAL_CALL -SwVbaDocument::FormFields( const uno::Any& /*index*/ ) +uno::Any SAL_CALL SwVbaDocument::FormFields(const uno::Any& index) { - uno::Reference< XCollection > xCol; - return uno::Any( xCol ); + uno::Reference<XCollection> xCol(new SwVbaFormFields(this, mxContext, mxModel)); + if (index.hasValue()) + return xCol->Item(index, uno::Any()); + return uno::Any(xCol); } uno::Any SAL_CALL diff --git a/sw/source/ui/vba/vbaformfield.cxx b/sw/source/ui/vba/vbaformfield.cxx new file mode 100644 index 000000000000..43b9f25cf660 --- /dev/null +++ b/sw/source/ui/vba/vbaformfield.cxx @@ -0,0 +1,255 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ooo/vba/word/WdFieldType.hpp> + +#include <sal/log.hxx> + +#include <doc.hxx> +#include <docsh.hxx> + +#include "vbaformfield.hxx" +#include "wordvbahelper.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +/** + * Information about the method and properties of FormFields was gathered from + * https://www.codevba.com/Word/FormField.htm + * + * FormFields are inline text objects that are only found in MS Word. + * They cannot be created in Excel or in Calc. + * + * There are three specific kinds of FormFields: CheckBox, DropDown, and TextInput. + */ +SwVbaFormField::SwVbaFormField(const uno::Reference<ooo::vba::XHelperInterface>& rParent, + const uno::Reference<uno::XComponentContext>& rContext, + const uno::Reference<frame::XModel>& xModel, + sw::mark::IFieldmark& rFormField) + : SwVbaFormField_BASE(rParent, rContext) + , mxModel(std::move(xModel)) + , m_rFormField(rFormField) +{ +} + +SwVbaFormField::~SwVbaFormField() {} + +uno::Any SAL_CALL SwVbaFormField::CheckBox() +{ + // return uno::Any(uno::Reference<word::XCheckBox>( + // new SwVbaFormFieldCheckBox(mxParent, mxContext, m_rFormField))); + return uno::Any(); +} + +uno::Any SAL_CALL SwVbaFormField::DropDown() +{ + // return uno::Any(uno::Reference<word::XDropDown>( + // new SwVbaFormFieldDropDown(mxParent, mxContext, m_rFormField))); + return uno::Any(); +} + +uno::Any SAL_CALL SwVbaFormField::TextInput() +{ + // return uno::Any(uno::Reference<word::XTextInput>( + // new SwVbaFormFieldTextInput(mxParent, mxContext, m_rFormField))); + return uno::Any(); +} + +uno::Any SAL_CALL SwVbaFormField::Previous() +{ + SwDoc* pDoc = word::getDocShell(mxModel)->GetDoc(); + if (!pDoc) + return uno::Any(); + + const IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); + if (!pMarkAccess) + return uno::Any(); + + sw::mark::IFieldmark* pFieldMark = pMarkAccess->getFieldmarkBefore(m_rFormField.GetMarkPos()); + + // DateFields are a LO specialty, and do not exist natively in MS documents. Ignore if added... + auto pDateField = dynamic_cast<sw::mark::IDateFieldmark*>(pFieldMark); + while (pDateField) + { + pFieldMark = pMarkAccess->getFieldmarkBefore(pDateField->GetMarkPos()); + pDateField = dynamic_cast<sw::mark::IDateFieldmark*>(pFieldMark); + } + + if (!pFieldMark) + return uno::Any(); + + return uno::Any(uno::Reference<word::XFormField>( + new SwVbaFormField(mxParent, mxContext, mxModel, *pFieldMark))); +} + +uno::Any SAL_CALL SwVbaFormField::Next() +{ + SwDoc* pDoc = word::getDocShell(mxModel)->GetDoc(); + if (!pDoc) + return uno::Any(); + + const IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); + if (!pMarkAccess) + return uno::Any(); + + sw::mark::IFieldmark* pFieldMark = pMarkAccess->getFieldmarkAfter(m_rFormField.GetMarkPos()); + + // DateFields are a LO specialty, and do not exist natively in MS documents. Ignore if added... + auto pDateField = dynamic_cast<sw::mark::IDateFieldmark*>(pFieldMark); + while (pDateField) + { + pFieldMark = pMarkAccess->getFieldmarkAfter(pDateField->GetMarkPos()); + pDateField = dynamic_cast<sw::mark::IDateFieldmark*>(pFieldMark); + } + + if (!pFieldMark) + return uno::Any(); + + return uno::Any(uno::Reference<word::XFormField>( + new SwVbaFormField(mxParent, mxContext, mxModel, *pFieldMark))); +} + +uno::Any SAL_CALL SwVbaFormField::Range() +{ + SAL_INFO("sw.vba", "SwVbaFormField::getRange stub"); + return uno::Any(); +} + +OUString SwVbaFormField::getDefaultPropertyName() { return "Type"; } + +sal_Int32 SwVbaFormField::getType() +{ + IDocumentMarkAccess::MarkType aType = IDocumentMarkAccess::GetType(m_rFormField); + if (aType == IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK) + return ooo::vba::word::WdFieldType::wdFieldFormCheckBox; + else if (aType == IDocumentMarkAccess::MarkType::TEXT_FIELDMARK) + return ooo::vba::word::WdFieldType::wdFieldFormTextInput; + return ooo::vba::word::WdFieldType::wdFieldFormDropDown; +} + +sal_Bool SwVbaFormField::getCalculateOnExit() +{ + SAL_INFO("sw.vba", "SwVbaFormField::getCalculateOnExit stub"); + return false; +} + +void SwVbaFormField::setCalculateOnExit(sal_Bool /*bSet*/) +{ + SAL_INFO("sw.vba", "SwVbaFormField::setCalculateOnExit stub"); +} + +sal_Bool SwVbaFormField::getEnabled() +{ + SAL_INFO("sw.vba", "SwVbaFormField::getEnabled stub"); + return true; +} + +void SwVbaFormField::setEnabled(sal_Bool /*bSet*/) +{ + SAL_INFO("sw.vba", "SwVbaFormField::setEnabled stub"); +} + +OUString SwVbaFormField::getEntryMacro() +{ + OUString sMacro; + (*m_rFormField.GetParameters())["EntryMacro"] >>= sMacro; + return sMacro; +} + +void SwVbaFormField::setEntryMacro(const OUString& rSet) +{ + (*m_rFormField.GetParameters())["EntryMacro"] <<= rSet; +} + +OUString SwVbaFormField::getExitMacro() +{ + OUString sMacro; + (*m_rFormField.GetParameters())["ExitMacro"] >>= sMacro; + return sMacro; +} + +void SwVbaFormField::setExitMacro(const OUString& rSet) +{ + (*m_rFormField.GetParameters())["ExitMacro"] <<= rSet; +} + +OUString SwVbaFormField::getHelpText() { return m_rFormField.GetFieldHelptext(); } + +void SwVbaFormField::setHelpText(const OUString& rSet) { m_rFormField.SetFieldHelptext(rSet); } + +sal_Bool SwVbaFormField::getOwnHelp() +{ + SAL_INFO("sw.vba", "SwVbaFormField::getOwnHelp stub"); + return true; +} + +void SwVbaFormField::setOwnHelp(sal_Bool /*bSet*/) +{ + SAL_INFO("sw.vba", "SwVbaFormField::setOwnHelp stub"); +} + +OUString SwVbaFormField::getName() { return m_rFormField.GetName(); } + +void SwVbaFormField::setName(const OUString& rSet) +{ + SAL_WARN("sw.vba", "SwVbaFormField::setName[" << rSet << "] stub"); +} + +OUString SwVbaFormField::getResult() { return m_rFormField.GetContent(); } + +void SwVbaFormField::setResult(const OUString& rSet) +{ + if (dynamic_cast<sw::mark::ICheckboxFieldmark*>(&m_rFormField)) + m_rFormField.ReplaceContent("false"); + else + m_rFormField.ReplaceContent(rSet); +} + +OUString SwVbaFormField::getStatusText() +{ + SAL_INFO("sw.vba", "SwVbaFormField::getStatusText stub"); + return OUString(); +} + +void SwVbaFormField::setStatusText(const OUString& rSet) +{ + SAL_INFO("sw.vba", "SwVbaFormField::setStatusText[" << rSet << "] stub"); +} + +sal_Bool SwVbaFormField::getOwnStatus() +{ + SAL_INFO("sw.vba", "SwVbaFormField::getOwnStatus stub"); + return true; +} + +void SwVbaFormField::setOwnStatus(sal_Bool /*bSet*/) +{ + SAL_INFO("sw.vba", "SwVbaFormField::setOwnStatus stub"); +} + +OUString SwVbaFormField::getServiceImplName() { return "SwVbaFormField"; } + +uno::Sequence<OUString> SwVbaFormField::getServiceNames() +{ + static uno::Sequence<OUString> const aServiceNames{ "ooo.vba.word.FormField" }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaformfield.hxx b/sw/source/ui/vba/vbaformfield.hxx new file mode 100644 index 000000000000..14f44fc3c779 --- /dev/null +++ b/sw/source/ui/vba/vbaformfield.hxx @@ -0,0 +1,98 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAFORMFIELD_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAFORMFIELD_HXX + +#include <ooo/vba/word/XFormField.hpp> + +#include <vbahelper/vbahelperinterface.hxx> + +#include <IDocumentMarkAccess.hxx> + +typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XFormField> SwVbaFormField_BASE; + +class SwVbaFormField : public SwVbaFormField_BASE +{ +private: + css::uno::Reference<css::frame::XModel> mxModel; + sw::mark::IFieldmark& m_rFormField; + +public: + /// @throws css::uno::RuntimeException + SwVbaFormField(const css::uno::Reference<ooo::vba::XHelperInterface>& rParent, + const css::uno::Reference<css::uno::XComponentContext>& rContext, + const css::uno::Reference<css::frame::XModel>& xModel, + sw::mark::IFieldmark& rFormField); + virtual ~SwVbaFormField() override; + + // XFormField Methods + virtual OUString SAL_CALL getDefaultPropertyName() override; + + virtual css::uno::Any SAL_CALL CheckBox() override; + virtual css::uno::Any SAL_CALL DropDown() override; + virtual css::uno::Any SAL_CALL TextInput() override; + virtual css::uno::Any SAL_CALL Previous() override; + virtual css::uno::Any SAL_CALL Next() override; + virtual css::uno::Any SAL_CALL Range() override; + + // Indicates which of the three form fields this is: oovbaapi/ooo/vba/word/WdFieldType.idl + virtual sal_Int32 SAL_CALL getType() override; + // True if references to the specified form field + // are automatically updated whenever the field is exited + virtual sal_Bool SAL_CALL getCalculateOnExit() override; + virtual void SAL_CALL setCalculateOnExit(sal_Bool bSet) override; + virtual sal_Bool SAL_CALL getEnabled() override; + virtual void SAL_CALL setEnabled(sal_Bool bSet) override; + virtual OUString SAL_CALL getEntryMacro() override; + virtual void SAL_CALL setEntryMacro(const OUString& rSet) override; + virtual OUString SAL_CALL getExitMacro() override; + virtual void SAL_CALL setExitMacro(const OUString& rSet) override; + /* + * If the OwnHelp property is set to True, + * HelpText specifies the text string value. + * If OwnHelp is set to False, HelpText specifies the name of an AutoText entry + * that contains help text for the form field. + */ + virtual OUString SAL_CALL getHelpText() override; + virtual void SAL_CALL setHelpText(const OUString& rSet) override; + virtual sal_Bool SAL_CALL getOwnHelp() override; + virtual void SAL_CALL setOwnHelp(sal_Bool bSet) override; + + virtual OUString SAL_CALL getName() override; + virtual void SAL_CALL setName(const OUString& rSet) override; + virtual OUString SAL_CALL getResult() override; + virtual void SAL_CALL setResult(const OUString& rSet) override; + /* + * If the OwnStatus property is set to True, + * StatusText specifies the status bar value. + * If OwnStatus is set to False, StatusText specifies the name of an AutoText entry + * that contains status bar text for the form field. + */ + virtual OUString SAL_CALL getStatusText() override; + virtual void SAL_CALL setStatusText(const OUString& rSet) override; + virtual sal_Bool SAL_CALL getOwnStatus() override; + virtual void SAL_CALL setOwnStatus(sal_Bool bSet) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAFORMFIELD_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaformfields.cxx b/sw/source/ui/vba/vbaformfields.cxx new file mode 100644 index 000000000000..f4bdd8cb6470 --- /dev/null +++ b/sw/source/ui/vba/vbaformfields.cxx @@ -0,0 +1,250 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <comphelper/sequence.hxx> +#include <sal/log.hxx> + +#include <doc.hxx> +#include <docsh.hxx> +#include <IDocumentMarkAccess.hxx> + +#include "vbaformfield.hxx" +#include "vbaformfields.hxx" +#include "wordvbahelper.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +// Helper function to access the fieldmarks +// @param rIndex serves multiple purposes +// [in] -1 to indicate searching using the provided name, SAL_MAX_INT32 for totals +// [out] rIndex indicates the found index, or the total number of fieldmarks +static sw::mark::IFieldmark* lcl_getFieldmark(std::string_view rName, sal_Int32& rIndex, + const css::uno::Reference<frame::XModel>& xModel, + uno::Sequence<OUString>* pElementNames = nullptr) +{ + SwDoc* pDoc = word::getDocShell(xModel)->GetDoc(); + if (!pDoc) + return nullptr; + + IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); + if (!pMarkAccess) + return nullptr; + + sal_Int32 nCounter = 0; + std::vector<OUString> vElementNames; + IDocumentMarkAccess::iterator aIter = pMarkAccess->getFieldmarksBegin(); + while (aIter != pMarkAccess->getFieldmarksEnd()) + { + switch (IDocumentMarkAccess::GetType(**aIter)) + { + case IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK: + case IDocumentMarkAccess::MarkType::DROPDOWN_FIELDMARK: + case IDocumentMarkAccess::MarkType::TEXT_FIELDMARK: + { + if (rIndex < 0 + && (*aIter)->GetName().equalsIgnoreAsciiCase(OUString::fromUtf8(rName))) + { + rIndex = nCounter; + return dynamic_cast<sw::mark::IFieldmark*>(*aIter); + } + else if (rIndex == nCounter) + return dynamic_cast<sw::mark::IFieldmark*>(*aIter); + + ++nCounter; + if (pElementNames) + vElementNames.push_back((*aIter)->GetName()); + break; + } + default:; + } + aIter++; + } + rIndex = nCounter; + if (pElementNames) + *pElementNames = comphelper::containerToSequence(vElementNames); + return nullptr; +} + +namespace +{ +class FormFieldsEnumWrapper : public EnumerationHelper_BASE +{ + uno::Reference<container::XIndexAccess> mxIndexAccess; + sal_Int32 nIndex; + +public: + explicit FormFieldsEnumWrapper(uno::Reference<container::XIndexAccess> xIndexAccess) + : mxIndexAccess(std::move(xIndexAccess)) + , nIndex(0) + { + } + virtual sal_Bool SAL_CALL hasMoreElements() override + { + return (nIndex < mxIndexAccess->getCount()); + } + + virtual uno::Any SAL_CALL nextElement() override + { + if (nIndex < mxIndexAccess->getCount()) + { + return mxIndexAccess->getByIndex(nIndex++); + } + throw container::NoSuchElementException(); + } +}; + +class FormFieldCollectionHelper + : public ::cppu::WeakImplHelper<container::XNameAccess, container::XIndexAccess, + container::XEnumerationAccess> +{ +private: + const uno::Reference<XHelperInterface> mxParent; + const uno::Reference<uno::XComponentContext> mxContext; + const css::uno::Reference<frame::XModel>& mxModel; + sw::mark::IFieldmark* m_pCache; + +public: + /// @throws css::uno::RuntimeException + FormFieldCollectionHelper(const css::uno::Reference<ov::XHelperInterface> xParent, + const css::uno::Reference<css::uno::XComponentContext> xContext, + const css::uno::Reference<frame::XModel>& xModel) + : mxParent(std::move(xParent)) + , mxContext(std::move(xContext)) + , mxModel(std::move(xModel)) + { + } + + // XIndexAccess + virtual sal_Int32 SAL_CALL getCount() override + { + sal_Int32 nCount = SAL_MAX_INT32; + lcl_getFieldmark("", nCount, mxModel); + return nCount == SAL_MAX_INT32 ? 0 : nCount; + } + + virtual uno::Any SAL_CALL getByIndex(sal_Int32 Index) override + { + m_pCache = lcl_getFieldmark("", Index, mxModel); + if (!m_pCache) + throw css::lang::IndexOutOfBoundsException(); + + return uno::Any(uno::Reference<word::XFormField>( + new SwVbaFormField(mxParent, mxContext, mxModel, *m_pCache))); + } + + // XNameAccess + virtual uno::Sequence<OUString> SAL_CALL getElementNames() override + { + sal_Int32 nCount = SAL_MAX_INT32; + uno::Sequence<OUString> aSeq; + lcl_getFieldmark("", nCount, mxModel, &aSeq); + return aSeq; + } + + virtual uno::Any SAL_CALL getByName(const OUString& aName) override + { + if (!hasByName(aName)) + throw container::NoSuchElementException(); + + return uno::Any(uno::Reference<word::XFormField>( + new SwVbaFormField(mxParent, mxContext, mxModel, *m_pCache))); + } + + virtual sal_Bool SAL_CALL hasByName(const OUString& aName) override + { + sal_Int32 nCount = -1; + m_pCache = lcl_getFieldmark(aName.toUtf8(), nCount, mxModel); + return m_pCache != nullptr; + } + + // XElementAccess + virtual uno::Type SAL_CALL getElementType() override + { + return cppu::UnoType<word::XFormField>::get(); + } + + virtual sal_Bool SAL_CALL hasElements() override { return getCount() != 0; } + + // XEnumerationAccess + virtual uno::Reference<container::XEnumeration> SAL_CALL createEnumeration() override + { + return new FormFieldsEnumWrapper(this); + } +}; +} + +SwVbaFormFields::SwVbaFormFields(const uno::Reference<XHelperInterface>& xParent, + const uno::Reference<uno::XComponentContext>& xContext, + const uno::Reference<frame::XModel>& xModel) + : SwVbaFormFields_BASE(xParent, xContext, + uno::Reference<container::XIndexAccess>( + new FormFieldCollectionHelper(xParent, xContext, xModel))) + , m_xModel(std::move(xModel)) +{ +} + +sal_Bool SwVbaFormFields::getShaded() +{ + SAL_INFO("sw.vba", "SwVbaFormFields::getShaded stub"); + return false; +} + +void SwVbaFormFields::setShaded(sal_Bool /*bSet*/) +{ + SAL_INFO("sw.vba", "SwVbaFormFields::setShaded stub"); +} + +// uno::Reference<ooo::vba::word::XFormField> SwVbaFormFields::Add(const css::uno::Any& Range, +// sal_Int32 Type) +// { +// sw::mark::IFieldmark* pFieldmark = nullptr; +// switch (Type) +// { +// case ooo::vba::word::WdFieldType::wdFieldFormCheckBox: +// break; +// case ooo::vba::word::WdFieldType::wdFieldFormDropDown: +// break; +// case ooo::vba::word::WdFieldType::wdFieldFormTextInput: +// default:; +// } +// +// return uno::Reference<ooo::vba::word::XFormField>( +// new SwVbaFormField(mxParent, mxContext, m_xModel, *pFieldmark)); +// } + +// XEnumerationAccess +uno::Type SwVbaFormFields::getElementType() { return cppu::UnoType<word::XFormField>::get(); } + +uno::Reference<container::XEnumeration> SwVbaFormFields::createEnumeration() +{ + return new FormFieldsEnumWrapper(m_xIndexAccess); +} + +uno::Any SwVbaFormFields::createCollectionObject(const css::uno::Any& aSource) { return aSource; } + +OUString SwVbaFormFields::getServiceImplName() { return "SwVbaFormFields"; } + +css::uno::Sequence<OUString> SwVbaFormFields::getServiceNames() +{ + static uno::Sequence<OUString> const sNames{ "ooo.vba.word.FormFields" }; + return sNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaformfields.hxx b/sw/source/ui/vba/vbaformfields.hxx new file mode 100644 index 000000000000..22160dfb61cb --- /dev/null +++ b/sw/source/ui/vba/vbaformfields.hxx @@ -0,0 +1,56 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAFORMFIELDS_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAFORMFIELDS_HXX + +#include <ooo/vba/word/XFormFields.hpp> + +#include <vbahelper/vbacollectionimpl.hxx> + +typedef CollTestImplHelper<ooo::vba::word::XFormFields> SwVbaFormFields_BASE; + +class SwVbaFormFields : public SwVbaFormFields_BASE +{ +private: + const css::uno::Reference<css::frame::XModel>& m_xModel; + +public: + /// @throws css::uno::RuntimeException + SwVbaFormFields(const css::uno::Reference<ov::XHelperInterface>& xParent, + const css::uno::Reference<css::uno::XComponentContext>& xContext, + const css::uno::Reference<css::frame::XModel>& xModel); + + // XFormFields + virtual sal_Bool SAL_CALL getShaded() override; + virtual void SAL_CALL setShaded(sal_Bool bSet) override; + //virtual css::uno::Reference<ooo::vba::word::XFormField> SAL_CALL Add(const css::uno::Any& Range, sal_Int32 Type) override; + + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference<css::container::XEnumeration> SAL_CALL createEnumeration() override; + + // SwVbaFormFields_BASE + virtual css::uno::Any createCollectionObject(const css::uno::Any& aSource) override; + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAFORMFIELDS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |