5 commits - CMakeLists.txt conversion/kolabconversion.cpp kolabformat/kolabdefinitions.h kolabformat/kolabobject.cpp kolabformat/kolabobject.h kolabformat/v2helpers.h mime/mimeutils.cpp tests/formattest.cpp tests/formattest.h tests/testfiles

Christian Mollekopf mollekopf at kolabsys.com
Fri Jun 8 12:48:00 CEST 2012


 CMakeLists.txt                         |    7 +++
 conversion/kolabconversion.cpp         |   72 +++++++++++++++++++++++++++++++-
 kolabformat/kolabdefinitions.h         |   10 +++-
 kolabformat/kolabobject.cpp            |   74 +++++++++++++++++++++++++++++----
 kolabformat/kolabobject.h              |    5 +-
 kolabformat/v2helpers.h                |   29 ++++++++++++
 mime/mimeutils.cpp                     |   22 +++------
 tests/formattest.cpp                   |   64 ++++++++++++++++++++++++++++
 tests/formattest.h                     |    2 
 tests/testfiles/v3/note/note.mime      |   10 ++++
 tests/testfiles/v3/note/note.mime.mime |   46 ++++++++++++++++++++
 11 files changed, 311 insertions(+), 30 deletions(-)

New commits:
commit 4cd01274a5e2792aab8da6fc0a76744dbde4528b
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Thu Jun 7 16:47:37 2012 +0200

    Support for the dictionary configuration object.

diff --git a/kolabformat/kolabobject.cpp b/kolabformat/kolabobject.cpp
index b46045b..1f46d95 100644
--- a/kolabformat/kolabobject.cpp
+++ b/kolabformat/kolabobject.cpp
@@ -60,6 +60,8 @@ public:
     KABC::Addressee mAddressee;
     KABC::ContactGroup mContactGroup;
     KMime::Message::Ptr mNote;
+    QStringList mDictionary;
+    QString mDictionaryLanguage;
     ObjectType mObjectType;
     Version mVersion;
 };
@@ -91,10 +93,12 @@ Kolab::ObjectType getObjectType(const QString &type)
         return JournalObject;
     } else if (type == contactKolabType()) {
         return ContactObject;
-    }  else if (type == distlistKolabType() || type == distlistKolabTypeCompat()) {
+    } else if (type == distlistKolabType() || type == distlistKolabTypeCompat()) {
         return DistlistObject;
-    }  else if (type == noteKolabType()) {
+    } else if (type == noteKolabType()) {
         return NoteObject;
+    } else if (type.contains(dictKolabType())) { //Previous versions appended the language to the type
+        return DictionaryConfigurationObject;
     }
     return Kolab::InvalidObject;
 }
@@ -123,7 +127,7 @@ ObjectType KolabObjectReader::parseMimeMessage(const KMime::Message::Ptr &msg)
     d->mObjectType = InvalidObject;
     KMime::Headers::Base *xKolabHeader = msg->getHeaderByType(X_KOLAB_TYPE_HEADER);
     if (!xKolabHeader) {
-        CRITICAL("could not find xKolabHeader");
+        CRITICAL("could not find the X-Kolab-Type Header");
         return InvalidObject;
     }
     const QString &kolabType = xKolabHeader->asUnicodeString(); //TODO we probably shouldn't use unicodeString
