Branch 'libkolab-0.4' - 14 commits - CMakeLists.txt cmake/modules conversion/CMakeLists.txt conversion/commonconversion.cpp conversion/timezoneconverter.cpp conversion/timezoneconverter.h freebusy/freebusy.cpp icalendar/icalendar.cpp kolabformat/kolabobject.cpp kolabformat/xmlobject.cpp tests/CMakeLists.txt tests/formattest.cpp tests/formattest.h tests/testfiles tests/timezonetest.cpp tests/timezonetest.h

Christian Mollekopf mollekopf at kolabsys.com
Wed Jan 9 14:01:48 CET 2013


 CMakeLists.txt                                |    8 -
 cmake/modules/COPYING-CMAKE-SCRIPTS           |   22 +++
 conversion/CMakeLists.txt                     |    5 
 conversion/commonconversion.cpp               |   10 +
 conversion/timezoneconverter.cpp              |  184 ++++++++++++++++++++++++++
 conversion/timezoneconverter.h                |   33 ++++
 freebusy/freebusy.cpp                         |    2 
 icalendar/icalendar.cpp                       |    5 
 kolabformat/kolabobject.cpp                   |    2 
 kolabformat/xmlobject.cpp                     |   22 +--
 tests/CMakeLists.txt                          |    1 
 tests/formattest.cpp                          |   79 +++++++++++
 tests/formattest.h                            |    3 
 tests/testfiles/v3/contacts/distlist.vcf      |    5 
 tests/testfiles/v3/contacts/distlist.vcf.mime |   18 --
 tests/timezonetest.cpp                        |  105 ++++++++++++++
 tests/timezonetest.h                          |   32 ++++
 17 files changed, 502 insertions(+), 34 deletions(-)

New commits:
commit ad58dcf75eba9e49d0d281de69d3f09c02c339f3
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Jan 9 13:52:40 2013 +0100

    Release 0.4.1

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5a459d3..7d46c48 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -33,10 +33,10 @@ endif()
 set(Libkolab_VERSION_MAJOR 0)
 set(Libkolab_VERSION_MINOR 4)
 # Enable the full x.y.z version only for release versions
-#set(Libkolab_VERSION_PATCH 1)
-#set(Libkolab_VERSION ${Libkolab_VERSION_MAJOR}.${Libkolab_VERSION_MINOR}.${Libkolab_VERSION_PATCH} )
-set(Libkolab_VERSION ${Libkolab_VERSION_MAJOR}.${Libkolab_VERSION_MINOR} )
-set(Libkolab_VERSION_STRING ${CMAKE_PROJECT_NAME}-${Libkolab_VERSION})
+set(Libkolab_VERSION_PATCH 1)
+set(Libkolab_VERSION ${Libkolab_VERSION_MAJOR}.${Libkolab_VERSION_MINOR}.${Libkolab_VERSION_PATCH} )
+#set(Libkolab_VERSION ${Libkolab_VERSION_MAJOR}.${Libkolab_VERSION_MINOR} )
+#set(Libkolab_VERSION_STRING ${CMAKE_PROJECT_NAME}-${Libkolab_VERSION})
 
 # set up install directories.
 set(LIB_INSTALL_DIR lib CACHE STRING "The directories where to install libraries to")


commit 9f939506c34d395ca6bc5203d0c6c8ba7b9fe6d1
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Jan 9 13:58:18 2013 +0100

    Use the correct kolab type for distlists + test.
    (cherry picked from commit 2befab0a53b6794020e750cab2e3a5feae1de412)
    
    Conflicts:
    	tests/testutils.h

diff --git a/kolabformat/kolabobject.cpp b/kolabformat/kolabobject.cpp
index 6377968..d2ff3ac 100644
--- a/kolabformat/kolabobject.cpp
+++ b/kolabformat/kolabobject.cpp
@@ -576,7 +576,7 @@ KMime::Message::Ptr KolabObjectWriter::writeDistlist(const KABC::ContactGroup &d
         const Kolab::DistList &dist = Kolab::Conversion::fromKABC(distlist);
         const std::string &v3String = Kolab::writeDistlist(dist, Conversion::toStdString(getProductId(productId)));
         ErrorHandler::handleLibkolabxmlErrors();
-        return  Mime::createMessage(Conversion::fromStdString(dist.uid()), xCardMimeType(), contactKolabType(), Conversion::fromStdString(v3String).toUtf8(), true, getProductId(productId));
+        return  Mime::createMessage(Conversion::fromStdString(dist.uid()), xCardMimeType(), distlistKolabType(), Conversion::fromStdString(v3String).toUtf8(), true, getProductId(productId));
     }
     KolabV2::DistributionList d(&distlist);
     return distListToKolabFormat(d, getProductId(productId));
diff --git a/tests/formattest.cpp b/tests/formattest.cpp
index 346c6e8..3ca0c24 100644
--- a/tests/formattest.cpp
+++ b/tests/formattest.cpp
@@ -29,6 +29,7 @@
 
 #include <kcalcore/icalformat.h>
 #include <kabc/vcardconverter.h>
+#include <kabc/contactgrouptool.h>
 #include <akonadi/notes/noteutils.h>
 
 #include "testutils.h"
@@ -279,6 +280,72 @@ void FormatTest::testContact()
     QCOMPARE(Kolab::ErrorHandler::instance().error(), Kolab::ErrorHandler::Debug);
 }
 
+void FormatTest::testDistlist_data()
+{
+    QTest::addColumn<Kolab::Version>( "version" );
+    QTest::addColumn<Kolab::ObjectType>( "type" );
+    QTest::addColumn<QString>( "vcardFileName" );
+    QTest::addColumn<QString>( "mimeFileName" );
+    
+    QTest::newRow( "v3distlistSimple" ) << Kolab::KolabV3 << Kolab::DistlistObject << TESTFILEDIR+QString::fromLatin1("v3/contacts/distlist.vcf") << TESTFILEDIR+QString::fromLatin1("v3/contacts/distlist.vcf.mime");
+}
+
+void FormatTest::testDistlist()
+{
+    QFETCH( Kolab::Version, version );
+    QFETCH( Kolab::ObjectType, type );
+    QFETCH( QString, vcardFileName ); //To compare
+    QFETCH( QString, mimeFileName ); //For parsing
+    
+    //Parse mime message
+    bool ok = false;
+    const KMime::Message::Ptr &msg = readMimeFile( mimeFileName, ok );
+    QVERIFY(ok);
+    Kolab::KolabObjectReader reader;
+    Kolab::ObjectType t = reader.parseMimeMessage(msg);
+    QCOMPARE(t, type);
+    QCOMPARE(reader.getVersion(), version);
+    QCOMPARE(Kolab::ErrorHandler::instance().error(), Kolab::ErrorHandler::Debug);
+    
+    KABC::ContactGroup convertedAddressee = reader.getDistlist();
+    
+    //Parse vcard
+    QFile vcardFile( vcardFileName );
+    QVERIFY( vcardFile.open( QFile::ReadOnly ) );
+    KABC::VCardConverter converter;
+    QByteArray c = vcardFile.readAll();
+    QBuffer data(&c);
+    data.open(QIODevice::ReadOnly);
+    
+    KABC::ContactGroup realAddressee;
+    KABC::ContactGroupTool::convertFromXml( &data, realAddressee );
+
+    {
+        QBuffer expected;
+        expected.open(QIODevice::WriteOnly);
+        KABC::ContactGroupTool::convertToXml(realAddressee, &expected);
+        
+        QBuffer converted;
+        converted.open(QIODevice::WriteOnly);
+        KABC::ContactGroupTool::convertToXml(convertedAddressee, &converted);
+        
+        showDiff(expected.buffer(), converted.buffer());
+    }
+    QCOMPARE( realAddressee, convertedAddressee );
+
+    //Write
+    const KMime::Message::Ptr &convertedMime = Kolab::KolabObjectWriter::writeDistlist(realAddressee, version);
+    
+    if ( !compareMimeMessage( convertedMime, msg )) {
+        QString expected = msg->encodedContent();
+        normalizeMimemessage(expected);
+        QString converted = convertedMime->encodedContent();
+        normalizeMimemessage(converted);
+        showDiff(expected, converted);
+        QVERIFY( false );
+    }
+    QCOMPARE(Kolab::ErrorHandler::instance().error(), Kolab::ErrorHandler::Debug);
+}
 
 void FormatTest::testNote_data()
 {
@@ -376,6 +443,18 @@ void FormatTest::generateVCard()
 //     KABC::Addressee convertedAddressee = reader.getContact();
 //     KABC::VCardConverter converter;
 //     qDebug() << converter.createVCard(convertedAddressee);
+
+//     bool ok = false;
+//     const KMime::Message::Ptr &msg = readMimeFile( TESTFILEDIR+QString::fromLatin1("v3/contacts/distlist.vcf.mime"), ok );
+//     qDebug() << msg->encodedContent();
+//     Kolab::KolabObjectReader reader;
+//     Kolab::ObjectType t = reader.parseMimeMessage(msg);
+// 
+//     KABC::ContactGroup convertedAddressee = reader.getDistlist();
+//     QBuffer buf;
+//     buf.open(QIODevice::WriteOnly);
+//     KABC::ContactGroupTool::convertToXml(convertedAddressee, &buf);
+//     qDebug() << buf.buffer();
 }
 
 //Pseudo test to show that JPG is always lossy, even with quality set to 100
diff --git a/tests/formattest.h b/tests/formattest.h
index 12655fb..8097bfc 100644
--- a/tests/formattest.h
+++ b/tests/formattest.h
@@ -55,6 +55,9 @@ private slots:
     
     void testContact_data();
     void testContact();
+    
+    void testDistlist_data();
+    void testDistlist();
 
     void testNote_data();
     void testNote();
diff --git a/tests/testfiles/v3/contacts/distlist.vcf b/tests/testfiles/v3/contacts/distlist.vcf
new file mode 100644
index 0000000..cc4984c
--- /dev/null
+++ b/tests/testfiles/v3/contacts/distlist.vcf
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<contactGroup uid="4xuyC0cyjV" name="My Distlist">
+    <contactData name="John Doe" email="jdoe at example.com"/>
+    <contactData name="John Doe2" email="jdoe2 at example.com"/>
+</contactGroup>
\ No newline at end of file
diff --git a/tests/testfiles/v3/contacts/distlist.vcf.mime b/tests/testfiles/v3/contacts/distlist.vcf.mime
index d54c26c..372728e 100644
--- a/tests/testfiles/v3/contacts/distlist.vcf.mime
+++ b/tests/testfiles/v3/contacts/distlist.vcf.mime
@@ -1,10 +1,9 @@
 Date: Mon, 23 Apr 2012 12:46:37 +0200
-X-Kolab-Type: application/x-vnd.kolab.distribution-list
+X-Kolab-Type: application/x-vnd.kolab.contact.distlist
 X-Kolab-Mime-Version: 3.0
 User-Agent: Libkolab-0.1.0
 Content-Type: multipart/mixed; boundary="nextPart1365947.WmFcbPlLFA"
 Subject: 4xuyC0cyjV
