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(¬e));
// 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