On Wed, 2010-09-08 at 13:32 +0200, Patrick Ohly wrote:
> Contacts
> ========
> 
> QtContacts:
> QContactLocalId, an integer,
> change notification via QContactManager signals
> 
> qtcontacts-tracker:
> nco::contactLocalUID, a Maemo/MeeGo extension of
> http://www.semanticdesktop.org/ontologies/nco/,
> custom QContactDetail mapped to nao::propertyName/Value,
> fuzzy phone number search implemented by storing normalized phone number
> in maemo::localPhoneNumber,
> detailed change notifications via
> SopranoLive::BackEnds::Tracker::ClassUpdateSignaler
> 
> QVersit:
> incomplete (?) subset of QContact
> 
> See
> http://gitorious.org/qtcontacts-tracker/qtcontacts-tracker/blobs/master/src/engine/contactsaverequest.cpp
> 
> Known issue: contact thumbnails are not stored
> (http://bugs.meego.com/show_bug.cgi?id=5879)
> 
> Question: are these extensions to the standard NCO documented
> somewhere public?

Mathias or Aleksandar, do you know?

> Question: there used to be documentation in QVersit about the mapping
> between vCard and QContact. Last time I looked, I only found that in the
> Google cache. Is that documentation still maintained somewhere?

Michael?

> Question: can someone provide an example of a full-featured contact (as
> many QContact details set as possible, including custom details) and how
> that is stored in Tracker and a vCard? 

I suppose it is do-it-yourself time again ;-)

Attached a test program, using current MeeGo Trunk
(libqtversit1-1.0.2-4.2.i586, libqtcontacts1-1.0.2-4.2.i586,
qtcontacts-tracker-4.8.8-1.6.i586). Output also attached.

Some comments about QVersit/QContacts. I suppose Michael (QtMobility)
and Sateesh (depends on QVersit for Buteo sync) would be in a good
position to answer.
     1. CATEGORIES is not valid in vCard 2.1. Is this an oversight or
        intentional? NICKNAME (vCard 3.0) and X-NICKNAME (vCard 2.1
        extension) are used correctly.
     2. Exporting the thumbnail data as VALUE=URL with an unspecified
        URL is not, eh, useful ;-) vCard is an interchange format, so
        data should IMHO be embedded inside it. In this case both is
        done, but I suspect that peers which expect PHOTO to be present
        only once will get confused by PHOTO;VALUE=URL:file://image
     3. How is QContactDisplayLabel created? The contact as stored in
        Tracker and retrieved later never gets a QContactDisplayLabel.
     4. Custom extensions are not getting mapped to vCard. We've
        discussed this in the context with Buteo before and agreed that
        there should be a default mapping that is used automatically.
        Does that still hold (Michael)? If not, how will Buteo map these
        extensions (Sateesh)? See also
        http://bugs.meego.com/show_bug.cgi?id=4897 and related issues.
     5. If QVersitReader::setDefaultCodec() is not called, what is the
        default? Is it always UTF-8 (as the debug output shows) or does
        that depend on env variables?
     6. I ran into strange errors when trying to read directly from a
        QByteArray with QVersitReader. See source code. Any ideas why
        the simpler code failed? I had to switch to the QBuffer method.
     7. CALURI, FBURL, LABEL do not seem to be supported. LABEL is kind
        of redundant, but CALURI and FBURL may be useful.
     8. Q_DECLARE_CUSTOM_CONTACT_DETAIL is mentioned, but not
        Q_IMPLEMENT_CUSTOM_CONTACT_DETAIL. Is the code for
        QContactFavourite correct? Current qtcontacts-tracker in MeeGo
        (4.8.8-1.6) does not yet support saving detail definitions
        (http://bugs.meego.com/show_bug.cgi?id=4893#c12). It sounded
        like they should be saved, but I cannot reproduce that. Mathias,
        should the "QContactDetail(name="MyFavourite", key=24,
        "MyFavourite"=QVariant(QString, "my favourite") )" detail be
        stored?

Regarding storing in Tracker, is there an easy way to dump the subgraph
starting at the contact ID? tracker-explorer helps, but sometimes it is
a bit hard to follow all connections.

One thing that surprised me is that all "WORK" related properties were
stored in an nco:affiliation. I have not found anything that marks that
affiliation as "work" (as in TYPE=WORK in vCard). Is that implicit?
Mathias?

A related question in this context: at which point will that affiliation
or other entities like mailto:[email protected] be removed? In particular the
later might be referenced by multiple different contacts. Perhaps I'm
not using the right vocabulary: what I mean is that RDFs with subject
"mailto:[email protected]"; may or may not become obsolete when the RDF
"contact:xyz nco:hasEmailAddress mailto:[email protected]"; gets removed.

Experiments show that mailto:[email protected] is not removed.

Connie, can you explain how meego-handset-people stores additional
information? For example, the "favourite" marker? I see that there are
"seaside" properties which contain additional "Comm*" properties, but I
don't find the "favourite" part in Tracker.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.

/*
 * Simple test program for QtVersit, QtContacts and qtcontacts-tracker.
 * Compile with:
 * g++ test-qtcontacts.cpp `pkg-config --cflags --libs QtContacts QtVersit QtCore QtGui`
 *
 * Part of SyncEvoltution QtContacts backend.
 *
 * This library 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 2.1 of the License, or (at your option) version 3.
 *
 * This library 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 library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301  USA
 */

/**
 * 
 */

#include <QContact>
#include <QContactManager>
#include <QContactFetchRequest>
#include <QContactRemoveRequest>
#include <QContactSaveRequest>
#include <QContactTimestamp>
#include <QContactAddress>
#include <QContactAvatar>
#include <QContactAnniversary>
#include <QContactBirthday>
#include <QContactEmailAddress>
#include <QContactFamily>
#include <QContactGender>
#include <QContactName>
#include <QContactNickname>
#include <QContactNote>
#include <QContactOrganization>
#include <QContactPhoneNumber>
#include <QContactTag>
#include <QContactThumbnail>
#include <QContactUrl>
#include <QContactLocalIdFilter>

#include <QVersitContactExporter>
#include <QVersitContactImporter>
#include <QVersitDocument>
#include <QVersitWriter>
#include <QVersitReader>

#include <QtGlobal>
#include <QtDebug>
#include <QByteArray>
#include <QBuffer>
#include <QApplication>
#include <QTextCodec>

