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