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 );

Reply via email to