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