summaryrefslogtreecommitdiff
path: root/writerfilter/source/dmapper
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2015-12-02 10:38:20 +0100
committerMiklos Vajna <vmiklos@collabora.co.uk>2015-12-02 10:55:11 +0100
commit831492f3d50f3d131f458f4ec0e5e802b612923f (patch)
tree8588488a1ec159171da00f11f8c53c9ea9478111 /writerfilter/source/dmapper
parentfb60f000525427af3b331a746f8cedc54fd32922 (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/dmapper')
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx2
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx2
-rw-r--r--writerfilter/source/dmapper/SmartTagHandler.cxx62
-rw-r--r--writerfilter/source/dmapper/SmartTagHandler.hxx15
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