summaryrefslogtreecommitdiff
path: root/writerfilter/source/dmapper
diff options
context:
space:
mode:
authorVasily Melenchuk <vasily.melenchuk@cib.de>2021-11-19 15:09:31 +0300
committerVasily Melenchuk <vasily.melenchuk@cib.de>2021-12-18 15:54:11 +0100
commitbe172e5a93a94b2c615dc0aae0979b9a9fa9ebab (patch)
tree79c311ae4607f33a30dca52fc5d335acb3bd93fa /writerfilter/source/dmapper
parent6e91ff7b57a231ca34f619a40297cf6ef1904ea2 (diff)
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.melenchuk@cib.de>
Diffstat (limited to 'writerfilter/source/dmapper')
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx5
-rw-r--r--writerfilter/source/dmapper/DomainMapper.hxx2
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx8
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.hxx8
-rw-r--r--writerfilter/source/dmapper/LoggedResources.hxx2
-rw-r--r--writerfilter/source/dmapper/SdtHelper.cxx55
-rw-r--r--writerfilter/source/dmapper/SdtHelper.hxx16
7 files changed, 92 insertions, 4 deletions
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; }