oovbaapi/ooo/vba/word/XFormField.idl | 3 +- sw/qa/core/data/docm/testVBA.docm |binary sw/source/filter/ww8/docxattributeoutput.cxx | 10 +++++++++ sw/source/filter/ww8/docxattributeoutput.hxx | 1 sw/source/ui/vba/vbadocument.cxx | 2 - sw/source/ui/vba/vbaformfield.cxx | 29 ++++++++++++++++++--------- sw/source/ui/vba/vbaformfield.hxx | 7 +++--- sw/source/ui/vba/vbaformfields.cxx | 26 +++++++++++++----------- sw/source/ui/vba/vbaformfields.hxx | 3 +- writerfilter/source/dmapper/DomainMapper.cxx | 11 +--------- 10 files changed, 56 insertions(+), 36 deletions(-)
New commits: commit 8d0a80fd909d961c37eb613d51858720aa766332 Author: Justin Luth <justin.l...@collabora.com> AuthorDate: Thu Dec 8 11:45:05 2022 -0500 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Tue Dec 20 08:07:11 2022 +0000 tdf#151548 sw content controls: preserve tag for block SDTs The tag is critical for VBA access. Although we do not yet import blockSdts as content controls, losing this would break any VBA macros for MS Word. So make sure it round-trips. I can't imagine why it wasn't treated the same as alias. I guess because Alias is seen, while tag appears to have no valuable function (until VBA, where it becomes the most likely ID field.) Change-Id: I05a04faa9d2314c7b37c5b86f107bd1a16019509 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143830 Tested-by: Jenkins Reviewed-by: Justin Luth <jl...@mail.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144552 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 9c8bd63a945f..bd9bba939aa7 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -615,6 +615,8 @@ void SdtBlockHelper::DeleteAndResetTheLists() m_pTextAttrs.clear(); if (!m_aAlias.isEmpty()) m_aAlias.clear(); + if (!m_aTag.isEmpty()) + m_aTag.clear(); if (!m_aPlaceHolderDocPart.isEmpty()) m_aPlaceHolderDocPart.clear(); if (!m_aColor.isEmpty()) @@ -718,6 +720,9 @@ void SdtBlockHelper::WriteExtraParams(::sax_fastparser::FSHelperPtr& pSerializer if (!m_aAlias.isEmpty()) pSerializer->singleElementNS(XML_w, XML_alias, FSNS(XML_w, XML_val), m_aAlias); + + if (!m_aTag.isEmpty()) + pSerializer->singleElementNS(XML_w, XML_tag, FSNS(XML_w, XML_val), m_aTag); } void SdtBlockHelper::EndSdtBlock(::sax_fastparser::FSHelperPtr& pSerializer) @@ -822,6 +827,11 @@ void SdtBlockHelper::GetSdtParamsFromGrabBag(const uno::Sequence<beans::Property if (!(aPropertyValue.Value >>= m_aAlias)) SAL_WARN("sw.ww8", "DocxAttributeOutput::GrabBag: unexpected sdt alias value"); } + else if (aPropertyValue.Name == "ooxml:CT_SdtPr_tag" && m_aTag.isEmpty()) + { + if (!(aPropertyValue.Value >>= m_aTag)) + SAL_WARN("sw.ww8", "DocxAttributeOutput::GrabBag: unexpected sdt tag value"); + } else if (aPropertyValue.Name == "ooxml:CT_SdtPr_id") m_bHasId = true; else if (aPropertyValue.Name == "ooxml:CT_SdtPr_citation") diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx index 262da0cc0051..07bffdb061ae 100644 --- a/sw/source/filter/ww8/docxattributeoutput.hxx +++ b/sw/source/filter/ww8/docxattributeoutput.hxx @@ -142,6 +142,7 @@ public: OUString m_aColor; OUString m_aPlaceHolderDocPart; OUString m_aAlias; + OUString m_aTag; sal_Int32 m_nSdtPrToken; void DeleteAndResetTheLists(); diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index 82a6264d4b8b..4395b65fc9c8 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -2874,14 +2874,6 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext ) break; } } - else - { - if (nSprmId == NS_ooxml::LN_CT_SdtPr_tag) - { - // Tag is only handled here in case of inline SDT. - break; - } - } // this is an unsupported SDT property, create a grab bag for it OUString sName; @@ -2897,6 +2889,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext ) case NS_ooxml::LN_CT_SdtPr_group: sName = "ooxml:CT_SdtPr_group"; break; case NS_ooxml::LN_CT_SdtPr_id: sName = "ooxml:CT_SdtPr_id"; break; case NS_ooxml::LN_CT_SdtPr_alias: sName = "ooxml:CT_SdtPr_alias"; break; + case NS_ooxml::LN_CT_SdtPr_tag: sName = "ooxml:CT_SdtPr_tag"; break; case NS_ooxml::LN_CT_SdtPlaceholder_docPart: sName = "ooxml:CT_SdtPlaceholder_docPart"; break; case NS_ooxml::LN_CT_SdtPr_color: sName = "ooxml:CT_SdtPr_color"; break; default: assert(false); @@ -2917,7 +2910,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext ) if (pProperties) pProperties->resolve(*this); - if (nSprmId == NS_ooxml::LN_CT_SdtPr_alias) + if (nSprmId == NS_ooxml::LN_CT_SdtPr_alias || nSprmId == NS_ooxml::LN_CT_SdtPr_tag) { beans::PropertyValue aValue; aValue.Name = sName; commit 61d0f5b8425b74c86c696a7934a6b6eb090ffec1 Author: Caolán McNamara <caol...@redhat.com> AuthorDate: Fri Nov 11 13:51:59 2022 +0000 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Tue Dec 20 08:07:01 2022 +0000 tdf#151548 vba FormFields: implement Range This squashed commit includes cid#1516788 Uninitialized pointer field Change-Id: I9565a995aa400fd391de70606b59c16e68a042c3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142584 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caol...@redhat.com> Msgbox (FormFields("text1").Range.Text) Change-Id: Iac195e09bd3f9619890b336a0cb537a1acd00049 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144136 Tested-by: Jenkins Reviewed-by: Justin Luth <jl...@mail.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144551 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/oovbaapi/ooo/vba/word/XFormField.idl b/oovbaapi/ooo/vba/word/XFormField.idl index 2b879fb6c652..54d432e64cdc 100644 --- a/oovbaapi/ooo/vba/word/XFormField.idl +++ b/oovbaapi/ooo/vba/word/XFormField.idl @@ -24,6 +24,7 @@ module ooo { module vba { module word { +interface XRange; interface XFormField { interface ooo::vba::XHelperInterface; @@ -80,7 +81,7 @@ interface XFormField * Represents a contiguous area in a document. * Each Range object is defined by a starting and ending character position. */ - any Range(); + XRange Range(); }; }; }; }; diff --git a/sw/qa/core/data/docm/testVBA.docm b/sw/qa/core/data/docm/testVBA.docm index 839c8dd9f73c..44e59f03a753 100644 Binary files a/sw/qa/core/data/docm/testVBA.docm and b/sw/qa/core/data/docm/testVBA.docm differ diff --git a/sw/source/ui/vba/vbadocument.cxx b/sw/source/ui/vba/vbadocument.cxx index e72fee6d478c..502636b33530 100644 --- a/sw/source/ui/vba/vbadocument.cxx +++ b/sw/source/ui/vba/vbadocument.cxx @@ -303,7 +303,7 @@ SwVbaDocument::TablesOfContents( const uno::Any& index ) uno::Any SAL_CALL SwVbaDocument::FormFields(const uno::Any& index) { - uno::Reference<XCollection> xCol(new SwVbaFormFields(this, mxContext, mxModel)); + uno::Reference<XCollection> xCol(new SwVbaFormFields(this, mxContext, mxTextDocument)); if (index.hasValue()) return xCol->Item(index, uno::Any()); return uno::Any(xCol); diff --git a/sw/source/ui/vba/vbaformfield.cxx b/sw/source/ui/vba/vbaformfield.cxx index 8afaeb9d9480..0c8a8644e990 100644 --- a/sw/source/ui/vba/vbaformfield.cxx +++ b/sw/source/ui/vba/vbaformfield.cxx @@ -13,11 +13,13 @@ #include <doc.hxx> #include <docsh.hxx> +#include <unotextrange.hxx> #include "vbaformfield.hxx" #include "vbaformfieldcheckbox.hxx" #include "vbaformfielddropdown.hxx" #include "vbaformfieldtextinput.hxx" +#include "vbarange.hxx" #include "wordvbahelper.hxx" using namespace ::ooo::vba; @@ -34,10 +36,10 @@ using namespace ::com::sun::star; */ SwVbaFormField::SwVbaFormField(const uno::Reference<ooo::vba::XHelperInterface>& rParent, const uno::Reference<uno::XComponentContext>& rContext, - const uno::Reference<frame::XModel>& xModel, + const uno::Reference<text::XTextDocument>& xTextDocument, sw::mark::IFieldmark& rFormField) : SwVbaFormField_BASE(rParent, rContext) - , mxModel(xModel) + , m_xTextDocument(xTextDocument) , m_rFormField(rFormField) { } @@ -64,7 +66,7 @@ uno::Any SAL_CALL SwVbaFormField::TextInput() uno::Any SAL_CALL SwVbaFormField::Previous() { - SwDoc* pDoc = word::getDocShell(mxModel)->GetDoc(); + SwDoc* pDoc = word::getDocShell(m_xTextDocument)->GetDoc(); if (!pDoc) return uno::Any(); @@ -86,12 +88,12 @@ uno::Any SAL_CALL SwVbaFormField::Previous() return uno::Any(); return uno::Any(uno::Reference<word::XFormField>( - new SwVbaFormField(mxParent, mxContext, mxModel, *pFieldMark))); + new SwVbaFormField(mxParent, mxContext, m_xTextDocument, *pFieldMark))); } uno::Any SAL_CALL SwVbaFormField::Next() { - SwDoc* pDoc = word::getDocShell(mxModel)->GetDoc(); + SwDoc* pDoc = word::getDocShell(m_xTextDocument)->GetDoc(); if (!pDoc) return uno::Any(); @@ -113,13 +115,22 @@ uno::Any SAL_CALL SwVbaFormField::Next() return uno::Any(); return uno::Any(uno::Reference<word::XFormField>( - new SwVbaFormField(mxParent, mxContext, mxModel, *pFieldMark))); + new SwVbaFormField(mxParent, mxContext, m_xTextDocument, *pFieldMark))); } -uno::Any SAL_CALL SwVbaFormField::Range() +uno::Reference<word::XRange> SwVbaFormField::Range() { - SAL_INFO("sw.vba", "SwVbaFormField::getRange stub"); - return uno::Any(); + uno::Reference<word::XRange> xRet; + SwDoc* pDoc = word::getDocShell(m_xTextDocument)->GetDoc(); + if (pDoc) + { + uno::Reference<text::XTextRange> xText(SwXTextRange::CreateXTextRange( + *pDoc, m_rFormField.GetMarkStart(), &m_rFormField.GetMarkEnd())); + if (xText.is()) + xRet = new SwVbaRange(mxParent, mxContext, m_xTextDocument, xText->getStart(), + xText->getEnd()); + } + return xRet; } OUString SwVbaFormField::getDefaultPropertyName() { return "Type"; } diff --git a/sw/source/ui/vba/vbaformfield.hxx b/sw/source/ui/vba/vbaformfield.hxx index b004e4088cdb..260e79093589 100644 --- a/sw/source/ui/vba/vbaformfield.hxx +++ b/sw/source/ui/vba/vbaformfield.hxx @@ -8,6 +8,7 @@ */ #pragma once +#include <com/sun/star/text/XTextDocument.hpp> #include <ooo/vba/word/XFormField.hpp> #include <vbahelper/vbahelperinterface.hxx> @@ -19,14 +20,14 @@ typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XFormField> SwVbaFormFi class SwVbaFormField : public SwVbaFormField_BASE { private: - css::uno::Reference<css::frame::XModel> mxModel; + css::uno::Reference<css::text::XTextDocument> m_xTextDocument; 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, + const uno::Reference<text::XTextDocument>& xTextDocument, sw::mark::IFieldmark& rFormField); ~SwVbaFormField() override; @@ -38,7 +39,7 @@ public: css::uno::Any SAL_CALL TextInput() override; css::uno::Any SAL_CALL Previous() override; css::uno::Any SAL_CALL Next() override; - css::uno::Any SAL_CALL Range() override; + css::uno::Reference<ooo::vba::word::XRange> SAL_CALL Range() override; // Indicates which of the three form fields this is: oovbaapi/ooo/vba/word/WdFieldType.idl sal_Int32 SAL_CALL getType() override; diff --git a/sw/source/ui/vba/vbaformfields.cxx b/sw/source/ui/vba/vbaformfields.cxx index 008c7e87d547..187f41f3b4f7 100644 --- a/sw/source/ui/vba/vbaformfields.cxx +++ b/sw/source/ui/vba/vbaformfields.cxx @@ -28,6 +28,7 @@ using namespace ::com::sun::star; static sw::mark::IFieldmark* lcl_getFieldmark(std::string_view rName, sal_Int32& rIndex, const uno::Reference<frame::XModel>& xModel, uno::Sequence<OUString>* pElementNames = nullptr) + { SwDoc* pDoc = word::getDocShell(xModel)->GetDoc(); if (!pDoc) @@ -104,17 +105,18 @@ class FormFieldCollectionHelper private: uno::Reference<XHelperInterface> mxParent; uno::Reference<uno::XComponentContext> mxContext; - uno::Reference<frame::XModel> mxModel; + uno::Reference<text::XTextDocument> mxTextDocument; sw::mark::IFieldmark* m_pCache; public: /// @throws css::uno::RuntimeException FormFieldCollectionHelper(uno::Reference<ov::XHelperInterface> xParent, uno::Reference<uno::XComponentContext> xContext, - uno::Reference<frame::XModel> xModel) + uno::Reference<text::XTextDocument> xTextDocument) : mxParent(std::move(xParent)) , mxContext(std::move(xContext)) - , mxModel(std::move(xModel)) + , mxTextDocument(std::move(xTextDocument)) + , m_pCache(nullptr) { } @@ -122,18 +124,18 @@ public: sal_Int32 SAL_CALL getCount() override { sal_Int32 nCount = SAL_MAX_INT32; - lcl_getFieldmark("", nCount, mxModel); + lcl_getFieldmark("", nCount, mxTextDocument); return nCount == SAL_MAX_INT32 ? 0 : nCount; } uno::Any SAL_CALL getByIndex(sal_Int32 Index) override { - m_pCache = lcl_getFieldmark("", Index, mxModel); + m_pCache = lcl_getFieldmark("", Index, mxTextDocument); if (!m_pCache) throw lang::IndexOutOfBoundsException(); return uno::Any(uno::Reference<word::XFormField>( - new SwVbaFormField(mxParent, mxContext, mxModel, *m_pCache))); + new SwVbaFormField(mxParent, mxContext, mxTextDocument, *m_pCache))); } // XNameAccess @@ -141,7 +143,7 @@ public: { sal_Int32 nCount = SAL_MAX_INT32; uno::Sequence<OUString> aSeq; - lcl_getFieldmark("", nCount, mxModel, &aSeq); + lcl_getFieldmark("", nCount, mxTextDocument, &aSeq); return aSeq; } @@ -151,13 +153,13 @@ public: throw container::NoSuchElementException(); return uno::Any(uno::Reference<word::XFormField>( - new SwVbaFormField(mxParent, mxContext, mxModel, *m_pCache))); + new SwVbaFormField(mxParent, mxContext, mxTextDocument, *m_pCache))); } sal_Bool SAL_CALL hasByName(const OUString& aName) override { sal_Int32 nCount = -1; - m_pCache = lcl_getFieldmark(aName.toUtf8(), nCount, mxModel); + m_pCache = lcl_getFieldmark(aName.toUtf8(), nCount, mxTextDocument); return m_pCache != nullptr; } @@ -176,10 +178,10 @@ public: SwVbaFormFields::SwVbaFormFields(const uno::Reference<XHelperInterface>& xParent, const uno::Reference<uno::XComponentContext>& xContext, - const uno::Reference<frame::XModel>& xModel) + const uno::Reference<text::XTextDocument>& xTextDocument) : SwVbaFormFields_BASE(xParent, xContext, uno::Reference<container::XIndexAccess>( - new FormFieldCollectionHelper(xParent, xContext, xModel))) + new FormFieldCollectionHelper(xParent, xContext, xTextDocument))) { } @@ -209,7 +211,7 @@ void SwVbaFormFields::setShaded(sal_Bool /*bSet*/) // } // // return uno::Reference<ooo::vba::word::XFormField>( -// new SwVbaFormField(mxParent, mxContext, m_xModel, *pFieldmark)); +// new SwVbaFormField(mxParent, mxContext, m_xTextDocument, *pFieldmark)); // } // XEnumerationAccess diff --git a/sw/source/ui/vba/vbaformfields.hxx b/sw/source/ui/vba/vbaformfields.hxx index 865a1dab5604..2dfa9e76b0c4 100644 --- a/sw/source/ui/vba/vbaformfields.hxx +++ b/sw/source/ui/vba/vbaformfields.hxx @@ -8,6 +8,7 @@ */ #pragma once +#include <com/sun/star/text/XTextDocument.hpp> #include <ooo/vba/word/XFormFields.hpp> #include <vbahelper/vbacollectionimpl.hxx> @@ -20,7 +21,7 @@ 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); + const css::uno::Reference<css::text::XTextDocument>& xTextDocument); // XFormFields sal_Bool SAL_CALL getShaded() override;