diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2015-12-02 10:38:20 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2015-12-02 10:55:11 +0100 |
commit | 831492f3d50f3d131f458f4ec0e5e802b612923f (patch) | |
tree | 8588488a1ec159171da00f11f8c53c9ea9478111 /writerfilter/source | |
parent | fb60f000525427af3b331a746f8cedc54fd32922 (diff) |
DOCX import: handle <w:smartTag>
These can be sort of arbitrary key-value pairs around one or multiple
runs, handle the following subset:
- when they appear at a paragraph context -> we assume they are
annotations on the paragraph
- when the smart tag's URI/element is RDF -> we map these to RDF
metadata statements on paragraphs
- when the attribute name's namespace is known, because in ODF we need
to specify both a path and a type (namespace) for the RDF graph, and
OOXML only provides a namespace
As a start, recognize the TSCP BAF namespace from
<https://www.tscp.org/wp-content/uploads/2013/08/TSCP_BAFv1.pdf>.
Change-Id: Ib188b1395e7ec7e0441b4f12f86cfef99fb9f096
Diffstat (limited to 'writerfilter/source')
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper.cxx | 2 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper_Impl.cxx | 2 | ||||
-rw-r--r-- | writerfilter/source/dmapper/SmartTagHandler.cxx | 62 | ||||
-rw-r--r-- | writerfilter/source/dmapper/SmartTagHandler.hxx | 15 |
4 files changed, 77 insertions, 4 deletions
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index 572f4444ea75..fb48b9a72800 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -2662,7 +2662,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext ) case NS_ooxml::LN_CT_SmartTagRun_smartTagPr: { writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if (pProperties.get()) + if (pProperties.get() && m_pImpl->GetTopContextType() == CONTEXT_PARAGRAPH) pProperties->resolve(m_pImpl->getSmartTagHandler()); } break; diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index ef126b8cd50f..2d858d4701a1 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -226,6 +226,7 @@ DomainMapper_Impl::DomainMapper_Impl( m_xAnnotationField(), m_nAnnotationId( -1 ), m_aAnnotationPositions(), + m_aSmartTagHandler(m_xComponentContext, m_xTextDocument), m_xInsertTextRange(rMediaDesc.getUnpackedValueOrDefault("TextInsertModeRange", uno::Reference<text::XTextRange>())), m_bIsNewDoc(!rMediaDesc.getUnpackedValueOrDefault("InsertMode", false)), m_bInTableStyleRunProps(false), @@ -1154,6 +1155,7 @@ void DomainMapper_Impl::finishParagraph( PropertyMapPtr pPropertyMap ) } } getTableManager( ).handle(xTextRange); + m_aSmartTagHandler.handle(xTextRange); // Get the end of paragraph character inserted uno::Reference< text::XTextCursor > xCur = xTextRange->getText( )->createTextCursor( ); diff --git a/writerfilter/source/dmapper/SmartTagHandler.cxx b/writerfilter/source/dmapper/SmartTagHandler.cxx index 7c44cde2d544..dc9f094e4917 100644 --- a/writerfilter/source/dmapper/SmartTagHandler.cxx +++ b/writerfilter/source/dmapper/SmartTagHandler.cxx @@ -8,8 +8,22 @@ */ #include <SmartTagHandler.hxx> + +#include <com/sun/star/rdf/URI.hpp> + #include <ooxml/resourceids.hxx> +namespace +{ +OUString lcl_getTypePath(const OUString& rType) +{ + OUString aRet; + if (rType == "urn:tscp:names:baf:1.1") + aRet = "tscp/baf.rdf"; + return aRet; +} +} + namespace writerfilter { namespace dmapper @@ -17,8 +31,10 @@ namespace dmapper using namespace ::com::sun::star; -SmartTagHandler::SmartTagHandler() - : LoggedProperties("SmartTagHandler") +SmartTagHandler::SmartTagHandler(const uno::Reference<uno::XComponentContext>& xComponentContext, const uno::Reference<text::XTextDocument>& xTextDocument) + : LoggedProperties("SmartTagHandler"), + m_xComponentContext(xComponentContext), + m_xDocumentMetadataAccess(xTextDocument, uno::UNO_QUERY) { } @@ -31,8 +47,11 @@ void SmartTagHandler::lcl_attribute(Id nName, Value& rValue) switch (nName) { case NS_ooxml::LN_CT_Attr_name: + m_aAttributes.emplace_back(rValue.getString(), OUString()); break; case NS_ooxml::LN_CT_Attr_val: + if (!m_aAttributes.empty()) + m_aAttributes.back().second = rValue.getString(); break; default: SAL_WARN("writerfilter", "SmartTagHandler::lcl_attribute: unhandled attribute " << nName << " (string value: '"<<rValue.getString()<<"')"); @@ -64,6 +83,45 @@ void SmartTagHandler::setElement(const OUString& rElement) m_aElement = rElement; } +void SmartTagHandler::handle(const uno::Reference<text::XTextRange>& xParagraph) +{ + if (!m_aURI.isEmpty() && !m_aElement.isEmpty() && !m_aAttributes.empty()) + { + uno::Reference<rdf::XResource> xSubject(xParagraph, uno::UNO_QUERY); + + for (const std::pair<OUString, OUString>& rAttribute : m_aAttributes) + { + sal_Int32 nIndex = rAttribute.first.indexOf('#'); + if (nIndex == -1) + continue; + + OUString aTypeNS = rAttribute.first.copy(0, nIndex); + OUString aMetadataFilePath = lcl_getTypePath(aTypeNS); + if (aMetadataFilePath.isEmpty()) + continue; + + uno::Reference<rdf::XURI> xType = rdf::URI::create(m_xComponentContext, aTypeNS); + uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = m_xDocumentMetadataAccess->getMetadataGraphsWithType(xType); + uno::Reference<rdf::XURI> xGraphName; + if (aGraphNames.hasElements()) + xGraphName = aGraphNames[0]; + else + { + uno::Sequence< uno::Reference<rdf::XURI> > xTypes = { xType }; + xGraphName = m_xDocumentMetadataAccess->addMetadataFile(aMetadataFilePath, xTypes); + } + uno::Reference<rdf::XNamedGraph> xGraph = m_xDocumentMetadataAccess->getRDFRepository()->getGraph(xGraphName); + uno::Reference<rdf::XURI> xKey = rdf::URI::create(m_xComponentContext, rAttribute.first); + uno::Reference<rdf::XURI> xValue = rdf::URI::create(m_xComponentContext, rAttribute.second); + xGraph->addStatement(xSubject, xKey, xValue); + } + + m_aURI.clear(); + m_aElement.clear(); + m_aAttributes.clear(); + } +} + } // namespace dmapper } // namespace writerfilter diff --git a/writerfilter/source/dmapper/SmartTagHandler.hxx b/writerfilter/source/dmapper/SmartTagHandler.hxx index ae5996b2d73c..e6a4a230fed5 100644 --- a/writerfilter/source/dmapper/SmartTagHandler.hxx +++ b/writerfilter/source/dmapper/SmartTagHandler.hxx @@ -9,6 +9,13 @@ #ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_SMARTTAGHANDLER_HXX #define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_SMARTTAGHANDLER_HXX +#include <vector> + +#include <com/sun/star/rdf/XDocumentMetadataAccess.hpp> +#include <com/sun/star/text/XTextDocument.hpp> +#include <com/sun/star/text/XTextRange.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> + #include "LoggedResources.hxx" namespace writerfilter @@ -20,11 +27,14 @@ namespace dmapper class SmartTagHandler : public LoggedProperties { + css::uno::Reference<css::uno::XComponentContext> m_xComponentContext; + css::uno::Reference<css::rdf::XDocumentMetadataAccess> m_xDocumentMetadataAccess; OUString m_aURI; OUString m_aElement; + std::vector< std::pair<OUString, OUString> > m_aAttributes; public: - SmartTagHandler(); + SmartTagHandler(const css::uno::Reference<css::uno::XComponentContext>& xComponentContext, const css::uno::Reference<css::text::XTextDocument>& xTextDocument); virtual ~SmartTagHandler(); virtual void lcl_attribute(Id Name, Value& val) override; @@ -32,6 +42,9 @@ public: void setURI(const OUString& rURI); void setElement(const OUString& rElement); + + /// Set m_aAttributes as RDF statements on xParagraph. + void handle(const css::uno::Reference<css::text::XTextRange>& xParagraph); }; } // namespace dmapper |