kmail

identitydialog.cpp

Go to the documentation of this file.
00001 /*  -*- mode: C++; c-file-style: "gnu" -*-
00002     identitydialog.cpp
00003 
00004     This file is part of KMail, the KDE mail client.
00005     Copyright (c) 2002 Marc Mutz <mutz@kde.org>
00006 
00007     KMail is free software; you can redistribute it and/or modify it
00008     under the terms of the GNU General Public License, version 2, as
00009     published by the Free Software Foundation.
00010 
00011     KMail is distributed in the hope that it will be useful, but
00012     WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00019 
00020     In addition, as a special exception, the copyright holders give
00021     permission to link the code of this program with any edition of
00022     the Qt library by Trolltech AS, Norway (or with modified versions
00023     of Qt that use the same license as Qt), and distribute linked
00024     combinations including the two.  You must obey the GNU General
00025     Public License in all respects for all of the code used other than
00026     Qt.  If you modify this file, you may extend this exception to
00027     your version of the file, but you are not obligated to do so.  If
00028     you do not wish to do so, delete this exception statement from
00029     your version.
00030 */
00031 
00032 #ifdef HAVE_CONFIG_H
00033 #include <config.h>
00034 #endif
00035 
00036 #include "identitydialog.h"
00037 
00038 // other KMail headers:
00039 #include "signatureconfigurator.h"
00040 #include "xfaceconfigurator.h"
00041 #include "folderrequester.h"
00042 using KMail::FolderRequester;
00043 #include "kmfoldermgr.h"
00044 #include "transportmanager.h"
00045 #include "dictionarycombobox.h"
00046 #include "kleo_util.h"
00047 #include "kmmainwidget.h"
00048 #include "kmfolder.h"
00049 #include "templatesconfiguration.h"
00050 #include "templatesconfiguration_kfg.h"
00051 
00052 // other kdepim headers:
00053 // libkdepim
00054 #include <libkpimidentities/identity.h>
00055 #include <libkdepim/addresseelineedit.h>
00056 // libkleopatra:
00057 #include <ui/keyrequester.h>
00058 #include <kleo/cryptobackendfactory.h>
00059 
00060 #include <libemailfunctions/email.h>
00061 
00062 // other KDE headers:
00063 #include <klocale.h>
00064 #include <kmessagebox.h>
00065 #include <kconfig.h>
00066 #include <kfileitem.h>
00067 #include <kurl.h>
00068 #include <kdebug.h>
00069 #include <kpushbutton.h>
00070 
00071 // Qt headers:
00072 #include <qtabwidget.h>
00073 #include <qlabel.h>
00074 #include <qwhatsthis.h>
00075 #include <qlayout.h>
00076 #include <qpushbutton.h>
00077 #include <qcheckbox.h>
00078 #include <qcombobox.h>
00079 
00080 // other headers:
00081 #include <gpgmepp/key.h>
00082 #include <iterator>
00083 #include <algorithm>
00084 
00085 using namespace KPIM;
00086 
00087 namespace KMail {
00088 
00089   IdentityDialog::IdentityDialog( QWidget * parent, const char * name )
00090     : KDialogBase( Plain, i18n("Edit Identity"), Ok|Cancel|Help, Ok,
00091                    parent, name )
00092   {
00093     // tmp. vars:
00094     QWidget * tab;
00095     QLabel  * label;
00096     int row;
00097     QGridLayout * glay;
00098     QString msg;
00099 
00100     //
00101     // Tab Widget: General
00102     //
00103     row = -1;
00104     QVBoxLayout * vlay = new QVBoxLayout( plainPage(), 0, spacingHint() );
00105     QTabWidget *tabWidget = new QTabWidget( plainPage(), "config-identity-tab" );
00106     vlay->addWidget( tabWidget );
00107 
00108     tab = new QWidget( tabWidget );
00109     tabWidget->addTab( tab, i18n("&General") );
00110     glay = new QGridLayout( tab, 4, 2, marginHint(), spacingHint() );
00111     glay->setRowStretch( 3, 1 );
00112     glay->setColStretch( 1, 1 );
00113 
00114     // "Name" line edit and label:
00115     ++row;
00116     mNameEdit = new KLineEdit( tab );
00117     glay->addWidget( mNameEdit, row, 1 );
00118     label = new QLabel( mNameEdit, i18n("&Your name:"), tab );
00119     glay->addWidget( label, row, 0 );
00120     msg = i18n("<qt><h3>Your name</h3>"
00121                "<p>This field should contain your name as you would like "
00122                "it to appear in the email header that is sent out;</p>"
00123                "<p>if you leave this blank your real name will not "
00124                "appear, only the email address.</p></qt>");
00125     QWhatsThis::add( label, msg );
00126     QWhatsThis::add( mNameEdit, msg );
00127 
00128     // "Organization" line edit and label:
00129     ++row;
00130     mOrganizationEdit = new KLineEdit( tab );
00131     glay->addWidget( mOrganizationEdit, row, 1 );
00132     label =  new QLabel( mOrganizationEdit, i18n("Organi&zation:"), tab );
00133     glay->addWidget( label, row, 0 );
00134     msg = i18n("<qt><h3>Organization</h3>"
00135                "<p>This field should have the name of your organization "
00136                "if you'd like it to be shown in the email header that "
00137                "is sent out.</p>"
00138                "<p>It is safe (and normal) to leave this blank.</p></qt>");
00139     QWhatsThis::add( label, msg );
00140     QWhatsThis::add( mOrganizationEdit, msg );
00141 
00142     // "Email Address" line edit and label:
00143     // (row 3: spacer)
00144     ++row;
00145     mEmailEdit = new KLineEdit( tab );
00146     glay->addWidget( mEmailEdit, row, 1 );
00147     label = new QLabel( mEmailEdit, i18n("&Email address:"), tab );
00148     glay->addWidget( label, row, 0 );
00149     msg = i18n("<qt><h3>Email address</h3>"
00150                "<p>This field should have your full email address.</p>"
00151                "<p>If you leave this blank, or get it wrong, people "
00152                "will have trouble replying to you.</p></qt>");
00153     QWhatsThis::add( label, msg );
00154     QWhatsThis::add( mEmailEdit, msg );
00155 
00156     //
00157     // Tab Widget: Cryptography
00158     //
00159     row = -1;
00160     mCryptographyTab = tab = new QWidget( tabWidget );
00161     tabWidget->addTab( tab, i18n("Cryptograph&y") );
00162     glay = new QGridLayout( tab, 6, 2, marginHint(), spacingHint() );
00163     glay->setColStretch( 1, 1 );
00164 
00165     // "OpenPGP Signature Key" requester and label:
00166     ++row;
00167     mPGPSigningKeyRequester = new Kleo::SigningKeyRequester( false, Kleo::SigningKeyRequester::OpenPGP, tab );
00168     mPGPSigningKeyRequester->dialogButton()->setText( i18n("Chang&e...") );
00169     mPGPSigningKeyRequester->setDialogCaption( i18n("Your OpenPGP Signature Key") );
00170     msg = i18n("Select the OpenPGP key which should be used to "
00171            "digitally sign your messages.");
00172     mPGPSigningKeyRequester->setDialogMessage( msg );
00173 
00174     msg = i18n("<qt><p>The OpenPGP key you choose here will be used "
00175                "to digitally sign messages. You can also use GnuPG keys.</p>"
00176                "<p>You can leave this blank, but KMail will not be able "
00177                "to digitally sign emails using OpenPGP; "
00178            "normal mail functions will not be affected.</p>"
00179                "<p>You can find out more about keys at <a>http://www.gnupg.org</a></p></qt>");
00180 
00181     label = new QLabel( mPGPSigningKeyRequester, i18n("OpenPGP signing key:"), tab );
00182     QWhatsThis::add( mPGPSigningKeyRequester, msg );
00183     QWhatsThis::add( label, msg );
00184 
00185     glay->addWidget( label, row, 0 );
00186     glay->addWidget( mPGPSigningKeyRequester, row, 1 );
00187 
00188 
00189     // "OpenPGP Encryption Key" requester and label:
00190     ++row;
00191     mPGPEncryptionKeyRequester = new Kleo::EncryptionKeyRequester( false, Kleo::EncryptionKeyRequester::OpenPGP, tab );
00192     mPGPEncryptionKeyRequester->dialogButton()->setText( i18n("Chang&e...") );
00193     mPGPEncryptionKeyRequester->setDialogCaption( i18n("Your OpenPGP Encryption Key") );
00194     msg = i18n("Select the OpenPGP key which should be used when encrypting "
00195            "to yourself and for the \"Attach My Public Key\" "
00196            "feature in the composer.");
00197     mPGPEncryptionKeyRequester->setDialogMessage( msg );
00198 
00199     msg = i18n("<qt><p>The OpenPGP key you choose here will be used "
00200                "to encrypt messages to yourself and for the \"Attach My Public Key\" "
00201            "feature in the composer. You can also use GnuPG keys.</p>"
00202                "<p>You can leave this blank, but KMail will not be able "
00203                "to encrypt copies of outgoing messages to you using OpenPGP; "
00204            "normal mail functions will not be affected.</p>"
00205                "<p>You can find out more about keys at <a>http://www.gnupg.org</a></qt>");
00206     label = new QLabel( mPGPEncryptionKeyRequester, i18n("OpenPGP encryption key:"), tab );
00207     QWhatsThis::add( mPGPEncryptionKeyRequester, msg );
00208     QWhatsThis::add( label, msg );
00209 
00210     glay->addWidget( label, row, 0 );
00211     glay->addWidget( mPGPEncryptionKeyRequester, row, 1 );
00212 
00213 
00214     // "S/MIME Signature Key" requester and label:
00215     ++row;
00216     mSMIMESigningKeyRequester = new Kleo::SigningKeyRequester( false, Kleo::SigningKeyRequester::SMIME, tab );
00217     mSMIMESigningKeyRequester->dialogButton()->setText( i18n("Chang&e...") );
00218     mSMIMESigningKeyRequester->setDialogCaption( i18n("Your S/MIME Signature Certificate") );
00219     msg = i18n("Select the S/MIME certificate which should be used to "
00220            "digitally sign your messages.");
00221     mSMIMESigningKeyRequester->setDialogMessage( msg );
00222 
00223     msg = i18n("<qt><p>The S/MIME (X.509) certificate you choose here will be used "
00224                "to digitally sign messages.</p>"
00225                "<p>You can leave this blank, but KMail will not be able "
00226                "to digitally sign emails using S/MIME; "
00227            "normal mail functions will not be affected.</p></qt>");
00228     label = new QLabel( mSMIMESigningKeyRequester, i18n("S/MIME signing certificate:"), tab );
00229     QWhatsThis::add( mSMIMESigningKeyRequester, msg );
00230     QWhatsThis::add( label, msg );
00231     glay->addWidget( label, row, 0 );
00232     glay->addWidget( mSMIMESigningKeyRequester, row, 1 );
00233 
00234     const Kleo::CryptoBackend::Protocol * smimeProtocol
00235       = Kleo::CryptoBackendFactory::instance()->smime();
00236 
00237     label->setEnabled( smimeProtocol );
00238     mSMIMESigningKeyRequester->setEnabled( smimeProtocol );
00239 
00240     // "S/MIME Encryption Key" requester and label:
00241     ++row;
00242     mSMIMEEncryptionKeyRequester = new Kleo::EncryptionKeyRequester( false, Kleo::EncryptionKeyRequester::SMIME, tab );
00243     mSMIMEEncryptionKeyRequester->dialogButton()->setText( i18n("Chang&e...") );
00244     mSMIMEEncryptionKeyRequester->setDialogCaption( i18n("Your S/MIME Encryption Certificate") );
00245     msg = i18n("Select the S/MIME certificate which should be used when encrypting "
00246            "to yourself and for the \"Attach My Certificate\" "
00247            "feature in the composer.");
00248     mSMIMEEncryptionKeyRequester->setDialogMessage( msg );
00249 
00250     msg = i18n("<qt><p>The S/MIME certificate you choose here will be used "
00251                "to encrypt messages to yourself and for the \"Attach My Certificate\" "
00252            "feature in the composer.</p>"
00253                "<p>You can leave this blank, but KMail will not be able "
00254                "to encrypt copies of outgoing messages to you using S/MIME; "
00255            "normal mail functions will not be affected.</p></qt>");
00256     label = new QLabel( mSMIMEEncryptionKeyRequester, i18n("S/MIME encryption certificate:"), tab );
00257     QWhatsThis::add( mSMIMEEncryptionKeyRequester, msg );
00258     QWhatsThis::add( label, msg );
00259 
00260     glay->addWidget( label, row, 0 );
00261     glay->addWidget( mSMIMEEncryptionKeyRequester, row, 1 );
00262 
00263     label->setEnabled( smimeProtocol );
00264     mSMIMEEncryptionKeyRequester->setEnabled( smimeProtocol );
00265 
00266     // "Preferred Crypto Message Format" combobox and label:
00267     ++row;
00268     mPreferredCryptoMessageFormat = new QComboBox( false, tab );
00269     QStringList l;
00270     l << Kleo::cryptoMessageFormatToLabel( Kleo::AutoFormat )
00271       << Kleo::cryptoMessageFormatToLabel( Kleo::InlineOpenPGPFormat )
00272       << Kleo::cryptoMessageFormatToLabel( Kleo::OpenPGPMIMEFormat )
00273       << Kleo::cryptoMessageFormatToLabel( Kleo::SMIMEFormat )
00274       << Kleo::cryptoMessageFormatToLabel( Kleo::SMIMEOpaqueFormat );
00275     mPreferredCryptoMessageFormat->insertStringList( l );
00276     label = new QLabel( mPreferredCryptoMessageFormat,
00277             i18n("Preferred crypto message format:"), tab );
00278 
00279     glay->addWidget( label, row, 0 );
00280     glay->addWidget( mPreferredCryptoMessageFormat, row, 1 );
00281 
00282     ++row;
00283     glay->setRowStretch( row, 1 );
00284 
00285     //
00286     // Tab Widget: Advanced
00287     //
00288     row = -1;
00289     tab = new QWidget( tabWidget );
00290     tabWidget->addTab( tab, i18n("&Advanced") );
00291     glay = new QGridLayout( tab, 8, 2, marginHint(), spacingHint() );
00292     // the last (empty) row takes all the remaining space
00293     glay->setRowStretch( 8-1, 1 );
00294     glay->setColStretch( 1, 1 );
00295 
00296     // "Reply-To Address" line edit and label:
00297     ++row;
00298     mReplyToEdit = new KPIM::AddresseeLineEdit( tab, true, "mReplyToEdit" );
00299     glay->addWidget( mReplyToEdit, row, 1 );
00300     label = new QLabel ( mReplyToEdit, i18n("&Reply-To address:"), tab);
00301     glay->addWidget( label , row, 0 );
00302     msg = i18n("<qt><h3>Reply-To addresses</h3>"
00303                "<p>This sets the <tt>Reply-to:</tt> header to contain a "
00304                "different email address to the normal <tt>From:</tt> "
00305                "address.</p>"
00306                "<p>This can be useful when you have a group of people "
00307                "working together in similar roles. For example, you "
00308                "might want any emails sent to have your email in the "
00309                "<tt>From:</tt> field, but any responses to go to "
00310                "a group address.</p>"
00311                "<p>If in doubt, leave this field blank.</p></qt>");
00312     QWhatsThis::add( label, msg );
00313     QWhatsThis::add( mReplyToEdit, msg );
00314 
00315     // "BCC addresses" line edit and label:
00316     ++row;
00317     mBccEdit = new KPIM::AddresseeLineEdit( tab, true, "mBccEdit" );
00318     glay->addWidget( mBccEdit, row, 1 );
00319     label = new QLabel( mBccEdit, i18n("&BCC addresses:"), tab );
00320     glay->addWidget( label, row, 0 );
00321     msg = i18n("<qt><h3>BCC (Blind Carbon Copy) addresses</h3>"
00322                "<p>The addresses that you enter here will be added to each "
00323                "outgoing mail that is sent with this identity. They will not "
00324                "be visible to other recipients.</p>"
00325                "<p>This is commonly used to send a copy of each sent message to "
00326                "another account of yours.</p>"
00327                "<p>To specify more than one address, use commas to separate "
00328                "the list of BCC recipients.</p>"
00329                "<p>If in doubt, leave this field blank.</p></qt>");
00330     QWhatsThis::add( label, msg );
00331     QWhatsThis::add( mBccEdit, msg );
00332 
00333     // "Dictionary" combo box and label:
00334     ++row;
00335     mDictionaryCombo = new DictionaryComboBox( tab );
00336     glay->addWidget( mDictionaryCombo, row, 1 );
00337     glay->addWidget( new QLabel( mDictionaryCombo, i18n("D&ictionary:"), tab ),
00338                      row, 0 );
00339 
00340     // "Sent-mail Folder" combo box and label:
00341     ++row;
00342     mFccCombo = new FolderRequester( tab, 
00343         kmkernel->getKMMainWidget()->folderTree() );
00344     mFccCombo->setShowOutbox( false );
00345     glay->addWidget( mFccCombo, row, 1 );
00346     glay->addWidget( new QLabel( mFccCombo, i18n("Sent-mail &folder:"), tab ),
00347                      row, 0 );
00348 
00349     // "Drafts Folder" combo box and label:
00350     ++row;
00351     mDraftsCombo = new FolderRequester( tab,
00352         kmkernel->getKMMainWidget()->folderTree() );
00353     mDraftsCombo->setShowOutbox( false );
00354     glay->addWidget( mDraftsCombo, row, 1 );
00355     glay->addWidget( new QLabel( mDraftsCombo, i18n("&Drafts folder:"), tab ),
00356                      row, 0 );
00357 
00358     // "Templates Folder" combo box and label:
00359     ++row;
00360     mTemplatesCombo = new FolderRequester( tab,
00361         kmkernel->getKMMainWidget()->folderTree() );
00362     mTemplatesCombo->setShowOutbox( false );
00363     glay->addWidget( mTemplatesCombo, row, 1 );
00364     glay->addWidget( new QLabel( mTemplatesCombo, i18n("&Templates folder:"), tab ),
00365                      row, 0 );
00366 
00367     // "Special transport" combobox and label:
00368     ++row;
00369     mTransportCheck = new QCheckBox( i18n("Special &transport:"), tab );
00370     glay->addWidget( mTransportCheck, row, 0 );
00371     mTransportCombo = new QComboBox( true, tab );
00372     mTransportCombo->setEnabled( false ); // since !mTransportCheck->isChecked()
00373     mTransportCombo->insertStringList( KMail::TransportManager::transportNames() );
00374     glay->addWidget( mTransportCombo, row, 1 );
00375     connect( mTransportCheck, SIGNAL(toggled(bool)),
00376              mTransportCombo, SLOT(setEnabled(bool)) );
00377 
00378     // the last row is a spacer
00379     
00380     // 
00381     // Tab Widget: Templates
00382     // 
00383         tab = new QWidget( tabWidget );
00384     tabWidget->addTab( tab, i18n("&Templates") );
00385     vlay = new QVBoxLayout( tab, marginHint(), spacingHint() );
00386         mCustom = new QCheckBox( i18n("&Use custom message templates"), tab );
00387         vlay->addWidget( mCustom );
00388         mWidget = new TemplatesConfiguration( tab , "identity-templates" );
00389         mWidget->setEnabled( false );
00390         vlay->addWidget( mWidget );
00391         QHBoxLayout *btns = new QHBoxLayout( vlay, spacingHint() );
00392         mCopyGlobal = new KPushButton( i18n("&Copy global templates"), tab );
00393         mCopyGlobal->setEnabled( false );
00394         btns->addWidget( mCopyGlobal );
00395         connect( mCustom, SIGNAL( toggled( bool ) ),
00396                     mWidget, SLOT( setEnabled( bool ) ) );
00397         connect( mCustom, SIGNAL( toggled( bool ) ),
00398                     mCopyGlobal, SLOT( setEnabled( bool ) ) );
00399         connect( mCopyGlobal, SIGNAL(clicked()),
00400                     this, SLOT(slotCopyGlobal()) );
00401         
00402     //
00403     // Tab Widget: Signature
00404     //
00405     mSignatureConfigurator = new SignatureConfigurator( tabWidget );
00406     mSignatureConfigurator->layout()->setMargin( KDialog::marginHint() );
00407     tabWidget->addTab( mSignatureConfigurator, i18n("&Signature") );
00408 
00409     mXFaceConfigurator = new XFaceConfigurator( tabWidget );
00410     mXFaceConfigurator->layout()->setMargin( KDialog::marginHint() );
00411     tabWidget->addTab( mXFaceConfigurator, i18n("&Picture") );
00412 
00413     KConfigGroup geometry( KMKernel::config(), "Geometry" );
00414     if ( geometry.hasKey( "Identity Dialog size" ) )
00415       resize( geometry.readSizeEntry( "Identity Dialog size" ) );
00416     mNameEdit->setFocus();
00417 
00418     connect( tabWidget, SIGNAL(currentChanged(QWidget*)),
00419          SLOT(slotAboutToShow(QWidget*)) );
00420   }
00421 
00422   IdentityDialog::~IdentityDialog() {
00423     KConfigGroup geometry( KMKernel::config(), "Geometry" );
00424     geometry.writeEntry( "Identity Dialog size", size() );
00425   }
00426 
00427   void IdentityDialog::slotAboutToShow( QWidget * w ) {
00428     if ( w == mCryptographyTab ) {
00429       // set the configured email address as inital query of the key
00430       // requesters:
00431       const QString email = mEmailEdit->text().stripWhiteSpace();
00432       mPGPEncryptionKeyRequester->setInitialQuery( email );
00433       mPGPSigningKeyRequester->setInitialQuery( email );
00434       mSMIMEEncryptionKeyRequester->setInitialQuery( email );
00435       mSMIMESigningKeyRequester->setInitialQuery( email );
00436     }
00437   }
00438   
00439   void IdentityDialog::slotCopyGlobal() {
00440     mWidget->loadFromGlobal();
00441   }
00442 
00443   namespace {
00444     struct DoesntMatchEMailAddress {
00445       explicit DoesntMatchEMailAddress( const QString & s )
00446     : email( s.stripWhiteSpace().lower() ) {}
00447       bool operator()( const GpgME::Key & key ) const;
00448     private:
00449       bool checkForEmail( const char * email ) const;
00450       static QString extractEmail( const char * email );
00451       const QString email;
00452     };
00453 
00454     bool DoesntMatchEMailAddress::operator()( const GpgME::Key & key ) const {
00455       const std::vector<GpgME::UserID> uids = key.userIDs();
00456       for ( std::vector<GpgME::UserID>::const_iterator it = uids.begin() ; it != uids.end() ; ++it )
00457     if ( checkForEmail( it->email() ? it->email() : it->id() ) )
00458       return false;
00459       return true; // note the negation!
00460     }
00461 
00462     bool DoesntMatchEMailAddress::checkForEmail( const char * e ) const {
00463       const QString em = extractEmail( e );
00464       return !em.isEmpty() && email == em;
00465     }
00466 
00467     QString DoesntMatchEMailAddress::extractEmail( const char * e ) {
00468       if ( !e || !*e )
00469     return QString::null;
00470       const QString em = QString::fromUtf8( e );
00471       if ( e[0] == '<' )
00472     return em.mid( 1, em.length() - 2 );
00473       else
00474     return em;
00475     }
00476   }
00477 
00478 bool IdentityDialog::validateAddresses( const QString & addresses )
00479 {
00480   QString brokenAddress;
00481   KPIM::EmailParseResult errorCode = KMMessage::isValidEmailAddressList( KMMessage::expandAliases( addresses ), brokenAddress );
00482   if ( !( errorCode == KPIM::AddressOk || errorCode == KPIM::AddressEmpty ) ) {
00483     QString errorMsg( "<qt><p><b>" + brokenAddress +
00484                       "</b></p><p>" + KPIM::emailParseResultToString( errorCode ) +
00485                       "</p></qt>" );
00486     KMessageBox::sorry( this, errorMsg, i18n("Invalid Email Address") );
00487     return false;
00488   } 
00489   return true;
00490 }
00491 
00492 void IdentityDialog::slotOk() {
00493     const QString email = mEmailEdit->text().stripWhiteSpace();
00494  
00495     // Validate email addresses
00496     if ( !isValidSimpleEmailAddress( email )) {
00497       QString errorMsg( simpleEmailAddressErrorMsg());
00498       KMessageBox::sorry( this, errorMsg, i18n("Invalid Email Address") );
00499       return;
00500     }
00501 
00502     if ( !validateAddresses( mReplyToEdit->text().stripWhiteSpace() ) ) {
00503       return;
00504     }
00505  
00506     if ( !validateAddresses( mBccEdit->text().stripWhiteSpace() ) ) {
00507       return;
00508     }
00509 
00510     const std::vector<GpgME::Key> & pgpSigningKeys = mPGPSigningKeyRequester->keys();
00511     const std::vector<GpgME::Key> & pgpEncryptionKeys = mPGPEncryptionKeyRequester->keys();
00512     const std::vector<GpgME::Key> & smimeSigningKeys = mSMIMESigningKeyRequester->keys();
00513     const std::vector<GpgME::Key> & smimeEncryptionKeys = mSMIMEEncryptionKeyRequester->keys();
00514     QString msg;
00515     bool err = false;
00516     if ( std::find_if( pgpSigningKeys.begin(), pgpSigningKeys.end(),
00517                DoesntMatchEMailAddress( email ) ) != pgpSigningKeys.end() ) {
00518       msg = i18n("One of the configured OpenPGP signing keys does not contain "
00519          "any user ID with the configured email address for this "
00520          "identity (%1).\n"
00521          "This might result in warning messages on the receiving side "
00522          "when trying to verify signatures made with this configuration.");
00523       err = true;
00524     }
00525     else if ( std::find_if( pgpEncryptionKeys.begin(), pgpEncryptionKeys.end(),
00526                 DoesntMatchEMailAddress( email ) ) != pgpEncryptionKeys.end() ) {
00527       msg = i18n("One of the configured OpenPGP encryption keys does not contain "
00528          "any user ID with the configured email address for this "
00529          "identity (%1).");
00530       err = true;
00531     }
00532     else if ( std::find_if( smimeSigningKeys.begin(), smimeSigningKeys.end(),
00533                 DoesntMatchEMailAddress( email ) ) != smimeSigningKeys.end() ) {
00534       msg = i18n("One of the configured S/MIME signing certificates does not contain "
00535          "the configured email address for this "
00536          "identity (%1).\n"
00537          "This might result in warning messages on the receiving side "
00538          "when trying to verify signatures made with this configuration.");
00539       err = true;
00540     }
00541     else if ( std::find_if( smimeEncryptionKeys.begin(), smimeEncryptionKeys.end(),
00542                 DoesntMatchEMailAddress( email ) ) != smimeEncryptionKeys.end() ) {
00543       msg = i18n("One of the configured S/MIME encryption certificates does not contain "
00544          "the configured email address for this "
00545          "identity (%1).");
00546       err = true;
00547     }
00548 
00549     if ( err )
00550       if ( KMessageBox::warningContinueCancel( this, msg.arg( email ),
00551                                           i18n("Email Address Not Found in Key/Certificates"),
00552                                           KStdGuiItem::cont(), "warn_email_not_in_certificate" )
00553      != KMessageBox::Continue)
00554         return;
00555 
00556 
00557     if ( mSignatureConfigurator->isSignatureEnabled() &&
00558          mSignatureConfigurator->signatureType()==Signature::FromFile ) {
00559       KURL url( mSignatureConfigurator->fileURL() );
00560       KFileItem signatureFile( KFileItem::Unknown, KFileItem::Unknown, url );
00561       if ( !signatureFile.isFile() || !signatureFile.isReadable() || !signatureFile.isLocalFile() ) {
00562         KMessageBox::error( this, i18n( "The signature file is not valid" ) );
00563         return;
00564       }
00565     }
00566 
00567     return KDialogBase::slotOk();
00568   }
00569 
00570   bool IdentityDialog::checkFolderExists( const QString & folderID,
00571                                           const QString & msg ) {
00572     KMFolder * folder = kmkernel->findFolderById( folderID );
00573     if ( !folder ) {
00574       KMessageBox::sorry( this, msg );
00575       return false;
00576     }
00577     return true;
00578   }
00579 
00580   void IdentityDialog::setIdentity( KPIM::Identity & ident ) {
00581 
00582     setCaption( i18n("Edit Identity \"%1\"").arg( ident.identityName() ) );
00583 
00584     // "General" tab:
00585     mNameEdit->setText( ident.fullName() );
00586     mOrganizationEdit->setText( ident.organization() );
00587     mEmailEdit->setText( ident.emailAddr() );
00588 
00589     // "Cryptography" tab:
00590     mPGPSigningKeyRequester->setFingerprint( ident.pgpSigningKey() );
00591     mPGPEncryptionKeyRequester->setFingerprint( ident.pgpEncryptionKey() );
00592     mSMIMESigningKeyRequester->setFingerprint( ident.smimeSigningKey() );
00593     mSMIMEEncryptionKeyRequester->setFingerprint( ident.smimeEncryptionKey() );
00594     mPreferredCryptoMessageFormat->setCurrentItem( format2cb( ident.preferredCryptoMessageFormat() ) );
00595 
00596     // "Advanced" tab:
00597     mReplyToEdit->setText( ident.replyToAddr() );
00598     mBccEdit->setText( ident.bcc() );
00599     mTransportCheck->setChecked( !ident.transport().isEmpty() );
00600     mTransportCombo->setEditText( ident.transport() );
00601     mTransportCombo->setEnabled( !ident.transport().isEmpty() );
00602     mDictionaryCombo->setCurrentByDictionary( ident.dictionary() );
00603 
00604     if ( ident.fcc().isEmpty() ||
00605          !checkFolderExists( ident.fcc(),
00606                              i18n("The custom sent-mail folder for identity "
00607                                   "\"%1\" does not exist (anymore); "
00608                                   "therefore, the default sent-mail folder "
00609                                   "will be used.")
00610                              .arg( ident.identityName() ) ) )
00611       mFccCombo->setFolder( kmkernel->sentFolder() );
00612     else
00613       mFccCombo->setFolder( ident.fcc() );
00614 
00615     if ( ident.drafts().isEmpty() ||
00616          !checkFolderExists( ident.drafts(),
00617                              i18n("The custom drafts folder for identity "
00618                                   "\"%1\" does not exist (anymore); "
00619                                   "therefore, the default drafts folder "
00620                                   "will be used.")
00621                              .arg( ident.identityName() ) ) )
00622       mDraftsCombo->setFolder( kmkernel->draftsFolder() );
00623     else
00624       mDraftsCombo->setFolder( ident.drafts() );
00625     
00626     if ( ident.templates().isEmpty() ||
00627          !checkFolderExists( ident.templates(),
00628                              i18n("The custom templates folder for identity "
00629                                   "\"%1\" does not exist (anymore); "
00630                                   "therefore, the default templates folder "
00631                                   "will be used.")
00632                              .arg( ident.identityName() ) ) )
00633       mTemplatesCombo->setFolder( kmkernel->templatesFolder() );
00634     else
00635       mTemplatesCombo->setFolder( ident.templates() );
00636     
00637     // "Templates" tab:
00638     uint identity = ident.uoid();
00639         QString iid = QString("IDENTITY_%1").arg( identity );
00640         Templates t( iid );
00641         mCustom->setChecked(t.useCustomTemplates());
00642         mWidget->loadFromIdentity( identity );
00643     
00644     // "Signature" tab:
00645     mSignatureConfigurator->setSignature( ident.signature() );
00646     mXFaceConfigurator->setXFace( ident.xface() );
00647     mXFaceConfigurator->setXFaceEnabled( ident.isXFaceEnabled() );
00648   }
00649 
00650   void IdentityDialog::updateIdentity( KPIM::Identity & ident ) {
00651     // "General" tab:
00652     ident.setFullName( mNameEdit->text() );
00653     ident.setOrganization( mOrganizationEdit->text() );
00654     QString email = mEmailEdit->text();
00655     ident.setEmailAddr( email );
00656     // "Cryptography" tab:
00657     ident.setPGPSigningKey( mPGPSigningKeyRequester->fingerprint().latin1() );
00658     ident.setPGPEncryptionKey( mPGPEncryptionKeyRequester->fingerprint().latin1() );
00659     ident.setSMIMESigningKey( mSMIMESigningKeyRequester->fingerprint().latin1() );
00660     ident.setSMIMEEncryptionKey( mSMIMEEncryptionKeyRequester->fingerprint().latin1() );
00661     ident.setPreferredCryptoMessageFormat( cb2format( mPreferredCryptoMessageFormat->currentItem() ) );
00662     // "Advanced" tab:
00663     ident.setReplyToAddr( mReplyToEdit->text() );
00664     ident.setBcc( mBccEdit->text() );
00665     ident.setTransport( ( mTransportCheck->isChecked() ) ?
00666                         mTransportCombo->currentText() : QString::null );
00667     ident.setDictionary( mDictionaryCombo->currentDictionary() );
00668     ident.setFcc( mFccCombo->folder() ?
00669                   mFccCombo->folder()->idString() : QString::null );
00670     ident.setDrafts( mDraftsCombo->folder() ?
00671                      mDraftsCombo->folder()->idString() : QString::null );
00672     ident.setTemplates( mTemplatesCombo->folder() ?
00673                      mTemplatesCombo->folder()->idString() : QString::null );
00674     // "Templates" tab:
00675     uint identity = ident.uoid();
00676     QString iid = QString("IDENTITY_%1").arg( identity );
00677     Templates t( iid );
00678         kdDebug() << "use custom templates for identity " << identity << ": " << mCustom->isChecked() << endl;
00679         t.setUseCustomTemplates(mCustom->isChecked());
00680         t.writeConfig();
00681         mWidget->saveToIdentity( identity );
00682     // "Signature" tab:
00683     ident.setSignature( mSignatureConfigurator->signature() );
00684     ident.setXFace( mXFaceConfigurator->xface() );
00685     ident.setXFaceEnabled( mXFaceConfigurator->isXFaceEnabled() );
00686   }
00687 
00688   void IdentityDialog::slotUpdateTransportCombo( const QStringList & sl ) {
00689     // save old setting:
00690     QString content = mTransportCombo->currentText();
00691     // update combo box:
00692     mTransportCombo->clear();
00693     mTransportCombo->insertStringList( sl );
00694     // restore saved setting:
00695     mTransportCombo->setEditText( content );
00696   }
00697 
00698 }
00699 
00700 #include "identitydialog.moc"