[Libreoffice-commits] libvisio.git: src/lib

Miklos Vajna vmiklos at collabora.co.uk
Tue Nov 25 00:59:20 PST 2014


 src/lib/Makefile.am             |    3 +
 src/lib/VSDCollector.h          |    3 +
 src/lib/VSDContentCollector.cpp |    5 +
 src/lib/VSDContentCollector.h   |    2 
 src/lib/VSDPages.cpp            |    6 ++
 src/lib/VSDPages.h              |    2 
 src/lib/VSDStylesCollector.h    |    2 
 src/lib/VSDXMetaData.cpp        |  113 ++++++++++++++++++++++++++++++++++++++++
 src/lib/VSDXMetaData.h          |   41 ++++++++++++++
 src/lib/VSDXParser.cpp          |   24 ++++++++
 src/lib/VSDXParser.h            |    1 
 src/lib/tokens.txt              |    2 
 12 files changed, 204 insertions(+)

New commits:
commit 2060d364bc0f7df97b864bf01fc5a27da12061c3
Author: Miklos Vajna <vmiklos at 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 at documentfoundation.org>
    Tested-by: Fridrich Strba <fridrich at documentfoundation.org>

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_ at VSD_MAJOR_VERSION@_ at 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


More information about the Libreoffice-commits mailing list