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 |    8 +++
 writerfilter/source/dmapper/LoggedResources.hxx   |    2 
 writerfilter/source/dmapper/SdtHelper.cxx         |   55 +++++++++++++++++++++-
 writerfilter/source/dmapper/SdtHelper.hxx         |   16 +++++-
 writerfilter/source/ooxml/OOXMLDocumentImpl.cxx   |    2 
 9 files changed, 96 insertions(+), 4 deletions(-)

New commits:
commit c3d3eb7bdcb07824af7d205112f36201634aee59
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 23:23:20 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>
    (cherry picked from commit be172e5a93a94b2c615dc0aae0979b9a9fa9ebab)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127060
    Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de>

diff --git a/writerfilter/inc/dmapper/resourcemodel.hxx 
b/writerfilter/inc/dmapper/resourcemodel.hxx
index 1a525b12296f..9e980494b09b 100644
--- a/writerfilter/inc/dmapper/resourcemodel.hxx
+++ b/writerfilter/inc/dmapper/resourcemodel.hxx
@@ -202,6 +202,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 2958f004553d..a7b759ed0e2d 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -187,6 +187,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 688f4c37edc0..4ed2cca83526 100644
--- a/writerfilter/source/dmapper/DomainMapper.hxx
+++ b/writerfilter/source/dmapper/DomainMapper.hxx
@@ -80,6 +80,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 5662e8967d8b..96b7b1391877 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -275,6 +275,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 ),
@@ -378,7 +379,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>());
 
@@ -402,6 +403,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 fb89fb7a7087..b4633cf8beeb 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -67,6 +67,10 @@ namespace com::sun::star{
         namespace beans{ class XPropertySet;}
 }
 
+namespace writerfilter::ooxml {
+    class OOXMLDocument;
+}
+
 namespace writerfilter::dmapper {
 
 class SdtHelper;
@@ -445,6 +449,7 @@ public:
 private:
     SourceDocumentType                                                         
     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;
@@ -629,6 +634,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 a6f49cf07d29..848d17b68219 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 5466baec8fc1..c53a93f62de6 100644
--- a/writerfilter/source/dmapper/SdtHelper.cxx
+++ b/writerfilter/source/dmapper/SdtHelper.cxx
@@ -21,9 +21,17 @@
 #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::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,
@@ -65,8 +73,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)
@@ -75,6 +85,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);
@@ -180,6 +221,7 @@ void SdtHelper::createDateContentControl()
     if (xNameCont.is())
     {
         OUString sDateFormat = m_sDateFormat.makeStringAndClear();
+
         // Replace quotation mark used for marking static strings in date 
format
         sDateFormat = sDateFormat.replaceAll("'", "\"");
         xNameCont->insertByName(ODF_FORMDATE_DATEFORMAT, 
uno::makeAny(sDateFormat));
@@ -187,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");
@@ -195,6 +242,12 @@ void SdtHelper::createDateContentControl()
         xNameCont->insertByName(ODF_FORMDATE_CURRENTDATE, 
uno::makeAny(sFullDate));
     }
 
+    uno::Reference<text::XTextFieldsSupplier> 
xTextFieldsSupplier(m_rDM_Impl.GetTextDocument(),
+                                                                  
uno::UNO_QUERY);
+    uno::Reference<util::XRefreshable> 
xRefreshable(xTextFieldsSupplier->getTextFields(),
+                                                    uno::UNO_QUERY);
+    xRefreshable->refresh();
+
     setControlType(SdtControlType::unknown);
 
     // Store all unused sdt parameters from grabbag
diff --git a/writerfilter/source/dmapper/SdtHelper.hxx 
b/writerfilter/source/dmapper/SdtHelper.hxx
index 9d31e1621504..9d2c6b1da7cf 100644
--- a/writerfilter/source/dmapper/SdtHelper.hxx
+++ b/writerfilter/source/dmapper/SdtHelper.hxx
@@ -10,6 +10,7 @@
 #pragma once
 
 #include <vector>
+#include <optional>
 
 #include <com/sun/star/beans/PropertyValue.hpp>
 #include <com/sun/star/text/XTextRange.hpp>
@@ -17,11 +18,18 @@
 #include <rtl/ustrbuf.hxx>
 #include <tools/ref.hxx>
 
-namespace com::sun::star::awt
+namespace com::sun::star
+{
+namespace uno
+{
+class XComponentContext;
+}
+namespace awt
 {
 struct Size;
 class XControlModel;
 }
+}
 
 namespace writerfilter::dmapper
 {
@@ -43,6 +51,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;
@@ -78,8 +87,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 53eeb93fe149..62cab6655fc9 100644
--- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
+++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
@@ -472,6 +472,8 @@ void OOXMLDocumentImpl::resolve(Stream & rStream)
 
     uno::Reference<uno::XComponentContext> xContext(mpStream->getContext());
 
+    rStream.setDocumentReference(this);
+
     rtl::Reference<OOXMLFastDocumentHandler> pDocHandler =
                 new OOXMLFastDocumentHandler(xContext, &rStream, this, 
mnXNoteId);
     pDocHandler->setIsSubstream( mbIsSubstream );

Reply via email to