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   delete context;
00387 
00388   if ( error ) {
00389     kdError() << error.asString() << endl;
00390     return;
00391   }
00392 
00393   KABC::Key key;
00394   key.setType( type );
00395   key.setBinaryData( dataProvider.data() );
00396 
00397   addr.insertKey( key );
00398 }
00399 
00400 // ---------- VCardViewer Dialog ---------------- //
00401 
00402 VCardViewerDialog::VCardViewerDialog( const KABC::Addressee::List &list,
00403                                       QWidget *parent, const char *name )
00404   : KDialogBase( Plain, i18n( "Import vCard" ), Yes | No | Apply | Cancel, Yes,
00405                  parent, name, true, true, KStdGuiItem::no(), KStdGuiItem::yes() ),
00406     mContacts( list )
00407 {
00408   QFrame *page = plainPage();
00409   QVBoxLayout *layout = new QVBoxLayout( page, marginHint(), spacingHint() );
00410 
00411   QLabel *label = new QLabel( i18n( "Do you want to import this contact in your address book?" ), page );
00412   QFont font = label->font();
00413   font.setBold( true );
00414   label->setFont( font );
00415   layout->addWidget( label );
00416 
00417   mView = new KPIM::AddresseeView( page );
00418   mView->enableLinks( 0 );
00419   mView->setVScrollBarMode( QScrollView::Auto );
00420   layout->addWidget( mView );
00421 
00422   setButtonText( Apply, i18n( "Import All..." ) );
00423 
00424   mIt = mContacts.begin();
00425 
00426   updateView();
00427 }
00428 
00429 KABC::Addressee::List VCardViewerDialog::contacts() const
00430 {
00431   return mContacts;
00432 }
00433 
00434 void VCardViewerDialog::updateView()
00435 {
00436   mView->setAddressee( *mIt );
00437 
00438   KABC::Addressee::List::Iterator it = mIt;
00439   actionButton( Apply )->setEnabled( (++it) != mContacts.end() );
00440 }
00441 
00442 void VCardViewerDialog::slotUser1()
00443 {
00444   mIt = mContacts.remove( mIt );
00445 
00446   if ( mIt == mContacts.end() )
00447     slotApply();
00448 
00449   updateView();
00450 }
00451 
00452 void VCardViewerDialog::slotUser2()
00453 {
00454   mIt++;
00455 
00456   if ( mIt == mContacts.end() )
00457     slotApply();
00458 
00459   updateView();
00460 }
00461 
00462 void VCardViewerDialog::slotApply()
00463 {
00464   QDialog::accept();
00465 }
00466 
00467 void VCardViewerDialog::slotCancel()
00468 {
00469   mContacts.clear();
00470   QDialog::accept();
00471 }
00472 
00473 // ---------- VCardExportSelection Dialog ---------------- //
00474 
00475 VCardExportSelectionDialog::VCardExportSelectionDialog( QWidget *parent,
00476                                                         const char *name )
00477   : KDialogBase( Plain, i18n( "Select vCard Fields" ), Ok | Cancel, Ok,
00478                  parent, name, true, true )
00479 {
00480   QFrame *page = plainPage();
00481 
00482   QVBoxLayout *layout = new QVBoxLayout( page, marginHint(), spacingHint() );
00483 
00484   QLabel *label = new QLabel( i18n( "Select the fields which shall be exported in the vCard." ), page );
00485   layout->addWidget( label );
00486 
00487   mPrivateBox = new QCheckBox( i18n( "Private fields" ), page );
00488   layout->addWidget( mPrivateBox );
00489 
00490   mBusinessBox = new QCheckBox( i18n( "Business fields" ), page );
00491   layout->addWidget( mBusinessBox );
00492 
00493   mOtherBox = new QCheckBox( i18n( "Other fields" ), page );
00494   layout->addWidget( mOtherBox );
00495 
00496   mEncryptionKeys = new QCheckBox( i18n( "Encryption keys" ), page );
00497   layout->addWidget( mEncryptionKeys );
00498 
00499   KConfig config( "kaddressbookrc" );
00500   config.setGroup( "XXPortVCard" );
00501 
00502   mPrivateBox->setChecked( config.readBoolEntry( "ExportPrivateFields", true ) );
00503   mBusinessBox->setChecked( config.readBoolEntry( "ExportBusinessFields", false ) );
00504   mOtherBox->setChecked( config.readBoolEntry( "ExportOtherFields", false ) );
00505   mEncryptionKeys->setChecked( config.readBoolEntry( "ExportEncryptionKeys", false ) );
00506 }
00507 
00508 VCardExportSelectionDialog::~VCardExportSelectionDialog()
00509 {
00510   KConfig config( "kaddressbookrc" );
00511   config.setGroup( "XXPortVCard" );
00512 
00513   config.writeEntry( "ExportPrivateFields", mPrivateBox->isChecked() );
00514   config.writeEntry( "ExportBusinessFields", mBusinessBox->isChecked() );
00515   config.writeEntry( "ExportOtherFields", mOtherBox->isChecked() );
00516   config.writeEntry( "ExportEncryptionKeys", mEncryptionKeys->isChecked() );
00517 }
00518 
00519 bool VCardExportSelectionDialog::exportPrivateFields() const
00520 {
00521   return mPrivateBox->isChecked();
00522 }
00523 
00524 bool VCardExportSelectionDialog::exportBusinessFields() const
00525 {
00526   return mBusinessBox->isChecked();
00527 }
00528 
00529 bool VCardExportSelectionDialog::exportOtherFields() const
00530 {
00531   return mOtherBox->isChecked();
00532 }
00533 
00534 bool VCardExportSelectionDialog::exportEncryptionKeys() const
00535 {
00536   return mEncryptionKeys->isChecked();
00537 }
00538 
00539 #include "vcard_xxport.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys