• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

kaddressbook

  • sources
  • kde-4.14
  • kdepim
  • kaddressbook
  • xxport
  • gmx
gmx_xxport.cpp
Go to the documentation of this file.
1 /*
2  This file is part of KAddressbook.
3  Copyright (c) 2003 - 2004 Helge Deller <deller@kde.org>
4  Copyright (c) 2009-2015 Laurent Montel <montel@kde.org>
5  Copyright (c) 2009 Urs Joss <tschenturs@gmx.ch>
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License along
18  with this program; if not, write to the Free Software Foundation, Inc.,
19  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 
21  As a special exception, permission is given to link this program
22  with any edition of Qt, and distribute the resulting executable,
23  without including the source code for Qt in the source distribution.
24 */
25 
26 /*
27  Description:
28 
29  This import/export filter reads and writes addressbook entries in the
30  gmx format which is natively used by the german freemail provider GMX.
31  The big advantage of this format is, that it stores it's information
32  very consistently and makes parsing pretty simple. Furthermore, most
33  information needed by KABC is available when compared to other formats.
34  For further information please visit http://www.gmx.com
35 
36  A couple of notes:
37 
38  a) Categories
39 
40  GMX allows to define categories in the UI and assign one or more categories
41  to each addressee. The gmxa file contains a list of defined categories in
42  the last part of the file, in the section AB_CATEGORIES. The Category_id in
43  this list is a 1-based index. The multi-category assignement of each
44  contact consists of a bitfield which applies one bit per category. E.g.
45  if one contact belongs to category 1 and 3, the bit-field for the category
46  assignment for this addressee is 0101 or decimal 5.
47 
48  The export of categories into hte gmxa file works flawlessly and also
49  transfers nicely into the addressee categories. During the import of a
50  gmxa file into GMX, the procedure will correctly manage the category
51  bitfield for each contact. However GMX does *not* process the category
52  list in the end of the file. In other words: If your categories have
53  changed (either in kadderssbook or in GMX) since your
54  previous import, the addressee records may point to the wrong - or even
55  non-existing - categories. After an import it is suggested that you
56  manually verify the category list is still valid. If not, you need to
57  manually delete any categories which alphabetically list beyond your new
58  or deleted category and recreate the remaining categories.
59 
60  Only up to 31 different categories over all contacts are exported. Any
61  more categories are ignored.
62 
63  b) Address types
64 
65  Home address and Work address are relatively straight forwardly handled.
66  The third address type "Other" is factored out of a bunch of different
67  address elements, which have been chosen relatively at random. There is
68  some interpretation which is not completely reversible.
69 
70  If you thus export a contact from kaddressbook to GMX
71  and reimport it into kaddressbook, you will not exactly
72  get the same contact as the original one.
73 
74  Also other items affect this non-reversability: GMX should receive a nick
75  name in the gmxa file. If there is none defined in kaddressbook,
76  the export will use the formatted name instead. If you reimport
77  such a record, you'll end up with the formatted name in the nickname field.
78 */
79 
80 #include "gmx_xxport.h"
81 #include "pimcommon/widgets/renamefiledialog.h"
82 
83 #include <KDebug>
84 #include <KFileDialog>
85 #include <KIO/NetAccess>
86 #include <KLocalizedString>
87 #include <KMessageBox>
88 #include <KTemporaryFile>
89 #include <KUrl>
90 
91 #include <QtCore/QFile>
92 #include <QtCore/QMap>
93 #include <QtCore/QList>
94 #include <QtCore/QTextStream>
95 
96 #define GMX_FILESELECTION_STRING QLatin1String("*.gmxa|") + i18n( "GMX address book file (*.gmxa)" )
97 
98 const int typeHome = 0;
99 const int typeWork = 1;
100 const int typeOther = 2;
101 
102 GMXXXPort::GMXXXPort( QWidget *parentWidget )
103  : XXPort( parentWidget )
104 {
105 }
106 
107 static bool checkDateTime( const QString &dateStr, QDateTime &dt )
108 {
109  if ( dateStr.isEmpty() ) {
110  return false;
111  }
112 
113  dt = QDateTime::fromString( dateStr, Qt::ISODate );
114  if ( dt.isValid() && dt.date().year() > 1901 ) {
115  return true;
116  }
117  dt.setDate( QDate() );
118 
119  return false;
120 }
121 
122 /* import */
123 
124 ContactList GMXXXPort::importContacts() const
125 {
126  ContactList contactList;
127  QString fileName =
128  KFileDialog::getOpenFileName( QDir::homePath(), GMX_FILESELECTION_STRING, 0 );
129 
130  if ( fileName.isEmpty() ) {
131  return contactList;
132  }
133 
134  QFile file( fileName );
135  if ( !file.open( QIODevice::ReadOnly ) ) {
136  QString msg = i18n( "<qt>Unable to open <b>%1</b> for reading.</qt>", fileName );
137  KMessageBox::error( parentWidget(), msg );
138  return contactList;
139  }
140 
141  QDateTime dt;
142  QTextStream gmxStream( &file );
143  gmxStream.setCodec( "ISO 8859-1" );
144  QString line, line2;
145  line = gmxStream.readLine();
146  line2 = gmxStream.readLine();
147  if ( !line.startsWith( QLatin1String( "AB_ADDRESSES:" ) ) ||
148  !line2.startsWith( QLatin1String( "Address_id" ) ) ) {
149  KMessageBox::error(
150  parentWidget(),
151  i18n( "%1 is not a GMX address book file.", fileName ) );
152  return contactList;
153  }
154 
155  QStringList itemList;
156  QMap<QString, QString> categoriesOfAddressee;
157  typedef QMap<QString, KABC::Addressee *> AddresseeMap;
158  AddresseeMap addresseeMap;
159 
160  // "Address_id,Nickname,Firstname,Lastname,Title,Birthday,Comments,
161  // Change_date,Status,Address_link_id,Categories"
162  line = gmxStream.readLine();
163  while ( ( line != QLatin1String( "####" ) ) && !gmxStream.atEnd() ) {
164  // an addressee entry may spread over several lines in the file
165  while ( 1 ) {
166  itemList = line.split( QLatin1Char('#'), QString::KeepEmptyParts );
167  if ( itemList.count() >= 11 ) {
168  break;
169  }
170  line.append( QLatin1Char('\n') );
171  line.append( gmxStream.readLine() );
172  };
173 
174  // populate the addressee
175  KABC::Addressee *addressee = new KABC::Addressee;
176  addressee->setNickName( itemList.at(1) );
177  addressee->setGivenName( itemList.at(2) );
178  addressee->setFamilyName( itemList.at(3) );
179  addressee->setFormattedName( itemList.at(3) + QLatin1String(", ") + itemList.at(2) );
180  addressee->setPrefix( itemList.at(4) );
181  if ( checkDateTime( itemList.at(5), dt ) ) {
182  addressee->setBirthday( dt );
183  }
184  addressee->setNote( itemList.at(6) );
185  if ( checkDateTime( itemList.at(7), dt ) ) {
186  addressee->setRevision( dt );
187  }
188  // addressee->setStatus( itemList[8] ); Status
189  // addressee->xxx( itemList[9] ); Address_link_id
190  categoriesOfAddressee[ itemList[0] ] = itemList[10];
191  addresseeMap[ itemList[0] ] = addressee;
192 
193  line = gmxStream.readLine();
194  }
195 
196  // now read the address records
197  line = gmxStream.readLine();
198  if ( !line.startsWith( QLatin1String( "AB_ADDRESS_RECORDS:" ) ) ) {
199  kWarning() << "Could not find address records!";
200  return contactList;
201  }
202  // Address_id,Record_id,Street,Country,Zipcode,City,Phone,Fax,Mobile,
203  // Mobile_type,Email,Homepage,Position,Comments,Record_type_id,Record_type,
204  // Company,Department,Change_date,Preferred,Status
205  line = gmxStream.readLine();
206  line = gmxStream.readLine();
207 
208  while ( !line.startsWith( QLatin1String( "####" ) ) && !gmxStream.atEnd() ) {
209  // an address entry may spread over several lines in the file
210  while ( 1 ) {
211  itemList = line.split( QLatin1Char('#'), QString::KeepEmptyParts );
212  if ( itemList.count() >= 21 ) {
213  break;
214  }
215  line.append( QLatin1Char('\n') );
216  line.append( gmxStream.readLine() );
217  };
218 
219  KABC::Addressee *addressee = addresseeMap[ itemList[0] ];
220  if ( addressee ) {
221  // itemList[1] = Record_id (numbered item, ignore here)
222  int recordTypeId = itemList[14].toInt();
223  KABC::Address::Type addressType;
224  KABC::PhoneNumber::Type phoneType;
225  switch ( recordTypeId ) {
226  case typeHome:
227  addressType = KABC::Address::Home;
228  phoneType = KABC::PhoneNumber::Home;
229  break;
230  case typeWork:
231  addressType = KABC::Address::Work;
232  phoneType = KABC::PhoneNumber::Work;
233  break;
234  case typeOther:
235  default:
236  addressType = KABC::Address::Intl;
237  phoneType = KABC::PhoneNumber::Voice;
238  break;
239  }
240  KABC::Address address = addressee->address( addressType );
241  address.setStreet( itemList[2] );
242  address.setCountry( itemList[3] );
243  address.setPostalCode( itemList[4] );
244  address.setLocality( itemList[5] );
245  if ( !itemList[6].isEmpty() ) {
246  addressee->insertPhoneNumber(
247  KABC::PhoneNumber( itemList[6], phoneType ) );
248  }
249  if ( !itemList[7].isEmpty() ) {
250  addressee->insertPhoneNumber(
251  KABC::PhoneNumber( itemList[7], KABC::PhoneNumber::Fax ) );
252  }
253  KABC::PhoneNumber::Type cellType = KABC::PhoneNumber::Cell;
254  // itemList[9]=Mobile_type // always 0 or -1(default phone).
255  // if ( itemList[19].toInt() & 4 ) cellType |= KABC::PhoneNumber::Pref;
256  // don't do the above to avoid duplicate mobile numbers
257  if ( !itemList[8].isEmpty() ) {
258  addressee->insertPhoneNumber( KABC::PhoneNumber( itemList[8], cellType ) );
259  }
260  bool preferred = false;
261  if ( itemList[19].toInt() & 1 ) {
262  preferred = true;
263  }
264  addressee->insertEmail( itemList[10], preferred );
265  if ( !itemList[11].isEmpty() ) {
266  addressee->setUrl( itemList[11] );
267  }
268  if ( !itemList[12].isEmpty() ) {
269  addressee->setRole( itemList[12] );
270  }
271  // itemList[13]=Comments
272  // itemList[14]=Record_type_id (0,1,2) - see above
273  // itemList[15]=Record_type (name of this additional record entry)
274  if ( !itemList[16].isEmpty() ) {
275  addressee->setOrganization( itemList[16] ); // Company
276  }
277  if ( !itemList[17].isEmpty() ) {
278  addressee->insertCustom( QLatin1String("KADDRESSBOOK"), QLatin1String("X-Department"), itemList[17] ); // Department
279  }
280  if ( checkDateTime( itemList[18], dt ) ) {
281  addressee->setRevision( dt ); // Change_date
282  }
283  // itemList[19]=Preferred (see above)
284  // itemList[20]=Status (should always be "1")
285  addressee->insertAddress( address );
286  } else {
287  kWarning() << "unresolved line:" << line;
288  }
289  line = gmxStream.readLine();
290  }
291 
292  // extract the categories from the list of addressees of the file to import
293  QStringList usedCategoryList;
294  line = gmxStream.readLine();
295  line2 = gmxStream.readLine();
296  if ( !line.startsWith( QLatin1String( "AB_CATEGORIES:" ) ) ||
297  !line2.startsWith( QLatin1String( "Category_id" ) ) ) {
298  kWarning() << "Could not find category records!";
299  } else {
300  while ( !line.startsWith( QLatin1String( "####" ) ) &&
301  !gmxStream.atEnd() ) {
302  // a category should not spread over multiple lines, but just in case
303  while ( 1 ) {
304  itemList = line.split( QLatin1Char('#'), QString::KeepEmptyParts );
305  if ( itemList.count() >= 3 ) {
306  break;
307  }
308  line.append( QLatin1Char('\n') );
309  line.append( gmxStream.readLine() );
310  };
311  usedCategoryList.append( itemList[1] );
312  line = gmxStream.readLine();
313  };
314  }
315  KABC::Addressee::List addresseeList;
316 
317  // now add the addresses to addresseeList
318  for ( AddresseeMap::Iterator addresseeIt = addresseeMap.begin();
319  addresseeIt != addresseeMap.end(); ++addresseeIt ) {
320  KABC::Addressee *addressee = addresseeIt.value();
321  // Add categories
322  // catgories is a bitfield with max 31 defined categories
323  int categories = categoriesOfAddressee[ addresseeIt.key() ].toInt();
324  for ( int i=32; i >= 0; --i ) {
325  // convert category index to bitfield value for comparison
326  int catBit = 1 << i;
327  if ( catBit > categories ) {
328  continue; // current index unassigned
329  }
330  if ( catBit & categories && usedCategoryList.count() > i ) {
331  addressee->insertCategory( usedCategoryList[i] );
332  }
333  }
334  addresseeList.append( *addressee );
335  delete addressee;
336  }
337 
338  file.close();
339  contactList.setAddressList(addresseeList);
340  return contactList;
341 }
342 
343 /* export */
344 
345 bool GMXXXPort::exportContacts( const ContactList &list, VCardExportSelectionWidget::ExportFields ) const
346 {
347  KUrl url = KFileDialog::getSaveUrl(
348  KUrl( QDir::homePath() + QLatin1String("/addressbook.gmx") ), GMX_FILESELECTION_STRING );
349  if ( url.isEmpty() ) {
350  return true;
351  }
352 
353  if ( QFileInfo( url.isLocalFile() ?
354  url.toLocalFile() : url.path() ).exists() ) {
355  if ( url.isLocalFile() && QFileInfo( url.toLocalFile() ).exists() ) {
356  PimCommon::RenameFileDialog::RenameFileDialogResult result = PimCommon::RenameFileDialog::RENAMEFILE_IGNORE;
357  PimCommon::RenameFileDialog *dialog = new PimCommon::RenameFileDialog(url, false, parentWidget());
358  result = static_cast<PimCommon::RenameFileDialog::RenameFileDialogResult>(dialog->exec());
359  if ( result == PimCommon::RenameFileDialog::RENAMEFILE_RENAME ) {
360  url = dialog->newName();
361  } else if (result == PimCommon::RenameFileDialog::RENAMEFILE_IGNORE) {
362  delete dialog;
363  return true;
364  }
365  delete dialog;
366  }
367  }
368 
369  if ( !url.isLocalFile() ) {
370  KTemporaryFile tmpFile;
371  if ( !tmpFile.open() ) {
372  QString txt = i18n( "<qt>Unable to open file <b>%1</b></qt>", url.url() );
373  KMessageBox::error( parentWidget(), txt );
374  return false;
375  }
376 
377  doExport( &tmpFile, list.addressList() );
378  tmpFile.flush();
379 
380  return KIO::NetAccess::upload( tmpFile.fileName(), url, parentWidget() );
381  } else {
382  QString fileName = url.toLocalFile();
383  QFile file( fileName );
384 
385  if ( !file.open( QIODevice::WriteOnly ) ) {
386  QString txt = i18n( "<qt>Unable to open file <b>%1</b>.</qt>", fileName );
387  KMessageBox::error( parentWidget(), txt );
388  return false;
389  }
390 
391  doExport( &file, list.addressList() );
392  file.close();
393 
394  return true;
395  }
396 }
397 
398 static const QString dateString( const QDateTime &dt )
399 {
400  if ( !dt.isValid() ) {
401  return QString::fromLatin1( "1000-01-01 00:00:00" );
402  }
403  QString d( dt.toString( Qt::ISODate ) );
404  d[10] = ' '; // remove the "T" in the middle of the string
405  return d;
406 }
407 
408 static const QStringList assignedCategoriesSorted( const KABC::AddresseeList &list )
409 {
410  // Walk through the addressees and return a unique list of up to 31
411  // categories, alphabetically sorted
412  QStringList categoryList;
413  const KABC::Addressee *addressee;
414  for ( KABC::AddresseeList::ConstIterator addresseeIt = list.begin();
415  addresseeIt != list.end() && categoryList.count() < 32; ++addresseeIt ) {
416  addressee = &( *addresseeIt );
417  if ( addressee->isEmpty() ) continue;
418  const QStringList categories = addressee->categories();
419  for ( int i=0; i < categories.count() && categoryList.count() < 32; ++i ) {
420  if ( !categoryList.contains( categories[i]) ) {
421  categoryList.append( categories[i] );
422  }
423  }
424  }
425  categoryList.sort();
426  return categoryList;
427 }
428 
429 void GMXXXPort::doExport( QFile *fp, const KABC::AddresseeList &list ) const
430 {
431  if ( !fp || !list.count() ) {
432  return;
433  }
434 
435  QTextStream t( fp );
436  t.setCodec( "ISO 8859-1" );
437 
438  typedef QMap<int, const KABC::Addressee *> AddresseeMap;
439  AddresseeMap addresseeMap;
440  const KABC::Addressee *addressee;
441 
442  t << "AB_ADDRESSES:\n";
443  t << "Address_id,Nickname,Firstname,Lastname,Title,Birthday,Comments,"
444  "Change_date,Status,Address_link_id,Categories\n";
445 
446  QList<QString> categoryMap;
447  categoryMap.append( assignedCategoriesSorted( list ) );
448 
449  int addresseeId = 0;
450  const QChar DELIM( QLatin1Char('#') );
451  for ( KABC::AddresseeList::ConstIterator it = list.begin();
452  it != list.end(); ++it ) {
453  addressee = &(*it);
454  if ( addressee->isEmpty() ) {
455  continue;
456  }
457  addresseeMap[ ++addresseeId ] = addressee;
458 
459  // Assign categories as bitfield
460  const QStringList categories = addressee->categories();
461  long int category = 0;
462  if ( categories.count() > 0 ) {
463  for ( int i=0; i < categories.count(); ++i ) {
464  if ( categoryMap.contains( categories[i] ) ) {
465  category |= 1 << categoryMap.indexOf( categories[i], 0 ) ;
466  }
467  }
468  }
469 
470  // GMX sorts by nickname by default - don't leave empty
471  QString nickName = addressee->nickName();
472  if ( nickName.isEmpty() ) {
473  nickName = addressee->formattedName();
474  }
475 
476  t << addresseeId << DELIM // Address_id
477  << nickName << DELIM // Nickname
478  << addressee->givenName() << DELIM // Firstname
479  << addressee->familyName() << DELIM // Lastname
480  << addressee->prefix() << DELIM // Title - Note: ->title()
481  // refers to the professional title
482  << dateString( addressee->birthday() ) << DELIM // Birthday
483  << addressee->note() /*.replace('\n',"\r\n")*/ << DELIM // Comments
484  << dateString( addressee->revision() ) << DELIM // Change_date
485  << "1" << DELIM // Status
486  << DELIM // Address_link_id
487  << category << endl; // Categories
488  }
489 
490  t << "####\n";
491  t << "AB_ADDRESS_RECORDS:\n";
492  t << "Address_id,Record_id,Street,Country,Zipcode,City,Phone,Fax,Mobile,"
493  "Mobile_type,Email,Homepage,Position,Comments,Record_type_id,Record_type,"
494  "Company,Department,Change_date,Preferred,Status\n";
495 
496  addresseeId = 1;
497  while ( ( addressee = addresseeMap[ addresseeId ] ) != 0 ) {
498 
499  const KABC::PhoneNumber::List cellPhones =
500  addressee->phoneNumbers( KABC::PhoneNumber::Cell );
501 
502  const QStringList emails = addressee->emails();
503 
504  for ( int recId=0; recId<3; ++recId ) {
505  KABC::Address address;
506  KABC::PhoneNumber phone, fax, cell;
507 
508  // address preference flag:
509  // & 1: preferred email address
510  // & 4: preferred cell phone
511  int prefFlag=0;
512 
513  switch ( recId ) {
514  // Assign address, phone and cellphone, fax if applicable
515  case typeHome:
516  address = addressee->address( KABC::Address::Home );
517  phone = addressee->phoneNumber( KABC::PhoneNumber::Home );
518  if ( cellPhones.count() > 0 ) {
519  cell = cellPhones.at( 0 );
520  if ( !cell.isEmpty() ) {
521  prefFlag |= 4;
522  }
523  }
524  break;
525  case typeWork:
526  address = addressee->address( KABC::Address::Work );
527  phone = addressee->phoneNumber( KABC::PhoneNumber::Work );
528  if ( cellPhones.count() >= 2 ) {
529  cell = cellPhones.at( 1 );
530  }
531  fax = addressee->phoneNumber( KABC::PhoneNumber::Fax );
532  break;
533  case typeOther:
534  default:
535  if ( addressee->addresses( KABC::Address::Home ).count() > 1 ) {
536  address = addressee->addresses( KABC::Address::Home ).at( 1 );
537  }
538  if ( ( address.isEmpty() ) &&
539  ( addressee->addresses( KABC::Address::Work ).count() > 1 ) ) {
540  address = addressee->addresses( KABC::Address::Work ).at( 1 );
541  }
542  if ( address.isEmpty() ) {
543  address = addressee->address( KABC::Address::Dom );
544  }
545  if ( address.isEmpty() ) {
546  address = addressee->address( KABC::Address::Intl );
547  }
548  if ( address.isEmpty() ) {
549  address = addressee->address( KABC::Address::Postal );
550  }
551  if ( address.isEmpty() ) {
552  address = addressee->address( KABC::Address::Parcel );
553  }
554 
555  if ( addressee->phoneNumbers( KABC::PhoneNumber::Home ).count() > 1 ) {
556  phone = addressee->phoneNumbers( KABC::PhoneNumber::Home ).at( 1 );
557  }
558  if ( ( phone.isEmpty() ) && ( addressee->phoneNumbers(
559  KABC::PhoneNumber::Work ).count() > 1 ) )
560  phone = addressee->phoneNumbers( KABC::PhoneNumber::Work ).at( 1 );
561  if ( phone.isEmpty() ) {
562  phone = addressee->phoneNumber( KABC::PhoneNumber::Voice );
563  }
564  if ( phone.isEmpty() ) {
565  phone = addressee->phoneNumber( KABC::PhoneNumber::Msg );
566  }
567  if ( phone.isEmpty() ) {
568  phone = addressee->phoneNumber( KABC::PhoneNumber::Isdn );
569  }
570  if ( phone.isEmpty() ) {
571  phone = addressee->phoneNumber( KABC::PhoneNumber::Car );
572  }
573  if ( phone.isEmpty() ) {
574  phone = addressee->phoneNumber( KABC::PhoneNumber::Pager );
575  }
576 
577  switch ( cellPhones.count() ) {
578  case 0:
579  break;
580  case 1:
581  case 2:
582  if ( !address.isEmpty() ) {
583  cell = cellPhones.at( 0 );
584  }
585  break;
586  default:
587  cell = cellPhones.at( 2 );
588  break;
589  }
590  break;
591  }
592 
593  QString email;
594  if ( emails.count()>recId ) {
595  email = emails[ recId ];
596  if ( email == addressee->preferredEmail() ) {
597  prefFlag |= 1;
598  }
599  }
600 
601  if ( !address.isEmpty() || !phone.isEmpty() ||
602  !cell.isEmpty() || !email.isEmpty() ) {
603  t << addresseeId << DELIM // Address_id
604  << recId << DELIM // Record_id
605  << address.street() << DELIM // Street
606  << address.country() << DELIM // Country
607  << address.postalCode() << DELIM // Zipcode
608  << address.locality() << DELIM // City
609  << phone.number() << DELIM // Phone
610  << fax.number() << DELIM // Fax
611  << cell.number() << DELIM // Mobile
612 
613  << ( ( recId == typeWork ) ? 0 : 1 ) << DELIM // Mobile_type
614 
615  << email << DELIM // Email
616 
617  << ( ( recId == typeWork ) ?
618  addressee->url().url() :
619  QString() ) << DELIM // Homepage
620 
621  << ( ( recId == typeWork ) ?
622  addressee->role() :
623  QString() ) << DELIM // Position
624 
625  << ( ( recId == typeHome ) ?
626  addressee->custom( QLatin1String("KADDRESSBOOK"), QLatin1String("X-SpousesName") ) :
627  QString() ) << DELIM // Comments
628 
629  << recId << DELIM // Record_type_id (0,1,2)
630 
631  << DELIM // Record_type
632 
633  << ( ( recId == typeWork ) ?
634  addressee->organization() :
635  QString() ) << DELIM // Company
636 
637  << ( ( recId == typeWork ) ?
638  addressee->custom( QLatin1String("KADDRESSBOOK"), QLatin1String("X-Department") ) :
639  QString() ) << DELIM // Department
640 
641  << dateString( addressee->revision() ) << DELIM // Change_date
642 
643  << prefFlag << DELIM // Preferred:
644  // ( & 1: preferred email,
645  // & 4: preferred cell phone )
646  << 1 << endl; // Status (should always be "1")
647  }
648  }
649 
650  ++addresseeId;
651  };
652 
653  t << "####" << endl;
654  t << "AB_CATEGORIES:" << endl;
655  t << "Category_id,Name,Icon_id" << endl;
656 
657  // Write Category List (beware: Category_ID 0 is reserved for none
658  // Interestingly: The index here is an int sequence and does not
659  // correspond to the bit reference used above.
660  for ( int i = 0; i < categoryMap.size(); ++i ) {
661  t << ( i + 1 ) << DELIM << categoryMap.at( i ) << DELIM << 0 << endl;
662  }
663  t << "####" << endl;
664 }
665 
QTextStream::setCodec
void setCodec(QTextCodec *codec)
QDateTime::toString
QString toString(Qt::DateFormat format) const
QWidget
QString::append
QString & append(QChar ch)
assignedCategoriesSorted
static const QStringList assignedCategoriesSorted(const KABC::AddresseeList &list)
Definition: gmx_xxport.cpp:408
QTextStream::readLine
QString readLine(qint64 maxlen)
ContactList::addressList
KABC::Addressee::List addressList() const
Definition: contactlist.cpp:64
GMXXXPort::importContacts
ContactList importContacts() const
Imports a list of contacts.
Definition: gmx_xxport.cpp:124
QChar
QString::split
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
QList::at
const T & at(int i) const
QMap
QStringList::contains
bool contains(const QString &str, Qt::CaseSensitivity cs) const
XXPort::parentWidget
QWidget * parentWidget() const
Returns the parent widget that can be used as parent for GUI components.
Definition: xxport.cpp:41
gmx_xxport.h
GMX_FILESELECTION_STRING
#define GMX_FILESELECTION_STRING
Definition: gmx_xxport.cpp:96
QDir::homePath
QString homePath()
QFile
QTextStream
QList::size
int size() const
QList::indexOf
int indexOf(const T &value, int from) const
typeWork
const int typeWork
Definition: gmx_xxport.cpp:99
typeHome
const int typeHome
Definition: gmx_xxport.cpp:98
QList::count
int count(const T &value) const
QList::append
void append(const T &value)
dateString
static const QString dateString(const QDateTime &dt)
Definition: gmx_xxport.cpp:398
QTextStream::atEnd
bool atEnd() const
ContactList
Definition: contactlist.h:27
QString::toInt
int toInt(bool *ok, int base) const
ContactList::setAddressList
void setAddressList(const KABC::Addressee::List &value)
Definition: contactlist.cpp:69
QString::isEmpty
bool isEmpty() const
QString::startsWith
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
checkDateTime
static bool checkDateTime(const QString &dateStr, QDateTime &dt)
Definition: gmx_xxport.cpp:107
QDateTime::setDate
void setDate(const QDate &date)
QDate
QDate::year
int year() const
QString
QList
QFile::open
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
QStringList
QFileInfo
XXPort
The base class for all import/export modules.
Definition: xxport.h:35
GMXXXPort::exportContacts
bool exportContacts(const ContactList &list, VCardExportSelectionWidget::ExportFields) const
Exports the list of contacts.
Definition: gmx_xxport.cpp:345
QLatin1Char
QDateTime::fromString
QDateTime fromString(const QString &string, Qt::DateFormat format)
QList::contains
bool contains(const T &value) const
QFile::close
virtual void close()
typeOther
const int typeOther
Definition: gmx_xxport.cpp:100
QDateTime::isValid
bool isValid() const
QDateTime::date
QDate date() const
QLatin1String
QString::fromLatin1
QString fromLatin1(const char *str, int size)
QStringList::sort
void sort()
GMXXXPort::GMXXXPort
GMXXXPort(QWidget *parent=0)
Definition: gmx_xxport.cpp:102
QDateTime
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:32:34 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kaddressbook

Skip menu "kaddressbook"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer
  • pimprint

Search



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