TDE personal information management applications
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

vcard_xxport.cpp 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. /*
  2. This file is part of KAddressbook.
  3. Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  15. As a special exception, permission is given to link this program
  16. with any edition of TQt, and distribute the resulting executable,
  17. without including the source code for TQt in the source distribution.
  18. */
  19. #include <tqcheckbox.h>
  20. #include <tqfile.h>
  21. #include <tqfont.h>
  22. #include <tqlabel.h>
  23. #include <tqlayout.h>
  24. #include <tqpushbutton.h>
  25. #include <kabc/vcardconverter.h>
  26. #include <kdialogbase.h>
  27. #include <kfiledialog.h>
  28. #include <kio/netaccess.h>
  29. #include <klocale.h>
  30. #include <kmessagebox.h>
  31. #include <ktempfile.h>
  32. #include <kurl.h>
  33. #include <kapplication.h>
  34. #include <libtdepim/addresseeview.h>
  35. #include "config.h" // ??
  36. #include "gpgmepp/context.h"
  37. #include "gpgmepp/data.h"
  38. #include "gpgmepp/key.h"
  39. #include "qgpgme/dataprovider.h"
  40. #include "xxportmanager.h"
  41. #include "vcard_xxport.h"
  42. K_EXPORT_KADDRESSBOOK_XXFILTER( libkaddrbk_vcard_xxport, VCardXXPort )
  43. class VCardViewerDialog : public KDialogBase
  44. {
  45. public:
  46. VCardViewerDialog( const KABC::Addressee::List &list,
  47. TQWidget *parent, const char *name = 0 );
  48. KABC::Addressee::List contacts() const;
  49. protected:
  50. void slotUser1();
  51. void slotUser2();
  52. void slotApply();
  53. void slotCancel();
  54. private:
  55. void updateView();
  56. KPIM::AddresseeView *mView;
  57. KABC::Addressee::List mContacts;
  58. KABC::Addressee::List::Iterator mIt;
  59. };
  60. class VCardExportSelectionDialog : public KDialogBase
  61. {
  62. public:
  63. VCardExportSelectionDialog( TQWidget *parent, const char *name = 0 );
  64. ~VCardExportSelectionDialog();
  65. bool exportPrivateFields() const;
  66. bool exportBusinessFields() const;
  67. bool exportOtherFields() const;
  68. bool exportEncryptionKeys() const;
  69. private:
  70. TQCheckBox *mPrivateBox;
  71. TQCheckBox *mBusinessBox;
  72. TQCheckBox *mOtherBox;
  73. TQCheckBox *mEncryptionKeys;
  74. };
  75. VCardXXPort::VCardXXPort( KABC::AddressBook *ab, TQWidget *parent, const char *name )
  76. : KAB::XXPort( ab, parent, name )
  77. {
  78. createImportAction( i18n( "Import vCard..." ) );
  79. createExportAction( i18n( "Export vCard 2.1..." ), "v21" );
  80. createExportAction( i18n( "Export vCard 3.0..." ), "v30" );
  81. }
  82. bool VCardXXPort::exportContacts( const KABC::AddresseeList &addrList, const TQString &data )
  83. {
  84. KABC::VCardConverter converter;
  85. KURL url;
  86. KABC::AddresseeList list;
  87. list = filterContacts( addrList );
  88. bool ok = true;
  89. if ( list.isEmpty() ) {
  90. return ok;
  91. } else if ( list.count() == 1 ) {
  92. url = KFileDialog::getSaveURL( list[ 0 ].givenName() + "_" + list[ 0 ].familyName() + ".vcf" );
  93. if ( url.isEmpty() )
  94. return true;
  95. if ( data == "v21" )
  96. #if defined(KABC_VCARD_ENCODING_FIX)
  97. ok = doExport( url, converter.createVCardsRaw( list, KABC::VCardConverter::v2_1 ) );
  98. else
  99. ok = doExport( url, converter.createVCardsRaw( list, KABC::VCardConverter::v3_0 ) );
  100. #else
  101. ok = doExport( url, converter.createVCards( list, KABC::VCardConverter::v2_1 ) );
  102. else
  103. ok = doExport( url, converter.createVCards( list, KABC::VCardConverter::v3_0 ) );
  104. #endif
  105. } else {
  106. TQString msg = i18n( "You have selected a list of contacts, shall they be "
  107. "exported to several files?" );
  108. switch ( KMessageBox::questionYesNo( parentWidget(), msg, TQString(), i18n("Export to Several Files"), i18n("Export to One File") ) ) {
  109. case KMessageBox::Yes: {
  110. KURL baseUrl = KFileDialog::getExistingURL();
  111. if ( baseUrl.isEmpty() )
  112. return true;
  113. KABC::AddresseeList::ConstIterator it;
  114. uint counter = 0;
  115. for ( it = list.begin(); it != list.end(); ++it ) {
  116. TQString testUrl;
  117. if ( (*it).givenName().isEmpty() && (*it).familyName().isEmpty() )
  118. testUrl = baseUrl.url() + "/" + (*it).organization();
  119. else
  120. testUrl = baseUrl.url() + "/" + (*it).givenName() + "_" + (*it).familyName();
  121. if ( KIO::NetAccess::exists( testUrl + (counter == 0 ? "" : TQString::number( counter )) + ".vcf", false, parentWidget() ) ) {
  122. counter++;
  123. url = testUrl + TQString::number( counter ) + ".vcf";
  124. } else
  125. url = testUrl + ".vcf";
  126. bool tmpOk;
  127. KABC::AddresseeList tmpList;
  128. tmpList.append( *it );
  129. if ( data == "v21" )
  130. #if defined(KABC_VCARD_ENCODING_FIX)
  131. tmpOk = doExport( url, converter.createVCardsRaw( tmpList, KABC::VCardConverter::v2_1 ) );
  132. else
  133. tmpOk = doExport( url, converter.createVCardsRaw( tmpList, KABC::VCardConverter::v3_0 ) );
  134. #else
  135. tmpOk = doExport( url, converter.createVCards( tmpList, KABC::VCardConverter::v2_1 ) );
  136. else
  137. tmpOk = doExport( url, converter.createVCards( tmpList, KABC::VCardConverter::v3_0 ) );
  138. #endif
  139. ok = ok && tmpOk;
  140. }
  141. break;
  142. }
  143. case KMessageBox::No:
  144. default: {
  145. url = KFileDialog::getSaveURL( "addressbook.vcf" );
  146. if ( url.isEmpty() )
  147. return true;
  148. if ( data == "v21" )
  149. #if defined(KABC_VCARD_ENCODING_FIX)
  150. ok = doExport( url, converter.createVCardsRaw( list, KABC::VCardConverter::v2_1 ) );
  151. else
  152. ok = doExport( url, converter.createVCardsRaw( list, KABC::VCardConverter::v3_0 ) );
  153. #else
  154. ok = doExport( url, converter.createVCards( list, KABC::VCardConverter::v2_1 ) );
  155. else
  156. ok = doExport( url, converter.createVCards( list, KABC::VCardConverter::v3_0 ) );
  157. #endif
  158. }
  159. }
  160. }
  161. return ok;
  162. }
  163. KABC::AddresseeList VCardXXPort::importContacts( const TQString& ) const
  164. {
  165. TQString fileName;
  166. KABC::AddresseeList addrList;
  167. KURL::List urls;
  168. if ( !XXPortManager::importData.isEmpty() ) {
  169. #if defined(KABC_VCARD_ENCODING_FIX)
  170. TQCString data = XXPortManager::importData.ascii();
  171. addrList = parseVCard( data );
  172. #else
  173. addrList = parseVCard( XXPortManager::importData );
  174. #endif
  175. } else {
  176. if ( XXPortManager::importURL.isEmpty() )
  177. urls = KFileDialog::getOpenURLs( TQString(), "*.vcf|vCards", parentWidget(),
  178. i18n( "Select vCard to Import" ) );
  179. else
  180. urls.append( XXPortManager::importURL );
  181. if ( urls.count() == 0 )
  182. return addrList;
  183. TQString caption( i18n( "vCard Import Failed" ) );
  184. bool anyFailures = false;
  185. KURL::List::Iterator it;
  186. for ( it = urls.begin(); it != urls.end(); ++it ) {
  187. if ( KIO::NetAccess::download( *it, fileName, parentWidget() ) ) {
  188. TQFile file( fileName );
  189. if ( file.open( IO_ReadOnly ) ) {
  190. #if defined(KABC_VCARD_ENCODING_FIX)
  191. TQByteArray data = file.readAll();
  192. file.close();
  193. if ( data.size() > 0 )
  194. addrList += parseVCard( data );
  195. #else
  196. TQByteArray rawData = file.readAll();
  197. file.close();
  198. if ( rawData.size() > 0 ) {
  199. TQString vCardText;
  200. // With version 3.0, vCards are encoded with UTF-8 by default. Otherwise, use tqfromLatin1()
  201. // and hope that are fields are encoded correctly.
  202. if ( TQString::tqfromLatin1( rawData ).lower().contains( "version:3.0" ) ) {
  203. vCardText = TQString::fromUtf8( rawData );
  204. } else {
  205. vCardText = TQString::tqfromLatin1( rawData );
  206. }
  207. addrList += parseVCard( vCardText );
  208. }
  209. #endif
  210. KIO::NetAccess::removeTempFile( fileName );
  211. } else {
  212. TQString text = i18n( "<qt>When trying to read the vCard, there was an error opening the file '%1': %2</qt>" );
  213. text = text.tqarg( (*it).url() );
  214. text = text.tqarg( kapp->translate( "TQFile",
  215. TQString(file.errorString()).latin1() ) );
  216. KMessageBox::error( parentWidget(), text, caption );
  217. anyFailures = true;
  218. }
  219. } else {
  220. TQString text = i18n( "<qt>Unable to access vCard: %1</qt>" );
  221. text = text.tqarg( KIO::NetAccess::lastErrorString() );
  222. KMessageBox::error( parentWidget(), text, caption );
  223. anyFailures = true;
  224. }
  225. }
  226. if ( !XXPortManager::importURL.isEmpty() ) { // a vcard was passed via cmd
  227. if ( addrList.isEmpty() ) {
  228. if ( anyFailures && urls.count() > 1 )
  229. KMessageBox::information( parentWidget(),
  230. i18n( "No contacts were imported, due to errors with the vCards." ) );
  231. else if ( !anyFailures )
  232. KMessageBox::information( parentWidget(), i18n( "The vCard does not contain any contacts." ) );
  233. } else {
  234. VCardViewerDialog dlg( addrList, parentWidget() );
  235. dlg.exec();
  236. addrList = dlg.contacts();
  237. }
  238. }
  239. }
  240. return addrList;
  241. }
  242. #if defined(KABC_VCARD_ENCODING_FIX)
  243. KABC::AddresseeList VCardXXPort::parseVCard( const TQByteArray &data ) const
  244. {
  245. KABC::VCardConverter converter;
  246. return converter.parseVCardsRaw( data.data() );
  247. }
  248. bool VCardXXPort::doExport( const KURL &url, const TQByteArray &data )
  249. {
  250. if( TQFileInfo(url.path()).exists() ) {
  251. if(KMessageBox::questionYesNo( parentWidget(), i18n("Do you want to overwrite file \"%1\"").tqarg( url.path()) ) == KMessageBox::No)
  252. return false;
  253. }
  254. KTempFile tmpFile;
  255. tmpFile.setAutoDelete( true );
  256. tmpFile.file()->writeBlock( data.data(), data.size() );
  257. tmpFile.close();
  258. return KIO::NetAccess::upload( tmpFile.name(), url, parentWidget() );
  259. }
  260. #else
  261. KABC::AddresseeList VCardXXPort::parseVCard( const TQString &data ) const
  262. {
  263. KABC::VCardConverter converter;
  264. return converter.parseVCards( data );
  265. }
  266. bool VCardXXPort::doExport( const KURL &url, const TQString &data )
  267. {
  268. if( TQFileInfo(url.path()).exists() ) {
  269. if(KMessageBox::questionYesNo( parentWidget(), i18n("Do you want to overwrite file \"%1\"").tqarg( url.path()) ) == KMessageBox::No)
  270. return false;
  271. }
  272. KTempFile tmpFile;
  273. tmpFile.setAutoDelete( true );
  274. TQTextStream stream( tmpFile.file() );
  275. stream.setEncoding( TQTextStream::UnicodeUTF8 );
  276. stream << data;
  277. tmpFile.close();
  278. return KIO::NetAccess::upload( tmpFile.name(), url, parentWidget() );
  279. }
  280. #endif
  281. KABC::AddresseeList VCardXXPort::filterContacts( const KABC::AddresseeList &addrList )
  282. {
  283. KABC::AddresseeList list;
  284. if ( addrList.isEmpty() )
  285. return addrList;
  286. VCardExportSelectionDialog dlg( parentWidget() );
  287. if ( !dlg.exec() )
  288. return list;
  289. KABC::AddresseeList::ConstIterator it;
  290. for ( it = addrList.begin(); it != addrList.end(); ++it ) {
  291. KABC::Addressee addr;
  292. addr.setUid( (*it).uid() );
  293. addr.setFormattedName( (*it).formattedName() );
  294. addr.setPrefix( (*it).prefix() );
  295. addr.setGivenName( (*it).givenName() );
  296. addr.setAdditionalName( (*it).additionalName() );
  297. addr.setFamilyName( (*it).familyName() );
  298. addr.setSuffix( (*it).suffix() );
  299. addr.setNickName( (*it).nickName() );
  300. addr.setMailer( (*it).mailer() );
  301. addr.setTimeZone( (*it).timeZone() );
  302. addr.setGeo( (*it).geo() );
  303. addr.setProductId( (*it).productId() );
  304. addr.setSortString( (*it).sortString() );
  305. addr.setUrl( (*it).url() );
  306. addr.setSecrecy( (*it).secrecy() );
  307. addr.setSound( (*it).sound() );
  308. addr.setEmails( (*it).emails() );
  309. addr.setCategories( (*it).categories() );
  310. if ( dlg.exportPrivateFields() ) {
  311. addr.setBirthday( (*it).birthday() );
  312. addr.setNote( (*it).note() );
  313. addr.setPhoto( (*it).photo() );
  314. }
  315. if ( dlg.exportBusinessFields() ) {
  316. addr.setTitle( (*it).title() );
  317. addr.setRole( (*it).role() );
  318. addr.setOrganization( (*it).organization() );
  319. addr.setLogo( (*it).logo() );
  320. KABC::PhoneNumber::List phones = (*it).phoneNumbers( KABC::PhoneNumber::Work );
  321. KABC::PhoneNumber::List::Iterator phoneIt;
  322. for ( phoneIt = phones.begin(); phoneIt != phones.end(); ++phoneIt )
  323. addr.insertPhoneNumber( *phoneIt );
  324. KABC::Address::List addresses = (*it).addresses( KABC::Address::Work );
  325. KABC::Address::List::Iterator addrIt;
  326. for ( addrIt = addresses.begin(); addrIt != addresses.end(); ++addrIt )
  327. addr.insertAddress( *addrIt );
  328. }
  329. KABC::PhoneNumber::List phones = (*it).phoneNumbers();
  330. KABC::PhoneNumber::List::Iterator phoneIt;
  331. for ( phoneIt = phones.begin(); phoneIt != phones.end(); ++phoneIt ) {
  332. int type = (*phoneIt).type();
  333. if ( type & KABC::PhoneNumber::Home && dlg.exportPrivateFields() )
  334. addr.insertPhoneNumber( *phoneIt );
  335. else if ( type & KABC::PhoneNumber::Work && dlg.exportBusinessFields() )
  336. addr.insertPhoneNumber( *phoneIt );
  337. else if ( dlg.exportOtherFields() )
  338. addr.insertPhoneNumber( *phoneIt );
  339. }
  340. KABC::Address::List addresses = (*it).addresses();
  341. KABC::Address::List::Iterator addrIt;
  342. for ( addrIt = addresses.begin(); addrIt != addresses.end(); ++addrIt ) {
  343. int type = (*addrIt).type();
  344. if ( type & KABC::Address::Home && dlg.exportPrivateFields() )
  345. addr.insertAddress( *addrIt );
  346. else if ( type & KABC::Address::Work && dlg.exportBusinessFields() )
  347. addr.insertAddress( *addrIt );
  348. else if ( dlg.exportOtherFields() )
  349. addr.insertAddress( *addrIt );
  350. }
  351. if ( dlg.exportOtherFields() )
  352. addr.setCustoms( (*it).customs() );
  353. if ( dlg.exportEncryptionKeys() ) {
  354. addKey( addr, KABC::Key::PGP );
  355. addKey( addr, KABC::Key::X509 );
  356. }
  357. list.append( addr );
  358. }
  359. return list;
  360. }
  361. void VCardXXPort::addKey( KABC::Addressee &addr, KABC::Key::Types type )
  362. {
  363. TQString fingerprint = addr.custom( "KADDRESSBOOK",
  364. (type == KABC::Key::PGP ? "OPENPGPFP" : "SMIMEFP") );
  365. if ( fingerprint.isEmpty() )
  366. return;
  367. GpgME::Context * context = GpgME::Context::createForProtocol( GpgME::Context::OpenPGP );
  368. if ( !context ) {
  369. kdError() << "No context available" << endl;
  370. return;
  371. }
  372. context->setArmor( false );
  373. context->setTextMode( false );
  374. QGpgME::TQByteArrayDataProvider dataProvider;
  375. GpgME::Data dataObj( &dataProvider );
  376. GpgME::Error error = context->exportPublicKeys( fingerprint.latin1(), dataObj );
  377. delete context;
  378. if ( error ) {
  379. kdError() << error.asString() << endl;
  380. return;
  381. }
  382. KABC::Key key;
  383. key.setType( type );
  384. key.setBinaryData( dataProvider.data() );
  385. addr.insertKey( key );
  386. }
  387. // ---------- VCardViewer Dialog ---------------- //
  388. VCardViewerDialog::VCardViewerDialog( const KABC::Addressee::List &list,
  389. TQWidget *parent, const char *name )
  390. : KDialogBase( Plain, i18n( "Import vCard" ), Yes | No | Apply | Cancel, Yes,
  391. parent, name, true, true, KStdGuiItem::no(), KStdGuiItem::yes() ),
  392. mContacts( list )
  393. {
  394. TQFrame *page = plainPage();
  395. TQVBoxLayout *tqlayout = new TQVBoxLayout( page, marginHint(), spacingHint() );
  396. TQLabel *label = new TQLabel( i18n( "Do you want to import this contact in your address book?" ), page );
  397. TQFont font = label->font();
  398. font.setBold( true );
  399. label->setFont( font );
  400. tqlayout->addWidget( label );
  401. mView = new KPIM::AddresseeView( page );
  402. mView->enableLinks( 0 );
  403. mView->setVScrollBarMode( TQScrollView::Auto );
  404. tqlayout->addWidget( mView );
  405. setButtonText( Apply, i18n( "Import All..." ) );
  406. mIt = mContacts.begin();
  407. updateView();
  408. }
  409. KABC::Addressee::List VCardViewerDialog::contacts() const
  410. {
  411. return mContacts;
  412. }
  413. void VCardViewerDialog::updateView()
  414. {
  415. mView->setAddressee( *mIt );
  416. KABC::Addressee::List::Iterator it = mIt;
  417. actionButton( Apply )->setEnabled( (++it) != mContacts.end() );
  418. }
  419. void VCardViewerDialog::slotUser1()
  420. {
  421. mIt = mContacts.remove( mIt );
  422. if ( mIt == mContacts.end() )
  423. slotApply();
  424. updateView();
  425. }
  426. void VCardViewerDialog::slotUser2()
  427. {
  428. mIt++;
  429. if ( mIt == mContacts.end() )
  430. slotApply();
  431. updateView();
  432. }
  433. void VCardViewerDialog::slotApply()
  434. {
  435. TQDialog::accept();
  436. }
  437. void VCardViewerDialog::slotCancel()
  438. {
  439. mContacts.clear();
  440. TQDialog::accept();
  441. }
  442. // ---------- VCardExportSelection Dialog ---------------- //
  443. VCardExportSelectionDialog::VCardExportSelectionDialog( TQWidget *parent,
  444. const char *name )
  445. : KDialogBase( Plain, i18n( "Select vCard Fields" ), Ok | Cancel, Ok,
  446. parent, name, true, true )
  447. {
  448. TQFrame *page = plainPage();
  449. TQVBoxLayout *tqlayout = new TQVBoxLayout( page, marginHint(), spacingHint() );
  450. TQLabel *label = new TQLabel( i18n( "Select the fields which shall be exported in the vCard." ), page );
  451. tqlayout->addWidget( label );
  452. mPrivateBox = new TQCheckBox( i18n( "Private fields" ), page );
  453. tqlayout->addWidget( mPrivateBox );
  454. mBusinessBox = new TQCheckBox( i18n( "Business fields" ), page );
  455. tqlayout->addWidget( mBusinessBox );
  456. mOtherBox = new TQCheckBox( i18n( "Other fields" ), page );
  457. tqlayout->addWidget( mOtherBox );
  458. mEncryptionKeys = new TQCheckBox( i18n( "Encryption keys" ), page );
  459. tqlayout->addWidget( mEncryptionKeys );
  460. KConfig config( "kaddressbookrc" );
  461. config.setGroup( "XXPortVCard" );
  462. mPrivateBox->setChecked( config.readBoolEntry( "ExportPrivateFields", true ) );
  463. mBusinessBox->setChecked( config.readBoolEntry( "ExportBusinessFields", false ) );
  464. mOtherBox->setChecked( config.readBoolEntry( "ExportOtherFields", false ) );
  465. mEncryptionKeys->setChecked( config.readBoolEntry( "ExportEncryptionKeys", false ) );
  466. }
  467. VCardExportSelectionDialog::~VCardExportSelectionDialog()
  468. {
  469. KConfig config( "kaddressbookrc" );
  470. config.setGroup( "XXPortVCard" );
  471. config.writeEntry( "ExportPrivateFields", mPrivateBox->isChecked() );
  472. config.writeEntry( "ExportBusinessFields", mBusinessBox->isChecked() );
  473. config.writeEntry( "ExportOtherFields", mOtherBox->isChecked() );
  474. config.writeEntry( "ExportEncryptionKeys", mEncryptionKeys->isChecked() );
  475. }
  476. bool VCardExportSelectionDialog::exportPrivateFields() const
  477. {
  478. return mPrivateBox->isChecked();
  479. }
  480. bool VCardExportSelectionDialog::exportBusinessFields() const
  481. {
  482. return mBusinessBox->isChecked();
  483. }
  484. bool VCardExportSelectionDialog::exportOtherFields() const
  485. {
  486. return mOtherBox->isChecked();
  487. }
  488. bool VCardExportSelectionDialog::exportEncryptionKeys() const
  489. {
  490. return mEncryptionKeys->isChecked();
  491. }
  492. #include "vcard_xxport.moc"