[Libreoffice-commits] core.git: external/libodfgen external/libvisio

Miklos Vajna vmiklos at collabora.co.uk
Tue Nov 25 03:56:05 PST 2014


 external/libodfgen/UnpackedTarball_libodfgen.mk |    4 
 external/libodfgen/metadata.patch               |   33 +
 external/libvisio/UnpackedTarball_libvisio.mk   |    1 
 external/libvisio/vsdx-metadata.patch.1         |  462 ++++++++++++++++++++++++
 4 files changed, 500 insertions(+)

New commits:
commit 411bd6e440266a0db95907ad73a3a5be92bd1827
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Nov 25 12:27:25 2014 +0100

    fdo#86664 VSDX import: handle metadata
    
    Change-Id: I04a446e6b8a8352be9f091980bca31842bb7e643

diff --git a/external/libodfgen/UnpackedTarball_libodfgen.mk b/external/libodfgen/UnpackedTarball_libodfgen.mk
index bb2153f..edf41b6 100644
--- a/external/libodfgen/UnpackedTarball_libodfgen.mk
+++ b/external/libodfgen/UnpackedTarball_libodfgen.mk
@@ -13,4 +13,8 @@ $(eval $(call gb_UnpackedTarball_set_tarball,libodfgen,$(ODFGEN_TARBALL)))
 
 $(eval $(call gb_UnpackedTarball_set_patchlevel,libodfgen,0))
 
+$(eval $(call gb_UnpackedTarball_add_patches,libodfgen, \
+    external/libodfgen/metadata.patch \
+))
+
 # vim: set noet sw=4 ts=4:
diff --git a/external/libodfgen/metadata.patch b/external/libodfgen/metadata.patch
new file mode 100644
index 0000000..1b904ed
--- /dev/null
+++ b/external/libodfgen/metadata.patch
@@ -0,0 +1,33 @@
+commit fb43d79e12ce132fc127cc0481ff5a6bdbcd1afe
+Author: Miklos Vajna <vmiklos at collabora.co.uk>
+Date:   Tue Nov 25 11:26:34 2014 +0100
+
+    Od[gp]Generator: declare meta namespace
+    
+    Other generators had it already, and without this, it's not possible to
+    declare creation date.
+
+diff --git src/OdgGenerator.cxx src/OdgGenerator.cxx
+index 6a2b1a4..ca4d4f0 100644
+--- src/OdgGenerator.cxx
++++ src/OdgGenerator.cxx
+@@ -283,6 +283,7 @@ bool OdgGeneratorPrivate::writeTargetDocument(OdfDocumentHandler *pHandler, OdfS
+ 	docContentPropList.addAttribute("xmlns:draw", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0");
+ 	docContentPropList.addAttribute("xmlns:table", "urn:oasis:names:tc:opendocument:xmlns:table:1.0");
+ 	docContentPropList.addAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink");
++	docContentPropList.addAttribute("xmlns:meta", "urn:oasis:names:tc:opendocument:xmlns:meta:1.0");
+ 	docContentPropList.addAttribute("xmlns:dc", "http://purl.org/dc/elements/1.1/");
+ 	docContentPropList.addAttribute("xmlns:svg", "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0");
+ 	docContentPropList.addAttribute("xmlns:fo", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0");
+diff --git a/src/OdpGenerator.cxx b/src/OdpGenerator.cxx
+index 4345c40..8ba4dc0 100644
+--- src/OdpGenerator.cxx
++++ src/OdpGenerator.cxx
+@@ -444,6 +444,7 @@ bool OdpGeneratorPrivate::writeTargetDocument(OdfDocumentHandler *pHandler, OdfS
+ 	docContentPropList.addAttribute("xmlns:fo", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0");
+ 	docContentPropList.addAttribute("xmlns:config", "urn:oasis:names:tc:opendocument:xmlns:config:1.0");
+ 	docContentPropList.addAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink");
++	docContentPropList.addAttribute("xmlns:meta", "urn:oasis:names:tc:opendocument:xmlns:meta:1.0");
+ 	// WARNING: this is not ODF!
+ 	docContentPropList.addAttribute("xmlns:ooo", "http://openoffice.org/2004/office");
+ 	docContentPropList.addAttribute("xmlns:officeooo", "http://openoffice.org/2009/office");
diff --git a/external/libvisio/UnpackedTarball_libvisio.mk b/external/libvisio/UnpackedTarball_libvisio.mk
index 1626dbb..4451eb5 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 0000000..58a0a7d
--- /dev/null
+++ b/external/libvisio/vsdx-metadata.patch.1
@@ -0,0 +1,462 @@
+commit 1b1fd1b07728590c94694b4e8b1b00058ca02d52
+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 6080d31..955aac4 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 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 at 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


More information about the Libreoffice-commits mailing list