@@ -143,6 +147,17 @@ ObjectType KolabObjectReader::parseMimeMessage(const KMime::Message::Ptr &msg)
     }
     d->mObjectType = getObjectType(kolabType);
     if (d->mVersion == KolabV2) {
+        if (d->mObjectType == DictionaryConfigurationObject) {
+            KMime::Content *xmlContent = Mime::findContentByType( msg, "application/xml" );
+            if ( !xmlContent ) {
+                CRITICAL("no part found");
+                return InvalidObject;
+            }
+            const QByteArray &xmlData = xmlContent->decodedContent();
+            d->mDictionary = readLegacyDictionaryConfiguration(xmlData, d->mDictionaryLanguage);
+            ErrorHandler::handleLibkolabxmlErrors();
+            return d->mObjectType;
+        }
         KMime::Content *xmlContent = Mime::findContentByType( msg, kolabType.toLocal8Bit() );
         if ( !xmlContent ) {
             CRITICAL("no part found");
@@ -218,6 +233,16 @@ ObjectType KolabObjectReader::parseMimeMessage(const KMime::Message::Ptr &msg)
                 d->mNote = Kolab::Conversion::toNote(note);
             }
                 break;
+            case DictionaryConfigurationObject: {
+                const Kolab::Configuration &configuration = Kolab::readConfiguration(std::string(xmlContent->decodedContent().data(), xmlContent->decodedContent().size()), false);
+                const Kolab::Dictionary &dictionary = configuration.dictionary();
+                d->mDictionary.clear();
+                foreach (const std::string &entry, dictionary.entries()) {
+                    d->mDictionary.append(QString::fromStdString(entry));
+                }
+                d->mDictionaryLanguage = QString::fromStdString(dictionary.language());
+            }
+                break;
             default:
                 CRITICAL("no kolab object found "+kolabType);
                 break;
@@ -277,6 +302,13 @@ KMime::Message::Ptr KolabObjectReader::getNote() const
     return d->mNote;
 }
 
+QStringList KolabObjectReader::getDictionary(QString& lang) const
+{
+    lang = d->mDictionaryLanguage;
+    return d->mDictionary;
+}
+
+
 //Normalize incidences before serializing them
 KCalCore::Incidence::Ptr normalizeIncidence(KCalCore::Incidence::Ptr original)
 {
@@ -404,6 +436,27 @@ KMime::Message::Ptr KolabObjectWriter::writeNote(const KMime::Message::Ptr &note
     return noteToKolab(note, getProductId(productId));
 }
 
+KMime::Message::Ptr KolabObjectWriter::writeDictionary(const QStringList &entries, const QString& lang, Version v, const QString& productId)
+{
+    ErrorHandler::clearErrors();
+    if (v != KolabV3) {
+        Critical() << "only v3 implementation available";
+    }
+
+    Kolab::Dictionary dictionary(lang.toStdString());
+    std::vector <std::string> ent;
+    foreach (const QString &e, entries) {
+        ent.push_back(e.toStdString());
+    }
+    dictionary.setEntries(ent);
+    Kolab::Configuration configuration(dictionary); //TODO preserve creation/lastModified date
+    const std::string &v3String = Kolab::writeConfiguration(configuration, getProductId(productId).toStdString());
+    ErrorHandler::handleLibkolabxmlErrors();
+    //TODO uid in subject?
+    return  Mime::createMessage(QString(), kolabMimeType(), dictKolabType(), QString::fromStdString(v3String).toLocal8Bit(), true, getProductId(productId));
+}
+
+
 
 
 
diff --git a/kolabformat/kolabobject.h b/kolabformat/kolabobject.h
index 604c1c5..ecde1f1 100644
--- a/kolabformat/kolabobject.h
+++ b/kolabformat/kolabobject.h
@@ -42,7 +42,8 @@ enum ObjectType {
     JournalObject,
     ContactObject,
     DistlistObject,
-    NoteObject
+    NoteObject,
+    DictionaryConfigurationObject
 };
 
 KOLAB_EXPORT KCalCore::Event::Ptr readV2EventXML(const QByteArray &xmlData, QStringList &attachments);
@@ -84,6 +85,7 @@ public:
     KABC::Addressee getContact() const;
     KABC::ContactGroup getDistlist() const;
     KMime::Message::Ptr getNote() const;
+    QStringList getDictionary(QString &lang) const;
 
 private:
     //@cond PRIVATE
@@ -106,6 +108,7 @@ public:
     static KMime::Message::Ptr writeContact(const KABC::Addressee &, Version v = KolabV3, const QString &productId = QString());
     static KMime::Message::Ptr writeDistlist(const KABC::ContactGroup &, Version v = KolabV3, const QString &productId = QString());
     static KMime::Message::Ptr writeNote(const KMime::Message::Ptr &, Version v = KolabV3, const QString &productId = QString());
+    static KMime::Message::Ptr writeDictionary(const QStringList &, const QString &lang, Version v = KolabV3, const QString &productId = QString());
 };
 
 }; //Namespace