#include <stdio.h>

using namespace QtMobility;

#ifdef QT_NO_DEBUG
# error must be compiled without QT_NO_DEBUG
#endif

static void dump(const QContact &contact, QVersitDocument::VersitType type)
{
    QVersitContactExporter exporter;
    Q_ASSERT(exporter.exportContacts(QList<QContact>() << contact, type));
    QByteArray vcard;
    QVersitWriter writer(&vcard);
    Q_ASSERT(writer.startWriting(exporter.documents()));
    writer.waitForFinished();
    qDebug() << vcard.constData();
}

static QImage testImage(20, 10, QImage::Format_Mono);

#if 0
// from testData below, but doesn't parse?
QImage::fromData(QByteArray::fromBase64(
    "9j/4AAQSkZJRgABAQEASABIAAD/4QAWRXhpZgAATU0AKgAA"
    "AAgAAAAAAAD//gAXQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q/9sAQwAFAwQEBAMFBAQEBQUFBgcM"
    "CAcHBwcPCwsJDBEPEhIRDxERExYcFxMUGhURERghGBodHR8fHxMXIiQiHiQcHh8e/9sAQwEF"
    "BQUHBgcOCAgOHhQRFB4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4e"
    "Hh4eHh4eHh4e/8AAEQgAFwAkAwEiAAIRAQMRAf/EABkAAQADAQEAAAAAAAAAAAAAAAAGBwgE"
    "Bf/EADIQAAECBQMCAwQLAAAAAAAAAAECBAADBQYRBxIhEzEUFSIIFjNBGCRHUVZ3lqXD0+P/"
    "xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMR"
    "AD8AuX6UehP45/aXv9MTPTLVKxNSvMPcqu+a+XdLxf1SfJ6fU37PioTnOxfbOMc/KIZ7U/2V"
    "fmTR/wCaKlu6+blu/Ui72zxWtUmmUOrTaWwkWDT09FPR4K587OVrUfVsIwElPPPAbAjxr2um"
    "hWXbDu5rmfeApLPZ4hx0lzNm9aUJ9KAVHKlJHAPf7ozPLqWt9y6Z0EPGmoLNjTq48a1iaybJ"
    "YV52yEtCms5KJmAT61JXtJyUdyQTEc1WlMql7N1/oZ6jagVZVFfUyZPpFy5lvWcxU7Z03BUk"
    "GZLWJqVhPYLkIIPBEBtSEUyNAsjI1q1m/VP+UICwL/sqlXp7v+aOHsnyGttq218MtKd8+Ru2"
    "JXuScoO45Awe2CIi96aKW1cVyubkYVy6rTqz0J8a5t2qqZl0UjAMwYKScfPAJ+cIQHHP0Dth"
    "VFaMWt0XwxetnM50Ks2rsxL6ZMnJlJmb5hBBBEiVxjA28dznqo+hdksbQuS3Hs6tVtNzdM1Z"
    "/VH5nO3Bl/CJmYHKDynjv3zCEB5rLQNo0bIbydWNWxKljbLQLoWkISOAkBKAABCEID//2Q==")));
#endif

static const char simpleTestData[] =
    "BEGIN:VCARD\r\n"
    "VERSION:3.0\r\n"
    "FN:John Doe\r\n"
    "N:Doe;John;;;\r\n"
    "END:VCARD\r\n";

static const char testData[] = 
    "BEGIN:VCARD\n"
    "VERSION:3.0\n"
    "URL:http://john.doe.com\n";
    "TITLE:Senior Tester\n"
    "ORG:Test Inc.;Testing;test#1\n"
    "ROLE:professional test case\n"
    "X-MANAGER:John Doe Senior\n"
    "X-ASSISTANT:John Doe Junior\n"
    "NICKNAME:user1\n"
    "BDAY:2006-01-08\n"
    "X-ANNIVERSARY:2006-01-09\n"
    "X-SPOUSE:Joan Doe\n"
    "NOTE:This is a test case which uses almost all Evolution fields.\n"
    "FN:John Doe\n"
    "N:Doe;John;;;\n"
    "CATEGORIES:TEST\n"
    "X-BLOG-URL:web log\n"
    "CALURI:calender\n"
    "FBURL:free/busy\n"
    "X-VIDEO-URL:chat\n"
    "X-MOZILLA-HTML:TRUE\n"
    "ADR;TYPE=WORK:Test Box #2;;Test Drive 2;Test Town;Upper Test County;12346;O\n"
    " ld Testovia\n"
    "LABEL;TYPE=WORK:Test Drive 2\\nTest Town\\, Upper Test County\\n12346\\nTest Bo\n"
    " x #2\\nOld Testovia\n"
    "ADR;TYPE=HOME:Test Box #1;;Test Drive 1;Test Village;Lower Test County;1234\n"
    " 5;Testovia\n"
    "LABEL;TYPE=HOME:Test Drive 1\\nTest Village\\, Lower Test County\\n12345\\nTest\n"
    "  Box #1\\nTestovia\n"
    "ADR:Test Box #3;;Test Drive 3;Test Megacity;Test County;12347;New Testonia\n"
    "LABEL;TYPE=OTHER:Test Drive 3\\nTest Megacity\\, Test County\\n12347\\nTest Box\n"
    "  #3\\nNew Testonia\n"
    "UID:pas-id-43C0ED3900000001\n"
    "EMAIL;TYPE=WORK:[email protected]\n"
    "EMAIL;TYPE=HOME:[email protected]\n"
    "EMAIL;TYPE=OTHER:[email protected]\n"
    "EMAIL;TYPE=OTHER:[email protected]\n"
    "TEL;TYPE=work;TYPE=Voice:business 1\n"
    "TEL;TYPE=homE;TYPE=VOICE:home 2\n"
    "TEL;TYPE=CELL:mobile 3\n"
    "TEL;TYPE=WORK;TYPE=FAX:businessfax 4\n"
    "TEL;TYPE=HOME;TYPE=FAX:homefax 5\n"
    "TEL;TYPE=PAGER:pager 6\n"
    "TEL;TYPE=CAR:car 7\n"
    "TEL;TYPE=PREF:primary 8\n"
    "X-AIM;TYPE=HOME:AIM JOHN\n"
    "X-YAHOO;TYPE=HOME:YAHOO JDOE\n"
    "X-ICQ;TYPE=HOME:ICQ JD\n"
    "X-GROUPWISE;TYPE=HOME:GROUPWISE DOE\n"
    "PHOTO;ENCODING=b;TYPE=JPEG:/9j/4AAQSkZJRgABAQEASABIAAD/4QAWRXhpZgAATU0AKgAA\n"
    " AAgAAAAAAAD//gAXQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q/9sAQwAFAwQEBAMFBAQEBQUFBgcM\n"
    " CAcHBwcPCwsJDBEPEhIRDxERExYcFxMUGhURERghGBodHR8fHxMXIiQiHiQcHh8e/9sAQwEF\n"
    " BQUHBgcOCAgOHhQRFB4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4e\n"
    " Hh4eHh4eHh4e/8AAEQgAFwAkAwEiAAIRAQMRAf/EABkAAQADAQEAAAAAAAAAAAAAAAAGBwgE\n"
    " Bf/EADIQAAECBQMCAwQLAAAAAAAAAAECBAADBQYRBxIhEzEUFSIIFjNBGCRHUVZ3lqXD0+P/\n"
    " xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMR\n"
    " AD8AuX6UehP45/aXv9MTPTLVKxNSvMPcqu+a+XdLxf1SfJ6fU37PioTnOxfbOMc/KIZ7U/2V\n"
    " fmTR/wCaKlu6+blu/Ui72zxWtUmmUOrTaWwkWDT09FPR4K587OVrUfVsIwElPPPAbAjxr2um\n"
    " hWXbDu5rmfeApLPZ4hx0lzNm9aUJ9KAVHKlJHAPf7ozPLqWt9y6Z0EPGmoLNjTq48a1iaybJ\n"
    " YV52yEtCms5KJmAT61JXtJyUdyQTEc1WlMql7N1/oZ6jagVZVFfUyZPpFy5lvWcxU7Z03BUk\n"
    " GZLWJqVhPYLkIIPBEBtSEUyNAsjI1q1m/VP+UICwL/sqlXp7v+aOHsnyGttq218MtKd8+Ru2\n"
    " JXuScoO45Awe2CIi96aKW1cVyubkYVy6rTqz0J8a5t2qqZl0UjAMwYKScfPAJ+cIQHHP0Dth\n"
    " VFaMWt0XwxetnM50Ks2rsxL6ZMnJlJmb5hBBBEiVxjA28dznqo+hdksbQuS3Hs6tVtNzdM1Z\n"
    " /VH5nO3Bl/CJmYHKDynjv3zCEB5rLQNo0bIbydWNWxKljbLQLoWkISOAkBKAABCEID//2Q==\n"
    "END:VCARD\n";


