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 f65bc56d749e19562dd6f295dcc286efe97b7246 Author: Vasily Melenchuk <vasily.melenc...@cib.de> AuthorDate: Fri Nov 19 15:09:31 2021 +0300 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Tue Dec 21 12:49:02 2021 +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> diff --git a/writerfilter/inc/dmapper/resourcemodel.hxx b/writerfilter/inc/dmapper/resourcemodel.hxx index bd528d1a1e59..18196a9004d5 100644 --- a/writerfilter/inc/dmapper/resourcemodel.hxx +++ b/writerfilter/inc/dmapper/resourcemodel.hxx @@ -204,6 +204,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 3ddb4c27c470..cb5b46525711 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -182,6 +182,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 0913dd125814..c472e1b3846e 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 dbc9af73c7d6..f555fdf92b10 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -241,6 +241,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 ), @@ -335,7 +336,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>()); } @@ -354,6 +355,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 2f264c4c9c19..7dc8f96bb6ea 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx @@ -72,6 +72,11 @@ namespace com{ namespace sun{ namespace star{ }}} namespace writerfilter { + +namespace ooxml { + class OOXMLDocument; +} + namespace dmapper { class SdtHelper; @@ -429,6 +434,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; @@ -592,6 +598,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 bec04a949ac7..8886420bc922 100644 --- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx +++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx @@ -465,6 +465,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 );