-From: Volker Krause <vkrause at kde.org>
 MIME-Version: 1.0
 
 
@@ -38,10 +37,6 @@ Content-Disposition: attachment; filename="kolab.xml"
     <rev>
       <timestamp>20120505T050505Z</timestamp>
     </rev>
-    <categories>
-      <text>cat1</text>
-      <text>cat2</text>
-    </categories>
     <kind>
       <text>group</text>
     </kind>
@@ -49,18 +44,13 @@ Content-Disposition: attachment; filename="kolab.xml"
       <text>My Distlist</text>
     </fn>
     <member>
-      <uri>mailto:John%20Doe%3cjdoe at example.com%3e</uri>
+      <uri>mailto:John%20Doe%3Cjdoe%40example.com%3E</uri>
     </member>
     <member>
-      <uri>mailto:John%20Doe2%3cjdoe2 at example.com%3e</uri>
+      <uri>mailto:John%20Doe2%3Cjdoe2%40example.com%3E</uri>
     </member>
-    <x-custom>
-      <identifier>X-Identifier</identifier>
-      <value>TestValue</value>
-    </x-custom>
-
   </vcard>
 
 </vcards>
 
---nextPart1365947.WmFcbPlLFA--
\ No newline at end of file
+--nextPart1365947.WmFcbPlLFA--


commit fcf79671941e296ab3b43f09aa1f0b3636574965
Merge: 7818a7b c517455
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Jan 1 17:48:48 2013 +0100

    Merge remote-tracking branch 'origin/timezones'
    
    Conflicts:
    	conversion/timezoneconverter.cpp



commit c517455d88ad50df1d90b2b512af64b3eaa2c226
Author: Sofia Balicka <balicka at kolabsys.com>
Date:   Fri Dec 21 09:56:35 2012 +0100

    Some timezones were wrong in the list I pasted in before

