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