src/lib/VSDDocumentStructure.h             |    4 
 src/lib/VSDFieldList.cpp                   |  169 ++++++++++++++++++++++++-----
 src/test/data/tdf76829-datetime-format.vsd |binary
 src/test/data/tdf76829-numeric-format.vsd  |binary
 src/test/importtest.cpp                    |   20 ++-
 5 files changed, 160 insertions(+), 33 deletions(-)

New commits:
commit d410b9bd6c763ec0037031b6b5913f754264beca
Author:     Bartosz Kosiorek <gan...@poczta.onet.pl>
AuthorDate: Wed Jun 26 16:19:18 2019 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Jul 3 16:40:21 2019 +0200

    tdf#76829 tdf#98291 Visio: Fix date and time conversion to string
    
    The documentation which implementation was based on was
    taken from:
    
https://docs.microsoft.com/en-us/openspecs/sharepoint_protocols/ms-vsdx/50c23601-c943-4ff2-b4a1-02445f52daf0
    
    Change-Id: I8a3544d198d0376bdc31b158c073f5340dff7237
    Reviewed-on: https://gerrit.libreoffice.org/74743
    Tested-by: Miklos Vajna <vmik...@collabora.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/src/lib/VSDDocumentStructure.h b/src/lib/VSDDocumentStructure.h
index 1f022b7..4fd8b61 100644
--- a/src/lib/VSDDocumentStructure.h
+++ b/src/lib/VSDDocumentStructure.h
@@ -152,8 +152,8 @@
 #define VSD_FIELD_FORMAT_DateLong  21
 #define VSD_FIELD_FORMAT_DateMDYY  22
 #define VSD_FIELD_FORMAT_DateMMDDYY  23
-#define VSD_FIELD_FORMAT_DateMmmDYYYY  24
-#define VSD_FIELD_FORMAT_DateMmmmDYYYY  25
+#define VSD_FIELD_FORMAT_DateMMMDYYYY  24
+#define VSD_FIELD_FORMAT_DateMMMMDYYYY  25
 #define VSD_FIELD_FORMAT_DateDMYY  26
 #define VSD_FIELD_FORMAT_DateDDMMYY  27
 #define VSD_FIELD_FORMAT_DateDMMMYYYY  28
diff --git a/src/lib/VSDFieldList.cpp b/src/lib/VSDFieldList.cpp
index c4c16ef..05482d0 100644
--- a/src/lib/VSDFieldList.cpp
+++ b/src/lib/VSDFieldList.cpp
@@ -10,6 +10,7 @@
 #include "VSDFieldList.h"
 
 #include <time.h>
+#include <cmath>
 #include "VSDCollector.h"
 #include "libvisio_utils.h"
 
