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