diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2014-11-25 09:49:05 +0100 |
---|---|---|
committer | Fridrich Strba <fridrich@documentfoundation.org> | 2014-11-25 08:58:58 +0000 |
commit | 2060d364bc0f7df97b864bf01fc5a27da12061c3 (patch) | |
tree | 2dd10c332938eee4313ec89bf36590f20dae81ac | |
parent | 6033e13300a7beff58a953241c0da6d760082827 (diff) |
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>
-rw-r--r-- | src/lib/Makefile.am | 3 | ||||
-rw-r--r-- | src/lib/VSDCollector.h | 3 | ||||
-rw-r--r-- | src/lib/VSDContentCollector.cpp | 5 | ||||
-rw-r--r-- | src/lib/VSDContentCollector.h | 2 | ||||
-rw-r--r-- | src/lib/VSDPages.cpp | 6 | ||||
-rw-r--r-- | src/lib/VSDPages.h | 2 | ||||
-rw-r--r-- | src/lib/VSDStylesCollector.h | 2 | ||||
-rw-r--r-- | src/lib/VSDXMetaData.cpp | 113 | ||||
-rw-r--r-- | src/lib/VSDXMetaData.h | 41 | ||||
-rw-r--r-- | src/lib/VSDXParser.cpp | 24 | ||||
-rw-r--r-- | src/lib/VSDXParser.h | 1 | ||||
-rw-r--r-- | src/lib/tokens.txt | 2 |
12 files changed, 204 insertions, 0 deletions
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 618f83a..e2daff8 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 87a5042..e617244 100644 --- a/src/lib/VSDContentCollector.cpp +++ b/src/lib/VSDContentCollector.cpp @@ -2732,6 +2732,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 1160ff0..9fe333a 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 3af92bd..544bab4 100644 --- a/src/lib/tokens.txt +++ b/src/lib/tokens.txt @@ -226,3 +226,5 @@ X XForm XForm1D Y +cp:coreProperties +dc:title |