@@ -25,6 +26,9 @@ libvisio::VSDFieldListElement *libvisio::VSDTextField::clone()
 
 librevenge::RVNGString libvisio::VSDTextField::getString(const 
std::map<unsigned, librevenge::RVNGString> &strVec)
 {
+  //TODO VSD_FIELD_FORMAT_StrNormal  37
+  //TODO VSD_FIELD_FORMAT_StrLower  38
+  //TODO VSD_FIELD_FORMAT_StrUpper  39
   auto iter = strVec.find(m_nameId);
   if (iter != strVec.end())
     return iter->second;
@@ -66,18 +70,111 @@ librevenge::RVNGString 
libvisio::VSDNumericField::datetimeToString(const char *f
 
 librevenge::RVNGString libvisio::VSDNumericField::getString(const 
std::map<unsigned, librevenge::RVNGString> &)
 {
-  if (m_format == 0xffff)
+  if (m_format == VSD_FIELD_FORMAT_Unknown)
     return librevenge::RVNGString();
   switch (m_format)
   {
+  case VSD_FIELD_FORMAT_NumGenNoUnits:
+  case VSD_FIELD_FORMAT_NumGenDefUnits:
+  {
+    // 0 Format string: 0.#### Example: 30060.9167
+    // 1 Format string: 0.#### u Example: 30060.9167 cm
+    //TODO We need to implement number of digits support after decimal 
separator in librevenge
+    double intpart;
+    // If there is no decimal value, then treat number as Integer
+    if (std::modf(m_number, &intpart) == 0.0)
+    {
+      std::unique_ptr<librevenge::RVNGProperty> 
pProp{librevenge::RVNGPropertyFactory::newIntProp(m_number)};
+      return pProp ? pProp->getStr() : librevenge::RVNGString();
+    }
+    std::unique_ptr<librevenge::RVNGProperty> 
pProp{librevenge::RVNGPropertyFactory::newDoubleProp(m_number)};
+    return pProp ? pProp->getStr() : librevenge::RVNGString();
+  }
+  case VSD_FIELD_FORMAT_0PlNoUnits:
+  case VSD_FIELD_FORMAT_0PlDefUnits:
+  {
+    // 2 Format string: 0 Example: 30061
+    // 3 Format string: 0 u Example: 30061 cm
+    std::unique_ptr<librevenge::RVNGProperty> 
pProp{librevenge::RVNGPropertyFactory::newIntProp(m_number)};
+    return pProp ? pProp->getStr() : librevenge::RVNGString();
+  }
+  //TODO VSD_FIELD_FORMAT_1PlNoUnits  4 Format string: 0.0
+  //TODO VSD_FIELD_FORMAT_1PlDefUnits  5 Format string: 0.0 u
+  //TODO VSD_FIELD_FORMAT_2PlNoUnits  6 Format string: 0.00
+  //TODO VSD_FIELD_FORMAT_2PlDefUnits  7 Format string: 0.00 u
+  //TODO VSD_FIELD_FORMAT_3PlNoUnits  8 Format string: 0.000
+  //TODO VSD_FIELD_FORMAT_3PlDefUnits  9 Format string: 0.000 u
+  //TODO VSD_FIELD_FORMAT_FeetAndInches  10 Format string: <,FEET/INCH>0.000 u
+  //TODO VSD_FIELD_FORMAT_Radians  11 Format string: <,rad>0.#### u
+  //TODO VSD_FIELD_FORMAT_Degrees  12 Format string: <,deg>0.# u
+  //TODO VSD_FIELD_FORMAT_FeetAndInches1Pl  13 Format string: <,FEET/INCH># 
#/# u
+  //TODO VSD_FIELD_FORMAT_FeetAndInches2Pl  14 Format string: <,FEET/INCH># 
#/## u
+  //TODO VSD_FIELD_FORMAT_Fraction1PlNoUnits  15 Format string: 0 #/#
+  //TODO VSD_FIELD_FORMAT_Fraction1PlDefUnits  16 Format string: 0 #/# u
+  //TODO VSD_FIELD_FORMAT_Fraction2PlNoUnits  17 Format string: 0 #/##
+  //TODO VSD_FIELD_FORMAT_Fraction2PlDefUnits  18 Format string: 0 #/## u
+  case VSD_FIELD_FORMAT_DateShort:
+    // 20 Format string: ddddd Example: Thu
+    return datetimeToString("%a", m_number);
+  case VSD_FIELD_FORMAT_DateLong:
+    // 21 Format string: dddddd Example: Thursday
+    return datetimeToString("%A", m_number);
   case VSD_FIELD_FORMAT_DateMDYY:
   case VSD_FIELD_FORMAT_DateMMDDYY:
-  case VSD_FIELD_FORMAT_DateMmmDYYYY:
-  case VSD_FIELD_FORMAT_DateMmmmDYYYY:
+    // 22 Format string: M/d/y Example: 4/19/82
+    // 23 Format string: MM/d/y Example: 4/19/82
+    return datetimeToString("%m/%d/%y", m_number);
+  case VSD_FIELD_FORMAT_DateMMMDYYYY:
+    // 24 Format string: MMM d, yyyy Example: Apr 19, 1982
+    return datetimeToString("%b %e, %Y", m_number);
+  case VSD_FIELD_FORMAT_DateMMMMDYYYY:
+    // 25 Format string: MMMM d, yyyy Example: April 19, 1982
+    return datetimeToString("%B %e, %Y", m_number);
   case VSD_FIELD_FORMAT_DateDMYY:
+    // 26 Format string: d/M/YY Example: 19/04/82
+    return datetimeToString("%e/%m/%y", m_number);
   case VSD_FIELD_FORMAT_DateDDMMYY:
+    // 27 Format string: dd/MM/YY Example: 19/04/82
+    return datetimeToString("%d/%m/%y", m_number);
   case VSD_FIELD_FORMAT_DateDMMMYYYY:
+    // 28 Format string: d MMM, yyyy Example: 19 Apr, 1982
+    return datetimeToString("%e %b, %Y", m_number);
   case VSD_FIELD_FORMAT_DateDMMMMYYYY:
+    // 29 Format string: d MMMM, yyyy Example: 19 April, 1982
+    return datetimeToString("%e %B, %Y", m_number);
+  case VSD_FIELD_FORMAT_TimeGen:
+    // The value is formatted using a format string "h:mm:ss tt" and inserted 
to the result string.
+    // For example, FORMAT(DATETIME("6/25/07 12:05"), "T") displays 12:05:00 
PM.
+    // 30 Format string: T Example: 10:02:02 PM
+    return datetimeToString("%r", m_number);
+  case VSD_FIELD_FORMAT_TimeHMM:
+  case VSD_FIELD_FORMAT_TimeHHMM:
+  case VSD_FIELD_FORMAT_TimeHMM24:
+  case VSD_FIELD_FORMAT_TimeHHMM24:
+    // 31 Format string: h:mm Example: 10:02
+    // 32 Format string: hh:mm Example: 10:02
+    // 33 Format string: H:mm Example: 10:02
+    // 34 Format string: HH:mm Example: 10:02
+    return datetimeToString("%H:%m:%S", m_number);
+  case VSD_FIELD_FORMAT_TimeHMMAMPM:
+  case VSD_FIELD_FORMAT_TimeHHMMAMPM:
+    // 35 Format string: h:mm tt Example: 10:02 PM
+    // 36 Format string: HH:mm tt Example: 10:02 PM
+    return datetimeToString("%I:%m %p", m_number);
+  case VSD_FIELD_FORMAT_TimeAMPMhmm_J:
+  case VSD_FIELD_FORMAT_TimeAMPMhmm_C:
+  case VSD_FIELD_FORMAT_TimeAMPMhmm_K:
+  case VSD_FIELD_FORMAT_TimeAMPM_hmm_J:
+  case VSD_FIELD_FORMAT_Timehmm_J:
+  case VSD_FIELD_FORMAT_TimeAMPM_hmm_C:
+  case VSD_FIELD_FORMAT_Timehmm_C:
+  case VSD_FIELD_FORMAT_TimeAMPM_hmm_K:
+  case VSD_FIELD_FORMAT_Timehmm_K:
+  case VSD_FIELD_FORMAT_TimeHMMAMPM_E:
+  case VSD_FIELD_FORMAT_TimeHHMMAMPM_E:
+  case VSD_FIELD_FORMAT_TimeAMPMhmm_S:
+  case VSD_FIELD_FORMAT_TimeAMPMhhmm_S:
+    return datetimeToString("%X", m_number);
   case VSD_FIELD_FORMAT_Dateyyyymd:
   case VSD_FIELD_FORMAT_Dateyymmdd:
   case VSD_FIELD_FORMAT_DateTWNfYYYYMMDDD_C:
@@ -101,45 +198,61 @@ librevenge::RVNGString 
libvisio::VSDNumericField::getString(const std::map<unsig
   case VSD_FIELD_FORMAT_Datewwyyyymmdd_S:
   case VSD_FIELD_FORMAT_Datewwyyyymd_S:
   case VSD_FIELD_FORMAT_MsoDateShort:
+  case VSD_FIELD_FORMAT_MsoFEExtra1:
+  case VSD_FIELD_FORMAT_MsoFEExtra2:
+  case VSD_FIELD_FORMAT_MsoFEExtra3:
+  case VSD_FIELD_FORMAT_MsoFEExtra4:
+  case VSD_FIELD_FORMAT_MsoFEExtra5:
+    // 40-81, 200, 217-221 Format string: M/d/yyyy Example: 4/19/1982
+    return datetimeToString("%m/%d/%Y", m_number);
   case VSD_FIELD_FORMAT_MsoDateLongDay:
+    // 201 Format string: dddd, MMMM dd, yyyy Example: Monday, April 19, 1982
+    return datetimeToString("%A, %B %d, %Y", m_number);
   case VSD_FIELD_FORMAT_MsoDateLong:
+    // 202 Format string: MMMM d, yyyy Example: April 19, 1982
+    return datetimeToString("%B %e, %Y", m_number);
   case VSD_FIELD_FORMAT_MsoDateShortAlt:
+    // 203 Format string: M/d/yy Example: 4/19/82
+    return datetimeToString("%m/%d/%y", m_number);
   case VSD_FIELD_FORMAT_MsoDateISO:
+    // 204 Format string: yyyy-MM-dd Example: 1982-04-19
+    return datetimeToString("%Y-%m-%d", m_number);
   case VSD_FIELD_FORMAT_MsoDateShortMon:
+    // 205 Format string: d-MMM-yy Example: 19-Apr-1982
+    return datetimeToString("%e-%b-%y", m_number);
   case VSD_FIELD_FORMAT_MsoDateShortSlash:
+    // 206 Format string: M.d.yyyy Example: 4.19.1982
+    return datetimeToString("%m.%d.%Y", m_number);
   case VSD_FIELD_FORMAT_MsoDateShortAbb:
+    // 207 Format string: MMM.d, yy Example: Apr.19, 82
+    return datetimeToString("%b.%d, %y", m_number);
   case VSD_FIELD_FORMAT_MsoDateEnglish:
+    // 208 Format string: D MMMM yyyy Example: 19 April 1982
+    return datetimeToString("%e %B %Y", m_number);
   case VSD_FIELD_FORMAT_MsoDateMonthYr:
+    // 209 Format string: MMMM yy Example: April 82
+    return datetimeToString("%B %y", m_number);
   case VSD_FIELD_FORMAT_MsoDateMon_Yr:
-    return datetimeToString("%x", m_number);
-  case VSD_FIELD_FORMAT_TimeGen:
-  case VSD_FIELD_FORMAT_TimeHMM:
-  case VSD_FIELD_FORMAT_TimeHHMM:
-  case VSD_FIELD_FORMAT_TimeHMM24:
-  case VSD_FIELD_FORMAT_TimeHHMM24:
-  case VSD_FIELD_FORMAT_TimeHMMAMPM:
-  case VSD_FIELD_FORMAT_TimeHHMMAMPM:
-  case VSD_FIELD_FORMAT_TimeAMPMhmm_J:
-  case VSD_FIELD_FORMAT_TimeAMPMhmm_C:
-  case VSD_FIELD_FORMAT_TimeAMPMhmm_K:
-  case VSD_FIELD_FORMAT_TimeAMPM_hmm_J:
-  case VSD_FIELD_FORMAT_Timehmm_J:
-  case VSD_FIELD_FORMAT_TimeAMPM_hmm_C:
-  case VSD_FIELD_FORMAT_Timehmm_C:
-  case VSD_FIELD_FORMAT_TimeAMPM_hmm_K:
-  case VSD_FIELD_FORMAT_Timehmm_K:
-  case VSD_FIELD_FORMAT_TimeHMMAMPM_E:
-  case VSD_FIELD_FORMAT_TimeHHMMAMPM_E:
-  case VSD_FIELD_FORMAT_TimeAMPMhmm_S:
-  case VSD_FIELD_FORMAT_TimeAMPMhhmm_S:
+    // 210 Format string: MMM-yy Example: Apr-82
+    return datetimeToString("%b-%y", m_number);
+  case VSD_FIELD_FORMAT_MsoTimeDatePM:
+    // 211 Format string: M/d/yyyy h:mm am/pm Example: 4/19/1982 10:02 PM
+    return datetimeToString("%m/%d/%Y %I:%m %p", m_number);
+  case VSD_FIELD_FORMAT_MsoTimeDateSecPM:
+    // 212 Format string: M/d/yyyy h:mm:ss am/pm Example: 4/19/1982 10:02:02 PM
+    return datetimeToString("%m/%d/%Y %I:%m:%S %p", m_number);
   case VSD_FIELD_FORMAT_MsoTimePM:
+    // 213 Format string: H:mm am/pm Example: 10:02 PM
+    return datetimeToString("%I:%m %p", m_number);
   case VSD_FIELD_FORMAT_MsoTimeSecPM:
+    // 214 Format string: h:mm:ss am/pm Example: 10:02:02 PM
+    return datetimeToString("%I:%m:%S %p", m_number);
   case VSD_FIELD_FORMAT_MsoTime24:
+    // 215 Format string: HH:mm Example: 10:02
+    return datetimeToString("%H:%m", m_number);
   case VSD_FIELD_FORMAT_MsoTimeSec24:
-    return datetimeToString("%X", m_number);
-  case VSD_FIELD_FORMAT_MsoTimeDatePM:
-  case VSD_FIELD_FORMAT_MsoTimeDateSecPM:
-    return datetimeToString("%x %X", m_number);
+    // 216 Format string: HH:mm:ss Example: 10:02:01
+    return datetimeToString("%H:%m:%S", m_number);
   default:
   {
     std::unique_ptr<librevenge::RVNGProperty> 
pProp{librevenge::RVNGPropertyFactory::newDoubleProp(m_number)};
diff --git a/src/test/data/tdf76829-datetime-format.vsd 
b/src/test/data/tdf76829-datetime-format.vsd
new file mode 100644
index 0000000..c9237fe
Binary files /dev/null and b/src/test/data/tdf76829-datetime-format.vsd differ
diff --git a/src/test/data/tdf76829-numeric-format.vsd 
b/src/test/data/tdf76829-numeric-format.vsd
new file mode 100644
index 0000000..a1c24cc
Binary files /dev/null and b/src/test/data/tdf76829-numeric-format.vsd differ
diff --git a/src/test/importtest.cpp b/src/test/importtest.cpp
index 418551f..13b665f 100644
--- a/src/test/importtest.cpp
+++ b/src/test/importtest.cpp
@@ -110,7 +110,6 @@ void assertBmpDataOffset(xmlDocPtr doc, const 
librevenge::RVNGString &xpath, con
   CPPUNIT_ASSERT_EQUAL_MESSAGE(message.cstr(), expectedValue, actualValue);
 }
 
-#if 0 // keep for future use
 /// Same as the assertXPathContent(), but don't assert: return the string 
instead.
 librevenge::RVNGString getXPathContent(xmlDocPtr doc, const 
librevenge::RVNGString &xpath)
 {
@@ -127,7 +126,6 @@ librevenge::RVNGString getXPathContent(xmlDocPtr doc, const 
librevenge::RVNGStri
   xmlXPathFreeObject(xpathObject);
   return s;
 }
-
 /// Assert that xpath exists, and its content equals to content.
 void assertXPathContent(xmlDocPtr doc, const librevenge::RVNGString &xpath, 
const librevenge::RVNGString &content)
 {
@@ -136,7 +134,6 @@ void assertXPathContent(xmlDocPtr doc, const 
librevenge::RVNGString &xpath, cons
   message.append("': contents of child does not match.");
   CPPUNIT_ASSERT_EQUAL_MESSAGE(message.cstr(), content, getXPathContent(doc, 
xpath));
 }
-#endif
 
 /// Paints an XML representation of filename into buffer, then returns the 
parsed buffer content.
 xmlDocPtr parse(const char *filename, xmlBufferPtr buffer)
@@ -179,6 +176,8 @@ class ImportTest : public CPPUNIT_NS::TestFixture
   CPPUNIT_TEST(testVsdxCharBgColor);
 #endif
   CPPUNIT_TEST(testVsdTextBlockWithoutBgColor);
+  CPPUNIT_TEST(testVsdNumericFormat);
+  CPPUNIT_TEST(testVsdDateTimeFormatting);
   CPPUNIT_TEST(testBmpFileHeader);
   CPPUNIT_TEST(testBmpFileHeader2);
   CPPUNIT_TEST_SUITE_END();
@@ -191,6 +190,8 @@ class ImportTest : public CPPUNIT_NS::TestFixture
   void testVsdxImportBgColorFromTheme();
   void testVsdxCharBgColor();
   void testVsdTextBlockWithoutBgColor();
+  void testVsdNumericFormat();
+  void testVsdDateTimeFormatting();
   void testBmpFileHeader();
   void testBmpFileHeader2();
 
@@ -313,6 +314,19 @@ void ImportTest::testVsdTextBlockWithoutBgColor()
   assertXPathNoAttribute(m_doc, 
"/document/page/layer[5]/textObject/paragraph[1]/span", "background-color");
 }
 
+void ImportTest::testVsdNumericFormat()
+{
+  m_doc = parse("tdf76829-numeric-format.vsd", m_buffer);
+  assertXPathContent(m_doc, 
"/document/page[1]/textObject[1]/paragraph[1]/span/insertText", "Zeichenblatt 1 
");
+  assertXPathContent(m_doc, 
"/document/page[2]/textObject[1]/paragraph[1]/span/insertText", "Zeichenblatt 2 
");
+}
+
+void ImportTest::testVsdDateTimeFormatting()
+{
+  m_doc = parse("tdf76829-datetime-format.vsd", m_buffer);
+  assertXPathContent(m_doc, 
"/document/page/textObject/paragraph/span/insertText", "11/30/2005");
+}
+
 void ImportTest::testBmpFileHeader()
 {
   m_doc = parse("bitmaps.vsd", m_buffer);
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to