diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2014-11-25 12:27:25 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2014-11-25 12:55:23 +0100 |
commit | 411bd6e440266a0db95907ad73a3a5be92bd1827 (patch) | |
tree | f7e1cfdada2eebcc129b1c251042225cb219d74e /external/libvisio | |
parent | b625baafd00ce578f8e68206fd8c1dd1206da2fc (diff) |
fdo#86664 VSDX import: handle metadata
Change-Id: I04a446e6b8a8352be9f091980bca31842bb7e643
Diffstat (limited to 'external/libvisio')
-rw-r--r-- | external/libvisio/UnpackedTarball_libvisio.mk | 1 | ||||
-rw-r--r-- | external/libvisio/vsdx-metadata.patch.1 | 462 |
2 files changed, 463 insertions, 0 deletions
diff --git a/external/libvisio/UnpackedTarball_libvisio.mk b/external/libvisio/UnpackedTarball_libvisio.mk index 1626dbb780d2..4451eb51d151 100644 --- a/external/libvisio/UnpackedTarball_libvisio.mk +++ b/external/libvisio/UnpackedTarball_libvisio.mk @@ -13,6 +13,7 @@ $(eval $(call gb_UnpackedTarball_set_tarball,libvisio,$(VISIO_TARBALL))) $(eval $(call gb_UnpackedTarball_add_patches,libvisio,\ external/libvisio/libvisio_quote.patch.1 \ + external/libvisio/vsdx-metadata.patch.1 \ )) # vim: set noet sw=4 ts=4: diff --git a/external/libvisio/vsdx-metadata.patch.1 b/external/libvisio/vsdx-metadata.patch.1 new file mode 100644 index 000000000000..58a0a7dc5d9a --- /dev/null +++ b/external/libvisio/vsdx-metadata.patch.1 @@ -0,0 +1,462 @@ +commit 1b1fd1b07728590c94694b4e8b1b00058ca02d52 +Author: Miklos Vajna <vmiklos@collabora.co.uk> +Date: Tue Nov 25 09:49:05 2014 +0100 + + fdo#86664 VSDX: import metadata + + Only title as a start. + + Change-Id: Id1b92992c75058f99b9c0c72d53c254110917ed7 + Reviewed-on: https://gerrit.libreoffice.org/13108 + Reviewed-by: Fridrich Strba <fridrich@documentfoundation.org> + Tested-by: Fridrich Strba <fridrich@documentfoundation.org> + +diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am +index 6080d31..955aac4 100644 +--- a/src/lib/Makefile.am ++++ b/src/lib/Makefile.am +@@ -75,6 +75,8 @@ libvisio_@VSD_MAJOR_VERSION@_@VSD_MINOR_VERSION@_la_SOURCES = \ + VSDXParser.h \ + VSDXTheme.cpp \ + VSDXTheme.h \ ++ VSDXMetaData.cpp \ ++ VSDXMetaData.h \ + $(generated_files) + + +@@ -83,6 +85,7 @@ VSDXMLParserBase.lo : $(generated_files) + VSDXMLTokenMap.lo : $(generated_files) + VSDXParser.lo : $(generated_files) + VSDXTheme.lo : $(generated_files) ++VSDXMetaData.lo : $(generated_files) + + $(top_builddir)/src/lib/tokens.h : $(top_builddir)/src/lib/tokens.gperf + +diff --git a/src/lib/VSDCollector.h b/src/lib/VSDCollector.h +index 26875f5..594fcf0 100644 +--- a/src/lib/VSDCollector.h ++++ b/src/lib/VSDCollector.h +@@ -139,6 +139,9 @@ public: + virtual void collectTextField(unsigned id, unsigned level, int nameId, int formatStringId) = 0; + virtual void collectNumericField(unsigned id, unsigned level, unsigned short format, double number, int formatStringId) = 0; + ++ // Metadata ++ virtual void collectMetaData(const librevenge::RVNGPropertyList &metaData) = 0; ++ + // Temporary hack + virtual void startPage(unsigned pageId) = 0; + virtual void endPage() = 0; +diff --git a/src/lib/VSDContentCollector.cpp b/src/lib/VSDContentCollector.cpp +index 9de0d30..822a5f4 100644 +--- a/src/lib/VSDContentCollector.cpp ++++ b/src/lib/VSDContentCollector.cpp +@@ -2730,6 +2730,11 @@ void libvisio::VSDContentCollector::_handleLevelChange(unsigned level) + m_currentLevel = level; + } + ++void libvisio::VSDContentCollector::collectMetaData(const librevenge::RVNGPropertyList &metaData) ++{ ++ m_pages.setMetaData(metaData); ++} ++ + void libvisio::VSDContentCollector::startPage(unsigned pageId) + { + if (m_isShapeStarted) +diff --git a/src/lib/VSDContentCollector.h b/src/lib/VSDContentCollector.h +index 38c6f72..a7d148a 100644 +--- a/src/lib/VSDContentCollector.h ++++ b/src/lib/VSDContentCollector.h +@@ -155,6 +155,8 @@ public: + void collectStyleThemeReference(unsigned level, const boost::optional<long> &lineColour, const boost::optional<long> &fillColour, + const boost::optional<long> &shadowColour, const boost::optional<long> &fontColour); + ++ virtual void collectMetaData(const librevenge::RVNGPropertyList &metaData); ++ + + // Field list + void collectFieldList(unsigned id, unsigned level); +diff --git a/src/lib/VSDPages.cpp b/src/lib/VSDPages.cpp +index e4a7792..544123b 100644 +--- a/src/lib/VSDPages.cpp ++++ b/src/lib/VSDPages.cpp +@@ -68,6 +68,11 @@ void libvisio::VSDPages::addBackgroundPage(const libvisio::VSDPage &page) + m_backgroundPages[page.m_currentPageID] = page; + } + ++void libvisio::VSDPages::setMetaData(const librevenge::RVNGPropertyList &metaData) ++{ ++ m_metaData = metaData; ++} ++ + void libvisio::VSDPages::draw(librevenge::RVNGDrawingInterface *painter) + { + if (!painter) +@@ -76,6 +81,7 @@ void libvisio::VSDPages::draw(librevenge::RVNGDrawingInterface *painter) + return; + + painter->startDocument(librevenge::RVNGPropertyList()); ++ painter->setDocumentMetaData(m_metaData); + + for (unsigned i = 0; i < m_pages.size(); ++i) + { +diff --git a/src/lib/VSDPages.h b/src/lib/VSDPages.h +index e87fd31..56358c2 100644 +--- a/src/lib/VSDPages.h ++++ b/src/lib/VSDPages.h +@@ -39,10 +39,12 @@ public: + void addPage(const VSDPage &page); + void addBackgroundPage(const VSDPage &page); + void draw(librevenge::RVNGDrawingInterface *painter); ++ void setMetaData(const librevenge::RVNGPropertyList &metaData); + private: + void _drawWithBackground(librevenge::RVNGDrawingInterface *painter, const VSDPage &page); + std::vector<VSDPage> m_pages; + std::map<unsigned, VSDPage> m_backgroundPages; ++ librevenge::RVNGPropertyList m_metaData; + }; + + +diff --git a/src/lib/VSDStylesCollector.h b/src/lib/VSDStylesCollector.h +index 38c9082..22f73a1 100644 +--- a/src/lib/VSDStylesCollector.h ++++ b/src/lib/VSDStylesCollector.h +@@ -152,6 +152,8 @@ public: + void collectTextField(unsigned id, unsigned level, int nameId, int formatStringId); + void collectNumericField(unsigned id, unsigned level, unsigned short format, double number, int formatStringId); + ++ virtual void collectMetaData(const librevenge::RVNGPropertyList &) { } ++ + // Temporary hack + void startPage(unsigned pageID); + void endPage(); +diff --git a/src/lib/VSDXMetaData.cpp b/src/lib/VSDXMetaData.cpp +new file mode 100644 +index 0000000..3cbd61d +--- /dev/null ++++ b/src/lib/VSDXMetaData.cpp +@@ -0,0 +1,113 @@ ++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ ++/* ++ * This file is part of the libvisio project. ++ * ++ * This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ */ ++ ++#include "VSDXMetaData.h" ++#include "VSDXMLTokenMap.h" ++#include "libvisio_utils.h" ++ ++libvisio::VSDXMetaData::VSDXMetaData() ++{ ++} ++ ++libvisio::VSDXMetaData::~VSDXMetaData() ++{ ++} ++ ++void libvisio::VSDXMetaData::readTitle(xmlTextReaderPtr reader) ++{ ++ int ret = 1; ++ int tokenId = XML_TOKEN_INVALID; ++ int tokenType = -1; ++ librevenge::RVNGString title; ++ do ++ { ++ ret = xmlTextReaderRead(reader); ++ tokenId = getElementToken(reader); ++ tokenType = xmlTextReaderNodeType(reader); ++ if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT) ++ title.append((const char *)xmlTextReaderConstValue(reader)); ++ } ++ while ((XML_DC_TITLE != tokenId || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret); ++ m_metaData.insert("dc:title", title); ++} ++ ++void libvisio::VSDXMetaData::readCoreProperties(xmlTextReaderPtr reader) ++{ ++ int ret = 1; ++ int tokenId = XML_TOKEN_INVALID; ++ int tokenType = -1; ++ do ++ { ++ ret = xmlTextReaderRead(reader); ++ tokenId = getElementToken(reader); ++ if (XML_TOKEN_INVALID == tokenId) ++ { ++ VSD_DEBUG_MSG(("VSDXMetaData::readCoreProperties: unknown token %s\n", xmlTextReaderConstName(reader))); ++ } ++ tokenType = xmlTextReaderNodeType(reader); ++ switch (tokenId) ++ { ++ case XML_DC_TITLE: ++ if (tokenType == XML_READER_TYPE_ELEMENT) ++ readTitle(reader); ++ break; ++ default: ++ break; ++ } ++ } ++ while ((XML_CP_COREPROPERTIES != tokenId || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret); ++} ++ ++bool libvisio::VSDXMetaData::parse(librevenge::RVNGInputStream *input) ++{ ++ if (!input) ++ return false; ++ ++ xmlTextReaderPtr reader = xmlReaderForStream(input, 0, 0, XML_PARSE_NOBLANKS|XML_PARSE_NOENT|XML_PARSE_NONET); ++ if (!reader) ++ return false; ++ ++ try ++ { ++ int ret = xmlTextReaderRead(reader); ++ while (1 == ret) ++ { ++ int tokenId = getElementToken(reader); ++ switch (tokenId) ++ { ++ case XML_CP_COREPROPERTIES: ++ readCoreProperties(reader); ++ break; ++ default: ++ break; ++ ++ } ++ ret = xmlTextReaderRead(reader); ++ } ++ } ++ catch (...) ++ { ++ xmlFreeTextReader(reader); ++ return false; ++ } ++ xmlFreeTextReader(reader); ++ return true; ++} ++ ++int libvisio::VSDXMetaData::getElementToken(xmlTextReaderPtr reader) ++{ ++ return VSDXMLTokenMap::getTokenId(xmlTextReaderConstName(reader)); ++} ++ ++const librevenge::RVNGPropertyList &libvisio::VSDXMetaData::getMetaData() ++{ ++ return m_metaData; ++} ++ ++/* vim:set shiftwidth=2 softtabstop=2 expandtab: */ +diff --git a/src/lib/VSDXMetaData.h b/src/lib/VSDXMetaData.h +new file mode 100644 +index 0000000..15d22c1 +--- /dev/null ++++ b/src/lib/VSDXMetaData.h +@@ -0,0 +1,41 @@ ++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ ++/* ++ * This file is part of the libvisio project. ++ * ++ * This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ */ ++ ++#ifndef __VSDXMETADATA_H__ ++#define __VSDXMETADATA_H__ ++ ++#include <librevenge-stream/librevenge-stream.h> ++#include "VSDXMLHelper.h" ++ ++namespace libvisio ++{ ++ ++class VSDXMetaData ++{ ++public: ++ VSDXMetaData(); ++ ~VSDXMetaData(); ++ bool parse(librevenge::RVNGInputStream *input); ++ const librevenge::RVNGPropertyList &getMetaData(); ++ ++private: ++ VSDXMetaData(const VSDXMetaData &); ++ VSDXMetaData &operator=(const VSDXMetaData &); ++ ++ int getElementToken(xmlTextReaderPtr reader); ++ void readCoreProperties(xmlTextReaderPtr reader); ++ void readTitle(xmlTextReaderPtr reader); ++ ++ librevenge::RVNGPropertyList m_metaData; ++}; ++ ++} // namespace libvisio ++ ++#endif // __VSDXMETADATA_H__ ++/* vim:set shiftwidth=2 softtabstop=2 expandtab: */ +diff --git a/src/lib/VSDXParser.cpp b/src/lib/VSDXParser.cpp +index 21e2d2c..4f676b0 100644 +--- a/src/lib/VSDXParser.cpp ++++ b/src/lib/VSDXParser.cpp +@@ -18,6 +18,7 @@ + #include "VSDStylesCollector.h" + #include "VSDXMLHelper.h" + #include "VSDXMLTokenMap.h" ++#include "VSDXMetaData.h" + + namespace + { +@@ -92,6 +93,10 @@ bool libvisio::VSDXParser::parseMain() + + VSDContentCollector contentCollector(m_painter, groupXFormsSequence, groupMembershipsSequence, documentPageShapeOrders, styles, m_stencils); + m_collector = &contentCollector; ++ const libvisio::VSDXRelationship *metaDataRel = rootRels.getRelationshipByType("http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties"); ++ if (metaDataRel) ++ parseMetaData(m_input, metaDataRel->getTarget().c_str()); ++ + if (!parseDocument(m_input, rel->getTarget().c_str())) + return false; + +@@ -275,6 +280,25 @@ bool libvisio::VSDXParser::parseTheme(librevenge::RVNGInputStream *input, const + return true; + } + ++bool libvisio::VSDXParser::parseMetaData(librevenge::RVNGInputStream *input, const char *name) ++{ ++ if (!input) ++ return false; ++ input->seek(0, librevenge::RVNG_SEEK_SET); ++ if (!input->isStructured()) ++ return false; ++ librevenge::RVNGInputStream *stream = input->getSubStreamByName(name); ++ if (!stream) ++ return false; ++ ++ VSDXMetaData metaData; ++ metaData.parse(stream); ++ m_collector->collectMetaData(metaData.getMetaData()); ++ ++ delete stream; ++ return true; ++} ++ + void libvisio::VSDXParser::processXmlDocument(librevenge::RVNGInputStream *input, VSDXRelationships &rels) + { + if (!input) +diff --git a/src/lib/VSDXParser.h b/src/lib/VSDXParser.h +index 75119bc..8566403 100644 +--- a/src/lib/VSDXParser.h ++++ b/src/lib/VSDXParser.h +@@ -54,6 +54,7 @@ private: + bool parsePages(librevenge::RVNGInputStream *input, const char *name); + bool parsePage(librevenge::RVNGInputStream *input, const char *name); + bool parseTheme(librevenge::RVNGInputStream *input, const char *name); ++ bool parseMetaData(librevenge::RVNGInputStream *input, const char *name); + void processXmlDocument(librevenge::RVNGInputStream *input, VSDXRelationships &rels); + void processXmlNode(xmlTextReaderPtr reader); + +diff --git a/src/lib/tokens.txt b/src/lib/tokens.txt +index 4421b59..0392862 100644 +--- a/src/lib/tokens.txt ++++ b/src/lib/tokens.txt +@@ -221,3 +221,5 @@ Width + X + XForm + Y ++cp:coreProperties ++dc:title + +commit caf5129b16458493d7b67baf922b92fcc40ee1d0 +Author: Miklos Vajna <vmiklos@collabora.co.uk> +Date: Tue Nov 25 12:08:53 2014 +0100 + + fdo#86664 VSDX: import <dcterms:created> and <dcterms:modified> + + Change-Id: I7ff5f87729419853146d941903f88f9277106b27 + +diff --git a/src/lib/VSDXMetaData.cpp b/src/lib/VSDXMetaData.cpp +index 3cbd61d..19c9709 100644 +--- a/src/lib/VSDXMetaData.cpp ++++ b/src/lib/VSDXMetaData.cpp +@@ -37,6 +37,42 @@ void libvisio::VSDXMetaData::readTitle(xmlTextReaderPtr reader) + m_metaData.insert("dc:title", title); + } + ++void libvisio::VSDXMetaData::readCreated(xmlTextReaderPtr reader) ++{ ++ int ret = 1; ++ int tokenId = XML_TOKEN_INVALID; ++ int tokenType = -1; ++ librevenge::RVNGString created; ++ do ++ { ++ ret = xmlTextReaderRead(reader); ++ tokenId = getElementToken(reader); ++ tokenType = xmlTextReaderNodeType(reader); ++ if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT) ++ created.append((const char *)xmlTextReaderConstValue(reader)); ++ } ++ while ((XML_DCTERMS_CREATED != tokenId || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret); ++ m_metaData.insert("meta:creation-date", created); ++} ++ ++void libvisio::VSDXMetaData::readModified(xmlTextReaderPtr reader) ++{ ++ int ret = 1; ++ int tokenId = XML_TOKEN_INVALID; ++ int tokenType = -1; ++ librevenge::RVNGString modified; ++ do ++ { ++ ret = xmlTextReaderRead(reader); ++ tokenId = getElementToken(reader); ++ tokenType = xmlTextReaderNodeType(reader); ++ if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT) ++ modified.append((const char *)xmlTextReaderConstValue(reader)); ++ } ++ while ((XML_DCTERMS_MODIFIED != tokenId || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret); ++ m_metaData.insert("dc:date", modified); ++} ++ + void libvisio::VSDXMetaData::readCoreProperties(xmlTextReaderPtr reader) + { + int ret = 1; +@@ -57,6 +93,14 @@ void libvisio::VSDXMetaData::readCoreProperties(xmlTextReaderPtr reader) + if (tokenType == XML_READER_TYPE_ELEMENT) + readTitle(reader); + break; ++ case XML_DCTERMS_CREATED: ++ if (tokenType == XML_READER_TYPE_ELEMENT) ++ readCreated(reader); ++ break; ++ case XML_DCTERMS_MODIFIED: ++ if (tokenType == XML_READER_TYPE_ELEMENT) ++ readModified(reader); ++ break; + default: + break; + } +diff --git a/src/lib/VSDXMetaData.h b/src/lib/VSDXMetaData.h +index 15d22c1..5ef98b8 100644 +--- a/src/lib/VSDXMetaData.h ++++ b/src/lib/VSDXMetaData.h +@@ -31,6 +31,8 @@ private: + int getElementToken(xmlTextReaderPtr reader); + void readCoreProperties(xmlTextReaderPtr reader); + void readTitle(xmlTextReaderPtr reader); ++ void readCreated(xmlTextReaderPtr reader); ++ void readModified(xmlTextReaderPtr reader); + + librevenge::RVNGPropertyList m_metaData; + }; +diff --git a/src/lib/tokens.txt b/src/lib/tokens.txt +index 0392862..d832604 100644 +--- a/src/lib/tokens.txt ++++ b/src/lib/tokens.txt +@@ -223,3 +223,5 @@ XForm + Y + cp:coreProperties + dc:title ++dcterms:created ++dcterms:modified |