diff --git a/kolabformat/v2helpers.h b/kolabformat/v2helpers.h
index 15e6304..3700f37 100644
--- a/kolabformat/v2helpers.h
+++ b/kolabformat/v2helpers.h
@@ -41,7 +41,6 @@ namespace Kolab {
 /*
  * Parse XML, create KCalCore container and extract attachments
  */
-//TODO V2 specific
 template <typename KCalPtr, typename Container>
 static KCalPtr fromXML(const QByteArray &xmlData, QStringList &attachments)
 {
@@ -56,7 +55,6 @@ static KCalPtr fromXML(const QByteArray &xmlData, QStringList &attachments)
     return i;
 }
 
-//TODO V2 specific
 template <typename IncidencePtr, typename Converter>
 static inline IncidencePtr incidenceFromKolabImpl( const KMime::Message::Ptr &data, const QByteArray &mimetype, const QString &timezoneId )
 {
@@ -241,6 +239,33 @@ KMime::Message::Ptr noteToKolab(const KMime::Message::Ptr& msg, const QString &p
     return Mime::createMessage(j.summary(), noteKolabType(), noteKolabType(), j.saveXML().toUtf8(), false, productId); 
 }
 
+QStringList readLegacyDictionaryConfiguration(const QByteArray &xmlData, QString &language)
+{
+    QStringList dictionary;
+    const QDomDocument xmlDoc = KolabV2::KolabBase::loadDocument( QString::fromUtf8(xmlData) ); //TODO extract function from V2 format
+    Q_ASSERT ( !xmlDoc.isNull() );
+
+    QDomElement top = xmlDoc.documentElement();
+
+    if ( top.tagName() != "configuration" ) {
+        qWarning( "XML error: Top tag was %s instead of the expected configuration",
+                top.tagName().toAscii().data() );
+        return QStringList();
+    }
+
+    for ( QDomNode n = top.firstChild(); !n.isNull(); n = n.nextSibling() ) {
+        if ( n.isComment() || !n.isElement() )
+            continue;
+        QDomElement e = n.toElement();
+        if (e.tagName() == "language") {
+            language = e.text();
+        } else if (e.tagName() == "e") {
+            dictionary.append(e.text());
+        }
+    }
+    return dictionary;
+}
+
 }
 
 #endif
\ No newline at end of file


commit 65fa1e9d505e16bf50a951dfcf5ffc9838305c62
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Thu Jun 7 16:45:25 2012 +0200

    cleanup

diff --git a/mime/mimeutils.cpp b/mime/mimeutils.cpp
index 28de780..3a7ee6c 100644
--- a/mime/mimeutils.cpp
+++ b/mime/mimeutils.cpp
@@ -34,22 +34,18 @@ KMime::Content* findContentByType(const KMime::Message::Ptr &data, const QByteAr
         Error() << "Empty type";
         return 0;
     }
-    const KMime::Content::List list = data->contents();
-    //     qDebug() << list.size();
-    Q_FOREACH(KMime::Content *c, list)
-    {
-        //         qDebug() << c->contentType()->mimeType() << type;
-        if (c->contentType()->mimeType() ==  type)
+    Q_FOREACH(KMime::Content *c, data->contents()) {
+//         qDebug() << c->contentType()->mimeType() << type;
+        if (c->contentType()->mimeType() ==  type) {
             return c;
+        }
     }
     return 0;
-    
 }
 
 KMime::Content* findContentByName(const KMime::Message::Ptr &data, const QString &name, QByteArray &type)
 {
-    const KMime::Content::List list = data->contents();
-    Q_FOREACH(KMime::Content *c, list) {
+    Q_FOREACH(KMime::Content *c, data->contents()) {
 //         kDebug() << "searching: " << c->contentType()->name();
         if ( c->contentType()->name() == name ) {
             type = c->contentType()->mimeType();
@@ -65,8 +61,7 @@ KMime::Content* findContentById(const KMime::Message::Ptr &data, const QByteArra
         Error() << "looking for empty cid";
         return 0;
     }
-    const KMime::Content::List list = data->contents();
-    Q_FOREACH(KMime::Content *c, list) {
+    Q_FOREACH(KMime::Content *c, data->contents()) {
 //         kDebug() << "searching: " << c->contentID()->identifier();
         if ( c->contentID()->identifier() == id ) {
             type = c->contentType()->mimeType();
@@ -80,8 +75,7 @@ KMime::Content* findContentById(const KMime::Message::Ptr &data, const QByteArra
 
 QByteArray getXmlDocument(const KMime::Message::Ptr &data, const QByteArray &mimetype)
 {
-    KMime::Content *xmlContent = findContentByType( data, mimetype );
-    if ( xmlContent ) {
+    if ( KMime::Content *xmlContent = findContentByType( data, mimetype ) ) {
         return xmlContent->decodedContent();
     }
     Error() << "document not found";


commit dddf11a5fbec412442e0b0bc81b88622adb6fc35
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Jun 6 00:13:15 2012 +0200

    Note conversion test.

diff --git a/tests/formattest.cpp b/tests/formattest.cpp
index 36d2ebe..6818187 100644
--- a/tests/formattest.cpp
+++ b/tests/formattest.cpp
@@ -31,10 +31,12 @@
 
 #include <kcalcore/icalformat.h>
 #include <kabc/vcardconverter.h>
+#include <akonadi/notes/noteutils.h>
 
 #include "testutils.h"
 #include "kolabformat/kolabobject.h"
 #include "kolabformat/errorhandler.h"
+#include "kolabformat/kolabdefinitions.h"
 
 void normalizeMimemessage(QString &content)
 {
@@ -44,6 +46,10 @@ void normalizeMimemessage(QString &content)
     content.replace(QRegExp("\\bLibkolabxml-\\d.\\d\\b", Qt::CaseSensitive), "Libkolabxml-x.x.x");
     content.replace(QRegExp("<uri>cid:*@kolab.resource.akonadi</uri>", Qt::CaseSensitive, QRegExp::Wildcard), "<uri>cid:id at kolab.resource.akonadi</uri>");
     content.replace(QRegExp("<last-modification-date>*</last-modification-date>", Qt::CaseSensitive, QRegExp::Wildcard), "<last-modification-date></last-modification-date>");
+
+    content.replace(QRegExp("--nextPart\\S*", Qt::CaseSensitive), "--part");
+    content.replace(QRegExp("\\bboundary=\"nextPart[^\\n]*", Qt::CaseSensitive), "boundary");
+    content.replace(QRegExp("Date[^\\n]*", Qt::CaseSensitive), "Date");
 }
 
 static bool compareMimeMessage( const KMime::Message::Ptr &msg, const KMime::Message::Ptr &expectedMsg )
@@ -56,7 +62,7 @@ static bool compareMimeMessage( const KMime::Message::Ptr &msg, const KMime::Mes
         KCOMPARE( msg->from()->mailboxes().first().address(), expectedMsg->from()->mailboxes().first().address() ); // matching address is enough, we don't need a display name
     }
     KCOMPARE( msg->contentType()->mimeType(), expectedMsg->contentType()->mimeType() );
-    KCOMPARE( msg->headerByType( "X-Kolab-Type" )->as7BitString(), expectedMsg->headerByType( "X-Kolab-Type" )->as7BitString() );
+    KCOMPARE( msg->headerByType( X_KOLAB_TYPE_HEADER )->as7BitString(), expectedMsg->headerByType( X_KOLAB_TYPE_HEADER )->as7BitString() );
     // date contains conversion time...
     //   KCOMPARE( msg->date()->asUnicodeString(), expectedMsg->date()->asUnicodeString() );
     
@@ -271,6 +277,62 @@ void FormatTest::testContact()
 }
 
 
+void FormatTest::testNote_data()
+{
+    QTest::addColumn<Kolab::Version>( "version" );
+    QTest::addColumn<Kolab::ObjectType>( "type" );
+    QTest::addColumn<QString>( "noteFileName" );
+    QTest::addColumn<QString>( "mimeFileName" );
+
+    QTest::newRow( "v3noteSimple" ) << Kolab::KolabV3 << Kolab::NoteObject << TESTFILEDIR+QString::fromLatin1("v3/note/note.mime") << TESTFILEDIR+QString::fromLatin1("v3/note/note.mime.mime");
+}
+
+
+void FormatTest::testNote()
+{
+    QFETCH( Kolab::Version, version );
+    QFETCH( Kolab::ObjectType, type );
+    QFETCH( QString, noteFileName ); //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);
+
+    KMime::Message::Ptr convertedNote = reader.getNote();
+    QVERIFY(convertedNote.get());
+
+    //Parse note
+    const KMime::Message::Ptr &realNote = readMimeFile( noteFileName, ok );
+    QVERIFY(ok);
+    QVERIFY(realNote.get());
+
+    QString expected = realNote->encodedContent();
+    normalizeMimemessage(expected);
+    QString converted = convertedNote->encodedContent();
+    normalizeMimemessage(converted);
+    showDiff(expected, converted);
+    
+    //Write
+    const KMime::Message::Ptr &convertedMime = Kolab::KolabObjectWriter::writeNote(realNote, version);
+    QVERIFY(convertedMime.get());
+    QVERIFY(msg.get());
+
+    QString expected2 = msg->encodedContent();
+    normalizeMimemessage(expected2);
+    QString converted2 = convertedMime->encodedContent();
+    normalizeMimemessage(converted2);
+    showDiff(expected2, converted2);
+
+    QCOMPARE(Kolab::ErrorHandler::instance().error(), Kolab::ErrorHandler::Debug);
+}
+
+
 //This function exists only to generate the reference files, it's not a real test.
 void FormatTest::generateMimefile()
 {
diff --git a/tests/formattest.h b/tests/formattest.h
index 92b285f..bf90f6c 100644
--- a/tests/formattest.h
+++ b/tests/formattest.h
@@ -58,6 +58,8 @@ private slots:
     void testContact_data();
     void testContact();
 
+    void testNote_data();
+    void testNote();
 
     //Some pseudo tests and helper functions
     void generateMimefile();
diff --git a/tests/testfiles/v3/note/note.mime b/tests/testfiles/v3/note/note.mime
new file mode 100644
index 0000000..3c25ece
--- /dev/null
+++ b/tests/testfiles/v3/note/note.mime
@@ -0,0 +1,10 @@
+Subject: title
+Content-Type: text/plain
+Date: Sat, 05 May 2012 05:05:05 +0000
+From: kolab at kde4
+X-Akonotes-LastModified: Sat, 05 May 2012 05:05:06 +0000
+X-Akonotes-UID: c04ad759-ff7f-0000-e12b-a41f537f0000
+X-Akonotes-Classification: Public
+MIME-Version: 1.0
+
+text
\ No newline at end of file
diff --git a/tests/testfiles/v3/note/note.mime.mime b/tests/testfiles/v3/note/note.mime.mime
new file mode 100644
index 0000000..bfb5968
--- /dev/null
+++ b/tests/testfiles/v3/note/note.mime.mime
@@ -0,0 +1,46 @@
+Date: Fri, 27 Apr 2012 23:36:50 +0200
+X-Kolab-Type: application/x-vnd.kolab.note
+X-Kolab-Mime-Version: 3.0
+User-Agent: Libkolab-0.2.0
+Content-Type: multipart/mixed; boundary="nextPart2028861.pg0urxaLml"
+Subject: title
+MIME-Version: 1.0
+
+
+--nextPart2028861.pg0urxaLml
+Content-Type: text/plain; charset="us-ascii"
+Content-Transfer-Encoding: 7Bit
+
+This is a Kolab Groupware object.
+To view this object you will need an email client that can understand the Kolab Groupware format.
+For a list of such email clients please visit
+http://www.kolab.org/get-kolab
+
+--nextPart2028861.pg0urxaLml
+Content-Type: application/vnd.kolab+xml; name="kolab.xml"
+Content-Transfer-Encoding: quoted-printable
+Content-Disposition: attachment; filename="kolab.xml"
+
+<?xml version=3D"1.0" encoding=3D"UTF-8" standalone=3D"no" ?>
+<note xmlns=3D"http://kolab.org" version=3D"3.0dev1">
+
+  <uid>c04ad759-ff7f-0000-e12b-a41f537f0000</uid>
+
+  <prodid>Libkolab-0.2.0 Libkolabxml-0.4.0</prodid>
+
+  <creation-date>2012-05-05T05:05:05Z</creation-date>
+
+  <last-modification-date>2012-05-05T05:05:06Z</last-modification-date>=
+
+
+  <classification>PUBLIC</classification>
+
+  <summary>title</summary>
+
+  <description>text</description>
+
+  <color/>
+
+</note>
+
+--nextPart2028861.pg0urxaLml--


commit 0426e00dc6404d79c7bdac8ef4c4a8119c2a8ea5
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Wed Jun 6 00:12:47 2012 +0200

    Convert all note fields (KDE 4.9 required).
    
    Compiled conditionally to avoid dependency on kde 4.9

diff --git a/CMakeLists.txt b/CMakeLists.txt
index b8ef17e..f26b32d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -48,6 +48,13 @@ find_package(KDE4 4.8 REQUIRED)
 find_package(KdepimLibs 4.8 REQUIRED)
 find_package(Libkolabxml 0.6 REQUIRED)
 
+# add_definitions(-DKDEPIMLIBS_VERSION=0x${KdepimLibs_VERSION_MAJOR}0${KdepimLibs_VERSION_MINOR}${KDEPIMLIBS_VERSION_PATCH})
+# add_definitions( -DKDEPIMLIBS_VERSION=((${KdepimLibs_VERSION_MAJOR}<<16)|(${KdepimLibs_VERSION_MINOR}<<8)|(${KDEPIMLIBS_VERSION_PATCH})) )
+
+if("${KdepimLibs_VERSION}" VERSION_GREATER "4.8.40" )
+    add_definitions(-DKDEPIMLIBS_VERSION_DEVEL)
+endif()
+
 set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS} -fPIC" )
 
 include_directories(    
diff --git a/conversion/kolabconversion.cpp b/conversion/kolabconversion.cpp
index e13e28e..4952b02 100644
--- a/conversion/kolabconversion.cpp
+++ b/conversion/kolabconversion.cpp
@@ -29,7 +29,48 @@ Note fromNote(const KMime::Message::Ptr &m)
     Note n;
     n.setSummary(note.title().toStdString());
     n.setDescription(note.text().toStdString());
-    n.setCreated(fromDate(note.creationDate()));
+    KDateTime created = note.creationDate();
+    created.setTimeSpec(KDateTime::UTC);
+    n.setCreated(fromDate(created));
+
+// #if KDEPIMLIBS_VERSION >= 0x040840
+#ifdef KDEPIMLIBS_VERSION_DEVEL
+    n.setUid(note.uid().toStdString());
+    KDateTime lastModified = note.lastModifiedDate();
+    lastModified.setTimeSpec(KDateTime::UTC);
+    n.setLastModified(fromDate(lastModified));
+    
+    switch (note.classification()) {
+        case Akonadi::NoteUtils::NoteMessageWrapper::Confidential:
+            n.setClassification(Kolab::ClassConfidential);
+            break;
+        case Akonadi::NoteUtils::NoteMessageWrapper::Private:
+            n.setClassification(Kolab::ClassPrivate);
+            break;
+        default:
+            n.setClassification(Kolab::ClassPublic);
+    }
+    
+    std::vector<Kolab::CustomProperty> customs;
+    for (QMap <QString, QString >::const_iterator it = note.custom().begin(); it != note.custom().end(); it ++) {
+        customs.push_back(Kolab::CustomProperty(it.key().toStdString(), it.value().toStdString()));
+    }
+    n.setCustomProperties(customs);
+    
+    std::vector<Kolab::Attachment> attachments;
+    foreach(const Akonadi::NoteUtils::Attachment &a, note.attachments()) {
+        Kolab::Attachment attachment;
+        if (a.url().isValid()) {
+            attachment.setUri(a.url().toString().toStdString(), a.mimetype().toStdString());
+        } else {
+            attachment.setData(QString(a.data()).toStdString(), a.mimetype().toStdString());
+        }
+        attachment.setLabel(a.label().toStdString());
+        attachments.push_back(attachment);
+    }
+    n.setAttachments(attachments);
+
+#endif
     return n;
 }
 
@@ -40,6 +81,35 @@ KMime::Message::Ptr toNote(const Note &n)
     note.setText(QString::fromStdString(n.description()));
     note.setFrom("kolab at kde4");
     note.setCreationDate(toDate(n.created()));
+#ifdef KDEPIMLIBS_VERSION_DEVEL
+    note.setUid(QString::fromStdString(n.uid()));
+    note.setLastModifiedDate(toDate(n.lastModified()));
+    switch (n.classification()) {
+        case Kolab::ClassPrivate:
+            note.setClassification(Akonadi::NoteUtils::NoteMessageWrapper::Private);
+            break;
+        case Kolab::ClassConfidential:
+            note.setClassification(Akonadi::NoteUtils::NoteMessageWrapper::Confidential);
+            break;
+        default:
+            note.setClassification(Akonadi::NoteUtils::NoteMessageWrapper::Public);
+    }
+
+    foreach (const Kolab::Attachment &a, n.attachments()) {
+        if (!a.uri().empty()) {
+            Akonadi::NoteUtils::Attachment attachment(QUrl(QString::fromStdString(a.uri())), QString::fromStdString(a.mimetype()));
+            attachment.setLabel(QString::fromStdString(a.label()));
+            note.attachments().append(attachment);
+        } else {
+            Akonadi::NoteUtils::Attachment attachment(QString::fromStdString(a.data()).toLatin1(), QString::fromStdString(a.mimetype()));
+            attachment.setLabel(QString::fromStdString(a.label()));
+            note.attachments().append(attachment);
+        }
+    }
+    foreach (const Kolab::CustomProperty &a, n.customProperties()) {
+        note.custom().insert(QString::fromStdString(a.identifier), QString::fromStdString(a.value));
+    }
+#endif
     return note.message();
 }
 


commit 1e214a3601d71647cc2e653b8e3cac5b7a695c17
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Tue Jun 5 23:46:19 2012 +0200

    new kolab mimetype application/vnd.kolab+xml, renamed mime version header.

diff --git a/kolabformat/kolabdefinitions.h b/kolabformat/kolabdefinitions.h
index 410abb6..2fdcf70 100644
--- a/kolabformat/kolabdefinitions.h
+++ b/kolabformat/kolabdefinitions.h
@@ -28,14 +28,16 @@ namespace Kolab {
 #define KOLAB_FOLDER_TYPE_TASK    "task"
 #define KOLAB_FOLDER_TYPE_JOURNAL "journal"
 #define KOLAB_FOLDER_TYPE_NOTE    "note"
+#define KOLAB_FOLDER_TYPE_CONFIGURATION    "configuration"
 
 #define KOLAB_FOLDER_TYPE_DEFAULT_SUFFIX ".default"
 
 #define KOLAB_FOLDER_TYPE_ANNOTATION "/vendor/kolab/folder-type"
 
 #define X_KOLAB_TYPE_HEADER "X-Kolab-Type"
-#define X_KOLAB_VERSION_HEADER "X-Kolab-Version"
-#define KOLAB_VERSION_V3 "v3"
+#define X_KOLAB_MIME_VERSION_HEADER "X-Kolab-Mime-Version"
+#define X_KOLAB_MIME_VERSION_HEADER_COMPAT "X-Kolab-Version"
+#define KOLAB_VERSION_V3 "3.0"
 
 #define KOLAB_OBJECT_FILENAME "kolab.xml"
 
@@ -46,10 +48,12 @@ static QString contactKolabType() { return QString::fromLatin1("application/x-vn
 static QString distlistKolabType() { return QString::fromLatin1("application/x-vnd.kolab.contact.distlist"); }
 static QString distlistKolabTypeCompat() { return QString::fromLatin1("application/x-vnd.kolab.distribution-list"); }
 static QString noteKolabType() { return QString::fromLatin1("application/x-vnd.kolab.note"); }
+static QString configurationKolabType() { return QString::fromLatin1("application/x-vnd.kolab.configuration"); }
+static QString dictKolabType() { return QString::fromLatin1("application/x-vnd.kolab.configuration.dictionary"); }
 
 static QString xCalMimeType() { return QString::fromLatin1("application/calendar+xml"); };
 static QString xCardMimeType() { return QString::fromLatin1("application/vcard+xml"); };
-static QString noteMimeType() { return QString::fromLatin1("application/x-vnd.kolab.*"); };
+static QString kolabMimeType() { return QString::fromLatin1("application/vnd.kolab+xml"); };
 
 }
 
diff --git a/kolabformat/kolabobject.cpp b/kolabformat/kolabobject.cpp
index d078e8a..b46045b 100644
--- a/kolabformat/kolabobject.cpp
+++ b/kolabformat/kolabobject.cpp
@@ -110,7 +110,7 @@ QByteArray getMimeType(Kolab::ObjectType type)
         case DistlistObject:
             return xCardMimeType().toLocal8Bit();
         case NoteObject:
-            return noteMimeType().toLocal8Bit();
+            return kolabMimeType().toLocal8Bit();
         default:
             Critical() << "unknown type "<< type;
     }
@@ -128,13 +128,18 @@ ObjectType KolabObjectReader::parseMimeMessage(const KMime::Message::Ptr &msg)
     }
     const QString &kolabType = xKolabHeader->asUnicodeString(); //TODO we probably shouldn't use unicodeString
     
-    KMime::Headers::Base *xKolabVersion = msg->getHeaderByType(X_KOLAB_VERSION_HEADER); //TODO make sure v3 is written out
+    KMime::Headers::Base *xKolabVersion = msg->getHeaderByType(X_KOLAB_MIME_VERSION_HEADER);
+    if (!xKolabVersion) {
+        //For backwards compatibility to development versions, can be removed in future versions
+        xKolabVersion = msg->getHeaderByType(X_KOLAB_MIME_VERSION_HEADER_COMPAT);
+    }
     if (!xKolabVersion) {
         d->mVersion = KolabV2;
     } else {
-        if (xKolabVersion->asUnicodeString() == KOLAB_VERSION_V3) {
-            d->mVersion = KolabV3;
+        if (xKolabVersion->asUnicodeString() != KOLAB_VERSION_V3) { //TODO version compatibility check?
+            WARNING("Kolab Version Header available but not on the same version as the implementation");
         }
+        d->mVersion = KolabV3;
     }
     d->mObjectType = getObjectType(kolabType);
     if (d->mVersion == KolabV2) {
@@ -394,7 +399,7 @@ KMime::Message::Ptr KolabObjectWriter::writeNote(const KMime::Message::Ptr &note
         const Kolab::Note &n = Kolab::Conversion::fromNote(note);
         const std::string &v3String = Kolab::writeNote(n, getProductId(productId).toStdString());
         ErrorHandler::handleLibkolabxmlErrors();
-        return  Mime::createMessage(QString::fromStdString(n.summary()) ,noteMimeType(), noteKolabType(), QString::fromStdString(v3String).toLocal8Bit(), true, getProductId(productId));
+        return  Mime::createMessage(QString::fromStdString(n.summary()), kolabMimeType(), noteKolabType(), QString::fromStdString(v3String).toLocal8Bit(), true, getProductId(productId));
     }
     return noteToKolab(note, getProductId(productId));
 }
diff --git a/mime/mimeutils.cpp b/mime/mimeutils.cpp
index 355a3eb..28de780 100644
--- a/mime/mimeutils.cpp
+++ b/mime/mimeutils.cpp
@@ -202,7 +202,7 @@ KMime::Message::Ptr createMessage(const QString& xKolabType, bool v3, const QStr
     KMime::Headers::Generic *h = new KMime::Headers::Generic( X_KOLAB_TYPE_HEADER, message.get(), xKolabType, "utf-8" );
     message->appendHeader( h );
     if (v3) {
-        KMime::Headers::Generic *vh = new KMime::Headers::Generic( X_KOLAB_VERSION_HEADER, message.get(), KOLAB_VERSION_V3, "utf-8" );
+        KMime::Headers::Generic *vh = new KMime::Headers::Generic( X_KOLAB_MIME_VERSION_HEADER, message.get(), KOLAB_VERSION_V3, "utf-8" );
         message->appendHeader( vh );
     }
     message->userAgent()->from7BitString( prodid.toLatin1() );





More information about the commits mailing list