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