00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <qcheckbox.h>
00025 #include <qfile.h>
00026 #include <qfont.h>
00027 #include <qlabel.h>
00028 #include <qlayout.h>
00029 #include <qpushbutton.h>
00030 #include <qtextcodec.h>
00031
00032 #include <kabc/vcardconverter.h>
00033 #include <kdialogbase.h>
00034 #include <kfiledialog.h>
00035 #include <kio/netaccess.h>
00036 #include <klocale.h>
00037 #include <kmessagebox.h>
00038 #include <ktempfile.h>
00039 #include <kurl.h>
00040 #include <libkdepim/addresseeview.h>
00041
00042 #include "config.h"
00043
00044 #include "gpgmepp/context.h"
00045 #include "gpgmepp/data.h"
00046 #include "gpgmepp/key.h"
00047 #include "qgpgme/dataprovider.h"
00048
00049 #include "xxportmanager.h"
00050
00051 #include "vcard_xxport.h"
00052
00053 class VCardXXPortFactory : public KAB::XXPortFactory
00054 {
00055 public:
00056 KAB::XXPort *xxportObject( KABC::AddressBook *ab, QWidget *parent, const char *name )
00057 {
00058 return new VCardXXPort( ab, parent, name );
00059 }
00060 };
00061
00062 extern "C"
00063 {
00064 void *init_libkaddrbk_vcard_xxport()
00065 {
00066 return ( new VCardXXPortFactory() );
00067 }
00068 }
00069
00070 class VCardViewerDialog : public KDialogBase
00071 {
00072 public:
00073 VCardViewerDialog( const KABC::Addressee::List &list,
00074 QWidget *parent, const char *name = 0 );
00075
00076 KABC::Addressee::List contacts() const;
00077
00078 protected:
00079 void slotUser1();
00080 void slotUser2();
00081 void slotApply();
00082 void slotCancel();
00083
00084 private:
00085 void updateView();
00086
00087 KPIM::AddresseeView *mView;
00088
00089 KABC::Addressee::List mContacts;
00090 KABC::Addressee::List::Iterator mIt;
00091 };
00092
00093 class VCardExportSelectionDialog : public KDialogBase
00094 {
00095 public:
00096 VCardExportSelectionDialog( QWidget *parent, const char *name = 0 );
00097 ~VCardExportSelectionDialog();
00098
00099 bool exportPrivateFields() const;
00100 bool exportBusinessFields() const;
00101 bool exportOtherFields() const;
00102 bool exportEncryptionKeys() const;
00103
00104 private:
00105 QCheckBox *mPrivateBox;
00106 QCheckBox *mBusinessBox;
00107 QCheckBox *mOtherBox;
00108 QCheckBox *mEncryptionKeys;
00109 };
00110
00111 VCardXXPort::VCardXXPort( KABC::AddressBook *ab, QWidget *parent, const char *name )
00112 : KAB::XXPort( ab, parent, name )
00113 {
00114 createImportAction( i18n( "Import vCard..." ) );
00115 createExportAction( i18n( "Export vCard 2.1..." ), "v21" );
00116 createExportAction( i18n( "Export vCard 3.0..." ), "v30" );
00117 }
00118
00119 bool VCardXXPort::exportContacts( const KABC::AddresseeList &addrList, const QString &data )
00120 {
00121 KABC::VCardConverter converter;
00122 KURL url;
00123 KABC::AddresseeList list;
00124
00125 list = filterContacts( addrList );
00126
00127 bool ok = true;
00128 if ( list.isEmpty() ) {
00129 return ok;
00130 } else if ( list.count() == 1 ) {
00131 url = KFileDialog::getSaveURL( list[ 0 ].givenName() + "_" + list[ 0 ].familyName() + ".vcf" );
00132 if ( url.isEmpty() )
00133 return true;
00134
00135 if ( data == "v21" )
00136 ok = doExport( url, converter.createVCards( list, KABC::VCardConverter::v2_1 ) );
00137 else
00138 ok = doExport( url, converter.createVCards( list, KABC::VCardConverter::v3_0 ) );
00139 } else {
00140 QString msg = i18n( "You have selected a list of contacts, shall they be "
00141 "exported to several files?" );
00142
00143 switch ( KMessageBox::questionYesNo( parentWidget(), msg ) ) {
00144 case KMessageBox::Yes: {
00145 KURL baseUrl = KFileDialog::getExistingURL();
00146 if ( baseUrl.isEmpty() )
00147 return true;
00148
00149 KABC::AddresseeList::ConstIterator it;
00150 for ( it = list.begin(); it != list.end(); ++it ) {
00151 url = baseUrl.url() + "/" + (*it).givenName() + "_" + (*it).familyName() + ".vcf";
00152
00153 bool tmpOk;
00154 KABC::AddresseeList tmpList;
00155 tmpList.append( *it );
00156
00157 if ( data == "v21" )
00158 tmpOk = doExport( url, converter.createVCards( tmpList, KABC::VCardConverter::v2_1 ) );
00159 else
00160 tmpOk = doExport( url, converter.createVCards( tmpList, KABC::VCardConverter::v3_0 ) );
00161
00162 ok = ok && tmpOk;
00163 }
00164 break;
00165 }
00166 case KMessageBox::No:
00167 default: {
00168 url = KFileDialog::getSaveURL( "addressbook.vcf" );
00169 if ( url.isEmpty() )
00170 return true;
00171
00172 if ( data == "v21" )
00173 ok = doExport( url, converter.createVCards( list, KABC::VCardConverter::v2_1 ) );
00174 else
00175 ok = doExport( url, converter.createVCards( list, KABC::VCardConverter::v3_0 ) );
00176 }
00177 }
00178 }
00179
00180 return ok;
00181 }
00182
00183 KABC::AddresseeList VCardXXPort::importContacts( const QString& ) const
00184 {
00185 QString fileName;
00186 KABC::AddresseeList addrList;
00187 KURL::List urls;
00188
00189 if ( !XXPortManager::importData.isEmpty() )
00190 addrList = parseVCard( XXPortManager::importData );
00191 else {
00192 if ( XXPortManager::importURL.isEmpty() )
00193 urls = KFileDialog::getOpenURLs( QString::null, "*.vcf|vCards", parentWidget(),
00194 i18n( "Select vCard to Import" ) );
00195 else
00196 urls.append( XXPortManager::importURL );
00197
00198 if ( urls.count() == 0 )
00199 return addrList;
00200
00201 QString caption( i18n( "vCard Import Failed" ) );
00202 KURL::List::Iterator it;
00203 for ( it = urls.begin(); it != urls.end(); ++it ) {
00204 if ( KIO::NetAccess::download( *it, fileName, parentWidget() ) ) {
00205
00206 QFile file( fileName );
00207
00208 file.open( IO_ReadOnly );
00209 QByteArray rawData = file.readAll();
00210 file.close();
00211
00212 QTextCodec *codec = QTextCodec::codecForContent( rawData.data(), 50 );
00213
00214 QString data;
00215 if ( codec )
00216 data = codec->toUnicode( rawData.data(), rawData.size() );
00217 else
00218 data = QString::fromUtf8( rawData.data(), rawData.size() );
00219 addrList += parseVCard( data );
00220
00221 KIO::NetAccess::removeTempFile( fileName );
00222 } else {
00223 QString text = i18n( "<qt>Unable to access <b>%1</b>.</qt>" );
00224 KMessageBox::error( parentWidget(), text.arg( (*it).url() ), caption );
00225 }
00226 }
00227
00228 if ( !XXPortManager::importURL.isEmpty() ) {
00229 if ( addrList.isEmpty() ) {
00230 KMessageBox::information( parentWidget(), i18n( "The vCard does not contain any contacts." ) );
00231 } else {
00232 VCardViewerDialog dlg( addrList, parentWidget() );
00233 dlg.exec();
00234 addrList = dlg.contacts();
00235 }
00236 }
00237 }
00238
00239 return addrList;
00240 }
00241
00242 KABC::AddresseeList VCardXXPort::parseVCard( const QString &data ) const
00243 {
00244 KABC::VCardConverter converter;
00245
00246 return converter.parseVCards( data );
00247 }
00248
00249 bool VCardXXPort::doExport( const KURL &url, const QString &data )
00250 {
00251 KTempFile tmpFile;
00252 tmpFile.setAutoDelete( true );
00253
00254 QTextStream stream( tmpFile.file() );
00255 stream.setEncoding( QTextStream::UnicodeUTF8 );
00256
00257 stream << data;
00258 tmpFile.close();
00259
00260 return KIO::NetAccess::upload( tmpFile.name(), url, parentWidget() );
00261 }
00262
00263 KABC::AddresseeList VCardXXPort::filterContacts( const KABC::AddresseeList &addrList )
00264 {
00265 KABC::AddresseeList list;
00266
00267 if ( addrList.isEmpty() )
00268 return addrList;
00269
00270 VCardExportSelectionDialog dlg( parentWidget() );
00271 if ( !dlg.exec() )
00272 return list;
00273
00274 KABC::AddresseeList::ConstIterator it;
00275 for ( it = addrList.begin(); it != addrList.end(); ++it ) {
00276 KABC::Addressee addr;
00277
00278 addr.setUid( (*it).uid() );
00279 addr.setFormattedName( (*it).formattedName() );
00280 addr.setPrefix( (*it).prefix() );
00281 addr.setGivenName( (*it).givenName() );
00282 addr.setAdditionalName( (*it).additionalName() );
00283 addr.setFamilyName( (*it).familyName() );
00284 addr.setSuffix( (*it).suffix() );
00285 addr.setNickName( (*it).nickName() );
00286 addr.setMailer( (*it).mailer() );
00287 addr.setTimeZone( (*it).timeZone() );
00288 addr.setGeo( (*it).geo() );
00289 addr.setProductId( (*it).productId() );
00290 addr.setSortString( (*it).sortString() );
00291 addr.setUrl( (*it).url() );
00292 addr.setSecrecy( (*it).secrecy() );
00293 addr.setSound( (*it).sound() );
00294 addr.setEmails( (*it).emails() );
00295 addr.setCategories( (*it).categories() );
00296
00297 if ( dlg.exportPrivateFields() ) {
00298 addr.setBirthday( (*it).birthday() );
00299 addr.setNote( (*it).note() );
00300 addr.setPhoto( (*it).photo() );
00301 }
00302
00303 if ( dlg.exportBusinessFields() ) {
00304 addr.setTitle( (*it).title() );
00305 addr.setRole( (*it).role() );
00306 addr.setOrganization( (*it).organization() );
00307
00308 addr.setLogo( (*it).logo() );
00309
00310 KABC::PhoneNumber::List phones = (*it).phoneNumbers( KABC::PhoneNumber::Work );
00311 KABC::PhoneNumber::List::Iterator phoneIt;
00312 for ( phoneIt = phones.begin(); phoneIt != phones.end(); ++phoneIt )
00313 addr.insertPhoneNumber( *phoneIt );
00314
00315 KABC::Address::List addresses = (*it).addresses( KABC::Address::Work );
00316 KABC::Address::List::Iterator addrIt;
00317 for ( addrIt = addresses.begin(); addrIt != addresses.end(); ++addrIt )
00318 addr.insertAddress( *addrIt );
00319 }
00320
00321 KABC::PhoneNumber::List phones = (*it).phoneNumbers();
00322 KABC::PhoneNumber::List::Iterator phoneIt;
00323 for ( phoneIt = phones.begin(); phoneIt != phones.end(); ++phoneIt ) {
00324 int type = (*phoneIt).type();
00325
00326 if ( type & KABC::PhoneNumber::Home && dlg.exportPrivateFields() )
00327 addr.insertPhoneNumber( *phoneIt );
00328 else if ( type & KABC::PhoneNumber::Work && dlg.exportBusinessFields() )
00329 addr.insertPhoneNumber( *phoneIt );
00330 else if ( dlg.exportOtherFields() )
00331 addr.insertPhoneNumber( *phoneIt );
00332 }
00333
00334 KABC::Address::List addresses = (*it).addresses();
00335 KABC::Address::List::Iterator addrIt;
00336 for ( addrIt = addresses.begin(); addrIt != addresses.end(); ++addrIt ) {
00337 int type = (*addrIt).type();
00338
00339 if ( type & KABC::Address::Home && dlg.exportPrivateFields() )
00340 addr.insertAddress( *addrIt );
00341 else if ( type & KABC::Address::Work && dlg.exportBusinessFields() )
00342 addr.insertAddress( *addrIt );
00343 else if ( dlg.exportOtherFields() )
00344 addr.insertAddress( *addrIt );
00345 }
00346
00347 if ( dlg.exportOtherFields() )
00348 addr.setCustoms( (*it).customs() );
00349
00350 if ( dlg.exportEncryptionKeys() ) {
00351 addKey( addr, KABC::Key::PGP );
00352 addKey( addr, KABC::Key::X509 );
00353 }
00354
00355 list.append( addr );
00356 }
00357
00358 return list;
00359 }
00360
00361 void VCardXXPort::addKey( KABC::Addressee &addr, KABC::Key::Types type )
00362 {
00363 QString fingerprint = addr.custom( "KADDRESSBOOK",
00364 (type == KABC::Key::PGP ? "OPENPGPFP" : "SMIMEFP") );
00365 if ( fingerprint.isEmpty() )
00366 return;
00367
00368 GpgME::Context * context = GpgME::Context::createForProtocol( GpgME::Context::OpenPGP );
00369 if ( !context ) {
00370 kdError() << "No context available" << endl;
00371 return;
00372 }
00373
00374 context->setArmor( false );
00375 context->setTextMode( false );
00376
00377 QGpgME::QByteArrayDataProvider dataProvider;
00378 GpgME::Data dataObj( &dataProvider );
00379 GpgME::Error error = context->exportPublicKeys( fingerprint.latin1(), dataObj );
00380
00381 if ( error ) {
00382 kdError() << error.asString() << endl;
00383 return;
00384 }
00385
00386 KABC::Key key;
00387 key.setType( type );
00388 key.setBinaryData( dataProvider.data() );
00389
00390 addr.insertKey( key );
00391 }
00392
00393
00394
00395 VCardViewerDialog::VCardViewerDialog( const KABC::Addressee::List &list,
00396 QWidget *parent, const char *name )
00397 : KDialogBase( Plain, i18n( "Import vCard" ), Yes | No | Apply | Cancel, Yes,
00398 parent, name, true, true, KStdGuiItem::no(), KStdGuiItem::yes() ),
00399 mContacts( list )
00400 {
00401 QFrame *page = plainPage();
00402 QVBoxLayout *layout = new QVBoxLayout( page, marginHint(), spacingHint() );
00403
00404 QLabel *label = new QLabel( i18n( "Do you want to import this contact in your address book?" ), page );
00405 QFont font = label->font();
00406 font.setBold( true );
00407 label->setFont( font );
00408 layout->addWidget( label );
00409
00410 mView = new KPIM::AddresseeView( page );
00411 mView->enableLinks( 0 );
00412 mView->setVScrollBarMode( QScrollView::Auto );
00413 layout->addWidget( mView );
00414
00415 setButtonText( Apply, i18n( "Import All..." ) );
00416
00417 mIt = mContacts.begin();
00418
00419 updateView();
00420 }
00421
00422 KABC::Addressee::List VCardViewerDialog::contacts() const
00423 {
00424 return mContacts;
00425 }
00426
00427 void VCardViewerDialog::updateView()
00428 {
00429 mView->setAddressee( *mIt );
00430
00431 KABC::Addressee::List::Iterator it = mIt;
00432 actionButton( Apply )->setEnabled( (++it) != mContacts.end() );
00433 }
00434
00435 void VCardViewerDialog::slotUser1()
00436 {
00437 mIt = mContacts.remove( mIt );
00438
00439 if ( mIt == mContacts.end() )
00440 slotApply();
00441
00442 updateView();
00443 }
00444
00445 void VCardViewerDialog::slotUser2()
00446 {
00447 mIt++;
00448
00449 if ( mIt == mContacts.end() )
00450 slotApply();
00451
00452 updateView();
00453 }
00454
00455 void VCardViewerDialog::slotApply()
00456 {
00457 QDialog::accept();
00458 }
00459
00460 void VCardViewerDialog::slotCancel()
00461 {
00462 mContacts.clear();
00463 QDialog::accept();
00464 }
00465
00466
00467
00468 VCardExportSelectionDialog::VCardExportSelectionDialog( QWidget *parent,
00469 const char *name )
00470 : KDialogBase( Plain, i18n( "Select vCard Fields" ), Ok | Cancel, Ok,
00471 parent, name, true, true )
00472 {
00473 QFrame *page = plainPage();
00474
00475 QVBoxLayout *layout = new QVBoxLayout( page, marginHint(), spacingHint() );
00476
00477 QLabel *label = new QLabel( i18n( "Select the fields which shall be exported in the vCard." ), page );
00478 layout->addWidget( label );
00479
00480 mPrivateBox = new QCheckBox( i18n( "Private fields" ), page );
00481 layout->addWidget( mPrivateBox );
00482
00483 mBusinessBox = new QCheckBox( i18n( "Business fields" ), page );
00484 layout->addWidget( mBusinessBox );
00485
00486 mOtherBox = new QCheckBox( i18n( "Other fields" ), page );
00487 layout->addWidget( mOtherBox );
00488
00489 mEncryptionKeys = new QCheckBox( i18n( "Encryption keys" ), page );
00490 layout->addWidget( mEncryptionKeys );
00491
00492 KConfig config( "kaddressbookrc" );
00493 config.setGroup( "XXPortVCard" );
00494
00495 mPrivateBox->setChecked( config.readBoolEntry( "ExportPrivateFields", true ) );
00496 mBusinessBox->setChecked( config.readBoolEntry( "ExportBusinessFields", false ) );
00497 mOtherBox->setChecked( config.readBoolEntry( "ExportOtherFields", false ) );
00498 mEncryptionKeys->setChecked( config.readBoolEntry( "ExportEncryptionKeys", false ) );
00499 }
00500
00501 VCardExportSelectionDialog::~VCardExportSelectionDialog()
00502 {
00503 KConfig config( "kaddressbookrc" );
00504 config.setGroup( "XXPortVCard" );
00505
00506 config.writeEntry( "ExportPrivateFields", mPrivateBox->isChecked() );
00507 config.writeEntry( "ExportBusinessFields", mBusinessBox->isChecked() );
00508 config.writeEntry( "ExportOtherFields", mOtherBox->isChecked() );
00509 config.writeEntry( "ExportEncryptionKeys", mEncryptionKeys->isChecked() );
00510 }
00511
00512 bool VCardExportSelectionDialog::exportPrivateFields() const
00513 {
00514 return mPrivateBox->isChecked();
00515 }
00516
00517 bool VCardExportSelectionDialog::exportBusinessFields() const
00518 {
00519 return mBusinessBox->isChecked();
00520 }
00521
00522 bool VCardExportSelectionDialog::exportOtherFields() const
00523 {
00524 return mOtherBox->isChecked();
00525 }
00526
00527 bool VCardExportSelectionDialog::exportEncryptionKeys() const
00528 {
00529 return mEncryptionKeys->isChecked();
00530 }
00531
00532 #include "vcard_xxport.moc"