• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.9.3 API Reference
  • KDE Home
  • Contact Us
 

kabc

  • kabc
vcardtool.cpp
1 /*
2  This file is part of libkabc.
3  Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Library General Public License for more details.
14 
15  You should have received a copy of the GNU Library General Public License
16  along with this library; see the file COPYING.LIB. If not, write to
17  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  Boston, MA 02110-1301, USA.
19 */
20 
21 #include "vcardtool.h"
22 #include "key.h"
23 #include "picture.h"
24 #include "secrecy.h"
25 #include "sound.h"
26 
27 #include <QtCore/QString>
28 #include <QtCore/QBuffer>
29 
30 using namespace KABC;
31 
32 static bool needsEncoding( const QString &value )
33 {
34  uint length = value.length();
35  for ( uint i = 0; i < length; ++i ) {
36  char c = value.at( i ).toLatin1();
37  if ( ( c < 33 || c > 126 ) && c != ' ' && c != '=' ) {
38  return true;
39  }
40  }
41 
42  return false;
43 }
44 
45 VCardTool::VCardTool()
46 {
47  mAddressTypeMap.insert( QLatin1String( "dom" ), Address::Dom );
48  mAddressTypeMap.insert( QLatin1String( "intl" ), Address::Intl );
49  mAddressTypeMap.insert( QLatin1String( "postal" ), Address::Postal );
50  mAddressTypeMap.insert( QLatin1String( "parcel" ), Address::Parcel );
51  mAddressTypeMap.insert( QLatin1String( "home" ), Address::Home );
52  mAddressTypeMap.insert( QLatin1String( "work" ), Address::Work );
53  mAddressTypeMap.insert( QLatin1String( "pref" ), Address::Pref );
54 
55  mPhoneTypeMap.insert( QLatin1String( "HOME" ), PhoneNumber::Home );
56  mPhoneTypeMap.insert( QLatin1String( "WORK" ), PhoneNumber::Work );
57  mPhoneTypeMap.insert( QLatin1String( "MSG" ), PhoneNumber::Msg );
58  mPhoneTypeMap.insert( QLatin1String( "PREF" ), PhoneNumber::Pref );
59  mPhoneTypeMap.insert( QLatin1String( "VOICE" ), PhoneNumber::Voice );
60  mPhoneTypeMap.insert( QLatin1String( "FAX" ), PhoneNumber::Fax );
61  mPhoneTypeMap.insert( QLatin1String( "CELL" ), PhoneNumber::Cell );
62  mPhoneTypeMap.insert( QLatin1String( "VIDEO" ), PhoneNumber::Video );
63  mPhoneTypeMap.insert( QLatin1String( "BBS" ), PhoneNumber::Bbs );
64  mPhoneTypeMap.insert( QLatin1String( "MODEM" ), PhoneNumber::Modem );
65  mPhoneTypeMap.insert( QLatin1String( "CAR" ), PhoneNumber::Car );
66  mPhoneTypeMap.insert( QLatin1String( "ISDN" ), PhoneNumber::Isdn );
67  mPhoneTypeMap.insert( QLatin1String( "PCS" ), PhoneNumber::Pcs );
68  mPhoneTypeMap.insert( QLatin1String( "PAGER" ), PhoneNumber::Pager );
69 }
70 
71 VCardTool::~VCardTool()
72 {
73 }
74 
75 QByteArray VCardTool::exportVCards( const Addressee::List &list, VCard::Version version ) const
76 {
77  return createVCards(list,version, true /*export vcard*/);
78 }
79 
80 QByteArray VCardTool::createVCards( const Addressee::List &list, VCard::Version version ) const
81 {
82  return createVCards(list,version, false/*don't export*/);
83 }
84 
85 QByteArray VCardTool::createVCards( const Addressee::List &list, VCard::Version version, bool exportVcard ) const
86 {
87  VCard::List vCardList;
88 
89  Addressee::List::ConstIterator addrIt;
90  Addressee::List::ConstIterator listEnd( list.constEnd() );
91  for ( addrIt = list.constBegin(); addrIt != listEnd; ++addrIt ) {
92  VCard card;
93  QStringList::ConstIterator strIt;
94 
95  // ADR + LABEL
96  const Address::List addresses = (*addrIt).addresses();
97  for ( Address::List::ConstIterator it = addresses.begin(); it != addresses.end(); ++it ) {
98  QStringList address;
99 
100  const bool isEmpty = ( (*it).postOfficeBox().isEmpty() &&
101  (*it).extended().isEmpty() &&
102  (*it).street().isEmpty() &&
103  (*it).locality().isEmpty() &&
104  (*it).region().isEmpty() &&
105  (*it).postalCode().isEmpty() &&
106  (*it).country().isEmpty() );
107 
108  address.append( (*it).postOfficeBox().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) );
109  address.append( (*it).extended().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) );
110  address.append( (*it).street().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) );
111  address.append( (*it).locality().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) );
112  address.append( (*it).region().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) );
113  address.append( (*it).postalCode().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) );
114  address.append( (*it).country().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) );
115 
116  VCardLine adrLine( QLatin1String( "ADR" ), address.join( QLatin1String( ";" ) ) );
117  if ( version == VCard::v2_1 && needsEncoding( address.join( QLatin1String( ";" ) ) ) ) {
118  adrLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
119  adrLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
120  }
121 
122  VCardLine labelLine( QLatin1String( "LABEL" ), (*it).label() );
123  if ( version == VCard::v2_1 && needsEncoding( (*it).label() ) ) {
124  labelLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
125  labelLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
126  }
127 
128  const bool hasLabel = !(*it).label().isEmpty();
129  QMap<QString, Address::TypeFlag>::ConstIterator typeIt;
130  for ( typeIt = mAddressTypeMap.constBegin();
131  typeIt != mAddressTypeMap.constEnd(); ++typeIt ) {
132  if ( typeIt.value() & (*it).type() ) {
133  adrLine.addParameter( QLatin1String( "TYPE" ), typeIt.key() );
134  if ( hasLabel ) {
135  labelLine.addParameter( QLatin1String( "TYPE" ), typeIt.key() );
136  }
137  }
138  }
139 
140  if ( !isEmpty ) {
141  card.addLine( adrLine );
142  }
143  if ( hasLabel ) {
144  card.addLine( labelLine );
145  }
146  }
147 
148  // BDAY
149  card.addLine( VCardLine( QLatin1String( "BDAY" ), createDateTime( (*addrIt).birthday() ) ) );
150 
151  // CATEGORIES
152  if ( version == VCard::v3_0 ) {
153  QStringList categories = (*addrIt).categories();
154  QStringList::Iterator catIt;
155  for ( catIt = categories.begin(); catIt != categories.end(); ++catIt ) {
156  (*catIt).replace( QLatin1Char( ',' ), QLatin1String( "\\," ) );
157  }
158 
159  VCardLine catLine( QLatin1String( "CATEGORIES" ), categories.join( QLatin1String( "," ) ) );
160  card.addLine( catLine );
161  }
162 
163  // CLASS
164  if ( version == VCard::v3_0 ) {
165  card.addLine( createSecrecy( (*addrIt).secrecy() ) );
166  }
167 
168  // EMAIL
169  const QStringList emails = (*addrIt).emails();
170  bool pref = true;
171  for ( strIt = emails.begin(); strIt != emails.end(); ++strIt ) {
172  VCardLine line( QLatin1String( "EMAIL" ), *strIt );
173  if ( pref == true && emails.count() > 1 ) {
174  line.addParameter( QLatin1String( "TYPE" ), QLatin1String( "PREF" ) );
175  pref = false;
176  }
177  card.addLine( line );
178  }
179 
180  // FN
181  VCardLine fnLine( QLatin1String( "FN" ), (*addrIt).formattedName() );
182  if ( version == VCard::v2_1 && needsEncoding( (*addrIt).formattedName() ) ) {
183  fnLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
184  fnLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
185  }
186  card.addLine( fnLine );
187 
188  // GEO
189  const Geo geo = (*addrIt).geo();
190  if ( geo.isValid() ) {
191  QString str;
192  str.sprintf( "%.6f;%.6f", geo.latitude(), geo.longitude() );
193  card.addLine( VCardLine( QLatin1String( "GEO" ), str ) );
194  }
195 
196  // KEY
197  const Key::List keys = (*addrIt).keys();
198  Key::List::ConstIterator keyIt;
199  for ( keyIt = keys.begin(); keyIt != keys.end(); ++keyIt ) {
200  card.addLine( createKey( *keyIt ) );
201  }
202 
203  // LOGO
204  card.addLine( createPicture( QLatin1String( "LOGO" ), (*addrIt).logo() ) );
205 
206  // MAILER
207  VCardLine mailerLine( QLatin1String( "MAILER" ), (*addrIt).mailer() );
208  if ( version == VCard::v2_1 && needsEncoding( (*addrIt).mailer() ) ) {
209  mailerLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
210  mailerLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
211  }
212  card.addLine( mailerLine );
213 
214  // N
215  QStringList name;
216  name.append( (*addrIt).familyName().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) );
217  name.append( (*addrIt).givenName().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) );
218  name.append( (*addrIt).additionalName().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) );
219  name.append( (*addrIt).prefix().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) );
220  name.append( (*addrIt).suffix().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) );
221 
222  VCardLine nLine( QLatin1String( "N" ), name.join( QLatin1String( ";" ) ) );
223  if ( version == VCard::v2_1 && needsEncoding( name.join( QLatin1String( ";" ) ) ) ) {
224  nLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
225  nLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
226  }
227  card.addLine( nLine );
228 
229  // NAME
230  VCardLine nameLine( QLatin1String( "NAME" ), (*addrIt).name() );
231  if ( version == VCard::v2_1 && needsEncoding( (*addrIt).name() ) ) {
232  nameLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
233  nameLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
234  }
235  card.addLine( nameLine );
236 
237  // NICKNAME
238  if ( version == VCard::v3_0 ) {
239  card.addLine( VCardLine( QLatin1String( "NICKNAME" ), (*addrIt).nickName() ) );
240  }
241 
242  // NOTE
243  VCardLine noteLine( QLatin1String( "NOTE" ), (*addrIt).note() );
244  if ( version == VCard::v2_1 && needsEncoding( (*addrIt).note() ) ) {
245  noteLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
246  noteLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
247  }
248  card.addLine( noteLine );
249 
250  // ORG
251  QStringList organization;
252  organization.append( ( *addrIt ).organization().replace( QLatin1Char( ';' ),
253  QLatin1String( "\\;" ) ) );
254  if ( !( *addrIt ).department().isEmpty() ) {
255  organization.append( ( *addrIt ).department().replace( QLatin1Char( ';' ),
256  QLatin1String( "\\;" ) ) );
257  }
258  VCardLine orgLine( QLatin1String( "ORG" ), organization.join( QLatin1String( ";" ) ) );
259  if ( version == VCard::v2_1 && needsEncoding( organization.join( QLatin1String( ";" ) ) ) ) {
260  orgLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
261  orgLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
262  }
263  card.addLine( orgLine );
264 
265  // PHOTO
266  card.addLine( createPicture( QLatin1String( "PHOTO" ), (*addrIt).photo() ) );
267 
268  // PROID
269  if ( version == VCard::v3_0 ) {
270  card.addLine( VCardLine( QLatin1String( "PRODID" ), (*addrIt).productId() ) );
271  }
272 
273  // REV
274  card.addLine( VCardLine( QLatin1String( "REV" ), createDateTime( (*addrIt).revision() ) ) );
275 
276  // ROLE
277  VCardLine roleLine( QLatin1String( "ROLE" ), (*addrIt).role() );
278  if ( version == VCard::v2_1 && needsEncoding( (*addrIt).role() ) ) {
279  roleLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
280  roleLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
281  }
282  card.addLine( roleLine );
283 
284  // SORT-STRING
285  if ( version == VCard::v3_0 ) {
286  card.addLine( VCardLine( QLatin1String( "SORT-STRING" ), (*addrIt).sortString() ) );
287  }
288 
289  // SOUND
290  card.addLine( createSound( (*addrIt).sound() ) );
291 
292  // TEL
293  const PhoneNumber::List phoneNumbers = (*addrIt).phoneNumbers();
294  PhoneNumber::List::ConstIterator phoneIt;
295  for ( phoneIt = phoneNumbers.begin(); phoneIt != phoneNumbers.end(); ++phoneIt ) {
296  VCardLine line( QLatin1String( "TEL" ), (*phoneIt).number() );
297 
298  QMap<QString, PhoneNumber::TypeFlag>::ConstIterator typeIt;
299  for ( typeIt = mPhoneTypeMap.constBegin(); typeIt != mPhoneTypeMap.constEnd(); ++typeIt ) {
300  if ( typeIt.value() & (*phoneIt).type() ) {
301  line.addParameter( QLatin1String( "TYPE" ), typeIt.key() );
302  }
303  }
304 
305  card.addLine( line );
306  }
307 
308  // TITLE
309  VCardLine titleLine( QLatin1String( "TITLE" ), (*addrIt).title() );
310  if ( version == VCard::v2_1 && needsEncoding( (*addrIt).title() ) ) {
311  titleLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
312  titleLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
313  }
314  card.addLine( titleLine );
315 
316  // TZ
317  const TimeZone timeZone = (*addrIt).timeZone();
318  if ( timeZone.isValid() ) {
319  QString str;
320 
321  int neg = 1;
322  if ( timeZone.offset() < 0 ) {
323  neg = -1;
324  }
325 
326  str.sprintf( "%c%02d:%02d", ( timeZone.offset() >= 0 ? '+' : '-' ),
327  ( timeZone.offset() / 60 ) * neg,
328  ( timeZone.offset() % 60 ) * neg );
329 
330  card.addLine( VCardLine( QLatin1String( "TZ" ), str ) );
331  }
332 
333  // UID
334  card.addLine( VCardLine( QLatin1String( "UID" ), (*addrIt).uid() ) );
335 
336  // URL
337  card.addLine( VCardLine( QLatin1String( "URL" ), (*addrIt).url().url() ) );
338 
339  // VERSION
340  if ( version == VCard::v2_1 ) {
341  card.addLine( VCardLine( QLatin1String( "VERSION" ), QLatin1String( "2.1" ) ) );
342  }
343  if ( version == VCard::v3_0 ) {
344  card.addLine( VCardLine( QLatin1String( "VERSION" ), QLatin1String( "3.0" ) ) );
345  }
346 
347  // X-
348  const QStringList customs = (*addrIt).customs();
349  for ( strIt = customs.begin(); strIt != customs.end(); ++strIt ) {
350  QString identifier = QLatin1String( "X-" ) +
351  (*strIt).left( (*strIt).indexOf( QLatin1Char( ':' ) ) );
352  const QString value = (*strIt).mid( (*strIt).indexOf( QLatin1Char( ':' ) ) + 1 );
353  if ( value.isEmpty() ) {
354  continue;
355  }
356  //Convert to standard identifier
357  if(exportVcard) {
358  if(identifier == QLatin1String("X-messaging/aim-All")) {
359  identifier = QLatin1String("X-AIM");
360  } else if(identifier == QLatin1String("X-messaging/icq-All")) {
361  identifier = QLatin1String("X-ICQ");
362  } else if(identifier == QLatin1String("X-messaging/xmpp-All")) {
363  identifier = QLatin1String("X-JABBER");
364  } else if(identifier == QLatin1String("X-messaging/msn-All")) {
365  identifier = QLatin1String("X-MSN");
366  } else if(identifier == QLatin1String("X-messaging/yahoo-All")) {
367  identifier = QLatin1String("X-YAHOO");
368  } else if(identifier == QLatin1String("X-messaging/gadu-All")) {
369  identifier = QLatin1String("X-GADUGADU");
370  } else if(identifier == QLatin1String("X-messaging/skype-All")) {
371  identifier = QLatin1String("X-SKYPE");
372  } else if(identifier == QLatin1String("X-messaging/groupwise-All")) {
373  identifier = QLatin1String("X-GROUPWISE");
374  } else if(identifier == QLatin1String("X-messaging/sms-All")) {
375  identifier = QLatin1String("X-SMS");
376  } else if(identifier == QLatin1String("X-messaging/meanwhile-All")) {
377  identifier = QLatin1String("X-MEANWHILE");
378  } else if ( identifier == QLatin1String( "X-messaging/irc-All" ) ) {
379  identifier = QLatin1String( "X-IRC" ); //Not defined by rfc but need for fixing #300869
380  }
381  }
382 
383  VCardLine line( identifier, value );
384  if ( version == VCard::v2_1 && needsEncoding( value ) ) {
385  line.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
386  line.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
387  }
388  card.addLine( line );
389  }
390 
391  vCardList.append( card );
392  }
393 
394  return VCardParser::createVCards( vCardList );
395 }
396 
397 Addressee::List VCardTool::parseVCards( const QByteArray &vcard ) const
398 {
399  static const QLatin1Char semicolonSep( ';' );
400  static const QLatin1Char commaSep( ',' );
401  QString identifier;
402 
403  Addressee::List addrList;
404  const VCard::List vCardList = VCardParser::parseVCards( vcard );
405 
406  VCard::List::ConstIterator cardIt;
407  VCard::List::ConstIterator listEnd( vCardList.end() );
408  for ( cardIt = vCardList.begin(); cardIt != listEnd; ++cardIt ) {
409  Addressee addr;
410 
411  const QStringList idents = (*cardIt).identifiers();
412  QStringList::ConstIterator identIt;
413  QStringList::ConstIterator identEnd( idents.end() );
414  for ( identIt = idents.begin(); identIt != identEnd; ++identIt ) {
415  const VCardLine::List lines = (*cardIt).lines( (*identIt) );
416  VCardLine::List::ConstIterator lineIt;
417 
418  // iterate over the lines
419  for ( lineIt = lines.begin(); lineIt != lines.end(); ++lineIt ) {
420  identifier = (*lineIt).identifier().toLower();
421  // ADR
422  if ( identifier == QLatin1String( "adr" ) ) {
423  Address address;
424  const QStringList addrParts = splitString( semicolonSep, (*lineIt).value().toString() );
425  if ( addrParts.count() > 0 ) {
426  address.setPostOfficeBox( addrParts[ 0 ] );
427  }
428  if ( addrParts.count() > 1 ) {
429  address.setExtended( addrParts[ 1 ] );
430  }
431  if ( addrParts.count() > 2 ) {
432  address.setStreet( addrParts[ 2 ] );
433  }
434  if ( addrParts.count() > 3 ) {
435  address.setLocality( addrParts[ 3 ] );
436  }
437  if ( addrParts.count() > 4 ) {
438  address.setRegion( addrParts[ 4 ] );
439  }
440  if ( addrParts.count() > 5 ) {
441  address.setPostalCode( addrParts[ 5 ] );
442  }
443  if ( addrParts.count() > 6 ) {
444  address.setCountry( addrParts[ 6 ] );
445  }
446 
447  Address::Type type;
448 
449  const QStringList types = (*lineIt).parameters( QLatin1String( "type" ) );
450  for ( QStringList::ConstIterator it = types.begin(); it != types.end(); ++it ) {
451  type |= mAddressTypeMap[ (*it).toLower() ];
452  }
453 
454  address.setType( type );
455  addr.insertAddress( address );
456  }
457 
458  // BDAY
459  else if ( identifier == QLatin1String( "bday" ) ) {
460  addr.setBirthday( parseDateTime( (*lineIt).value().toString() ) );
461  }
462 
463  // CATEGORIES
464  else if ( identifier == QLatin1String( "categories" ) ) {
465  const QStringList categories = splitString( commaSep, (*lineIt).value().toString() );
466  addr.setCategories( categories );
467  }
468 
469  // CLASS
470  else if ( identifier == QLatin1String( "class" ) ) {
471  addr.setSecrecy( parseSecrecy( *lineIt ) );
472  }
473 
474  // EMAIL
475  else if ( identifier == QLatin1String( "email" ) ) {
476  const QStringList types = (*lineIt).parameters( QLatin1String( "type" ) );
477  addr.insertEmail( (*lineIt).value().toString(),
478  types.contains( QLatin1String( "PREF" ) ) );
479  }
480 
481  // FN
482  else if ( identifier == QLatin1String( "fn" ) ) {
483  addr.setFormattedName( (*lineIt).value().toString() );
484  }
485 
486  // GEO
487  else if ( identifier == QLatin1String( "geo" ) ) {
488  Geo geo;
489 
490  const QStringList geoParts =
491  (*lineIt).value().toString().split( QLatin1Char( ';' ), QString::KeepEmptyParts );
492  if ( geoParts.size() >= 2 ) {
493  geo.setLatitude( geoParts[ 0 ].toFloat() );
494  geo.setLongitude( geoParts[ 1 ].toFloat() );
495  addr.setGeo( geo );
496  }
497  }
498 
499  // KEY
500  else if ( identifier == QLatin1String( "key" ) ) {
501  addr.insertKey( parseKey( *lineIt ) );
502  }
503 
504  // LABEL
505  else if ( identifier == QLatin1String( "label" ) ) {
506  Address::Type type;
507 
508  const QStringList types = (*lineIt).parameters( QLatin1String( "type" ) );
509  for ( QStringList::ConstIterator it = types.begin(); it != types.end(); ++it ) {
510  type |= mAddressTypeMap[ (*it).toLower() ];
511  }
512 
513  bool available = false;
514  KABC::Address::List addressList = addr.addresses();
515  for ( KABC::Address::List::Iterator it = addressList.begin();
516  it != addressList.end(); ++it ) {
517  if ( (*it).type() == type ) {
518  (*it).setLabel( (*lineIt).value().toString() );
519  addr.insertAddress( *it );
520  available = true;
521  break;
522  }
523  }
524 
525  if ( !available ) { // a standalone LABEL tag
526  KABC::Address address( type );
527  address.setLabel( (*lineIt).value().toString() );
528  addr.insertAddress( address );
529  }
530  }
531 
532  // LOGO
533  else if ( identifier == QLatin1String( "logo" ) ) {
534  addr.setLogo( parsePicture( *lineIt ) );
535  }
536 
537  // MAILER
538  else if ( identifier == QLatin1String( "mailer" ) ) {
539  addr.setMailer( (*lineIt).value().toString() );
540  }
541 
542  // N
543  else if ( identifier == QLatin1String( "n" ) ) {
544  const QStringList nameParts = splitString( semicolonSep, (*lineIt).value().toString() );
545  const int numberOfParts(nameParts.count());
546  if ( numberOfParts > 0 ) {
547  addr.setFamilyName( nameParts[ 0 ] );
548  }
549  if ( numberOfParts > 1 ) {
550  addr.setGivenName( nameParts[ 1 ] );
551  }
552  if ( numberOfParts > 2 ) {
553  addr.setAdditionalName( nameParts[ 2 ] );
554  }
555  if ( numberOfParts > 3 ) {
556  addr.setPrefix( nameParts[ 3 ] );
557  }
558  if ( numberOfParts > 4 ) {
559  addr.setSuffix( nameParts[ 4 ] );
560  }
561  }
562 
563  // NAME
564  else if ( identifier == QLatin1String( "name" ) ) {
565  addr.setName( (*lineIt).value().toString() );
566  }
567 
568  // NICKNAME
569  else if ( identifier == QLatin1String( "nickname" ) ) {
570  addr.setNickName( (*lineIt).value().toString() );
571  }
572 
573  // NOTE
574  else if ( identifier == QLatin1String( "note" ) ) {
575  addr.setNote( (*lineIt).value().toString() );
576  }
577 
578  // ORGANIZATION
579  else if ( identifier == QLatin1String( "org" ) ) {
580  const QStringList orgParts = splitString( semicolonSep, (*lineIt).value().toString() );
581  if ( orgParts.count() > 0 ) {
582  addr.setOrganization( orgParts[ 0 ] );
583  }
584  if ( orgParts.count() > 1 ) {
585  addr.setDepartment( orgParts[ 1 ] );
586  }
587  }
588 
589  // PHOTO
590  else if ( identifier == QLatin1String( "photo" ) ) {
591  addr.setPhoto( parsePicture( *lineIt ) );
592  }
593 
594  // PROID
595  else if ( identifier == QLatin1String( "prodid" ) ) {
596  addr.setProductId( (*lineIt).value().toString() );
597  }
598 
599  // REV
600  else if ( identifier == QLatin1String( "rev" ) ) {
601  addr.setRevision( parseDateTime( (*lineIt).value().toString() ) );
602  }
603 
604  // ROLE
605  else if ( identifier == QLatin1String( "role" ) ) {
606  addr.setRole( (*lineIt).value().toString() );
607  }
608 
609  // SORT-STRING
610  else if ( identifier == QLatin1String( "sort-string" ) ) {
611  addr.setSortString( (*lineIt).value().toString() );
612  }
613 
614  // SOUND
615  else if ( identifier == QLatin1String( "sound" ) ) {
616  addr.setSound( parseSound( *lineIt ) );
617  }
618 
619  // TEL
620  else if ( identifier == QLatin1String( "tel" ) ) {
621  PhoneNumber phone;
622  phone.setNumber( (*lineIt).value().toString() );
623 
624  PhoneNumber::Type type;
625 
626  const QStringList types = (*lineIt).parameters( QLatin1String( "type" ) );
627  QStringList::ConstIterator typeEnd(types.end());
628  for ( QStringList::ConstIterator it = types.begin(); it != typeEnd; ++it ) {
629  type |= mPhoneTypeMap[(*it).toUpper()];
630  }
631 
632  phone.setType( type );
633 
634  addr.insertPhoneNumber( phone );
635  }
636 
637  // TITLE
638  else if ( identifier == QLatin1String( "title" ) ) {
639  addr.setTitle( (*lineIt).value().toString() );
640  }
641 
642  // TZ
643  else if ( identifier == QLatin1String( "tz" ) ) {
644  TimeZone tz;
645  const QString date = (*lineIt).value().toString();
646 
647  if ( !date.isEmpty() ) {
648  int hours = date.mid( 1, 2 ).toInt();
649  int minutes = date.mid( 4, 2 ).toInt();
650  int offset = ( hours * 60 ) + minutes;
651  offset = offset * ( date[ 0 ] == QLatin1Char( '+' ) ? 1 : -1 );
652 
653  tz.setOffset( offset );
654  addr.setTimeZone( tz );
655  }
656  }
657 
658  // UID
659  else if ( identifier == QLatin1String( "uid" ) ) {
660  addr.setUid( (*lineIt).value().toString() );
661  }
662 
663  // URL
664  else if ( identifier == QLatin1String( "url" ) ) {
665  addr.setUrl( KUrl( (*lineIt).value().toString() ) );
666  }
667 
668  // X-
669  else if ( identifier.startsWith( QLatin1String( "x-" ) ) ) {
670  QString ident = ( *lineIt ).identifier();
671  //X-Evolution
672  if(identifier==QLatin1String("x-evolution-spouse") || identifier == QLatin1String("x-spouse")) {
673  ident = QLatin1String("X-KADDRESSBOOK-X-SpousesName");
674  } else if(identifier == QLatin1String("x-evolution-blog-url")) {
675  ident = QLatin1String("X-KADDRESSBOOK-BlogFeed");
676  } else if(identifier == QLatin1String("x-evolution-assistant") || identifier == QLatin1String("x-assistant")) {
677  ident = QLatin1String("X-KADDRESSBOOK-X-AssistantsName");
678  } else if(identifier == QLatin1String("x-evolution-anniversary") || identifier == QLatin1String("x-anniversary")) {
679  ident = QLatin1String("X-KADDRESSBOOK-X-Anniversary");
680  } else if(identifier == QLatin1String("x-evolution-manager") || identifier == QLatin1String("x-manager")) {
681  ident = QLatin1String("X-KADDRESSBOOK-X-ManagersName");
682  } else if(identifier == QLatin1String("x-aim")) {
683  ident = QLatin1String("X-messaging/aim-All");
684  } else if(identifier == QLatin1String("x-icq")) {
685  ident = QLatin1String("X-messaging/icq-All");
686  } else if(identifier == QLatin1String("x-jabber")) {
687  ident = QLatin1String("X-messaging/xmpp-All");
688  } else if(identifier == QLatin1String("x-jabber")) {
689  ident = QLatin1String("X-messaging/xmpp-All");
690  } else if(identifier == QLatin1String("x-msn")) {
691  ident = QLatin1String("X-messaging/msn-All");
692  } else if(identifier == QLatin1String("x-yahoo")) {
693  ident = QLatin1String("X-messaging/yahoo-All");
694  } else if(identifier == QLatin1String("x-gadugadu")) {
695  ident = QLatin1String("X-messaging/gadu-All");
696  } else if(identifier == QLatin1String("x-skype")) {
697  ident = QLatin1String("X-messaging/skype-All");
698  } else if(identifier == QLatin1String("x-groupwise")) {
699  ident = QLatin1String("X-messaging/groupwise-All");
700  } else if(identifier == QLatin1String("x-sms")) {
701  ident = QLatin1String("X-messaging/sms-All");
702  } else if(identifier == QLatin1String("x-meanwhile")) {
703  ident = QLatin1String("X-messaging/meanwhile-All");
704  } else if ( identifier == QLatin1String( "x-irc" ) ) {
705  ident = QLatin1String( "X-messaging/irc-All" );
706  }
707 
708  const QString key = ident.mid( 2 );
709  const int dash = key.indexOf( QLatin1Char( '-' ) );
710  addr.insertCustom( key.left( dash ), key.mid( dash + 1 ), ( *lineIt ).value().toString() );
711  }
712  }
713  }
714 
715  addrList.append( addr );
716  }
717 
718  return addrList;
719 }
720 
721 QDateTime VCardTool::parseDateTime( const QString &str ) const
722 {
723  QDate date;
724  QTime time;
725 
726  if ( str.indexOf( QLatin1Char( '-' ) ) == -1 ) { // is base format (yyyymmdd)
727  date = QDate( str.left( 4 ).toInt(), str.mid( 4, 2 ).toInt(),
728  str.mid( 6, 2 ).toInt() );
729  } else { // is extended format yyyy-mm-dd
730  date = QDate( str.left( 4 ).toInt(), str.mid( 5, 2 ).toInt(),
731  str.mid( 8, 2 ).toInt() );
732  }
733 
734  // does it also contain a time ? (Note: mm, ss are optional according ISO-8601)
735  int timeStart = str.indexOf( QLatin1Char( 'T' ) );
736  if ( timeStart >= 0 ) {
737  int hour = 0, minute = 0, second = 0;
738 
739  hour = str.mid( timeStart + 1, 2 ).toInt(); // hour must always be given
740 
741  if ( str.indexOf( QLatin1Char( ':' ), timeStart + 1 ) > 0 ) { // extended format (hh:mm:ss)
742  if ( str.length() >= ( timeStart + 5 ) ) {
743  minute = str.mid( timeStart + 4, 2 ).toInt();
744  if ( str.length() >= ( timeStart + 8 ) ) {
745  second = str.mid( timeStart + 7, 2 ).toInt();
746  }
747  }
748  } else { // basic format (hhmmss)
749  if ( str.length() >= ( timeStart + 4 ) ) {
750  minute = str.mid( timeStart + 3, 2 ).toInt();
751  if ( str.length() >= ( timeStart + 6 ) ) {
752  second = str.mid( timeStart + 5, 2 ).toInt();
753  }
754  }
755  }
756 
757  time = QTime( hour, minute, second );
758  }
759 
760  Qt::TimeSpec spec = ( str.right( 1 ) == QLatin1String( "Z" ) ) ? Qt::UTC : Qt::LocalTime;
761 
762  QDateTime dateTime(date);
763 
764  // explicitly set the time, which might be invalid, to keep the information
765  // that the time is invalid. In createDateTime() the time/invalid flag is
766  // checked which omits then to print the timestamp
767  // This is needed to reproduce the given string in input
768  // e.g. BDAY:2008-12-30
769  // without time shall also result in a string without a time
770  dateTime.setTime(time);
771 
772  dateTime.setTimeSpec(spec);
773  return dateTime;
774 }
775 
776 QString VCardTool::createDateTime( const QDateTime &dateTime ) const
777 {
778  QString str;
779 
780  if ( dateTime.date().isValid() ) {
781  str.sprintf( "%4d-%02d-%02d", dateTime.date().year(), dateTime.date().month(),
782  dateTime.date().day() );
783  if ( dateTime.time().isValid() ) {
784  QString tmp;
785  tmp.sprintf( "T%02d:%02d:%02d", dateTime.time().hour(), dateTime.time().minute(),
786  dateTime.time().second() );
787  str += tmp;
788 
789  if ( dateTime.timeSpec() == Qt::UTC ) {
790  str += QLatin1Char( 'Z' );
791  }
792  }
793  }
794 
795  return str;
796 }
797 
798 Picture VCardTool::parsePicture( const VCardLine &line ) const
799 {
800  Picture pic;
801 
802  const QStringList params = line.parameterList();
803  if ( params.contains( QLatin1String( "encoding" ) ) ) {
804  QImage img;
805  img.loadFromData( line.value().toByteArray() );
806  pic.setData( img );
807  } else if ( params.contains( QLatin1String( "value" ) ) ) {
808  if ( line.parameter( QLatin1String( "value" ) ).toLower() == QLatin1String( "uri" ) ) {
809  pic.setUrl( line.value().toString() );
810  }
811  }
812 
813  if ( params.contains( QLatin1String( "type" ) ) ) {
814  pic.setType( line.parameter( QLatin1String( "type" ) ) );
815  }
816 
817  return pic;
818 }
819 
820 VCardLine VCardTool::createPicture( const QString &identifier, const Picture &pic ) const
821 {
822  VCardLine line( identifier );
823 
824  if ( pic.isIntern() ) {
825  if ( !pic.data().isNull() ) {
826  QByteArray input;
827  QBuffer buffer( &input );
828  buffer.open( QIODevice::WriteOnly );
829 
830  if ( !pic.data().hasAlphaChannel() ) {
831  pic.data().save( &buffer, "JPEG" );
832 
833  line.setValue( input );
834  line.addParameter( QLatin1String( "encoding" ), QLatin1String( "b" ) );
835  line.addParameter( QLatin1String( "type" ), QLatin1String( "jpeg" ) );
836  } else {
837  pic.data().save( &buffer, "PNG" );
838 
839  line.setValue( input );
840  line.addParameter( QLatin1String( "encoding" ), QLatin1String( "b" ) );
841  line.addParameter( QLatin1String( "type" ), QLatin1String( "png" ) );
842  }
843  }
844  } else if ( !pic.url().isEmpty() ) {
845  line.setValue( pic.url() );
846  line.addParameter( QLatin1String( "value" ), QLatin1String( "URI" ) );
847  }
848 
849  return line;
850 }
851 
852 Sound VCardTool::parseSound( const VCardLine &line ) const
853 {
854  Sound snd;
855 
856  const QStringList params = line.parameterList();
857  if ( params.contains( QLatin1String( "encoding" ) ) ) {
858  snd.setData( line.value().toByteArray() );
859  } else if ( params.contains( QLatin1String( "value" ) ) ) {
860  if ( line.parameter( QLatin1String( "value" ) ).toLower() == QLatin1String( "uri" ) ) {
861  snd.setUrl( line.value().toString() );
862  }
863  }
864 
865 /* TODO: support sound types
866  if ( params.contains( "type" ) )
867  snd.setType( line.parameter( "type" ) );
868 */
869 
870  return snd;
871 }
872 
873 VCardLine VCardTool::createSound( const Sound &snd ) const
874 {
875  VCardLine line( QLatin1String( "SOUND" ) );
876 
877  if ( snd.isIntern() ) {
878  if ( !snd.data().isEmpty() ) {
879  line.setValue( snd.data() );
880  line.addParameter( QLatin1String( "encoding" ), QLatin1String( "b" ) );
881  // TODO: need to store sound type!!!
882  }
883  } else if ( !snd.url().isEmpty() ) {
884  line.setValue( snd.url() );
885  line.addParameter( QLatin1String( "value" ), QLatin1String( "URI" ) );
886  }
887 
888  return line;
889 }
890 
891 Key VCardTool::parseKey( const VCardLine &line ) const
892 {
893  Key key;
894 
895  const QStringList params = line.parameterList();
896  if ( params.contains( QLatin1String( "encoding" ) ) ) {
897  key.setBinaryData( line.value().toByteArray() );
898  } else {
899  key.setTextData( line.value().toString() );
900  }
901 
902  if ( params.contains( QLatin1String( "type" ) ) ) {
903  if ( line.parameter( QLatin1String( "type" ) ).toLower() == QLatin1String( "x509" ) ) {
904  key.setType( Key::X509 );
905  } else if ( line.parameter( QLatin1String( "type" ) ).toLower() == QLatin1String( "pgp" ) ) {
906  key.setType( Key::PGP );
907  } else {
908  key.setType( Key::Custom );
909  key.setCustomTypeString( line.parameter( QLatin1String( "type" ) ) );
910  }
911  }
912 
913  return key;
914 }
915 
916 VCardLine VCardTool::createKey( const Key &key ) const
917 {
918  VCardLine line( QLatin1String( "KEY" ) );
919 
920  if ( key.isBinary() ) {
921  if ( !key.binaryData().isEmpty() ) {
922  line.setValue( key.binaryData() );
923  line.addParameter( QLatin1String( "encoding" ), QLatin1String( "b" ) );
924  }
925  } else if ( !key.textData().isEmpty() ) {
926  line.setValue( key.textData() );
927  }
928 
929  if ( key.type() == Key::X509 ) {
930  line.addParameter( QLatin1String( "type" ), QLatin1String( "X509" ) );
931  } else if ( key.type() == Key::PGP ) {
932  line.addParameter( QLatin1String( "type" ), QLatin1String( "PGP" ) );
933  } else if ( key.type() == Key::Custom ) {
934  line.addParameter( QLatin1String( "type" ), key.customTypeString() );
935  }
936 
937  return line;
938 }
939 
940 Secrecy VCardTool::parseSecrecy( const VCardLine &line ) const
941 {
942  Secrecy secrecy;
943 
944  const QString value = line.value().toString().toLower();
945  if ( value == QLatin1String( "public" ) ) {
946  secrecy.setType( Secrecy::Public );
947  } else if ( value == QLatin1String( "private" ) ) {
948  secrecy.setType( Secrecy::Private );
949  } else if ( value == QLatin1String( "confidential" ) ) {
950  secrecy.setType( Secrecy::Confidential );
951  }
952 
953  return secrecy;
954 }
955 
956 VCardLine VCardTool::createSecrecy( const Secrecy &secrecy ) const
957 {
958  VCardLine line( QLatin1String( "CLASS" ) );
959 
960  int type = secrecy.type();
961 
962  if ( type == Secrecy::Public ) {
963  line.setValue( QLatin1String( "PUBLIC" ) );
964  } else if ( type == Secrecy::Private ) {
965  line.setValue( QLatin1String( "PRIVATE" ) );
966  } else if ( type == Secrecy::Confidential ) {
967  line.setValue( QLatin1String( "CONFIDENTIAL" ) );
968  }
969 
970  return line;
971 }
972 
973 QStringList VCardTool::splitString( const QChar &sep, const QString &str ) const
974 {
975  QStringList list;
976  QString value( str );
977 
978  int start = 0;
979  int pos = value.indexOf( sep, start );
980 
981  while ( pos != -1 ) {
982  if ( pos == 0 || value[ pos - 1 ] != QLatin1Char( '\\' ) ) {
983  if ( pos > start && pos <= (int)value.length() ) {
984  list << value.mid( start, pos - start );
985  } else {
986  list << QString();
987  }
988 
989  start = pos + 1;
990  pos = value.indexOf( sep, start );
991  } else {
992  value.replace( pos - 1, 2, sep );
993  pos = value.indexOf( sep, pos );
994  }
995  }
996 
997  int l = value.length() - 1;
998  if ( value.mid( start, l - start + 1 ).length() > 0 ) {
999  list << value.mid( start, l - start + 1 );
1000  } else {
1001  list << QString();
1002  }
1003 
1004  return list;
1005 }
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Wed Nov 28 2012 21:59:38 by doxygen 1.8.1.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kabc

Skip menu "kabc"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Related Pages

kdepimlibs-4.9.3 API Reference

Skip menu "kdepimlibs-4.9.3 API Reference"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal