• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.9.1 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  }
379  }
380 
381  VCardLine line( identifier, value );
382  if ( version == VCard::v2_1 && needsEncoding( value ) ) {
383  line.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) );
384  line.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) );
385  }
386  card.addLine( line );
387  }
388 
389  vCardList.append( card );
390  }
391 
392  return VCardParser::createVCards( vCardList );
393 }
394 
395 Addressee::List VCardTool::parseVCards( const QByteArray &vcard ) const
396 {
397  static const QLatin1Char semicolonSep( ';' );
398  static const QLatin1Char commaSep( ',' );
399  QString identifier;
400 
401  Addressee::List addrList;
402  const VCard::List vCardList = VCardParser::parseVCards( vcard );
403 
404  VCard::List::ConstIterator cardIt;
405  VCard::List::ConstIterator listEnd( vCardList.end() );
406  for ( cardIt = vCardList.begin(); cardIt != listEnd; ++cardIt ) {
407  Addressee addr;
408 
409  const QStringList idents = (*cardIt).identifiers();
410  QStringList::ConstIterator identIt;
411  QStringList::ConstIterator identEnd( idents.end() );
412  for ( identIt = idents.begin(); identIt != identEnd; ++identIt ) {
413  const VCardLine::List lines = (*cardIt).lines( (*identIt) );
414  VCardLine::List::ConstIterator lineIt;
415 
416  // iterate over the lines
417  for ( lineIt = lines.begin(); lineIt != lines.end(); ++lineIt ) {
418  identifier = (*lineIt).identifier().toLower();
419  // ADR
420  if ( identifier == QLatin1String( "adr" ) ) {
421  Address address;
422  const QStringList addrParts = splitString( semicolonSep, (*lineIt).value().toString() );
423  if ( addrParts.count() > 0 ) {
424  address.setPostOfficeBox( addrParts[ 0 ] );
425  }
426  if ( addrParts.count() > 1 ) {
427  address.setExtended( addrParts[ 1 ] );
428  }
429  if ( addrParts.count() > 2 ) {
430  address.setStreet( addrParts[ 2 ] );
431  }
432  if ( addrParts.count() > 3 ) {
433  address.setLocality( addrParts[ 3 ] );
434  }
435  if ( addrParts.count() > 4 ) {
436  address.setRegion( addrParts[ 4 ] );
437  }
438  if ( addrParts.count() > 5 ) {
439  address.setPostalCode( addrParts[ 5 ] );
440  }
441  if ( addrParts.count() > 6 ) {
442  address.setCountry( addrParts[ 6 ] );
443  }
444 
445  Address::Type type;
446 
447  const QStringList types = (*lineIt).parameters( QLatin1String( "type" ) );
448  for ( QStringList::ConstIterator it = types.begin(); it != types.end(); ++it ) {
449  type |= mAddressTypeMap[ (*it).toLower() ];
450  }
451 
452  address.setType( type );
453  addr.insertAddress( address );
454  }
455 
456  // BDAY
457  else if ( identifier == QLatin1String( "bday" ) ) {
458  addr.setBirthday( parseDateTime( (*lineIt).value().toString() ) );
459  }
460 
461  // CATEGORIES
462  else if ( identifier == QLatin1String( "categories" ) ) {
463  const QStringList categories = splitString( commaSep, (*lineIt).value().toString() );
464  addr.setCategories( categories );
465  }
466 
467  // CLASS
468  else if ( identifier == QLatin1String( "class" ) ) {
469  addr.setSecrecy( parseSecrecy( *lineIt ) );
470  }
471 
472  // EMAIL
473  else if ( identifier == QLatin1String( "email" ) ) {
474  const QStringList types = (*lineIt).parameters( QLatin1String( "type" ) );
475  addr.insertEmail( (*lineIt).value().toString(),
476  types.contains( QLatin1String( "PREF" ) ) );
477  }
478 
479  // FN
480  else if ( identifier == QLatin1String( "fn" ) ) {
481  addr.setFormattedName( (*lineIt).value().toString() );
482  }
483 
484  // GEO
485  else if ( identifier == QLatin1String( "geo" ) ) {
486  Geo geo;
487 
488  const QStringList geoParts =
489  (*lineIt).value().toString().split( QLatin1Char( ';' ), QString::KeepEmptyParts );
490  if ( geoParts.size() >= 2 ) {
491  geo.setLatitude( geoParts[ 0 ].toFloat() );
492  geo.setLongitude( geoParts[ 1 ].toFloat() );
493  addr.setGeo( geo );
494  }
495  }
496 
497  // KEY
498  else if ( identifier == QLatin1String( "key" ) ) {
499  addr.insertKey( parseKey( *lineIt ) );
500  }
501 
502  // LABEL
503  else if ( identifier == QLatin1String( "label" ) ) {
504  Address::Type type;
505 
506  const QStringList types = (*lineIt).parameters( QLatin1String( "type" ) );
507  for ( QStringList::ConstIterator it = types.begin(); it != types.end(); ++it ) {
508  type |= mAddressTypeMap[ (*it).toLower() ];
509  }
510 
511  bool available = false;
512  KABC::Address::List addressList = addr.addresses();
513  for ( KABC::Address::List::Iterator it = addressList.begin();
514  it != addressList.end(); ++it ) {
515  if ( (*it).type() == type ) {
516  (*it).setLabel( (*lineIt).value().toString() );
517  addr.insertAddress( *it );
518  available = true;
519  break;
520  }
521  }
522 
523  if ( !available ) { // a standalone LABEL tag
524  KABC::Address address( type );
525  address.setLabel( (*lineIt).value().toString() );
526  addr.insertAddress( address );
527  }
528  }
529 
530  // LOGO
531  else if ( identifier == QLatin1String( "logo" ) ) {
532  addr.setLogo( parsePicture( *lineIt ) );
533  }
534 
535  // MAILER
536  else if ( identifier == QLatin1String( "mailer" ) ) {
537  addr.setMailer( (*lineIt).value().toString() );
538  }
539 
540  // N
541  else if ( identifier == QLatin1String( "n" ) ) {
542  const QStringList nameParts = splitString( semicolonSep, (*lineIt).value().toString() );
543  const int numberOfParts(nameParts.count());
544  if ( numberOfParts > 0 ) {
545  addr.setFamilyName( nameParts[ 0 ] );
546  }
547  if ( numberOfParts > 1 ) {
548  addr.setGivenName( nameParts[ 1 ] );
549  }
550  if ( numberOfParts > 2 ) {
551  addr.setAdditionalName( nameParts[ 2 ] );
552  }
553  if ( numberOfParts > 3 ) {
554  addr.setPrefix( nameParts[ 3 ] );
555  }
556  if ( numberOfParts > 4 ) {
557  addr.setSuffix( nameParts[ 4 ] );
558  }
559  }
560 
561  // NAME
562  else if ( identifier == QLatin1String( "name" ) ) {
563  addr.setName( (*lineIt).value().toString() );
564  }
565 
566  // NICKNAME
567  else if ( identifier == QLatin1String( "nickname" ) ) {
568  addr.setNickName( (*lineIt).value().toString() );
569  }
570 
571  // NOTE
572  else if ( identifier == QLatin1String( "note" ) ) {
573  addr.setNote( (*lineIt).value().toString() );
574  }
575 
576  // ORGANIZATION
577  else if ( identifier == QLatin1String( "org" ) ) {
578  const QStringList orgParts = splitString( semicolonSep, (*lineIt).value().toString() );
579  if ( orgParts.count() > 0 ) {
580  addr.setOrganization( orgParts[ 0 ] );
581  }
582  if ( orgParts.count() > 1 ) {
583  addr.setDepartment( orgParts[ 1 ] );
584  }
585  }
586 
587  // PHOTO
588  else if ( identifier == QLatin1String( "photo" ) ) {
589  addr.setPhoto( parsePicture( *lineIt ) );
590  }
591 
592  // PROID
593  else if ( identifier == QLatin1String( "prodid" ) ) {
594  addr.setProductId( (*lineIt).value().toString() );
595  }
596 
597  // REV
598  else if ( identifier == QLatin1String( "rev" ) ) {
599  addr.setRevision( parseDateTime( (*lineIt).value().toString() ) );
600  }
601 
602  // ROLE
603  else if ( identifier == QLatin1String( "role" ) ) {
604  addr.setRole( (*lineIt).value().toString() );
605  }
606 
607  // SORT-STRING
608  else if ( identifier == QLatin1String( "sort-string" ) ) {
609  addr.setSortString( (*lineIt).value().toString() );
610  }
611 
612  // SOUND
613  else if ( identifier == QLatin1String( "sound" ) ) {
614  addr.setSound( parseSound( *lineIt ) );
615  }
616 
617  // TEL
618  else if ( identifier == QLatin1String( "tel" ) ) {
619  PhoneNumber phone;
620  phone.setNumber( (*lineIt).value().toString() );
621 
622  PhoneNumber::Type type;
623 
624  const QStringList types = (*lineIt).parameters( QLatin1String( "type" ) );
625  QStringList::ConstIterator typeEnd(types.end());
626  for ( QStringList::ConstIterator it = types.begin(); it != typeEnd; ++it ) {
627  type |= mPhoneTypeMap[(*it).toUpper()];
628  }
629 
630  phone.setType( type );
631 
632  addr.insertPhoneNumber( phone );
633  }
634 
635  // TITLE
636  else if ( identifier == QLatin1String( "title" ) ) {
637  addr.setTitle( (*lineIt).value().toString() );
638  }
639 
640  // TZ
641  else if ( identifier == QLatin1String( "tz" ) ) {
642  TimeZone tz;
643  const QString date = (*lineIt).value().toString();
644 
645  if ( !date.isEmpty() ) {
646  int hours = date.mid( 1, 2 ).toInt();
647  int minutes = date.mid( 4, 2 ).toInt();
648  int offset = ( hours * 60 ) + minutes;
649  offset = offset * ( date[ 0 ] == QLatin1Char( '+' ) ? 1 : -1 );
650 
651  tz.setOffset( offset );
652  addr.setTimeZone( tz );
653  }
654  }
655 
656  // UID
657  else if ( identifier == QLatin1String( "uid" ) ) {
658  addr.setUid( (*lineIt).value().toString() );
659  }
660 
661  // URL
662  else if ( identifier == QLatin1String( "url" ) ) {
663  addr.setUrl( KUrl( (*lineIt).value().toString() ) );
664  }
665 
666  // X-
667  else if ( identifier.startsWith( QLatin1String( "x-" ) ) ) {
668  QString ident = ( *lineIt ).identifier();
669  //X-Evolution
670  if(identifier==QLatin1String("x-evolution-spouse") || identifier == QLatin1String("x-spouse")) {
671  ident = QLatin1String("X-KADDRESSBOOK-X-SpousesName");
672  } else if(identifier == QLatin1String("x-evolution-blog-url")) {
673  ident = QLatin1String("X-KADDRESSBOOK-BlogFeed");
674  } else if(identifier == QLatin1String("x-evolution-assistant") || identifier == QLatin1String("x-assistant")) {
675  ident = QLatin1String("X-KADDRESSBOOK-X-AssistantsName");
676  } else if(identifier == QLatin1String("x-evolution-anniversary") || identifier == QLatin1String("x-anniversary")) {
677  ident = QLatin1String("X-KADDRESSBOOK-X-Anniversary");
678  } else if(identifier == QLatin1String("x-evolution-manager") || identifier == QLatin1String("x-manager")) {
679  ident = QLatin1String("X-KADDRESSBOOK-X-ManagersName");
680  } else if(identifier == QLatin1String("x-aim")) {
681  ident = QLatin1String("X-messaging/aim-All");
682  } else if(identifier == QLatin1String("x-icq")) {
683  ident = QLatin1String("X-messaging/icq-All");
684  } else if(identifier == QLatin1String("x-jabber")) {
685  ident = QLatin1String("X-messaging/xmpp-All");
686  } else if(identifier == QLatin1String("x-jabber")) {
687  ident = QLatin1String("X-messaging/xmpp-All");
688  } else if(identifier == QLatin1String("x-msn")) {
689  ident = QLatin1String("X-messaging/msn-All");
690  } else if(identifier == QLatin1String("x-yahoo")) {
691  ident = QLatin1String("X-messaging/yahoo-All");
692  } else if(identifier == QLatin1String("x-gadugadu")) {
693  ident = QLatin1String("X-messaging/gadu-All");
694  } else if(identifier == QLatin1String("x-skype")) {
695  ident = QLatin1String("X-messaging/skype-All");
696  } else if(identifier == QLatin1String("x-groupwise")) {
697  ident = QLatin1String("X-messaging/groupwise-All");
698  } else if(identifier == QLatin1String("x-sms")) {
699  ident = QLatin1String("X-messaging/sms-All");
700  } else if(identifier == QLatin1String("x-meanwhile")) {
701  ident = QLatin1String("X-messaging/meanwhile-All");
702  }
703 
704  const QString key = ident.mid( 2 );
705  const int dash = key.indexOf( QLatin1Char( '-' ) );
706  addr.insertCustom( key.left( dash ), key.mid( dash + 1 ), ( *lineIt ).value().toString() );
707  }
708  }
709  }
710 
711  addrList.append( addr );
712  }
713 
714  return addrList;
715 }
716 
717 QDateTime VCardTool::parseDateTime( const QString &str ) const
718 {
719  QDate date;
720  QTime time;
721 
722  if ( str.indexOf( QLatin1Char( '-' ) ) == -1 ) { // is base format (yyyymmdd)
723  date = QDate( str.left( 4 ).toInt(), str.mid( 4, 2 ).toInt(),
724  str.mid( 6, 2 ).toInt() );
725  } else { // is extended format yyyy-mm-dd
726  date = QDate( str.left( 4 ).toInt(), str.mid( 5, 2 ).toInt(),
727  str.mid( 8, 2 ).toInt() );
728  }
729 
730  // does it also contain a time ? (Note: mm, ss are optional according ISO-8601)
731  int timeStart = str.indexOf( QLatin1Char( 'T' ) );
732  if ( timeStart >= 0 ) {
733  int hour = 0, minute = 0, second = 0;
734 
735  hour = str.mid( timeStart + 1, 2 ).toInt(); // hour must always be given
736 
737  if ( str.indexOf( QLatin1Char( ':' ), timeStart + 1 ) > 0 ) { // extended format (hh:mm:ss)
738  if ( str.length() >= ( timeStart + 5 ) ) {
739  minute = str.mid( timeStart + 4, 2 ).toInt();
740  if ( str.length() >= ( timeStart + 8 ) ) {
741  second = str.mid( timeStart + 7, 2 ).toInt();
742  }
743  }
744  } else { // basic format (hhmmss)
745  if ( str.length() >= ( timeStart + 4 ) ) {
746  minute = str.mid( timeStart + 3, 2 ).toInt();
747  if ( str.length() >= ( timeStart + 6 ) ) {
748  second = str.mid( timeStart + 5, 2 ).toInt();
749  }
750  }
751  }
752 
753  time = QTime( hour, minute, second );
754  }
755 
756  Qt::TimeSpec spec = ( str.right( 1 ) == QLatin1String( "Z" ) ) ? Qt::UTC : Qt::LocalTime;
757 
758  QDateTime dateTime(date);
759 
760  // explicitly set the time, which might be invalid, to keep the information
761  // that the time is invalid. In createDateTime() the time/invalid flag is
762  // checked which omits then to print the timestamp
763  // This is needed to reproduce the given string in input
764  // e.g. BDAY:2008-12-30
765  // without time shall also result in a string without a time
766  dateTime.setTime(time);
767 
768  dateTime.setTimeSpec(spec);
769  return dateTime;
770 }
771 
772 QString VCardTool::createDateTime( const QDateTime &dateTime ) const
773 {
774  QString str;
775 
776  if ( dateTime.date().isValid() ) {
777  str.sprintf( "%4d-%02d-%02d", dateTime.date().year(), dateTime.date().month(),
778  dateTime.date().day() );
779  if ( dateTime.time().isValid() ) {
780  QString tmp;
781  tmp.sprintf( "T%02d:%02d:%02d", dateTime.time().hour(), dateTime.time().minute(),
782  dateTime.time().second() );
783  str += tmp;
784 
785  if ( dateTime.timeSpec() == Qt::UTC ) {
786  str += QLatin1Char( 'Z' );
787  }
788  }
789  }
790 
791  return str;
792 }
793 
794 Picture VCardTool::parsePicture( const VCardLine &line ) const
795 {
796  Picture pic;
797 
798  const QStringList params = line.parameterList();
799  if ( params.contains( QLatin1String( "encoding" ) ) ) {
800  QImage img;
801  img.loadFromData( line.value().toByteArray() );
802  pic.setData( img );
803  } else if ( params.contains( QLatin1String( "value" ) ) ) {
804  if ( line.parameter( QLatin1String( "value" ) ).toLower() == QLatin1String( "uri" ) ) {
805  pic.setUrl( line.value().toString() );
806  }
807  }
808 
809  if ( params.contains( QLatin1String( "type" ) ) ) {
810  pic.setType( line.parameter( QLatin1String( "type" ) ) );
811  }
812 
813  return pic;
814 }
815 
816 VCardLine VCardTool::createPicture( const QString &identifier, const Picture &pic ) const
817 {
818  VCardLine line( identifier );
819 
820  if ( pic.isIntern() ) {
821  if ( !pic.data().isNull() ) {
822  QByteArray input;
823  QBuffer buffer( &input );
824  buffer.open( QIODevice::WriteOnly );
825 
826  if ( !pic.data().hasAlphaChannel() ) {
827  pic.data().save( &buffer, "JPEG" );
828 
829  line.setValue( input );
830  line.addParameter( QLatin1String( "encoding" ), QLatin1String( "b" ) );
831  line.addParameter( QLatin1String( "type" ), QLatin1String( "image/jpeg" ) );
832  } else {
833  pic.data().save( &buffer, "PNG" );
834 
835  line.setValue( input );
836  line.addParameter( QLatin1String( "encoding" ), QLatin1String( "b" ) );
837  line.addParameter( QLatin1String( "type" ), QLatin1String( "image/png" ) );
838  }
839  }
840  } else if ( !pic.url().isEmpty() ) {
841  line.setValue( pic.url() );
842  line.addParameter( QLatin1String( "value" ), QLatin1String( "URI" ) );
843  }
844 
845  return line;
846 }
847 
848 Sound VCardTool::parseSound( const VCardLine &line ) const
849 {
850  Sound snd;
851 
852  const QStringList params = line.parameterList();
853  if ( params.contains( QLatin1String( "encoding" ) ) ) {
854  snd.setData( line.value().toByteArray() );
855  } else if ( params.contains( QLatin1String( "value" ) ) ) {
856  if ( line.parameter( QLatin1String( "value" ) ).toLower() == QLatin1String( "uri" ) ) {
857  snd.setUrl( line.value().toString() );
858  }
859  }
860 
861 /* TODO: support sound types
862  if ( params.contains( "type" ) )
863  snd.setType( line.parameter( "type" ) );
864 */
865 
866  return snd;
867 }
868 
869 VCardLine VCardTool::createSound( const Sound &snd ) const
870 {
871  VCardLine line( QLatin1String( "SOUND" ) );
872 
873  if ( snd.isIntern() ) {
874  if ( !snd.data().isEmpty() ) {
875  line.setValue( snd.data() );
876  line.addParameter( QLatin1String( "encoding" ), QLatin1String( "b" ) );
877  // TODO: need to store sound type!!!
878  }
879  } else if ( !snd.url().isEmpty() ) {
880  line.setValue( snd.url() );
881  line.addParameter( QLatin1String( "value" ), QLatin1String( "URI" ) );
882  }
883 
884  return line;
885 }
886 
887 Key VCardTool::parseKey( const VCardLine &line ) const
888 {
889  Key key;
890 
891  const QStringList params = line.parameterList();
892  if ( params.contains( QLatin1String( "encoding" ) ) ) {
893  key.setBinaryData( line.value().toByteArray() );
894  } else {
895  key.setTextData( line.value().toString() );
896  }
897 
898  if ( params.contains( QLatin1String( "type" ) ) ) {
899  if ( line.parameter( QLatin1String( "type" ) ).toLower() == QLatin1String( "x509" ) ) {
900  key.setType( Key::X509 );
901  } else if ( line.parameter( QLatin1String( "type" ) ).toLower() == QLatin1String( "pgp" ) ) {
902  key.setType( Key::PGP );
903  } else {
904  key.setType( Key::Custom );
905  key.setCustomTypeString( line.parameter( QLatin1String( "type" ) ) );
906  }
907  }
908 
909  return key;
910 }
911 
912 VCardLine VCardTool::createKey( const Key &key ) const
913 {
914  VCardLine line( QLatin1String( "KEY" ) );
915 
916  if ( key.isBinary() ) {
917  if ( !key.binaryData().isEmpty() ) {
918  line.setValue( key.binaryData() );
919  line.addParameter( QLatin1String( "encoding" ), QLatin1String( "b" ) );
920  }
921  } else if ( !key.textData().isEmpty() ) {
922  line.setValue( key.textData() );
923  }
924 
925  if ( key.type() == Key::X509 ) {
926  line.addParameter( QLatin1String( "type" ), QLatin1String( "X509" ) );
927  } else if ( key.type() == Key::PGP ) {
928  line.addParameter( QLatin1String( "type" ), QLatin1String( "PGP" ) );
929  } else if ( key.type() == Key::Custom ) {
930  line.addParameter( QLatin1String( "type" ), key.customTypeString() );
931  }
932 
933  return line;
934 }
935 
936 Secrecy VCardTool::parseSecrecy( const VCardLine &line ) const
937 {
938  Secrecy secrecy;
939 
940  const QString value = line.value().toString().toLower();
941  if ( value == QLatin1String( "public" ) ) {
942  secrecy.setType( Secrecy::Public );
943  } else if ( value == QLatin1String( "private" ) ) {
944  secrecy.setType( Secrecy::Private );
945  } else if ( value == QLatin1String( "confidential" ) ) {
946  secrecy.setType( Secrecy::Confidential );
947  }
948 
949  return secrecy;
950 }
951 
952 VCardLine VCardTool::createSecrecy( const Secrecy &secrecy ) const
953 {
954  VCardLine line( QLatin1String( "CLASS" ) );
955 
956  int type = secrecy.type();
957 
958  if ( type == Secrecy::Public ) {
959  line.setValue( QLatin1String( "PUBLIC" ) );
960  } else if ( type == Secrecy::Private ) {
961  line.setValue( QLatin1String( "PRIVATE" ) );
962  } else if ( type == Secrecy::Confidential ) {
963  line.setValue( QLatin1String( "CONFIDENTIAL" ) );
964  }
965 
966  return line;
967 }
968 
969 QStringList VCardTool::splitString( const QChar &sep, const QString &str ) const
970 {
971  QStringList list;
972  QString value( str );
973 
974  int start = 0;
975  int pos = value.indexOf( sep, start );
976 
977  while ( pos != -1 ) {
978  if ( pos == 0 || value[ pos - 1 ] != QLatin1Char( '\\' ) ) {
979  if ( pos > start && pos <= (int)value.length() ) {
980  list << value.mid( start, pos - start );
981  } else {
982  list << QString();
983  }
984 
985  start = pos + 1;
986  pos = value.indexOf( sep, start );
987  } else {
988  value.replace( pos - 1, 2, sep );
989  pos = value.indexOf( sep, pos );
990  }
991  }
992 
993  int l = value.length() - 1;
994  if ( value.mid( start, l - start + 1 ).length() > 0 ) {
995  list << value.mid( start, l - start + 1 );
996  } else {
997  list << QString();
998  }
999 
1000  return list;
1001 }
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Sep 24 2012 09:09:51 by doxygen 1.8.1.1 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.1 API Reference

Skip menu "kdepimlibs-4.9.1 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