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