diff --git a/conversion/timezoneconverter.cpp b/conversion/timezoneconverter.cpp
index 3321b18..ffb04e9 100644
--- a/conversion/timezoneconverter.cpp
+++ b/conversion/timezoneconverter.cpp
@@ -84,7 +84,7 @@ static const struct WindowsTimezone {
 //   const int gmtOffset;
   const char *timezoneSpecifier; //This one should be stable and always in english
   const char *name; //The display name (which is in some cases still useful to try guessing)
-  const char *olson[35]; //Corresponding olson timezones we can map to
+  const char *olson[28]; //Corresponding olson timezones we can map to
 } windowsTimezones[] = {
     {"Afghanistan Standard Time", "Kabul", {"Asia/Kabul", "Asia/Kabul"}},
     {"Alaskan Standard Time", "Alaska", {"America/Anchorage", "America/Anchorage America/Juneau America/Nome America/Sitka America/Yakutat"}},
@@ -101,12 +101,12 @@ static const struct WindowsTimezone {
     {"Caucasus Standard Time", "Yerevan", {"Asia/Yerevan", "Asia/Yerevan"}},
     {"Cen. Australia Standard Time", "Adelaide", {"Australia/Adelaide", "Australia/Adelaide Australia/Broken_Hill"}},
     {"Central America Standard Time", "Central America", {"America/Guatemala", "America/Belize", "America/Costa_Rica", "Pacific/Galapagos", "America/Guatemala", "America/Tegucigalpa", "America/Managua", "America/El_Salvador", "Etc/GMT+6"}},
-    {"Central Asia Standard Time", "Astana, Dhaka", {"Asia/Almaty", "Antarctica/Vostok", "Indian/Chagos", "Asia/Bishkek", "Asia/Almaty Asia/Qyzylorda", "Etc/GMT-6", "Asia/Novosibirsk", "Asia/Novosibirsk Asia/Novokuznetsk Asia/Omsk"}},
+    {"Central Asia Standard Time", "Astana, Dhaka", {"Asia/Almaty", "Antarctica/Vostok", "Indian/Chagos", "Asia/Bishkek", "Asia/Almaty Asia/Qyzylorda", "Etc/GMT-6"}},
     {"Central Brazilian Standard Time", "Manaus", {"America/Cuiaba", "America/Cuiaba America/Campo_Grande"}},
     {"Central Europe Standard Time", "Belgrade, Bratislava, Budapest, Ljubljana, Prague", {"Europe/Budapest", "Europe/Tirane", "Europe/Prague", "Europe/Budapest", "Europe/Podgorica", "Europe/Belgrade", "Europe/Ljubljana", "Europe/Bratislava"}},
     {"Central European Standard Time", "Sarajevo, Skopje, Warsaw, Zagreb", {"Europe/Warsaw", "Europe/Sarajevo", "Europe/Zagreb", "Europe/Skopje", "Europe/Warsaw"}},
     {"Central Pacific Standard Time", "Magadan, Solomon Islands, New Caledonia", {"Pacific/Guadalcanal", "Antarctica/Macquarie", "Pacific/Ponape Pacific/Kosrae", "Pacific/Noumea", "Pacific/Guadalcanal", "Pacific/Efate", "Etc/GMT-11"}},
-    {"Central Standard Time", "Central Time (US and Canada)", {"America/Chicago", "America/Winnipeg America/Rainy_River America/Rankin_Inlet America/Resolute", "America/Matamoros", "America/Chicago America/Indiana/Knox America/Indiana/Tell_City America/Menominee America/North_Dakota/Beulah America/North_Dakota/Center America/North_Dakota/New_Salem", "CST6CDT", "America/Mexico_City", "America/Mexico_City America/Bahia_Banderas America/Cancun America/Merida America/Monterrey", "America/Regina", "America/Regina America/Swift_Current", "Australia/Darwin", "Australia/Darwin"}},
+    {"Central Standard Time", "Central Time (US and Canada)", {"America/Chicago", "America/Winnipeg America/Rainy_River America/Rankin_Inlet America/Resolute", "America/Matamoros", "America/Chicago America/Indiana/Knox America/Indiana/Tell_City America/Menominee America/North_Dakota/Beulah America/North_Dakota/Center America/North_Dakota/New_Salem", "CST6CDT"}},
     {"Central Standard Time (Mexico)", "Guadalajara, Mexico City, Monterrey", {"America/Mexico_City", "America/Mexico_City America/Bahia_Banderas America/Cancun America/Merida America/Monterrey"}},
     {"China Standard Time", "Beijing, Chongqing, Hong Kong SAR, Urumqi", {"Asia/Shanghai", "Asia/Shanghai Asia/Chongqing Asia/Harbin Asia/Kashgar Asia/Urumqi", "Asia/Hong_Kong", "Asia/Macau"}},
     {"Dateline Standard Time", "International Date Line West", {"Etc/GMT+12", "Etc/GMT+12"}},
@@ -114,7 +114,7 @@ static const struct WindowsTimezone {
     {"E. Australia Standard Time", "Brisbane", {"Australia/Brisbane", "Australia/Brisbane Australia/Lindeman"}},
     {"E. Europe Standard Time", "Minsk", {"Asia/Nicosia", "Asia/Nicosia"}},
     {"E. South America Standard Time", "Brasilia", {"America/Sao_Paulo", "America/Sao_Paulo"}},
-    {"Eastern Standard Time", "Eastern Time (US and Canada)", {"America/New_York", "America/Nassau", "America/Toronto America/Iqaluit America/Montreal America/Nipigon America/Pangnirtung America/Thunder_Bay", "America/Grand_Turk", "America/New_York America/Detroit America/Indiana/Petersburg America/Indiana/Vincennes America/Indiana/Winamac America/Kentucky/Monticello America/Louisville", "EST5EDT", "America/Indianapolis", "America/Indianapolis America/Indiana/Marengo America/Indiana/Vevay", "America/Cayenne", "Antarctica/Rothera", "America/Fortaleza America/Araguaina America/Belem America/Maceio America/Recife America/Santarem", "Atlantic/Stanley", "America/Cayenne", "America/Paramaribo", "Etc/GMT+3", "Australia/Sydney", "Australia/Sydney Australia/Melbourne"}},
+    {"Eastern Standard Time", "Eastern Time (US and Canada)", {"America/New_York", "America/Nassau", "America/Toronto America/Iqaluit America/Montreal America/Nipigon America/Pangnirtung America/Thunder_Bay", "America/Grand_Turk", "America/New_York America/Detroit America/Indiana/Petersburg America/Indiana/Vincennes America/Indiana/Winamac America/Kentucky/Monticello America/Louisville", "EST5EDT"}},
     {"Egypt Standard Time", "Cairo", {"Africa/Cairo", "Africa/Cairo", "Asia/Gaza Asia/Hebron"}},
     {"Ekaterinburg Standard Time", "Ekaterinburg", {"Asia/Yekaterinburg", "Asia/Yekaterinburg"}},
     {"Fiji Standard Time", "Fiji Islands, Kamchatka, Marshall Islands", {"Pacific/Fiji", "Pacific/Fiji"}},
@@ -130,7 +130,7 @@ static const struct WindowsTimezone {
     {"Israel Standard Time", "Jerusalem", {"Asia/Jerusalem", "Asia/Jerusalem"}},
     {"Korea Standard Time", "Seoul", {"Asia/Seoul", "Asia/Pyongyang", "Asia/Seoul"}},
 //    {"Mid-Atlantic Standard Time", "Mid-Atlantic", {"}},
-    {"Mountain Standard Time", "Mountain Time (US and Canada)", {"America/Phoenix", "America/Dawson_Creek America/Creston", "America/Hermosillo", "America/Phoenix", "Etc/GMT+7", "America/Chihuahua", "America/Chihuahua America/Mazatlan", "America/Denver", "America/Edmonton America/Cambridge_Bay America/Inuvik America/Yellowknife", "America/Ojinaga", "America/Denver America/Boise America/Shiprock", "MST7MDT"}},
+    {"Mountain Standard Time", "Mountain Time (US and Canada)", {"America/Denver", "America/Edmonton America/Cambridge_Bay America/Inuvik America/Yellowknife", "America/Ojinaga", "America/Denver America/Boise America/Shiprock", "MST7MDT"}},
     {"Mountain Standard Time (Mexico)", "Chihuahua, La Paz, Mazatlan", {"America/Chihuahua", "America/Chihuahua America/Mazatlan"}},
     {"Myanmar Standard Time", "Yangon (Rangoon)", {"Asia/Rangoon", "Indian/Cocos", "Asia/Rangoon"}},
     {"N. Central Asia Standard Time", "Almaty, Novosibirsk", {"Asia/Novosibirsk", "Asia/Novosibirsk Asia/Novokuznetsk Asia/Omsk"}},
@@ -141,7 +141,7 @@ static const struct WindowsTimezone {
     {"North Asia East Standard Time", "Irkutsk, Ulaanbaatar", {"Asia/Irkutsk", "Asia/Irkutsk"}},
     {"North Asia Standard Time", "Krasnoyarsk", {"Asia/Krasnoyarsk", "Asia/Krasnoyarsk"}},
     {"Pacific SA Standard Time", "Santiago", {"America/Santiago", "Antarctica/Palmer", "America/Santiago"}},
-    {"Pacific Standard Time", "Pacific Time (US and Canada); Tijuana", {"America/Santa_Isabel", "America/Santa_Isabel", "America/Los_Angeles", "America/Vancouver America/Dawson America/Whitehorse", "America/Tijuana", "America/Los_Angeles", "PST8PDT", "America/Bogota", "America/Coral_Harbour", "America/Bogota", "America/Guayaquil", "America/Port-au-Prince", "America/Jamaica", "America/Cayman", "America/Panama", "America/Lima", "Etc/GMT+5", "Pacific/Port_Moresby", "Antarctica/DumontDUrville", "Pacific/Truk", "Pacific/Guam", "Pacific/Saipan", "Pacific/Port_Moresby", "Etc/GMT-10", "Pacific/Guadalcanal", "Antarctica/Macquarie", "Pacific/Ponape Pacific/Kosrae", "Pacific/Noumea", "Pacific/Guadalcanal", "Pacific/Efate", "Etc/GMT-11"}},
+    {"Pacific Standard Time", "Pacific Time (US and Canada); Tijuana", {"America/Los_Angeles", "America/Vancouver America/Dawson America/Whitehorse", "America/Tijuana", "America/Los_Angeles", "PST8PDT"}},
     {"Romance Standard Time", "Brussels, Copenhagen, Madrid, Paris", {"Europe/Paris", "Europe/Brussels", "Europe/Copenhagen", "Europe/Madrid Africa/Ceuta", "Europe/Paris"}},
     {"Russian Standard Time", "Moscow, St. Petersburg, Volgograd", {"Europe/Moscow", "Europe/Moscow Europe/Samara Europe/Volgograd"}},
     {"SA Eastern Standard Time", "Buenos Aires, Georgetown", {"America/Cayenne", "Antarctica/Rothera", "America/Fortaleza America/Araguaina America/Belem America/Maceio America/Recife America/Santarem", "Atlantic/Stanley", "America/Cayenne", "America/Paramaribo", "Etc/GMT+3"}},
@@ -156,7 +156,7 @@ static const struct WindowsTimezone {
     {"Tasmania Standard Time", "Hobart", {"Australia/Hobart", "Australia/Hobart Australia/Currie"}},
     {"Tokyo Standard Time", "Osaka, Sapporo, Tokyo", {"Asia/Tokyo", "Asia/Jayapura", "Asia/Tokyo", "Pacific/Palau", "Asia/Dili", "Etc/GMT-9"}},
     {"Tonga Standard Time", "Nuku'alofa", {"Pacific/Tongatapu", "Pacific/Enderbury", "Pacific/Fakaofo", "Pacific/Tongatapu", "Etc/GMT-13"}},
-    {"US Eastern Standard Time", "Indiana (East)", {"America/Indianapolis", "America/Indianapolis America/Indiana/Marengo America/Indiana/Vevay", "Australia/Sydney", "Australia/Sydney Australia/Melbourne"}},
+    {"US Eastern Standard Time", "Indiana (East)", {"America/Indianapolis", "America/Indianapolis America/Indiana/Marengo America/Indiana/Vevay"}},
     {"US Mountain Standard Time", "Arizona", {"America/Phoenix", "America/Dawson_Creek America/Creston", "America/Hermosillo", "America/Phoenix", "Etc/GMT+7"}},
     {"Vladivostok Standard Time", "Vladivostok", {"Asia/Vladivostok", "Asia/Vladivostok Asia/Sakhalin"}},
     {"W. Australia Standard Time", "Perth", {"Australia/Perth", "Antarctica/Casey", "Australia/Perth"}},


commit cec79bd22536929e72f5634feee52497a03abb2c
Author: Sofia Balicka <balicka at kolabsys.com>
Date:   Fri Dec 21 09:20:09 2012 +0100

    Added complete timezone mapping

diff --git a/conversion/timezoneconverter.cpp b/conversion/timezoneconverter.cpp
index 57c9b70..3321b18 100644
--- a/conversion/timezoneconverter.cpp
+++ b/conversion/timezoneconverter.cpp
@@ -84,49 +84,87 @@ static const struct WindowsTimezone {
 //   const int gmtOffset;
   const char *timezoneSpecifier; //This one should be stable and always in english
   const char *name; //The display name (which is in some cases still useful to try guessing)
-  const char *olson[2]; //Corresponding olson timezones we can map to
+  const char *olson[35]; //Corresponding olson timezones we can map to
 } windowsTimezones[] = {
-    {"Afghanistan Standard Time", "Kabul", {"Asia/Kabul"}},
-    {"Alaskan Standard Time", "Alaska", {"America/Anchorage"}},
-    {"Arab Standard Time", "Kuwait, Riyadh", {"Asia/Riyadh"}},
-    {"Arabian Standard Time", "Abu Dhabi, Muscat", {"Asia/Dubai"}},
-    {"Arabic Standard Time", "Baghdad", {"Asia/Baghdad"}},
-    {"Atlantic Standard Time", "Atlantic Time (Canada)", {"America/Halifax"}},
-    {"AUS Central Standard Time", "Darwin", {"Australia/Darwin"}},
-    {"AUS Eastern Standard Time", "Canberra, Melbourne, Sydney", {"Australia/Sydney"}},
-    {"Azerbaijan Standard Time", "Baku", {"Asia/Baku"}},
-    {"Azores Standard Time", "Azores", {"Atlantic/Azores"}},
-    {"Canada Central Standard Time", "Saskatchewan", {"America/Regina"}},
-    {"Cape Verde Standard Time", "Cape Verde Islands", {"Atlantic/Cape_Verde"}},
-    {"Caucasus Standard Time", "Yerevan", {"Asia/Yerevan"}},
-    {"Cen. Australia Standard Time", "Adelaide", {"Australia/Adelaide"}},
-    {"Central America Standard Time", "Central America", {"America/Guatemala"}},
-    {"Central Asia Standard Time", "Astana, Dhaka", {"Asia/Almaty"}},
-    {"Central Brazilian Standard Time", "Manaus", {"America/Manaus"}},
-    {"Central Europe Standard Time", "Belgrade, Bratislava, Budapest, Ljubljana, Prague", {"Europe/Budapest"}},
-    {"Central European Standard Time", "Sarajevo, Skopje, Warsaw, Zagreb", {"Europe/Warsaw"}},
-    {"Central Pacific Standard Time", "Magadan, Solomon Islands, New Caledonia", {"Asia/Magadan"}},
-    {"Central Standard Time", "Central Time", {"America/Chicago"}},
-    {"Central Standard Time (Mexico)", "Guadalajara, Mexico City, Monterrey", {"America/Mexico_City"}},
-    {"China Standard Time", "Beijing, Chongqing, Hong Kong SAR, Urumqi", {"Asia/Shanghai"}},
-//     {"Dateline Standard Time", "International Date Line West", {""}},
-    {"E. Africa Standard Time", "Nairobi", {"Africa/Nairobi"}},
-    {"E. Australia Standard Time", "Brisbane", {"Australia/Brisbane"}},
-    {"E. Europe Standard Time", "Minsk", {"Europe/Minsk"}},
-    {"E. South America Standard Time", "Brasilia", {"America/Sao_Paulo"}},
-    {"Eastern Standard Time", "Eastern Time", {"America/New_York"}},
-    {"Egypt Standard Time", "Cairo", {"Africa/Cairo"}},
-    {"Ekaterinburg Standard Time", "Ekaterinburg", {"Asia/Yekaterinburg"}},
-    {"Fiji Standard Time", "Fiji Islands, Kamchatka, Marshall Islands", {"Pacific/Fiji"}},
-    {"FLE Standard Time", "Helsinki, Kiev, Riga, Sofia, Tallinn, Vilnius", {"Europe/Kiev"}},
-    {"Georgian Standard Time", "Tblisi", {"Asia/Tbilisi"}},
-    {"GMT Standard Time", "Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London", {"Europe/London"}},
-    {"Greenland Standard Time", "Greenland", {"America/Godthab"}},
-    {"Greenwich Standard Time", "Casablanca, Monrovia", {"Atlantic/Reykjavik"}},
-    {"", "", {""}},
-    
-    {"W. Europe Standard Time", "Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna", {"Europe/Berlin", "Europe/Amsterdam"}},
-    {"W. Central Africa Standard Time", "West Central Africa", {"Africa/Lagos"}}
+    {"Afghanistan Standard Time", "Kabul", {"Asia/Kabul", "Asia/Kabul"}},
+    {"Alaskan Standard Time", "Alaska", {"America/Anchorage", "America/Anchorage America/Juneau America/Nome America/Sitka America/Yakutat"}},
+    {"Arab Standard Time", "Kuwait, Riyadh", {"Asia/Riyadh", "Asia/Bahrain", "Asia/Kuwait", "Asia/Qatar", "Asia/Riyadh", "Asia/Aden"}},
+    {"Arabian Standard Time", "Abu Dhabi, Muscat", {"Asia/Dubai", "Asia/Dubai", "Asia/Muscat", "Etc/GMT-4"}},
+    {"Arabic Standard Time", "Baghdad", {"Asia/Baghdad", "Asia/Baghdad"}},
+    {"Atlantic Standard Time", "Atlantic Time (Canada)", {"America/Halifax", "Atlantic/Bermuda", "America/Halifax America/Glace_Bay America/Goose_Bay America/Moncton", "America/Thule"}},
+    {"AUS Central Standard Time", "Darwin", {"Australia/Darwin", "Australia/Darwin"}},
+    {"AUS Eastern Standard Time", "Canberra, Melbourne, Sydney", {"Australia/Sydney", "Australia/Sydney Australia/Melbourne"}},
+    {"Azerbaijan Standard Time", "Baku", {"Asia/Baku", "Asia/Baku"}},
+    {"Azores Standard Time", "Azores", {"Atlantic/Azores", "America/Scoresbysund", "Atlantic/Azores"}},
+    {"Canada Central Standard Time", "Saskatchewan", {"America/Regina", "America/Regina America/Swift_Current"}},
+    {"Cape Verde Standard Time", "Cape Verde Islands", {"Atlantic/Cape_Verde", "Atlantic/Cape_Verde", "Etc/GMT+1"}},
+    {"Caucasus Standard Time", "Yerevan", {"Asia/Yerevan", "Asia/Yerevan"}},
+    {"Cen. Australia Standard Time", "Adelaide", {"Australia/Adelaide", "Australia/Adelaide Australia/Broken_Hill"}},
+    {"Central America Standard Time", "Central America", {"America/Guatemala", "America/Belize", "America/Costa_Rica", "Pacific/Galapagos", "America/Guatemala", "America/Tegucigalpa", "America/Managua", "America/El_Salvador", "Etc/GMT+6"}},
+    {"Central Asia Standard Time", "Astana, Dhaka", {"Asia/Almaty", "Antarctica/Vostok", "Indian/Chagos", "Asia/Bishkek", "Asia/Almaty Asia/Qyzylorda", "Etc/GMT-6", "Asia/Novosibirsk", "Asia/Novosibirsk Asia/Novokuznetsk Asia/Omsk"}},
+    {"Central Brazilian Standard Time", "Manaus", {"America/Cuiaba", "America/Cuiaba America/Campo_Grande"}},
+    {"Central Europe Standard Time", "Belgrade, Bratislava, Budapest, Ljubljana, Prague", {"Europe/Budapest", "Europe/Tirane", "Europe/Prague", "Europe/Budapest", "Europe/Podgorica", "Europe/Belgrade", "Europe/Ljubljana", "Europe/Bratislava"}},
+    {"Central European Standard Time", "Sarajevo, Skopje, Warsaw, Zagreb", {"Europe/Warsaw", "Europe/Sarajevo", "Europe/Zagreb", "Europe/Skopje", "Europe/Warsaw"}},
+    {"Central Pacific Standard Time", "Magadan, Solomon Islands, New Caledonia", {"Pacific/Guadalcanal", "Antarctica/Macquarie", "Pacific/Ponape Pacific/Kosrae", "Pacific/Noumea", "Pacific/Guadalcanal", "Pacific/Efate", "Etc/GMT-11"}},
+    {"Central Standard Time", "Central Time (US and Canada)", {"America/Chicago", "America/Winnipeg America/Rainy_River America/Rankin_Inlet America/Resolute", "America/Matamoros", "America/Chicago America/Indiana/Knox America/Indiana/Tell_City America/Menominee America/North_Dakota/Beulah America/North_Dakota/Center America/North_Dakota/New_Salem", "CST6CDT", "America/Mexico_City", "America/Mexico_City America/Bahia_Banderas America/Cancun America/Merida America/Monterrey", "America/Regina", "America/Regina America/Swift_Current", "Australia/Darwin", "Australia/Darwin"}},
+    {"Central Standard Time (Mexico)", "Guadalajara, Mexico City, Monterrey", {"America/Mexico_City", "America/Mexico_City America/Bahia_Banderas America/Cancun America/Merida America/Monterrey"}},
+    {"China Standard Time", "Beijing, Chongqing, Hong Kong SAR, Urumqi", {"Asia/Shanghai", "Asia/Shanghai Asia/Chongqing Asia/Harbin Asia/Kashgar Asia/Urumqi", "Asia/Hong_Kong", "Asia/Macau"}},
+    {"Dateline Standard Time", "International Date Line West", {"Etc/GMT+12", "Etc/GMT+12"}},
+    {"E. Africa Standard Time", "Nairobi", {"Africa/Nairobi", "Antarctica/Syowa", "Africa/Djibouti", "Africa/Asmera", "Africa/Addis_Ababa", "Africa/Nairobi", "Indian/Comoro", "Indian/Antananarivo", "Africa/Khartoum", "Africa/Mogadishu", "Africa/Juba", "Africa/Dar_es_Salaam", "Africa/Kampala", "Indian/Mayotte", "Etc/GMT-3"}},
+    {"E. Australia Standard Time", "Brisbane", {"Australia/Brisbane", "Australia/Brisbane Australia/Lindeman"}},
+    {"E. Europe Standard Time", "Minsk", {"Asia/Nicosia", "Asia/Nicosia"}},
+    {"E. South America Standard Time", "Brasilia", {"America/Sao_Paulo", "America/Sao_Paulo"}},
+    {"Eastern Standard Time", "Eastern Time (US and Canada)", {"America/New_York", "America/Nassau", "America/Toronto America/Iqaluit America/Montreal America/Nipigon America/Pangnirtung America/Thunder_Bay", "America/Grand_Turk", "America/New_York America/Detroit America/Indiana/Petersburg America/Indiana/Vincennes America/Indiana/Winamac America/Kentucky/Monticello America/Louisville", "EST5EDT", "America/Indianapolis", "America/Indianapolis America/Indiana/Marengo America/Indiana/Vevay", "America/Cayenne", "Antarctica/Rothera", "America/Fortaleza America/Araguaina America/Belem America/Maceio America/Recife America/Santarem", "Atlantic/Stanley", "America/Cayenne", "America/Paramaribo", "Etc/GMT+3", "Australia/Sydney", "Australia/Sydney Australia/Melbourne"}},
+    {"Egypt Standard Time", "Cairo", {"Africa/Cairo", "Africa/Cairo", "Asia/Gaza Asia/Hebron"}},
+    {"Ekaterinburg Standard Time", "Ekaterinburg", {"Asia/Yekaterinburg", "Asia/Yekaterinburg"}},
+    {"Fiji Standard Time", "Fiji Islands, Kamchatka, Marshall Islands", {"Pacific/Fiji", "Pacific/Fiji"}},
+    {"FLE Standard Time", "Helsinki, Kiev, Riga, Sofia, Tallinn, Vilnius", {"Europe/Kiev", "Europe/Mariehamn", "Europe/Sofia", "Europe/Tallinn", "Europe/Helsinki", "Europe/Vilnius", "Europe/Riga", "Europe/Kiev Europe/Simferopol Europe/Uzhgorod Europe/Zaporozhye"}},
+    {"Georgian Standard Time", "Tblisi", {"Asia/Tbilisi", "Asia/Tbilisi"}},
+    {"GMT Standard Time", "Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London", {"Europe/London", "Atlantic/Canary", "Atlantic/Faeroe", "Europe/London", "Europe/Guernsey", "Europe/Dublin", "Europe/Isle_of_Man", "Europe/Jersey", "Europe/Lisbon Atlantic/Madeira"}},
+    {"Greenland Standard Time", "Greenland", {"America/Godthab", "America/Godthab"}},
+    {"Greenwich Standard Time", "Casablanca, Monrovia", {"Atlantic/Reykjavik", "Africa/Ouagadougou", "Africa/Abidjan", "Africa/El_Aaiun", "Africa/Accra", "Africa/Banjul", "Africa/Conakry", "Africa/Bissau", "Atlantic/Reykjavik", "Africa/Monrovia", "Africa/Bamako", "Africa/Nouakchott", "Atlantic/St_Helena", "Africa/Freetown", "Africa/Dakar", "Africa/Sao_Tome", "Africa/Lome"}},
+    {"GTB Standard Time", "Athens, Bucharest, Istanbul", {"Europe/Bucharest", "Europe/Athens", "Europe/Chisinau", "Europe/Bucharest"}},
+    {"Hawaiian Standard Time", "Hawaii", {"Pacific/Honolulu", "Pacific/Rarotonga", "Pacific/Tahiti", "Pacific/Johnston", "Pacific/Honolulu", "Etc/GMT+10"}},
+    {"India Standard Time", "Chennai, Kolkata, Mumbai, New Delhi", {"Asia/Calcutta", "Asia/Calcutta"}},
+    {"Iran Standard Time", "Tehran", {"Asia/Tehran", "Asia/Tehran"}},
+    {"Israel Standard Time", "Jerusalem", {"Asia/Jerusalem", "Asia/Jerusalem"}},
+    {"Korea Standard Time", "Seoul", {"Asia/Seoul", "Asia/Pyongyang", "Asia/Seoul"}},
+//    {"Mid-Atlantic Standard Time", "Mid-Atlantic", {"}},
+    {"Mountain Standard Time", "Mountain Time (US and Canada)", {"America/Phoenix", "America/Dawson_Creek America/Creston", "America/Hermosillo", "America/Phoenix", "Etc/GMT+7", "America/Chihuahua", "America/Chihuahua America/Mazatlan", "America/Denver", "America/Edmonton America/Cambridge_Bay America/Inuvik America/Yellowknife", "America/Ojinaga", "America/Denver America/Boise America/Shiprock", "MST7MDT"}},
+    {"Mountain Standard Time (Mexico)", "Chihuahua, La Paz, Mazatlan", {"America/Chihuahua", "America/Chihuahua America/Mazatlan"}},
+    {"Myanmar Standard Time", "Yangon (Rangoon)", {"Asia/Rangoon", "Indian/Cocos", "Asia/Rangoon"}},
+    {"N. Central Asia Standard Time", "Almaty, Novosibirsk", {"Asia/Novosibirsk", "Asia/Novosibirsk Asia/Novokuznetsk Asia/Omsk"}},
+    {"Namibia Standard Time", "Windhoek", {"Africa/Windhoek", "Africa/Windhoek"}},
+    {"Nepal Standard Time", "Kathmandu", {"Asia/Katmandu", "Asia/Katmandu"}},
+    {"New Zealand Standard Time", "Auckland, Wellington", {"Pacific/Auckland", "Antarctica/South_Pole Antarctica/McMurdo", "Pacific/Auckland"}},
+    {"Newfoundland Standard Time", "Newfoundland and Labrador", {"America/St_Johns", "America/St_Johns"}},
+    {"North Asia East Standard Time", "Irkutsk, Ulaanbaatar", {"Asia/Irkutsk", "Asia/Irkutsk"}},
+    {"North Asia Standard Time", "Krasnoyarsk", {"Asia/Krasnoyarsk", "Asia/Krasnoyarsk"}},
+    {"Pacific SA Standard Time", "Santiago", {"America/Santiago", "Antarctica/Palmer", "America/Santiago"}},
+    {"Pacific Standard Time", "Pacific Time (US and Canada); Tijuana", {"America/Santa_Isabel", "America/Santa_Isabel", "America/Los_Angeles", "America/Vancouver America/Dawson America/Whitehorse", "America/Tijuana", "America/Los_Angeles", "PST8PDT", "America/Bogota", "America/Coral_Harbour", "America/Bogota", "America/Guayaquil", "America/Port-au-Prince", "America/Jamaica", "America/Cayman", "America/Panama", "America/Lima", "Etc/GMT+5", "Pacific/Port_Moresby", "Antarctica/DumontDUrville", "Pacific/Truk", "Pacific/Guam", "Pacific/Saipan", "Pacific/Port_Moresby", "Etc/GMT-10", "Pacific/Guadalcanal", "Antarctica/Macquarie", "Pacific/Ponape Pacific/Kosrae", "Pacific/Noumea", "Pacific/Guadalcanal", "Pacific/Efate", "Etc/GMT-11"}},
+    {"Romance Standard Time", "Brussels, Copenhagen, Madrid, Paris", {"Europe/Paris", "Europe/Brussels", "Europe/Copenhagen", "Europe/Madrid Africa/Ceuta", "Europe/Paris"}},
+    {"Russian Standard Time", "Moscow, St. Petersburg, Volgograd", {"Europe/Moscow", "Europe/Moscow Europe/Samara Europe/Volgograd"}},
+    {"SA Eastern Standard Time", "Buenos Aires, Georgetown", {"America/Cayenne", "Antarctica/Rothera", "America/Fortaleza America/Araguaina America/Belem America/Maceio America/Recife America/Santarem", "Atlantic/Stanley", "America/Cayenne", "America/Paramaribo", "Etc/GMT+3"}},
+    {"SA Pacific Standard Time", "Bogota, Lima, Quito", {"America/Bogota", "America/Coral_Harbour", "America/Bogota", "America/Guayaquil", "America/Port-au-Prince", "America/Jamaica", "America/Cayman", "America/Panama", "America/Lima", "Etc/GMT+5"}},
+    {"SA Western Standard Time", "Caracas, La Paz", {"America/La_Paz", "America/Antigua", "America/Anguilla", "America/Aruba", "America/Barbados", "America/St_Barthelemy", "America/La_Paz", "America/Kralendijk", "America/Manaus America/Boa_Vista America/Eirunepe America/Porto_Velho America/Rio_Branco", "America/Blanc-Sablon", "America/Curacao", "America/Dominica", "America/Santo_Domingo", "America/Grenada", "America/Guadeloupe", "America/Guyana", "America/St_Kitts", "America/St_Lucia", "America/Marigot", "America/Martinique", "America/Montserrat", "America/Puerto_Rico", "America/Lower_Princes", "America/Port_of_Spain", "America/St_Vincent", "America/Tortola", "America/St_Thomas", "Etc/GMT+4"}},
+    {"Samoa Standard Time", "Midway Island, Samoa", {"Pacific/Apia", "Pacific/Apia"}},
+    {"SE Asia Standard Time", "Bangkok, Hanoi, Jakarta", {"Asia/Bangkok", "Antarctica/Davis", "Indian/Christmas", "Asia/Jakarta Asia/Pontianak", "Asia/Phnom_Penh", "Asia/Vientiane", "Asia/Hovd", "Asia/Bangkok", "Asia/Saigon", "Etc/GMT-7"}},
+    {"Singapore Standard Time", "Kuala Lumpur, Singapore", {"Asia/Singapore", "Asia/Brunei", "Asia/Makassar", "Asia/Kuala_Lumpur Asia/Kuching", "Asia/Manila", "Asia/Singapore", "Etc/GMT-8"}},
+    {"South Africa Standard Time", "Harare, Pretoria", {"Africa/Johannesburg", "Africa/Bujumbura", "Africa/Gaborone", "Africa/Lubumbashi", "Africa/Maseru", "Africa/Blantyre", "Africa/Maputo", "Africa/Kigali", "Africa/Mbabane", "Africa/Johannesburg", "Africa/Lusaka", "Africa/Harare", "Etc/GMT-2"}},
+    {"Sri Lanka Standard Time", "Sri Jayawardenepura", {"Asia/Colombo", "Asia/Colombo"}},
+    {"Taipei Standard Time", "Taipei", {"Asia/Taipei", "Asia/Taipei"}},
+    {"Tasmania Standard Time", "Hobart", {"Australia/Hobart", "Australia/Hobart Australia/Currie"}},
+    {"Tokyo Standard Time", "Osaka, Sapporo, Tokyo", {"Asia/Tokyo", "Asia/Jayapura", "Asia/Tokyo", "Pacific/Palau", "Asia/Dili", "Etc/GMT-9"}},
+    {"Tonga Standard Time", "Nuku'alofa", {"Pacific/Tongatapu", "Pacific/Enderbury", "Pacific/Fakaofo", "Pacific/Tongatapu", "Etc/GMT-13"}},
+    {"US Eastern Standard Time", "Indiana (East)", {"America/Indianapolis", "America/Indianapolis America/Indiana/Marengo America/Indiana/Vevay", "Australia/Sydney", "Australia/Sydney Australia/Melbourne"}},
+    {"US Mountain Standard Time", "Arizona", {"America/Phoenix", "America/Dawson_Creek America/Creston", "America/Hermosillo", "America/Phoenix", "Etc/GMT+7"}},
+    {"Vladivostok Standard Time", "Vladivostok", {"Asia/Vladivostok", "Asia/Vladivostok Asia/Sakhalin"}},
+    {"W. Australia Standard Time", "Perth", {"Australia/Perth", "Antarctica/Casey", "Australia/Perth"}},
+    {"W. Central Africa Standard Time", "West Central Africa", {"Africa/Lagos", "Africa/Luanda", "Africa/Porto-Novo", "Africa/Kinshasa", "Africa/Bangui", "Africa/Brazzaville", "Africa/Douala", "Africa/Algiers", "Africa/Libreville", "Africa/Malabo", "Africa/Niamey", "Africa/Lagos", "Africa/Ndjamena", "Africa/Tunis", "Etc/GMT-1"}},
+    {"W. Europe Standard Time", "Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna", {"Europe/Berlin", "Europe/Andorra", "Europe/Vienna", "Europe/Zurich", "Europe/Berlin", "Europe/Gibraltar", "Europe/Rome", "Europe/Vaduz", "Europe/Luxembourg", "Africa/Tripoli", "Europe/Monaco", "Europe/Malta", "Europe/Amsterdam", "Europe/Oslo", "Europe/Stockholm", "Arctic/Longyearbyen", "Europe/San_Marino", "Europe/Vatican"}},
+    {"West Asia Standard Time", "Islamabad, Karachi, Tashkent", {"Asia/Tashkent", "Antarctica/Mawson", "Asia/Oral Asia/Aqtau Asia/Aqtobe", "Indian/Maldives", "Indian/Kerguelen", "Asia/Dushanbe", "Asia/Ashgabat", "Asia/Tashkent Asia/Samarkand", "Etc/GMT-5"}},
+    {"West Pacific Standard Time", "Guam, Port Moresby", {"Pacific/Port_Moresby", "Antarctica/DumontDUrville", "Pacific/Truk", "Pacific/Guam", "Pacific/Saipan", "Pacific/Port_Moresby", "Etc/GMT-10"}},
+    {"Yakutsk Standard Time", "Yakuts", {"Asia/Yakutsk", "Asia/Yakutsk"}}
 };
 static const int numWindowsTimezones = sizeof windowsTimezones / sizeof *windowsTimezones;
 


commit 7818a7b193b7702963b1f24683df8aa5c7c2a593
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Thu Dec 20 18:36:00 2012 +0100

    Deal with failure to fix the timezone.

diff --git a/conversion/commonconversion.cpp b/conversion/commonconversion.cpp
index 6af1ec0..489a1d6 100644
--- a/conversion/commonconversion.cpp
+++ b/conversion/commonconversion.cpp
@@ -90,7 +90,12 @@ cDateTime fromDate(const KDateTime &dt)
             //TODO handle local timezone?
             //Convert non-olson timezones if necessary
             const QString timezone = TimezoneConverter::normalizeTimezone(dt.timeZone().name());
-            date.setTimezone(toStdString(timezone));
+            if (!timezone.isEmpty()) {
+                date.setTimezone(toStdString(timezone));
+            } else {
+                Error() << "invalid timezone: " << dt.timeZone().name() << " , assuming floating time";
+                return date;
+            }
         } else if (dt.timeType() != KDateTime::ClockTime) {
             Error() << "invalid timespec, assuming floating time" << dt.timeType();
             return date;
diff --git a/tests/timezonetest.cpp b/tests/timezonetest.cpp
index 1850978..54b1fbf 100644
--- a/tests/timezonetest.cpp
+++ b/tests/timezonetest.cpp
@@ -74,6 +74,7 @@ void TimezoneTest::testFromHardcodedList_data()
     QTest::newRow( "11" ) << QString::fromLatin1("(GMT-03:30) Newfoundland and Labrador");
     QTest::newRow( "12" ) << QString::fromLatin1("(GMT-08:00) Pacific Time (US and Canada); Tijuana");
     QTest::newRow( "13" ) << QString::fromLatin1("(GMT-11:00) Midway Island, Samoa");
+    QTest::newRow( "14" ) << QString::fromLatin1("W. Europe Standard Time");
 }
 
 void TimezoneTest::testFromHardcodedList()
@@ -81,7 +82,9 @@ void TimezoneTest::testFromHardcodedList()
     TimezoneConverter converter;
     QFETCH(QString, timezone);
     const QString tz = converter.normalizeTimezone(timezone);
+    kDebug() << tz;
     QVERIFY(!tz.isEmpty());
+    QVERIFY(tz != timezone);
 }
 
 void TimezoneTest::testKolabObjectWriter()


commit 6212554c7b34f8c151e09ae867958639aa77da31
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Thu Dec 20 14:59:50 2012 +0100

    Completed the timezone lookup table with sofias help.

diff --git a/conversion/timezoneconverter.cpp b/conversion/timezoneconverter.cpp
index 57c9b70..693b143 100644
--- a/conversion/timezoneconverter.cpp
+++ b/conversion/timezoneconverter.cpp
@@ -123,10 +123,47 @@ static const struct WindowsTimezone {
     {"GMT Standard Time", "Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London", {"Europe/London"}},
     {"Greenland Standard Time", "Greenland", {"America/Godthab"}},
     {"Greenwich Standard Time", "Casablanca, Monrovia", {"Atlantic/Reykjavik"}},
-    {"", "", {""}},
-    
-    {"W. Europe Standard Time", "Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna", {"Europe/Berlin", "Europe/Amsterdam"}},
-    {"W. Central Africa Standard Time", "West Central Africa", {"Africa/Lagos"}}
+    {"GTB Standard Time", "Athens, Bucharest, Istanbul", {"Europe/Bucharest"}},
+    {"Hawaiian Standard Time", "Hawaii", {"Pacific/Honolulu"}},
+    {"India Standard Time", "Chennai, Kolkata, Mumbai, New Delhi", {"Asia/Calcutta"}},
+    {"Iran Standard Time", "Tehran", {"Asia/Tehran"}},
+    {"Israel Standard Time", "Jerusalem", {"Asia/Jerusalem"}},
+    {"Korea Standard Time", "Seoul", {"Asia/Seoul"}},
+    {"Mountain Standard Time", "Mountain Time", {"America/Phoenix"}},
+    {"Mountain Standard Time (Mexico)", "Chihuahua, La Paz, Mazatlan", {"America/Chihuahua"}},
+    {"Myanmar Standard Time", "Yangon (Rangoon)", {"Asia/Rangoon"}},
+    {"N. Central Asia Standard Time", "Almaty, Novosibirsk", {"Asia/Novosibirsk"}},
+    {"Namibia Standard Time", " Windhoek", {"Africa/Windhoek"}},
+    {"Nepal Standard Time", "Kathmandu", {"Asia/Katmandu"}},
+    {"New Zealand Standard Time", "Auckland, Wellington", {"Pacific/Auckland"}},
+    {"Newfoundland Standard Time", "Newfoundland and Labrador", {"America/St_Johns"}},
+    {"North Asia East Standard Time", "Irkutsk, Ulaanbaatar", {"Asia/Irkutsk"}},
+    {"North Asia Standard Time", "Krasnoyarsk", {"Asia/Krasnoyarsk"}},
+    {"Pacific SA Standard Time", "Santiago", {"America/Santiago"}},
+    {"Pacific Standard Time", "Pacific Time (US and Canada); Tijuana", {"America/Los_Angeles"}},
+    {"Romance Standard Time", "Brussels, Copenhagen, Madrid, Paris", {"Europe/Paris"}},
+    {"Russian Standard Time", "Moscow, St. Petersburg, Volgograd", {"Europe/Moscow"}},
+    {"SA Eastern Standard Time", "Buenos Aires, Georgetown", {"America/Cayenne"}},
+    {"SA Pacific Standard Time", "Bogota, Lima, Quito", {"America/Bogota"}},
+    {"SA Western Standard Time", "Caracas, La Paz", {"America/La_Paz"}},
+    {"Samoa Standard Time", "Midway Island, Samoa", {"Pacific/Apia"}},
+    {"SE Asia Standard Time", "Bangkok, Hanoi, Jakarta", {"Asia/Bangkok"}},
+    {"Singapore Standard Time", "Kuala Lumpur, Singapore", {"Asia/Singapore"}},
+    {"South Africa Standard Time", "Harare, Pretoria", {"Africa/Johannesburg"}},
+    {"Sri Lanka Standard Time", "Sri Jayawardenepura", {"Asia/Colombo"}},
+    {"Taipei Standard Time", "Taipei", {"Asia/Taipei"}},
+    {"Tasmania Standard Time", "Hobart", {"Australia/Hobart"}},
+    {"Tokyo Standard Time", "Osaka, Sapporo, Tokyo", {"Asia/Tokyo"}},
+    {"Tonga Standard Time", "Nuku'alofa", {"Pacific/Tongatapu"}},
+    {"US Eastern Standard Time", "Indiana (East)", {"America/Indianapolis"}},
+    {"US Mountain Standard Time", "Arizona", {"America/Phoenix"}},
+    {"Vladivostok Standard Time", "Vladivostok", {"Asia/Vladivostok"}},
+    {"W. Australia Standard Time", "Perth", {"Australia/Perth"}},
+    {"W. Central Africa Standard Time", "West Central Africa", {"Africa/Lagos"}},
+    {"W. Europe Standard Time", "Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna", {"Europe/Berlin"}},
+    {"West Asia Standard Time", "Islamabad, Karachi, Tashkent", {"Asia/Tashkent"}},
+    {"West Pacific Standard Time", "Guam, Port Moresby", {"Pacific/Port_Moresby"}},
+    {"Yakutsk Standard Time", "Yakutsk", {"Asia/Yakutsk"}}
 };
 static const int numWindowsTimezones = sizeof windowsTimezones / sizeof *windowsTimezones;
 
@@ -142,19 +179,5 @@ QString TimezoneConverter::fromHardcodedList(const QString& tz)
             return QString::fromLatin1(windowsTimezone.olson[0]);
         }
     }
-    
-
-//     if (tz.contains(QLatin1String("Mid-Atlantic"))) {
-//         return QLatin1String();
-//     }
-    if (tz.contains(QLatin1String("Mountain Time"))) {
-        return QLatin1String("America/Denver");
-    }
-    if (tz.contains(QLatin1String("Newfoundland and Labrador"))) {
-        return QLatin1String("America/St_Johns");
-    }
-    if (tz.contains(QLatin1String("Pacific Time"))) {
-        return QLatin1String("America/Los_Angeles");
-    }
     return QString();
 }


commit 799219cc7e45073dc86e2d97475e483c70f2b030
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Thu Dec 20 02:53:29 2012 +0100

    Beginning of a more thorough windows timezone conversion table.

diff --git a/conversion/timezoneconverter.cpp b/conversion/timezoneconverter.cpp
index 6941681..57c9b70 100644
--- a/conversion/timezoneconverter.cpp
+++ b/conversion/timezoneconverter.cpp
@@ -74,32 +74,76 @@ QString TimezoneConverter::fromCityName(const QString& tz)
     return QString();
 }
 
+
+//Based on
+// * http://msdn.microsoft.com/en-us/library/ms912391(v=winembedded.11).aspx
+// * http://technet.microsoft.com/en-us/library/cc749073(v=ws.10).aspx
+// * http://unicode.org/repos/cldr/trunk/common/supplemental/windowsZones.xml
+// * http://stackoverflow.com/questions/4967903/linux-windows-timezone-mapping
+static const struct WindowsTimezone {
+//   const int gmtOffset;
+  const char *timezoneSpecifier; //This one should be stable and always in english
+  const char *name; //The display name (which is in some cases still useful to try guessing)
+  const char *olson[2]; //Corresponding olson timezones we can map to
+} windowsTimezones[] = {
+    {"Afghanistan Standard Time", "Kabul", {"Asia/Kabul"}},
+    {"Alaskan Standard Time", "Alaska", {"America/Anchorage"}},
+    {"Arab Standard Time", "Kuwait, Riyadh", {"Asia/Riyadh"}},
+    {"Arabian Standard Time", "Abu Dhabi, Muscat", {"Asia/Dubai"}},
+    {"Arabic Standard Time", "Baghdad", {"Asia/Baghdad"}},
+    {"Atlantic Standard Time", "Atlantic Time (Canada)", {"America/Halifax"}},
+    {"AUS Central Standard Time", "Darwin", {"Australia/Darwin"}},
+    {"AUS Eastern Standard Time", "Canberra, Melbourne, Sydney", {"Australia/Sydney"}},
+    {"Azerbaijan Standard Time", "Baku", {"Asia/Baku"}},
+    {"Azores Standard Time", "Azores", {"Atlantic/Azores"}},
+    {"Canada Central Standard Time", "Saskatchewan", {"America/Regina"}},
+    {"Cape Verde Standard Time", "Cape Verde Islands", {"Atlantic/Cape_Verde"}},
+    {"Caucasus Standard Time", "Yerevan", {"Asia/Yerevan"}},
+    {"Cen. Australia Standard Time", "Adelaide", {"Australia/Adelaide"}},
+    {"Central America Standard Time", "Central America", {"America/Guatemala"}},
+    {"Central Asia Standard Time", "Astana, Dhaka", {"Asia/Almaty"}},
+    {"Central Brazilian Standard Time", "Manaus", {"America/Manaus"}},
+    {"Central Europe Standard Time", "Belgrade, Bratislava, Budapest, Ljubljana, Prague", {"Europe/Budapest"}},
+    {"Central European Standard Time", "Sarajevo, Skopje, Warsaw, Zagreb", {"Europe/Warsaw"}},
+    {"Central Pacific Standard Time", "Magadan, Solomon Islands, New Caledonia", {"Asia/Magadan"}},
+    {"Central Standard Time", "Central Time", {"America/Chicago"}},
+    {"Central Standard Time (Mexico)", "Guadalajara, Mexico City, Monterrey", {"America/Mexico_City"}},
+    {"China Standard Time", "Beijing, Chongqing, Hong Kong SAR, Urumqi", {"Asia/Shanghai"}},
+//     {"Dateline Standard Time", "International Date Line West", {""}},
+    {"E. Africa Standard Time", "Nairobi", {"Africa/Nairobi"}},
+    {"E. Australia Standard Time", "Brisbane", {"Australia/Brisbane"}},
+    {"E. Europe Standard Time", "Minsk", {"Europe/Minsk"}},
+    {"E. South America Standard Time", "Brasilia", {"America/Sao_Paulo"}},
+    {"Eastern Standard Time", "Eastern Time", {"America/New_York"}},
+    {"Egypt Standard Time", "Cairo", {"Africa/Cairo"}},
+    {"Ekaterinburg Standard Time", "Ekaterinburg", {"Asia/Yekaterinburg"}},
+    {"Fiji Standard Time", "Fiji Islands, Kamchatka, Marshall Islands", {"Pacific/Fiji"}},
+    {"FLE Standard Time", "Helsinki, Kiev, Riga, Sofia, Tallinn, Vilnius", {"Europe/Kiev"}},
+    {"Georgian Standard Time", "Tblisi", {"Asia/Tbilisi"}},
+    {"GMT Standard Time", "Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London", {"Europe/London"}},
+    {"Greenland Standard Time", "Greenland", {"America/Godthab"}},
+    {"Greenwich Standard Time", "Casablanca, Monrovia", {"Atlantic/Reykjavik"}},
+    {"", "", {""}},
+    
+    {"W. Europe Standard Time", "Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna", {"Europe/Berlin", "Europe/Amsterdam"}},
+    {"W. Central Africa Standard Time", "West Central Africa", {"Africa/Lagos"}}
+};
+static const int numWindowsTimezones = sizeof windowsTimezones / sizeof *windowsTimezones;
+
 QString TimezoneConverter::fromHardcodedList(const QString& tz)
 {
-    if (tz.contains(QLatin1String("West Central Africa"))) {
-        return QLatin1String("Africa/Lagos");
-    }
-    if (tz.contains(QLatin1String("Atlantic Time"))) {
-        return QLatin1String("America/Halifax");
-    }
-    if (tz.contains(QLatin1String("Saskatchewan"))) {
-        return QLatin1String("America/Regina");
-    }
-    if (tz.contains(QLatin1String("Cape Verde Islands"))) {
-        return QLatin1String("Atlantic/Cape_Verde");
-    }
-    if (tz.contains(QLatin1String("Central America"))) {
-        return QLatin1String("America/Guatemala");
-    }
-    if (tz.contains(QLatin1String("Central Time"))) {
-        return QLatin1String("America/Chicago");
-    }
-//     if (tz.contains(QLatin1String("International Date Line West"))) {
-//         return QLatin1String("");
-//     }
-    if (tz.contains(QLatin1String("Eastern Time"))) {
-        return QLatin1String("America/New_York");
+    for (int i = 0; i <numWindowsTimezones; i++) {
+        const WindowsTimezone &windowsTimezone = windowsTimezones[i];
+        const QByteArray specifier(windowsTimezone.timezoneSpecifier);
+        const QByteArray windowsName(windowsTimezone.name);
+        if ((!specifier.isEmpty() && tz.contains(specifier)) ||
+            (!windowsName.isEmpty() && tz.contains(windowsName))) {
+            //TODO find the olson timezone matching the local timezone if we have multiple to map to
+            return QString::fromLatin1(windowsTimezone.olson[0]);
+        }
     }
+    
+
 //     if (tz.contains(QLatin1String("Mid-Atlantic"))) {
 //         return QLatin1String();
 //     }


commit 3e735fab30b250aed509e620fc34c16d4ced92f9
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Sat Dec 15 16:14:17 2012 +0100

    Forgot to add timezonetest sourcefiles.

diff --git a/tests/timezonetest.cpp b/tests/timezonetest.cpp
new file mode 100644
index 0000000..1850978
--- /dev/null
+++ b/tests/timezonetest.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "timezonetest.h"
+#include <conversion/timezoneconverter.h>
+#include <kolabformat/kolabobject.h>
+#include <kolabformat/errorhandler.h>
+
+#include <QTest>
+// #include <unicode/uversion.h>
+// #include <unicode/timezone.h>
+// #include <iostream>
+#include <kdebug.h>
+#include <kcalcore/event.h>
+
+// void icuFoo()
+// {
+//     icu::UnicodeString s;
+//     UErrorCode error;
+// //     icu::TimeZone::getCanonicalID("GMT+01.00) Sarajevo/Warsaw/Zagreb", s, error);
+// //     icu::TimeZone::getCanonicalID(icu::UnicodeString::fromUTF8("Europe/Zurich"), s, error);
+//     icu::TimeZone::getCanonicalID(icu::UnicodeString::fromUTF8("GMT+01.00"), s, error);
+//     std::string cs;
+//     s.toUTF8String(cs);
+//     std::cout << "This is the new timezone: " << cs  << std::endl << u_errorName(error) << std::endl;
+// // 
+// // 
+// //     icu::TimeZone *tz = icu::TimeZone::createTimeZone("GMT-8:00");
+// //     icu::UnicodeString result;
+// //     tz->getDisplayName(result);
+// //     std::string stringresult;
+// //     result.toUTF8String(stringresult);
+// //     std::cout << stringresult;
+//     
+// //     icu::TimeZone *tz = icu::TimeZone::getStaticClassID();
+// 
+// }
+
+void TimezoneTest::testFromName()
+{
+    TimezoneConverter converter;
+    const QString timezone = converter.normalizeTimezone("(GMT+01.00) Sarajevo/Warsaw/Zagreb");
+    QCOMPARE(timezone, QLatin1String("Europe/Sarajevo"));
+}
+
+void TimezoneTest::testFromHardcodedList_data()
+{
+    QTest::addColumn<QString>( "timezone" );
+    
+    QTest::newRow( "1" ) << QString::fromLatin1("(GMT+01:00) West Central Africa");
+    QTest::newRow( "2" ) << QString::fromLatin1("(GMT-04:00) Atlantic Time (Canada)");
+    QTest::newRow( "3" ) << QString::fromLatin1("(GMT-06:00) Saskatchewan");
+    QTest::newRow( "4" ) << QString::fromLatin1("(GMT-01:00) Cape Verde Islands");
+    QTest::newRow( "5" ) << QString::fromLatin1("(GMT-06:00) Central America");
+    QTest::newRow( "6" ) << QString::fromLatin1("(GMT-06:00) Central Time (US and Canada)");
+//     QTest::newRow( "7" ) << QString::fromLatin1("(GMT-12:00) International Date Line West"); //Not mappable
+    QTest::newRow( "8" ) << QString::fromLatin1("(GMT-05:00) Eastern Time (US and Canada)");
+//     QTest::newRow( "9" ) << QString::fromLatin1("(GMT-02:00) Mid-Atlantic"); //Not mappable
+    QTest::newRow( "10" ) << QString::fromLatin1("(GMT-07:00) Mountain Time (US and Canada)");
+    QTest::newRow( "11" ) << QString::fromLatin1("(GMT-03:30) Newfoundland and Labrador");
+    QTest::newRow( "12" ) << QString::fromLatin1("(GMT-08:00) Pacific Time (US and Canada); Tijuana");
+    QTest::newRow( "13" ) << QString::fromLatin1("(GMT-11:00) Midway Island, Samoa");
+}
+
+void TimezoneTest::testFromHardcodedList()
+{
+    TimezoneConverter converter;
+    QFETCH(QString, timezone);
+    const QString tz = converter.normalizeTimezone(timezone);
+    QVERIFY(!tz.isEmpty());
+}
+
+void TimezoneTest::testKolabObjectWriter()
+{
+    KCalCore::Event::Ptr event(new KCalCore::Event());
+    event->setOrganizer(KCalCore::Person::Ptr());
+    event->setDtStart(KDateTime(QDate(2012,11,11), QTime(1,1), KDateTime::Spec(KTimeZone("(GMT+01:00) West Central Africa"))));
+    KMime::Message::Ptr msg = Kolab::KolabObjectWriter::writeEvent(event);
+    Kolab::KolabObjectReader reader(msg);
+    KCalCore::Event::Ptr result = reader.getEvent();
+    kDebug() << result->dtStart().timeZone().name();
+    QCOMPARE(result->dtStart().timeZone().name(), KTimeZone(QLatin1String("Africa/Lagos")).name());
+}
+
+
+QTEST_MAIN( TimezoneTest )
+
+#include "timezonetest.moc"
diff --git a/tests/timezonetest.h b/tests/timezonetest.h
new file mode 100644
index 0000000..cf7a4d5
--- /dev/null
+++ b/tests/timezonetest.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TIMEZONETEST_H
+#define TIMEZONETEST_H
+#include <QObject>
+
+class TimezoneTest: public QObject
+{
+    Q_OBJECT
+private slots:
+    void testFromName();
+    void testFromHardcodedList_data();
+    void testFromHardcodedList();
+    void testKolabObjectWriter();
+};
+
+#endif // TIMEZONETEST_H


commit 4b2a015cb41717495f9d3369a33e854437aff6b9
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 14 18:03:14 2012 +0100

    Convert non-olson timezones (such as windows timezones).

diff --git a/conversion/commonconversion.cpp b/conversion/commonconversion.cpp
index d516520..6af1ec0 100644
--- a/conversion/commonconversion.cpp
+++ b/conversion/commonconversion.cpp
@@ -16,6 +16,7 @@
  */
 
 #include "commonconversion.h"
+#include "timezoneconverter.h"
 #include <kolabformat/errorhandler.h>
 
 #include <iostream>
@@ -87,7 +88,9 @@ cDateTime fromDate(const KDateTime &dt)
             date.setUTC(true);
         } else if (dt.timeType() == KDateTime::TimeZone) { //Timezone
             //TODO handle local timezone?
-            date.setTimezone(toStdString(dt.timeZone().name())); //FIXME use system independent name according to spec
+            //Convert non-olson timezones if necessary
+            const QString timezone = TimezoneConverter::normalizeTimezone(dt.timeZone().name());
+            date.setTimezone(toStdString(timezone));
         } else if (dt.timeType() != KDateTime::ClockTime) {
             Error() << "invalid timespec, assuming floating time" << dt.timeType();
             return date;


commit efdfdd535c701ddc9ac352c1175e6bd2097df912
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 14 17:59:45 2012 +0100

    Use the proper conversion functions.

diff --git a/kolabformat/xmlobject.cpp b/kolabformat/xmlobject.cpp
index bead9f2..ebeca5f 100644
--- a/kolabformat/xmlobject.cpp
+++ b/kolabformat/xmlobject.cpp
@@ -55,7 +55,7 @@ std::string XMLObject::writeEvent(const Event &event, Version version, const std
         if (i->uid().isEmpty()) {
             i->setUid(createUuid());
         }
-        mWrittenUID = Conversion::toStdString(i->uid().toUtf8().constData());
+        mWrittenUID = Conversion::toStdString(i->uid());
         //The timezone is used for created and last modified dates
         const QString &xml = KolabV2::Event::eventToXML(i, QLatin1String("UTC"));
         return Conversion::toStdString(xml);
@@ -72,7 +72,7 @@ Event XMLObject::readEvent(const std::string& s, Version version)
         const KCalCore::Event::Ptr event = Kolab::fromXML<KCalCore::Event::Ptr, KolabV2::Event>(QString::fromUtf8(s.c_str()).toUtf8(), attachments);
         mAttachments.clear();
         foreach (const QString &attachment, attachments) {
-            mAttachments.push_back(std::string(attachment.toUtf8().constData()));
+            mAttachments.push_back(Conversion::toStdString(attachment));
         }
         return Conversion::fromKCalCore(*event);
     }
@@ -87,7 +87,7 @@ std::string XMLObject::writeTodo(const Todo &event, Version version, const std::
         if (i->uid().isEmpty()) {
             i->setUid(createUuid());
         }
-        mWrittenUID = Conversion::toStdString(i->uid().toUtf8().constData());
+        mWrittenUID = Conversion::toStdString(i->uid());
         //The timezone is used for created and last modified dates
         const QString &xml = KolabV2::Task::taskToXML(i, QLatin1String("UTC"));
         return Conversion::toStdString(xml);
@@ -104,7 +104,7 @@ Todo XMLObject::readTodo(const std::string& s, Version version)
         const KCalCore::Todo::Ptr event = Kolab::fromXML<KCalCore::Todo::Ptr, KolabV2::Task>(QString::fromUtf8(s.c_str()).toUtf8(), attachments);
         mAttachments.clear();
         foreach (const QString &attachment, attachments) {
-            mAttachments.push_back(std::string(attachment.toUtf8().constData()));
+            mAttachments.push_back(Conversion::toStdString(attachment));
         }
         return Conversion::fromKCalCore(*event);
     }
@@ -119,7 +119,7 @@ std::string XMLObject::writeJournal(const Journal &event, Version version, const
         if (i->uid().isEmpty()) {
             i->setUid(createUuid());
         }
-        mWrittenUID = Conversion::toStdString(i->uid().toUtf8().constData());
+        mWrittenUID = Conversion::toStdString(i->uid());
         //The timezone is used for created and last modified dates
         const QString &xml = KolabV2::Journal::journalToXML(i, QLatin1String("UTC"));
         return Conversion::toStdString(xml);
@@ -136,7 +136,7 @@ Journal XMLObject::readJournal(const std::string& s, Version version)
         const KCalCore::Journal::Ptr event = Kolab::fromXML<KCalCore::Journal::Ptr, KolabV2::Journal>(QString::fromUtf8(s.c_str()).toUtf8(), attachments);
         mAttachments.clear();
         foreach (const QString &attachment, attachments) {
-            mAttachments.push_back(std::string(attachment.toUtf8().constData()));
+            mAttachments.push_back(Conversion::toStdString(attachment));
         }
         return Conversion::fromKCalCore(*event);
     }
@@ -204,10 +204,9 @@ std::string XMLObject::writeContact(const Contact &contact, Version version, con
         if (addressee.uid().isEmpty()) {
             addressee.setUid(createUuid());
         }
-        mWrittenUID = Conversion::toStdString(addressee.uid().toUtf8().constData());
+        mWrittenUID = Conversion::toStdString(addressee.uid());
         const KolabV2::Contact contact(&addressee);
-        const QByteArray xml = contact.saveXML().toUtf8();
-        return std::string(xml.constData());
+        return Conversion::toStdString(contact.saveXML());
     }
     const std::string result = Kolab::writeContact(contact, productId);
     mWrittenUID = Kolab::getSerializedUID();
@@ -232,10 +231,9 @@ std::string XMLObject::writeDistlist(const DistList &distlist, Version version,
         if (contactGroup.id().isEmpty()) {
             contactGroup.setId(createUuid());
         }
-        mWrittenUID = Conversion::toStdString(contactGroup.id().toUtf8().constData());
+        mWrittenUID = Conversion::toStdString(contactGroup.id());
         const KolabV2::DistributionList d(&contactGroup);
-        const QByteArray xml = d.saveXML().toUtf8();
-        return std::string(xml.constData());
+        return Conversion::toStdString(d.saveXML());
     }
     const std::string result = Kolab::writeDistlist(distlist, productId);
     mWrittenUID = Kolab::getSerializedUID();


commit e91085aeeb73cf4475c23583ce40ed23b1d7b0f9
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 14 17:58:35 2012 +0100

    Windows timezone conversion.

diff --git a/conversion/CMakeLists.txt b/conversion/CMakeLists.txt
index c4f323e..683de63 100644
--- a/conversion/CMakeLists.txt
+++ b/conversion/CMakeLists.txt
@@ -2,6 +2,7 @@
 set (CONVERSION_SRCS
     ${CMAKE_CURRENT_SOURCE_DIR}/kcalconversion.cpp 
     ${CMAKE_CURRENT_SOURCE_DIR}/kabcconversion.cpp 
-    ${CMAKE_CURRENT_SOURCE_DIR}/commonconversion.cpp 
-    ${CMAKE_CURRENT_SOURCE_DIR}/kolabconversion.cpp PARENT_SCOPE)
+    ${CMAKE_CURRENT_SOURCE_DIR}/commonconversion.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/kolabconversion.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/timezoneconverter.cpp PARENT_SCOPE)
 
diff --git a/conversion/timezoneconverter.cpp b/conversion/timezoneconverter.cpp
new file mode 100644
index 0000000..6941681
--- /dev/null
+++ b/conversion/timezoneconverter.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "timezoneconverter.h"
+#include <ktimezone.h>
+#include <ksystemtimezone.h>
+#include <kdebug.h>
+#include <QRegExp>
+#include <QStringList>
+
+QString TimezoneConverter::normalizeTimezone(const QString& tz)
+{
+    KTimeZone timezone = KSystemTimeZones::zone(tz); //Needs ktimezoned (timezone daemon running) http://api.kde.org/4.x-api/kdelibs-apidocs/kdecore/html/classKSystemTimeZones.html
+    if (timezone.isValid()) {
+        return tz;
+    }
+    //We're dealing with an invalid or unknown timezone, try to parse it
+    QString guessedTimezone = fromCityName(tz);
+    if (guessedTimezone.isEmpty()) {
+        guessedTimezone = fromHardcodedList(tz);
+    }
+    if (guessedTimezone.isEmpty()) {
+        guessedTimezone = fromGMTOffsetTimezone(tz);
+    }
+    return guessedTimezone;
+}
+
+QString TimezoneConverter::fromGMTOffsetTimezone(const QString& tz)
+{
+    Q_UNUSED(tz);
+    return QString();
+}
+
+QString TimezoneConverter::fromCityName(const QString& tz)
+{
+    const KTimeZones::ZoneMap zones = KSystemTimeZones::zones();
+    KTimeZones::ZoneMap::const_iterator it = zones.constBegin();
+    QHash<QString, QString> countryMap;
+    for(;it != zones.constEnd(); it++) {
+        const QString cityName = it.key().split('/').last();
+//         kDebug() << it.key() << it.value().name() << cityName;
+        Q_ASSERT(!countryMap.contains(cityName));
+        countryMap.insert(cityName, it.key());
+    }
+
+    QRegExp locationFinder("\\b([a-zA-Z])+\\b", Qt::CaseSensitive, QRegExp::RegExp2);
+    int pos = 0;
+    while (pos >= 0) {
+        pos = locationFinder.indexIn(tz, pos);
+        if (pos >= 0) {
+            ++pos;
+        }
+        const QString location = locationFinder.capturedTexts().first();
+//         kDebug() << "location " << location;
+        if (countryMap.contains(location)) {
+//             kDebug() << "found match " << countryMap.value(location);
+            return countryMap.value(location);
+        }
+    }
+    return QString();
+}
+
+QString TimezoneConverter::fromHardcodedList(const QString& tz)
+{
+    if (tz.contains(QLatin1String("West Central Africa"))) {
+        return QLatin1String("Africa/Lagos");
+    }
+    if (tz.contains(QLatin1String("Atlantic Time"))) {
+        return QLatin1String("America/Halifax");
+    }
+    if (tz.contains(QLatin1String("Saskatchewan"))) {
+        return QLatin1String("America/Regina");
+    }
+    if (tz.contains(QLatin1String("Cape Verde Islands"))) {
+        return QLatin1String("Atlantic/Cape_Verde");
+    }
+    if (tz.contains(QLatin1String("Central America"))) {
+        return QLatin1String("America/Guatemala");
+    }
+    if (tz.contains(QLatin1String("Central Time"))) {
+        return QLatin1String("America/Chicago");
+    }
+//     if (tz.contains(QLatin1String("International Date Line West"))) {
+//         return QLatin1String("");
+//     }
+    if (tz.contains(QLatin1String("Eastern Time"))) {
+        return QLatin1String("America/New_York");
+    }
+//     if (tz.contains(QLatin1String("Mid-Atlantic"))) {
+//         return QLatin1String();
+//     }
+    if (tz.contains(QLatin1String("Mountain Time"))) {
+        return QLatin1String("America/Denver");
+    }
+    if (tz.contains(QLatin1String("Newfoundland and Labrador"))) {
+        return QLatin1String("America/St_Johns");
+    }
+    if (tz.contains(QLatin1String("Pacific Time"))) {
+        return QLatin1String("America/Los_Angeles");
+    }
+    return QString();
+}
diff --git a/conversion/timezoneconverter.h b/conversion/timezoneconverter.h
new file mode 100644
index 0000000..84cad70
--- /dev/null
+++ b/conversion/timezoneconverter.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TIMEZONECONVERTER_H
+#define TIMEZONECONVERTER_H
+
+#include <QString>
+
+class TimezoneConverter
+{
+public:
+    static QString normalizeTimezone(const QString &tz);
+private:
+    static QString fromCityName(const QString &tz);
+    static QString fromHardcodedList(const QString &tz);
+    static QString fromGMTOffsetTimezone(const QString &tz);
+};
+
+#endif // TIMEZONECONVERTER_H
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 7362351..b3aa7ac 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -20,3 +20,4 @@ addTest(calendaringtest)
 addTest(icalendartest)
 addTest(freebusytest)
 addTest(kolabobjecttest)
+addTest(timezonetest)


commit 818bb8576480c59f1623af370fa50034aca08074
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Fri Dec 14 17:56:49 2012 +0100

    Set libkolab application string.

diff --git a/freebusy/freebusy.cpp b/freebusy/freebusy.cpp
index 878904b..7b20c20 100644
--- a/freebusy/freebusy.cpp
+++ b/freebusy/freebusy.cpp
@@ -19,6 +19,7 @@
 #include "freebusy.h"
 #include "conversion/kcalconversion.h"
 #include "conversion/commonconversion.h"
+#include "libkolab-version.h"
 #include <kcalcore/freebusy.h>
 #include <kcalcore/icalformat.h>
 #include <kdebug.h>
@@ -311,6 +312,7 @@ std::string toIFB(const Kolab::Freebusy &freebusy)
     fb->setLastModified(Kolab::Conversion::toDate(freebusy.timestamp()));
 
     KCalCore::ICalFormat format;
+    format.setApplication("libkolab", LIBKOLAB_LIB_VERSION_STRING);
     QString data = format.createScheduleMessage( fb, KCalCore::iTIPPublish );
     return Conversion::toStdString(data);
 }
diff --git a/icalendar/icalendar.cpp b/icalendar/icalendar.cpp
index 77aa01a..be7c0e6 100644
--- a/icalendar/icalendar.cpp
+++ b/icalendar/icalendar.cpp
@@ -20,6 +20,7 @@
 
 #include "icalendar.h"
 #include "imip.h"
+#include "libkolab-version.h"
 #include <conversion/kcalconversion.h>
 #include <conversion/commonconversion.h>
 #include <mime/mimeutils.h>
@@ -42,6 +43,7 @@ std::string toICal(const std::vector<Event> &events)
         calendar->addEvent(kcalEvent);
     }
     KCalCore::ICalFormat format;
+    format.setApplication("libkolab", LIBKOLAB_LIB_VERSION_STRING);
 //     qDebug() << format.createScheduleMessage(calendar->events().first(), KCalCore::iTIPRequest);
 
     return Conversion::toStdString(format.toString(calendar));
@@ -52,6 +54,7 @@ std::vector< Event > fromICalEvents(const std::string &input)
 {
     KCalCore::Calendar::Ptr calendar(new KCalCore::MemoryCalendar(Kolab::Conversion::getTimeSpec(true, std::string())));
     KCalCore::ICalFormat format;
+    format.setApplication("libkolab", LIBKOLAB_LIB_VERSION_STRING);
     format.fromString(calendar, Conversion::fromStdString(input));
     std::vector<Event> events;
     foreach (const KCalCore::Event::Ptr &event, calendar->events()) {
@@ -84,6 +87,7 @@ KCalCore::iTIPMethod mapToKCalCore(ITipHandler::ITipMethod method)
 std::string ITipHandler::toITip(const Event &event, ITipHandler::ITipMethod method) const
 {
     KCalCore::ICalFormat format;
+    format.setApplication("libkolab", LIBKOLAB_LIB_VERSION_STRING);
     KCalCore::iTIPMethod m = mapToKCalCore(method);
     if (m == KCalCore::iTIPNoMethod) {
         return std::string();
@@ -125,6 +129,7 @@ std::string ITipHandler::toIMip(const Event &event , ITipHandler::ITipMethod m,
     KCalCore::Event::Ptr e = Conversion::toKCalCore(event);
 //     e->recurrence()->addRDateTime(e->dtStart()); //FIXME The createScheduleMessage converts everything to utc without a recurrence.
     KCalCore::ICalFormat format;
+    format.setApplication("libkolab", LIBKOLAB_LIB_VERSION_STRING);
     KCalCore::iTIPMethod method = mapToKCalCore(m);
     const QString &messageText = format.createScheduleMessage( e, method );
     //This code is mostly from MailScheduler::performTransaction


commit 344d747ea8ad79ff0981931f83d0fb166f8a8ff5
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Nov 21 17:39:25 2012 +0100

    Added COPYING-CMAKE-SCRIPTS.

diff --git a/cmake/modules/COPYING-CMAKE-SCRIPTS b/cmake/modules/COPYING-CMAKE-SCRIPTS
new file mode 100644
index 0000000..4b41776
--- /dev/null
+++ b/cmake/modules/COPYING-CMAKE-SCRIPTS
@@ -0,0 +1,22 @@
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products 
+   derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.





More information about the commits mailing list