writerfilter/inc/dmapper/resourcemodel.hxx | 2 writerfilter/source/dmapper/DomainMapper.cxx | 5 ++ writerfilter/source/dmapper/DomainMapper.hxx | 2 writerfilter/source/dmapper/DomainMapper_Impl.cxx | 8 +++ writerfilter/source/dmapper/DomainMapper_Impl.hxx | 9 ++++ writerfilter/source/dmapper/LoggedResources.hxx | 2 writerfilter/source/dmapper/SdtHelper.cxx | 47 +++++++++++++++++++++- writerfilter/source/dmapper/SdtHelper.hxx | 11 ++++- writerfilter/source/ooxml/OOXMLDocumentImpl.cxx | 1 9 files changed, 84 insertions(+), 3 deletions(-)
New commits: commit 20c7e0355ed83bfb235b1b188171d7cb4c6664c9 Author: Vasily Melenchuk <vasily.melenc...@cib.de> AuthorDate: Fri Nov 19 15:09:31 2021 +0300 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Fri Feb 18 08:26:28 2022 +0100 tdf#104823: basic support for reading field data from databinding Change-Id: Ie45eb18205c1c54a631303b45887e54e456b6d5d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125550 Tested-by: Jenkins Reviewed-by: Vasily Melenchuk <vasily.melenc...@cib.de> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127129 Tested-by: Thorsten Behrens <thorsten.behr...@allotropia.de> Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130042 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/writerfilter/inc/dmapper/resourcemodel.hxx b/writerfilter/inc/dmapper/resourcemodel.hxx index 44e659235845..f54cfb0b455f 100644 --- a/writerfilter/inc/dmapper/resourcemodel.hxx +++ b/writerfilter/inc/dmapper/resourcemodel.hxx @@ -205,6 +205,8 @@ public: /// The current section is the last one in this body text. virtual void markLastSectionGroup( ) { }; + virtual void setDocumentReference(void* pDocument) = 0; + /** Receives start mark for group with the same paragraph properties. */ diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index 2d983a496e1e..e794bdcdc2c8 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -183,6 +183,11 @@ DomainMapper::DomainMapper( const uno::Reference< uno::XComponentContext >& xCon catch( const uno::Exception& ) {} } +void DomainMapper::setDocumentReference(void* pDocument) +{ + m_pImpl->setDocumentReference(pDocument); +} + DomainMapper::~DomainMapper() { try diff --git a/writerfilter/source/dmapper/DomainMapper.hxx b/writerfilter/source/dmapper/DomainMapper.hxx index b2c2ba63d9a0..6fcbf14bdb93 100644 --- a/writerfilter/source/dmapper/DomainMapper.hxx +++ b/writerfilter/source/dmapper/DomainMapper.hxx @@ -81,6 +81,8 @@ public: utl::MediaDescriptor const & rMediaDesc); virtual ~DomainMapper() override; + virtual void setDocumentReference(void* pDocument) override; + // Stream virtual void markLastParagraphInSection() override; virtual void markLastSectionGroup() override; diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index 985041c292ea..cf41cc167e53 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -270,6 +270,7 @@ DomainMapper_Impl::DomainMapper_Impl( utl::MediaDescriptor const & rMediaDesc) : m_eDocumentType( eDocumentType ), m_rDMapper( rDMapper ), + m_pOOXMLDocument(nullptr), m_xTextDocument( xModel, uno::UNO_QUERY ), m_xTextFactory( xModel, uno::UNO_QUERY ), m_xComponentContext( xContext ), @@ -371,7 +372,7 @@ DomainMapper_Impl::DomainMapper_Impl( getTableManager( ).startLevel(); m_bUsingEnhancedFields = !utl::ConfigManager::IsFuzzing() && officecfg::Office::Common::Filter::Microsoft::Import::ImportWWFieldsAsEnhancedFields::get(m_xComponentContext); - m_pSdtHelper = new SdtHelper(*this); + m_pSdtHelper = new SdtHelper(*this, m_xComponentContext); m_aRedlines.push(std::vector<RedlineParamsPtr>()); @@ -395,6 +396,11 @@ DomainMapper_Impl::~DomainMapper_Impl() } } +writerfilter::ooxml::OOXMLDocument* DomainMapper_Impl::getDocumentReference() const +{ + return static_cast<writerfilter::ooxml::OOXMLDocument*>(m_pOOXMLDocument); +} + uno::Reference< container::XNameContainer > const & DomainMapper_Impl::GetPageStyles() { if(!m_xPageStyles1.is()) diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx index 668461bc978a..c6f4755507eb 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx @@ -75,6 +75,11 @@ namespace com{ namespace sun{ namespace star{ }}} namespace writerfilter { + +namespace ooxml { + class OOXMLDocument; +} + namespace dmapper { class SdtHelper; @@ -436,6 +441,7 @@ public: private: SourceDocumentType const m_eDocumentType; DomainMapper& m_rDMapper; + void* m_pOOXMLDocument; OUString m_aBaseUrl; css::uno::Reference<css::text::XTextDocument> m_xTextDocument; css::uno::Reference<css::beans::XPropertySet> m_xDocumentSettings; @@ -602,6 +608,9 @@ public: utl::MediaDescriptor const & rMediaDesc); ~DomainMapper_Impl(); + void setDocumentReference(void* pDocument) { m_pOOXMLDocument = pDocument; }; + writerfilter::ooxml::OOXMLDocument* getDocumentReference() const; + SectionPropertyMap* GetLastSectionContext( ) { return dynamic_cast< SectionPropertyMap* >( m_pLastSectionContext.get( ) ); diff --git a/writerfilter/source/dmapper/LoggedResources.hxx b/writerfilter/source/dmapper/LoggedResources.hxx index 3177224d4664..acb06d08781f 100644 --- a/writerfilter/source/dmapper/LoggedResources.hxx +++ b/writerfilter/source/dmapper/LoggedResources.hxx @@ -72,6 +72,8 @@ public: void startGlossaryEntry() override; void endGlossaryEntry() override; + virtual void setDocumentReference(void* /*pDocument*/) override{}; + protected: virtual void lcl_startSectionGroup() = 0; virtual void lcl_endSectionGroup() = 0; diff --git a/writerfilter/source/dmapper/SdtHelper.cxx b/writerfilter/source/dmapper/SdtHelper.cxx index d64f6aaf5b55..58252661ef20 100644 --- a/writerfilter/source/dmapper/SdtHelper.cxx +++ b/writerfilter/source/dmapper/SdtHelper.cxx @@ -20,12 +20,19 @@ #include "DomainMapper_Impl.hxx" #include "StyleSheetTable.hxx" #include <officecfg/Office/Writer.hxx> +#include <com/sun/star/util/XRefreshable.hpp> +#include <com/sun/star/text/XTextFieldsSupplier.hpp> +#include <ooxml/OOXMLDocument.hxx> +#include <com/sun/star/xml/xpath/XPathAPI.hpp> +#include <com/sun/star/xml/dom/XNode.hpp> namespace writerfilter { namespace dmapper + { using namespace ::com::sun::star; +using namespace ::css::xml::xpath; /// w:sdt's w:dropDownList doesn't have width, so guess the size based on the longest string. static awt::Size lcl_getOptimalWidth(const StyleSheetTablePtr& pStyleSheet, @@ -68,8 +75,10 @@ static awt::Size lcl_getOptimalWidth(const StyleSheetTablePtr& pStyleSheet, return { nWidth + nBorder + nHeight, nHeight + nBorder }; } -SdtHelper::SdtHelper(DomainMapper_Impl& rDM_Impl) +SdtHelper::SdtHelper(DomainMapper_Impl& rDM_Impl, + css::uno::Reference<css::uno::XComponentContext> const& xContext) : m_rDM_Impl(rDM_Impl) + , m_xComponentContext(xContext) , m_aControlType(SdtControlType::unknown) , m_bHasElements(false) , m_bOutsideAParagraph(false) @@ -78,6 +87,37 @@ SdtHelper::SdtHelper(DomainMapper_Impl& rDM_Impl) SdtHelper::~SdtHelper() = default; +std::optional<OUString> SdtHelper::getValueFromDataBinding() +{ + // No xpath - nothing to do + if (m_sDataBindingXPath.isEmpty()) + return {}; + + writerfilter::ooxml::OOXMLDocument* pDocument = m_rDM_Impl.getDocumentReference(); + assert(pDocument); + if (!pDocument) + return {}; + + // Iterate all custom xmls documents and evaluate xpath to get value + uno::Sequence<uno::Reference<xml::dom::XDocument>> aCustomXmls + = pDocument->getCustomXmlDomList(); + for (const auto& xCustomXml : aCustomXmls) + { + uno::Reference<XXPathAPI> xXpathAPI = XPathAPI::create(m_xComponentContext); + + //xXpathAPI->registerNS("ns0", m_sDataBindingPrefixMapping); + xXpathAPI->registerNS("ns0", "http://schemas.microsoft.com/vsto/samples"); + uno::Reference<XXPathObject> xResult = xXpathAPI->eval(xCustomXml, m_sDataBindingXPath); + + if (xResult.is()) + { + return xResult->getString(); + } + } + + return {}; +} + void SdtHelper::createDropDownControl() { assert(getControlType() == SdtControlType::dropDown); @@ -189,6 +229,11 @@ void SdtHelper::createDateContentControl() uno::makeAny(m_sLocale.makeStringAndClear())); } OUString sFullDate = m_sDate.makeStringAndClear(); + + std::optional<OUString> oData = getValueFromDataBinding(); + if (oData.has_value()) + sFullDate = *oData; + if (!sFullDate.isEmpty()) { sal_Int32 nTimeSep = sFullDate.indexOf("T"); diff --git a/writerfilter/source/dmapper/SdtHelper.hxx b/writerfilter/source/dmapper/SdtHelper.hxx index ed2c3c690f7a..771bfdb8ef22 100644 --- a/writerfilter/source/dmapper/SdtHelper.hxx +++ b/writerfilter/source/dmapper/SdtHelper.hxx @@ -11,6 +11,7 @@ #define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_SDTHELPER_HXX #include <vector> +#include <optional> #include <com/sun/star/beans/PropertyValue.hpp> #include <com/sun/star/text/XTextRange.hpp> @@ -24,6 +25,10 @@ namespace sun { namespace star { +namespace uno +{ +class XComponentContext; +} namespace awt { struct Size; @@ -55,6 +60,7 @@ enum class SdtControlType class SdtHelper final : public virtual SvRefBase { DomainMapper_Impl& m_rDM_Impl; + css::uno::Reference<css::uno::XComponentContext> m_xComponentContext; /// Items of the drop-down control. std::vector<OUString> m_aDropDownItems; @@ -90,8 +96,11 @@ class SdtHelper final : public virtual SvRefBase css::uno::Reference<css::awt::XControlModel> const& xControlModel, const css::uno::Sequence<css::beans::PropertyValue>& rGrabBag); + std::optional<OUString> getValueFromDataBinding(); + public: - explicit SdtHelper(DomainMapper_Impl& rDM_Impl); + explicit SdtHelper(DomainMapper_Impl& rDM_Impl, + css::uno::Reference<css::uno::XComponentContext> const& xContext); ~SdtHelper() override; std::vector<OUString>& getDropDownItems() { return m_aDropDownItems; } diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx index 2df01a68f27c..e8449752c77b 100644 --- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx +++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx @@ -478,6 +478,7 @@ void OOXMLDocumentImpl::resolve(Stream & rStream) { uno::Reference<uno::XComponentContext> xContext(mpStream->getContext()); + rStream.setDocumentReference(this); OOXMLFastDocumentHandler * pDocHandler = new OOXMLFastDocumentHandler(xContext, &rStream, this, mnXNoteId); pDocHandler->setIsSubstream( mbIsSubstream );