summaryrefslogtreecommitdiff
path: root/noncore/unsupported/libopie/pim/ocontactaccessbackend_vcard.cpp
Unidiff
Diffstat (limited to 'noncore/unsupported/libopie/pim/ocontactaccessbackend_vcard.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/unsupported/libopie/pim/ocontactaccessbackend_vcard.cpp649
1 files changed, 649 insertions, 0 deletions
diff --git a/noncore/unsupported/libopie/pim/ocontactaccessbackend_vcard.cpp b/noncore/unsupported/libopie/pim/ocontactaccessbackend_vcard.cpp
new file mode 100644
index 0000000..a795b56
--- a/dev/null
+++ b/noncore/unsupported/libopie/pim/ocontactaccessbackend_vcard.cpp
@@ -0,0 +1,649 @@
1/*
2 * VCard Backend for the OPIE-Contact Database.
3 *
4 * Copyright (C) 2000 Trolltech AS. All rights reserved.
5 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
6 *
7 * =====================================================================
8 *This program is free software; you can redistribute it and/or
9 *modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 * =====================================================================
13 * ToDo:
14 *
15 * =====================================================================
16 * Version: $Id$
17 * =====================================================================
18 * History:
19 * $Log$
20 * Revision 1.1 2004/11/16 21:46:07 mickeyl
21 * libopie1 goes into unsupported
22 *
23 * Revision 1.11 2003/08/01 12:30:16 eilers
24 * Merging changes from BRANCH_1_0 to HEAD
25 *
26 * Revision 1.10.4.3 2003/07/23 08:54:37 eilers
27 * Default email was added to the list of all emails, which already contains
28 * the default email..
29 * This closes bug #1045
30 *
31 * Revision 1.10.4.2 2003/07/23 08:44:45 eilers
32 * Importing of Notes in vcard files wasn't implemented.
33 * Closes bug #1044
34 *
35 * Revision 1.10.4.1 2003/06/02 13:37:49 eilers
36 * Fixing memory leak
37 *
38 * Revision 1.10 2003/04/13 18:07:10 zecke
39 * More API doc
40 * QString -> const QString&
41 * QString = 0l -> QString::null
42 *
43 * Revision 1.9 2003/03/21 10:33:09 eilers
44 * Merged speed optimized xml backend for contacts to main.
45 * Added QDateTime to querybyexample. For instance, it is now possible to get
46 * all Birthdays/Anniversaries between two dates. This should be used
47 * to show all birthdays in the datebook..
48 * This change is sourcecode backward compatible but you have to upgrade
49 * the binaries for today-addressbook.
50 *
51 * Revision 1.8 2003/02/21 16:52:49 zecke
52 * -Remove old Todo classes they're deprecated and today I already using the
53 * new API
54 * -Guard against self assignment in OTodo
55 * -Add test apps for OPIM
56 * -Opiefied Event classes
57 * -Added TimeZone handling and pinning of TimeZones to OEvent
58 * -Adjust ORecur and the widget to better timezone behaviour
59 *
60 * Revision 1.7 2003/02/16 22:25:46 zecke
61 * 0000276 Fix for that bug.. or better temp workaround
62 * A Preferred Number is HOME|VOICE
63 * A CellPhone is HOME|VOICE|CELL the type & HOME|VOICE test
64 * triggers both
65 * and the cell phone number overrides the other entries..
66 *
67 * as a temp I check that it's not equal to HOME|VOICE|CELL before setting the
68 * number
69 *
70 * The right and final fix would be to reorder the if statement to make it
71 * if else based and the less common thing put to the bottom
72 *
73 * OTodoAccessVcal fix the date for beaming
74 *
75 * Revision 1.6 2003/01/13 15:49:31 eilers
76 * Fixing crash when businesscard.vcf is missing..
77 *
78 * Revision 1.5 2002/12/07 13:26:22 eilers
79 * Fixing bug in storing anniversary..
80 *
81 * Revision 1.4 2002/11/13 14:14:51 eilers
82 * Added sorted for Contacts..
83 *
84 * Revision 1.3 2002/11/11 16:41:09 kergoth
85 * no default arguments in implementation
86 *
87 * Revision 1.2 2002/11/10 15:41:53 eilers
88 * Bugfixes..
89 *
90 * Revision 1.1 2002/11/09 14:34:52 eilers
91 * Added VCard Backend.
92 *
93 */
94#include "ocontactaccessbackend_vcard.h"
95#include "../../library/backend/vobject_p.h"
96#include "../../library/backend/qfiledirect_p.h"
97
98#include <qpe/timeconversion.h>
99
100#include <qfile.h>
101
102OContactAccessBackend_VCard::OContactAccessBackend_VCard ( const QString& , const QString& filename ):
103 m_dirty( false ),
104 m_file( filename )
105{
106 load();
107}
108
109
110bool OContactAccessBackend_VCard::load ()
111{
112 m_map.clear();
113 m_dirty = false;
114
115 VObject* obj = 0l;
116
117 if ( QFile::exists(m_file) ){
118 obj = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() );
119 if ( !obj )
120 return false;
121 }else{
122 qWarning("File \"%s\" not found !", m_file.latin1() );
123 return false;
124 }
125
126 while ( obj ) {
127 OContact con = parseVObject( obj );
128 /*
129 * if uid is 0 assign a new one
130 * this at least happens on
131 * Nokia6210
132 */
133 if ( con.uid() == 0 ){
134 con.setUid( 1 );
135 qWarning("assigned new uid %d",con.uid() );
136 }
137
138 m_map.insert( con.uid(), con );
139
140 VObject *t = obj;
141 obj = nextVObjectInList(obj);
142 cleanVObject( t );
143 }
144
145 return true;
146
147}
148bool OContactAccessBackend_VCard::reload()
149{
150 return load();
151}
152bool OContactAccessBackend_VCard::save()
153{
154 if (!m_dirty )
155 return true;
156
157 QFileDirect file( m_file );
158 if (!file.open(IO_WriteOnly ) )
159 return false;
160
161 VObject *obj;
162 obj = newVObject( VCCalProp );
163 addPropValue( obj, VCVersionProp, "1.0" );
164
165 VObject *vo;
166 for(QMap<int, OContact>::ConstIterator it=m_map.begin(); it !=m_map.end(); ++it ){
167 vo = createVObject( *it );
168 writeVObject( file.directHandle() , vo );
169 cleanVObject( vo );
170 }
171 cleanStrTbl();
172 deleteVObject( obj );
173
174 m_dirty = false;
175 return true;
176
177
178}
179void OContactAccessBackend_VCard::clear ()
180{
181 m_map.clear();
182 m_dirty = true; // ??? sure ? (se)
183}
184
185bool OContactAccessBackend_VCard::add ( const OContact& newcontact )
186{
187 m_map.insert( newcontact.uid(), newcontact );
188 m_dirty = true;
189 return true;
190}
191
192bool OContactAccessBackend_VCard::remove ( int uid )
193{
194 m_map.remove( uid );
195 m_dirty = true;
196 return true;
197}
198
199bool OContactAccessBackend_VCard::replace ( const OContact &contact )
200{
201 m_map.replace( contact.uid(), contact );
202 m_dirty = true;
203 return true;
204}
205
206OContact OContactAccessBackend_VCard::find ( int uid ) const
207{
208 return m_map[uid];
209}
210
211QArray<int> OContactAccessBackend_VCard::allRecords() const
212{
213 QArray<int> ar( m_map.count() );
214 QMap<int, OContact>::ConstIterator it;
215 int i = 0;
216 for ( it = m_map.begin(); it != m_map.end(); ++it ) {
217 ar[i] = it.key();
218 i++;
219 }
220 return ar;
221}
222
223// Not implemented
224QArray<int> OContactAccessBackend_VCard::queryByExample ( const OContact&, int, const QDateTime& )
225{
226 QArray<int> ar(0);
227 return ar;
228}
229
230// Not implemented
231QArray<int> OContactAccessBackend_VCard::matchRegexp( const QRegExp& ) const
232{
233 QArray<int> ar(0);
234 return ar;
235}
236
237const uint OContactAccessBackend_VCard::querySettings()
238{
239 return 0; // No search possible
240}
241
242bool OContactAccessBackend_VCard::hasQuerySettings (uint ) const
243{
244 return false; // No search possible, therefore all settings invalid ;)
245}
246
247bool OContactAccessBackend_VCard::wasChangedExternally()
248{
249 return false; // Don't expect concurrent access
250}
251
252// Not implemented
253QArray<int> OContactAccessBackend_VCard::sorted( bool , int, int, int )
254{
255 QArray<int> ar(0);
256 return ar;
257}
258
259// *** Private stuff ***
260
261
262OContact OContactAccessBackend_VCard::parseVObject( VObject *obj )
263{
264 OContact c;
265
266 VObjectIterator it;
267 initPropIterator( &it, obj );
268 while( moreIteration( &it ) ) {
269 VObject *o = nextVObject( &it );
270 QCString name = vObjectName( o );
271 QCString value = vObjectStringZValue( o );
272 if ( name == VCNameProp ) {
273 VObjectIterator nit;
274 initPropIterator( &nit, o );
275 while( moreIteration( &nit ) ) {
276 VObject *o = nextVObject( &nit );
277 QCString name = vObjectTypeInfo( o );
278 QString value = vObjectStringZValue( o );
279 if ( name == VCNamePrefixesProp )
280 c.setTitle( value );
281 else if ( name == VCNameSuffixesProp )
282 c.setSuffix( value );
283 else if ( name == VCFamilyNameProp )
284 c.setLastName( value );
285 else if ( name == VCGivenNameProp )
286 c.setFirstName( value );
287 else if ( name == VCAdditionalNamesProp )
288 c.setMiddleName( value );
289 }
290 }
291 else if ( name == VCAdrProp ) {
292 bool work = TRUE; // default address is work address
293 QString street;
294 QString city;
295 QString region;
296 QString postal;
297 QString country;
298
299 VObjectIterator nit;
300 initPropIterator( &nit, o );
301 while( moreIteration( &nit ) ) {
302 VObject *o = nextVObject( &nit );
303 QCString name = vObjectName( o );
304 QString value = vObjectStringZValue( o );
305 if ( name == VCHomeProp )
306 work = FALSE;
307 else if ( name == VCWorkProp )
308 work = TRUE;
309 else if ( name == VCStreetAddressProp )
310 street = value;
311 else if ( name == VCCityProp )
312 city = value;
313 else if ( name == VCRegionProp )
314 region = value;
315 else if ( name == VCPostalCodeProp )
316 postal = value;
317 else if ( name == VCCountryNameProp )
318 country = value;
319 }
320 if ( work ) {
321 c.setBusinessStreet( street );
322 c.setBusinessCity( city );
323 c.setBusinessCountry( country );
324 c.setBusinessZip( postal );
325 c.setBusinessState( region );
326 } else {
327 c.setHomeStreet( street );
328 c.setHomeCity( city );
329 c.setHomeCountry( country );
330 c.setHomeZip( postal );
331 c.setHomeState( region );
332 }
333 }
334 else if ( name == VCTelephoneProp ) {
335 enum {
336 HOME = 0x01,
337 WORK = 0x02,
338 VOICE = 0x04,
339 CELL = 0x08,
340 FAX = 0x10,
341 PAGER = 0x20,
342 UNKNOWN = 0x80
343 };
344 int type = 0;
345
346 VObjectIterator nit;
347 initPropIterator( &nit, o );
348 while( moreIteration( &nit ) ) {
349 VObject *o = nextVObject( &nit );
350 QCString name = vObjectTypeInfo( o );
351 if ( name == VCHomeProp )
352 type |= HOME;
353 else if ( name == VCWorkProp )
354 type |= WORK;
355 else if ( name == VCVoiceProp )
356 type |= VOICE;
357 else if ( name == VCCellularProp )
358 type |= CELL;
359 else if ( name == VCFaxProp )
360 type |= FAX;
361 else if ( name == VCPagerProp )
362 type |= PAGER;
363 else if ( name == VCPreferredProp )
364 ;
365 else
366 type |= UNKNOWN;
367 }
368 if ( (type & UNKNOWN) != UNKNOWN ) {
369 if ( ( type & (HOME|WORK) ) == 0 ) // default
370 type |= HOME;
371 if ( ( type & (VOICE|CELL|FAX|PAGER) ) == 0 ) // default
372 type |= VOICE;
373
374 qWarning("value %s %d", value.data(), type );
375 if ( (type & (VOICE|HOME) ) == (VOICE|HOME) && (type & (CELL|HOME) ) != (CELL|HOME) )
376 c.setHomePhone( value );
377 if ( ( type & (FAX|HOME) ) == (FAX|HOME) )
378 c.setHomeFax( value );
379 if ( ( type & (CELL|HOME) ) == (CELL|HOME) )
380 c.setHomeMobile( value );
381 if ( ( type & (VOICE|WORK) ) == (VOICE|WORK) && (type & (CELL|WORK) ) != (CELL|WORK) )
382 c.setBusinessPhone( value );
383 if ( ( type & (FAX|WORK) ) == (FAX|WORK) )
384 c.setBusinessFax( value );
385 if ( ( type & (CELL|WORK) ) == (CELL|WORK) )
386 c.setBusinessMobile( value );
387 if ( ( type & (PAGER|WORK) ) == (PAGER|WORK) )
388 c.setBusinessPager( value );
389 }
390 }
391 else if ( name == VCEmailAddressProp ) {
392 QString email = vObjectStringZValue( o );
393 bool valid = TRUE;
394 VObjectIterator nit;
395 initPropIterator( &nit, o );
396 while( moreIteration( &nit ) ) {
397 VObject *o = nextVObject( &nit );
398 QCString name = vObjectTypeInfo( o );
399 if ( name != VCInternetProp && name != VCHomeProp &&
400 name != VCWorkProp &&
401 name != VCPreferredProp )
402 // ### preffered should map to default email
403 valid = FALSE;
404 }
405 if ( valid ) {
406 c.insertEmail( email );
407 }
408 }
409 else if ( name == VCURLProp ) {
410 VObjectIterator nit;
411 initPropIterator( &nit, o );
412 while( moreIteration( &nit ) ) {
413 VObject *o = nextVObject( &nit );
414 QCString name = vObjectTypeInfo( o );
415 if ( name == VCHomeProp )
416 c.setHomeWebpage( value );
417 else if ( name == VCWorkProp )
418 c.setBusinessWebpage( value );
419 }
420 }
421 else if ( name == VCOrgProp ) {
422 VObjectIterator nit;
423 initPropIterator( &nit, o );
424 while( moreIteration( &nit ) ) {
425 VObject *o = nextVObject( &nit );
426 QCString name = vObjectName( o );
427 QString value = vObjectStringZValue( o );
428 if ( name == VCOrgNameProp )
429 c.setCompany( value );
430 else if ( name == VCOrgUnitProp )
431 c.setDepartment( value );
432 else if ( name == VCOrgUnit2Prop )
433 c.setOffice( value );
434 }
435 }
436 else if ( name == VCTitleProp ) {
437 c.setJobTitle( value );
438 }
439 else if ( name == "X-Qtopia-Profession" ) {
440 c.setProfession( value );
441 }
442 else if ( name == "X-Qtopia-Manager" ) {
443 c.setManager( value );
444 }
445 else if ( name == "X-Qtopia-Assistant" ) {
446 c.setAssistant( value );
447 }
448 else if ( name == "X-Qtopia-Spouse" ) {
449 c.setSpouse( value );
450 }
451 else if ( name == "X-Qtopia-Gender" ) {
452 c.setGender( value );
453 }
454 else if ( name == "X-Qtopia-Anniversary" ) {
455 c.setAnniversary( convVCardDateToDate( value ) );
456 }
457 else if ( name == "X-Qtopia-Nickname" ) {
458 c.setNickname( value );
459 }
460 else if ( name == "X-Qtopia-Children" ) {
461 c.setChildren( value );
462 }
463 else if ( name == VCBirthDateProp ) {
464 // Reading Birthdate regarding RFC 2425 (5.8.4)
465 c.setBirthday( convVCardDateToDate( value ) );
466
467 }
468 else if ( name == VCCommentProp ) {
469 c.setNotes( value );
470 }
471#if 0
472 else {
473 printf("Name: %s, value=%s\n", name.data(), vObjectStringZValue( o ) );
474 VObjectIterator nit;
475 initPropIterator( &nit, o );
476 while( moreIteration( &nit ) ) {
477 VObject *o = nextVObject( &nit );
478 QCString name = vObjectName( o );
479 QString value = vObjectStringZValue( o );
480 printf(" subprop: %s = %s\n", name.data(), value.latin1() );
481 }
482 }
483#endif
484 }
485 c.setFileAs();
486 return c;
487}
488
489
490VObject* OContactAccessBackend_VCard::createVObject( const OContact &c )
491{
492 VObject *vcard = newVObject( VCCardProp );
493 safeAddPropValue( vcard, VCVersionProp, "2.1" );
494 safeAddPropValue( vcard, VCLastRevisedProp, TimeConversion::toISO8601( QDateTime::currentDateTime() ) );
495 safeAddPropValue( vcard, VCUniqueStringProp, QString::number(c.uid()) );
496
497 // full name
498 safeAddPropValue( vcard, VCFullNameProp, c.fullName() );
499
500 // name properties
501 VObject *name = safeAddProp( vcard, VCNameProp );
502 safeAddPropValue( name, VCFamilyNameProp, c.lastName() );
503 safeAddPropValue( name, VCGivenNameProp, c.firstName() );
504 safeAddPropValue( name, VCAdditionalNamesProp, c.middleName() );
505 safeAddPropValue( name, VCNamePrefixesProp, c.title() );
506 safeAddPropValue( name, VCNameSuffixesProp, c.suffix() );
507
508 // home properties
509 VObject *home_adr= safeAddProp( vcard, VCAdrProp );
510 safeAddProp( home_adr, VCHomeProp );
511 safeAddPropValue( home_adr, VCStreetAddressProp, c.homeStreet() );
512 safeAddPropValue( home_adr, VCCityProp, c.homeCity() );
513 safeAddPropValue( home_adr, VCRegionProp, c.homeState() );
514 safeAddPropValue( home_adr, VCPostalCodeProp, c.homeZip() );
515 safeAddPropValue( home_adr, VCCountryNameProp, c.homeCountry() );
516
517 VObject *home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homePhone() );
518 safeAddProp( home_phone, VCHomeProp );
519 home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeMobile() );
520 safeAddProp( home_phone, VCHomeProp );
521 safeAddProp( home_phone, VCCellularProp );
522 home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeFax() );
523 safeAddProp( home_phone, VCHomeProp );
524 safeAddProp( home_phone, VCFaxProp );
525
526 VObject *url = safeAddPropValue( vcard, VCURLProp, c.homeWebpage() );
527 safeAddProp( url, VCHomeProp );
528
529 // work properties
530 VObject *work_adr= safeAddProp( vcard, VCAdrProp );
531 safeAddProp( work_adr, VCWorkProp );
532 safeAddPropValue( work_adr, VCStreetAddressProp, c.businessStreet() );
533 safeAddPropValue( work_adr, VCCityProp, c.businessCity() );
534 safeAddPropValue( work_adr, VCRegionProp, c.businessState() );
535 safeAddPropValue( work_adr, VCPostalCodeProp, c.businessZip() );
536 safeAddPropValue( work_adr, VCCountryNameProp, c.businessCountry() );
537
538 VObject *work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPhone() );
539 safeAddProp( work_phone, VCWorkProp );
540 work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessMobile() );
541 safeAddProp( work_phone, VCWorkProp );
542 safeAddProp( work_phone, VCCellularProp );
543 work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessFax() );
544 safeAddProp( work_phone, VCWorkProp );
545 safeAddProp( work_phone, VCFaxProp );
546 work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPager() );
547 safeAddProp( work_phone, VCWorkProp );
548 safeAddProp( work_phone, VCPagerProp );
549
550 url = safeAddPropValue( vcard, VCURLProp, c.businessWebpage() );
551 safeAddProp( url, VCWorkProp );
552
553 VObject *title = safeAddPropValue( vcard, VCTitleProp, c.jobTitle() );
554 safeAddProp( title, VCWorkProp );
555
556
557 QStringList emails = c.emailList();
558 // emails.prepend( c.defaultEmail() ); Fix for bugreport #1045
559 for( QStringList::Iterator it = emails.begin(); it != emails.end(); ++it ) {
560 VObject *email = safeAddPropValue( vcard, VCEmailAddressProp, *it );
561 safeAddProp( email, VCInternetProp );
562 }
563
564 safeAddPropValue( vcard, VCNoteProp, c.notes() );
565
566 // Exporting Birthday regarding RFC 2425 (5.8.4)
567 if ( c.birthday().isValid() ){
568 qWarning("Exporting birthday as: %s", convDateToVCardDate( c.birthday() ).latin1() );
569 safeAddPropValue( vcard, VCBirthDateProp, convDateToVCardDate( c.birthday() ) );
570 }
571
572 if ( !c.company().isEmpty() || !c.department().isEmpty() || !c.office().isEmpty() ) {
573 VObject *org = safeAddProp( vcard, VCOrgProp );
574 safeAddPropValue( org, VCOrgNameProp, c.company() );
575 safeAddPropValue( org, VCOrgUnitProp, c.department() );
576 safeAddPropValue( org, VCOrgUnit2Prop, c.office() );
577 }
578
579 // some values we have to export as custom fields
580 safeAddPropValue( vcard, "X-Qtopia-Profession", c.profession() );
581 safeAddPropValue( vcard, "X-Qtopia-Manager", c.manager() );
582 safeAddPropValue( vcard, "X-Qtopia-Assistant", c.assistant() );
583
584 safeAddPropValue( vcard, "X-Qtopia-Spouse", c.spouse() );
585 safeAddPropValue( vcard, "X-Qtopia-Gender", c.gender() );
586 if ( c.anniversary().isValid() ){
587 qWarning("Exporting anniversary as: %s", convDateToVCardDate( c.anniversary() ).latin1() );
588 safeAddPropValue( vcard, "X-Qtopia-Anniversary", convDateToVCardDate( c.anniversary() ) );
589 }
590 safeAddPropValue( vcard, "X-Qtopia-Nickname", c.nickname() );
591 safeAddPropValue( vcard, "X-Qtopia-Children", c.children() );
592
593 return vcard;
594}
595
596QString OContactAccessBackend_VCard::convDateToVCardDate( const QDate& d ) const
597{
598 QString str_rfc2425 = QString("%1-%2-%3")
599 .arg( d.year() )
600 .arg( d.month(), 2 )
601 .arg( d.day(), 2 );
602 // Now replace spaces with "0"...
603 int pos = 0;
604 while ( ( pos = str_rfc2425.find (' ') ) > 0 )
605 str_rfc2425.replace( pos, 1, "0" );
606
607 return str_rfc2425;
608}
609
610QDate OContactAccessBackend_VCard::convVCardDateToDate( const QString& datestr )
611{
612 int monthPos = datestr.find('-');
613 int dayPos = datestr.find('-', monthPos+1 );
614 int sep_ignore = 1;
615 if ( monthPos == -1 || dayPos == -1 ) {
616 qDebug("fromString didn't find - in str = %s; mpos = %d ypos = %d", datestr.latin1(), monthPos, dayPos );
617 // Ok.. No "-" found, therefore we will try to read other format ( YYYYMMDD )
618 if ( datestr.length() == 8 ){
619 monthPos = 4;
620 dayPos = 6;
621 sep_ignore = 0;
622 qDebug("Try with follwing positions str = %s; mpos = %d ypos = %d", datestr.latin1(), monthPos, dayPos );
623 } else {
624 return QDate();
625 }
626 }
627 int y = datestr.left( monthPos ).toInt();
628 int m = datestr.mid( monthPos + sep_ignore, dayPos - monthPos - sep_ignore ).toInt();
629 int d = datestr.mid( dayPos + sep_ignore ).toInt();
630 qDebug("TimeConversion::fromString ymd = %s => %d %d %d; mpos = %d ypos = %d", datestr.latin1(), y, m, d, monthPos, dayPos);
631 QDate date ( y,m,d );
632 return date;
633}
634
635VObject* OContactAccessBackend_VCard::safeAddPropValue( VObject *o, const char *prop, const QString &value )
636{
637 VObject *ret = 0;
638 if ( o && !value.isEmpty() )
639 ret = addPropValue( o, prop, value.latin1() );
640 return ret;
641}
642
643VObject* OContactAccessBackend_VCard::safeAddProp( VObject *o, const char *prop)
644{
645 VObject *ret = 0;
646 if ( o )
647 ret = addProp( o, prop );
648 return ret;
649}