class Q_CONTACTS_EXPORT QContactFavourite : public QContactDetail
{
public:
    Q_DECLARE_CUSTOM_CONTACT_DETAIL(QContactFavourite, "MyFavourite")
    Q_DECLARE_LATIN1_CONSTANT(FieldFavourite, "MyFavourite");

    void setFavourite(const QString &favourite) { setValue(FieldFavourite, favourite); }
    QString favorite() const { return value(FieldFavourite); }
};

Q_IMPLEMENT_CUSTOM_CONTACT_DETAIL(QContactFavourite, "MyFavourite");
Q_DEFINE_LATIN1_CONSTANT(QContactFavourite::FieldFavourite, "MyFavourite");

int main(int argc, char **argv)
{
    QApplication app(argc, argv);
    testImage.fill(0);

    QContactManager *manager(QContactManager::fromUri(QString("qtcontacts:tracker:")));
    QContact contact;

    // TODO: TypeGroup
    contact.setType(QContactType::TypeContact);

    // home address
    QContactAddress addressA;
    addressA.setCountry("Country A");
    addressA.setLocality("Locality A");
    addressA.setPostOfficeBox("Post office box A");
    addressA.setPostcode("Post code A");
    addressA.setRegion("Region A");
    addressA.setStreet("Street A");
    // SubTypeDomestic, SubTypeInternational, 
    addressA.setSubTypes(QContactAddress::SubTypePostal);
    addressA.setContexts(QContactDetail::ContextHome);
    Q_ASSERT(contact.saveDetail(&addressA));
     
    // work parcel address
    QContactAddress addressB;
    addressB.setCountry("Country B");
    addressB.setLocality("Locality B");
    addressB.setPostOfficeBox("Post office box B");
    addressB.setPostcode("Post code B");
    addressB.setRegion("Region B");
    addressB.setStreet("Street B");
    // SubTypeDomestic, SubTypeInternational, 
    addressB.setSubTypes(QContactAddress::SubTypeParcel);
    addressB.setContexts(QContactDetail::ContextWork);
    Q_ASSERT(contact.saveDetail(&addressB));
 
    QContactAnniversary anniversary;
    anniversary.setCalendarId("calendar ID");
    anniversary.setEvent("anniversary");
    anniversary.setOriginalDate(QDate(2010, 01, 31));
    // SubTypeEmployment, SubTypeEngagement, SubTypeMemorial
    anniversary.setSubType(QContactAnniversary::SubTypeWedding);
    Q_ASSERT(contact.saveDetail(&anniversary));

    QContactAvatar avatar;
    avatar.setImageUrl(QUrl("file://image"));
    avatar.setVideoUrl(QUrl("file://video"));
    Q_ASSERT(contact.saveDetail(&avatar));

    QContactBirthday birthday;
    birthday.setDate(QDate(2000, 01, 15));
    Q_ASSERT(contact.saveDetail(&birthday));

    QContactEmailAddress email_work;
    email_work.setEmailAddress("[email protected]");
    email_work.setContexts(QContactDetail::ContextWork);
    Q_ASSERT(contact.saveDetail(&email_work));

    QContactEmailAddress email_home;
    email_home.setEmailAddress("[email protected]");
    email_home.setContexts(QContactDetail::ContextHome);
    Q_ASSERT(contact.saveDetail(&email_home));

    QContactFamily family;
    family.setChildren(QStringList() << "Joe" << "Joan");
    family.setSpouse("Jane");
    Q_ASSERT(contact.saveDetail(&family));

    QContactGender gender;
    // GenderFemale, GenderUnspecified
    gender.setGender(QContactGender::GenderMale);
    Q_ASSERT(contact.saveDetail(&gender));

    // QContactGeoLocation, QContactGlobalPresence

    QContactName name;
    name.setCustomLabel("Label");
    name.setFirstName("John");
    name.setLastName("Doe");
    name.setPrefix("Mr.");
    name.setSuffix("Sr.");
    Q_ASSERT(contact.saveDetail(&name));

    // QContactDisplayLabel label;
    // label.setLabel("John Doe");
    // Q_ASSERT(contact.saveDetail(&label));

    QContactNickname nick;
    nick.setNickname("Johnny Walker");
    Q_ASSERT(contact.saveDetail(&nick));

    QContactNote note;
    note.setNote("note: this is a dummy contact");
    Q_ASSERT(contact.saveDetail(&note));

    // QContactOnlineAccount
    // meego-handset-people has to use something else,
    // QContactOnlineAccount was too limited.

    QContactOrganization org;
    org.setAssistantName("assistant");
    org.setDepartment(QStringList() << "foo group" << "bar unit" << "xyz team");
    org.setLocation("loc");
    org.setLogoUrl(QUrl("http://acme.com/icon.png";));
    org.setName("ACME");
    org.setRole("manager");
    org.setTitle("CEO");
    Q_ASSERT(contact.saveDetail(&org));


    QContactPhoneNumber voice;
    voice.setNumber("1234");
    voice.setSubTypes(QStringList() <<
                      QContactPhoneNumber::SubTypeVoice <<
                      QContactPhoneNumber::SubTypeLandline);
    voice.setContexts(QContactDetail::ContextHome);
    Q_ASSERT(contact.saveDetail(&voice));

    QContactPhoneNumber mobile;
    mobile.setNumber("5678");
    mobile.setSubTypes(QStringList() <<
                       QContactPhoneNumber::SubTypeVoice <<
                       QContactPhoneNumber::SubTypeMobile);
    mobile.setContexts(QContactDetail::ContextWork);
    Q_ASSERT(contact.saveDetail(&mobile));

    QContactPhoneNumber fax;
    fax.setNumber("5678");
    fax.setSubTypes(QStringList() <<
                    QContactPhoneNumber::SubTypeFax);
    fax.setContexts(QContactDetail::ContextWork);
    Q_ASSERT(contact.saveDetail(&fax));

    // preferred telephone? TYPE=PREF in vCard 

    // QContactRingtone
    // QContactSyncTarget
    
    QContactTag tag;
    tag.setTag("favorite");
    Q_ASSERT(contact.saveDetail(&tag));
    tag.setTag("work");
    Q_ASSERT(contact.saveDetail(&tag));

    QContactThumbnail thumbnail;
    thumbnail.setThumbnail(testImage);
    qDebug() << "test image:" << testImage.width() << testImage.height();
    Q_ASSERT(contact.saveDetail(&thumbnail));

    QContactUrl url_fav;
    url_fav.setUrl("http://favorite.com";);
    url_fav.setSubType(QContactUrl::SubTypeFavourite);
    Q_ASSERT(contact.saveDetail(&url_fav));

    QContactUrl url_homepage;
    url_homepage.setUrl("http://john.doe.name";);
    url_homepage.setSubType(QContactUrl::SubTypeHomePage);
    Q_ASSERT(contact.saveDetail(&url_homepage));

    // custom detail
    QContactFavourite favourite;
    favourite.setFavourite("my favourite");
    Q_ASSERT(contact.saveDetail(&favourite));

    QContactDetailDefinition favouriteDefinition;
    favouriteDefinition.setName(QContactFavourite::DefinitionName);
    favouriteDefinition.setUnique(true);
    QContactDetailFieldDefinition fieldFavourite;
    fieldFavourite.setDataType(QVariant::String);
    favouriteDefinition.insertField(QContactFavourite::FieldFavourite, fieldFavourite);
    // Q_ASSERT(manager->saveDetailDefinition(favouriteDefinition, QContactType::TypeContact));
    // not supported by qtcontacts-tracker (http://bugs.meego.com/show_bug.cgi?id=4893#c12)
    

    // not covered:
    // - relationships

    // QContactDisplayLabel cannot be set, but it is also not synthesized either?
    qDebug() << "Original QContact" << contact.detail<QContactDisplayLabel>();
    qDebug() << contact;
    qDebug() << "Converted to vCard 3.0:";
    dump(contact, QVersitDocument::VCard30Type);
    qDebug() << "Converted to vCard 2.1:";
    dump(contact, QVersitDocument::VCard21Type);

    QContactSaveRequest save;
    save.setManager(manager);
    save.setContacts(QList<QContact>() << contact);
    save.start();
    save.waitForFinished();
    Q_ASSERT(!save.error());

    QContactFetchRequest fetch;
    fetch.setManager(manager);
    QContactLocalIdFilter filter;
    filter.setIds(QList<QContactLocalId>() << save.contacts().first().localId());
    fetch.setFilter(filter);
    fetch.start();
    fetch.waitForFinished();
    QContact fetched = fetch.contacts().first();

    qDebug() << "Stored in Tracker and retrieved again:";
    qDebug() << fetched;

    qDebug() << "Parsing vCard 3.0:\n" << testData;

    // QVersitReader reader(QByteArray(simpleTestData));
    //
    // Huh? Fails to compile?!
    // => test-qtcontacts.cpp:311:5: error: request for member 'startReading' in 'reader', which is of non-class type 'QtMobility::QVersitReader(QByteArray)'

    // QVersitReader reader;
    // reader.setData(QByteArray(simpleTestData));
    //
    // Compiles, but startReading() fails?!

    QVersitReader reader;
    QBuffer input;
    input.open(QBuffer::ReadWrite);
    input.write(testData);
    input.seek(0);
    reader.setDevice(&input);
    if (reader.defaultCodec()) {
        qDebug() << "default codec:" << reader.defaultCodec()->name();
    }
    Q_ASSERT(reader.startReading());
    reader.waitForFinished();
    QVersitContactImporter importer;
    Q_ASSERT(importer.importDocuments(reader.results()));
    QList<QContact> contacts = importer.contacts();
    QContact &imported = contacts.first();

    qDebug() << "Converted into:";
    qDebug() << imported;

    return 0;
}
: initializing  
test image: 20 10 
Original QContact QContactDetail(name="DisplayLabel", key=1, 
"Label"=QVariant(QString, "") )
QContact(QContactId("", 0)) 
 QContactDetail(name="DisplayLabel", key=1, "Label"=QVariant(QString, "") ) 
 QContactDetail(name="Type", key=3, "Type"=QVariant(QString, "Contact") ) 
 QContactDetail(name="Address", key=4, "Context"=QVariant(QStringList, ("Home") 
) , "Country"=QVariant(QString, "Country A") , "Locality"=QVariant(QString, 
"Locality A") , "PostOfficeBox"=QVariant(QString, "Post office box A") , 
"Postcode"=QVariant(QString, "Post code A") , "Region"=QVariant(QString, 
"Region A") , "Street"=QVariant(QString, "Street A") , 
"SubTypes"=QVariant(QStringList, ("Postal") ) ) 
 QContactDetail(name="Address", key=5, "Context"=QVariant(QStringList, ("Work") 
) , "Country"=QVariant(QString, "Country B") , "Locality"=QVariant(QString, 
"Locality B") , "PostOfficeBox"=QVariant(QString, "Post office box B") , 
"Postcode"=QVariant(QString, "Post code B") , "Region"=QVariant(QString, 
"Region B") , "Street"=QVariant(QString, "Street B") , 
"SubTypes"=QVariant(QStringList, ("Parcel") ) ) 
 QContactDetail(name="Anniversary", key=6, "CalendarId"=QVariant(QString, 
"calendar ID") , "Event"=QVariant(QString, "anniversary") , 
"OriginalDate"=QVariant(QDate, QDate("Sun Jan 31 2010") ) , 
"SubType"=QVariant(QString, "Wedding") ) 
 QContactDetail(name="Avatar", key=7, "ImageUrl"=QVariant(QUrl, 
QUrl("file://image") ) , "VideoUrl"=QVariant(QUrl, QUrl("file://video") ) ) 
 QContactDetail(name="Birthday", key=8, "Birthday"=QVariant(QDate, QDate("Sat 
Jan 15 2000") ) ) 
 QContactDetail(name="EmailAddress", key=9, "Context"=QVariant(QStringList, 
("Work") ) , "EmailAddress"=QVariant(QString, "[email protected]") ) 
 QContactDetail(name="EmailAddress", key=10, "Context"=QVariant(QStringList, 
("Home") ) , "EmailAddress"=QVariant(QString, "[email protected]") ) 
 QContactDetail(name="Family", key=11, "Children"=QVariant(QStringList, ("Joe", 
"Joan") ) , "Spouse"=QVariant(QString, "Jane") ) 
 QContactDetail(name="Gender", key=12, "Gender"=QVariant(QString, "Male") ) 
 QContactDetail(name="Name", key=13, "CustomLabel"=QVariant(QString, "Label") , 
"FirstName"=QVariant(QString, "John") , "LastName"=QVariant(QString, "Doe") , 
"Prefix"=QVariant(QString, "Mr.") , "Suffix"=QVariant(QString, "Sr.") ) 
 QContactDetail(name="Nickname", key=14, "Nickname"=QVariant(QString, "Johnny 
Walker") ) 
 QContactDetail(name="Note", key=15, "Note"=QVariant(QString, "note: this is a 
dummy contact") ) 
 QContactDetail(name="Organization", key=16, "AssistantName"=QVariant(QString, 
"assistant") , "Department"=QVariant(QStringList, ("foo group", "bar unit", 
"xyz team") ) , "Location"=QVariant(QString, "loc") , "LogoUrl"=QVariant(QUrl, 
QUrl("http://acme.com/icon.png";) ) , "Name"=QVariant(QString, "ACME") , 
"Role"=QVariant(QString, "manager") , "Title"=QVariant(QString, "CEO") ) 
 QContactDetail(name="PhoneNumber", key=17, "Context"=QVariant(QStringList, 
("Home") ) , "PhoneNumber"=QVariant(QString, "1234") , 
"SubTypes"=QVariant(QStringList, ("Voice", "Landline") ) ) 
 QContactDetail(name="PhoneNumber", key=18, "Context"=QVariant(QStringList, 
("Work") ) , "PhoneNumber"=QVariant(QString, "5678") , 
"SubTypes"=QVariant(QStringList, ("Voice", "Mobile") ) ) 
 QContactDetail(name="PhoneNumber", key=19, "Context"=QVariant(QStringList, 
("Work") ) , "PhoneNumber"=QVariant(QString, "5678") , 
"SubTypes"=QVariant(QStringList, ("Fax") ) ) 
 QContactDetail(name="Tag", key=20, "Tag"=QVariant(QString, "work") ) 
 QContactDetail(name="Thumbnail", key=21, "Thumbnail"=QVariant(QImage, ) ) 
 QContactDetail(name="Url", key=22, "SubType"=QVariant(QString, "Favourite") , 
"Url"=QVariant(QString, "http://favorite.com";) ) 
 QContactDetail(name="Url", key=23, "SubType"=QVariant(QString, "HomePage") , 
"Url"=QVariant(QString, "http://john.doe.name";) ) 
 QContactDetail(name="MyFavourite", key=24, "MyFavourite"=QVariant(QString, "my 
favourite") )
Converted to vCard 3.0: 
BEGIN:VCARD
VERSION:3.0
FN:Label
ADR;TYPE=HOME,POSTAL:Post office box A;;Street A;Locality A;Region A;Post co
 de A;Country A
ADR;TYPE=WORK,PARCEL:Post office box B;;Street B;Locality B;Region B;Post co
 de B;Country B
X-ANNIVERSARY:2010-01-31
PHOTO;VALUE=URL:file://image
BDAY:2000-01-15
EMAIL;TYPE=WORK:[email protected]
EMAIL;TYPE=HOME:[email protected]
X-SPOUSE:Jane
X-CHILDREN:Joe,Joan
X-GENDER:Male
N:Doe;John;;Mr.;Sr.
NICKNAME:Johnny Walker
NOTE:note: this is a dummy contact
TITLE:CEO
ORG:ACME;foo group;bar unit;xyz team
LOGO;VALUE=URL:http://acme.com/icon.png
X-ASSISTANT:assistant
ROLE:manager
TEL;TYPE=HOME,VOICE:1234
TEL;TYPE=WORK,VOICE,CELL:5678
TEL;TYPE=WORK,FAX:5678
CATEGORIES:work
PHOTO;TYPE=PNG;ENCODING=b:iVBORw0KGgoAAAANSUhEUgAAABQAAAAKAQMAAACOm+ylAAAAA3
 NCSVQICAjb4U/gAAAABlBMVEUAAAD///+l2Z/dAAAACXBIWXMAAAuJAAALiQE3ycutAAAADElEQ
 VQImWNgIA4AAAAoAAFgSV8yAAAAAElFTkSuQmCC
URL:http://favorite.com
URL:http://john.doe.name
END:VCARD
 
Converted to vCard 2.1: 
BEGIN:VCARD
VERSION:2.1
FN:Label
ADR;HOME;POSTAL:Post office box A;;Street A;Locality A;Region A;Post code A;
 Country A
ADR;WORK;PARCEL:Post office box B;;Street B;Locality B;Region B;Post code B;
 Country B
X-ANNIVERSARY:2010-01-31
PHOTO;VALUE=URL:file://image
BDAY:2000-01-15
EMAIL;WORK;ENCODING=QUOTED-PRINTABLE:foo=40work.com
EMAIL;HOME;ENCODING=QUOTED-PRINTABLE:bar=40priv.org
X-SPOUSE:Jane
X-CHILDREN:Joe,Joan
X-GENDER:Male
N:Doe;John;;Mr.;Sr.
X-NICKNAME:Johnny Walker
NOTE:note: this is a dummy contact
TITLE:CEO
ORG:ACME;foo group;bar unit;xyz team
LOGO;VALUE=URL:http://acme.com/icon.png
X-ASSISTANT:assistant
ROLE:manager
TEL;HOME;VOICE:1234
TEL;WORK;VOICE;CELL:5678
TEL;WORK;FAX:5678
CATEGORIES:work
PHOTO;PNG;ENCODING=BASE64:
 iVBORw0KGgoAAAANSUhEUgAAABQAAAAKAQMAAACOm+ylAAAAA3NCSVQICAjb4U/gAAAABlBMVEU
 AAAD///+l2Z/dAAAACXBIWXMAAAuJAAALiQE3ycutAAAADElEQVQImWNgIA4AAAAoAAFgSV8yAA
 AAAElFTkSuQmCC

URL:http://favorite.com
URL:http://john.doe.name
END:VCARD
 
Stored in Tracker and retrieved again: 
QContact(QContactId("qtcontacts:tracker:", 101202484)) 
 QContactDetail(name="DisplayLabel", key=54, "Label"=QVariant(QString, "Label") 
) 
 QContactDetail(name="Type", key=2, "Type"=QVariant(QString, "Contact") ) 
 QContactDetail(name="Avatar", key=33, "DetailUri"=QVariant(QString, 
"contact:101202484#Avatar") , "ImageUrl"=QVariant(QUrl, QUrl("file://image") ) 
) 
 QContactDetail(name="Birthday", key=34, "Birthday"=QVariant(QDate, QDate("Sat 
Jan 15 2000") ) , "DetailUri"=QVariant(QString, "contact:101202484#Birthday") ) 
 QContactDetail(name="Gender", key=35, "DetailUri"=QVariant(QString, 
"contact:101202484#Gender") , "Gender"=QVariant(QString, "Male") ) 
 QContactDetail(name="Guid", key=36, "DetailUri"=QVariant(QString, 
"contact:101202484#Guid") , "Guid"=QVariant(QString, 
"a314ccac-93d0-4df6-80cc-6c7a32519e1d") ) 
 QContactDetail(name="Name", key=37, "CustomLabel"=QVariant(QString, "Label") , 
"DetailUri"=QVariant(QString, "contact:101202484#Name") , 
"FirstName"=QVariant(QString, "John") , "LastName"=QVariant(QString, "Doe") , 
"Prefix"=QVariant(QString, "Mr.") , "Suffix"=QVariant(QString, "Sr.") ) 
 QContactDetail(name="Nickname", key=38, "DetailUri"=QVariant(QString, 
"contact:101202484#Nickname") , "Nickname"=QVariant(QString, "Johnny Walker") ) 
 QContactDetail(name="Note", key=39, "DetailUri"=QVariant(QString, 
"contact:101202484#Note") , "Note"=QVariant(QString, "note: this is a dummy 
contact") ) 
 QContactDetail(name="Organization", key=40, "DetailUri"=QVariant(QString, 
"organization:101202484") , "Location"=QVariant(QString, "loc") , 
"LogoUrl"=QVariant(QUrl, QUrl("http://acme.com/icon.png";) ) , 
"Name"=QVariant(QString, "ACME") , "Role"=QVariant(QString, "manager") , 
"Title"=QVariant(QString, "CEO") ) 
 QContactDetail(name="Timestamp", key=41, 
"CreationTimestamp"=QVariant(QDateTime, QDateTime("Wed Sep 15 16:23:12 2010") ) 
, "DetailUri"=QVariant(QString, "contact:101202484#Timestamp") , 
"ModificationTimestamp"=QVariant(QDateTime, QDateTime("Wed Sep 15 16:23:12 
2010") ) ) 
 QContactDetail(name="Address", key=42, "Context"=QVariant(QStringList, 
("Home") ) , "Country"=QVariant(QString, "Country A") , 
"DetailUri"=QVariant(QString, "contact:101202484#Address-Home") , 
"Locality"=QVariant(QString, "Locality A") , "PostOfficeBox"=QVariant(QString, 
"Post office box A") , "Postcode"=QVariant(QString, "Post code A") , 
"Region"=QVariant(QString, "Region A") , "Street"=QVariant(QString, "Street A") 
, "SubTypes"=QVariant(QStringList, ("Postal") ) ) 
 QContactDetail(name="Address", key=43, "Context"=QVariant(QStringList, 
("Work") ) , "Country"=QVariant(QString, "Country B") , 
"DetailUri"=QVariant(QString, "contact:101202484#Address-Work") , 
"Locality"=QVariant(QString, "Locality B") , "PostOfficeBox"=QVariant(QString, 
"Post office box B") , "Postcode"=QVariant(QString, "Post code B") , 
"Region"=QVariant(QString, "Region B") , "Street"=QVariant(QString, "Street B") 
, "SubTypes"=QVariant(QStringList, ("Parcel", "Postal") ) ) 
 QContactDetail(name="EmailAddress", key=44, "Context"=QVariant(QStringList, 
("Home") ) , "DetailUri"=QVariant(QString, "mailto:[email protected]";) , 
"EmailAddress"=QVariant(QString, "[email protected]") ) 
 QContactDetail(name="EmailAddress", key=45, "Context"=QVariant(QStringList, 
("Work") ) , "DetailUri"=QVariant(QString, "mailto:[email protected]";) , 
"EmailAddress"=QVariant(QString, "[email protected]") ) 
 QContactDetail(name="PhoneNumber", key=46, "Context"=QVariant(QStringList, 
("Home") ) , "DetailUri"=QVariant(QString, "tel:1234") , 
"PhoneNumber"=QVariant(QString, "1234") , "SubTypes"=QVariant(QStringList, 
("Voice") ) ) 
 QContactDetail(name="PhoneNumber", key=47, "Context"=QVariant(QStringList, 
("Work") ) , "DetailUri"=QVariant(QString, "tel:5678") , 
"PhoneNumber"=QVariant(QString, "5678") , "SubTypes"=QVariant(QStringList, 
("Mobile", "MessagingCapable", "Fax", "Voice") ) ) 
 QContactDetail(name="Tag", key=48, "DetailUri"=QVariant(QString, 
"contact:101202484#Tag") , "Tag"=QVariant(QString, "addressbook") ) 
 QContactDetail(name="Tag", key=49, "DetailUri"=QVariant(QString, 
"contact:101202484#Tag") , "Tag"=QVariant(QString, "work") ) 
 QContactDetail(name="Url", key=50, "Context"=QVariant(QStringList, ("Home") ) 
, "DetailUri"=QVariant(QString, "contact:101202484#Url-Home") , 
"SubType"=QVariant(QString, "HomePage") , "Url"=QVariant(QString, 
"http://favorite.com";) ) 
 QContactDetail(name="Url", key=51, "Context"=QVariant(QStringList, ("Home") ) 
, "DetailUri"=QVariant(QString, "contact:101202484#Url-Home") , 
"SubType"=QVariant(QString, "HomePage") , "Url"=QVariant(QString, 
"http://john.doe.name";) )
Parsing vCard 3.0:
 BEGIN:VCARD
VERSION:3.0
URL:http://john.doe.com
TITLE:Senior Tester
ORG:Test Inc.;Testing;test#1
ROLE:professional test case
X-MANAGER:John Doe Senior
X-ASSISTANT:John Doe Junior
NICKNAME:user1
BDAY:2006-01-08
X-ANNIVERSARY:2006-01-09
X-SPOUSE:Joan Doe
NOTE:This is a test case which uses almost all Evolution fields.
FN:John Doe
N:Doe;John;;;
CATEGORIES:TEST
X-BLOG-URL:web log
CALURI:calender
FBURL:free/busy
X-VIDEO-URL:chat
X-MOZILLA-HTML:TRUE
ADR;TYPE=WORK:Test Box #2;;Test Drive 2;Test Town;Upper Test County;12346;O
 ld Testovia
LABEL;TYPE=WORK:Test Drive 2\nTest Town\, Upper Test County\n12346\nTest Bo
 x #2\nOld Testovia
ADR;TYPE=HOME:Test Box #1;;Test Drive 1;Test Village;Lower Test County;1234
 5;Testovia
LABEL;TYPE=HOME:Test Drive 1\nTest Village\, Lower Test County\n12345\nTest
  Box #1\nTestovia
ADR:Test Box #3;;Test Drive 3;Test Megacity;Test County;12347;New Testonia
LABEL;TYPE=OTHER:Test Drive 3\nTest Megacity\, Test County\n12347\nTest Box
  #3\nNew Testonia
UID:pas-id-43C0ED3900000001
EMAIL;TYPE=WORK:[email protected]
EMAIL;TYPE=HOME:[email protected]
EMAIL;TYPE=OTHER:[email protected]
EMAIL;TYPE=OTHER:[email protected]
TEL;TYPE=work;TYPE=Voice:business 1
TEL;TYPE=homE;TYPE=VOICE:home 2
TEL;TYPE=CELL:mobile 3
TEL;TYPE=WORK;TYPE=FAX:businessfax 4
TEL;TYPE=HOME;TYPE=FAX:homefax 5
TEL;TYPE=PAGER:pager 6
TEL;TYPE=CAR:car 7
TEL;TYPE=PREF:primary 8
X-AIM;TYPE=HOME:AIM JOHN
X-YAHOO;TYPE=HOME:YAHOO JDOE
X-ICQ;TYPE=HOME:ICQ JD
X-GROUPWISE;TYPE=HOME:GROUPWISE DOE
PHOTO;ENCODING=b;TYPE=JPEG:/9j/4AAQSkZJRgABAQEASABIAAD/4QAWRXhpZgAATU0AKgAA
 AAgAAAAAAAD//gAXQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q/9sAQwAFAwQEBAMFBAQEBQUFBgcM
 CAcHBwcPCwsJDBEPEhIRDxERExYcFxMUGhURERghGBodHR8fHxMXIiQiHiQcHh8e/9sAQwEF
 BQUHBgcOCAgOHhQRFB4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4e
 Hh4eHh4eHh4e/8AAEQgAFwAkAwEiAAIRAQMRAf/EABkAAQADAQEAAAAAAAAAAAAAAAAGBwgE
 Bf/EADIQAAECBQMCAwQLAAAAAAAAAAECBAADBQYRBxIhEzEUFSIIFjNBGCRHUVZ3lqXD0+P/
 xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMR
 AD8AuX6UehP45/aXv9MTPTLVKxNSvMPcqu+a+XdLxf1SfJ6fU37PioTnOxfbOMc/KIZ7U/2V
 fmTR/wCaKlu6+blu/Ui72zxWtUmmUOrTaWwkWDT09FPR4K587OVrUfVsIwElPPPAbAjxr2um
 hWXbDu5rmfeApLPZ4hx0lzNm9aUJ9KAVHKlJHAPf7ozPLqWt9y6Z0EPGmoLNjTq48a1iaybJ
 YV52yEtCms5KJmAT61JXtJyUdyQTEc1WlMql7N1/oZ6jagVZVFfUyZPpFy5lvWcxU7Z03BUk
 GZLWJqVhPYLkIIPBEBtSEUyNAsjI1q1m/VP+UICwL/sqlXp7v+aOHsnyGttq218MtKd8+Ru2
 JXuScoO45Awe2CIi96aKW1cVyubkYVy6rTqz0J8a5t2qqZl0UjAMwYKScfPAJ+cIQHHP0Dth
 VFaMWt0XwxetnM50Ks2rsxL6ZMnJlJmb5hBBBEiVxjA28dznqo+hdksbQuS3Hs6tVtNzdM1Z
 /VH5nO3Bl/CJmYHKDynjv3zCEB5rLQNo0bIbydWNWxKljbLQLoWkISOAkBKAABCEID//2Q==
END:VCARD
 
default codec: "UTF-8" 
Converted into: 
QContact(QContactId("", 0)) 
 QContactDetail(name="DisplayLabel", key=92, "Label"=QVariant(QString, "John 
Doe") ) 
 QContactDetail(name="Type", key=91, "Type"=QVariant(QString, "Contact") ) 
 QContactDetail(name="PhoneNumber", key=57, "PhoneNumber"=QVariant(QString, 
"primary 8") ) 
 QContactDetail(name="Url", key=58, "Url"=QVariant(QString, 
"http://john.doe.com";) ) 
 QContactDetail(name="Organization", key=59, "AssistantName"=QVariant(QString, 
"John Doe Junior") , "Department"=QVariant(QStringList, ("Testing", "test#1") ) 
, "Name"=QVariant(QString, "Test Inc.") , "Role"=QVariant(QString, 
"professional test case") , "Title"=QVariant(QString, "Senior Tester") ) 
 QContactDetail(name="Nickname", key=63, "Nickname"=QVariant(QString, "user1") 
) 
 QContactDetail(name="Birthday", key=64, "Birthday"=QVariant(QDate, QDate("Sun 
Jan 8 2006") ) ) 
 QContactDetail(name="Anniversary", key=65, "OriginalDate"=QVariant(QDate, 
QDate("Mon Jan 9 2006") ) ) 
 QContactDetail(name="Family", key=67, "Spouse"=QVariant(QString, "Joan Doe") ) 
 QContactDetail(name="Note", key=68, "Note"=QVariant(QString, "This is a test 
case which uses almost all Evolution fields.") ) 
 QContactDetail(name="Name", key=69, "CustomLabel"=QVariant(QString, "John 
Doe") , "FirstName"=QVariant(QString, "John") , "LastName"=QVariant(QString, 
"Doe") ) 
 QContactDetail(name="Tag", key=73, "Tag"=QVariant(QString, "TEST") ) 
 QContactDetail(name="Address", key=74, "Context"=QVariant(QStringList, 
("Work") ) , "Country"=QVariant(QString, "Old Testovia") , 
"Locality"=QVariant(QString, "Test Town") , "PostOfficeBox"=QVariant(QString, 
"Test Box #2") , "Postcode"=QVariant(QString, "12346") , 
"Region"=QVariant(QString, "Upper Test County") , "Street"=QVariant(QString, 
"Test Drive 2") ) 
 QContactDetail(name="Address", key=75, "Context"=QVariant(QStringList, 
("Home") ) , "Country"=QVariant(QString, "Testovia") , 
"Locality"=QVariant(QString, "Test Village") , 
"PostOfficeBox"=QVariant(QString, "Test Box #1") , "Postcode"=QVariant(QString, 
"12345") , "Region"=QVariant(QString, "Lower Test County") , 
"Street"=QVariant(QString, "Test Drive 1") ) 
 QContactDetail(name="Address", key=76, "Country"=QVariant(QString, "New 
Testonia") , "Locality"=QVariant(QString, "Test Megacity") , 
"PostOfficeBox"=QVariant(QString, "Test Box #3") , "Postcode"=QVariant(QString, 
"12347") , "Region"=QVariant(QString, "Test County") , 
"Street"=QVariant(QString, "Test Drive 3") ) 
 QContactDetail(name="Guid", key=77, "Guid"=QVariant(QString, 
"pas-id-43C0ED3900000001") ) 
 QContactDetail(name="EmailAddress", key=78, "Context"=QVariant(QStringList, 
("Work") ) , "EmailAddress"=QVariant(QString, "[email protected]") ) 
 QContactDetail(name="EmailAddress", key=79, "Context"=QVariant(QStringList, 
("Home") ) , "EmailAddress"=QVariant(QString, "[email protected]") ) 
 QContactDetail(name="EmailAddress", key=80, "EmailAddress"=QVariant(QString, 
"[email protected]") ) 
 QContactDetail(name="EmailAddress", key=81, "EmailAddress"=QVariant(QString, 
"[email protected]") ) 
 QContactDetail(name="PhoneNumber", key=82, "Context"=QVariant(QStringList, 
("Work") ) , "PhoneNumber"=QVariant(QString, "business 1") , 
"SubTypes"=QVariant(QStringList, ("Voice") ) ) 
 QContactDetail(name="PhoneNumber", key=83, "Context"=QVariant(QStringList, 
("Home") ) , "PhoneNumber"=QVariant(QString, "home 2") , 
"SubTypes"=QVariant(QStringList, ("Voice") ) ) 
 QContactDetail(name="PhoneNumber", key=84, "PhoneNumber"=QVariant(QString, 
"mobile 3") , "SubTypes"=QVariant(QStringList, ("Mobile") ) ) 
 QContactDetail(name="PhoneNumber", key=85, "Context"=QVariant(QStringList, 
("Work") ) , "PhoneNumber"=QVariant(QString, "businessfax 4") , 
"SubTypes"=QVariant(QStringList, ("Fax") ) ) 
 QContactDetail(name="PhoneNumber", key=86, "Context"=QVariant(QStringList, 
("Home") ) , "PhoneNumber"=QVariant(QString, "homefax 5") , 
"SubTypes"=QVariant(QStringList, ("Fax") ) ) 
 QContactDetail(name="PhoneNumber", key=87, "PhoneNumber"=QVariant(QString, 
"pager 6") , "SubTypes"=QVariant(QStringList, ("Pager") ) ) 
 QContactDetail(name="PhoneNumber", key=88, "PhoneNumber"=QVariant(QString, 
"car 7") , "SubTypes"=QVariant(QStringList, ("Car") ) ) 
 QContactDetail(name="Thumbnail", key=90, "Thumbnail"=QVariant(QImage, ) )
_______________________________________________
MeeGo-dev mailing list
[email protected]
http://lists.meego.com/listinfo/meego-dev

Reply via email to