00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <config.h>
00025
00026
00027 #include "configuredialog.h"
00028 #include "configuredialog_p.h"
00029
00030 #include "globalsettings.h"
00031 #include "replyphrases.h"
00032
00033
00034 #include "kmkernel.h"
00035 #include "simplestringlisteditor.h"
00036 #include "accountdialog.h"
00037 using KMail::AccountDialog;
00038 #include "colorlistbox.h"
00039 #include "kmacctseldlg.h"
00040 #include "messagesender.h"
00041 #include "kmtransport.h"
00042 #include "kmfoldermgr.h"
00043 #include <libkpimidentities/identitymanager.h>
00044 #include "identitylistview.h"
00045 using KMail::IdentityListView;
00046 using KMail::IdentityListViewItem;
00047 #include "kcursorsaver.h"
00048 #include "accountmanager.h"
00049 #include <composercryptoconfiguration.h>
00050 #include <warningconfiguration.h>
00051 #include <smimeconfiguration.h>
00052 #include "folderrequester.h"
00053 using KMail::FolderRequester;
00054 #include "accountcombobox.h"
00055 #include "imapaccountbase.h"
00056 using KMail::ImapAccountBase;
00057 #include "folderstorage.h"
00058 #include "kmfolder.h"
00059 #include "kmmainwidget.h"
00060 #include "recentaddresses.h"
00061 using KRecentAddress::RecentAddresses;
00062 #include "completionordereditor.h"
00063 #include "ldapclient.h"
00064 #include "index.h"
00065
00066 using KMail::IdentityListView;
00067 using KMail::IdentityListViewItem;
00068 #include "identitydialog.h"
00069 using KMail::IdentityDialog;
00070
00071
00072 #include <libkpimidentities/identity.h>
00073 #include <kmime_util.h>
00074 using KMime::DateFormatter;
00075 #include <kleo/cryptoconfig.h>
00076 #include <kleo/cryptobackendfactory.h>
00077 #include <ui/backendconfigwidget.h>
00078 #include <ui/keyrequester.h>
00079 #include <ui/keyselectiondialog.h>
00080
00081
00082 #include <klocale.h>
00083 #include <kapplication.h>
00084 #include <kcharsets.h>
00085 #include <kasciistringtools.h>
00086 #include <kdebug.h>
00087 #include <knuminput.h>
00088 #include <kfontdialog.h>
00089 #include <kmessagebox.h>
00090 #include <kurlrequester.h>
00091 #include <kseparator.h>
00092 #include <kiconloader.h>
00093 #include <kstandarddirs.h>
00094 #include <kwin.h>
00095 #include <knotifydialog.h>
00096 #include <kconfig.h>
00097 #include <kactivelabel.h>
00098 #include <kcmultidialog.h>
00099
00100
00101 #include <qvalidator.h>
00102 #include <qwhatsthis.h>
00103 #include <qvgroupbox.h>
00104 #include <qvbox.h>
00105 #include <qvbuttongroup.h>
00106 #include <qhbuttongroup.h>
00107 #include <qtooltip.h>
00108 #include <qlabel.h>
00109 #include <qtextcodec.h>
00110 #include <qheader.h>
00111 #include <qpopupmenu.h>
00112 #include <qradiobutton.h>
00113 #include <qlayout.h>
00114 #include <qcheckbox.h>
00115 #include <qwidgetstack.h>
00116
00117
00118 #include <assert.h>
00119 #include <stdlib.h>
00120
00121 #ifndef _PATH_SENDMAIL
00122 #define _PATH_SENDMAIL "/usr/sbin/sendmail"
00123 #endif
00124
00125 #ifdef DIM
00126 #undef DIM
00127 #endif
00128 #define DIM(x) sizeof(x) / sizeof(*x)
00129
00130 namespace {
00131
00132 struct EnumConfigEntryItem {
00133 const char * key;
00134 const char * desc;
00135 };
00136 struct EnumConfigEntry {
00137 const char * group;
00138 const char * key;
00139 const char * desc;
00140 const EnumConfigEntryItem * items;
00141 int numItems;
00142 int defaultItem;
00143 };
00144 struct BoolConfigEntry {
00145 const char * group;
00146 const char * key;
00147 const char * desc;
00148 bool defaultValue;
00149 };
00150
00151 static const char * lockedDownWarning =
00152 I18N_NOOP("<qt><p>This setting has been fixed by your administrator.</p>"
00153 "<p>If you think this is an error, please contact him.</p></qt>");
00154
00155 void checkLockDown( QWidget * w, const KConfigBase & c, const char * key ) {
00156 if ( c.entryIsImmutable( key ) ) {
00157 w->setEnabled( false );
00158 QToolTip::add( w, i18n( lockedDownWarning ) );
00159 } else {
00160 QToolTip::remove( w );
00161 }
00162 }
00163
00164 void populateButtonGroup( QButtonGroup * g, const EnumConfigEntry & e ) {
00165 g->setTitle( i18n( e.desc ) );
00166 g->layout()->setSpacing( KDialog::spacingHint() );
00167 for ( int i = 0 ; i < e.numItems ; ++i )
00168 g->insert( new QRadioButton( i18n( e.items[i].desc ), g ), i );
00169 }
00170
00171 void populateCheckBox( QCheckBox * b, const BoolConfigEntry & e ) {
00172 b->setText( i18n( e.desc ) );
00173 }
00174
00175 void loadWidget( QCheckBox * b, const KConfigBase & c, const BoolConfigEntry & e ) {
00176 Q_ASSERT( c.group() == e.group );
00177 checkLockDown( b, c, e.key );
00178 b->setChecked( c.readBoolEntry( e.key, e.defaultValue ) );
00179 }
00180
00181 void loadWidget( QButtonGroup * g, const KConfigBase & c, const EnumConfigEntry & e ) {
00182 Q_ASSERT( c.group() == e.group );
00183 Q_ASSERT( g->count() == e.numItems );
00184 checkLockDown( g, c, e.key );
00185 const QString s = c.readEntry( e.key, e.items[e.defaultItem].key );
00186 for ( int i = 0 ; i < e.numItems ; ++i )
00187 if ( s == e.items[i].key ) {
00188 g->setButton( i );
00189 return;
00190 }
00191 g->setButton( e.defaultItem );
00192 }
00193
00194 void saveCheckBox( QCheckBox * b, KConfigBase & c, const BoolConfigEntry & e ) {
00195 Q_ASSERT( c.group() == e.group );
00196 c.writeEntry( e.key, b->isChecked() );
00197 }
00198
00199 void saveButtonGroup( QButtonGroup * g, KConfigBase & c, const EnumConfigEntry & e ) {
00200 Q_ASSERT( c.group() == e.group );
00201 Q_ASSERT( g->count() == e.numItems );
00202 c.writeEntry( e.key, e.items[ g->id( g->selected() ) ].key );
00203 }
00204
00205 template <typename T_Widget, typename T_Entry>
00206 inline void loadProfile( T_Widget * g, const KConfigBase & c, const T_Entry & e ) {
00207 if ( c.hasKey( e.key ) )
00208 loadWidget( g, c, e );
00209 }
00210 }
00211
00212
00213 ConfigureDialog::ConfigureDialog( QWidget *parent, const char *name, bool modal )
00214 : KCMultiDialog( KDialogBase::IconList, KGuiItem( i18n( "&Load Profile..." ) ),
00215 KGuiItem(), User2, i18n( "Configure" ), parent, name, modal )
00216 , mProfileDialog( 0 )
00217 {
00218 KWin::setIcons( winId(), kapp->icon(), kapp->miniIcon() );
00219 showButton( User1, true );
00220
00221 addModule ( "kmail_config_identity", false );
00222 addModule ( "kmail_config_accounts", false );
00223 addModule ( "kmail_config_appearance", false );
00224 addModule ( "kmail_config_composer", false );
00225 addModule ( "kmail_config_security", false );
00226 addModule ( "kmail_config_misc", false );
00227
00228
00229
00230
00231
00232 KConfigGroup geometry( KMKernel::config(), "Geometry" );
00233 int width = geometry.readNumEntry( "ConfigureDialogWidth" );
00234 int height = geometry.readNumEntry( "ConfigureDialogHeight" );
00235 if ( width != 0 && height != 0 ) {
00236 setMinimumSize( width, height );
00237 }
00238
00239 }
00240
00241 void ConfigureDialog::hideEvent( QHideEvent *ev ) {
00242 KConfigGroup geometry( KMKernel::config(), "Geometry" );
00243 geometry.writeEntry( "ConfigureDialogWidth", width() );
00244 geometry.writeEntry( "ConfigureDialogHeight",height() );
00245 KDialogBase::hideEvent( ev );
00246 }
00247
00248 ConfigureDialog::~ConfigureDialog() {
00249 }
00250
00251 void ConfigureDialog::slotApply() {
00252 GlobalSettings::self()->writeConfig();
00253 KCMultiDialog::slotApply();
00254 }
00255
00256 void ConfigureDialog::slotOk() {
00257 GlobalSettings::self()->writeConfig();
00258 KCMultiDialog::slotOk();
00259 }
00260
00261 void ConfigureDialog::slotUser2() {
00262 if ( mProfileDialog ) {
00263 mProfileDialog->raise();
00264 return;
00265 }
00266 mProfileDialog = new ProfileDialog( this, "mProfileDialog" );
00267 connect( mProfileDialog, SIGNAL(profileSelected(KConfig*)),
00268 this, SIGNAL(installProfile(KConfig*)) );
00269 mProfileDialog->show();
00270 }
00271
00272
00273
00274
00275
00276
00277 QString IdentityPage::helpAnchor() const {
00278 return QString::fromLatin1("configure-identity");
00279 }
00280
00281 IdentityPage::IdentityPage( QWidget * parent, const char * name )
00282 : ConfigModule( parent, name ),
00283 mIdentityDialog( 0 )
00284 {
00285 QHBoxLayout * hlay = new QHBoxLayout( this, 0, KDialog::spacingHint() );
00286
00287 mIdentityList = new IdentityListView( this );
00288 connect( mIdentityList, SIGNAL(selectionChanged()),
00289 SLOT(slotIdentitySelectionChanged()) );
00290 connect( mIdentityList, SIGNAL(itemRenamed(QListViewItem*,const QString&,int)),
00291 SLOT(slotRenameIdentity(QListViewItem*,const QString&,int)) );
00292 connect( mIdentityList, SIGNAL(doubleClicked(QListViewItem*,const QPoint&,int)),
00293 SLOT(slotModifyIdentity()) );
00294 connect( mIdentityList, SIGNAL(contextMenu(KListView*,QListViewItem*,const QPoint&)),
00295 SLOT(slotContextMenu(KListView*,QListViewItem*,const QPoint&)) );
00296
00297
00298 hlay->addWidget( mIdentityList, 1 );
00299
00300 QVBoxLayout * vlay = new QVBoxLayout( hlay );
00301
00302 QPushButton * button = new QPushButton( i18n("&Add..."), this );
00303 mModifyButton = new QPushButton( i18n("&Modify..."), this );
00304 mRenameButton = new QPushButton( i18n("&Rename"), this );
00305 mRemoveButton = new QPushButton( i18n("Remo&ve"), this );
00306 mSetAsDefaultButton = new QPushButton( i18n("Set as &Default"), this );
00307 button->setAutoDefault( false );
00308 mModifyButton->setAutoDefault( false );
00309 mModifyButton->setEnabled( false );
00310 mRenameButton->setAutoDefault( false );
00311 mRenameButton->setEnabled( false );
00312 mRemoveButton->setAutoDefault( false );
00313 mRemoveButton->setEnabled( false );
00314 mSetAsDefaultButton->setAutoDefault( false );
00315 mSetAsDefaultButton->setEnabled( false );
00316 connect( button, SIGNAL(clicked()),
00317 this, SLOT(slotNewIdentity()) );
00318 connect( mModifyButton, SIGNAL(clicked()),
00319 this, SLOT(slotModifyIdentity()) );
00320 connect( mRenameButton, SIGNAL(clicked()),
00321 this, SLOT(slotRenameIdentity()) );
00322 connect( mRemoveButton, SIGNAL(clicked()),
00323 this, SLOT(slotRemoveIdentity()) );
00324 connect( mSetAsDefaultButton, SIGNAL(clicked()),
00325 this, SLOT(slotSetAsDefault()) );
00326 vlay->addWidget( button );
00327 vlay->addWidget( mModifyButton );
00328 vlay->addWidget( mRenameButton );
00329 vlay->addWidget( mRemoveButton );
00330 vlay->addWidget( mSetAsDefaultButton );
00331 vlay->addStretch( 1 );
00332 load();
00333 }
00334
00335 void IdentityPage::load()
00336 {
00337 KPIM::IdentityManager * im = kmkernel->identityManager();
00338 mOldNumberOfIdentities = im->shadowIdentities().count();
00339
00340 mIdentityList->clear();
00341 QListViewItem * item = 0;
00342 for ( KPIM::IdentityManager::Iterator it = im->modifyBegin() ; it != im->modifyEnd() ; ++it )
00343 item = new IdentityListViewItem( mIdentityList, item, *it );
00344 mIdentityList->setSelected( mIdentityList->currentItem(), true );
00345 }
00346
00347 void IdentityPage::save() {
00348 assert( !mIdentityDialog );
00349
00350 kmkernel->identityManager()->sort();
00351 kmkernel->identityManager()->commit();
00352
00353 if( mOldNumberOfIdentities < 2 && mIdentityList->childCount() > 1 ) {
00354
00355
00356 KConfigGroup composer( KMKernel::config(), "Composer" );
00357 int showHeaders = composer.readNumEntry( "headers", HDR_STANDARD );
00358 showHeaders |= HDR_IDENTITY;
00359 composer.writeEntry( "headers", showHeaders );
00360 }
00361
00362 if( mOldNumberOfIdentities > 1 && mIdentityList->childCount() < 2 ) {
00363
00364 KConfigGroup composer( KMKernel::config(), "Composer" );
00365 int showHeaders = composer.readNumEntry( "headers", HDR_STANDARD );
00366 showHeaders &= ~HDR_IDENTITY;
00367 composer.writeEntry( "headers", showHeaders );
00368 }
00369 }
00370
00371 void IdentityPage::slotNewIdentity()
00372 {
00373 assert( !mIdentityDialog );
00374
00375 KPIM::IdentityManager * im = kmkernel->identityManager();
00376 NewIdentityDialog dialog( im->shadowIdentities(), this, "new", true );
00377
00378 if( dialog.exec() == QDialog::Accepted ) {
00379 QString identityName = dialog.identityName().stripWhiteSpace();
00380 assert( !identityName.isEmpty() );
00381
00382
00383
00384
00385 switch ( dialog.duplicateMode() ) {
00386 case NewIdentityDialog::ExistingEntry:
00387 {
00388 KPIM::Identity & dupThis = im->modifyIdentityForName( dialog.duplicateIdentity() );
00389 im->newFromExisting( dupThis, identityName );
00390 break;
00391 }
00392 case NewIdentityDialog::ControlCenter:
00393 im->newFromControlCenter( identityName );
00394 break;
00395 case NewIdentityDialog::Empty:
00396 im->newFromScratch( identityName );
00397 default: ;
00398 }
00399
00400
00401
00402
00403 KPIM::Identity & newIdent = im->modifyIdentityForName( identityName );
00404 QListViewItem * item = mIdentityList->selectedItem();
00405 if ( item )
00406 item = item->itemAbove();
00407 mIdentityList->setSelected( new IdentityListViewItem( mIdentityList,
00408 item,
00409 newIdent ), true );
00410 slotModifyIdentity();
00411 }
00412 }
00413
00414 void IdentityPage::slotModifyIdentity() {
00415 assert( !mIdentityDialog );
00416
00417 IdentityListViewItem * item =
00418 dynamic_cast<IdentityListViewItem*>( mIdentityList->selectedItem() );
00419 if ( !item ) return;
00420
00421 mIdentityDialog = new IdentityDialog( this );
00422 mIdentityDialog->setIdentity( item->identity() );
00423
00424
00425 if ( mIdentityDialog->exec() == QDialog::Accepted ) {
00426 mIdentityDialog->updateIdentity( item->identity() );
00427 item->redisplay();
00428 emit changed(true);
00429 }
00430
00431 delete mIdentityDialog;
00432 mIdentityDialog = 0;
00433 }
00434
00435 void IdentityPage::slotRemoveIdentity()
00436 {
00437 assert( !mIdentityDialog );
00438
00439 KPIM::IdentityManager * im = kmkernel->identityManager();
00440 kdFatal( im->shadowIdentities().count() < 2 )
00441 << "Attempted to remove the last identity!" << endl;
00442
00443 IdentityListViewItem * item =
00444 dynamic_cast<IdentityListViewItem*>( mIdentityList->selectedItem() );
00445 if ( !item ) return;
00446
00447 QString msg = i18n("<qt>Do you really want to remove the identity named "
00448 "<b>%1</b>?</qt>").arg( item->identity().identityName() );
00449 if( KMessageBox::warningContinueCancel( this, msg, i18n("Remove Identity"),
00450 KGuiItem(i18n("&Remove"),"editdelete") ) == KMessageBox::Continue )
00451 if ( im->removeIdentity( item->identity().identityName() ) ) {
00452 delete item;
00453 mIdentityList->setSelected( mIdentityList->currentItem(), true );
00454 refreshList();
00455 }
00456 }
00457
00458 void IdentityPage::slotRenameIdentity() {
00459 assert( !mIdentityDialog );
00460
00461 QListViewItem * item = mIdentityList->selectedItem();
00462 if ( !item ) return;
00463
00464 mIdentityList->rename( item, 0 );
00465 }
00466
00467 void IdentityPage::slotRenameIdentity( QListViewItem * i,
00468 const QString & s, int col ) {
00469 assert( col == 0 );
00470 Q_UNUSED( col );
00471
00472 IdentityListViewItem * item = dynamic_cast<IdentityListViewItem*>( i );
00473 if ( !item ) return;
00474
00475 QString newName = s.stripWhiteSpace();
00476 if ( !newName.isEmpty() &&
00477 !kmkernel->identityManager()->shadowIdentities().contains( newName ) ) {
00478 KPIM::Identity & ident = item->identity();
00479 ident.setIdentityName( newName );
00480 emit changed(true);
00481 }
00482 item->redisplay();
00483 }
00484
00485 void IdentityPage::slotContextMenu( KListView *, QListViewItem * i,
00486 const QPoint & pos ) {
00487 IdentityListViewItem * item = dynamic_cast<IdentityListViewItem*>( i );
00488
00489 QPopupMenu * menu = new QPopupMenu( this );
00490 menu->insertItem( i18n("Add..."), this, SLOT(slotNewIdentity()) );
00491 if ( item ) {
00492 menu->insertItem( i18n("Modify..."), this, SLOT(slotModifyIdentity()) );
00493 if ( mIdentityList->childCount() > 1 )
00494 menu->insertItem( i18n("Remove"), this, SLOT(slotRemoveIdentity()) );
00495 if ( !item->identity().isDefault() )
00496 menu->insertItem( i18n("Set as Default"), this, SLOT(slotSetAsDefault()) );
00497 }
00498 menu->exec( pos );
00499 delete menu;
00500 }
00501
00502
00503 void IdentityPage::slotSetAsDefault() {
00504 assert( !mIdentityDialog );
00505
00506 IdentityListViewItem * item =
00507 dynamic_cast<IdentityListViewItem*>( mIdentityList->selectedItem() );
00508 if ( !item ) return;
00509
00510 KPIM::IdentityManager * im = kmkernel->identityManager();
00511 im->setAsDefault( item->identity().identityName() );
00512 refreshList();
00513 }
00514
00515 void IdentityPage::refreshList() {
00516 for ( QListViewItemIterator it( mIdentityList ) ; it.current() ; ++it ) {
00517 IdentityListViewItem * item =
00518 dynamic_cast<IdentityListViewItem*>(it.current());
00519 if ( item )
00520 item->redisplay();
00521 }
00522 emit changed(true);
00523 }
00524
00525 void IdentityPage::slotIdentitySelectionChanged()
00526 {
00527 IdentityListViewItem *item =
00528 dynamic_cast<IdentityListViewItem*>( mIdentityList->selectedItem() );
00529
00530 mRemoveButton->setEnabled( item && mIdentityList->childCount() > 1 );
00531 mModifyButton->setEnabled( item );
00532 mRenameButton->setEnabled( item );
00533 mSetAsDefaultButton->setEnabled( item && !item->identity().isDefault() );
00534 }
00535
00536 void IdentityPage::slotUpdateTransportCombo( const QStringList & sl )
00537 {
00538 if ( mIdentityDialog ) mIdentityDialog->slotUpdateTransportCombo( sl );
00539 }
00540
00541
00542
00543
00544
00545
00546
00547
00548 QString AccountsPage::helpAnchor() const {
00549 return QString::fromLatin1("configure-accounts");
00550 }
00551
00552 AccountsPage::AccountsPage( QWidget * parent, const char * name )
00553 : ConfigModuleWithTabs( parent, name )
00554 {
00555
00556
00557
00558 mReceivingTab = new ReceivingTab();
00559 addTab( mReceivingTab, i18n( "&Receiving" ) );
00560 connect( mReceivingTab, SIGNAL(accountListChanged(const QStringList &)),
00561 this, SIGNAL(accountListChanged(const QStringList &)) );
00562
00563
00564
00565
00566 mSendingTab = new SendingTab();
00567 addTab( mSendingTab, i18n( "&Sending" ) );
00568 connect( mSendingTab, SIGNAL(transportListChanged(const QStringList&)),
00569 this, SIGNAL(transportListChanged(const QStringList&)) );
00570
00571 load();
00572 }
00573
00574 QString AccountsPage::SendingTab::helpAnchor() const {
00575 return QString::fromLatin1("configure-accounts-sending");
00576 }
00577
00578 AccountsPageSendingTab::AccountsPageSendingTab( QWidget * parent, const char * name )
00579 : ConfigModuleTab( parent, name )
00580 {
00581 mTransportInfoList.setAutoDelete( true );
00582
00583 QVBoxLayout *vlay;
00584 QVBoxLayout *btn_vlay;
00585 QHBoxLayout *hlay;
00586 QGridLayout *glay;
00587 QPushButton *button;
00588 QGroupBox *group;
00589
00590 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
00591
00592 vlay->addWidget( new QLabel( i18n("Outgoing accounts (add at least one):"), this ) );
00593
00594
00595 hlay = new QHBoxLayout();
00596 vlay->addLayout( hlay, 10 );
00597
00598
00599
00600 mTransportList = new ListView( this, "transportList", 5 );
00601 mTransportList->addColumn( i18n("Name") );
00602 mTransportList->addColumn( i18n("Type") );
00603 mTransportList->setAllColumnsShowFocus( true );
00604 mTransportList->setSorting( -1 );
00605 connect( mTransportList, SIGNAL(selectionChanged()),
00606 this, SLOT(slotTransportSelected()) );
00607 connect( mTransportList, SIGNAL(doubleClicked( QListViewItem *)),
00608 this, SLOT(slotModifySelectedTransport()) );
00609 hlay->addWidget( mTransportList, 1 );
00610
00611
00612 btn_vlay = new QVBoxLayout( hlay );
00613
00614
00615 button = new QPushButton( i18n("A&dd..."), this );
00616 button->setAutoDefault( false );
00617 connect( button, SIGNAL(clicked()),
00618 this, SLOT(slotAddTransport()) );
00619 btn_vlay->addWidget( button );
00620
00621
00622 mModifyTransportButton = new QPushButton( i18n("&Modify..."), this );
00623 mModifyTransportButton->setAutoDefault( false );
00624 mModifyTransportButton->setEnabled( false );
00625 connect( mModifyTransportButton, SIGNAL(clicked()),
00626 this, SLOT(slotModifySelectedTransport()) );
00627 btn_vlay->addWidget( mModifyTransportButton );
00628
00629
00630 mRemoveTransportButton = new QPushButton( i18n("R&emove"), this );
00631 mRemoveTransportButton->setAutoDefault( false );
00632 mRemoveTransportButton->setEnabled( false );
00633 connect( mRemoveTransportButton, SIGNAL(clicked()),
00634 this, SLOT(slotRemoveSelectedTransport()) );
00635 btn_vlay->addWidget( mRemoveTransportButton );
00636
00637 mSetDefaultTransportButton = new QPushButton( i18n("Set Default"), this );
00638 mSetDefaultTransportButton->setAutoDefault( false );
00639 mSetDefaultTransportButton->setEnabled( false );
00640 connect ( mSetDefaultTransportButton, SIGNAL(clicked()),
00641 this, SLOT(slotSetDefaultTransport()) );
00642 btn_vlay->addWidget( mSetDefaultTransportButton );
00643 btn_vlay->addStretch( 1 );
00644
00645
00646 group = new QGroupBox( 0, Qt::Vertical,
00647 i18n("Common Options"), this );
00648 vlay->addWidget(group);
00649
00650
00651 glay = new QGridLayout( group->layout(), 5, 3, KDialog::spacingHint() );
00652 glay->setColStretch( 2, 10 );
00653
00654
00655 mConfirmSendCheck = new QCheckBox( i18n("Confirm &before send"), group );
00656 glay->addMultiCellWidget( mConfirmSendCheck, 0, 0, 0, 1 );
00657 connect( mConfirmSendCheck, SIGNAL( stateChanged( int ) ),
00658 this, SLOT( slotEmitChanged( void ) ) );
00659
00660
00661 mSendOnCheckCombo = new QComboBox( false, group );
00662 mSendOnCheckCombo->insertStringList( QStringList()
00663 << i18n("Never Automatically")
00664 << i18n("On Manual Mail Checks")
00665 << i18n("On All Mail Checks") );
00666 glay->addWidget( mSendOnCheckCombo, 1, 1 );
00667 connect( mSendOnCheckCombo, SIGNAL( activated( int ) ),
00668 this, SLOT( slotEmitChanged( void ) ) );
00669
00670
00671 mSendMethodCombo = new QComboBox( false, group );
00672 mSendMethodCombo->insertStringList( QStringList()
00673 << i18n("Send Now")
00674 << i18n("Send Later") );
00675 glay->addWidget( mSendMethodCombo, 2, 1 );
00676 connect( mSendMethodCombo, SIGNAL( activated( int ) ),
00677 this, SLOT( slotEmitChanged( void ) ) );
00678
00679
00680
00681
00682 mMessagePropertyCombo = new QComboBox( false, group );
00683 mMessagePropertyCombo->insertStringList( QStringList()
00684 << i18n("Allow 8-bit")
00685 << i18n("MIME Compliant (Quoted Printable)") );
00686 glay->addWidget( mMessagePropertyCombo, 3, 1 );
00687 connect( mMessagePropertyCombo, SIGNAL( activated( int ) ),
00688 this, SLOT( slotEmitChanged( void ) ) );
00689
00690
00691 mDefaultDomainEdit = new KLineEdit( group );
00692 glay->addMultiCellWidget( mDefaultDomainEdit, 4, 4, 1, 2 );
00693 connect( mDefaultDomainEdit, SIGNAL( textChanged( const QString& ) ),
00694 this, SLOT( slotEmitChanged( void ) ) );
00695
00696
00697 QLabel *l = new QLabel( mSendOnCheckCombo,
00698 i18n("Send &messages in outbox folder:"), group );
00699 glay->addWidget( l, 1, 0 );
00700
00701 QString msg = i18n( GlobalSettings::self()->sendOnCheckItem()->whatsThis().utf8() );
00702 QWhatsThis::add( l, msg );
00703 QWhatsThis::add( mSendOnCheckCombo, msg );
00704
00705 glay->addWidget( new QLabel( mSendMethodCombo,
00706 i18n("Defa&ult send method:"), group ), 2, 0 );
00707 glay->addWidget( new QLabel( mMessagePropertyCombo,
00708 i18n("Message &property:"), group ), 3, 0 );
00709 l = new QLabel( mDefaultDomainEdit,
00710 i18n("Defaul&t domain:"), group );
00711 glay->addWidget( l, 4, 0 );
00712
00713
00714 msg = i18n( "<qt><p>The default domain is used to complete email "
00715 "addresses that only consist of the user's name."
00716 "</p></qt>" );
00717 QWhatsThis::add( l, msg );
00718 QWhatsThis::add( mDefaultDomainEdit, msg );
00719 }
00720
00721
00722 void AccountsPage::SendingTab::slotTransportSelected()
00723 {
00724 QListViewItem *cur = mTransportList->selectedItem();
00725 mModifyTransportButton->setEnabled( cur );
00726 mRemoveTransportButton->setEnabled( cur );
00727 mSetDefaultTransportButton->setEnabled( cur );
00728 }
00729
00730
00731 static inline QString uniqueName( const QStringList & list,
00732 const QString & name )
00733 {
00734 int suffix = 1;
00735 QString result = name;
00736 while ( list.find( result ) != list.end() ) {
00737 result = i18n("%1: name; %2: number appended to it to make it unique "
00738 "among a list of names", "%1 %2")
00739 .arg( name ).arg( suffix );
00740 suffix++;
00741 }
00742 return result;
00743 }
00744
00745 void AccountsPage::SendingTab::slotSetDefaultTransport()
00746 {
00747 QListViewItem *item = mTransportList->selectedItem();
00748 if ( !item ) return;
00749
00750 KMTransportInfo ti;
00751
00752 QListViewItemIterator it( mTransportList );
00753 for ( ; it.current(); ++it ) {
00754 ti.readConfig( KMTransportInfo::findTransport( it.current()->text(0) ));
00755 if ( ti.type != "sendmail" ) {
00756 it.current()->setText( 1, "smtp" );
00757 } else {
00758 it.current()->setText( 1, "sendmail" );
00759 }
00760 }
00761
00762 if ( item->text(1) != "sendmail" ) {
00763 item->setText( 1, i18n( "smtp (Default)" ));
00764 } else {
00765 item->setText( 1, i18n( "sendmail (Default)" ));
00766 }
00767
00768 GlobalSettings::self()->setDefaultTransport( item->text(0) );
00769
00770 }
00771
00772 void AccountsPage::SendingTab::slotAddTransport()
00773 {
00774 int transportType;
00775
00776 {
00777 KMTransportSelDlg selDialog( this );
00778 if ( selDialog.exec() != QDialog::Accepted ) return;
00779 transportType = selDialog.selected();
00780 }
00781
00782 KMTransportInfo *transportInfo = new KMTransportInfo();
00783 switch ( transportType ) {
00784 case 0:
00785 transportInfo->type = QString::fromLatin1("smtp");
00786 break;
00787 case 1:
00788 transportInfo->type = QString::fromLatin1("sendmail");
00789 transportInfo->name = i18n("Sendmail");
00790 transportInfo->host = _PATH_SENDMAIL;
00791 break;
00792 default:
00793 assert( 0 );
00794 }
00795
00796 KMTransportDialog dialog( i18n("Add Transport"), transportInfo, this );
00797
00798
00799
00800 QStringList transportNames;
00801 QPtrListIterator<KMTransportInfo> it( mTransportInfoList );
00802 for ( it.toFirst() ; it.current() ; ++it )
00803 transportNames << (*it)->name;
00804
00805 if( dialog.exec() != QDialog::Accepted ) {
00806 delete transportInfo;
00807 return;
00808 }
00809
00810
00811
00812 transportInfo->name = uniqueName( transportNames, transportInfo->name );
00813
00814 transportNames << transportInfo->name;
00815 mTransportInfoList.append( transportInfo );
00816
00817
00818
00819 QListViewItem *lastItem = mTransportList->firstChild();
00820 QString typeDisplayName;
00821 if ( lastItem ) {
00822 typeDisplayName = transportInfo->type;
00823 } else {
00824 typeDisplayName = i18n("%1: type of transport. Result used in "
00825 "Configure->Accounts->Sending listview, \"type\" "
00826 "column, first row, to indicate that this is the "
00827 "default transport", "%1 (Default)")
00828 .arg( transportInfo->type );
00829 GlobalSettings::self()->setDefaultTransport( transportInfo->name );
00830 }
00831 (void) new QListViewItem( mTransportList, lastItem, transportInfo->name,
00832 typeDisplayName );
00833
00834
00835 emit transportListChanged( transportNames );
00836 emit changed( true );
00837 }
00838
00839 void AccountsPage::SendingTab::slotModifySelectedTransport()
00840 {
00841 QListViewItem *item = mTransportList->selectedItem();
00842 if ( !item ) return;
00843
00844 QPtrListIterator<KMTransportInfo> it( mTransportInfoList );
00845 for ( it.toFirst() ; it.current() ; ++it )
00846 if ( (*it)->name == item->text(0) ) break;
00847 if ( !it.current() ) return;
00848
00849 KMTransportDialog dialog( i18n("Modify Transport"), (*it), this );
00850
00851 if ( dialog.exec() != QDialog::Accepted ) return;
00852
00853
00854
00855 QStringList transportNames;
00856 QPtrListIterator<KMTransportInfo> jt( mTransportInfoList );
00857 int entryLocation = -1;
00858 for ( jt.toFirst() ; jt.current() ; ++jt )
00859 if ( jt != it )
00860 transportNames << (*jt)->name;
00861 else
00862 entryLocation = transportNames.count();
00863 assert( entryLocation >= 0 );
00864
00865
00866 (*it)->name = uniqueName( transportNames, (*it)->name );
00867
00868 item->setText( 0, (*it)->name );
00869
00870
00871 transportNames.insert( transportNames.at( entryLocation ), (*it)->name );
00872 emit transportListChanged( transportNames );
00873 emit changed( true );
00874 }
00875
00876 void AccountsPage::SendingTab::slotRemoveSelectedTransport()
00877 {
00878 QListViewItem *item = mTransportList->selectedItem();
00879 if ( !item ) return;
00880
00881 QStringList changedIdents;
00882 KPIM::IdentityManager * im = kmkernel->identityManager();
00883 for ( KPIM::IdentityManager::Iterator it = im->modifyBegin(); it != im->modifyEnd(); ++it ) {
00884 if ( item->text( 0 ) == (*it).transport() ) {
00885 (*it).setTransport( QString::null );
00886 changedIdents += (*it).identityName();
00887 }
00888 }
00889
00890
00891 const QString& currentTransport = GlobalSettings::self()->currentTransport();
00892 if ( item->text( 0 ) == currentTransport ) {
00893 GlobalSettings::self()->setCurrentTransport( QString::null );
00894 }
00895
00896 if ( !changedIdents.isEmpty() ) {
00897 QString information = i18n( "This identity has been changed to use the default transport:",
00898 "These %n identities have been changed to use the default transport:",
00899 changedIdents.count() );
00900 KMessageBox::informationList( this, information, changedIdents );
00901 }
00902
00903 QPtrListIterator<KMTransportInfo> it( mTransportInfoList );
00904 for ( it.toFirst() ; it.current() ; ++it )
00905 if ( (*it)->name == item->text(0) ) break;
00906 if ( !it.current() ) return;
00907
00908 KMTransportInfo ti;
00909
00910 QListViewItem *newCurrent = item->itemBelow();
00911 if ( !newCurrent ) newCurrent = item->itemAbove();
00912
00913 if ( newCurrent ) {
00914 mTransportList->setCurrentItem( newCurrent );
00915 mTransportList->setSelected( newCurrent, true );
00916 GlobalSettings::self()->setDefaultTransport( newCurrent->text(0) );
00917 ti.readConfig( KMTransportInfo::findTransport( newCurrent->text(0) ));
00918 if ( item->text( 0 ) == GlobalSettings::self()->defaultTransport() ) {
00919 if ( ti.type != "sendmail" ) {
00920 newCurrent->setText( 1, i18n("smtp (Default)") );
00921 } else {
00922 newCurrent->setText( 1, i18n("sendmail (Default)" ));
00923 }
00924 }
00925 } else {
00926 GlobalSettings::self()->setDefaultTransport( QString::null );
00927 }
00928
00929 delete item;
00930 mTransportInfoList.remove( it );
00931
00932 QStringList transportNames;
00933 for ( it.toFirst() ; it.current() ; ++it )
00934 transportNames << (*it)->name;
00935 emit transportListChanged( transportNames );
00936 emit changed( true );
00937 }
00938
00939 void AccountsPage::SendingTab::doLoadFromGlobalSettings() {
00940 mSendOnCheckCombo->setCurrentItem( GlobalSettings::self()->sendOnCheck() );
00941 }
00942
00943 void AccountsPage::SendingTab::doLoadOther() {
00944 KConfigGroup general( KMKernel::config(), "General");
00945 KConfigGroup composer( KMKernel::config(), "Composer");
00946
00947 int numTransports = general.readNumEntry("transports", 0);
00948
00949 QListViewItem *top = 0;
00950 mTransportInfoList.clear();
00951 mTransportList->clear();
00952 QStringList transportNames;
00953 for ( int i = 1 ; i <= numTransports ; i++ ) {
00954 KMTransportInfo *ti = new KMTransportInfo();
00955 ti->readConfig(i);
00956 mTransportInfoList.append( ti );
00957 transportNames << ti->name;
00958 top = new QListViewItem( mTransportList, top, ti->name, ti->type );
00959 }
00960 emit transportListChanged( transportNames );
00961
00962 const QString &defaultTransport = GlobalSettings::self()->defaultTransport();
00963
00964 QListViewItemIterator it( mTransportList );
00965 for ( ; it.current(); ++it ) {
00966 if ( it.current()->text(0) == defaultTransport ) {
00967 if ( it.current()->text(1) != "sendmail" ) {
00968 it.current()->setText( 1, i18n( "smtp (Default)" ));
00969 } else {
00970 it.current()->setText( 1, i18n( "sendmail (Default)" ));
00971 }
00972 } else {
00973 if ( it.current()->text(1) != "sendmail" ) {
00974 it.current()->setText( 1, "smtp" );
00975 } else {
00976 it.current()->setText( 1, "sendmail" );
00977 }
00978 }
00979 }
00980
00981 mSendMethodCombo->setCurrentItem(
00982 kmkernel->msgSender()->sendImmediate() ? 0 : 1 );
00983 mMessagePropertyCombo->setCurrentItem(
00984 kmkernel->msgSender()->sendQuotedPrintable() ? 1 : 0 );
00985
00986 mConfirmSendCheck->setChecked( composer.readBoolEntry( "confirm-before-send",
00987 false ) );
00988 QString str = general.readEntry( "Default domain" );
00989 if( str.isEmpty() )
00990 {
00991
00992
00993
00994 char buffer[256];
00995 if ( !gethostname( buffer, 255 ) )
00996
00997 buffer[255] = 0;
00998 else
00999 buffer[0] = 0;
01000 str = QString::fromLatin1( *buffer ? buffer : "localhost" );
01001 }
01002 mDefaultDomainEdit->setText( str );
01003 }
01004
01005 void AccountsPage::SendingTab::save() {
01006 KConfigGroup general( KMKernel::config(), "General" );
01007 KConfigGroup composer( KMKernel::config(), "Composer" );
01008
01009
01010 general.writeEntry( "transports", mTransportInfoList.count() );
01011 QPtrListIterator<KMTransportInfo> it( mTransportInfoList );
01012 for ( int i = 1 ; it.current() ; ++it, ++i )
01013 (*it)->writeConfig(i);
01014
01015
01016 GlobalSettings::self()->setSendOnCheck( mSendOnCheckCombo->currentItem() );
01017 kmkernel->msgSender()->setSendImmediate(
01018 mSendMethodCombo->currentItem() == 0 );
01019 kmkernel->msgSender()->setSendQuotedPrintable(
01020 mMessagePropertyCombo->currentItem() == 1 );
01021 kmkernel->msgSender()->writeConfig( false );
01022 composer.writeEntry("confirm-before-send", mConfirmSendCheck->isChecked() );
01023 general.writeEntry( "Default domain", mDefaultDomainEdit->text() );
01024 }
01025
01026 QString AccountsPage::ReceivingTab::helpAnchor() const {
01027 return QString::fromLatin1("configure-accounts-receiving");
01028 }
01029
01030 AccountsPageReceivingTab::AccountsPageReceivingTab( QWidget * parent, const char * name )
01031 : ConfigModuleTab ( parent, name )
01032 {
01033
01034 QVBoxLayout *vlay;
01035 QVBoxLayout *btn_vlay;
01036 QHBoxLayout *hlay;
01037 QPushButton *button;
01038 QGroupBox *group;
01039
01040 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
01041
01042
01043 vlay->addWidget( new QLabel( i18n("Incoming accounts (add at least one):"), this ) );
01044
01045
01046 hlay = new QHBoxLayout();
01047 vlay->addLayout( hlay, 10 );
01048
01049
01050 mAccountList = new ListView( this, "accountList", 5 );
01051 mAccountList->addColumn( i18n("Name") );
01052 mAccountList->addColumn( i18n("Type") );
01053 mAccountList->addColumn( i18n("Folder") );
01054 mAccountList->setAllColumnsShowFocus( true );
01055 mAccountList->setSorting( -1 );
01056 connect( mAccountList, SIGNAL(selectionChanged()),
01057 this, SLOT(slotAccountSelected()) );
01058 connect( mAccountList, SIGNAL(doubleClicked( QListViewItem *)),
01059 this, SLOT(slotModifySelectedAccount()) );
01060 hlay->addWidget( mAccountList, 1 );
01061
01062
01063 btn_vlay = new QVBoxLayout( hlay );
01064
01065
01066 button = new QPushButton( i18n("A&dd..."), this );
01067 button->setAutoDefault( false );
01068 connect( button, SIGNAL(clicked()),
01069 this, SLOT(slotAddAccount()) );
01070 btn_vlay->addWidget( button );
01071
01072
01073 mModifyAccountButton = new QPushButton( i18n("&Modify..."), this );
01074 mModifyAccountButton->setAutoDefault( false );
01075 mModifyAccountButton->setEnabled( false );
01076 connect( mModifyAccountButton, SIGNAL(clicked()),
01077 this, SLOT(slotModifySelectedAccount()) );
01078 btn_vlay->addWidget( mModifyAccountButton );
01079
01080
01081 mRemoveAccountButton = new QPushButton( i18n("R&emove"), this );
01082 mRemoveAccountButton->setAutoDefault( false );
01083 mRemoveAccountButton->setEnabled( false );
01084 connect( mRemoveAccountButton, SIGNAL(clicked()),
01085 this, SLOT(slotRemoveSelectedAccount()) );
01086 btn_vlay->addWidget( mRemoveAccountButton );
01087 btn_vlay->addStretch( 1 );
01088
01089 mCheckmailStartupCheck = new QCheckBox( i18n("Chec&k mail on startup"), this );
01090 vlay->addWidget( mCheckmailStartupCheck );
01091 connect( mCheckmailStartupCheck, SIGNAL( stateChanged( int ) ),
01092 this, SLOT( slotEmitChanged( void ) ) );
01093
01094
01095 group = new QVGroupBox( i18n("New Mail Notification"), this );
01096 vlay->addWidget( group );
01097 group->layout()->setSpacing( KDialog::spacingHint() );
01098
01099
01100 mBeepNewMailCheck = new QCheckBox(i18n("&Beep"), group );
01101 mBeepNewMailCheck->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding,
01102 QSizePolicy::Fixed ) );
01103 connect( mBeepNewMailCheck, SIGNAL( stateChanged( int ) ),
01104 this, SLOT( slotEmitChanged( void ) ) );
01105
01106
01107 mVerboseNotificationCheck =
01108 new QCheckBox( i18n( "Deta&iled new mail notification" ), group );
01109 mVerboseNotificationCheck->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding,
01110 QSizePolicy::Fixed ) );
01111 QToolTip::add( mVerboseNotificationCheck,
01112 i18n( "Show for each folder the number of newly arrived "
01113 "messages" ) );
01114 QWhatsThis::add( mVerboseNotificationCheck,
01115 GlobalSettings::self()->verboseNewMailNotificationItem()->whatsThis() );
01116 connect( mVerboseNotificationCheck, SIGNAL( stateChanged( int ) ),
01117 this, SLOT( slotEmitChanged() ) );
01118
01119
01120 mOtherNewMailActionsButton = new QPushButton( i18n("Other Actio&ns"), group );
01121 mOtherNewMailActionsButton->setSizePolicy( QSizePolicy( QSizePolicy::Fixed,
01122 QSizePolicy::Fixed ) );
01123 connect( mOtherNewMailActionsButton, SIGNAL(clicked()),
01124 this, SLOT(slotEditNotifications()) );
01125 }
01126
01127
01128 void AccountsPage::ReceivingTab::slotAccountSelected()
01129 {
01130 QListViewItem * item = mAccountList->selectedItem();
01131 mModifyAccountButton->setEnabled( item );
01132 mRemoveAccountButton->setEnabled( item );
01133 }
01134
01135 QStringList AccountsPage::ReceivingTab::occupiedNames()
01136 {
01137 QStringList accountNames = kmkernel->acctMgr()->getAccounts();
01138
01139 QValueList<ModifiedAccountsType*>::Iterator k;
01140 for (k = mModifiedAccounts.begin(); k != mModifiedAccounts.end(); ++k )
01141 if ((*k)->oldAccount)
01142 accountNames.remove( (*k)->oldAccount->name() );
01143
01144 QValueList< QGuardedPtr<KMAccount> >::Iterator l;
01145 for (l = mAccountsToDelete.begin(); l != mAccountsToDelete.end(); ++l )
01146 if (*l)
01147 accountNames.remove( (*l)->name() );
01148
01149 QValueList< QGuardedPtr<KMAccount> >::Iterator it;
01150 for (it = mNewAccounts.begin(); it != mNewAccounts.end(); ++it )
01151 if (*it)
01152 accountNames += (*it)->name();
01153
01154 QValueList<ModifiedAccountsType*>::Iterator j;
01155 for (j = mModifiedAccounts.begin(); j != mModifiedAccounts.end(); ++j )
01156 accountNames += (*j)->newAccount->name();
01157
01158 return accountNames;
01159 }
01160
01161 void AccountsPage::ReceivingTab::slotAddAccount() {
01162 KMAcctSelDlg accountSelectorDialog( this );
01163 if( accountSelectorDialog.exec() != QDialog::Accepted ) return;
01164
01165 const char *accountType = 0;
01166 switch ( accountSelectorDialog.selected() ) {
01167 case 0: accountType = "local"; break;
01168 case 1: accountType = "pop"; break;
01169 case 2: accountType = "imap"; break;
01170 case 3: accountType = "cachedimap"; break;
01171 case 4: accountType = "maildir"; break;
01172
01173 default:
01174
01175
01176 KMessageBox::sorry( this, i18n("Unknown account type selected") );
01177 return;
01178 }
01179
01180 KMAccount *account
01181 = kmkernel->acctMgr()->create( QString::fromLatin1( accountType ) );
01182 if ( !account ) {
01183
01184
01185 KMessageBox::sorry( this, i18n("Unable to create account") );
01186 return;
01187 }
01188
01189 account->init();
01190
01191 AccountDialog dialog( i18n("Add Account"), account, this );
01192
01193 QStringList accountNames = occupiedNames();
01194
01195 if( dialog.exec() != QDialog::Accepted ) {
01196 delete account;
01197 return;
01198 }
01199
01200 account->deinstallTimer();
01201 account->setName( uniqueName( accountNames, account->name() ) );
01202
01203 QListViewItem *after = mAccountList->firstChild();
01204 while ( after && after->nextSibling() )
01205 after = after->nextSibling();
01206
01207 QListViewItem *listItem =
01208 new QListViewItem( mAccountList, after, account->name(), account->type() );
01209 if( account->folder() )
01210 listItem->setText( 2, account->folder()->label() );
01211
01212 mNewAccounts.append( account );
01213 emit changed( true );
01214 }
01215
01216
01217
01218 void AccountsPage::ReceivingTab::slotModifySelectedAccount()
01219 {
01220 QListViewItem *listItem = mAccountList->selectedItem();
01221 if( !listItem ) return;
01222
01223 KMAccount *account = 0;
01224 QValueList<ModifiedAccountsType*>::Iterator j;
01225 for (j = mModifiedAccounts.begin(); j != mModifiedAccounts.end(); ++j )
01226 if ( (*j)->newAccount->name() == listItem->text(0) ) {
01227 account = (*j)->newAccount;
01228 break;
01229 }
01230
01231 if ( !account ) {
01232 QValueList< QGuardedPtr<KMAccount> >::Iterator it;
01233 for ( it = mNewAccounts.begin() ; it != mNewAccounts.end() ; ++it )
01234 if ( (*it)->name() == listItem->text(0) ) {
01235 account = *it;
01236 break;
01237 }
01238
01239 if ( !account ) {
01240 account = kmkernel->acctMgr()->findByName( listItem->text(0) );
01241 if( !account ) {
01242
01243 KMessageBox::sorry( this, i18n("Unable to locate account") );
01244 return;
01245 }
01246 if ( account->type() == "imap" || account->type() == "cachedimap" )
01247 {
01248 ImapAccountBase* ai = static_cast<ImapAccountBase*>( account );
01249 if ( ai->namespaces().isEmpty() || ai->namespaceToDelimiter().isEmpty() )
01250 {
01251
01252 kdDebug(5006) << "slotModifySelectedAccount - connect" << endl;
01253 ai->makeConnection();
01254 }
01255 }
01256
01257 ModifiedAccountsType *mod = new ModifiedAccountsType;
01258 mod->oldAccount = account;
01259 mod->newAccount = kmkernel->acctMgr()->create( account->type(),
01260 account->name() );
01261 mod->newAccount->pseudoAssign( account );
01262 mModifiedAccounts.append( mod );
01263 account = mod->newAccount;
01264 }
01265 }
01266
01267 QStringList accountNames = occupiedNames();
01268 accountNames.remove( account->name() );
01269
01270 AccountDialog dialog( i18n("Modify Account"), account, this );
01271
01272 if( dialog.exec() != QDialog::Accepted ) return;
01273
01274 account->setName( uniqueName( accountNames, account->name() ) );
01275
01276 listItem->setText( 0, account->name() );
01277 listItem->setText( 1, account->type() );
01278 if( account->folder() )
01279 listItem->setText( 2, account->folder()->label() );
01280
01281 emit changed( true );
01282 }
01283
01284
01285
01286 void AccountsPage::ReceivingTab::slotRemoveSelectedAccount() {
01287 QListViewItem *listItem = mAccountList->selectedItem();
01288 if( !listItem ) return;
01289
01290 KMAccount *acct = 0;
01291 QValueList<ModifiedAccountsType*>::Iterator j;
01292 for ( j = mModifiedAccounts.begin() ; j != mModifiedAccounts.end() ; ++j )
01293 if ( (*j)->newAccount->name() == listItem->text(0) ) {
01294 acct = (*j)->oldAccount;
01295 mAccountsToDelete.append( acct );
01296 mModifiedAccounts.remove( j );
01297 break;
01298 }
01299 if ( !acct ) {
01300 QValueList< QGuardedPtr<KMAccount> >::Iterator it;
01301 for ( it = mNewAccounts.begin() ; it != mNewAccounts.end() ; ++it )
01302 if ( (*it)->name() == listItem->text(0) ) {
01303 acct = *it;
01304 mNewAccounts.remove( it );
01305 break;
01306 }
01307 }
01308 if ( !acct ) {
01309 acct = kmkernel->acctMgr()->findByName( listItem->text(0) );
01310 if ( acct )
01311 mAccountsToDelete.append( acct );
01312 }
01313 if ( !acct ) {
01314
01315 KMessageBox::sorry( this, i18n("<qt>Unable to locate account <b>%1</b>.</qt>")
01316 .arg(listItem->text(0)) );
01317 return;
01318 }
01319
01320 QListViewItem * item = listItem->itemBelow();
01321 if ( !item ) item = listItem->itemAbove();
01322 delete listItem;
01323
01324 if ( item )
01325 mAccountList->setSelected( item, true );
01326
01327 emit changed( true );
01328 }
01329
01330 void AccountsPage::ReceivingTab::slotEditNotifications()
01331 {
01332 if(kmkernel->xmlGuiInstance())
01333 KNotifyDialog::configure(this, 0, kmkernel->xmlGuiInstance()->aboutData());
01334 else
01335 KNotifyDialog::configure(this);
01336 }
01337
01338 void AccountsPage::ReceivingTab::doLoadFromGlobalSettings() {
01339 mVerboseNotificationCheck->setChecked( GlobalSettings::self()->verboseNewMailNotification() );
01340 }
01341
01342 void AccountsPage::ReceivingTab::doLoadOther() {
01343 KConfigGroup general( KMKernel::config(), "General" );
01344
01345 mAccountList->clear();
01346 QListViewItem *top = 0;
01347
01348 for( KMAccount *a = kmkernel->acctMgr()->first(); a!=0;
01349 a = kmkernel->acctMgr()->next() ) {
01350 QListViewItem *listItem =
01351 new QListViewItem( mAccountList, top, a->name(), a->type() );
01352 if( a->folder() )
01353 listItem->setText( 2, a->folder()->label() );
01354 top = listItem;
01355 }
01356 QListViewItem *listItem = mAccountList->firstChild();
01357 if ( listItem ) {
01358 mAccountList->setCurrentItem( listItem );
01359 mAccountList->setSelected( listItem, true );
01360 }
01361
01362 mBeepNewMailCheck->setChecked( general.readBoolEntry("beep-on-mail", false ) );
01363 mCheckmailStartupCheck->setChecked( general.readBoolEntry("checkmail-startup", false) );
01364 QTimer::singleShot( 0, this, SLOT( slotTweakAccountList() ) );
01365 }
01366
01367 void AccountsPage::ReceivingTab::slotTweakAccountList()
01368 {
01369
01370
01371 mAccountList->resizeContents( mAccountList->visibleWidth(), mAccountList->contentsHeight() );
01372 }
01373
01374 void AccountsPage::ReceivingTab::save() {
01375
01376 QValueList< QGuardedPtr<KMAccount> >::Iterator it;
01377 for (it = mNewAccounts.begin(); it != mNewAccounts.end(); ++it ) {
01378 kmkernel->acctMgr()->add( *it );
01379 (*it)->installTimer();
01380 }
01381
01382
01383 QValueList<ModifiedAccountsType*>::Iterator j;
01384 for ( j = mModifiedAccounts.begin() ; j != mModifiedAccounts.end() ; ++j ) {
01385 (*j)->oldAccount->pseudoAssign( (*j)->newAccount );
01386 delete (*j)->newAccount;
01387 delete (*j);
01388 }
01389 mModifiedAccounts.clear();
01390
01391
01392 for ( it = mAccountsToDelete.begin() ;
01393 it != mAccountsToDelete.end() ; ++it ) {
01394 kmkernel->acctMgr()->writeConfig( true );
01395 if ( (*it) && !kmkernel->acctMgr()->remove(*it) )
01396 KMessageBox::sorry( this, i18n("<qt>Unable to locate account <b>%1</b>.</qt>")
01397 .arg( (*it)->name() ) );
01398 }
01399 mAccountsToDelete.clear();
01400
01401
01402 kmkernel->acctMgr()->writeConfig( false );
01403 kmkernel->cleanupImapFolders();
01404
01405
01406 KConfigGroup general( KMKernel::config(), "General" );
01407 general.writeEntry( "beep-on-mail", mBeepNewMailCheck->isChecked() );
01408 GlobalSettings::self()->setVerboseNewMailNotification( mVerboseNotificationCheck->isChecked() );
01409
01410 general.writeEntry( "checkmail-startup", mCheckmailStartupCheck->isChecked() );
01411
01412
01413 for (it = mNewAccounts.begin(); it != mNewAccounts.end(); ++it ) {
01414 KMAccount *macc = (*it);
01415 ImapAccountBase *acc = dynamic_cast<ImapAccountBase*> (macc);
01416 if ( acc ) {
01417 AccountUpdater *au = new AccountUpdater( acc );
01418 au->update();
01419 }
01420 }
01421 mNewAccounts.clear();
01422
01423 }
01424
01425
01426
01427
01428
01429
01430 QString AppearancePage::helpAnchor() const {
01431 return QString::fromLatin1("configure-appearance");
01432 }
01433
01434 AppearancePage::AppearancePage( QWidget * parent, const char * name )
01435 : ConfigModuleWithTabs( parent, name )
01436 {
01437
01438
01439
01440 mFontsTab = new FontsTab();
01441 addTab( mFontsTab, i18n("&Fonts") );
01442
01443
01444
01445
01446 mColorsTab = new ColorsTab();
01447 addTab( mColorsTab, i18n("Color&s") );
01448
01449
01450
01451
01452 mLayoutTab = new LayoutTab();
01453 addTab( mLayoutTab, i18n("La&yout") );
01454
01455
01456
01457
01458 mHeadersTab = new HeadersTab();
01459 addTab( mHeadersTab, i18n("M&essage List") );
01460
01461
01462
01463
01464 mReaderTab = new ReaderTab();
01465 addTab( mReaderTab, i18n("Message W&indow") );
01466
01467
01468
01469
01470 mSystemTrayTab = new SystemTrayTab();
01471 addTab( mSystemTrayTab, i18n("System &Tray") );
01472
01473 load();
01474 }
01475
01476
01477 QString AppearancePage::FontsTab::helpAnchor() const {
01478 return QString::fromLatin1("configure-appearance-fonts");
01479 }
01480
01481 static const struct {
01482 const char * configName;
01483 const char * displayName;
01484 bool enableFamilyAndSize;
01485 bool onlyFixed;
01486 } fontNames[] = {
01487 { "body-font", I18N_NOOP("Message Body"), true, false },
01488 { "list-font", I18N_NOOP("Message List"), true, false },
01489 { "list-new-font", I18N_NOOP("Message List - New Messages"), true, false },
01490 { "list-unread-font", I18N_NOOP("Message List - Unread Messages"), true, false },
01491 { "list-important-font", I18N_NOOP("Message List - Important Messages"), true, false },
01492 { "list-todo-font", I18N_NOOP("Message List - Todo Messages"), true, false },
01493 { "list-date-font", I18N_NOOP("Message List - Date Field"), true, false },
01494 { "folder-font", I18N_NOOP("Folder List"), true, false },
01495 { "quote1-font", I18N_NOOP("Quoted Text - First Level"), false, false },
01496 { "quote2-font", I18N_NOOP("Quoted Text - Second Level"), false, false },
01497 { "quote3-font", I18N_NOOP("Quoted Text - Third Level"), false, false },
01498 { "fixed-font", I18N_NOOP("Fixed Width Font"), true, true },
01499 { "composer-font", I18N_NOOP("Composer"), true, false },
01500 { "print-font", I18N_NOOP("Printing Output"), true, false },
01501 };
01502 static const int numFontNames = sizeof fontNames / sizeof *fontNames;
01503
01504 AppearancePageFontsTab::AppearancePageFontsTab( QWidget * parent, const char * name )
01505 : ConfigModuleTab( parent, name ), mActiveFontIndex( -1 )
01506 {
01507 assert( numFontNames == sizeof mFont / sizeof *mFont );
01508
01509 QVBoxLayout *vlay;
01510 QHBoxLayout *hlay;
01511 QLabel *label;
01512
01513
01514 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
01515 mCustomFontCheck = new QCheckBox( i18n("&Use custom fonts"), this );
01516 vlay->addWidget( mCustomFontCheck );
01517 vlay->addWidget( new KSeparator( KSeparator::HLine, this ) );
01518 connect ( mCustomFontCheck, SIGNAL( stateChanged( int ) ),
01519 this, SLOT( slotEmitChanged( void ) ) );
01520
01521
01522 hlay = new QHBoxLayout( vlay );
01523 mFontLocationCombo = new QComboBox( false, this );
01524 mFontLocationCombo->setEnabled( false );
01525
01526 QStringList fontDescriptions;
01527 for ( int i = 0 ; i < numFontNames ; i++ )
01528 fontDescriptions << i18n( fontNames[i].displayName );
01529 mFontLocationCombo->insertStringList( fontDescriptions );
01530
01531 label = new QLabel( mFontLocationCombo, i18n("Apply &to:"), this );
01532 label->setEnabled( false );
01533 hlay->addWidget( label );
01534
01535 hlay->addWidget( mFontLocationCombo );
01536 hlay->addStretch( 10 );
01537 vlay->addSpacing( KDialog::spacingHint() );
01538 mFontChooser = new KFontChooser( this, "font", false, QStringList(),
01539 false, 4 );
01540 mFontChooser->setEnabled( false );
01541 vlay->addWidget( mFontChooser );
01542 connect ( mFontChooser, SIGNAL( fontSelected( const QFont& ) ),
01543 this, SLOT( slotEmitChanged( void ) ) );
01544
01545
01546
01547 connect( mCustomFontCheck, SIGNAL(toggled(bool)),
01548 label, SLOT(setEnabled(bool)) );
01549 connect( mCustomFontCheck, SIGNAL(toggled(bool)),
01550 mFontLocationCombo, SLOT(setEnabled(bool)) );
01551 connect( mCustomFontCheck, SIGNAL(toggled(bool)),
01552 mFontChooser, SLOT(setEnabled(bool)) );
01553
01554 connect( mFontLocationCombo, SIGNAL(activated(int) ),
01555 this, SLOT(slotFontSelectorChanged(int)) );
01556 }
01557
01558
01559 void AppearancePage::FontsTab::slotFontSelectorChanged( int index )
01560 {
01561 kdDebug(5006) << "slotFontSelectorChanged() called" << endl;
01562 if( index < 0 || index >= mFontLocationCombo->count() )
01563 return;
01564
01565
01566 if( mActiveFontIndex == 0 ) {
01567 mFont[0] = mFontChooser->font();
01568
01569 for ( int i = 0 ; i < numFontNames ; i++ )
01570 if ( !fontNames[i].enableFamilyAndSize ) {
01571
01572
01573
01574 mFont[i].setFamily( mFont[0].family() );
01575 mFont[i].setPointSize( mFont[0].pointSize() );
01576 }
01577 } else if ( mActiveFontIndex > 0 )
01578 mFont[ mActiveFontIndex ] = mFontChooser->font();
01579 mActiveFontIndex = index;
01580
01581
01582 disconnect ( mFontChooser, SIGNAL( fontSelected( const QFont& ) ),
01583 this, SLOT( slotEmitChanged( void ) ) );
01584
01585
01586 mFontChooser->setFont( mFont[index], fontNames[index].onlyFixed );
01587
01588 connect ( mFontChooser, SIGNAL( fontSelected( const QFont& ) ),
01589 this, SLOT( slotEmitChanged( void ) ) );
01590
01591
01592 mFontChooser->enableColumn( KFontChooser::FamilyList|KFontChooser::SizeList,
01593 fontNames[ index ].enableFamilyAndSize );
01594 }
01595
01596 void AppearancePage::FontsTab::doLoadOther() {
01597 KConfigGroup fonts( KMKernel::config(), "Fonts" );
01598
01599 mFont[0] = KGlobalSettings::generalFont();
01600 QFont fixedFont = KGlobalSettings::fixedFont();
01601 for ( int i = 0 ; i < numFontNames ; i++ )
01602 mFont[i] = fonts.readFontEntry( fontNames[i].configName,
01603 (fontNames[i].onlyFixed) ? &fixedFont : &mFont[0] );
01604
01605 mCustomFontCheck->setChecked( !fonts.readBoolEntry( "defaultFonts", true ) );
01606 mFontLocationCombo->setCurrentItem( 0 );
01607 slotFontSelectorChanged( 0 );
01608 }
01609
01610 void AppearancePage::FontsTab::installProfile( KConfig * profile ) {
01611 KConfigGroup fonts( profile, "Fonts" );
01612
01613
01614 bool needChange = false;
01615 for ( int i = 0 ; i < numFontNames ; i++ )
01616 if ( fonts.hasKey( fontNames[i].configName ) ) {
01617 needChange = true;
01618 mFont[i] = fonts.readFontEntry( fontNames[i].configName );
01619 kdDebug(5006) << "got font \"" << fontNames[i].configName
01620 << "\" thusly: \"" << mFont[i].toString() << "\"" << endl;
01621 }
01622 if ( needChange && mFontLocationCombo->currentItem() > 0 )
01623 mFontChooser->setFont( mFont[ mFontLocationCombo->currentItem() ],
01624 fontNames[ mFontLocationCombo->currentItem() ].onlyFixed );
01625
01626 if ( fonts.hasKey( "defaultFonts" ) )
01627 mCustomFontCheck->setChecked( !fonts.readBoolEntry( "defaultFonts" ) );
01628 }
01629
01630 void AppearancePage::FontsTab::save() {
01631 KConfigGroup fonts( KMKernel::config(), "Fonts" );
01632
01633
01634 if ( mActiveFontIndex >= 0 )
01635 mFont[ mActiveFontIndex ] = mFontChooser->font();
01636
01637 bool customFonts = mCustomFontCheck->isChecked();
01638 fonts.writeEntry( "defaultFonts", !customFonts );
01639 for ( int i = 0 ; i < numFontNames ; i++ )
01640 if ( customFonts || fonts.hasKey( fontNames[i].configName ) )
01641
01642
01643 fonts.writeEntry( fontNames[i].configName, mFont[i] );
01644 }
01645
01646 QString AppearancePage::ColorsTab::helpAnchor() const {
01647 return QString::fromLatin1("configure-appearance-colors");
01648 }
01649
01650
01651 static const struct {
01652 const char * configName;
01653 const char * displayName;
01654 } colorNames[] = {
01655 { "BackgroundColor", I18N_NOOP("Composer Background") },
01656 { "AltBackgroundColor", I18N_NOOP("Alternative Background Color") },
01657 { "ForegroundColor", I18N_NOOP("Normal Text") },
01658 { "QuotedText1", I18N_NOOP("Quoted Text - First Level") },
01659 { "QuotedText2", I18N_NOOP("Quoted Text - Second Level") },
01660 { "QuotedText3", I18N_NOOP("Quoted Text - Third Level") },
01661 { "LinkColor", I18N_NOOP("Link") },
01662 { "FollowedColor", I18N_NOOP("Followed Link") },
01663 { "MisspelledColor", I18N_NOOP("Misspelled Words") },
01664 { "NewMessage", I18N_NOOP("New Message") },
01665 { "UnreadMessage", I18N_NOOP("Unread Message") },
01666 { "FlagMessage", I18N_NOOP("Important Message") },
01667 { "TodoMessage", I18N_NOOP("Todo Message") },
01668 { "PGPMessageEncr", I18N_NOOP("OpenPGP Message - Encrypted") },
01669 { "PGPMessageOkKeyOk", I18N_NOOP("OpenPGP Message - Valid Signature with Trusted Key") },
01670 { "PGPMessageOkKeyBad", I18N_NOOP("OpenPGP Message - Valid Signature with Untrusted Key") },
01671 { "PGPMessageWarn", I18N_NOOP("OpenPGP Message - Unchecked Signature") },
01672 { "PGPMessageErr", I18N_NOOP("OpenPGP Message - Bad Signature") },
01673 { "HTMLWarningColor", I18N_NOOP("Border Around Warning Prepending HTML Messages") },
01674 { "ColorbarBackgroundPlain", I18N_NOOP("HTML Status Bar Background - No HTML Message") },
01675 { "ColorbarForegroundPlain", I18N_NOOP("HTML Status Bar Foreground - No HTML Message") },
01676 { "ColorbarBackgroundHTML", I18N_NOOP("HTML Status Bar Background - HTML Message") },
01677 { "ColorbarForegroundHTML", I18N_NOOP("HTML Status Bar Foreground - HTML Message") },
01678 };
01679 static const int numColorNames = sizeof colorNames / sizeof *colorNames;
01680
01681 AppearancePageColorsTab::AppearancePageColorsTab( QWidget * parent, const char * name )
01682 : ConfigModuleTab( parent, name )
01683 {
01684
01685 QVBoxLayout *vlay;
01686
01687
01688 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
01689 mCustomColorCheck = new QCheckBox( i18n("&Use custom colors"), this );
01690 vlay->addWidget( mCustomColorCheck );
01691 connect( mCustomColorCheck, SIGNAL( stateChanged( int ) ),
01692 this, SLOT( slotEmitChanged( void ) ) );
01693
01694
01695 mColorList = new ColorListBox( this );
01696 mColorList->setEnabled( false );
01697 QStringList modeList;
01698 for ( int i = 0 ; i < numColorNames ; i++ )
01699 mColorList->insertItem( new ColorListItem( i18n( colorNames[i].displayName ) ) );
01700 vlay->addWidget( mColorList, 1 );
01701
01702
01703 mRecycleColorCheck =
01704 new QCheckBox( i18n("Recycle colors on deep "ing"), this );
01705 mRecycleColorCheck->setEnabled( false );
01706 vlay->addWidget( mRecycleColorCheck );
01707 connect( mRecycleColorCheck, SIGNAL( stateChanged( int ) ),
01708 this, SLOT( slotEmitChanged( void ) ) );
01709
01710
01711 connect( mCustomColorCheck, SIGNAL(toggled(bool)),
01712 mColorList, SLOT(setEnabled(bool)) );
01713 connect( mCustomColorCheck, SIGNAL(toggled(bool)),
01714 mRecycleColorCheck, SLOT(setEnabled(bool)) );
01715 connect( mCustomColorCheck, SIGNAL( stateChanged( int ) ),
01716 this, SLOT( slotEmitChanged( void ) ) );
01717 }
01718
01719 void AppearancePage::ColorsTab::doLoadOther() {
01720 KConfigGroup reader( KMKernel::config(), "Reader" );
01721
01722 mCustomColorCheck->setChecked( !reader.readBoolEntry( "defaultColors", true ) );
01723 mRecycleColorCheck->setChecked( reader.readBoolEntry( "RecycleQuoteColors", false ) );
01724
01725 static const QColor defaultColor[ numColorNames ] = {
01726 kapp->palette().active().base(),
01727 KGlobalSettings::alternateBackgroundColor(),
01728 kapp->palette().active().text(),
01729 QColor( 0x00, 0x80, 0x00 ),
01730 QColor( 0x00, 0x70, 0x00 ),
01731 QColor( 0x00, 0x60, 0x00 ),
01732 KGlobalSettings::linkColor(),
01733 KGlobalSettings::visitedLinkColor(),
01734 Qt::red,
01735 Qt::red,
01736 Qt::blue,
01737 QColor( 0x00, 0x7F, 0x00 ),
01738 QColor( 0x00, 0x80, 0xFF ),
01739 QColor( 0x40, 0xFF, 0x40 ),
01740 QColor( 0xFF, 0xFF, 0x40 ),
01741 QColor( 0xFF, 0xFF, 0x40 ),
01742 Qt::red,
01743 QColor( 0xFF, 0x40, 0x40 ),
01744 Qt::lightGray,
01745 Qt::black,
01746 Qt::black,
01747 Qt::white,
01748 };
01749
01750 for ( int i = 0 ; i < numColorNames ; i++ )
01751 mColorList->setColor( i,
01752 reader.readColorEntry( colorNames[i].configName, &defaultColor[i] ) );
01753 connect( mColorList, SIGNAL( changed( ) ),
01754 this, SLOT( slotEmitChanged( void ) ) );
01755 }
01756
01757 void AppearancePage::ColorsTab::installProfile( KConfig * profile ) {
01758 KConfigGroup reader( profile, "Reader" );
01759
01760 if ( reader.hasKey( "defaultColors" ) )
01761 mCustomColorCheck->setChecked( !reader.readBoolEntry( "defaultColors" ) );
01762 if ( reader.hasKey( "RecycleQuoteColors" ) )
01763 mRecycleColorCheck->setChecked( reader.readBoolEntry( "RecycleQuoteColors" ) );
01764
01765 for ( int i = 0 ; i < numColorNames ; i++ )
01766 if ( reader.hasKey( colorNames[i].configName ) )
01767 mColorList->setColor( i, reader.readColorEntry( colorNames[i].configName ) );
01768 }
01769
01770 void AppearancePage::ColorsTab::save() {
01771 KConfigGroup reader( KMKernel::config(), "Reader" );
01772
01773 bool customColors = mCustomColorCheck->isChecked();
01774 reader.writeEntry( "defaultColors", !customColors );
01775
01776 for ( int i = 0 ; i < numColorNames ; i++ )
01777
01778
01779 if ( customColors || reader.hasKey( colorNames[i].configName ) )
01780 reader.writeEntry( colorNames[i].configName, mColorList->color(i) );
01781
01782 reader.writeEntry( "RecycleQuoteColors", mRecycleColorCheck->isChecked() );
01783 }
01784
01785 QString AppearancePage::LayoutTab::helpAnchor() const {
01786 return QString::fromLatin1("configure-appearance-layout");
01787 }
01788
01789 static const EnumConfigEntryItem folderListModes[] = {
01790 { "long", I18N_NOOP("Lon&g folder list") },
01791 { "short", I18N_NOOP("Shor&t folder list" ) }
01792 };
01793 static const EnumConfigEntry folderListMode = {
01794 "Geometry", "FolderList", I18N_NOOP("Folder List"),
01795 folderListModes, DIM(folderListModes), 0
01796 };
01797
01798
01799 static const EnumConfigEntryItem mimeTreeLocations[] = {
01800 { "top", I18N_NOOP("Abo&ve the message pane") },
01801 { "bottom", I18N_NOOP("&Below the message pane") }
01802 };
01803 static const EnumConfigEntry mimeTreeLocation = {
01804 "Reader", "MimeTreeLocation", I18N_NOOP("Message Structure Viewer Placement"),
01805 mimeTreeLocations, DIM(mimeTreeLocations), 1
01806 };
01807
01808 static const EnumConfigEntryItem mimeTreeModes[] = {
01809 { "never", I18N_NOOP("Show &never") },
01810 { "smart", I18N_NOOP("Show only for non-plaintext &messages") },
01811 { "always", I18N_NOOP("Show alway&s") }
01812 };
01813 static const EnumConfigEntry mimeTreeMode = {
01814 "Reader", "MimeTreeMode", I18N_NOOP("Message Structure Viewer"),
01815 mimeTreeModes, DIM(mimeTreeModes), 1
01816 };
01817
01818
01819 static const EnumConfigEntryItem readerWindowModes[] = {
01820 { "hide", I18N_NOOP("&Do not show a message preview pane") },
01821 { "below", I18N_NOOP("Show the message preview pane belo&w the message list") },
01822 { "right", I18N_NOOP("Show the message preview pane ne&xt to the message list") }
01823 };
01824 static const EnumConfigEntry readerWindowMode = {
01825 "Geometry", "readerWindowMode", I18N_NOOP("Message Preview Pane"),
01826 readerWindowModes, DIM(readerWindowModes), 1
01827 };
01828
01829 AppearancePageLayoutTab::AppearancePageLayoutTab( QWidget * parent, const char * name )
01830 : ConfigModuleTab( parent, name )
01831 {
01832
01833 QVBoxLayout * vlay;
01834
01835 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
01836
01837
01838 populateButtonGroup( mFolderListGroup = new QHButtonGroup( this ), folderListMode );
01839 vlay->addWidget( mFolderListGroup );
01840 connect( mFolderListGroup, SIGNAL ( clicked( int ) ),
01841 this, SLOT( slotEmitChanged() ) );
01842
01843
01844 populateButtonGroup( mReaderWindowModeGroup = new QVButtonGroup( this ), readerWindowMode );
01845 vlay->addWidget( mReaderWindowModeGroup );
01846 connect( mReaderWindowModeGroup, SIGNAL ( clicked( int ) ),
01847 this, SLOT( slotEmitChanged() ) );
01848
01849
01850 populateButtonGroup( mMIMETreeModeGroup = new QVButtonGroup( this ), mimeTreeMode );
01851 vlay->addWidget( mMIMETreeModeGroup );
01852 connect( mMIMETreeModeGroup, SIGNAL ( clicked( int ) ),
01853 this, SLOT( slotEmitChanged() ) );
01854
01855
01856 populateButtonGroup( mMIMETreeLocationGroup = new QHButtonGroup( this ), mimeTreeLocation );
01857 vlay->addWidget( mMIMETreeLocationGroup );
01858 connect( mMIMETreeLocationGroup, SIGNAL ( clicked( int ) ),
01859 this, SLOT( slotEmitChanged() ) );
01860
01861 vlay->addStretch( 10 );
01862 }
01863
01864 void AppearancePage::LayoutTab::doLoadOther() {
01865 const KConfigGroup reader( KMKernel::config(), "Reader" );
01866 const KConfigGroup geometry( KMKernel::config(), "Geometry" );
01867
01868 loadWidget( mFolderListGroup, geometry, folderListMode );
01869 loadWidget( mMIMETreeLocationGroup, reader, mimeTreeLocation );
01870 loadWidget( mMIMETreeModeGroup, reader, mimeTreeMode );
01871 loadWidget( mReaderWindowModeGroup, geometry, readerWindowMode );
01872 }
01873
01874 void AppearancePage::LayoutTab::installProfile( KConfig * profile ) {
01875 const KConfigGroup reader( profile, "Reader" );
01876 const KConfigGroup geometry( profile, "Geometry" );
01877
01878 loadProfile( mFolderListGroup, geometry, folderListMode );
01879 loadProfile( mMIMETreeLocationGroup, reader, mimeTreeLocation );
01880 loadProfile( mMIMETreeModeGroup, reader, mimeTreeMode );
01881 loadProfile( mReaderWindowModeGroup, geometry, readerWindowMode );
01882 }
01883
01884 void AppearancePage::LayoutTab::save() {
01885 KConfigGroup reader( KMKernel::config(), "Reader" );
01886 KConfigGroup geometry( KMKernel::config(), "Geometry" );
01887
01888 saveButtonGroup( mFolderListGroup, geometry, folderListMode );
01889 saveButtonGroup( mMIMETreeLocationGroup, reader, mimeTreeLocation );
01890 saveButtonGroup( mMIMETreeModeGroup, reader, mimeTreeMode );
01891 saveButtonGroup( mReaderWindowModeGroup, geometry, readerWindowMode );
01892 }
01893
01894
01895
01896
01897
01898 QString AppearancePage::HeadersTab::helpAnchor() const {
01899 return QString::fromLatin1("configure-appearance-headers");
01900 }
01901
01902 static const struct {
01903 const char * displayName;
01904 DateFormatter::FormatType dateDisplay;
01905 } dateDisplayConfig[] = {
01906 { I18N_NOOP("Sta&ndard format (%1)"), KMime::DateFormatter::CTime },
01907 { I18N_NOOP("Locali&zed format (%1)"), KMime::DateFormatter::Localized },
01908 { I18N_NOOP("Fancy for&mat (%1)"), KMime::DateFormatter::Fancy },
01909 { I18N_NOOP("C&ustom format (Shift+F1 for help):"),
01910 KMime::DateFormatter::Custom }
01911 };
01912 static const int numDateDisplayConfig =
01913 sizeof dateDisplayConfig / sizeof *dateDisplayConfig;
01914
01915 AppearancePageHeadersTab::AppearancePageHeadersTab( QWidget * parent, const char * name )
01916 : ConfigModuleTab( parent, name ),
01917 mCustomDateFormatEdit( 0 )
01918 {
01919
01920 QButtonGroup * group;
01921 QRadioButton * radio;
01922
01923 QVBoxLayout * vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
01924
01925
01926 group = new QVButtonGroup( i18n( "General Options" ), this );
01927 group->layout()->setSpacing( KDialog::spacingHint() );
01928
01929 mMessageSizeCheck = new QCheckBox( i18n("Display messa&ge sizes"), group );
01930
01931 mCryptoIconsCheck = new QCheckBox( i18n( "Show crypto &icons" ), group );
01932
01933 mAttachmentCheck = new QCheckBox( i18n("Show attachment icon"), group );
01934
01935 mNestedMessagesCheck =
01936 new QCheckBox( i18n("&Threaded message list"), group );
01937
01938 connect( mMessageSizeCheck, SIGNAL( stateChanged( int ) ),
01939 this, SLOT( slotEmitChanged( void ) ) );
01940 connect( mAttachmentCheck, SIGNAL( stateChanged( int ) ),
01941 this, SLOT( slotEmitChanged( void ) ) );
01942 connect( mCryptoIconsCheck, SIGNAL( stateChanged( int ) ),
01943 this, SLOT( slotEmitChanged( void ) ) );
01944 connect( mNestedMessagesCheck, SIGNAL( stateChanged( int ) ),
01945 this, SLOT( slotEmitChanged( void ) ) );
01946
01947
01948 vlay->addWidget( group );
01949
01950
01951 mNestingPolicy =
01952 new QVButtonGroup( i18n("Threaded Message List Options"), this );
01953 mNestingPolicy->layout()->setSpacing( KDialog::spacingHint() );
01954
01955 mNestingPolicy->insert(
01956 new QRadioButton( i18n("Always &keep threads open"),
01957 mNestingPolicy ), 0 );
01958 mNestingPolicy->insert(
01959 new QRadioButton( i18n("Threads default to o&pen"),
01960 mNestingPolicy ), 1 );
01961 mNestingPolicy->insert(
01962 new QRadioButton( i18n("Threads default to closed"),
01963 mNestingPolicy ), 2 );
01964 mNestingPolicy->insert(
01965 new QRadioButton( i18n("Open threads that contain ne&w, unread "
01966 "or important messages and open watched threads."),
01967 mNestingPolicy ), 3 );
01968
01969 vlay->addWidget( mNestingPolicy );
01970
01971 connect( mNestingPolicy, SIGNAL( clicked( int ) ),
01972 this, SLOT( slotEmitChanged( void ) ) );
01973
01974
01975 mDateDisplay = new QVButtonGroup( i18n("Date Display"), this );
01976 mDateDisplay->layout()->setSpacing( KDialog::spacingHint() );
01977
01978 for ( int i = 0 ; i < numDateDisplayConfig ; i++ ) {
01979 QString buttonLabel = i18n(dateDisplayConfig[i].displayName);
01980 if ( buttonLabel.contains("%1") )
01981 buttonLabel = buttonLabel.arg( DateFormatter::formatCurrentDate( dateDisplayConfig[i].dateDisplay ) );
01982 radio = new QRadioButton( buttonLabel, mDateDisplay );
01983 mDateDisplay->insert( radio, i );
01984 if ( dateDisplayConfig[i].dateDisplay == DateFormatter::Custom ) {
01985 mCustomDateFormatEdit = new KLineEdit( mDateDisplay );
01986 mCustomDateFormatEdit->setEnabled( false );
01987 connect( radio, SIGNAL(toggled(bool)),
01988 mCustomDateFormatEdit, SLOT(setEnabled(bool)) );
01989 connect( mCustomDateFormatEdit, SIGNAL(textChanged(const QString&)),
01990 this, SLOT(slotEmitChanged(void)) );
01991 QString customDateWhatsThis =
01992 i18n("<qt><p><strong>These expressions may be used for the date:"
01993 "</strong></p>"
01994 "<ul>"
01995 "<li>d - the day as a number without a leading zero (1-31)</li>"
01996 "<li>dd - the day as a number with a leading zero (01-31)</li>"
01997 "<li>ddd - the abbreviated day name (Mon - Sun)</li>"
01998 "<li>dddd - the long day name (Monday - Sunday)</li>"
01999 "<li>M - the month as a number without a leading zero (1-12)</li>"
02000 "<li>MM - the month as a number with a leading zero (01-12)</li>"
02001 "<li>MMM - the abbreviated month name (Jan - Dec)</li>"
02002 "<li>MMMM - the long month name (January - December)</li>"
02003 "<li>yy - the year as a two digit number (00-99)</li>"
02004 "<li>yyyy - the year as a four digit number (0000-9999)</li>"
02005 "</ul>"
02006 "<p><strong>These expressions may be used for the time:"
02007 "</string></p> "
02008 "<ul>"
02009 "<li>h - the hour without a leading zero (0-23 or 1-12 if AM/PM display)</li>"
02010 "<li>hh - the hour with a leading zero (00-23 or 01-12 if AM/PM display)</li>"
02011 "<li>m - the minutes without a leading zero (0-59)</li>"
02012 "<li>mm - the minutes with a leading zero (00-59)</li>"
02013 "<li>s - the seconds without a leading zero (0-59)</li>"
02014 "<li>ss - the seconds with a leading zero (00-59)</li>"
02015 "<li>z - the milliseconds without leading zeroes (0-999)</li>"
02016 "<li>zzz - the milliseconds with leading zeroes (000-999)</li>"
02017 "<li>AP - switch to AM/PM display. AP will be replaced by either \"AM\" or \"PM\".</li>"
02018 "<li>ap - switch to AM/PM display. ap will be replaced by either \"am\" or \"pm\".</li>"
02019 "<li>Z - time zone in numeric form (-0500)</li>"
02020 "</ul>"
02021 "<p><strong>All other input characters will be ignored."
02022 "</strong></p></qt>");
02023 QWhatsThis::add( mCustomDateFormatEdit, customDateWhatsThis );
02024 QWhatsThis::add( radio, customDateWhatsThis );
02025 }
02026 }
02027
02028 vlay->addWidget( mDateDisplay );
02029 connect( mDateDisplay, SIGNAL( clicked( int ) ),
02030 this, SLOT( slotEmitChanged( void ) ) );
02031
02032
02033 vlay->addStretch( 10 );
02034 }
02035
02036 void AppearancePage::HeadersTab::doLoadOther() {
02037 KConfigGroup general( KMKernel::config(), "General" );
02038 KConfigGroup geometry( KMKernel::config(), "Geometry" );
02039
02040
02041 mNestedMessagesCheck->setChecked( geometry.readBoolEntry( "nestedMessages", false ) );
02042 mMessageSizeCheck->setChecked( general.readBoolEntry( "showMessageSize", false ) );
02043 mCryptoIconsCheck->setChecked( general.readBoolEntry( "showCryptoIcons", false ) );
02044 mAttachmentCheck->setChecked( general.readBoolEntry( "showAttachmentIcon", true ) );
02045
02046
02047 int num = geometry.readNumEntry( "nestingPolicy", 3 );
02048 if ( num < 0 || num > 3 ) num = 3;
02049 mNestingPolicy->setButton( num );
02050
02051
02052 setDateDisplay( general.readNumEntry( "dateFormat", DateFormatter::Fancy ),
02053 general.readEntry( "customDateFormat" ) );
02054 }
02055
02056 void AppearancePage::HeadersTab::setDateDisplay( int num, const QString & format ) {
02057 DateFormatter::FormatType dateDisplay =
02058 static_cast<DateFormatter::FormatType>( num );
02059
02060
02061 if ( dateDisplay == DateFormatter::Custom )
02062 mCustomDateFormatEdit->setText( format );
02063
02064 for ( int i = 0 ; i < numDateDisplayConfig ; i++ )
02065 if ( dateDisplay == dateDisplayConfig[i].dateDisplay ) {
02066 mDateDisplay->setButton( i );
02067 return;
02068 }
02069
02070 mDateDisplay->setButton( numDateDisplayConfig - 2 );
02071 }
02072
02073 void AppearancePage::HeadersTab::installProfile( KConfig * profile ) {
02074 KConfigGroup general( profile, "General" );
02075 KConfigGroup geometry( profile, "Geometry" );
02076
02077 if ( geometry.hasKey( "nestedMessages" ) )
02078 mNestedMessagesCheck->setChecked( geometry.readBoolEntry( "nestedMessages" ) );
02079 if ( general.hasKey( "showMessageSize" ) )
02080 mMessageSizeCheck->setChecked( general.readBoolEntry( "showMessageSize" ) );
02081
02082 if( general.hasKey( "showCryptoIcons" ) )
02083 mCryptoIconsCheck->setChecked( general.readBoolEntry( "showCryptoIcons" ) );
02084 if ( general.hasKey( "showAttachmentIcon" ) )
02085 mAttachmentCheck->setChecked( general.readBoolEntry( "showAttachmentIcon" ) );
02086
02087 if ( geometry.hasKey( "nestingPolicy" ) ) {
02088 int num = geometry.readNumEntry( "nestingPolicy" );
02089 if ( num < 0 || num > 3 ) num = 3;
02090 mNestingPolicy->setButton( num );
02091 }
02092
02093 if ( general.hasKey( "dateFormat" ) )
02094 setDateDisplay( general.readNumEntry( "dateFormat" ),
02095 general.readEntry( "customDateFormat" ) );
02096 }
02097
02098 void AppearancePage::HeadersTab::save() {
02099 KConfigGroup general( KMKernel::config(), "General" );
02100 KConfigGroup geometry( KMKernel::config(), "Geometry" );
02101
02102 if ( geometry.readBoolEntry( "nestedMessages", false )
02103 != mNestedMessagesCheck->isChecked() ) {
02104 int result = KMessageBox::warningContinueCancel( this,
02105 i18n("Changing the global threading setting will override "
02106 "all folder specific values."),
02107 QString::null, KStdGuiItem::cont(), "threadOverride" );
02108 if ( result == KMessageBox::Continue ) {
02109 geometry.writeEntry( "nestedMessages", mNestedMessagesCheck->isChecked() );
02110
02111 QStringList groups = KMKernel::config()->groupList().grep( QRegExp("^Folder-") );
02112 kdDebug(5006) << "groups.count() == " << groups.count() << endl;
02113 for ( QStringList::const_iterator it = groups.begin() ; it != groups.end() ; ++it ) {
02114 KConfigGroup group( KMKernel::config(), *it );
02115 group.deleteEntry( "threadMessagesOverride" );
02116 }
02117 }
02118 }
02119
02120 geometry.writeEntry( "nestingPolicy",
02121 mNestingPolicy->id( mNestingPolicy->selected() ) );
02122 general.writeEntry( "showMessageSize", mMessageSizeCheck->isChecked() );
02123 general.writeEntry( "showCryptoIcons", mCryptoIconsCheck->isChecked() );
02124 general.writeEntry( "showAttachmentIcon", mAttachmentCheck->isChecked() );
02125
02126 int dateDisplayID = mDateDisplay->id( mDateDisplay->selected() );
02127
02128 assert( dateDisplayID >= 0 ); assert( dateDisplayID < numDateDisplayConfig );
02129 general.writeEntry( "dateFormat",
02130 dateDisplayConfig[ dateDisplayID ].dateDisplay );
02131 general.writeEntry( "customDateFormat", mCustomDateFormatEdit->text() );
02132 }
02133
02134
02135
02136
02137
02138
02139
02140 static const BoolConfigEntry showColorbarMode = {
02141 "Reader", "showColorbar", I18N_NOOP("Show HTML stat&us bar"), false
02142 };
02143
02144 static const BoolConfigEntry showSpamStatusMode = {
02145 "Reader", "showSpamStatus", I18N_NOOP("Show s&pam status in fancy headers"), true
02146 };
02147
02148 static const BoolConfigEntry showEmoticons = {
02149 "Reader", "ShowEmoticons", I18N_NOOP("Replace smileys by emoticons"), true
02150 };
02151
02152 static const BoolConfigEntry shrinkQuotes = {
02153 "Reader", "ShrinkQuotes", I18N_NOOP("Use smaller font for quoted text"), false
02154 };
02155
02156 static const BoolConfigEntry showExpandQuotesMark= {
02157 "Reader", "ShowExpandQuotesMark", I18N_NOOP("Show expand/collapse quote marks"), false
02158 };
02159
02160
02161 QString AppearancePage::ReaderTab::helpAnchor() const {
02162 return QString::fromLatin1("configure-appearance-reader");
02163 }
02164
02165 AppearancePageReaderTab::AppearancePageReaderTab( QWidget * parent,
02166 const char * name )
02167 : ConfigModuleTab( parent, name )
02168 {
02169 QVBoxLayout *vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
02170
02171
02172 populateCheckBox( mShowColorbarCheck = new QCheckBox( this ), showColorbarMode );
02173 vlay->addWidget( mShowColorbarCheck );
02174 connect( mShowColorbarCheck, SIGNAL ( stateChanged( int ) ),
02175 this, SLOT( slotEmitChanged() ) );
02176
02177
02178 populateCheckBox( mShowSpamStatusCheck = new QCheckBox( this ), showSpamStatusMode );
02179 vlay->addWidget( mShowSpamStatusCheck );
02180 connect( mShowSpamStatusCheck, SIGNAL ( stateChanged( int ) ),
02181 this, SLOT( slotEmitChanged() ) );
02182
02183
02184 populateCheckBox( mShowEmoticonsCheck = new QCheckBox( this ), showEmoticons );
02185 vlay->addWidget( mShowEmoticonsCheck );
02186 connect( mShowEmoticonsCheck, SIGNAL ( stateChanged( int ) ),
02187 this, SLOT( slotEmitChanged() ) );
02188
02189
02190 mShrinkQuotesCheck = new QCheckBox( i18n( shrinkQuotes.desc ), this,
02191 "kcfg_ShrinkQuotes" );
02192 vlay->addWidget( mShrinkQuotesCheck );
02193 connect( mShrinkQuotesCheck, SIGNAL( stateChanged( int ) ),
02194 this, SLOT( slotEmitChanged() ) );
02195
02196
02197 QHBoxLayout *hlay= new QHBoxLayout( vlay );
02198 populateCheckBox( mShowExpandQuotesMark= new QCheckBox( this ), showExpandQuotesMark);
02199 hlay->addWidget( mShowExpandQuotesMark);
02200 connect( mShowExpandQuotesMark, SIGNAL ( stateChanged( int ) ),
02201 this, SLOT( slotEmitChanged() ) );
02202
02203 hlay->addStretch( 1 );
02204 mCollapseQuoteLevelSpin = new KIntSpinBox( 0,10,1,
02205 3,10,this );
02206
02207 QLabel *label = new QLabel( mCollapseQuoteLevelSpin,
02208 GlobalSettings::self()->collapseQuoteLevelSpinItem()->label(), this );
02209
02210 hlay->addWidget( label );
02211
02212 mCollapseQuoteLevelSpin->setEnabled( false );
02213 connect( mCollapseQuoteLevelSpin, SIGNAL( valueChanged( int ) ),
02214 this, SLOT( slotEmitChanged( void ) ) );
02215 hlay->addWidget( mCollapseQuoteLevelSpin);
02216
02217 connect( mShowExpandQuotesMark, SIGNAL( toggled( bool ) ),
02218 mCollapseQuoteLevelSpin, SLOT( setEnabled( bool ) ) );
02219
02220
02221 hlay = new QHBoxLayout( vlay );
02222 mCharsetCombo = new QComboBox( this );
02223 mCharsetCombo->insertStringList( KMMsgBase::supportedEncodings( false ) );
02224
02225 connect( mCharsetCombo, SIGNAL( activated( int ) ),
02226 this, SLOT( slotEmitChanged( void ) ) );
02227
02228 QString fallbackCharsetWhatsThis =
02229 i18n( GlobalSettings::self()->fallbackCharacterEncodingItem()->whatsThis().utf8() );
02230 QWhatsThis::add( mCharsetCombo, fallbackCharsetWhatsThis );
02231
02232 label = new QLabel( i18n("Fallback ch&aracter encoding:"), this );
02233 label->setBuddy( mCharsetCombo );
02234
02235 hlay->addWidget( label );
02236 hlay->addWidget( mCharsetCombo );
02237
02238
02239 QHBoxLayout *hlay2 = new QHBoxLayout( vlay );
02240 mOverrideCharsetCombo = new QComboBox( this );
02241 QStringList encodings = KMMsgBase::supportedEncodings( false );
02242 encodings.prepend( i18n( "Auto" ) );
02243 mOverrideCharsetCombo->insertStringList( encodings );
02244 mOverrideCharsetCombo->setCurrentItem(0);
02245
02246 connect( mOverrideCharsetCombo, SIGNAL( activated( int ) ),
02247 this, SLOT( slotEmitChanged( void ) ) );
02248
02249 QString overrideCharsetWhatsThis =
02250 i18n( GlobalSettings::self()->overrideCharacterEncodingItem()->whatsThis().utf8() );
02251 QWhatsThis::add( mOverrideCharsetCombo, overrideCharsetWhatsThis );
02252
02253 label = new QLabel( i18n("&Override character encoding:"), this );
02254 label->setBuddy( mOverrideCharsetCombo );
02255
02256 hlay2->addWidget( label );
02257 hlay2->addWidget( mOverrideCharsetCombo );
02258
02259 vlay->addStretch( 100 );
02260 }
02261
02262
02263 void AppearancePage::ReaderTab::readCurrentFallbackCodec()
02264 {
02265 QStringList encodings = KMMsgBase::supportedEncodings( false );
02266 QStringList::ConstIterator it( encodings.begin() );
02267 QStringList::ConstIterator end( encodings.end() );
02268 const QString ¤tEncoding = GlobalSettings::self()->fallbackCharacterEncoding();
02269 int i = 0;
02270 for( ; it != end; ++it)
02271 {
02272 if( KGlobal::charsets()->encodingForName(*it) == currentEncoding )
02273 {
02274 mCharsetCombo->setCurrentItem( i );
02275 break;
02276 }
02277 i++;
02278 }
02279 }
02280
02281 void AppearancePage::ReaderTab::readCurrentOverrideCodec()
02282 {
02283 const QString ¤tOverrideEncoding = GlobalSettings::self()->overrideCharacterEncoding();
02284 if ( currentOverrideEncoding.isEmpty() ) {
02285 mOverrideCharsetCombo->setCurrentItem( 0 );
02286 return;
02287 }
02288 QStringList encodings = KMMsgBase::supportedEncodings( false );
02289 encodings.prepend( i18n( "Auto" ) );
02290 QStringList::Iterator it( encodings.begin() );
02291 QStringList::Iterator end( encodings.end() );
02292 int i = 0;
02293 for( ; it != end; ++it)
02294 {
02295 if( KGlobal::charsets()->encodingForName(*it) == currentOverrideEncoding )
02296 {
02297 mOverrideCharsetCombo->setCurrentItem( i );
02298 break;
02299 }
02300 i++;
02301 }
02302 }
02303
02304 void AppearancePage::ReaderTab::doLoadFromGlobalSettings()
02305 {
02306 mShowEmoticonsCheck->setChecked( GlobalSettings::self()->showEmoticons() );
02307 mShrinkQuotesCheck->setChecked( GlobalSettings::self()->shrinkQuotes() );
02308 mShowExpandQuotesMark->setChecked( GlobalSettings::self()->showExpandQuotesMark() );
02309 mCollapseQuoteLevelSpin->setValue( GlobalSettings::self()->collapseQuoteLevelSpin() );
02310 readCurrentFallbackCodec();
02311 readCurrentOverrideCodec();
02312 }
02313
02314 void AppearancePage::ReaderTab::doLoadOther()
02315 {
02316 const KConfigGroup reader( KMKernel::config(), "Reader" );
02317 loadWidget( mShowColorbarCheck, reader, showColorbarMode );
02318 loadWidget( mShowSpamStatusCheck, reader, showSpamStatusMode );
02319 }
02320
02321
02322 void AppearancePage::ReaderTab::save() {
02323 KConfigGroup reader( KMKernel::config(), "Reader" );
02324 saveCheckBox( mShowColorbarCheck, reader, showColorbarMode );
02325 saveCheckBox( mShowSpamStatusCheck, reader, showSpamStatusMode );
02326 GlobalSettings::self()->setShowEmoticons( mShowEmoticonsCheck->isChecked() );
02327 GlobalSettings::self()->setShrinkQuotes( mShrinkQuotesCheck->isChecked() );
02328 GlobalSettings::self()->setShowExpandQuotesMark( mShowExpandQuotesMark->isChecked() );
02329
02330 GlobalSettings::self()->setCollapseQuoteLevelSpin( mCollapseQuoteLevelSpin->value() );
02331 GlobalSettings::self()->setFallbackCharacterEncoding(
02332 KGlobal::charsets()->encodingForName( mCharsetCombo->currentText() ) );
02333 GlobalSettings::self()->setOverrideCharacterEncoding(
02334 mOverrideCharsetCombo->currentItem() == 0 ?
02335 QString() :
02336 KGlobal::charsets()->encodingForName( mOverrideCharsetCombo->currentText() ) );
02337 }
02338
02339
02340 void AppearancePage::ReaderTab::installProfile( KConfig * ) {
02341 const KConfigGroup reader( KMKernel::config(), "Reader" );
02342 loadProfile( mShowColorbarCheck, reader, showColorbarMode );
02343 loadProfile( mShowSpamStatusCheck, reader, showSpamStatusMode );
02344 loadProfile( mShowEmoticonsCheck, reader, showEmoticons );
02345 loadProfile( mShrinkQuotesCheck, reader, shrinkQuotes );
02346 loadProfile( mShowExpandQuotesMark, reader, showExpandQuotesMark);
02347 }
02348
02349
02350 QString AppearancePage::SystemTrayTab::helpAnchor() const {
02351 return QString::fromLatin1("configure-appearance-systemtray");
02352 }
02353
02354 AppearancePageSystemTrayTab::AppearancePageSystemTrayTab( QWidget * parent,
02355 const char * name )
02356 : ConfigModuleTab( parent, name )
02357 {
02358 QVBoxLayout * vlay = new QVBoxLayout( this, KDialog::marginHint(),
02359 KDialog::spacingHint() );
02360
02361
02362 mSystemTrayCheck = new QCheckBox( i18n("Enable system tray icon"), this );
02363 vlay->addWidget( mSystemTrayCheck );
02364 connect( mSystemTrayCheck, SIGNAL( stateChanged( int ) ),
02365 this, SLOT( slotEmitChanged( void ) ) );
02366
02367
02368 mSystemTrayGroup = new QVButtonGroup( i18n("System Tray Mode"), this );
02369 mSystemTrayGroup->layout()->setSpacing( KDialog::spacingHint() );
02370 vlay->addWidget( mSystemTrayGroup );
02371 connect( mSystemTrayGroup, SIGNAL( clicked( int ) ),
02372 this, SLOT( slotEmitChanged( void ) ) );
02373 connect( mSystemTrayCheck, SIGNAL( toggled( bool ) ),
02374 mSystemTrayGroup, SLOT( setEnabled( bool ) ) );
02375
02376 mSystemTrayGroup->insert( new QRadioButton( i18n("Always show KMail in system tray"), mSystemTrayGroup ),
02377 GlobalSettings::EnumSystemTrayPolicy::ShowAlways );
02378
02379 mSystemTrayGroup->insert( new QRadioButton( i18n("Only show KMail in system tray if there are unread messages"), mSystemTrayGroup ),
02380 GlobalSettings::EnumSystemTrayPolicy::ShowOnUnread );
02381
02382 vlay->addStretch( 10 );
02383 }
02384
02385 void AppearancePage::SystemTrayTab::doLoadFromGlobalSettings() {
02386 mSystemTrayCheck->setChecked( GlobalSettings::self()->systemTrayEnabled() );
02387 mSystemTrayGroup->setButton( GlobalSettings::self()->systemTrayPolicy() );
02388 mSystemTrayGroup->setEnabled( mSystemTrayCheck->isChecked() );
02389 }
02390
02391 void AppearancePage::SystemTrayTab::installProfile( KConfig * profile ) {
02392 KConfigGroup general( profile, "General" );
02393
02394 if ( general.hasKey( "SystemTrayEnabled" ) ) {
02395 mSystemTrayCheck->setChecked( general.readBoolEntry( "SystemTrayEnabled" ) );
02396 }
02397 if ( general.hasKey( "SystemTrayPolicy" ) ) {
02398 mSystemTrayGroup->setButton( general.readNumEntry( "SystemTrayPolicy" ) );
02399 }
02400 mSystemTrayGroup->setEnabled( mSystemTrayCheck->isChecked() );
02401 }
02402
02403 void AppearancePage::SystemTrayTab::save() {
02404 GlobalSettings::self()->setSystemTrayEnabled( mSystemTrayCheck->isChecked() );
02405 GlobalSettings::self()->setSystemTrayPolicy( mSystemTrayGroup->id( mSystemTrayGroup->selected() ) );
02406 }
02407
02408
02409
02410
02411
02412
02413
02414
02415 QString ComposerPage::helpAnchor() const {
02416 return QString::fromLatin1("configure-composer");
02417 }
02418
02419 ComposerPage::ComposerPage( QWidget * parent, const char * name )
02420 : ConfigModuleWithTabs( parent, name )
02421 {
02422
02423
02424
02425 mGeneralTab = new GeneralTab();
02426 addTab( mGeneralTab, i18n("&General") );
02427 addConfig( GlobalSettings::self(), mGeneralTab );
02428
02429
02430
02431
02432 mPhrasesTab = new PhrasesTab();
02433 addTab( mPhrasesTab, i18n("&Phrases") );
02434
02435
02436
02437
02438 mSubjectTab = new SubjectTab();
02439 addTab( mSubjectTab, i18n("&Subject") );
02440 addConfig( GlobalSettings::self(), mSubjectTab );
02441
02442
02443
02444
02445 mCharsetTab = new CharsetTab();
02446 addTab( mCharsetTab, i18n("Cha&rset") );
02447
02448
02449
02450
02451 mHeadersTab = new HeadersTab();
02452 addTab( mHeadersTab, i18n("H&eaders") );
02453
02454
02455
02456
02457 mAttachmentsTab = new AttachmentsTab();
02458 addTab( mAttachmentsTab, i18n("Config->Composer->Attachments", "A&ttachments") );
02459 load();
02460 }
02461
02462 QString ComposerPage::GeneralTab::helpAnchor() const {
02463 return QString::fromLatin1("configure-composer-general");
02464 }
02465
02466 ComposerPageGeneralTab::ComposerPageGeneralTab( QWidget * parent, const char * name )
02467 : ConfigModuleTab( parent, name )
02468 {
02469
02470 QVBoxLayout *vlay;
02471 QHBoxLayout *hlay;
02472 QGroupBox *group;
02473 QLabel *label;
02474 QHBox *hbox;
02475 QString msg;
02476
02477 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
02478
02479
02480 mAutoAppSignFileCheck = new QCheckBox(
02481 GlobalSettings::self()->autoTextSignatureItem()->label(),
02482 this );
02483 vlay->addWidget( mAutoAppSignFileCheck );
02484 connect( mAutoAppSignFileCheck, SIGNAL( stateChanged(int) ),
02485 this, SLOT( slotEmitChanged( void ) ) );
02486
02487 mSmartQuoteCheck = new QCheckBox(
02488 GlobalSettings::self()->smartQuoteItem()->label(),
02489 this, "kcfg_SmartQuote" );
02490 vlay->addWidget( mSmartQuoteCheck );
02491 connect( mSmartQuoteCheck, SIGNAL( stateChanged(int) ),
02492 this, SLOT( slotEmitChanged( void ) ) );
02493
02494 mAutoRequestMDNCheck = new QCheckBox(
02495 GlobalSettings::self()->requestMDNItem()->label(),
02496 this, "kcfg_RequestMDN" );
02497 vlay->addWidget( mAutoRequestMDNCheck );
02498 connect( mAutoRequestMDNCheck, SIGNAL( stateChanged(int) ),
02499 this, SLOT( slotEmitChanged( void ) ) );
02500
02501 mShowRecentAddressesInComposer = new QCheckBox(
02502 GlobalSettings::self()->showRecentAddressesInComposerItem()->label(),
02503 this, "kcfg_ShowRecentAddressesInComposer" );
02504 vlay->addWidget( mShowRecentAddressesInComposer );
02505 connect( mShowRecentAddressesInComposer, SIGNAL( stateChanged(int) ),
02506 this, SLOT( slotEmitChanged( void ) ) );
02507
02508
02509
02510 hlay = new QHBoxLayout( vlay );
02511 mWordWrapCheck = new QCheckBox(
02512 GlobalSettings::self()->wordWrapItem()->label(),
02513 this, "kcfg_WordWrap" );
02514 hlay->addWidget( mWordWrapCheck );
02515 connect( mWordWrapCheck, SIGNAL( stateChanged(int) ),
02516 this, SLOT( slotEmitChanged( void ) ) );
02517
02518 mWrapColumnSpin = new KIntSpinBox( 30, 78, 1,
02519 78, 10 , this, "kcfg_LineWrapWidth" );
02520 mWrapColumnSpin->setEnabled( false );
02521 connect( mWrapColumnSpin, SIGNAL( valueChanged(int) ),
02522 this, SLOT( slotEmitChanged( void ) ) );
02523
02524 hlay->addWidget( mWrapColumnSpin );
02525 hlay->addStretch( 1 );
02526
02527 connect( mWordWrapCheck, SIGNAL(toggled(bool)),
02528 mWrapColumnSpin, SLOT(setEnabled(bool)) );
02529
02530 hlay = new QHBoxLayout( vlay );
02531 mAutoSave = new KIntSpinBox( 0, 60, 1, 1, 10, this, "kcfg_AutosaveInterval" );
02532 label = new QLabel( mAutoSave,
02533 GlobalSettings::self()->autosaveIntervalItem()->label(), this );
02534 hlay->addWidget( label );
02535 hlay->addWidget( mAutoSave );
02536 mAutoSave->setSpecialValueText( i18n("No autosave") );
02537 mAutoSave->setSuffix( i18n(" min") );
02538 hlay->addStretch( 1 );
02539 connect( mAutoSave, SIGNAL( valueChanged(int) ),
02540 this, SLOT( slotEmitChanged( void ) ) );
02541
02542 hlay = new QHBoxLayout( vlay );
02543 QPushButton *completionOrderBtn = new QPushButton( i18n( "Configure Completion Order" ), this );
02544 connect( completionOrderBtn, SIGNAL( clicked() ),
02545 this, SLOT( slotConfigureCompletionOrder() ) );
02546 hlay->addWidget( completionOrderBtn );
02547 hlay->addItem( new QSpacerItem(0, 0) );
02548
02549
02550 hlay = new QHBoxLayout( vlay );
02551 QPushButton *recentAddressesBtn = new QPushButton( i18n( "Edit Recent Addresses" ), this );
02552 connect( recentAddressesBtn, SIGNAL( clicked() ),
02553 this, SLOT( slotConfigureRecentAddresses() ) );
02554 hlay->addWidget( recentAddressesBtn );
02555 hlay->addItem( new QSpacerItem(0, 0) );
02556
02557
02558 group = new QVGroupBox( i18n("External Editor"), this );
02559 group->layout()->setSpacing( KDialog::spacingHint() );
02560
02561 mExternalEditorCheck = new QCheckBox(
02562 GlobalSettings::self()->useExternalEditorItem()->label(),
02563 group, "kcfg_UseExternalEditor" );
02564 connect( mExternalEditorCheck, SIGNAL( toggled( bool ) ),
02565 this, SLOT( slotEmitChanged( void ) ) );
02566
02567 hbox = new QHBox( group );
02568 label = new QLabel( GlobalSettings::self()->externalEditorItem()->label(),
02569 hbox );
02570 mEditorRequester = new KURLRequester( hbox, "kcfg_ExternalEditor" );
02571 connect( mEditorRequester, SIGNAL( urlSelected(const QString&) ),
02572 this, SLOT( slotEmitChanged( void ) ) );
02573 connect( mEditorRequester, SIGNAL( textChanged(const QString&) ),
02574 this, SLOT( slotEmitChanged( void ) ) );
02575
02576 hbox->setStretchFactor( mEditorRequester, 1 );
02577 label->setBuddy( mEditorRequester );
02578 label->setEnabled( false );
02579
02580 mEditorRequester->setFilter( "application/x-executable "
02581 "application/x-shellscript "
02582 "application/x-desktop" );
02583 mEditorRequester->setEnabled( false );
02584 connect( mExternalEditorCheck, SIGNAL(toggled(bool)),
02585 label, SLOT(setEnabled(bool)) );
02586 connect( mExternalEditorCheck, SIGNAL(toggled(bool)),
02587 mEditorRequester, SLOT(setEnabled(bool)) );
02588
02589 label = new QLabel( i18n("<b>%f</b> will be replaced with the "
02590 "filename to edit."), group );
02591 label->setEnabled( false );
02592 connect( mExternalEditorCheck, SIGNAL(toggled(bool)),
02593 label, SLOT(setEnabled(bool)) );
02594
02595 vlay->addWidget( group );
02596 vlay->addStretch( 100 );
02597 }
02598
02599 void ComposerPage::GeneralTab::doLoadFromGlobalSettings() {
02600
02601
02602 mAutoAppSignFileCheck->setChecked(
02603 GlobalSettings::self()->autoTextSignature()=="auto" );
02604 mSmartQuoteCheck->setChecked( GlobalSettings::self()->smartQuote() );
02605 mAutoRequestMDNCheck->setChecked( GlobalSettings::self()->requestMDN() );
02606 mWordWrapCheck->setChecked( GlobalSettings::self()->wordWrap() );
02607
02608 mWrapColumnSpin->setValue( GlobalSettings::self()->lineWrapWidth() );
02609 mAutoSave->setValue( GlobalSettings::self()->autosaveInterval() );
02610
02611
02612 mExternalEditorCheck->setChecked( GlobalSettings::self()->useExternalEditor() );
02613 mEditorRequester->setURL( GlobalSettings::self()->externalEditor() );
02614 }
02615
02616 void ComposerPage::GeneralTab::installProfile( KConfig * profile ) {
02617 KConfigGroup composer( profile, "Composer" );
02618 KConfigGroup general( profile, "General" );
02619
02620 if ( composer.hasKey( "signature" ) ) {
02621 bool state = composer.readBoolEntry("signature");
02622 mAutoAppSignFileCheck->setChecked( state );
02623 }
02624 if ( composer.hasKey( "smart-quote" ) )
02625 mSmartQuoteCheck->setChecked( composer.readBoolEntry( "smart-quote" ) );
02626 if ( composer.hasKey( "request-mdn" ) )
02627 mAutoRequestMDNCheck->setChecked( composer.readBoolEntry( "request-mdn" ) );
02628 if ( composer.hasKey( "word-wrap" ) )
02629 mWordWrapCheck->setChecked( composer.readBoolEntry( "word-wrap" ) );
02630 if ( composer.hasKey( "break-at" ) )
02631 mWrapColumnSpin->setValue( composer.readNumEntry( "break-at" ) );
02632 if ( composer.hasKey( "autosave" ) )
02633 mAutoSave->setValue( composer.readNumEntry( "autosave" ) );
02634
02635 if ( general.hasKey( "use-external-editor" )
02636 && general.hasKey( "external-editor" ) ) {
02637 mExternalEditorCheck->setChecked( general.readBoolEntry( "use-external-editor" ) );
02638 mEditorRequester->setURL( general.readPathEntry( "external-editor" ) );
02639 }
02640 }
02641
02642 void ComposerPage::GeneralTab::save() {
02643 GlobalSettings::self()->setAutoTextSignature(
02644 mAutoAppSignFileCheck->isChecked() ? "auto" : "manual" );
02645 GlobalSettings::self()->setSmartQuote( mSmartQuoteCheck->isChecked() );
02646 GlobalSettings::self()->setRequestMDN( mAutoRequestMDNCheck->isChecked() );
02647 GlobalSettings::self()->setWordWrap( mWordWrapCheck->isChecked() );
02648
02649 GlobalSettings::self()->setLineWrapWidth( mWrapColumnSpin->value() );
02650 GlobalSettings::self()->setAutosaveInterval( mAutoSave->value() );
02651
02652
02653 GlobalSettings::self()->setUseExternalEditor( mExternalEditorCheck->isChecked() );
02654 GlobalSettings::self()->setExternalEditor( mEditorRequester->url() );
02655 }
02656
02657 void ComposerPage::GeneralTab::slotConfigureRecentAddresses( )
02658 {
02659 KRecentAddress::RecentAddressDialog dlg( this );
02660 dlg.setAddresses( RecentAddresses::self( KMKernel::config() )->addresses() );
02661 if ( dlg.exec() ) {
02662 RecentAddresses::self( KMKernel::config() )->clear();
02663 const QStringList &addrList = dlg.addresses();
02664 QStringList::ConstIterator it;
02665 for ( it = addrList.constBegin(); it != addrList.constEnd(); ++it )
02666 RecentAddresses::self( KMKernel::config() )->add( *it );
02667 }
02668 }
02669
02670 void ComposerPage::GeneralTab::slotConfigureCompletionOrder( )
02671 {
02672 KPIM::LdapSearch search;
02673 KPIM::CompletionOrderEditor editor( &search, this );
02674 editor.exec();
02675 }
02676
02677 QString ComposerPage::PhrasesTab::helpAnchor() const {
02678 return QString::fromLatin1("configure-composer-phrases");
02679 }
02680
02681 ComposerPagePhrasesTab::ComposerPagePhrasesTab( QWidget * parent, const char * name )
02682 : ConfigModuleTab( parent, name )
02683 {
02684
02685 QGridLayout *glay;
02686 QPushButton *button;
02687
02688 glay = new QGridLayout( this, 7, 3, KDialog::spacingHint() );
02689 glay->setMargin( KDialog::marginHint() );
02690 glay->setColStretch( 1, 1 );
02691 glay->setColStretch( 2, 1 );
02692 glay->setRowStretch( 7, 1 );
02693
02694
02695 glay->addMultiCellWidget( new QLabel( i18n("<qt>The following placeholders are "
02696 "supported in the reply phrases:<br>"
02697 "<b>%D</b>: date, <b>%S</b>: subject,<br>"
02698 "<b>%e</b>: sender's address, <b>%F</b>: sender's name, <b>%f</b>: sender's initials,<br>"
02699 "<b>%T</b>: recipient's name, <b>%t</b>: recipient's name and address,<br>"
02700 "<b>%C</b>: carbon copy names, <b>%c</b>: carbon copy names and addresses,<br>"
02701 "<b>%%</b>: percent sign, <b>%_</b>: space, "
02702 "<b>%L</b>: linebreak</qt>"), this ),
02703 0, 0, 0, 2 );
02704
02705
02706 mPhraseLanguageCombo = new LanguageComboBox( false, this );
02707 glay->addWidget( new QLabel( mPhraseLanguageCombo,
02708 i18n("Lang&uage:"), this ), 1, 0 );
02709 glay->addMultiCellWidget( mPhraseLanguageCombo, 1, 1, 1, 2 );
02710 connect( mPhraseLanguageCombo, SIGNAL(activated(const QString&)),
02711 this, SLOT(slotLanguageChanged(const QString&)) );
02712
02713
02714 button = new QPushButton( i18n("A&dd..."), this );
02715 button->setAutoDefault( false );
02716 glay->addWidget( button, 2, 1 );
02717 mRemoveButton = new QPushButton( i18n("Re&move"), this );
02718 mRemoveButton->setAutoDefault( false );
02719 mRemoveButton->setEnabled( false );
02720 glay->addWidget( mRemoveButton, 2, 2 );
02721 connect( button, SIGNAL(clicked()),
02722 this, SLOT(slotNewLanguage()) );
02723 connect( mRemoveButton, SIGNAL(clicked()),
02724 this, SLOT(slotRemoveLanguage()) );
02725
02726
02727 mPhraseReplyEdit = new KLineEdit( this );
02728 connect( mPhraseReplyEdit, SIGNAL( textChanged( const QString& ) ),
02729 this, SLOT( slotEmitChanged( void ) ) );
02730 glay->addWidget( new QLabel( mPhraseReplyEdit,
02731 i18n("Reply to se&nder:"), this ), 3, 0 );
02732 glay->addMultiCellWidget( mPhraseReplyEdit, 3, 3, 1, 2 );
02733
02734
02735 mPhraseReplyAllEdit = new KLineEdit( this );
02736 connect( mPhraseReplyAllEdit, SIGNAL( textChanged( const QString& ) ),
02737 this, SLOT( slotEmitChanged( void ) ) );
02738 glay->addWidget( new QLabel( mPhraseReplyAllEdit,
02739 i18n("Repl&y to all:"), this ), 4, 0 );
02740 glay->addMultiCellWidget( mPhraseReplyAllEdit, 4, 4, 1, 2 );
02741
02742
02743 mPhraseForwardEdit = new KLineEdit( this );
02744 connect( mPhraseForwardEdit, SIGNAL( textChanged( const QString& ) ),
02745 this, SLOT( slotEmitChanged( void ) ) );
02746 glay->addWidget( new QLabel( mPhraseForwardEdit,
02747 i18n("&Forward:"), this ), 5, 0 );
02748 glay->addMultiCellWidget( mPhraseForwardEdit, 5, 5, 1, 2 );
02749
02750
02751 mPhraseIndentPrefixEdit = new KLineEdit( this );
02752 connect( mPhraseIndentPrefixEdit, SIGNAL( textChanged( const QString& ) ),
02753 this, SLOT( slotEmitChanged( void ) ) );
02754 glay->addWidget( new QLabel( mPhraseIndentPrefixEdit,
02755 i18n("&Quote indicator:"), this ), 6, 0 );
02756 glay->addMultiCellWidget( mPhraseIndentPrefixEdit, 6, 6, 1, 2 );
02757
02758
02759 }
02760
02761
02762 void ComposerPage::PhrasesTab::setLanguageItemInformation( int index ) {
02763 assert( 0 <= index && index < (int)mLanguageList.count() );
02764
02765 LanguageItem &l = *mLanguageList.at( index );
02766
02767 mPhraseReplyEdit->setText( l.mReply );
02768 mPhraseReplyAllEdit->setText( l.mReplyAll );
02769 mPhraseForwardEdit->setText( l.mForward );
02770 mPhraseIndentPrefixEdit->setText( l.mIndentPrefix );
02771 }
02772
02773 void ComposerPage::PhrasesTab::saveActiveLanguageItem() {
02774 int index = mActiveLanguageItem;
02775 if (index == -1) return;
02776 assert( 0 <= index && index < (int)mLanguageList.count() );
02777
02778 LanguageItem &l = *mLanguageList.at( index );
02779
02780 l.mReply = mPhraseReplyEdit->text();
02781 l.mReplyAll = mPhraseReplyAllEdit->text();
02782 l.mForward = mPhraseForwardEdit->text();
02783 l.mIndentPrefix = mPhraseIndentPrefixEdit->text();
02784 }
02785
02786 void ComposerPage::PhrasesTab::slotNewLanguage()
02787 {
02788 NewLanguageDialog dialog( mLanguageList, parentWidget(), "New", true );
02789 if ( dialog.exec() == QDialog::Accepted ) slotAddNewLanguage( dialog.language() );
02790 }
02791
02792 void ComposerPage::PhrasesTab::slotAddNewLanguage( const QString& lang )
02793 {
02794 mPhraseLanguageCombo->setCurrentItem(
02795 mPhraseLanguageCombo->insertLanguage( lang ) );
02796 KLocale locale("kmail");
02797 locale.setLanguage( lang );
02798 mLanguageList.append(
02799 LanguageItem( lang,
02800 locale.translate("On %D, you wrote:"),
02801 locale.translate("On %D, %F wrote:"),
02802 locale.translate("Forwarded Message"),
02803 locale.translate(">%_") ) );
02804 mRemoveButton->setEnabled( true );
02805 slotLanguageChanged( QString::null );
02806 }
02807
02808 void ComposerPage::PhrasesTab::slotRemoveLanguage()
02809 {
02810 assert( mPhraseLanguageCombo->count() > 1 );
02811 int index = mPhraseLanguageCombo->currentItem();
02812 assert( 0 <= index && index < (int)mLanguageList.count() );
02813
02814
02815 mLanguageList.remove( mLanguageList.at( index ) );
02816 mPhraseLanguageCombo->removeItem( index );
02817
02818 if ( index >= (int)mLanguageList.count() ) index--;
02819
02820 mActiveLanguageItem = index;
02821 setLanguageItemInformation( index );
02822 mRemoveButton->setEnabled( mLanguageList.count() > 1 );
02823 emit changed( true );
02824 }
02825
02826 void ComposerPage::PhrasesTab::slotLanguageChanged( const QString& )
02827 {
02828 int index = mPhraseLanguageCombo->currentItem();
02829 assert( index < (int)mLanguageList.count() );
02830 saveActiveLanguageItem();
02831 mActiveLanguageItem = index;
02832 setLanguageItemInformation( index );
02833 emit changed( true );
02834 }
02835
02836
02837 void ComposerPage::PhrasesTab::doLoadFromGlobalSettings() {
02838 mLanguageList.clear();
02839 mPhraseLanguageCombo->clear();
02840 mActiveLanguageItem = -1;
02841
02842 int numLang = GlobalSettings::self()->replyLanguagesCount();
02843 int currentNr = GlobalSettings::self()->replyCurrentLanguage();
02844
02845
02846 for ( int i = 0 ; i < numLang ; i++ ) {
02847 ReplyPhrases replyPhrases( QString::number(i) );
02848 replyPhrases.readConfig();
02849 QString lang = replyPhrases.language();
02850 mLanguageList.append(
02851 LanguageItem( lang,
02852 replyPhrases.phraseReplySender(),
02853 replyPhrases.phraseReplyAll(),
02854 replyPhrases.phraseForward(),
02855 replyPhrases.indentPrefix() ) );
02856 mPhraseLanguageCombo->insertLanguage( lang );
02857 }
02858
02859 if ( currentNr >= numLang || currentNr < 0 )
02860 currentNr = 0;
02861
02862 if ( numLang == 0 ) {
02863 slotAddNewLanguage( KGlobal::locale()->language() );
02864 }
02865
02866 mPhraseLanguageCombo->setCurrentItem( currentNr );
02867 mActiveLanguageItem = currentNr;
02868 setLanguageItemInformation( currentNr );
02869 mRemoveButton->setEnabled( mLanguageList.count() > 1 );
02870 }
02871
02872 void ComposerPage::PhrasesTab::save() {
02873 GlobalSettings::self()->setReplyLanguagesCount( mLanguageList.count() );
02874 GlobalSettings::self()->setReplyCurrentLanguage( mPhraseLanguageCombo->currentItem() );
02875
02876 saveActiveLanguageItem();
02877 LanguageItemList::Iterator it = mLanguageList.begin();
02878 for ( int i = 0 ; it != mLanguageList.end() ; ++it, ++i ) {
02879 ReplyPhrases replyPhrases( QString::number(i) );
02880 replyPhrases.setLanguage( (*it).mLanguage );
02881 replyPhrases.setPhraseReplySender( (*it).mReply );
02882 replyPhrases.setPhraseReplyAll( (*it).mReplyAll );
02883 replyPhrases.setPhraseForward( (*it).mForward );
02884 replyPhrases.setIndentPrefix( (*it).mIndentPrefix );
02885 replyPhrases.writeConfig();
02886 }
02887 }
02888
02889 QString ComposerPage::SubjectTab::helpAnchor() const {
02890 return QString::fromLatin1("configure-composer-subject");
02891 }
02892
02893 ComposerPageSubjectTab::ComposerPageSubjectTab( QWidget * parent, const char * name )
02894 : ConfigModuleTab( parent, name )
02895 {
02896
02897 QVBoxLayout *vlay;
02898 QGroupBox *group;
02899 QLabel *label;
02900
02901
02902 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
02903
02904 group = new QVGroupBox( i18n("Repl&y Subject Prefixes"), this );
02905 group->layout()->setSpacing( KDialog::spacingHint() );
02906
02907
02908 label = new QLabel( i18n("Recognize any sequence of the following prefixes\n"
02909 "(entries are case-insensitive regular expressions):"), group );
02910 label->setAlignment( AlignLeft|WordBreak );
02911
02912
02913 SimpleStringListEditor::ButtonCode buttonCode =
02914 static_cast<SimpleStringListEditor::ButtonCode>( SimpleStringListEditor::Add | SimpleStringListEditor::Remove | SimpleStringListEditor::Modify );
02915 mReplyListEditor =
02916 new SimpleStringListEditor( group, 0, buttonCode,
02917 i18n("A&dd..."), i18n("Re&move"),
02918 i18n("Mod&ify..."),
02919 i18n("Enter new reply prefix:") );
02920 connect( mReplyListEditor, SIGNAL( changed( void ) ),
02921 this, SLOT( slotEmitChanged( void ) ) );
02922
02923
02924 mReplaceReplyPrefixCheck = new QCheckBox(
02925 GlobalSettings::self()->replaceReplyPrefixItem()->label(),
02926 group, "kcfg_ReplaceReplyPrefix" );
02927 connect( mReplaceReplyPrefixCheck, SIGNAL( stateChanged( int ) ),
02928 this, SLOT( slotEmitChanged( void ) ) );
02929
02930 vlay->addWidget( group );
02931
02932
02933 group = new QVGroupBox( i18n("For&ward Subject Prefixes"), this );
02934 group->layout()->setSpacing( KDialog::marginHint() );
02935
02936
02937 label= new QLabel( i18n("Recognize any sequence of the following prefixes\n"
02938 "(entries are case-insensitive regular expressions):"), group );
02939 label->setAlignment( AlignLeft|WordBreak );
02940
02941
02942 mForwardListEditor =
02943 new SimpleStringListEditor( group, 0, buttonCode,
02944 i18n("Add..."),
02945 i18n("Remo&ve"),
02946 i18n("Modify..."),
02947 i18n("Enter new forward prefix:") );
02948 connect( mForwardListEditor, SIGNAL( changed( void ) ),
02949 this, SLOT( slotEmitChanged( void ) ) );
02950
02951
02952 mReplaceForwardPrefixCheck = new QCheckBox(
02953 GlobalSettings::self()->replaceForwardPrefixItem()->label(),
02954 group, "kcfg_ReplaceForwardPrefix" );
02955 connect( mReplaceForwardPrefixCheck, SIGNAL( stateChanged( int ) ),
02956 this, SLOT( slotEmitChanged( void ) ) );
02957
02958 vlay->addWidget( group );
02959 }
02960
02961 void ComposerPage::SubjectTab::doLoadFromGlobalSettings() {
02962 mReplyListEditor->setStringList( GlobalSettings::self()->replyPrefixes() );
02963 mReplaceReplyPrefixCheck->setChecked( GlobalSettings::self()->replaceReplyPrefix() );
02964 mForwardListEditor->setStringList( GlobalSettings::self()->forwardPrefixes() );
02965 mReplaceForwardPrefixCheck->setChecked( GlobalSettings::self()->replaceForwardPrefix() );
02966 }
02967
02968 void ComposerPage::SubjectTab::save() {
02969 GlobalSettings::self()->setReplyPrefixes( mReplyListEditor->stringList() );
02970 GlobalSettings::self()->setForwardPrefixes( mForwardListEditor->stringList() );
02971 }
02972
02973 QString ComposerPage::CharsetTab::helpAnchor() const {
02974 return QString::fromLatin1("configure-composer-charset");
02975 }
02976
02977 ComposerPageCharsetTab::ComposerPageCharsetTab( QWidget * parent, const char * name )
02978 : ConfigModuleTab( parent, name )
02979 {
02980
02981 QVBoxLayout *vlay;
02982 QLabel *label;
02983
02984 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
02985
02986 label = new QLabel( i18n("This list is checked for every outgoing message "
02987 "from the top to the bottom for a charset that "
02988 "contains all required characters."), this );
02989 label->setAlignment( WordBreak);
02990 vlay->addWidget( label );
02991
02992 mCharsetListEditor =
02993 new SimpleStringListEditor( this, 0, SimpleStringListEditor::All,
02994 i18n("A&dd..."), i18n("Remo&ve"),
02995 i18n("&Modify..."), i18n("Enter charset:") );
02996 connect( mCharsetListEditor, SIGNAL( changed( void ) ),
02997 this, SLOT( slotEmitChanged( void ) ) );
02998
02999 vlay->addWidget( mCharsetListEditor, 1 );
03000
03001 mKeepReplyCharsetCheck = new QCheckBox( i18n("&Keep original charset when "
03002 "replying or forwarding (if "
03003 "possible)"), this );
03004 connect( mKeepReplyCharsetCheck, SIGNAL ( stateChanged( int ) ),
03005 this, SLOT( slotEmitChanged( void ) ) );
03006 vlay->addWidget( mKeepReplyCharsetCheck );
03007
03008 connect( mCharsetListEditor, SIGNAL(aboutToAdd(QString&)),
03009 this, SLOT(slotVerifyCharset(QString&)) );
03010 }
03011
03012 void ComposerPage::CharsetTab::slotVerifyCharset( QString & charset ) {
03013 if ( charset.isEmpty() ) return;
03014
03015
03016
03017 if ( charset.lower() == QString::fromLatin1("us-ascii") ) {
03018 charset = QString::fromLatin1("us-ascii");
03019 return;
03020 }
03021
03022 if ( charset.lower() == QString::fromLatin1("locale") ) {
03023 charset = QString::fromLatin1("%1 (locale)")
03024 .arg( QCString( kmkernel->networkCodec()->mimeName() ).lower() );
03025 return;
03026 }
03027
03028 bool ok = false;
03029 QTextCodec *codec = KGlobal::charsets()->codecForName( charset, ok );
03030 if ( ok && codec ) {
03031 charset = QString::fromLatin1( codec->mimeName() ).lower();
03032 return;
03033 }
03034
03035 KMessageBox::sorry( this, i18n("This charset is not supported.") );
03036 charset = QString::null;
03037 }
03038
03039 void ComposerPage::CharsetTab::doLoadOther() {
03040 KConfigGroup composer( KMKernel::config(), "Composer" );
03041
03042 QStringList charsets = composer.readListEntry( "pref-charsets" );
03043 for ( QStringList::Iterator it = charsets.begin() ;
03044 it != charsets.end() ; ++it )
03045 if ( (*it) == QString::fromLatin1("locale") ) {
03046 QCString cset = kmkernel->networkCodec()->mimeName();
03047 KPIM::kAsciiToLower( cset.data() );
03048 (*it) = QString("%1 (locale)").arg( cset );
03049 }
03050
03051 mCharsetListEditor->setStringList( charsets );
03052 mKeepReplyCharsetCheck->setChecked( !composer.readBoolEntry( "force-reply-charset", false ) );
03053 }
03054
03055 void ComposerPage::CharsetTab::save() {
03056 KConfigGroup composer( KMKernel::config(), "Composer" );
03057
03058 QStringList charsetList = mCharsetListEditor->stringList();
03059 QStringList::Iterator it = charsetList.begin();
03060 for ( ; it != charsetList.end() ; ++it )
03061 if ( (*it).endsWith("(locale)") )
03062 (*it) = "locale";
03063 composer.writeEntry( "pref-charsets", charsetList );
03064 composer.writeEntry( "force-reply-charset",
03065 !mKeepReplyCharsetCheck->isChecked() );
03066 }
03067
03068 QString ComposerPage::HeadersTab::helpAnchor() const {
03069 return QString::fromLatin1("configure-composer-headers");
03070 }
03071
03072 ComposerPageHeadersTab::ComposerPageHeadersTab( QWidget * parent, const char * name )
03073 : ConfigModuleTab( parent, name )
03074 {
03075
03076 QVBoxLayout *vlay;
03077 QHBoxLayout *hlay;
03078 QGridLayout *glay;
03079 QLabel *label;
03080 QPushButton *button;
03081
03082 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
03083
03084
03085 mCreateOwnMessageIdCheck =
03086 new QCheckBox( i18n("&Use custom message-id suffix"), this );
03087 connect( mCreateOwnMessageIdCheck, SIGNAL ( stateChanged( int ) ),
03088 this, SLOT( slotEmitChanged( void ) ) );
03089 vlay->addWidget( mCreateOwnMessageIdCheck );
03090
03091
03092 hlay = new QHBoxLayout( vlay );
03093 mMessageIdSuffixEdit = new KLineEdit( this );
03094
03095 mMessageIdSuffixValidator =
03096 new QRegExpValidator( QRegExp( "[a-zA-Z0-9+-]+(?:\\.[a-zA-Z0-9+-]+)*" ), this );
03097 mMessageIdSuffixEdit->setValidator( mMessageIdSuffixValidator );
03098 label = new QLabel( mMessageIdSuffixEdit,
03099 i18n("Custom message-&id suffix:"), this );
03100 label->setEnabled( false );
03101 mMessageIdSuffixEdit->setEnabled( false );
03102 hlay->addWidget( label );
03103 hlay->addWidget( mMessageIdSuffixEdit, 1 );
03104 connect( mCreateOwnMessageIdCheck, SIGNAL(toggled(bool) ),
03105 label, SLOT(setEnabled(bool)) );
03106 connect( mCreateOwnMessageIdCheck, SIGNAL(toggled(bool) ),
03107 mMessageIdSuffixEdit, SLOT(setEnabled(bool)) );
03108 connect( mMessageIdSuffixEdit, SIGNAL( textChanged( const QString& ) ),
03109 this, SLOT( slotEmitChanged( void ) ) );
03110
03111
03112 vlay->addWidget( new KSeparator( KSeparator::HLine, this ) );
03113 vlay->addWidget( new QLabel( i18n("Define custom mime header fields:"), this) );
03114
03115
03116 glay = new QGridLayout( vlay, 5, 3 );
03117 glay->setRowStretch( 2, 1 );
03118 glay->setColStretch( 1, 1 );
03119 mTagList = new ListView( this, "tagList" );
03120 mTagList->addColumn( i18n("Name") );
03121 mTagList->addColumn( i18n("Value") );
03122 mTagList->setAllColumnsShowFocus( true );
03123 mTagList->setSorting( -1 );
03124 connect( mTagList, SIGNAL(selectionChanged()),
03125 this, SLOT(slotMimeHeaderSelectionChanged()) );
03126 glay->addMultiCellWidget( mTagList, 0, 2, 0, 1 );
03127
03128
03129 button = new QPushButton( i18n("Ne&w"), this );
03130 connect( button, SIGNAL(clicked()), this, SLOT(slotNewMimeHeader()) );
03131 button->setAutoDefault( false );
03132 glay->addWidget( button, 0, 2 );
03133 mRemoveHeaderButton = new QPushButton( i18n("Re&move"), this );
03134 connect( mRemoveHeaderButton, SIGNAL(clicked()),
03135 this, SLOT(slotRemoveMimeHeader()) );
03136 button->setAutoDefault( false );
03137 glay->addWidget( mRemoveHeaderButton, 1, 2 );
03138
03139
03140 mTagNameEdit = new KLineEdit( this );
03141 mTagNameEdit->setEnabled( false );
03142 mTagNameLabel = new QLabel( mTagNameEdit, i18n("&Name:"), this );
03143 mTagNameLabel->setEnabled( false );
03144 glay->addWidget( mTagNameLabel, 3, 0 );
03145 glay->addWidget( mTagNameEdit, 3, 1 );
03146 connect( mTagNameEdit, SIGNAL(textChanged(const QString&)),
03147 this, SLOT(slotMimeHeaderNameChanged(const QString&)) );
03148
03149 mTagValueEdit = new KLineEdit( this );
03150 mTagValueEdit->setEnabled( false );
03151 mTagValueLabel = new QLabel( mTagValueEdit, i18n("&Value:"), this );
03152 mTagValueLabel->setEnabled( false );
03153 glay->addWidget( mTagValueLabel, 4, 0 );
03154 glay->addWidget( mTagValueEdit, 4, 1 );
03155 connect( mTagValueEdit, SIGNAL(textChanged(const QString&)),
03156 this, SLOT(slotMimeHeaderValueChanged(const QString&)) );
03157 }
03158
03159 void ComposerPage::HeadersTab::slotMimeHeaderSelectionChanged()
03160 {
03161 QListViewItem * item = mTagList->selectedItem();
03162
03163 if ( item ) {
03164 mTagNameEdit->setText( item->text( 0 ) );
03165 mTagValueEdit->setText( item->text( 1 ) );
03166 } else {
03167 mTagNameEdit->clear();
03168 mTagValueEdit->clear();
03169 }
03170 mRemoveHeaderButton->setEnabled( item );
03171 mTagNameEdit->setEnabled( item );
03172 mTagValueEdit->setEnabled( item );
03173 mTagNameLabel->setEnabled( item );
03174 mTagValueLabel->setEnabled( item );
03175 }
03176
03177
03178 void ComposerPage::HeadersTab::slotMimeHeaderNameChanged( const QString & text ) {
03179
03180
03181 QListViewItem * item = mTagList->selectedItem();
03182 if ( item )
03183 item->setText( 0, text );
03184 emit changed( true );
03185 }
03186
03187
03188 void ComposerPage::HeadersTab::slotMimeHeaderValueChanged( const QString & text ) {
03189
03190
03191 QListViewItem * item = mTagList->selectedItem();
03192 if ( item )
03193 item->setText( 1, text );
03194 emit changed( true );
03195 }
03196
03197
03198 void ComposerPage::HeadersTab::slotNewMimeHeader()
03199 {
03200 QListViewItem *listItem = new QListViewItem( mTagList );
03201 mTagList->setCurrentItem( listItem );
03202 mTagList->setSelected( listItem, true );
03203 emit changed( true );
03204 }
03205
03206
03207 void ComposerPage::HeadersTab::slotRemoveMimeHeader()
03208 {
03209
03210 QListViewItem * item = mTagList->selectedItem();
03211 if ( !item ) {
03212 kdDebug(5006) << "==================================================\n"
03213 << "Error: Remove button was pressed although no custom header was selected\n"
03214 << "==================================================\n";
03215 return;
03216 }
03217
03218 QListViewItem * below = item->nextSibling();
03219 delete item;
03220
03221 if ( below )
03222 mTagList->setSelected( below, true );
03223 else if ( mTagList->lastItem() )
03224 mTagList->setSelected( mTagList->lastItem(), true );
03225 emit changed( true );
03226 }
03227
03228 void ComposerPage::HeadersTab::doLoadOther() {
03229 KConfigGroup general( KMKernel::config(), "General" );
03230
03231 QString suffix = general.readEntry( "myMessageIdSuffix" );
03232 mMessageIdSuffixEdit->setText( suffix );
03233 bool state = ( !suffix.isEmpty() &&
03234 general.readBoolEntry( "useCustomMessageIdSuffix", false ) );
03235 mCreateOwnMessageIdCheck->setChecked( state );
03236
03237 mTagList->clear();
03238 mTagNameEdit->clear();
03239 mTagValueEdit->clear();
03240
03241 QListViewItem * item = 0;
03242
03243 int count = general.readNumEntry( "mime-header-count", 0 );
03244 for( int i = 0 ; i < count ; i++ ) {
03245 KConfigGroup config( KMKernel::config(),
03246 QCString("Mime #") + QCString().setNum(i) );
03247 QString name = config.readEntry( "name" );
03248 QString value = config.readEntry( "value" );
03249 if( !name.isEmpty() )
03250 item = new QListViewItem( mTagList, item, name, value );
03251 }
03252 if ( mTagList->childCount() ) {
03253 mTagList->setCurrentItem( mTagList->firstChild() );
03254 mTagList->setSelected( mTagList->firstChild(), true );
03255 }
03256 else {
03257
03258 mRemoveHeaderButton->setEnabled( false );
03259 }
03260 }
03261
03262 void ComposerPage::HeadersTab::save() {
03263 KConfigGroup general( KMKernel::config(), "General" );
03264
03265 general.writeEntry( "useCustomMessageIdSuffix",
03266 mCreateOwnMessageIdCheck->isChecked() );
03267 general.writeEntry( "myMessageIdSuffix",
03268 mMessageIdSuffixEdit->text() );
03269
03270 int numValidEntries = 0;
03271 QListViewItem * item = mTagList->firstChild();
03272 for ( ; item ; item = item->itemBelow() )
03273 if( !item->text(0).isEmpty() ) {
03274 KConfigGroup config( KMKernel::config(), QCString("Mime #")
03275 + QCString().setNum( numValidEntries ) );
03276 config.writeEntry( "name", item->text( 0 ) );
03277 config.writeEntry( "value", item->text( 1 ) );
03278 numValidEntries++;
03279 }
03280 general.writeEntry( "mime-header-count", numValidEntries );
03281 }
03282
03283 QString ComposerPage::AttachmentsTab::helpAnchor() const {
03284 return QString::fromLatin1("configure-composer-attachments");
03285 }
03286
03287 ComposerPageAttachmentsTab::ComposerPageAttachmentsTab( QWidget * parent,
03288 const char * name )
03289 : ConfigModuleTab( parent, name ) {
03290
03291 QVBoxLayout *vlay;
03292 QLabel *label;
03293
03294 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
03295
03296
03297 mOutlookCompatibleCheck =
03298 new QCheckBox( i18n( "Outlook-compatible attachment naming" ), this );
03299 mOutlookCompatibleCheck->setChecked( false );
03300 QToolTip::add( mOutlookCompatibleCheck, i18n(
03301 "Turn this option on to make Outlook(tm) understand attachment names "
03302 "containing non-English characters" ) );
03303 connect( mOutlookCompatibleCheck, SIGNAL( stateChanged( int ) ),
03304 this, SLOT( slotEmitChanged( void ) ) );
03305 connect( mOutlookCompatibleCheck, SIGNAL( clicked() ),
03306 this, SLOT( slotOutlookCompatibleClicked() ) );
03307 vlay->addWidget( mOutlookCompatibleCheck );
03308 vlay->addSpacing( 5 );
03309
03310
03311 mMissingAttachmentDetectionCheck =
03312 new QCheckBox( i18n("E&nable detection of missing attachments"), this );
03313 mMissingAttachmentDetectionCheck->setChecked( true );
03314 connect( mMissingAttachmentDetectionCheck, SIGNAL( stateChanged( int ) ),
03315 this, SLOT( slotEmitChanged( void ) ) );
03316 vlay->addWidget( mMissingAttachmentDetectionCheck );
03317
03318
03319 label = new QLabel( i18n("Recognize any of the following key words as "
03320 "intention to attach a file:"), this );
03321 label->setAlignment( AlignLeft|WordBreak );
03322 vlay->addWidget( label );
03323
03324 SimpleStringListEditor::ButtonCode buttonCode =
03325 static_cast<SimpleStringListEditor::ButtonCode>( SimpleStringListEditor::Add | SimpleStringListEditor::Remove | SimpleStringListEditor::Modify );
03326 mAttachWordsListEditor =
03327 new SimpleStringListEditor( this, 0, buttonCode,
03328 i18n("A&dd..."), i18n("Re&move"),
03329 i18n("Mod&ify..."),
03330 i18n("Enter new key word:") );
03331 connect( mAttachWordsListEditor, SIGNAL( changed( void ) ),
03332 this, SLOT( slotEmitChanged( void ) ) );
03333 vlay->addWidget( mAttachWordsListEditor );
03334
03335 connect( mMissingAttachmentDetectionCheck, SIGNAL(toggled(bool) ),
03336 label, SLOT(setEnabled(bool)) );
03337 connect( mMissingAttachmentDetectionCheck, SIGNAL(toggled(bool) ),
03338 mAttachWordsListEditor, SLOT(setEnabled(bool)) );
03339 }
03340
03341 void ComposerPage::AttachmentsTab::doLoadOther() {
03342 KConfigGroup composer( KMKernel::config(), "Composer" );
03343
03344 mOutlookCompatibleCheck->setChecked(
03345 composer.readBoolEntry( "outlook-compatible-attachments", false ) );
03346 mMissingAttachmentDetectionCheck->setChecked(
03347 composer.readBoolEntry( "showForgottenAttachmentWarning", true ) );
03348 QStringList attachWordsList =
03349 composer.readListEntry( "attachment-keywords" );
03350 if ( attachWordsList.isEmpty() ) {
03351
03352 attachWordsList << QString::fromLatin1("attachment")
03353 << QString::fromLatin1("attached");
03354 if ( QString::fromLatin1("attachment") != i18n("attachment") )
03355 attachWordsList << i18n("attachment");
03356 if ( QString::fromLatin1("attached") != i18n("attached") )
03357 attachWordsList << i18n("attached");
03358 }
03359
03360 mAttachWordsListEditor->setStringList( attachWordsList );
03361 }
03362
03363 void ComposerPage::AttachmentsTab::save() {
03364 KConfigGroup composer( KMKernel::config(), "Composer" );
03365 composer.writeEntry( "outlook-compatible-attachments",
03366 mOutlookCompatibleCheck->isChecked() );
03367 composer.writeEntry( "showForgottenAttachmentWarning",
03368 mMissingAttachmentDetectionCheck->isChecked() );
03369 composer.writeEntry( "attachment-keywords",
03370 mAttachWordsListEditor->stringList() );
03371 }
03372
03373 void ComposerPageAttachmentsTab::slotOutlookCompatibleClicked()
03374 {
03375 if (mOutlookCompatibleCheck->isChecked()) {
03376 KMessageBox::information(0,i18n("You have chosen to "
03377 "encode attachment names containing non-English characters in a way that "
03378 "is understood by Outlook(tm) and other mail clients that do not "
03379 "support standard-compliant encoded attachment names.\n"
03380 "Note that KMail may create non-standard compliant messages, "
03381 "and consequently it is possible that your messages will not be "
03382 "understood by standard-compliant mail clients; so, unless you have no "
03383 "other choice, you should not enable this option." ) );
03384 }
03385 }
03386
03387
03388
03389
03390
03391
03392 QString SecurityPage::helpAnchor() const {
03393 return QString::fromLatin1("configure-security");
03394 }
03395
03396 SecurityPage::SecurityPage( QWidget * parent, const char * name )
03397 : ConfigModuleWithTabs( parent, name )
03398 {
03399
03400
03401
03402 mGeneralTab = new GeneralTab();
03403 addTab( mGeneralTab, i18n("&Reading") );
03404
03405
03406
03407
03408 mComposerCryptoTab = new ComposerCryptoTab();
03409 addTab( mComposerCryptoTab, i18n("Composing") );
03410
03411
03412
03413
03414 mWarningTab = new WarningTab();
03415 addTab( mWarningTab, i18n("Warnings") );
03416
03417
03418
03419
03420 mSMimeTab = new SMimeTab();
03421 addTab( mSMimeTab, i18n("S/MIME &Validation") );
03422
03423
03424
03425
03426 mCryptPlugTab = new CryptPlugTab();
03427 addTab( mCryptPlugTab, i18n("Crypto Backe&nds") );
03428 load();
03429 }
03430
03431
03432 void SecurityPage::installProfile( KConfig * profile ) {
03433 mGeneralTab->installProfile( profile );
03434 mComposerCryptoTab->installProfile( profile );
03435 mWarningTab->installProfile( profile );
03436 mSMimeTab->installProfile( profile );
03437 }
03438
03439 QString SecurityPage::GeneralTab::helpAnchor() const {
03440 return QString::fromLatin1("configure-security-reading");
03441 }
03442
03443 SecurityPageGeneralTab::SecurityPageGeneralTab( QWidget * parent, const char * name )
03444 : ConfigModuleTab ( parent, name )
03445 {
03446
03447 QVBoxLayout *vlay;
03448 QHBox *hbox;
03449 QGroupBox *group;
03450 QRadioButton *radio;
03451 KActiveLabel *label;
03452 QWidget *w;
03453 QString msg;
03454
03455 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
03456
03457
03458 QString htmlWhatsThis = i18n( "<qt><p>Messages sometimes come in both formats. "
03459 "This option controls whether you want the HTML part or the plain "
03460 "text part to be displayed.</p>"
03461 "<p>Displaying the HTML part makes the message look better, "
03462 "but at the same time increases the risk of security holes "
03463 "being exploited.</p>"
03464 "<p>Displaying the plain text part loses much of the message's "
03465 "formatting, but makes it almost <em>impossible</em> "
03466 "to exploit security holes in the HTML renderer (Konqueror).</p>"
03467 "<p>The option below guards against one common misuse of HTML "
03468 "messages, but it cannot guard against security issues that were "
03469 "not known at the time this version of KMail was written.</p>"
03470 "<p>It is therefore advisable to <em>not</em> prefer HTML to "
03471 "plain text.</p>"
03472 "<p><b>Note:</b> You can set this option on a per-folder basis "
03473 "from the <i>Folder</i> menu of KMail's main window.</p></qt>" );
03474
03475 QString externalWhatsThis = i18n( "<qt><p>Some mail advertisements are in HTML "
03476 "and contain references to, for example, images that the advertisers"
03477 " employ to find out that you have read their message "
03478 "("web bugs").</p>"
03479 "<p>There is no valid reason to load images off the Internet like "
03480 "this, since the sender can always attach the required images "
03481 "directly to the message.</p>"
03482 "<p>To guard from such a misuse of the HTML displaying feature "
03483 "of KMail, this option is <em>disabled</em> by default.</p>"
03484 "<p>However, if you wish to, for example, view images in HTML "
03485 "messages that were not attached to it, you can enable this "
03486 "option, but you should be aware of the possible problem.</p></qt>" );
03487
03488 QString receiptWhatsThis = i18n( "<qt><h3>Message Disposition "
03489 "Notification Policy</h3>"
03490 "<p>MDNs are a generalization of what is commonly called <b>read "
03491 "receipt</b>. The message author requests a disposition "
03492 "notification to be sent and the receiver's mail program "
03493 "generates a reply from which the author can learn what "
03494 "happened to his message. Common disposition types include "
03495 "<b>displayed</b> (i.e. read), <b>deleted</b> and <b>dispatched</b> "
03496 "(e.g. forwarded).</p>"
03497 "<p>The following options are available to control KMail's "
03498 "sending of MDNs:</p>"
03499 "<ul>"
03500 "<li><em>Ignore</em>: Ignores any request for disposition "
03501 "notifications. No MDN will ever be sent automatically "
03502 "(recommended).</li>"
03503 "<li><em>Ask</em>: Answers requests only after asking the user "
03504 "for permission. This way, you can send MDNs for selected "
03505 "messages while denying or ignoring them for others.</li>"
03506 "<li><em>Deny</em>: Always sends a <b>denied</b> notification. This "
03507 "is only <em>slightly</em> better than always sending MDNs. "
03508 "The author will still know that the messages has been acted "
03509 "upon, he just cannot tell whether it was deleted or read etc.</li>"
03510 "<li><em>Always send</em>: Always sends the requested "
03511 "disposition notification. That means that the author of the "
03512 "message gets to know when the message was acted upon and, "
03513 "in addition, what happened to it (displayed, deleted, "
03514 "etc.). This option is strongly discouraged, but since it "
03515 "makes much sense e.g. for customer relationship management, "
03516 "it has been made available.</li>"
03517 "</ul></qt>" );
03518
03519
03520
03521 group = new QVGroupBox( i18n( "HTML Messages" ), this );
03522 group->layout()->setSpacing( KDialog::spacingHint() );
03523
03524 mHtmlMailCheck = new QCheckBox( i18n("Prefer H&TML to plain text"), group );
03525 QWhatsThis::add( mHtmlMailCheck, htmlWhatsThis );
03526 connect( mHtmlMailCheck, SIGNAL( stateChanged( int ) ),
03527 this, SLOT( slotEmitChanged( void ) ) );
03528 mExternalReferences = new QCheckBox( i18n("Allow messages to load e&xternal "
03529 "references from the Internet" ), group );
03530 QWhatsThis::add( mExternalReferences, externalWhatsThis );
03531 connect( mExternalReferences, SIGNAL( stateChanged( int ) ),
03532 this, SLOT( slotEmitChanged( void ) ) );
03533 label = new KActiveLabel( i18n("<b>WARNING:</b> Allowing HTML in email may "
03534 "increase the risk that your system will be "
03535 "compromised by present and anticipated security "
03536 "exploits. <a href=\"whatsthis:%1\">More about "
03537 "HTML mails...</a> <a href=\"whatsthis:%2\">More "
03538 "about external references...</a>")
03539 .arg(htmlWhatsThis).arg(externalWhatsThis),
03540 group );
03541
03542 vlay->addWidget( group );
03543
03544
03545 group = new QVGroupBox( i18n("Message Disposition Notifications"), this );
03546 group->layout()->setSpacing( KDialog::spacingHint() );
03547
03548
03549
03550 mMDNGroup = new QButtonGroup( group );
03551 mMDNGroup->hide();
03552 connect( mMDNGroup, SIGNAL( clicked( int ) ),
03553 this, SLOT( slotEmitChanged( void ) ) );
03554 hbox = new QHBox( group );
03555 hbox->setSpacing( KDialog::spacingHint() );
03556
03557 (void)new QLabel( i18n("Send policy:"), hbox );
03558
03559 radio = new QRadioButton( i18n("&Ignore"), hbox );
03560 mMDNGroup->insert( radio );
03561
03562 radio = new QRadioButton( i18n("As&k"), hbox );
03563 mMDNGroup->insert( radio );
03564
03565 radio = new QRadioButton( i18n("&Deny"), hbox );
03566 mMDNGroup->insert( radio );
03567
03568 radio = new QRadioButton( i18n("Al&ways send"), hbox );
03569 mMDNGroup->insert( radio );
03570
03571 for ( int i = 0 ; i < mMDNGroup->count() ; ++i )
03572 QWhatsThis::add( mMDNGroup->find( i ), receiptWhatsThis );
03573
03574 w = new QWidget( hbox );
03575 hbox->setStretchFactor( w, 1 );
03576
03577
03578 mOrigQuoteGroup = new QButtonGroup( group );
03579 mOrigQuoteGroup->hide();
03580 connect( mOrigQuoteGroup, SIGNAL( clicked( int ) ),
03581 this, SLOT( slotEmitChanged( void ) ) );
03582
03583 hbox = new QHBox( group );
03584 hbox->setSpacing( KDialog::spacingHint() );
03585
03586 (void)new QLabel( i18n("Quote original message:"), hbox );
03587
03588 radio = new QRadioButton( i18n("Nothin&g"), hbox );
03589 mOrigQuoteGroup->insert( radio );
03590
03591 radio = new QRadioButton( i18n("&Full message"), hbox );
03592 mOrigQuoteGroup->insert( radio );
03593
03594 radio = new QRadioButton( i18n("Onl&y headers"), hbox );
03595 mOrigQuoteGroup->insert( radio );
03596
03597 w = new QWidget( hbox );
03598 hbox->setStretchFactor( w, 1 );
03599
03600 mNoMDNsWhenEncryptedCheck = new QCheckBox( i18n("Do not send MDNs in response to encrypted messages"), group );
03601 connect( mNoMDNsWhenEncryptedCheck, SIGNAL(toggled(bool)), SLOT(slotEmitChanged()) );
03602
03603
03604 label = new KActiveLabel( i18n("<b>WARNING:</b> Unconditionally returning "
03605 "confirmations undermines your privacy. "
03606 "<a href=\"whatsthis:%1\">More...</a>")
03607 .arg(receiptWhatsThis),
03608 group );
03609
03610 vlay->addWidget( group );
03611
03612
03613 group = new QVGroupBox( i18n( "Certificate && Key Bundle Attachments" ), this );
03614 group->layout()->setSpacing( KDialog::spacingHint() );
03615
03616 mAutomaticallyImportAttachedKeysCheck = new QCheckBox( i18n("Automatically import keys and certificates"), group );
03617 connect( mAutomaticallyImportAttachedKeysCheck, SIGNAL(toggled(bool)), SLOT(slotEmitChanged()) );
03618
03619 vlay->addWidget( group );
03620
03621
03622
03623 vlay->addStretch( 10 );
03624 }
03625
03626 void SecurityPage::GeneralTab::doLoadOther() {
03627 const KConfigGroup reader( KMKernel::config(), "Reader" );
03628
03629 mHtmlMailCheck->setChecked( reader.readBoolEntry( "htmlMail", false ) );
03630 mExternalReferences->setChecked( reader.readBoolEntry( "htmlLoadExternal", false ) );
03631 mAutomaticallyImportAttachedKeysCheck->setChecked( reader.readBoolEntry( "AutoImportKeys", false ) );
03632
03633 const KConfigGroup mdn( KMKernel::config(), "MDN" );
03634
03635 int num = mdn.readNumEntry( "default-policy", 0 );
03636 if ( num < 0 || num >= mMDNGroup->count() ) num = 0;
03637 mMDNGroup->setButton( num );
03638 num = mdn.readNumEntry( "quote-message", 0 );
03639 if ( num < 0 || num >= mOrigQuoteGroup->count() ) num = 0;
03640 mOrigQuoteGroup->setButton( num );
03641 mNoMDNsWhenEncryptedCheck->setChecked(mdn.readBoolEntry( "not-send-when-encrypted", true ));
03642 }
03643
03644 void SecurityPage::GeneralTab::installProfile( KConfig * profile ) {
03645 const KConfigGroup reader( profile, "Reader" );
03646 const KConfigGroup mdn( profile, "MDN" );
03647
03648 if ( reader.hasKey( "htmlMail" ) )
03649 mHtmlMailCheck->setChecked( reader.readBoolEntry( "htmlMail" ) );
03650 if ( reader.hasKey( "htmlLoadExternal" ) )
03651 mExternalReferences->setChecked( reader.readBoolEntry( "htmlLoadExternal" ) );
03652 if ( reader.hasKey( "AutoImportKeys" ) )
03653 mAutomaticallyImportAttachedKeysCheck->setChecked( reader.readBoolEntry( "AutoImportKeys" ) );
03654
03655 if ( mdn.hasKey( "default-policy" ) ) {
03656 int num = mdn.readNumEntry( "default-policy" );
03657 if ( num < 0 || num >= mMDNGroup->count() ) num = 0;
03658 mMDNGroup->setButton( num );
03659 }
03660 if ( mdn.hasKey( "quote-message" ) ) {
03661 int num = mdn.readNumEntry( "quote-message" );
03662 if ( num < 0 || num >= mOrigQuoteGroup->count() ) num = 0;
03663 mOrigQuoteGroup->setButton( num );
03664 }
03665 if ( mdn.hasKey( "not-send-when-encrypted" ) )
03666 mNoMDNsWhenEncryptedCheck->setChecked(mdn.readBoolEntry( "not-send-when-encrypted" ));
03667 }
03668
03669 void SecurityPage::GeneralTab::save() {
03670 KConfigGroup reader( KMKernel::config(), "Reader" );
03671 KConfigGroup mdn( KMKernel::config(), "MDN" );
03672
03673 if (reader.readBoolEntry( "htmlMail", false ) != mHtmlMailCheck->isChecked())
03674 {
03675 if (KMessageBox::warningContinueCancel(this, i18n("Changing the global "
03676 "HTML setting will override all folder specific values."), QString::null,
03677 KStdGuiItem::cont(), "htmlMailOverride") == KMessageBox::Continue)
03678 {
03679 reader.writeEntry( "htmlMail", mHtmlMailCheck->isChecked() );
03680 QStringList names;
03681 QValueList<QGuardedPtr<KMFolder> > folders;
03682 kmkernel->folderMgr()->createFolderList(&names, &folders);
03683 kmkernel->imapFolderMgr()->createFolderList(&names, &folders);
03684 kmkernel->dimapFolderMgr()->createFolderList(&names, &folders);
03685 kmkernel->searchFolderMgr()->createFolderList(&names, &folders);
03686 for (QValueList<QGuardedPtr<KMFolder> >::iterator it = folders.begin();
03687 it != folders.end(); ++it)
03688 {
03689 if (*it)
03690 {
03691 KConfigGroupSaver saver(KMKernel::config(),
03692 "Folder-" + (*it)->idString());
03693 KMKernel::config()->writeEntry("htmlMailOverride", false);
03694 }
03695 }
03696 }
03697 }
03698 reader.writeEntry( "htmlLoadExternal", mExternalReferences->isChecked() );
03699 reader.writeEntry( "AutoImportKeys", mAutomaticallyImportAttachedKeysCheck->isChecked() );
03700 mdn.writeEntry( "default-policy", mMDNGroup->id( mMDNGroup->selected() ) );
03701 mdn.writeEntry( "quote-message", mOrigQuoteGroup->id( mOrigQuoteGroup->selected() ) );
03702 mdn.writeEntry( "not-send-when-encrypted", mNoMDNsWhenEncryptedCheck->isChecked() );
03703 }
03704
03705
03706 QString SecurityPage::ComposerCryptoTab::helpAnchor() const {
03707 return QString::fromLatin1("configure-security-composing");
03708 }
03709
03710 SecurityPageComposerCryptoTab::SecurityPageComposerCryptoTab( QWidget * parent, const char * name )
03711 : ConfigModuleTab ( parent, name )
03712 {
03713
03714 QVBoxLayout* vlay = new QVBoxLayout( this, 0, 0 );
03715
03716 mWidget = new ComposerCryptoConfiguration( this );
03717 connect( mWidget->mAutoSignature, SIGNAL( toggled(bool) ), this, SLOT( slotEmitChanged() ) );
03718 connect( mWidget->mEncToSelf, SIGNAL( toggled(bool) ), this, SLOT( slotEmitChanged() ) );
03719 connect( mWidget->mShowEncryptionResult, SIGNAL( toggled(bool) ), this, SLOT( slotEmitChanged() ) );
03720 connect( mWidget->mShowKeyApprovalDlg, SIGNAL( toggled(bool) ), this, SLOT( slotEmitChanged() ) );
03721 connect( mWidget->mAutoEncrypt, SIGNAL( toggled(bool) ), this, SLOT( slotEmitChanged() ) );
03722 connect( mWidget->mNeverEncryptWhenSavingInDrafts, SIGNAL( toggled(bool) ), this, SLOT( slotEmitChanged() ) );
03723 connect( mWidget->mStoreEncrypted, SIGNAL( toggled(bool) ), this, SLOT( slotEmitChanged() ) );
03724 vlay->addWidget( mWidget );
03725 }
03726
03727 void SecurityPage::ComposerCryptoTab::doLoadOther() {
03728 const KConfigGroup composer( KMKernel::config(), "Composer" );
03729
03730
03731
03732 mWidget->mAutoSignature->setChecked( composer.readBoolEntry( "pgp-auto-sign", false ) );
03733
03734 mWidget->mEncToSelf->setChecked( composer.readBoolEntry( "crypto-encrypt-to-self", true ) );
03735 mWidget->mShowEncryptionResult->setChecked( false );
03736 mWidget->mShowEncryptionResult->hide();
03737 mWidget->mShowKeyApprovalDlg->setChecked( composer.readBoolEntry( "crypto-show-keys-for-approval", true ) );
03738
03739 mWidget->mAutoEncrypt->setChecked( composer.readBoolEntry( "pgp-auto-encrypt", false ) );
03740 mWidget->mNeverEncryptWhenSavingInDrafts->setChecked( composer.readBoolEntry( "never-encrypt-drafts", true ) );
03741
03742 mWidget->mStoreEncrypted->setChecked( composer.readBoolEntry( "crypto-store-encrypted", true ) );
03743 }
03744
03745 void SecurityPage::ComposerCryptoTab::installProfile( KConfig * profile ) {
03746 const KConfigGroup composer( profile, "Composer" );
03747
03748 if ( composer.hasKey( "pgp-auto-sign" ) )
03749 mWidget->mAutoSignature->setChecked( composer.readBoolEntry( "pgp-auto-sign" ) );
03750
03751 if ( composer.hasKey( "crypto-encrypt-to-self" ) )
03752 mWidget->mEncToSelf->setChecked( composer.readBoolEntry( "crypto-encrypt-to-self" ) );
03753 if ( composer.hasKey( "crypto-show-encryption-result" ) )
03754 mWidget->mShowEncryptionResult->setChecked( composer.readBoolEntry( "crypto-show-encryption-result" ) );
03755 if ( composer.hasKey( "crypto-show-keys-for-approval" ) )
03756 mWidget->mShowKeyApprovalDlg->setChecked( composer.readBoolEntry( "crypto-show-keys-for-approval" ) );
03757 if ( composer.hasKey( "pgp-auto-encrypt" ) )
03758 mWidget->mAutoEncrypt->setChecked( composer.readBoolEntry( "pgp-auto-encrypt" ) );
03759 if ( composer.hasKey( "never-encrypt-drafts" ) )
03760 mWidget->mNeverEncryptWhenSavingInDrafts->setChecked( composer.readBoolEntry( "never-encrypt-drafts" ) );
03761
03762 if ( composer.hasKey( "crypto-store-encrypted" ) )
03763 mWidget->mStoreEncrypted->setChecked( composer.readBoolEntry( "crypto-store-encrypted" ) );
03764 }
03765
03766 void SecurityPage::ComposerCryptoTab::save() {
03767 KConfigGroup composer( KMKernel::config(), "Composer" );
03768
03769 composer.writeEntry( "pgp-auto-sign", mWidget->mAutoSignature->isChecked() );
03770
03771 composer.writeEntry( "crypto-encrypt-to-self", mWidget->mEncToSelf->isChecked() );
03772 composer.writeEntry( "crypto-show-encryption-result", mWidget->mShowEncryptionResult->isChecked() );
03773 composer.writeEntry( "crypto-show-keys-for-approval", mWidget->mShowKeyApprovalDlg->isChecked() );
03774
03775 composer.writeEntry( "pgp-auto-encrypt", mWidget->mAutoEncrypt->isChecked() );
03776 composer.writeEntry( "never-encrypt-drafts", mWidget->mNeverEncryptWhenSavingInDrafts->isChecked() );
03777
03778 composer.writeEntry( "crypto-store-encrypted", mWidget->mStoreEncrypted->isChecked() );
03779 }
03780
03781 QString SecurityPage::WarningTab::helpAnchor() const {
03782 return QString::fromLatin1("configure-security-warnings");
03783 }
03784
03785 SecurityPageWarningTab::SecurityPageWarningTab( QWidget * parent, const char * name )
03786 : ConfigModuleTab( parent, name )
03787 {
03788
03789 QVBoxLayout* vlay = new QVBoxLayout( this, 0, 0 );
03790
03791 mWidget = new WarningConfiguration( this );
03792 vlay->addWidget( mWidget );
03793
03794 connect( mWidget->warnGroupBox, SIGNAL(toggled(bool)), SLOT(slotEmitChanged()) );
03795 connect( mWidget->mWarnUnsigned, SIGNAL(toggled(bool)), SLOT(slotEmitChanged()) );
03796 connect( mWidget->warnUnencryptedCB, SIGNAL(toggled(bool)), SLOT(slotEmitChanged()) );
03797 connect( mWidget->warnReceiverNotInCertificateCB, SIGNAL(toggled(bool)), SLOT(slotEmitChanged()) );
03798 connect( mWidget->mWarnSignKeyExpiresSB, SIGNAL( valueChanged( int ) ), SLOT( slotEmitChanged() ) );
03799 connect( mWidget->mWarnSignChainCertExpiresSB, SIGNAL( valueChanged( int ) ), SLOT( slotEmitChanged() ) );
03800 connect( mWidget->mWarnSignRootCertExpiresSB, SIGNAL( valueChanged( int ) ), SLOT( slotEmitChanged() ) );
03801
03802 connect( mWidget->mWarnEncrKeyExpiresSB, SIGNAL( valueChanged( int ) ), SLOT( slotEmitChanged() ) );
03803 connect( mWidget->mWarnEncrChainCertExpiresSB, SIGNAL( valueChanged( int ) ), SLOT( slotEmitChanged() ) );
03804 connect( mWidget->mWarnEncrRootCertExpiresSB, SIGNAL( valueChanged( int ) ), SLOT( slotEmitChanged() ) );
03805
03806 connect( mWidget->enableAllWarningsPB, SIGNAL(clicked()),
03807 SLOT(slotReenableAllWarningsClicked()) );
03808 }
03809
03810 void SecurityPage::WarningTab::doLoadOther() {
03811 const KConfigGroup composer( KMKernel::config(), "Composer" );
03812
03813 mWidget->warnUnencryptedCB->setChecked( composer.readBoolEntry( "crypto-warning-unencrypted", false ) );
03814 mWidget->mWarnUnsigned->setChecked( composer.readBoolEntry( "crypto-warning-unsigned", false ) );
03815 mWidget->warnReceiverNotInCertificateCB->setChecked( composer.readBoolEntry( "crypto-warn-recv-not-in-cert", true ) );
03816
03817
03818
03819 mWidget->warnGroupBox->setChecked( composer.readBoolEntry( "crypto-warn-when-near-expire", true ) );
03820
03821 mWidget->mWarnSignKeyExpiresSB->setValue( composer.readNumEntry( "crypto-warn-sign-key-near-expire-int", 14 ) );
03822 mWidget->mWarnSignChainCertExpiresSB->setValue( composer.readNumEntry( "crypto-warn-sign-chaincert-near-expire-int", 14 ) );
03823 mWidget->mWarnSignRootCertExpiresSB->setValue( composer.readNumEntry( "crypto-warn-sign-root-near-expire-int", 14 ) );
03824
03825 mWidget->mWarnEncrKeyExpiresSB->setValue( composer.readNumEntry( "crypto-warn-encr-key-near-expire-int", 14 ) );
03826 mWidget->mWarnEncrChainCertExpiresSB->setValue( composer.readNumEntry( "crypto-warn-encr-chaincert-near-expire-int", 14 ) );
03827 mWidget->mWarnEncrRootCertExpiresSB->setValue( composer.readNumEntry( "crypto-warn-encr-root-near-expire-int", 14 ) );
03828
03829 mWidget->enableAllWarningsPB->setEnabled( true );
03830 }
03831
03832 void SecurityPage::WarningTab::installProfile( KConfig * profile ) {
03833 const KConfigGroup composer( profile, "Composer" );
03834
03835 if ( composer.hasKey( "crypto-warning-unencrypted" ) )
03836 mWidget->warnUnencryptedCB->setChecked( composer.readBoolEntry( "crypto-warning-unencrypted" ) );
03837 if ( composer.hasKey( "crypto-warning-unsigned" ) )
03838 mWidget->mWarnUnsigned->setChecked( composer.readBoolEntry( "crypto-warning-unsigned" ) );
03839 if ( composer.hasKey( "crypto-warn-recv-not-in-cert" ) )
03840 mWidget->warnReceiverNotInCertificateCB->setChecked( composer.readBoolEntry( "crypto-warn-recv-not-in-cert" ) );
03841
03842 if ( composer.hasKey( "crypto-warn-when-near-expire" ) )
03843 mWidget->warnGroupBox->setChecked( composer.readBoolEntry( "crypto-warn-when-near-expire" ) );
03844
03845 if ( composer.hasKey( "crypto-warn-sign-key-near-expire-int" ) )
03846 mWidget->mWarnSignKeyExpiresSB->setValue( composer.readNumEntry( "crypto-warn-sign-key-near-expire-int" ) );
03847 if ( composer.hasKey( "crypto-warn-sign-chaincert-near-expire-int" ) )
03848 mWidget->mWarnSignChainCertExpiresSB->setValue( composer.readNumEntry( "crypto-warn-sign-chaincert-near-expire-int" ) );
03849 if ( composer.hasKey( "crypto-warn-sign-root-near-expire-int" ) )
03850 mWidget->mWarnSignRootCertExpiresSB->setValue( composer.readNumEntry( "crypto-warn-sign-root-near-expire-int" ) );
03851
03852 if ( composer.hasKey( "crypto-warn-encr-key-near-expire-int" ) )
03853 mWidget->mWarnEncrKeyExpiresSB->setValue( composer.readNumEntry( "crypto-warn-encr-key-near-expire-int" ) );
03854 if ( composer.hasKey( "crypto-warn-encr-chaincert-near-expire-int" ) )
03855 mWidget->mWarnEncrChainCertExpiresSB->setValue( composer.readNumEntry( "crypto-warn-encr-chaincert-near-expire-int" ) );
03856 if ( composer.hasKey( "crypto-warn-encr-root-near-expire-int" ) )
03857 mWidget->mWarnEncrRootCertExpiresSB->setValue( composer.readNumEntry( "crypto-warn-encr-root-near-expire-int" ) );
03858 }
03859
03860 void SecurityPage::WarningTab::save() {
03861 KConfigGroup composer( KMKernel::config(), "Composer" );
03862
03863 composer.writeEntry( "crypto-warn-recv-not-in-cert", mWidget->warnReceiverNotInCertificateCB->isChecked() );
03864 composer.writeEntry( "crypto-warning-unencrypted", mWidget->warnUnencryptedCB->isChecked() );
03865 composer.writeEntry( "crypto-warning-unsigned", mWidget->mWarnUnsigned->isChecked() );
03866
03867 composer.writeEntry( "crypto-warn-when-near-expire", mWidget->warnGroupBox->isChecked() );
03868 composer.writeEntry( "crypto-warn-sign-key-near-expire-int",
03869 mWidget->mWarnSignKeyExpiresSB->value() );
03870 composer.writeEntry( "crypto-warn-sign-chaincert-near-expire-int",
03871 mWidget->mWarnSignChainCertExpiresSB->value() );
03872 composer.writeEntry( "crypto-warn-sign-root-near-expire-int",
03873 mWidget->mWarnSignRootCertExpiresSB->value() );
03874
03875 composer.writeEntry( "crypto-warn-encr-key-near-expire-int",
03876 mWidget->mWarnEncrKeyExpiresSB->value() );
03877 composer.writeEntry( "crypto-warn-encr-chaincert-near-expire-int",
03878 mWidget->mWarnEncrChainCertExpiresSB->value() );
03879 composer.writeEntry( "crypto-warn-encr-root-near-expire-int",
03880 mWidget->mWarnEncrRootCertExpiresSB->value() );
03881 }
03882
03883 void SecurityPage::WarningTab::slotReenableAllWarningsClicked() {
03884 KMessageBox::enableAllMessages();
03885 mWidget->enableAllWarningsPB->setEnabled( false );
03886 }
03887
03889
03890 QString SecurityPage::SMimeTab::helpAnchor() const {
03891 return QString::fromLatin1("configure-security-smime-validation");
03892 }
03893
03894 SecurityPageSMimeTab::SecurityPageSMimeTab( QWidget * parent, const char * name )
03895 : ConfigModuleTab( parent, name )
03896 {
03897
03898 QVBoxLayout* vlay = new QVBoxLayout( this, 0, 0 );
03899
03900 mWidget = new SMimeConfiguration( this );
03901 vlay->addWidget( mWidget );
03902
03903
03904 QButtonGroup* bg = new QButtonGroup( mWidget );
03905 bg->hide();
03906 bg->insert( mWidget->CRLRB );
03907 bg->insert( mWidget->OCSPRB );
03908
03909
03910 mWidget->OCSPResponderSignature->setAllowedKeys(
03911 Kleo::KeySelectionDialog::SMIMEKeys
03912 | Kleo::KeySelectionDialog::TrustedKeys
03913 | Kleo::KeySelectionDialog::ValidKeys
03914 | Kleo::KeySelectionDialog::SigningKeys
03915 | Kleo::KeySelectionDialog::PublicKeys );
03916 mWidget->OCSPResponderSignature->setMultipleKeysEnabled( false );
03917
03918 mConfig = Kleo::CryptoBackendFactory::instance()->config();
03919
03920 connect( mWidget->CRLRB, SIGNAL( toggled( bool ) ), this, SLOT( slotEmitChanged() ) );
03921 connect( mWidget->OCSPRB, SIGNAL( toggled( bool ) ), this, SLOT( slotEmitChanged() ) );
03922 connect( mWidget->OCSPResponderURL, SIGNAL( textChanged( const QString& ) ), this, SLOT( slotEmitChanged() ) );
03923 connect( mWidget->OCSPResponderSignature, SIGNAL( changed() ), this, SLOT( slotEmitChanged() ) );
03924 connect( mWidget->doNotCheckCertPolicyCB, SIGNAL( toggled( bool ) ), this, SLOT( slotEmitChanged() ) );
03925 connect( mWidget->neverConsultCB, SIGNAL( toggled( bool ) ), this, SLOT( slotEmitChanged() ) );
03926 connect( mWidget->fetchMissingCB, SIGNAL( toggled( bool ) ), this, SLOT( slotEmitChanged() ) );
03927
03928 connect( mWidget->ignoreServiceURLCB, SIGNAL( toggled( bool ) ), this, SLOT( slotEmitChanged() ) );
03929 connect( mWidget->ignoreHTTPDPCB, SIGNAL( toggled( bool ) ), this, SLOT( slotEmitChanged() ) );
03930 connect( mWidget->disableHTTPCB, SIGNAL( toggled( bool ) ), this, SLOT( slotEmitChanged() ) );
03931 connect( mWidget->honorHTTPProxyRB, SIGNAL( toggled( bool ) ), this, SLOT( slotEmitChanged() ) );
03932 connect( mWidget->useCustomHTTPProxyRB, SIGNAL( toggled( bool ) ), this, SLOT( slotEmitChanged() ) );
03933 connect( mWidget->customHTTPProxy, SIGNAL( textChanged( const QString& ) ), this, SLOT( slotEmitChanged() ) );
03934 connect( mWidget->ignoreLDAPDPCB, SIGNAL( toggled( bool ) ), this, SLOT( slotEmitChanged() ) );
03935 connect( mWidget->disableLDAPCB, SIGNAL( toggled( bool ) ), this, SLOT( slotEmitChanged() ) );
03936 connect( mWidget->customLDAPProxy, SIGNAL( textChanged( const QString& ) ), this, SLOT( slotEmitChanged() ) );
03937
03938 connect( mWidget->disableHTTPCB, SIGNAL( toggled( bool ) ),
03939 this, SLOT( slotUpdateHTTPActions() ) );
03940 connect( mWidget->ignoreHTTPDPCB, SIGNAL( toggled( bool ) ),
03941 this, SLOT( slotUpdateHTTPActions() ) );
03942
03943
03944 QButtonGroup* bgHTTPProxy = new QButtonGroup( mWidget );
03945 bgHTTPProxy->hide();
03946 bgHTTPProxy->insert( mWidget->honorHTTPProxyRB );
03947 bgHTTPProxy->insert( mWidget->useCustomHTTPProxyRB );
03948
03949 if ( !connectDCOPSignal( 0, "KPIM::CryptoConfig", "changed()",
03950 "load()", false ) )
03951 kdError(5650) << "SecurityPageSMimeTab: connection to CryptoConfig's changed() failed" << endl;
03952
03953 }
03954
03955 SecurityPageSMimeTab::~SecurityPageSMimeTab()
03956 {
03957 }
03958
03959 static void disableDirmngrWidget( QWidget* w ) {
03960 w->setEnabled( false );
03961 QWhatsThis::remove( w );
03962 QWhatsThis::add( w, i18n( "This option requires dirmngr >= 0.9.0" ) );
03963 }
03964
03965 static void initializeDirmngrCheckbox( QCheckBox* cb, Kleo::CryptoConfigEntry* entry ) {
03966 if ( entry )
03967 cb->setChecked( entry->boolValue() );
03968 else
03969 disableDirmngrWidget( cb );
03970 }
03971
03972 struct SMIMECryptoConfigEntries {
03973 SMIMECryptoConfigEntries( Kleo::CryptoConfig* config )
03974 : mConfig( config ) {
03975
03976
03977 mCheckUsingOCSPConfigEntry = configEntry( "gpgsm", "Security", "enable-ocsp", Kleo::CryptoConfigEntry::ArgType_None, false );
03978 mEnableOCSPsendingConfigEntry = configEntry( "dirmngr", "OCSP", "allow-ocsp", Kleo::CryptoConfigEntry::ArgType_None, false );
03979 mDoNotCheckCertPolicyConfigEntry = configEntry( "gpgsm", "Security", "disable-policy-checks", Kleo::CryptoConfigEntry::ArgType_None, false );
03980 mNeverConsultConfigEntry = configEntry( "gpgsm", "Security", "disable-crl-checks", Kleo::CryptoConfigEntry::ArgType_None, false );
03981 mFetchMissingConfigEntry = configEntry( "gpgsm", "Security", "auto-issuer-key-retrieve", Kleo::CryptoConfigEntry::ArgType_None, false );
03982
03983 mIgnoreServiceURLEntry = configEntry( "dirmngr", "OCSP", "ignore-ocsp-service-url", Kleo::CryptoConfigEntry::ArgType_None, false );
03984 mIgnoreHTTPDPEntry = configEntry( "dirmngr", "HTTP", "ignore-http-dp", Kleo::CryptoConfigEntry::ArgType_None, false );
03985 mDisableHTTPEntry = configEntry( "dirmngr", "HTTP", "disable-http", Kleo::CryptoConfigEntry::ArgType_None, false );
03986 mHonorHTTPProxy = configEntry( "dirmngr", "HTTP", "honor-http-proxy", Kleo::CryptoConfigEntry::ArgType_None, false );
03987
03988 mIgnoreLDAPDPEntry = configEntry( "dirmngr", "LDAP", "ignore-ldap-dp", Kleo::CryptoConfigEntry::ArgType_None, false );
03989 mDisableLDAPEntry = configEntry( "dirmngr", "LDAP", "disable-ldap", Kleo::CryptoConfigEntry::ArgType_None, false );
03990
03991 mOCSPResponderURLConfigEntry = configEntry( "dirmngr", "OCSP", "ocsp-responder", Kleo::CryptoConfigEntry::ArgType_String, false );
03992 mOCSPResponderSignature = configEntry( "dirmngr", "OCSP", "ocsp-signer", Kleo::CryptoConfigEntry::ArgType_String, false );
03993 mCustomHTTPProxy = configEntry( "dirmngr", "HTTP", "http-proxy", Kleo::CryptoConfigEntry::ArgType_String, false );
03994 mCustomLDAPProxy = configEntry( "dirmngr", "LDAP", "ldap-proxy", Kleo::CryptoConfigEntry::ArgType_String, false );
03995 }
03996
03997 Kleo::CryptoConfigEntry* configEntry( const char* componentName,
03998 const char* groupName,
03999 const char* entryName,
04000 int argType,
04001 bool isList );
04002
04003
04004 Kleo::CryptoConfigEntry* mCheckUsingOCSPConfigEntry;
04005 Kleo::CryptoConfigEntry* mEnableOCSPsendingConfigEntry;
04006 Kleo::CryptoConfigEntry* mDoNotCheckCertPolicyConfigEntry;
04007 Kleo::CryptoConfigEntry* mNeverConsultConfigEntry;
04008 Kleo::CryptoConfigEntry* mFetchMissingConfigEntry;
04009 Kleo::CryptoConfigEntry* mIgnoreServiceURLEntry;
04010 Kleo::CryptoConfigEntry* mIgnoreHTTPDPEntry;
04011 Kleo::CryptoConfigEntry* mDisableHTTPEntry;
04012 Kleo::CryptoConfigEntry* mHonorHTTPProxy;
04013 Kleo::CryptoConfigEntry* mIgnoreLDAPDPEntry;
04014 Kleo::CryptoConfigEntry* mDisableLDAPEntry;
04015
04016 Kleo::CryptoConfigEntry* mOCSPResponderURLConfigEntry;
04017 Kleo::CryptoConfigEntry* mOCSPResponderSignature;
04018 Kleo::CryptoConfigEntry* mCustomHTTPProxy;
04019 Kleo::CryptoConfigEntry* mCustomLDAPProxy;
04020
04021 Kleo::CryptoConfig* mConfig;
04022 };
04023
04024 void SecurityPage::SMimeTab::doLoadOther() {
04025 if ( !mConfig ) {
04026 setEnabled( false );
04027 return;
04028 }
04029
04030
04031
04032 mConfig->clear();
04033
04034
04035
04036
04037 SMIMECryptoConfigEntries e( mConfig );
04038
04039
04040
04041 if ( e.mCheckUsingOCSPConfigEntry ) {
04042 bool b = e.mCheckUsingOCSPConfigEntry->boolValue();
04043 mWidget->OCSPRB->setChecked( b );
04044 mWidget->CRLRB->setChecked( !b );
04045 mWidget->OCSPGroupBox->setEnabled( b );
04046 } else {
04047 mWidget->OCSPGroupBox->setEnabled( false );
04048 }
04049 if ( e.mDoNotCheckCertPolicyConfigEntry )
04050 mWidget->doNotCheckCertPolicyCB->setChecked( e.mDoNotCheckCertPolicyConfigEntry->boolValue() );
04051 if ( e.mNeverConsultConfigEntry )
04052 mWidget->neverConsultCB->setChecked( e.mNeverConsultConfigEntry->boolValue() );
04053 if ( e.mFetchMissingConfigEntry )
04054 mWidget->fetchMissingCB->setChecked( e.mFetchMissingConfigEntry->boolValue() );
04055
04056 if ( e.mOCSPResponderURLConfigEntry )
04057 mWidget->OCSPResponderURL->setText( e.mOCSPResponderURLConfigEntry->stringValue() );
04058 if ( e.mOCSPResponderSignature ) {
04059 mWidget->OCSPResponderSignature->setFingerprint( e.mOCSPResponderSignature->stringValue() );
04060 }
04061
04062
04063 initializeDirmngrCheckbox( mWidget->ignoreServiceURLCB, e.mIgnoreServiceURLEntry );
04064 initializeDirmngrCheckbox( mWidget->ignoreHTTPDPCB, e.mIgnoreHTTPDPEntry );
04065 initializeDirmngrCheckbox( mWidget->disableHTTPCB, e.mDisableHTTPEntry );
04066 initializeDirmngrCheckbox( mWidget->ignoreLDAPDPCB, e.mIgnoreLDAPDPEntry );
04067 initializeDirmngrCheckbox( mWidget->disableLDAPCB, e.mDisableLDAPEntry );
04068 if ( e.mCustomHTTPProxy ) {
04069 QString systemProxy = QString::fromLocal8Bit( getenv( "http_proxy" ) );
04070 if ( systemProxy.isEmpty() )
04071 systemProxy = i18n( "no proxy" );
04072 mWidget->systemHTTPProxy->setText( i18n( "(Current system setting: %1)" ).arg( systemProxy ) );
04073 bool honor = e.mHonorHTTPProxy && e.mHonorHTTPProxy->boolValue();
04074 mWidget->honorHTTPProxyRB->setChecked( honor );
04075 mWidget->useCustomHTTPProxyRB->setChecked( !honor );
04076 mWidget->customHTTPProxy->setText( e.mCustomHTTPProxy->stringValue() );
04077 } else {
04078 disableDirmngrWidget( mWidget->honorHTTPProxyRB );
04079 disableDirmngrWidget( mWidget->useCustomHTTPProxyRB );
04080 disableDirmngrWidget( mWidget->systemHTTPProxy );
04081 disableDirmngrWidget( mWidget->customHTTPProxy );
04082 }
04083 if ( e.mCustomLDAPProxy )
04084 mWidget->customLDAPProxy->setText( e.mCustomLDAPProxy->stringValue() );
04085 else {
04086 disableDirmngrWidget( mWidget->customLDAPProxy );
04087 disableDirmngrWidget( mWidget->customLDAPLabel );
04088 }
04089 slotUpdateHTTPActions();
04090 }
04091
04092 void SecurityPage::SMimeTab::slotUpdateHTTPActions() {
04093 mWidget->ignoreHTTPDPCB->setEnabled( !mWidget->disableHTTPCB->isChecked() );
04094
04095
04096 bool enableProxySettings = !mWidget->disableHTTPCB->isChecked()
04097 && mWidget->ignoreHTTPDPCB->isChecked();
04098 mWidget->systemHTTPProxy->setEnabled( enableProxySettings );
04099 mWidget->useCustomHTTPProxyRB->setEnabled( enableProxySettings );
04100 mWidget->honorHTTPProxyRB->setEnabled( enableProxySettings );
04101 mWidget->customHTTPProxy->setEnabled( enableProxySettings );
04102 }
04103
04104 void SecurityPage::SMimeTab::installProfile( KConfig * ) {
04105 }
04106
04107 static void saveCheckBoxToKleoEntry( QCheckBox* cb, Kleo::CryptoConfigEntry* entry ) {
04108 const bool b = cb->isChecked();
04109 if ( entry && entry->boolValue() != b )
04110 entry->setBoolValue( b );
04111 }
04112
04113 void SecurityPage::SMimeTab::save() {
04114 if ( !mConfig ) {
04115 return;
04116 }
04117
04118
04119
04120 SMIMECryptoConfigEntries e( mConfig );
04121
04122 bool b = mWidget->OCSPRB->isChecked();
04123 if ( e.mCheckUsingOCSPConfigEntry && e.mCheckUsingOCSPConfigEntry->boolValue() != b )
04124 e.mCheckUsingOCSPConfigEntry->setBoolValue( b );
04125
04126 if ( e.mEnableOCSPsendingConfigEntry && e.mEnableOCSPsendingConfigEntry->boolValue() != b )
04127 e.mEnableOCSPsendingConfigEntry->setBoolValue( b );
04128
04129 saveCheckBoxToKleoEntry( mWidget->doNotCheckCertPolicyCB, e.mDoNotCheckCertPolicyConfigEntry );
04130 saveCheckBoxToKleoEntry( mWidget->neverConsultCB, e.mNeverConsultConfigEntry );
04131 saveCheckBoxToKleoEntry( mWidget->fetchMissingCB, e.mFetchMissingConfigEntry );
04132
04133 QString txt = mWidget->OCSPResponderURL->text();
04134 if ( e.mOCSPResponderURLConfigEntry && e.mOCSPResponderURLConfigEntry->stringValue() != txt )
04135 e.mOCSPResponderURLConfigEntry->setStringValue( txt );
04136
04137 txt = mWidget->OCSPResponderSignature->fingerprint();
04138 if ( e.mOCSPResponderSignature && e.mOCSPResponderSignature->stringValue() != txt ) {
04139 e.mOCSPResponderSignature->setStringValue( txt );
04140 }
04141
04142
04143 saveCheckBoxToKleoEntry( mWidget->ignoreServiceURLCB, e.mIgnoreServiceURLEntry );
04144 saveCheckBoxToKleoEntry( mWidget->ignoreHTTPDPCB, e.mIgnoreHTTPDPEntry );
04145 saveCheckBoxToKleoEntry( mWidget->disableHTTPCB, e.mDisableHTTPEntry );
04146 saveCheckBoxToKleoEntry( mWidget->ignoreLDAPDPCB, e.mIgnoreLDAPDPEntry );
04147 saveCheckBoxToKleoEntry( mWidget->disableLDAPCB, e.mDisableLDAPEntry );
04148 if ( e.mCustomHTTPProxy ) {
04149 const bool honor = mWidget->honorHTTPProxyRB->isChecked();
04150 if ( e.mHonorHTTPProxy && e.mHonorHTTPProxy->boolValue() != honor )
04151 e.mHonorHTTPProxy->setBoolValue( honor );
04152
04153 QString chosenProxy = mWidget->customHTTPProxy->text();
04154 if ( chosenProxy != e.mCustomHTTPProxy->stringValue() )
04155 e.mCustomHTTPProxy->setStringValue( chosenProxy );
04156 }
04157 txt = mWidget->customLDAPProxy->text();
04158 if ( e.mCustomLDAPProxy && e.mCustomLDAPProxy->stringValue() != txt )
04159 e.mCustomLDAPProxy->setStringValue( mWidget->customLDAPProxy->text() );
04160
04161 mConfig->sync( true );
04162 }
04163
04164 bool SecurityPageSMimeTab::process(const QCString &fun, const QByteArray &data, QCString& replyType, QByteArray &replyData)
04165 {
04166 if ( fun == "load()" ) {
04167 replyType = "void";
04168 load();
04169 } else {
04170 return DCOPObject::process( fun, data, replyType, replyData );
04171 }
04172 return true;
04173 }
04174
04175 QCStringList SecurityPageSMimeTab::interfaces()
04176 {
04177 QCStringList ifaces = DCOPObject::interfaces();
04178 ifaces += "SecurityPageSMimeTab";
04179 return ifaces;
04180 }
04181
04182 QCStringList SecurityPageSMimeTab::functions()
04183 {
04184
04185 return DCOPObject::functions();
04186 }
04187
04188 Kleo::CryptoConfigEntry* SMIMECryptoConfigEntries::configEntry( const char* componentName,
04189 const char* groupName,
04190 const char* entryName,
04191 int argType,
04192 bool isList )
04193 {
04194 Kleo::CryptoConfigEntry* entry = mConfig->entry( componentName, groupName, entryName );
04195 if ( !entry ) {
04196 kdWarning(5006) << QString( "Backend error: gpgconf doesn't seem to know the entry for %1/%2/%3" ).arg( componentName, groupName, entryName ) << endl;
04197 return 0;
04198 }
04199 if( entry->argType() != argType || entry->isList() != isList ) {
04200 kdWarning(5006) << QString( "Backend error: gpgconf has wrong type for %1/%2/%3: %4 %5" ).arg( componentName, groupName, entryName ).arg( entry->argType() ).arg( entry->isList() ) << endl;
04201 return 0;
04202 }
04203 return entry;
04204 }
04205
04207
04208 QString SecurityPage::CryptPlugTab::helpAnchor() const {
04209 return QString::fromLatin1("configure-security-crypto-backends");
04210 }
04211
04212 SecurityPageCryptPlugTab::SecurityPageCryptPlugTab( QWidget * parent, const char * name )
04213 : ConfigModuleTab( parent, name )
04214 {
04215 QVBoxLayout * vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
04216
04217 mBackendConfig = Kleo::CryptoBackendFactory::instance()->configWidget( this, "mBackendConfig" );
04218 connect( mBackendConfig, SIGNAL( changed( bool ) ), this, SIGNAL( changed( bool ) ) );
04219
04220 vlay->addWidget( mBackendConfig );
04221 }
04222
04223 SecurityPageCryptPlugTab::~SecurityPageCryptPlugTab()
04224 {
04225
04226 }
04227
04228 void SecurityPage::CryptPlugTab::doLoadOther() {
04229 mBackendConfig->load();
04230 }
04231
04232 void SecurityPage::CryptPlugTab::save() {
04233 mBackendConfig->save();
04234 }
04235
04236
04237
04238
04239
04240
04241 QString MiscPage::helpAnchor() const {
04242 return QString::fromLatin1("configure-misc");
04243 }
04244
04245 MiscPage::MiscPage( QWidget * parent, const char * name )
04246 : ConfigModuleWithTabs( parent, name )
04247 {
04248 mFolderTab = new FolderTab();
04249 addTab( mFolderTab, i18n("&Folders") );
04250
04251 mGroupwareTab = new GroupwareTab();
04252 addTab( mGroupwareTab, i18n("&Groupware") );
04253 load();
04254 }
04255
04256 QString MiscPage::FolderTab::helpAnchor() const {
04257 return QString::fromLatin1("configure-misc-folders");
04258 }
04259
04260 MiscPageFolderTab::MiscPageFolderTab( QWidget * parent, const char * name )
04261 : ConfigModuleTab( parent, name )
04262 {
04263
04264 QVBoxLayout *vlay;
04265 QHBoxLayout *hlay;
04266 QLabel *label;
04267
04268 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
04269
04270
04271 mEmptyFolderConfirmCheck =
04272 new QCheckBox( i18n("Corresponds to Folder->Move All Messages to Trash",
04273 "Ask for co&nfirmation before moving all messages to "
04274 "trash"),
04275 this );
04276 vlay->addWidget( mEmptyFolderConfirmCheck );
04277 connect( mEmptyFolderConfirmCheck, SIGNAL( stateChanged( int ) ),
04278 this, SLOT( slotEmitChanged( void ) ) );
04279 mExcludeImportantFromExpiry =
04280 new QCheckBox( i18n("E&xclude important messages from expiry"), this );
04281 vlay->addWidget( mExcludeImportantFromExpiry );
04282 connect( mExcludeImportantFromExpiry, SIGNAL( stateChanged( int ) ),
04283 this, SLOT( slotEmitChanged( void ) ) );
04284
04285
04286 hlay = new QHBoxLayout( vlay );
04287 mLoopOnGotoUnread = new QComboBox( false, this );
04288 label = new QLabel( mLoopOnGotoUnread,
04289 i18n("to be continued with \"do not loop\", \"loop in current folder\", "
04290 "and \"loop in all folders\".",
04291 "When trying to find unread messages:"), this );
04292 mLoopOnGotoUnread->insertStringList( QStringList()
04293 << i18n("continuation of \"When trying to find unread messages:\"",
04294 "Do not Loop")
04295 << i18n("continuation of \"When trying to find unread messages:\"",
04296 "Loop in Current Folder")
04297 << i18n("continuation of \"When trying to find unread messages:\"",
04298 "Loop in All Folders"));
04299 hlay->addWidget( label );
04300 hlay->addWidget( mLoopOnGotoUnread, 1 );
04301 connect( mLoopOnGotoUnread, SIGNAL( activated( int ) ),
04302 this, SLOT( slotEmitChanged( void ) ) );
04303
04304
04305 hlay = new QHBoxLayout( vlay );
04306 mActionEnterFolder = new QComboBox( false, this );
04307 label = new QLabel( mActionEnterFolder,
04308 i18n("to be continued with \"jump to first new message\", "
04309 "\"jump to first unread or new message\","
04310 "and \"jump to last selected message\".",
04311 "When entering a folder:"), this );
04312 mActionEnterFolder->insertStringList( QStringList()
04313 << i18n("continuation of \"When entering a folder:\"",
04314 "Jump to First New Message")
04315 << i18n("continuation of \"When entering a folder:\"",
04316 "Jump to First Unread or New Message")
04317 << i18n("continuation of \"When entering a folder:\"",
04318 "Jump to Last Selected Message"));
04319 hlay->addWidget( label );
04320 hlay->addWidget( mActionEnterFolder, 1 );
04321 connect( mActionEnterFolder, SIGNAL( activated( int ) ),
04322 this, SLOT( slotEmitChanged( void ) ) );
04323
04324 hlay = new QHBoxLayout( vlay );
04325 mDelayedMarkAsRead = new QCheckBox( i18n("Mar&k selected message as read after"), this );
04326 hlay->addWidget( mDelayedMarkAsRead );
04327 mDelayedMarkTime = new KIntSpinBox( 0 , 60 , 1,
04328 0 , 10 , this);
04329 mDelayedMarkTime->setSuffix( i18n(" sec") );
04330 mDelayedMarkTime->setEnabled( false );
04331 hlay->addWidget( mDelayedMarkTime );
04332 hlay->addStretch( 1 );
04333 connect( mDelayedMarkTime, SIGNAL( valueChanged( int ) ),
04334 this, SLOT( slotEmitChanged( void ) ) );
04335 connect( mDelayedMarkAsRead, SIGNAL(toggled(bool)),
04336 mDelayedMarkTime, SLOT(setEnabled(bool)));
04337 connect( mDelayedMarkAsRead, SIGNAL(toggled(bool)),
04338 this , SLOT(slotEmitChanged( void )));
04339
04340
04341 mShowPopupAfterDnD =
04342 new QCheckBox( i18n("Ask for action after &dragging messages to another folder"), this );
04343 vlay->addWidget( mShowPopupAfterDnD );
04344 connect( mShowPopupAfterDnD, SIGNAL( stateChanged( int ) ),
04345 this, SLOT( slotEmitChanged( void ) ) );
04346
04347
04348 hlay = new QHBoxLayout( vlay );
04349 mMailboxPrefCombo = new QComboBox( false, this );
04350 label = new QLabel( mMailboxPrefCombo,
04351 i18n("to be continued with \"flat files\" and "
04352 "\"directories\", resp.",
04353 "By default, &message folders on disk are:"), this );
04354 mMailboxPrefCombo->insertStringList( QStringList()
04355 << i18n("continuation of \"By default, &message folders on disk are\"",
04356 "Flat Files (\"mbox\" format)")
04357 << i18n("continuation of \"By default, &message folders on disk are\"",
04358 "Directories (\"maildir\" format)") );
04359 hlay->addWidget( label );
04360 hlay->addWidget( mMailboxPrefCombo, 1 );
04361 connect( mMailboxPrefCombo, SIGNAL( activated( int ) ),
04362 this, SLOT( slotEmitChanged( void ) ) );
04363
04364
04365 hlay = new QHBoxLayout( vlay );
04366 mOnStartupOpenFolder = new FolderRequester( this,
04367 kmkernel->getKMMainWidget()->folderTree() );
04368 label = new QLabel( mOnStartupOpenFolder,
04369 i18n("Open this folder on startup:"), this );
04370 hlay->addWidget( label );
04371 hlay->addWidget( mOnStartupOpenFolder, 1 );
04372 connect( mOnStartupOpenFolder, SIGNAL( folderChanged( KMFolder* ) ),
04373 this, SLOT( slotEmitChanged( void ) ) );
04374
04375
04376 mEmptyTrashCheck = new QCheckBox( i18n("Empty local &trash folder on program exit"),
04377 this );
04378 vlay->addWidget( mEmptyTrashCheck );
04379 connect( mEmptyTrashCheck, SIGNAL( stateChanged( int ) ),
04380 this, SLOT( slotEmitChanged( void ) ) );
04381
04382 #ifdef HAVE_INDEXLIB
04383
04384 mIndexingEnabled = new QCheckBox( i18n("Enable full text &indexing"), this );
04385 vlay->addWidget( mIndexingEnabled );
04386 connect( mIndexingEnabled, SIGNAL( stateChanged( int ) ),
04387 this, SLOT( slotEmitChanged( void ) ) );
04388 #endif
04389
04390
04391
04392 vlay->addStretch( 1 );
04393
04394
04395 QString msg = i18n( "what's this help",
04396 "<qt><p>This selects which mailbox format will be "
04397 "the default for local folders:</p>"
04398 "<p><b>mbox:</b> KMail's mail "
04399 "folders are represented by a single file each. "
04400 "Individual messages are separated from each other by a "
04401 "line starting with \"From \". This saves space on "
04402 "disk, but may be less robust, e.g. when moving messages "
04403 "between folders.</p>"
04404 "<p><b>maildir:</b> KMail's mail folders are "
04405 "represented by real folders on disk. Individual messages "
04406 "are separate files. This may waste a bit of space on "
04407 "disk, but should be more robust, e.g. when moving "
04408 "messages between folders.</p></qt>");
04409 QWhatsThis::add( mMailboxPrefCombo, msg );
04410 QWhatsThis::add( label, msg );
04411
04412 msg = i18n( "what's this help",
04413 "<qt><p>When jumping to the next unread message, it may occur "
04414 "that no more unread messages are below the current message.</p>"
04415 "<p><b>Do not loop:</b> The search will stop at the last message in "
04416 "the current folder.</p>"
04417 "<p><b>Loop in current folder:</b> The search will continue at the "
04418 "top of the message list, but not go to another folder.</p>"
04419 "<p><b>Loop in all folders:</b> The search will continue at the top of "
04420 "the message list. If no unread messages are found it will then continue "
04421 "to the next folder.</p>"
04422 "<p>Similarly, when searching for the previous unread message, "
04423 "the search will start from the bottom of the message list and continue to "
04424 "the previous folder depending on which option is selected.</p></qt>" );
04425 QWhatsThis::add( mLoopOnGotoUnread, msg );
04426
04427 #ifdef HAVE_INDEXLIB
04428
04429 msg = i18n( "what's this help",
04430 "<qt><p>Full text indexing allows very fast searches on the content "
04431 "of your messages. When enabled, the search dialog will work very fast. "
04432 "Also, the search tool bar will select messages based on content.</p>"
04433 "<p>It takes up a certain amount of disk space "
04434 "(about half the disk space for the messages).</p>"
04435 "<p>After enabling, the index will need to be built, but you can continue to use KMail "
04436 "while this operation is running.</p>"
04437 "</qt>"
04438 );
04439
04440 QWhatsThis::add( mIndexingEnabled, msg );
04441 #endif
04442 }
04443
04444 void MiscPage::FolderTab::doLoadFromGlobalSettings() {
04445 mExcludeImportantFromExpiry->setChecked( GlobalSettings::self()->excludeImportantMailFromExpiry() );
04446
04447 mLoopOnGotoUnread->setCurrentItem( GlobalSettings::self()->loopOnGotoUnread() );
04448 mActionEnterFolder->setCurrentItem( GlobalSettings::self()->actionEnterFolder() );
04449 mDelayedMarkAsRead->setChecked( GlobalSettings::self()->delayedMarkAsRead() );
04450 mDelayedMarkTime->setValue( GlobalSettings::self()->delayedMarkTime() );
04451 mShowPopupAfterDnD->setChecked( GlobalSettings::self()->showPopupAfterDnD() );
04452 }
04453
04454 void MiscPage::FolderTab::doLoadOther() {
04455 KConfigGroup general( KMKernel::config(), "General" );
04456
04457 mEmptyTrashCheck->setChecked( general.readBoolEntry( "empty-trash-on-exit", true ) );
04458 mOnStartupOpenFolder->setFolder( general.readEntry( "startupFolder",
04459 kmkernel->inboxFolder()->idString() ) );
04460 mEmptyFolderConfirmCheck->setChecked( general.readBoolEntry( "confirm-before-empty", true ) );
04461
04462 int num = general.readNumEntry("default-mailbox-format", 1 );
04463 if ( num < 0 || num > 1 ) num = 1;
04464 mMailboxPrefCombo->setCurrentItem( num );
04465
04466 #ifdef HAVE_INDEXLIB
04467 mIndexingEnabled->setChecked( kmkernel->msgIndex() && kmkernel->msgIndex()->isEnabled() );
04468 #endif
04469 }
04470
04471 void MiscPage::FolderTab::save() {
04472 KConfigGroup general( KMKernel::config(), "General" );
04473
04474 general.writeEntry( "empty-trash-on-exit", mEmptyTrashCheck->isChecked() );
04475 general.writeEntry( "confirm-before-empty", mEmptyFolderConfirmCheck->isChecked() );
04476 general.writeEntry( "default-mailbox-format", mMailboxPrefCombo->currentItem() );
04477 general.writeEntry( "startupFolder", mOnStartupOpenFolder->folder() ?
04478 mOnStartupOpenFolder->folder()->idString() : QString::null );
04479
04480 GlobalSettings::self()->setDelayedMarkAsRead( mDelayedMarkAsRead->isChecked() );
04481 GlobalSettings::self()->setDelayedMarkTime( mDelayedMarkTime->value() );
04482 GlobalSettings::self()->setActionEnterFolder( mActionEnterFolder->currentItem() );
04483 GlobalSettings::self()->setLoopOnGotoUnread( mLoopOnGotoUnread->currentItem() );
04484 GlobalSettings::self()->setShowPopupAfterDnD( mShowPopupAfterDnD->isChecked() );
04485 GlobalSettings::self()->setExcludeImportantMailFromExpiry(
04486 mExcludeImportantFromExpiry->isChecked() );
04487 #ifdef HAVE_INDEXLIB
04488 if ( kmkernel->msgIndex() ) kmkernel->msgIndex()->setEnabled( mIndexingEnabled->isChecked() );
04489 #endif
04490 }
04491
04492 QString MiscPage::GroupwareTab::helpAnchor() const {
04493 return QString::fromLatin1("configure-misc-groupware");
04494 }
04495
04496 MiscPageGroupwareTab::MiscPageGroupwareTab( QWidget* parent, const char* name )
04497 : ConfigModuleTab( parent, name )
04498 {
04499 QBoxLayout* vlay = new QVBoxLayout( this, KDialog::marginHint(),
04500 KDialog::spacingHint() );
04501 vlay->setAutoAdd( true );
04502
04503
04504 QVGroupBox* b1 = new QVGroupBox( i18n("&IMAP Resource Folder Options"),
04505 this );
04506
04507 mEnableImapResCB =
04508 new QCheckBox( i18n("&Enable IMAP resource functionality"), b1 );
04509 QToolTip::add( mEnableImapResCB, i18n( "This enables the IMAP storage for "
04510 "the Kontact applications" ) );
04511 QWhatsThis::add( mEnableImapResCB,
04512 i18n( GlobalSettings::self()->theIMAPResourceEnabledItem()->whatsThis().utf8() ) );
04513 connect( mEnableImapResCB, SIGNAL( stateChanged( int ) ),
04514 this, SLOT( slotEmitChanged( void ) ) );
04515
04516 mBox = new QWidget( b1 );
04517 QGridLayout* grid = new QGridLayout( mBox, 4, 2, 0, KDialog::spacingHint() );
04518 grid->setColStretch( 1, 1 );
04519 connect( mEnableImapResCB, SIGNAL( toggled(bool) ),
04520 mBox, SLOT( setEnabled(bool) ) );
04521
04522 QLabel* storageFormatLA = new QLabel( i18n("&Format used for the groupware folders:"),
04523 mBox );
04524 QString toolTip = i18n( "Choose the format to use to store the contents of the groupware folders." );
04525 QString whatsThis = i18n( GlobalSettings::self()
04526 ->theIMAPResourceStorageFormatItem()->whatsThis().utf8() );
04527 grid->addWidget( storageFormatLA, 0, 0 );
04528 QToolTip::add( storageFormatLA, toolTip );
04529 QWhatsThis::add( storageFormatLA, whatsThis );
04530 mStorageFormatCombo = new QComboBox( false, mBox );
04531 storageFormatLA->setBuddy( mStorageFormatCombo );
04532 QStringList formatLst;
04533 formatLst << i18n("Standard (Ical / Vcard)") << i18n("Kolab (XML)");
04534 mStorageFormatCombo->insertStringList( formatLst );
04535 grid->addWidget( mStorageFormatCombo, 0, 1 );
04536 QToolTip::add( mStorageFormatCombo, toolTip );
04537 QWhatsThis::add( mStorageFormatCombo, whatsThis );
04538 connect( mStorageFormatCombo, SIGNAL( activated( int ) ),
04539 this, SLOT( slotStorageFormatChanged( int ) ) );
04540
04541 QLabel* languageLA = new QLabel( i18n("&Language of the groupware folders:"),
04542 mBox );
04543
04544 toolTip = i18n( "Set the language of the folder names" );
04545 whatsThis = i18n( GlobalSettings::self()
04546 ->theIMAPResourceFolderLanguageItem()->whatsThis().utf8() );
04547 grid->addWidget( languageLA, 1, 0 );
04548 QToolTip::add( languageLA, toolTip );
04549 QWhatsThis::add( languageLA, whatsThis );
04550 mLanguageCombo = new QComboBox( false, mBox );
04551 languageLA->setBuddy( mLanguageCombo );
04552 QStringList lst;
04553 lst << i18n("English") << i18n("German") << i18n("French") << i18n("Dutch");
04554 mLanguageCombo->insertStringList( lst );
04555 grid->addWidget( mLanguageCombo, 1, 1 );
04556 QToolTip::add( mLanguageCombo, toolTip );
04557 QWhatsThis::add( mLanguageCombo, whatsThis );
04558 connect( mLanguageCombo, SIGNAL( activated( int ) ),
04559 this, SLOT( slotEmitChanged( void ) ) );
04560
04561 mFolderComboLabel = new QLabel( mBox );
04562 toolTip = i18n( "Set the parent of the resource folders" );
04563 whatsThis = i18n( GlobalSettings::self()->theIMAPResourceFolderParentItem()->whatsThis().utf8() );
04564 QToolTip::add( mFolderComboLabel, toolTip );
04565 QWhatsThis::add( mFolderComboLabel, whatsThis );
04566 grid->addWidget( mFolderComboLabel, 2, 0 );
04567
04568 mFolderComboStack = new QWidgetStack( mBox );
04569 grid->addWidget( mFolderComboStack, 2, 1 );
04570
04571
04572
04573 mFolderCombo = new FolderRequester( mBox,
04574 kmkernel->getKMMainWidget()->folderTree() );
04575 mFolderComboStack->addWidget( mFolderCombo, 0 );
04576 QToolTip::add( mFolderCombo, toolTip );
04577 QWhatsThis::add( mFolderCombo, whatsThis );
04578 connect( mFolderCombo, SIGNAL( folderChanged( KMFolder* ) ),
04579 this, SLOT( slotEmitChanged() ) );
04580
04581
04582
04583
04584 mAccountCombo = new KMail::AccountComboBox( mBox );
04585 mFolderComboStack->addWidget( mAccountCombo, 1 );
04586 QToolTip::add( mAccountCombo, toolTip );
04587 QWhatsThis::add( mAccountCombo, whatsThis );
04588 connect( mAccountCombo, SIGNAL( activated( int ) ),
04589 this, SLOT( slotEmitChanged() ) );
04590
04591 mHideGroupwareFolders = new QCheckBox( i18n( "&Hide groupware folders" ),
04592 mBox, "HideGroupwareFoldersBox" );
04593 grid->addMultiCellWidget( mHideGroupwareFolders, 3, 3, 0, 1 );
04594 QToolTip::add( mHideGroupwareFolders,
04595 i18n( "When this is checked, you will not see the IMAP "
04596 "resource folders in the folder tree." ) );
04597 QWhatsThis::add( mHideGroupwareFolders, i18n( GlobalSettings::self()
04598 ->hideGroupwareFoldersItem()->whatsThis().utf8() ) );
04599 connect( mHideGroupwareFolders, SIGNAL( toggled( bool ) ),
04600 this, SLOT( slotEmitChanged() ) );
04601
04602
04603 b1 = new QVGroupBox( i18n("Groupware Compatibility && Legacy Options"), this );
04604
04605 gBox = new QVBox( b1 );
04606 #if 0
04607
04608 mEnableGwCB = new QCheckBox( i18n("&Enable groupware functionality"), b1 );
04609 gBox->setSpacing( KDialog::spacingHint() );
04610 connect( mEnableGwCB, SIGNAL( toggled(bool) ),
04611 gBox, SLOT( setEnabled(bool) ) );
04612 connect( mEnableGwCB, SIGNAL( stateChanged( int ) ),
04613 this, SLOT( slotEmitChanged( void ) ) );
04614 #endif
04615 mEnableGwCB = 0;
04616 mLegacyMangleFromTo = new QCheckBox( i18n( "Mangle From:/To: headers in replies to invitations" ), gBox );
04617 QToolTip::add( mLegacyMangleFromTo, i18n( "Turn this option on in order to make Outlook(tm) understand your answers to invitation replies" ) );
04618 QWhatsThis::add( mLegacyMangleFromTo, i18n( GlobalSettings::self()->
04619 legacyMangleFromToHeadersItem()->whatsThis().utf8() ) );
04620 connect( mLegacyMangleFromTo, SIGNAL( stateChanged( int ) ),
04621 this, SLOT( slotEmitChanged( void ) ) );
04622 mLegacyBodyInvites = new QCheckBox( i18n( "Send invitations in the mail body" ), gBox );
04623 QToolTip::add( mLegacyBodyInvites, i18n( "Turn this option on in order to make Outlook(tm) understand your answers to invitations" ) );
04624 QWhatsThis::add( mLegacyMangleFromTo, i18n( GlobalSettings::self()->
04625 legacyBodyInvitesItem()->whatsThis().utf8() ) );
04626 connect( mLegacyBodyInvites, SIGNAL( toggled( bool ) ),
04627 this, SLOT( slotLegacyBodyInvitesToggled( bool ) ) );
04628 connect( mLegacyBodyInvites, SIGNAL( stateChanged( int ) ),
04629 this, SLOT( slotEmitChanged( void ) ) );
04630 mAutomaticSending = new QCheckBox( i18n( "Automatic invitation sending" ), gBox );
04631 QToolTip::add( mAutomaticSending, i18n( "When this is on, the user will not see the mail composer window. Invitation mails are sent automatically" ) );
04632 QWhatsThis::add( mAutomaticSending, i18n( GlobalSettings::self()->
04633 automaticSendingItem()->whatsThis().utf8() ) );
04634 connect( mAutomaticSending, SIGNAL( stateChanged( int ) ),
04635 this, SLOT( slotEmitChanged( void ) ) );
04636
04637
04638 new QLabel( this );
04639 }
04640
04641 void MiscPageGroupwareTab::slotLegacyBodyInvitesToggled( bool on )
04642 {
04643 if ( on ) {
04644 QString txt = i18n( "<qt>Invitations are normally sent as attachments to "
04645 "a mail. This switch changes the invitation mails to "
04646 "be sent in the text of the mail instead; this is "
04647 "necessary to send invitations and replies to "
04648 "Microsoft Outlook.<br>But, when you do this, you no "
04649 "longer get descriptive text that mail programs "
04650 "can read; so, to people who have email programs "
04651 "that do not understand the invitations, the "
04652 "resulting messages look very odd.<br>People that have email "
04653 "programs that do understand invitations will still "
04654 "be able to work with this.</qt>" );
04655 KMessageBox::information( this, txt, QString::null,
04656 "LegacyBodyInvitesWarning" );
04657 }
04658
04659
04660 mAutomaticSending->setEnabled( !mLegacyBodyInvites->isChecked() );
04661 }
04662
04663 void MiscPage::GroupwareTab::doLoadFromGlobalSettings() {
04664
04665 if ( mEnableGwCB ) {
04666 mEnableGwCB->setChecked( GlobalSettings::self()->groupwareEnabled() );
04667 gBox->setEnabled( mEnableGwCB->isChecked() );
04668 }
04669 mLegacyMangleFromTo->setChecked( GlobalSettings::self()->legacyMangleFromToHeaders() );
04670 mLegacyBodyInvites->blockSignals( true );
04671 mLegacyBodyInvites->setChecked( GlobalSettings::self()->legacyBodyInvites() );
04672 mLegacyBodyInvites->blockSignals( false );
04673 mAutomaticSending->setChecked( GlobalSettings::self()->automaticSending() );
04674 mAutomaticSending->setEnabled( !mLegacyBodyInvites->isChecked() );
04675
04676
04677 mEnableImapResCB->setChecked( GlobalSettings::self()->theIMAPResourceEnabled() );
04678 mBox->setEnabled( mEnableImapResCB->isChecked() );
04679
04680 mHideGroupwareFolders->setChecked( GlobalSettings::self()->hideGroupwareFolders() );
04681 int i = GlobalSettings::self()->theIMAPResourceFolderLanguage();
04682 mLanguageCombo->setCurrentItem(i);
04683 i = GlobalSettings::self()->theIMAPResourceStorageFormat();
04684 mStorageFormatCombo->setCurrentItem(i);
04685 slotStorageFormatChanged( i );
04686
04687 QString folderId( GlobalSettings::self()->theIMAPResourceFolderParent() );
04688 if( !folderId.isNull() && kmkernel->findFolderById( folderId ) ) {
04689 mFolderCombo->setFolder( folderId );
04690 } else {
04691
04692 mFolderCombo->setFolder( i18n( "<Choose a Folder>" ) );
04693 }
04694
04695 KMAccount* selectedAccount = 0;
04696 int accountId = GlobalSettings::self()->theIMAPResourceAccount();
04697 if ( accountId )
04698 selectedAccount = kmkernel->acctMgr()->find( accountId );
04699 else {
04700
04701 for( KMAccount *a = kmkernel->acctMgr()->first(); a!=0;
04702 a = kmkernel->acctMgr()->next() ) {
04703 if( a->folder() && a->folder()->child() ) {
04704
04705 KMFolderNode *node;
04706 for (node = a->folder()->child()->first(); node; node = a->folder()->child()->next())
04707 if (!node->isDir() && node->name() == "INBOX") break;
04708
04709 if ( node && static_cast<KMFolder*>(node)->idString() == folderId ) {
04710 selectedAccount = a;
04711 break;
04712 }
04713 }
04714 }
04715 }
04716 if ( selectedAccount )
04717 mAccountCombo->setCurrentAccount( selectedAccount );
04718 else if ( GlobalSettings::self()->theIMAPResourceStorageFormat() == 1 )
04719 kdDebug(5006) << "Folder " << folderId << " not found as an account's inbox" << endl;
04720 }
04721
04722 void MiscPage::GroupwareTab::save() {
04723
04724 if ( mEnableGwCB )
04725 GlobalSettings::self()->setGroupwareEnabled( mEnableGwCB->isChecked() );
04726 GlobalSettings::self()->setLegacyMangleFromToHeaders( mLegacyMangleFromTo->isChecked() );
04727 GlobalSettings::self()->setLegacyBodyInvites( mLegacyBodyInvites->isChecked() );
04728 GlobalSettings::self()->setAutomaticSending( mAutomaticSending->isChecked() );
04729
04730 int format = mStorageFormatCombo->currentItem();
04731 GlobalSettings::self()->setTheIMAPResourceStorageFormat( format );
04732
04733
04734 GlobalSettings::self()->setHideGroupwareFolders( mHideGroupwareFolders->isChecked() );
04735
04736
04737
04738 QString folderId;
04739 if ( format == 0 ) {
04740 KMFolder* folder = mFolderCombo->folder();
04741 if ( folder )
04742 folderId = folder->idString();
04743 } else {
04744
04745 KMAccount* acct = mAccountCombo->currentAccount();
04746 if ( acct ) {
04747 folderId = QString( ".%1.directory/INBOX" ).arg( acct->id() );
04748 GlobalSettings::self()->setTheIMAPResourceAccount( acct->id() );
04749 }
04750 }
04751
04752 bool enabled = mEnableImapResCB->isChecked() && !folderId.isEmpty();
04753 GlobalSettings::self()->setTheIMAPResourceEnabled( enabled );
04754 GlobalSettings::self()->setTheIMAPResourceFolderLanguage( mLanguageCombo->currentItem() );
04755 GlobalSettings::self()->setTheIMAPResourceFolderParent( folderId );
04756 }
04757
04758 void MiscPage::GroupwareTab::slotStorageFormatChanged( int format )
04759 {
04760 mLanguageCombo->setEnabled( format == 0 );
04761 mFolderComboStack->raiseWidget( format );
04762 if ( format == 0 ) {
04763 mFolderComboLabel->setText( i18n("&Resource folders are subfolders of:") );
04764 mFolderComboLabel->setBuddy( mFolderCombo );
04765 } else {
04766 mFolderComboLabel->setText( i18n("&Resource folders are in account:") );
04767 mFolderComboLabel->setBuddy( mAccountCombo );
04768 }
04769 slotEmitChanged();
04770 }
04771
04772
04773
04774
04775
04776
04777
04778 AccountUpdater::AccountUpdater(ImapAccountBase *account)
04779 : QObject()
04780 {
04781 mAccount = account;
04782 }
04783
04784 void AccountUpdater::update()
04785 {
04786 connect( mAccount, SIGNAL( connectionResult(int, const QString&) ),
04787 this, SLOT( namespacesFetched() ) );
04788 mAccount->makeConnection();
04789 }
04790
04791 void AccountUpdater::namespacesFetched()
04792 {
04793 mAccount->setCheckingMail( true );
04794 mAccount->processNewMail( false );
04795 deleteLater();
04796 }
04797
04798 #undef DIM
04799
04800
04801 #include "configuredialog.moc"