kaddressbook

vcard_xxport.cpp

00001 /*
00002     This file is part of KAddressbook.
00003     Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
00004 
00005     This program is free software; you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program; if not, write to the Free Software
00017     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018 
00019     As a special exception, permission is given to link this program
00020     with any edition of Qt, and distribute the resulting executable,
00021     without including the source code for Qt in the source distribution.
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             addrList += parseVCard( rawData );
00210 
00211           KIO::NetAccess::removeTempFile( fileName );
00212         } else {
00213           QString text = i18n( "<qt>When trying to read the vCard, there was an error opening the file '%1': %2</qt>" );
00214           text = text.arg( (*it).url() );
00215           text = text.arg( kapp->translate( "QFile",
00216                                             file.errorString().latin1() ) );
00217           KMessageBox::error( parentWidget(), text, caption );
00218           anyFailures = true;
00219         }
00220       } else {
00221         QString text = i18n( "<qt>Unable to access vCard: %1</qt>" );
00222         text = text.arg( KIO::NetAccess::lastErrorString() );
00223         KMessageBox::error( parentWidget(), text, caption );
00224         anyFailures = true;
00225       }
00226     }
00227 
00228     if ( !XXPortManager::importURL.isEmpty() ) { // a vcard was passed via cmd
00229       if ( addrList.isEmpty() ) {
00230         if ( anyFailures && urls.count() > 1 )
00231           KMessageBox::information( parentWidget(),
00232                                     i18n( "No contacts were imported, due to errors with the vCards." ) );
00233         else if ( !anyFailures )
00234           KMessageBox::information( parentWidget(), i18n( "The vCard does not contain any contacts." ) );
00235       } else {
00236         VCardViewerDialog dlg( addrList, parentWidget() );
00237         dlg.exec();
00238         addrList = dlg.contacts();
00239       }
00240     }
00241   }
00242 
00243   return addrList;
00244 }
00245 
00246 KABC::AddresseeList VCardXXPort::parseVCard( const QString &data ) const
00247 {
00248   KABC::VCardConverter converter;
00249 
00250   return converter.parseVCards( data );
00251 }
00252 
00253 bool VCardXXPort::doExport( const KURL &url, const QString &data )
00254 {
00255   KTempFile tmpFile;
00256   tmpFile.setAutoDelete( true );
00257 
00258   QTextStream stream( tmpFile.file() );
00259   stream.setEncoding( QTextStream::UnicodeUTF8 );
00260 
00261   stream << data;
00262   tmpFile.close();
00263 
00264   return KIO::NetAccess::upload( tmpFile.name(), url, parentWidget() );
00265 }
00266 
00267 KABC::AddresseeList VCardXXPort::filterContacts( const KABC::AddresseeList &addrList )
00268 {
00269   KABC::AddresseeList list;
00270 
00271   if ( addrList.isEmpty() )
00272     return addrList;
00273 
00274   VCardExportSelectionDialog dlg( parentWidget() );
00275   if ( !dlg.exec() )
00276     return list;
00277 
00278   KABC::AddresseeList::ConstIterator it;
00279   for ( it = addrList.begin(); it != addrList.end(); ++it ) {
00280     KABC::Addressee addr;
00281 
00282     addr.setUid( (*it).uid() );
00283     addr.setFormattedName( (*it).formattedName() );
00284     addr.setPrefix( (*it).prefix() );
00285     addr.setGivenName( (*it).givenName() );
00286     addr.setAdditionalName( (*it).additionalName() );
00287     addr.setFamilyName( (*it).familyName() );
00288     addr.setSuffix( (*it).suffix() );
00289     addr.setNickName( (*it).nickName() );
00290     addr.setMailer( (*it).mailer() );
00291     addr.setTimeZone( (*it).timeZone() );
00292     addr.setGeo( (*it).geo() );
00293     addr.setProductId( (*it).productId() );
00294     addr.setSortString( (*it).sortString() );
00295     addr.setUrl( (*it).url() );
00296     addr.setSecrecy( (*it).secrecy() );
00297     addr.setSound( (*it).sound() );
00298     addr.setEmails( (*it).emails() );
00299     addr.setCategories( (*it).categories() );
00300 
00301     if ( dlg.exportPrivateFields() ) {
00302       addr.setBirthday( (*it).birthday() );
00303       addr.setNote( (*it).note() );
00304       addr.setPhoto( (*it).photo() );
00305     }
00306 
00307     if ( dlg.exportBusinessFields() ) {
00308       addr.setTitle( (*it).title() );
00309       addr.setRole( (*it).role() );
00310       addr.setOrganization( (*it).organization() );
00311 
00312       addr.setLogo( (*it).logo() );
00313 
00314       KABC::PhoneNumber::List phones = (*it).phoneNumbers( KABC::PhoneNumber::Work );
00315       KABC::PhoneNumber::List::Iterator phoneIt;
00316       for ( phoneIt = phones.begin(); phoneIt != phones.end(); ++phoneIt )
00317         addr.insertPhoneNumber( *phoneIt );
00318 
00319       KABC::Address::List addresses = (*it).addresses( KABC::Address::Work );
00320       KABC::Address::List::Iterator addrIt;
00321       for ( addrIt = addresses.begin(); addrIt != addresses.end(); ++addrIt )
00322         addr.insertAddress( *addrIt );
00323     }
00324 
00325     KABC::PhoneNumber::List phones = (*it).phoneNumbers();
00326     KABC::PhoneNumber::List::Iterator phoneIt;
00327     for ( phoneIt = phones.begin(); phoneIt != phones.end(); ++phoneIt ) {
00328       int type = (*phoneIt).type();
00329 
00330       if ( type & KABC::PhoneNumber::Home && dlg.exportPrivateFields() )
00331         addr.insertPhoneNumber( *phoneIt );
00332       else if ( type & KABC::PhoneNumber::Work && dlg.exportBusinessFields() )
00333         addr.insertPhoneNumber( *phoneIt );
00334       else if ( dlg.exportOtherFields() )
00335         addr.insertPhoneNumber( *phoneIt );
00336     }
00337 
00338     KABC::Address::List addresses = (*it).addresses();
00339     KABC::Address::List::Iterator addrIt;
00340     for ( addrIt = addresses.begin(); addrIt != addresses.end(); ++addrIt ) {
00341       int type = (*addrIt).type();
00342 
00343       if ( type & KABC::Address::Home && dlg.exportPrivateFields() )
00344         addr.insertAddress( *addrIt );
00345       else if ( type & KABC::Address::Work && dlg.exportBusinessFields() )
00346         addr.insertAddress( *addrIt );
00347       else if ( dlg.exportOtherFields() )
00348         addr.insertAddress( *addrIt );
00349     }
00350 
00351     if ( dlg.exportOtherFields() )
00352       addr.setCustoms( (*it).customs() );
00353 
00354     if ( dlg.exportEncryptionKeys() ) {
00355       addKey( addr, KABC::Key::PGP );
00356       addKey( addr, KABC::Key::X509 );
00357     }
00358 
00359     list.append( addr );
00360   }
00361 
00362   return list;
00363 }
00364 
00365 void VCardXXPort::addKey( KABC::Addressee &addr, KABC::Key::Types type )
00366 {
00367   QString fingerprint = addr.custom( "KADDRESSBOOK",
00368                                      (type == KABC::Key::PGP ? "OPENPGPFP" : "SMIMEFP") );
00369   if ( fingerprint.isEmpty() )
00370     return;
00371 
00372   GpgME::Context * context = GpgME::Context::createForProtocol( GpgME::Context::OpenPGP );
00373   if ( !context ) {
00374     kdError() << "No context available" << endl;
00375     return;
00376   }
00377 
00378   context->setArmor( false );
00379   context->setTextMode( false );
00380 
00381   QGpgME::QByteArrayDataProvider dataProvider;
00382   GpgME::Data dataObj( &dataProvider );
00383   GpgME::Error error = context->exportPublicKeys( fingerprint.latin1(), dataObj );
00384   delete context;
00385 
00386   if ( error ) {
00387     kdError() << error.asString() << endl;
00388     return;
00389   }
00390 
00391   KABC::Key key;
00392   key.setType( type );
00393   key.setBinaryData( dataProvider.data() );
00394 
00395   addr.insertKey( key );
00396 }
00397 
00398 // ---------- VCardViewer Dialog ---------------- //
00399 
00400 VCardViewerDialog::VCardViewerDialog( const KABC::Addressee::List &list,
00401                                       QWidget *parent, const char *name )
00402   : KDialogBase( Plain, i18n( "Import vCard" ), Yes | No | Apply | Cancel, Yes,
00403                  parent, name, true, true, KStdGuiItem::no(), KStdGuiItem::yes() ),
00404     mContacts( list )
00405 {
00406   QFrame *page = plainPage();
00407   QVBoxLayout *layout = new QVBoxLayout( page, marginHint(), spacingHint() );
00408 
00409   QLabel *label = new QLabel( i18n( "Do you want to import this contact in your address book?" ), page );
00410   QFont font = label->font();
00411   font.setBold( true );
00412   label->setFont( font );
00413   layout->addWidget( label );
00414 
00415   mView = new KPIM::AddresseeView( page );
00416   mView->enableLinks( 0 );
00417   mView->setVScrollBarMode( QScrollView::Auto );
00418   layout->addWidget( mView );
00419 
00420   setButtonText( Apply, i18n( "Import All..." ) );
00421 
00422   mIt = mContacts.begin();
00423 
00424   updateView();
00425 }
00426 
00427 KABC::Addressee::List VCardViewerDialog::contacts() const
00428 {
00429   return mContacts;
00430 }
00431 
00432 void VCardViewerDialog::updateView()
00433 {
00434   mView->setAddressee( *mIt );
00435 
00436   KABC::Addressee::List::Iterator it = mIt;
00437   actionButton( Apply )->setEnabled( (++it) != mContacts.end() );
00438 }
00439 
00440 void VCardViewerDialog::slotUser1()
00441 {
00442   mIt = mContacts.remove( mIt );
00443 
00444   if ( mIt == mContacts.end() )
00445     slotApply();
00446 
00447   updateView();
00448 }
00449 
00450 void VCardViewerDialog::slotUser2()
00451 {
00452   mIt++;
00453 
00454   if ( mIt == mContacts.end() )
00455     slotApply();
00456 
00457   updateView();
00458 }
00459 
00460 void VCardViewerDialog::slotApply()
00461 {
00462   QDialog::accept();
00463 }
00464 
00465 void VCardViewerDialog::slotCancel()
00466 {
00467   mContacts.clear();
00468   QDialog::accept();
00469 }
00470 
00471 // ---------- VCardExportSelection Dialog ---------------- //
00472 
00473 VCardExportSelectionDialog::VCardExportSelectionDialog( QWidget *parent,
00474                                                         const char *name )
00475   : KDialogBase( Plain, i18n( "Select vCard Fields" ), Ok | Cancel, Ok,
00476                  parent, name, true, true )
00477 {
00478   QFrame *page = plainPage();
00479 
00480   QVBoxLayout *layout = new QVBoxLayout( page, marginHint(), spacingHint() );
00481 
00482   QLabel *label = new QLabel( i18n( "Select the fields which shall be exported in the vCard." ), page );
00483   layout->addWidget( label );
00484 
00485   mPrivateBox = new QCheckBox( i18n( "Private fields" ), page );
00486   layout->addWidget( mPrivateBox );
00487 
00488   mBusinessBox = new QCheckBox( i18n( "Business fields" ), page );
00489   layout->addWidget( mBusinessBox );
00490 
00491   mOtherBox = new QCheckBox( i18n( "Other fields" ), page );
00492   layout->addWidget( mOtherBox );
00493 
00494   mEncryptionKeys = new QCheckBox( i18n( "Encryption keys" ), page );
00495   layout->addWidget( mEncryptionKeys );
00496 
00497   KConfig config( "kaddressbookrc" );
00498   config.setGroup( "XXPortVCard" );
00499 
00500   mPrivateBox->setChecked( config.readBoolEntry( "ExportPrivateFields", true ) );
00501   mBusinessBox->setChecked( config.readBoolEntry( "ExportBusinessFields", false ) );
00502   mOtherBox->setChecked( config.readBoolEntry( "ExportOtherFields", false ) );
00503   mEncryptionKeys->setChecked( config.readBoolEntry( "ExportEncryptionKeys", false ) );
00504 }
00505 
00506 VCardExportSelectionDialog::~VCardExportSelectionDialog()
00507 {
00508   KConfig config( "kaddressbookrc" );
00509   config.setGroup( "XXPortVCard" );
00510 
00511   config.writeEntry( "ExportPrivateFields", mPrivateBox->isChecked() );
00512   config.writeEntry( "ExportBusinessFields", mBusinessBox->isChecked() );
00513   config.writeEntry( "ExportOtherFields", mOtherBox->isChecked() );
00514   config.writeEntry( "ExportEncryptionKeys", mEncryptionKeys->isChecked() );
00515 }
00516 
00517 bool VCardExportSelectionDialog::exportPrivateFields() const
00518 {
00519   return mPrivateBox->isChecked();
00520 }
00521 
00522 bool VCardExportSelectionDialog::exportBusinessFields() const
00523 {
00524   return mBusinessBox->isChecked();
00525 }
00526 
00527 bool VCardExportSelectionDialog::exportOtherFields() const
00528 {
00529   return mOtherBox->isChecked();
00530 }
00531 
00532 bool VCardExportSelectionDialog::exportEncryptionKeys() const
00533 {
00534   return mEncryptionKeys->isChecked();
00535 }
00536 
00537 #include "vcard_xxport.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys