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>
This commit is contained in:
Vasily Melenchuk
2021-12-18 15:54:11 +01:00
parent 6e91ff7b57
commit be172e5a93
9 changed files with 96 additions and 4 deletions
@@ -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.
*/
@@ -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
@@ -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;
@@ -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())
@@ -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( ) );
@@ -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;
+54 -1
View File
@@ -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
+14 -2
View File
@@ -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; }
@@ -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 );