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 { "ColorbarBackgroundPlain", I18N_NOOP("HTML Status Bar Background - No HTML Message") },
01729 { "ColorbarForegroundPlain", I18N_NOOP("HTML Status Bar Foreground - No HTML Message") },
01730 { "ColorbarBackgroundHTML", I18N_NOOP("HTML Status Bar Background - HTML Message") },
01731 { "ColorbarForegroundHTML", I18N_NOOP("HTML Status Bar Foreground - HTML Message") },
01732 };
01733 static const int numColorNames = sizeof colorNames / sizeof *colorNames;
01734
01735 AppearancePageColorsTab::AppearancePageColorsTab( QWidget * parent, const char * name )
01736 : ConfigModuleTab( parent, name )
01737 {
01738
01739 QVBoxLayout *vlay;
01740
01741
01742 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
01743 mCustomColorCheck = new QCheckBox( i18n("&Use custom colors"), this );
01744 vlay->addWidget( mCustomColorCheck );
01745 connect( mCustomColorCheck, SIGNAL( stateChanged( int ) ),
01746 this, SLOT( slotEmitChanged( void ) ) );
01747
01748
01749 mColorList = new ColorListBox( this );
01750 mColorList->setEnabled( false );
01751 QStringList modeList;
01752 for ( int i = 0 ; i < numColorNames ; i++ )
01753 mColorList->insertItem( new ColorListItem( i18n( colorNames[i].displayName ) ) );
01754 vlay->addWidget( mColorList, 1 );
01755
01756
01757 mRecycleColorCheck =
01758 new QCheckBox( i18n("Recycle colors on deep "ing"), this );
01759 mRecycleColorCheck->setEnabled( false );
01760 vlay->addWidget( mRecycleColorCheck );
01761 connect( mRecycleColorCheck, SIGNAL( stateChanged( int ) ),
01762 this, SLOT( slotEmitChanged( void ) ) );
01763
01764
01765 connect( mCustomColorCheck, SIGNAL(toggled(bool)),
01766 mColorList, SLOT(setEnabled(bool)) );
01767 connect( mCustomColorCheck, SIGNAL(toggled(bool)),
01768 mRecycleColorCheck, SLOT(setEnabled(bool)) );
01769 connect( mCustomColorCheck, SIGNAL( stateChanged( int ) ),
01770 this, SLOT( slotEmitChanged( void ) ) );
01771 }
01772
01773 void AppearancePage::ColorsTab::doLoadOther() {
01774 KConfigGroup reader( KMKernel::config(), "Reader" );
01775
01776 mCustomColorCheck->setChecked( !reader.readBoolEntry( "defaultColors", true ) );
01777 mRecycleColorCheck->setChecked( reader.readBoolEntry( "RecycleQuoteColors", false ) );
01778
01779 static const QColor defaultColor[ numColorNames ] = {
01780 kapp->palette().active().base(),
01781 KGlobalSettings::alternateBackgroundColor(),
01782 kapp->palette().active().text(),
01783 QColor( 0x00, 0x80, 0x00 ),
01784 QColor( 0x00, 0x70, 0x00 ),
01785 QColor( 0x00, 0x60, 0x00 ),
01786 KGlobalSettings::linkColor(),
01787 KGlobalSettings::visitedLinkColor(),
01788 Qt::red,
01789 Qt::red,
01790 Qt::blue,
01791 QColor( 0x00, 0x7F, 0x00 ),
01792 QColor( 0x00, 0x80, 0xFF ),
01793 QColor( 0x40, 0xFF, 0x40 ),
01794 QColor( 0xFF, 0xFF, 0x40 ),
01795 QColor( 0xFF, 0xFF, 0x40 ),
01796 Qt::red,
01797 QColor( 0xFF, 0x40, 0x40 ),
01798 Qt::lightGray,
01799 Qt::black,
01800 Qt::black,
01801 Qt::white,
01802 };
01803
01804 for ( int i = 0 ; i < numColorNames ; i++ )
01805 mColorList->setColor( i,
01806 reader.readColorEntry( colorNames[i].configName, &defaultColor[i] ) );
01807 connect( mColorList, SIGNAL( changed( ) ),
01808 this, SLOT( slotEmitChanged( void ) ) );
01809 }
01810
01811 void AppearancePage::ColorsTab::installProfile( KConfig * profile ) {
01812 KConfigGroup reader( profile, "Reader" );
01813
01814 if ( reader.hasKey( "defaultColors" ) )
01815 mCustomColorCheck->setChecked( !reader.readBoolEntry( "defaultColors" ) );
01816 if ( reader.hasKey( "RecycleQuoteColors" ) )
01817 mRecycleColorCheck->setChecked( reader.readBoolEntry( "RecycleQuoteColors" ) );
01818
01819 for ( int i = 0 ; i < numColorNames ; i++ )
01820 if ( reader.hasKey( colorNames[i].configName ) )
01821 mColorList->setColor( i, reader.readColorEntry( colorNames[i].configName ) );
01822 }
01823
01824 void AppearancePage::ColorsTab::save() {
01825 KConfigGroup reader( KMKernel::config(), "Reader" );
01826
01827 bool customColors = mCustomColorCheck->isChecked();
01828 reader.writeEntry( "defaultColors", !customColors );
01829
01830 for ( int i = 0 ; i < numColorNames ; i++ )
01831
01832
01833 if ( customColors || reader.hasKey( colorNames[i].configName ) )
01834 reader.writeEntry( colorNames[i].configName, mColorList->color(i) );
01835
01836 reader.writeEntry( "RecycleQuoteColors", mRecycleColorCheck->isChecked() );
01837 }
01838
01839 QString AppearancePage::LayoutTab::helpAnchor() const {
01840 return QString::fromLatin1("configure-appearance-layout");
01841 }
01842
01843 static const EnumConfigEntryItem folderListModes[] = {
01844 { "long", I18N_NOOP("Lon&g folder list") },
01845 { "short", I18N_NOOP("Shor&t folder list" ) }
01846 };
01847 static const EnumConfigEntry folderListMode = {
01848 "Geometry", "FolderList", I18N_NOOP("Folder List"),
01849 folderListModes, DIM(folderListModes), 0
01850 };
01851
01852
01853 static const EnumConfigEntryItem mimeTreeLocations[] = {
01854 { "top", I18N_NOOP("Abo&ve the message pane") },
01855 { "bottom", I18N_NOOP("&Below the message pane") }
01856 };
01857 static const EnumConfigEntry mimeTreeLocation = {
01858 "Reader", "MimeTreeLocation", I18N_NOOP("Message Structure Viewer Placement"),
01859 mimeTreeLocations, DIM(mimeTreeLocations), 1
01860 };
01861
01862 static const EnumConfigEntryItem mimeTreeModes[] = {
01863 { "never", I18N_NOOP("Show &never") },
01864 { "smart", I18N_NOOP("Show only for non-plaintext &messages") },
01865 { "always", I18N_NOOP("Show alway&s") }
01866 };
01867 static const EnumConfigEntry mimeTreeMode = {
01868 "Reader", "MimeTreeMode", I18N_NOOP("Message Structure Viewer"),
01869 mimeTreeModes, DIM(mimeTreeModes), 1
01870 };
01871
01872
01873 static const EnumConfigEntryItem readerWindowModes[] = {
01874 { "hide", I18N_NOOP("&Do not show a message preview pane") },
01875 { "below", I18N_NOOP("Show the message preview pane belo&w the message list") },
01876 { "right", I18N_NOOP("Show the message preview pane ne&xt to the message list") }
01877 };
01878 static const EnumConfigEntry readerWindowMode = {
01879 "Geometry", "readerWindowMode", I18N_NOOP("Message Preview Pane"),
01880 readerWindowModes, DIM(readerWindowModes), 1
01881 };
01882
01883 AppearancePageLayoutTab::AppearancePageLayoutTab( QWidget * parent, const char * name )
01884 : ConfigModuleTab( parent, name )
01885 {
01886
01887 QVBoxLayout * vlay;
01888
01889 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
01890
01891
01892 populateButtonGroup( mFolderListGroup = new QHButtonGroup( this ), folderListMode );
01893 vlay->addWidget( mFolderListGroup );
01894 connect( mFolderListGroup, SIGNAL ( clicked( int ) ),
01895 this, SLOT( slotEmitChanged() ) );
01896
01897
01898 populateButtonGroup( mReaderWindowModeGroup = new QVButtonGroup( this ), readerWindowMode );
01899 vlay->addWidget( mReaderWindowModeGroup );
01900 connect( mReaderWindowModeGroup, SIGNAL ( clicked( int ) ),
01901 this, SLOT( slotEmitChanged() ) );
01902
01903
01904 populateButtonGroup( mMIMETreeModeGroup = new QVButtonGroup( this ), mimeTreeMode );
01905 vlay->addWidget( mMIMETreeModeGroup );
01906 connect( mMIMETreeModeGroup, SIGNAL ( clicked( int ) ),
01907 this, SLOT( slotEmitChanged() ) );
01908
01909
01910 populateButtonGroup( mMIMETreeLocationGroup = new QHButtonGroup( this ), mimeTreeLocation );
01911 vlay->addWidget( mMIMETreeLocationGroup );
01912 connect( mMIMETreeLocationGroup, SIGNAL ( clicked( int ) ),
01913 this, SLOT( slotEmitChanged() ) );
01914
01915 vlay->addStretch( 10 );
01916 }
01917
01918 void AppearancePage::LayoutTab::doLoadOther() {
01919 const KConfigGroup reader( KMKernel::config(), "Reader" );
01920 const KConfigGroup geometry( KMKernel::config(), "Geometry" );
01921
01922 loadWidget( mFolderListGroup, geometry, folderListMode );
01923 loadWidget( mMIMETreeLocationGroup, reader, mimeTreeLocation );
01924 loadWidget( mMIMETreeModeGroup, reader, mimeTreeMode );
01925 loadWidget( mReaderWindowModeGroup, geometry, readerWindowMode );
01926 }
01927
01928 void AppearancePage::LayoutTab::installProfile( KConfig * profile ) {
01929 const KConfigGroup reader( profile, "Reader" );
01930 const KConfigGroup geometry( profile, "Geometry" );
01931
01932 loadProfile( mFolderListGroup, geometry, folderListMode );
01933 loadProfile( mMIMETreeLocationGroup, reader, mimeTreeLocation );
01934 loadProfile( mMIMETreeModeGroup, reader, mimeTreeMode );
01935 loadProfile( mReaderWindowModeGroup, geometry, readerWindowMode );
01936 }
01937
01938 void AppearancePage::LayoutTab::save() {
01939 KConfigGroup reader( KMKernel::config(), "Reader" );
01940 KConfigGroup geometry( KMKernel::config(), "Geometry" );
01941
01942 saveButtonGroup( mFolderListGroup, geometry, folderListMode );
01943 saveButtonGroup( mMIMETreeLocationGroup, reader, mimeTreeLocation );
01944 saveButtonGroup( mMIMETreeModeGroup, reader, mimeTreeMode );
01945 saveButtonGroup( mReaderWindowModeGroup, geometry, readerWindowMode );
01946 }
01947
01948
01949
01950
01951
01952 QString AppearancePage::HeadersTab::helpAnchor() const {
01953 return QString::fromLatin1("configure-appearance-headers");
01954 }
01955
01956 static const struct {
01957 const char * displayName;
01958 DateFormatter::FormatType dateDisplay;
01959 } dateDisplayConfig[] = {
01960 { I18N_NOOP("Sta&ndard format (%1)"), KMime::DateFormatter::CTime },
01961 { I18N_NOOP("Locali&zed format (%1)"), KMime::DateFormatter::Localized },
01962 { I18N_NOOP("Fancy for&mat (%1)"), KMime::DateFormatter::Fancy },
01963 { I18N_NOOP("C&ustom format (Shift+F1 for help):"),
01964 KMime::DateFormatter::Custom }
01965 };
01966 static const int numDateDisplayConfig =
01967 sizeof dateDisplayConfig / sizeof *dateDisplayConfig;
01968
01969 AppearancePageHeadersTab::AppearancePageHeadersTab( QWidget * parent, const char * name )
01970 : ConfigModuleTab( parent, name ),
01971 mCustomDateFormatEdit( 0 )
01972 {
01973
01974 QButtonGroup * group;
01975 QRadioButton * radio;
01976
01977 QVBoxLayout * vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
01978
01979
01980 group = new QVButtonGroup( i18n( "General Options" ), this );
01981 group->layout()->setSpacing( KDialog::spacingHint() );
01982
01983 mMessageSizeCheck = new QCheckBox( i18n("Display messa&ge sizes"), group );
01984
01985 mCryptoIconsCheck = new QCheckBox( i18n( "Show crypto &icons" ), group );
01986
01987 mAttachmentCheck = new QCheckBox( i18n("Show attachment icon"), group );
01988
01989 mNestedMessagesCheck =
01990 new QCheckBox( i18n("&Threaded message list"), group );
01991
01992 connect( mMessageSizeCheck, SIGNAL( stateChanged( int ) ),
01993 this, SLOT( slotEmitChanged( void ) ) );
01994 connect( mAttachmentCheck, SIGNAL( stateChanged( int ) ),
01995 this, SLOT( slotEmitChanged( void ) ) );
01996 connect( mCryptoIconsCheck, SIGNAL( stateChanged( int ) ),
01997 this, SLOT( slotEmitChanged( void ) ) );
01998 connect( mNestedMessagesCheck, SIGNAL( stateChanged( int ) ),
01999 this, SLOT( slotEmitChanged( void ) ) );
02000
02001
02002 vlay->addWidget( group );
02003
02004
02005 mNestingPolicy =
02006 new QVButtonGroup( i18n("Threaded Message List Options"), this );
02007 mNestingPolicy->layout()->setSpacing( KDialog::spacingHint() );
02008
02009 mNestingPolicy->insert(
02010 new QRadioButton( i18n("Always &keep threads open"),
02011 mNestingPolicy ), 0 );
02012 mNestingPolicy->insert(
02013 new QRadioButton( i18n("Threads default to o&pen"),
02014 mNestingPolicy ), 1 );
02015 mNestingPolicy->insert(
02016 new QRadioButton( i18n("Threads default to closed"),
02017 mNestingPolicy ), 2 );
02018 mNestingPolicy->insert(
02019 new QRadioButton( i18n("Open threads that contain ne&w, unread "
02020 "or important messages and open watched threads."),
02021 mNestingPolicy ), 3 );
02022
02023 vlay->addWidget( mNestingPolicy );
02024
02025 connect( mNestingPolicy, SIGNAL( clicked( int ) ),
02026 this, SLOT( slotEmitChanged( void ) ) );
02027
02028
02029 mDateDisplay = new QVButtonGroup( i18n("Date Display"), this );
02030 mDateDisplay->layout()->setSpacing( KDialog::spacingHint() );
02031
02032 for ( int i = 0 ; i < numDateDisplayConfig ; i++ ) {
02033 QString buttonLabel = i18n(dateDisplayConfig[i].displayName);
02034 if ( buttonLabel.contains("%1") )
02035 buttonLabel = buttonLabel.arg( DateFormatter::formatCurrentDate( dateDisplayConfig[i].dateDisplay ) );
02036 radio = new QRadioButton( buttonLabel, mDateDisplay );
02037 mDateDisplay->insert( radio, i );
02038 if ( dateDisplayConfig[i].dateDisplay == DateFormatter::Custom ) {
02039 mCustomDateFormatEdit = new KLineEdit( mDateDisplay );
02040 mCustomDateFormatEdit->setEnabled( false );
02041 connect( radio, SIGNAL(toggled(bool)),
02042 mCustomDateFormatEdit, SLOT(setEnabled(bool)) );
02043 connect( mCustomDateFormatEdit, SIGNAL(textChanged(const QString&)),
02044 this, SLOT(slotEmitChanged(void)) );
02045 QString customDateWhatsThis =
02046 i18n("<qt><p><strong>These expressions may be used for the date:"
02047 "</strong></p>"
02048 "<ul>"
02049 "<li>d - the day as a number without a leading zero (1-31)</li>"
02050 "<li>dd - the day as a number with a leading zero (01-31)</li>"
02051 "<li>ddd - the abbreviated day name (Mon - Sun)</li>"
02052 "<li>dddd - the long day name (Monday - Sunday)</li>"
02053 "<li>M - the month as a number without a leading zero (1-12)</li>"
02054 "<li>MM - the month as a number with a leading zero (01-12)</li>"
02055 "<li>MMM - the abbreviated month name (Jan - Dec)</li>"
02056 "<li>MMMM - the long month name (January - December)</li>"
02057 "<li>yy - the year as a two digit number (00-99)</li>"
02058 "<li>yyyy - the year as a four digit number (0000-9999)</li>"
02059 "</ul>"
02060 "<p><strong>These expressions may be used for the time:"
02061 "</string></p> "
02062 "<ul>"
02063 "<li>h - the hour without a leading zero (0-23 or 1-12 if AM/PM display)</li>"
02064 "<li>hh - the hour with a leading zero (00-23 or 01-12 if AM/PM display)</li>"
02065 "<li>m - the minutes without a leading zero (0-59)</li>"
02066 "<li>mm - the minutes with a leading zero (00-59)</li>"
02067 "<li>s - the seconds without a leading zero (0-59)</li>"
02068 "<li>ss - the seconds with a leading zero (00-59)</li>"
02069 "<li>z - the milliseconds without leading zeroes (0-999)</li>"
02070 "<li>zzz - the milliseconds with leading zeroes (000-999)</li>"
02071 "<li>AP - switch to AM/PM display. AP will be replaced by either \"AM\" or \"PM\".</li>"
02072 "<li>ap - switch to AM/PM display. ap will be replaced by either \"am\" or \"pm\".</li>"
02073 "<li>Z - time zone in numeric form (-0500)</li>"
02074 "</ul>"
02075 "<p><strong>All other input characters will be ignored."
02076 "</strong></p></qt>");
02077 QWhatsThis::add( mCustomDateFormatEdit, customDateWhatsThis );
02078 QWhatsThis::add( radio, customDateWhatsThis );
02079 }
02080 }
02081
02082 vlay->addWidget( mDateDisplay );
02083 connect( mDateDisplay, SIGNAL( clicked( int ) ),
02084 this, SLOT( slotEmitChanged( void ) ) );
02085
02086
02087 vlay->addStretch( 10 );
02088 }
02089
02090 void AppearancePage::HeadersTab::doLoadOther() {
02091 KConfigGroup general( KMKernel::config(), "General" );
02092 KConfigGroup geometry( KMKernel::config(), "Geometry" );
02093
02094
02095 mNestedMessagesCheck->setChecked( geometry.readBoolEntry( "nestedMessages", false ) );
02096 mMessageSizeCheck->setChecked( general.readBoolEntry( "showMessageSize", false ) );
02097 mCryptoIconsCheck->setChecked( general.readBoolEntry( "showCryptoIcons", false ) );
02098 mAttachmentCheck->setChecked( general.readBoolEntry( "showAttachmentIcon", true ) );
02099
02100
02101 int num = geometry.readNumEntry( "nestingPolicy", 3 );
02102 if ( num < 0 || num > 3 ) num = 3;
02103 mNestingPolicy->setButton( num );
02104
02105
02106 setDateDisplay( general.readNumEntry( "dateFormat", DateFormatter::Fancy ),
02107 general.readEntry( "customDateFormat" ) );
02108 }
02109
02110 void AppearancePage::HeadersTab::setDateDisplay( int num, const QString & format ) {
02111 DateFormatter::FormatType dateDisplay =
02112 static_cast<DateFormatter::FormatType>( num );
02113
02114
02115 if ( dateDisplay == DateFormatter::Custom )
02116 mCustomDateFormatEdit->setText( format );
02117
02118 for ( int i = 0 ; i < numDateDisplayConfig ; i++ )
02119 if ( dateDisplay == dateDisplayConfig[i].dateDisplay ) {
02120 mDateDisplay->setButton( i );
02121 return;
02122 }
02123
02124 mDateDisplay->setButton( numDateDisplayConfig - 2 );
02125 }
02126
02127 void AppearancePage::HeadersTab::installProfile( KConfig * profile ) {
02128 KConfigGroup general( profile, "General" );
02129 KConfigGroup geometry( profile, "Geometry" );
02130
02131 if ( geometry.hasKey( "nestedMessages" ) )
02132 mNestedMessagesCheck->setChecked( geometry.readBoolEntry( "nestedMessages" ) );
02133 if ( general.hasKey( "showMessageSize" ) )
02134 mMessageSizeCheck->setChecked( general.readBoolEntry( "showMessageSize" ) );
02135
02136 if( general.hasKey( "showCryptoIcons" ) )
02137 mCryptoIconsCheck->setChecked( general.readBoolEntry( "showCryptoIcons" ) );
02138 if ( general.hasKey( "showAttachmentIcon" ) )
02139 mAttachmentCheck->setChecked( general.readBoolEntry( "showAttachmentIcon" ) );
02140
02141 if ( geometry.hasKey( "nestingPolicy" ) ) {
02142 int num = geometry.readNumEntry( "nestingPolicy" );
02143 if ( num < 0 || num > 3 ) num = 3;
02144 mNestingPolicy->setButton( num );
02145 }
02146
02147 if ( general.hasKey( "dateFormat" ) )
02148 setDateDisplay( general.readNumEntry( "dateFormat" ),
02149 general.readEntry( "customDateFormat" ) );
02150 }
02151
02152 void AppearancePage::HeadersTab::save() {
02153 KConfigGroup general( KMKernel::config(), "General" );
02154 KConfigGroup geometry( KMKernel::config(), "Geometry" );
02155
02156 if ( geometry.readBoolEntry( "nestedMessages", false )
02157 != mNestedMessagesCheck->isChecked() ) {
02158 int result = KMessageBox::warningContinueCancel( this,
02159 i18n("Changing the global threading setting will override "
02160 "all folder specific values."),
02161 QString::null, KStdGuiItem::cont(), "threadOverride" );
02162 if ( result == KMessageBox::Continue ) {
02163 geometry.writeEntry( "nestedMessages", mNestedMessagesCheck->isChecked() );
02164
02165 QStringList groups = KMKernel::config()->groupList().grep( QRegExp("^Folder-") );
02166 kdDebug(5006) << "groups.count() == " << groups.count() << endl;
02167 for ( QStringList::const_iterator it = groups.begin() ; it != groups.end() ; ++it ) {
02168 KConfigGroup group( KMKernel::config(), *it );
02169 group.deleteEntry( "threadMessagesOverride" );
02170 }
02171 }
02172 }
02173
02174 geometry.writeEntry( "nestingPolicy",
02175 mNestingPolicy->id( mNestingPolicy->selected() ) );
02176 general.writeEntry( "showMessageSize", mMessageSizeCheck->isChecked() );
02177 general.writeEntry( "showCryptoIcons", mCryptoIconsCheck->isChecked() );
02178 general.writeEntry( "showAttachmentIcon", mAttachmentCheck->isChecked() );
02179
02180 int dateDisplayID = mDateDisplay->id( mDateDisplay->selected() );
02181
02182 assert( dateDisplayID >= 0 ); assert( dateDisplayID < numDateDisplayConfig );
02183 general.writeEntry( "dateFormat",
02184 dateDisplayConfig[ dateDisplayID ].dateDisplay );
02185 general.writeEntry( "customDateFormat", mCustomDateFormatEdit->text() );
02186 }
02187
02188
02189
02190
02191
02192
02193
02194 static const BoolConfigEntry showColorbarMode = {
02195 "Reader", "showColorbar", I18N_NOOP("Show HTML stat&us bar"), false
02196 };
02197
02198 static const BoolConfigEntry showSpamStatusMode = {
02199 "Reader", "showSpamStatus", I18N_NOOP("Show s&pam status in fancy headers"), true
02200 };
02201
02202 static const BoolConfigEntry showEmoticons = {
02203 "Reader", "ShowEmoticons", I18N_NOOP("Replace smileys by emoticons"), true
02204 };
02205
02206 static const BoolConfigEntry shrinkQuotes = {
02207 "Reader", "ShrinkQuotes", I18N_NOOP("Use smaller font for quoted text"), false
02208 };
02209
02210 static const BoolConfigEntry showExpandQuotesMark= {
02211 "Reader", "ShowExpandQuotesMark", I18N_NOOP("Show expand/collapse quote marks"), false
02212 };
02213
02214
02215 QString AppearancePage::ReaderTab::helpAnchor() const {
02216 return QString::fromLatin1("configure-appearance-reader");
02217 }
02218
02219 AppearancePageReaderTab::AppearancePageReaderTab( QWidget * parent,
02220 const char * name )
02221 : ConfigModuleTab( parent, name )
02222 {
02223 QVBoxLayout *vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
02224
02225
02226 populateCheckBox( mShowColorbarCheck = new QCheckBox( this ), showColorbarMode );
02227 vlay->addWidget( mShowColorbarCheck );
02228 connect( mShowColorbarCheck, SIGNAL ( stateChanged( int ) ),
02229 this, SLOT( slotEmitChanged() ) );
02230
02231
02232 populateCheckBox( mShowSpamStatusCheck = new QCheckBox( this ), showSpamStatusMode );
02233 vlay->addWidget( mShowSpamStatusCheck );
02234 connect( mShowSpamStatusCheck, SIGNAL ( stateChanged( int ) ),
02235 this, SLOT( slotEmitChanged() ) );
02236
02237
02238 populateCheckBox( mShowEmoticonsCheck = new QCheckBox( this ), showEmoticons );
02239 vlay->addWidget( mShowEmoticonsCheck );
02240 connect( mShowEmoticonsCheck, SIGNAL ( stateChanged( int ) ),
02241 this, SLOT( slotEmitChanged() ) );
02242
02243
02244 mShrinkQuotesCheck = new QCheckBox( i18n( shrinkQuotes.desc ), this,
02245 "kcfg_ShrinkQuotes" );
02246 vlay->addWidget( mShrinkQuotesCheck );
02247 connect( mShrinkQuotesCheck, SIGNAL( stateChanged( int ) ),
02248 this, SLOT( slotEmitChanged() ) );
02249
02250
02251 QHBoxLayout *hlay= new QHBoxLayout( vlay );
02252 populateCheckBox( mShowExpandQuotesMark= new QCheckBox( this ), showExpandQuotesMark);
02253 hlay->addWidget( mShowExpandQuotesMark);
02254 connect( mShowExpandQuotesMark, SIGNAL ( stateChanged( int ) ),
02255 this, SLOT( slotEmitChanged() ) );
02256
02257 hlay->addStretch( 1 );
02258 mCollapseQuoteLevelSpin = new KIntSpinBox( 0,10,1,
02259 3,10,this );
02260
02261 QLabel *label = new QLabel( mCollapseQuoteLevelSpin,
02262 GlobalSettings::self()->collapseQuoteLevelSpinItem()->label(), this );
02263
02264 hlay->addWidget( label );
02265
02266 mCollapseQuoteLevelSpin->setEnabled( false );
02267 connect( mCollapseQuoteLevelSpin, SIGNAL( valueChanged( int ) ),
02268 this, SLOT( slotEmitChanged( void ) ) );
02269 hlay->addWidget( mCollapseQuoteLevelSpin);
02270
02271 connect( mShowExpandQuotesMark, SIGNAL( toggled( bool ) ),
02272 mCollapseQuoteLevelSpin, SLOT( setEnabled( bool ) ) );
02273
02274
02275 hlay = new QHBoxLayout( vlay );
02276 mCharsetCombo = new QComboBox( this );
02277 mCharsetCombo->insertStringList( KMMsgBase::supportedEncodings( false ) );
02278
02279 connect( mCharsetCombo, SIGNAL( activated( int ) ),
02280 this, SLOT( slotEmitChanged( void ) ) );
02281
02282 QString fallbackCharsetWhatsThis =
02283 i18n( GlobalSettings::self()->fallbackCharacterEncodingItem()->whatsThis().utf8() );
02284 QWhatsThis::add( mCharsetCombo, fallbackCharsetWhatsThis );
02285
02286 label = new QLabel( i18n("Fallback ch&aracter encoding:"), this );
02287 label->setBuddy( mCharsetCombo );
02288
02289 hlay->addWidget( label );
02290 hlay->addWidget( mCharsetCombo );
02291
02292
02293 QHBoxLayout *hlay2 = new QHBoxLayout( vlay );
02294 mOverrideCharsetCombo = new QComboBox( this );
02295 QStringList encodings = KMMsgBase::supportedEncodings( false );
02296 encodings.prepend( i18n( "Auto" ) );
02297 mOverrideCharsetCombo->insertStringList( encodings );
02298 mOverrideCharsetCombo->setCurrentItem(0);
02299
02300 connect( mOverrideCharsetCombo, SIGNAL( activated( int ) ),
02301 this, SLOT( slotEmitChanged( void ) ) );
02302
02303 QString overrideCharsetWhatsThis =
02304 i18n( GlobalSettings::self()->overrideCharacterEncodingItem()->whatsThis().utf8() );
02305 QWhatsThis::add( mOverrideCharsetCombo, overrideCharsetWhatsThis );
02306
02307 label = new QLabel( i18n("&Override character encoding:"), this );
02308 label->setBuddy( mOverrideCharsetCombo );
02309
02310 hlay2->addWidget( label );
02311 hlay2->addWidget( mOverrideCharsetCombo );
02312
02313 vlay->addStretch( 100 );
02314 }
02315
02316
02317 void AppearancePage::ReaderTab::readCurrentFallbackCodec()
02318 {
02319 QStringList encodings = KMMsgBase::supportedEncodings( false );
02320 QStringList::ConstIterator it( encodings.begin() );
02321 QStringList::ConstIterator end( encodings.end() );
02322 QString currentEncoding = GlobalSettings::self()->fallbackCharacterEncoding();
02323 currentEncoding = currentEncoding.replace( "iso ", "iso-", false );
02325 int i = 0;
02326 int indexOfLatin9 = 0;
02327 bool found = false;
02328 for( ; it != end; ++it)
02329 {
02330 const QString encoding = KGlobal::charsets()->encodingForName(*it);
02331 if ( encoding == "iso-8859-15" )
02332 indexOfLatin9 = i;
02333 if( encoding == currentEncoding )
02334 {
02335 mCharsetCombo->setCurrentItem( i );
02336 found = true;
02337 break;
02338 }
02339 i++;
02340 }
02341 if ( !found )
02342 mCharsetCombo->setCurrentItem( indexOfLatin9 );
02343 }
02344
02345 void AppearancePage::ReaderTab::readCurrentOverrideCodec()
02346 {
02347 const QString ¤tOverrideEncoding = GlobalSettings::self()->overrideCharacterEncoding();
02348 if ( currentOverrideEncoding.isEmpty() ) {
02349 mOverrideCharsetCombo->setCurrentItem( 0 );
02350 return;
02351 }
02352 QStringList encodings = KMMsgBase::supportedEncodings( false );
02353 encodings.prepend( i18n( "Auto" ) );
02354 QStringList::Iterator it( encodings.begin() );
02355 QStringList::Iterator end( encodings.end() );
02356 uint i = 0;
02357 for( ; it != end; ++it)
02358 {
02359 if( KGlobal::charsets()->encodingForName(*it) == currentOverrideEncoding )
02360 {
02361 mOverrideCharsetCombo->setCurrentItem( i );
02362 break;
02363 }
02364 i++;
02365 }
02366 if ( i == encodings.size() ) {
02367
02368 kdWarning(5006) << "Unknown override character encoding \"" << currentOverrideEncoding
02369 << "\". Resetting to Auto." << endl;
02370 mOverrideCharsetCombo->setCurrentItem( 0 );
02371 GlobalSettings::self()->setOverrideCharacterEncoding( QString::null );
02372 }
02373 }
02374
02375 void AppearancePage::ReaderTab::doLoadFromGlobalSettings()
02376 {
02377 mShowEmoticonsCheck->setChecked( GlobalSettings::self()->showEmoticons() );
02378 mShrinkQuotesCheck->setChecked( GlobalSettings::self()->shrinkQuotes() );
02379 mShowExpandQuotesMark->setChecked( GlobalSettings::self()->showExpandQuotesMark() );
02380 mCollapseQuoteLevelSpin->setValue( GlobalSettings::self()->collapseQuoteLevelSpin() );
02381 readCurrentFallbackCodec();
02382 readCurrentOverrideCodec();
02383 }
02384
02385 void AppearancePage::ReaderTab::doLoadOther()
02386 {
02387 const KConfigGroup reader( KMKernel::config(), "Reader" );
02388 loadWidget( mShowColorbarCheck, reader, showColorbarMode );
02389 loadWidget( mShowSpamStatusCheck, reader, showSpamStatusMode );
02390 }
02391
02392
02393 void AppearancePage::ReaderTab::save() {
02394 KConfigGroup reader( KMKernel::config(), "Reader" );
02395 saveCheckBox( mShowColorbarCheck, reader, showColorbarMode );
02396 saveCheckBox( mShowSpamStatusCheck, reader, showSpamStatusMode );
02397 GlobalSettings::self()->setShowEmoticons( mShowEmoticonsCheck->isChecked() );
02398 GlobalSettings::self()->setShrinkQuotes( mShrinkQuotesCheck->isChecked() );
02399 GlobalSettings::self()->setShowExpandQuotesMark( mShowExpandQuotesMark->isChecked() );
02400
02401 GlobalSettings::self()->setCollapseQuoteLevelSpin( mCollapseQuoteLevelSpin->value() );
02402 GlobalSettings::self()->setFallbackCharacterEncoding(
02403 KGlobal::charsets()->encodingForName( mCharsetCombo->currentText() ) );
02404 GlobalSettings::self()->setOverrideCharacterEncoding(
02405 mOverrideCharsetCombo->currentItem() == 0 ?
02406 QString() :
02407 KGlobal::charsets()->encodingForName( mOverrideCharsetCombo->currentText() ) );
02408 }
02409
02410
02411 void AppearancePage::ReaderTab::installProfile( KConfig * ) {
02412 const KConfigGroup reader( KMKernel::config(), "Reader" );
02413 loadProfile( mShowColorbarCheck, reader, showColorbarMode );
02414 loadProfile( mShowSpamStatusCheck, reader, showSpamStatusMode );
02415 loadProfile( mShowEmoticonsCheck, reader, showEmoticons );
02416 loadProfile( mShrinkQuotesCheck, reader, shrinkQuotes );
02417 loadProfile( mShowExpandQuotesMark, reader, showExpandQuotesMark);
02418 }
02419
02420
02421 QString AppearancePage::SystemTrayTab::helpAnchor() const {
02422 return QString::fromLatin1("configure-appearance-systemtray");
02423 }
02424
02425 AppearancePageSystemTrayTab::AppearancePageSystemTrayTab( QWidget * parent,
02426 const char * name )
02427 : ConfigModuleTab( parent, name )
02428 {
02429 QVBoxLayout * vlay = new QVBoxLayout( this, KDialog::marginHint(),
02430 KDialog::spacingHint() );
02431
02432
02433 mSystemTrayCheck = new QCheckBox( i18n("Enable system tray icon"), this );
02434 vlay->addWidget( mSystemTrayCheck );
02435 connect( mSystemTrayCheck, SIGNAL( stateChanged( int ) ),
02436 this, SLOT( slotEmitChanged( void ) ) );
02437
02438
02439 mSystemTrayGroup = new QVButtonGroup( i18n("System Tray Mode"), this );
02440 mSystemTrayGroup->layout()->setSpacing( KDialog::spacingHint() );
02441 vlay->addWidget( mSystemTrayGroup );
02442 connect( mSystemTrayGroup, SIGNAL( clicked( int ) ),
02443 this, SLOT( slotEmitChanged( void ) ) );
02444 connect( mSystemTrayCheck, SIGNAL( toggled( bool ) ),
02445 mSystemTrayGroup, SLOT( setEnabled( bool ) ) );
02446
02447 mSystemTrayGroup->insert( new QRadioButton( i18n("Always show KMail in system tray"), mSystemTrayGroup ),
02448 GlobalSettings::EnumSystemTrayPolicy::ShowAlways );
02449
02450 mSystemTrayGroup->insert( new QRadioButton( i18n("Only show KMail in system tray if there are unread messages"), mSystemTrayGroup ),
02451 GlobalSettings::EnumSystemTrayPolicy::ShowOnUnread );
02452
02453 vlay->addStretch( 10 );
02454 }
02455
02456 void AppearancePage::SystemTrayTab::doLoadFromGlobalSettings() {
02457 mSystemTrayCheck->setChecked( GlobalSettings::self()->systemTrayEnabled() );
02458 mSystemTrayGroup->setButton( GlobalSettings::self()->systemTrayPolicy() );
02459 mSystemTrayGroup->setEnabled( mSystemTrayCheck->isChecked() );
02460 }
02461
02462 void AppearancePage::SystemTrayTab::installProfile( KConfig * profile ) {
02463 KConfigGroup general( profile, "General" );
02464
02465 if ( general.hasKey( "SystemTrayEnabled" ) ) {
02466 mSystemTrayCheck->setChecked( general.readBoolEntry( "SystemTrayEnabled" ) );
02467 }
02468 if ( general.hasKey( "SystemTrayPolicy" ) ) {
02469 mSystemTrayGroup->setButton( general.readNumEntry( "SystemTrayPolicy" ) );
02470 }
02471 mSystemTrayGroup->setEnabled( mSystemTrayCheck->isChecked() );
02472 }
02473
02474 void AppearancePage::SystemTrayTab::save() {
02475 GlobalSettings::self()->setSystemTrayEnabled( mSystemTrayCheck->isChecked() );
02476 GlobalSettings::self()->setSystemTrayPolicy( mSystemTrayGroup->id( mSystemTrayGroup->selected() ) );
02477 }
02478
02479
02480
02481
02482
02483
02484
02485
02486 QString ComposerPage::helpAnchor() const {
02487 return QString::fromLatin1("configure-composer");
02488 }
02489
02490 ComposerPage::ComposerPage( QWidget * parent, const char * name )
02491 : ConfigModuleWithTabs( parent, name )
02492 {
02493
02494
02495
02496 mGeneralTab = new GeneralTab();
02497 addTab( mGeneralTab, i18n("&General") );
02498 addConfig( GlobalSettings::self(), mGeneralTab );
02499
02500
02501
02502
02503
02504
02505
02506
02507
02508
02509 mTemplatesTab = new TemplatesTab();
02510 addTab( mTemplatesTab, i18n("&Templates") );
02511
02512
02513
02514
02515 mCustomTemplatesTab = new CustomTemplatesTab();
02516 addTab( mCustomTemplatesTab, i18n("&Custom Templates") );
02517
02518
02519
02520
02521 mSubjectTab = new SubjectTab();
02522 addTab( mSubjectTab, i18n("&Subject") );
02523 addConfig( GlobalSettings::self(), mSubjectTab );
02524
02525
02526
02527
02528 mCharsetTab = new CharsetTab();
02529 addTab( mCharsetTab, i18n("Cha&rset") );
02530
02531
02532
02533
02534 mHeadersTab = new HeadersTab();
02535 addTab( mHeadersTab, i18n("H&eaders") );
02536
02537
02538
02539
02540 mAttachmentsTab = new AttachmentsTab();
02541 addTab( mAttachmentsTab, i18n("Config->Composer->Attachments", "A&ttachments") );
02542 load();
02543 }
02544
02545 QString ComposerPage::GeneralTab::helpAnchor() const {
02546 return QString::fromLatin1("configure-composer-general");
02547 }
02548
02549 ComposerPageGeneralTab::ComposerPageGeneralTab( QWidget * parent, const char * name )
02550 : ConfigModuleTab( parent, name )
02551 {
02552
02553 QVBoxLayout *vlay;
02554 QHBoxLayout *hlay;
02555 QGroupBox *group;
02556 QLabel *label;
02557 QHBox *hbox;
02558 QString msg;
02559
02560 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
02561
02562
02563 mAutoAppSignFileCheck = new QCheckBox(
02564 GlobalSettings::self()->autoTextSignatureItem()->label(),
02565 this );
02566 vlay->addWidget( mAutoAppSignFileCheck );
02567 connect( mAutoAppSignFileCheck, SIGNAL( stateChanged(int) ),
02568 this, SLOT( slotEmitChanged( void ) ) );
02569
02570 mSmartQuoteCheck = new QCheckBox(
02571 GlobalSettings::self()->smartQuoteItem()->label(),
02572 this, "kcfg_SmartQuote" );
02573 vlay->addWidget( mSmartQuoteCheck );
02574 connect( mSmartQuoteCheck, SIGNAL( stateChanged(int) ),
02575 this, SLOT( slotEmitChanged( void ) ) );
02576
02577 mAutoRequestMDNCheck = new QCheckBox(
02578 GlobalSettings::self()->requestMDNItem()->label(),
02579 this, "kcfg_RequestMDN" );
02580 vlay->addWidget( mAutoRequestMDNCheck );
02581 connect( mAutoRequestMDNCheck, SIGNAL( stateChanged(int) ),
02582 this, SLOT( slotEmitChanged( void ) ) );
02583
02584 mShowRecentAddressesInComposer = new QCheckBox(
02585 GlobalSettings::self()->showRecentAddressesInComposerItem()->label(),
02586 this, "kcfg_ShowRecentAddressesInComposer" );
02587 vlay->addWidget( mShowRecentAddressesInComposer );
02588 connect( mShowRecentAddressesInComposer, SIGNAL( stateChanged(int) ),
02589 this, SLOT( slotEmitChanged( void ) ) );
02590
02591
02592
02593 hlay = new QHBoxLayout( vlay );
02594 mWordWrapCheck = new QCheckBox(
02595 GlobalSettings::self()->wordWrapItem()->label(),
02596 this, "kcfg_WordWrap" );
02597 hlay->addWidget( mWordWrapCheck );
02598 connect( mWordWrapCheck, SIGNAL( stateChanged(int) ),
02599 this, SLOT( slotEmitChanged( void ) ) );
02600
02601 mWrapColumnSpin = new KIntSpinBox( 30, 78, 1,
02602 78, 10 , this, "kcfg_LineWrapWidth" );
02603 mWrapColumnSpin->setEnabled( false );
02604 connect( mWrapColumnSpin, SIGNAL( valueChanged(int) ),
02605 this, SLOT( slotEmitChanged( void ) ) );
02606
02607 hlay->addWidget( mWrapColumnSpin );
02608 hlay->addStretch( 1 );
02609
02610 connect( mWordWrapCheck, SIGNAL(toggled(bool)),
02611 mWrapColumnSpin, SLOT(setEnabled(bool)) );
02612
02613 hlay = new QHBoxLayout( vlay );
02614 mAutoSave = new KIntSpinBox( 0, 60, 1, 1, 10, this, "kcfg_AutosaveInterval" );
02615 label = new QLabel( mAutoSave,
02616 GlobalSettings::self()->autosaveIntervalItem()->label(), this );
02617 hlay->addWidget( label );
02618 hlay->addWidget( mAutoSave );
02619 mAutoSave->setSpecialValueText( i18n("No autosave") );
02620 mAutoSave->setSuffix( i18n(" min") );
02621 hlay->addStretch( 1 );
02622 connect( mAutoSave, SIGNAL( valueChanged(int) ),
02623 this, SLOT( slotEmitChanged( void ) ) );
02624
02625 hlay = new QHBoxLayout( vlay );
02626 QPushButton *completionOrderBtn = new QPushButton( i18n( "Configure Completion Order" ), this );
02627 connect( completionOrderBtn, SIGNAL( clicked() ),
02628 this, SLOT( slotConfigureCompletionOrder() ) );
02629 hlay->addWidget( completionOrderBtn );
02630 hlay->addItem( new QSpacerItem(0, 0) );
02631
02632
02633 hlay = new QHBoxLayout( vlay );
02634 QPushButton *recentAddressesBtn = new QPushButton( i18n( "Edit Recent Addresses..." ), this );
02635 connect( recentAddressesBtn, SIGNAL( clicked() ),
02636 this, SLOT( slotConfigureRecentAddresses() ) );
02637 hlay->addWidget( recentAddressesBtn );
02638 hlay->addItem( new QSpacerItem(0, 0) );
02639
02640
02641 group = new QVGroupBox( i18n("External Editor"), this );
02642 group->layout()->setSpacing( KDialog::spacingHint() );
02643
02644 mExternalEditorCheck = new QCheckBox(
02645 GlobalSettings::self()->useExternalEditorItem()->label(),
02646 group, "kcfg_UseExternalEditor" );
02647 connect( mExternalEditorCheck, SIGNAL( toggled( bool ) ),
02648 this, SLOT( slotEmitChanged( void ) ) );
02649
02650 hbox = new QHBox( group );
02651 label = new QLabel( GlobalSettings::self()->externalEditorItem()->label(),
02652 hbox );
02653 mEditorRequester = new KURLRequester( hbox, "kcfg_ExternalEditor" );
02654 connect( mEditorRequester, SIGNAL( urlSelected(const QString&) ),
02655 this, SLOT( slotEmitChanged( void ) ) );
02656 connect( mEditorRequester, SIGNAL( textChanged(const QString&) ),
02657 this, SLOT( slotEmitChanged( void ) ) );
02658
02659 hbox->setStretchFactor( mEditorRequester, 1 );
02660 label->setBuddy( mEditorRequester );
02661 label->setEnabled( false );
02662
02663 mEditorRequester->setFilter( "application/x-executable "
02664 "application/x-shellscript "
02665 "application/x-desktop" );
02666 mEditorRequester->setEnabled( false );
02667 connect( mExternalEditorCheck, SIGNAL(toggled(bool)),
02668 label, SLOT(setEnabled(bool)) );
02669 connect( mExternalEditorCheck, SIGNAL(toggled(bool)),
02670 mEditorRequester, SLOT(setEnabled(bool)) );
02671
02672 label = new QLabel( i18n("<b>%f</b> will be replaced with the "
02673 "filename to edit."), group );
02674 label->setEnabled( false );
02675 connect( mExternalEditorCheck, SIGNAL(toggled(bool)),
02676 label, SLOT(setEnabled(bool)) );
02677
02678 vlay->addWidget( group );
02679 vlay->addStretch( 100 );
02680 }
02681
02682 void ComposerPage::GeneralTab::doLoadFromGlobalSettings() {
02683
02684
02685 mAutoAppSignFileCheck->setChecked(
02686 GlobalSettings::self()->autoTextSignature()=="auto" );
02687 mSmartQuoteCheck->setChecked( GlobalSettings::self()->smartQuote() );
02688 mAutoRequestMDNCheck->setChecked( GlobalSettings::self()->requestMDN() );
02689 mWordWrapCheck->setChecked( GlobalSettings::self()->wordWrap() );
02690
02691 mWrapColumnSpin->setValue( GlobalSettings::self()->lineWrapWidth() );
02692 mAutoSave->setValue( GlobalSettings::self()->autosaveInterval() );
02693
02694
02695 mExternalEditorCheck->setChecked( GlobalSettings::self()->useExternalEditor() );
02696 mEditorRequester->setURL( GlobalSettings::self()->externalEditor() );
02697 }
02698
02699 void ComposerPage::GeneralTab::installProfile( KConfig * profile ) {
02700 KConfigGroup composer( profile, "Composer" );
02701 KConfigGroup general( profile, "General" );
02702
02703 if ( composer.hasKey( "signature" ) ) {
02704 bool state = composer.readBoolEntry("signature");
02705 mAutoAppSignFileCheck->setChecked( state );
02706 }
02707 if ( composer.hasKey( "smart-quote" ) )
02708 mSmartQuoteCheck->setChecked( composer.readBoolEntry( "smart-quote" ) );
02709 if ( composer.hasKey( "request-mdn" ) )
02710 mAutoRequestMDNCheck->setChecked( composer.readBoolEntry( "request-mdn" ) );
02711 if ( composer.hasKey( "word-wrap" ) )
02712 mWordWrapCheck->setChecked( composer.readBoolEntry( "word-wrap" ) );
02713 if ( composer.hasKey( "break-at" ) )
02714 mWrapColumnSpin->setValue( composer.readNumEntry( "break-at" ) );
02715 if ( composer.hasKey( "autosave" ) )
02716 mAutoSave->setValue( composer.readNumEntry( "autosave" ) );
02717
02718 if ( general.hasKey( "use-external-editor" )
02719 && general.hasKey( "external-editor" ) ) {
02720 mExternalEditorCheck->setChecked( general.readBoolEntry( "use-external-editor" ) );
02721 mEditorRequester->setURL( general.readPathEntry( "external-editor" ) );
02722 }
02723 }
02724
02725 void ComposerPage::GeneralTab::save() {
02726 GlobalSettings::self()->setAutoTextSignature(
02727 mAutoAppSignFileCheck->isChecked() ? "auto" : "manual" );
02728 GlobalSettings::self()->setSmartQuote( mSmartQuoteCheck->isChecked() );
02729 GlobalSettings::self()->setRequestMDN( mAutoRequestMDNCheck->isChecked() );
02730 GlobalSettings::self()->setWordWrap( mWordWrapCheck->isChecked() );
02731
02732 GlobalSettings::self()->setLineWrapWidth( mWrapColumnSpin->value() );
02733 GlobalSettings::self()->setAutosaveInterval( mAutoSave->value() );
02734
02735
02736 GlobalSettings::self()->setUseExternalEditor( mExternalEditorCheck->isChecked() );
02737 GlobalSettings::self()->setExternalEditor( mEditorRequester->url() );
02738 }
02739
02740 void ComposerPage::GeneralTab::slotConfigureRecentAddresses( )
02741 {
02742 KRecentAddress::RecentAddressDialog dlg( this );
02743 dlg.setAddresses( RecentAddresses::self( KMKernel::config() )->addresses() );
02744 if ( dlg.exec() ) {
02745 RecentAddresses::self( KMKernel::config() )->clear();
02746 const QStringList &addrList = dlg.addresses();
02747 QStringList::ConstIterator it;
02748 for ( it = addrList.constBegin(); it != addrList.constEnd(); ++it )
02749 RecentAddresses::self( KMKernel::config() )->add( *it );
02750 }
02751 }
02752
02753 void ComposerPage::GeneralTab::slotConfigureCompletionOrder( )
02754 {
02755 KPIM::LdapSearch search;
02756 KPIM::CompletionOrderEditor editor( &search, this );
02757 editor.exec();
02758 }
02759
02760 QString ComposerPage::PhrasesTab::helpAnchor() const {
02761 return QString::fromLatin1("configure-composer-phrases");
02762 }
02763
02764 ComposerPagePhrasesTab::ComposerPagePhrasesTab( QWidget * parent, const char * name )
02765 : ConfigModuleTab( parent, name )
02766 {
02767
02768 QGridLayout *glay;
02769 QPushButton *button;
02770
02771 glay = new QGridLayout( this, 7, 3, KDialog::spacingHint() );
02772 glay->setMargin( KDialog::marginHint() );
02773 glay->setColStretch( 1, 1 );
02774 glay->setColStretch( 2, 1 );
02775 glay->setRowStretch( 7, 1 );
02776
02777
02778 glay->addMultiCellWidget( new QLabel( i18n("<qt>The following placeholders are "
02779 "supported in the reply phrases:<br>"
02780 "<b>%D</b>: date, <b>%S</b>: subject,<br>"
02781 "<b>%e</b>: sender's address, <b>%F</b>: sender's name, <b>%f</b>: sender's initials,<br>"
02782 "<b>%T</b>: recipient's name, <b>%t</b>: recipient's name and address,<br>"
02783 "<b>%C</b>: carbon copy names, <b>%c</b>: carbon copy names and addresses,<br>"
02784 "<b>%%</b>: percent sign, <b>%_</b>: space, "
02785 "<b>%L</b>: linebreak</qt>"), this ),
02786 0, 0, 0, 2 );
02787
02788
02789 mPhraseLanguageCombo = new LanguageComboBox( false, this );
02790 glay->addWidget( new QLabel( mPhraseLanguageCombo,
02791 i18n("Lang&uage:"), this ), 1, 0 );
02792 glay->addMultiCellWidget( mPhraseLanguageCombo, 1, 1, 1, 2 );
02793 connect( mPhraseLanguageCombo, SIGNAL(activated(const QString&)),
02794 this, SLOT(slotLanguageChanged(const QString&)) );
02795
02796
02797 button = new QPushButton( i18n("A&dd..."), this );
02798 button->setAutoDefault( false );
02799 glay->addWidget( button, 2, 1 );
02800 mRemoveButton = new QPushButton( i18n("Re&move"), this );
02801 mRemoveButton->setAutoDefault( false );
02802 mRemoveButton->setEnabled( false );
02803 glay->addWidget( mRemoveButton, 2, 2 );
02804 connect( button, SIGNAL(clicked()),
02805 this, SLOT(slotNewLanguage()) );
02806 connect( mRemoveButton, SIGNAL(clicked()),
02807 this, SLOT(slotRemoveLanguage()) );
02808
02809
02810 mPhraseReplyEdit = new KLineEdit( this );
02811 connect( mPhraseReplyEdit, SIGNAL( textChanged( const QString& ) ),
02812 this, SLOT( slotEmitChanged( void ) ) );
02813 glay->addWidget( new QLabel( mPhraseReplyEdit,
02814 i18n("Reply to se&nder:"), this ), 3, 0 );
02815 glay->addMultiCellWidget( mPhraseReplyEdit, 3, 3, 1, 2 );
02816
02817
02818 mPhraseReplyAllEdit = new KLineEdit( this );
02819 connect( mPhraseReplyAllEdit, SIGNAL( textChanged( const QString& ) ),
02820 this, SLOT( slotEmitChanged( void ) ) );
02821 glay->addWidget( new QLabel( mPhraseReplyAllEdit,
02822 i18n("Repl&y to all:"), this ), 4, 0 );
02823 glay->addMultiCellWidget( mPhraseReplyAllEdit, 4, 4, 1, 2 );
02824
02825
02826 mPhraseForwardEdit = new KLineEdit( this );
02827 connect( mPhraseForwardEdit, SIGNAL( textChanged( const QString& ) ),
02828 this, SLOT( slotEmitChanged( void ) ) );
02829 glay->addWidget( new QLabel( mPhraseForwardEdit,
02830 i18n("&Forward:"), this ), 5, 0 );
02831 glay->addMultiCellWidget( mPhraseForwardEdit, 5, 5, 1, 2 );
02832
02833
02834 mPhraseIndentPrefixEdit = new KLineEdit( this );
02835 connect( mPhraseIndentPrefixEdit, SIGNAL( textChanged( const QString& ) ),
02836 this, SLOT( slotEmitChanged( void ) ) );
02837 glay->addWidget( new QLabel( mPhraseIndentPrefixEdit,
02838 i18n("&Quote indicator:"), this ), 6, 0 );
02839 glay->addMultiCellWidget( mPhraseIndentPrefixEdit, 6, 6, 1, 2 );
02840
02841
02842 }
02843
02844
02845 void ComposerPage::PhrasesTab::setLanguageItemInformation( int index ) {
02846 assert( 0 <= index && index < (int)mLanguageList.count() );
02847
02848 LanguageItem &l = *mLanguageList.at( index );
02849
02850 mPhraseReplyEdit->setText( l.mReply );
02851 mPhraseReplyAllEdit->setText( l.mReplyAll );
02852 mPhraseForwardEdit->setText( l.mForward );
02853 mPhraseIndentPrefixEdit->setText( l.mIndentPrefix );
02854 }
02855
02856 void ComposerPage::PhrasesTab::saveActiveLanguageItem() {
02857 int index = mActiveLanguageItem;
02858 if (index == -1) return;
02859 assert( 0 <= index && index < (int)mLanguageList.count() );
02860
02861 LanguageItem &l = *mLanguageList.at( index );
02862
02863 l.mReply = mPhraseReplyEdit->text();
02864 l.mReplyAll = mPhraseReplyAllEdit->text();
02865 l.mForward = mPhraseForwardEdit->text();
02866 l.mIndentPrefix = mPhraseIndentPrefixEdit->text();
02867 }
02868
02869 void ComposerPage::PhrasesTab::slotNewLanguage()
02870 {
02871 NewLanguageDialog dialog( mLanguageList, parentWidget(), "New", true );
02872 if ( dialog.exec() == QDialog::Accepted ) slotAddNewLanguage( dialog.language() );
02873 }
02874
02875 void ComposerPage::PhrasesTab::slotAddNewLanguage( const QString& lang )
02876 {
02877 mPhraseLanguageCombo->setCurrentItem(
02878 mPhraseLanguageCombo->insertLanguage( lang ) );
02879 KLocale locale("kmail");
02880 locale.setLanguage( lang );
02881 mLanguageList.append(
02882 LanguageItem( lang,
02883 locale.translate("On %D, you wrote:"),
02884 locale.translate("On %D, %F wrote:"),
02885 locale.translate("Forwarded Message"),
02886 locale.translate(">%_") ) );
02887 mRemoveButton->setEnabled( true );
02888 slotLanguageChanged( QString::null );
02889 }
02890
02891 void ComposerPage::PhrasesTab::slotRemoveLanguage()
02892 {
02893 assert( mPhraseLanguageCombo->count() > 1 );
02894 int index = mPhraseLanguageCombo->currentItem();
02895 assert( 0 <= index && index < (int)mLanguageList.count() );
02896
02897
02898 mLanguageList.remove( mLanguageList.at( index ) );
02899 mPhraseLanguageCombo->removeItem( index );
02900
02901 if ( index >= (int)mLanguageList.count() ) index--;
02902
02903 mActiveLanguageItem = index;
02904 setLanguageItemInformation( index );
02905 mRemoveButton->setEnabled( mLanguageList.count() > 1 );
02906 emit changed( true );
02907 }
02908
02909 void ComposerPage::PhrasesTab::slotLanguageChanged( const QString& )
02910 {
02911 int index = mPhraseLanguageCombo->currentItem();
02912 assert( index < (int)mLanguageList.count() );
02913 saveActiveLanguageItem();
02914 mActiveLanguageItem = index;
02915 setLanguageItemInformation( index );
02916 emit changed( true );
02917 }
02918
02919
02920 void ComposerPage::PhrasesTab::doLoadFromGlobalSettings() {
02921 mLanguageList.clear();
02922 mPhraseLanguageCombo->clear();
02923 mActiveLanguageItem = -1;
02924
02925 int numLang = GlobalSettings::self()->replyLanguagesCount();
02926 int currentNr = GlobalSettings::self()->replyCurrentLanguage();
02927
02928
02929 for ( int i = 0 ; i < numLang ; i++ ) {
02930 ReplyPhrases replyPhrases( QString::number(i) );
02931 replyPhrases.readConfig();
02932 QString lang = replyPhrases.language();
02933 mLanguageList.append(
02934 LanguageItem( lang,
02935 replyPhrases.phraseReplySender(),
02936 replyPhrases.phraseReplyAll(),
02937 replyPhrases.phraseForward(),
02938 replyPhrases.indentPrefix() ) );
02939 mPhraseLanguageCombo->insertLanguage( lang );
02940 }
02941
02942 if ( currentNr >= numLang || currentNr < 0 )
02943 currentNr = 0;
02944
02945 if ( numLang == 0 ) {
02946 slotAddNewLanguage( KGlobal::locale()->language() );
02947 }
02948
02949 mPhraseLanguageCombo->setCurrentItem( currentNr );
02950 mActiveLanguageItem = currentNr;
02951 setLanguageItemInformation( currentNr );
02952 mRemoveButton->setEnabled( mLanguageList.count() > 1 );
02953 }
02954
02955 void ComposerPage::PhrasesTab::save() {
02956 GlobalSettings::self()->setReplyLanguagesCount( mLanguageList.count() );
02957 GlobalSettings::self()->setReplyCurrentLanguage( mPhraseLanguageCombo->currentItem() );
02958
02959 saveActiveLanguageItem();
02960 LanguageItemList::Iterator it = mLanguageList.begin();
02961 for ( int i = 0 ; it != mLanguageList.end() ; ++it, ++i ) {
02962 ReplyPhrases replyPhrases( QString::number(i) );
02963 replyPhrases.setLanguage( (*it).mLanguage );
02964 replyPhrases.setPhraseReplySender( (*it).mReply );
02965 replyPhrases.setPhraseReplyAll( (*it).mReplyAll );
02966 replyPhrases.setPhraseForward( (*it).mForward );
02967 replyPhrases.setIndentPrefix( (*it).mIndentPrefix );
02968 replyPhrases.writeConfig();
02969 }
02970 }
02971
02972 QString ComposerPage::TemplatesTab::helpAnchor() const {
02973 return QString::fromLatin1("configure-composer-templates");
02974 }
02975
02976 ComposerPageTemplatesTab::ComposerPageTemplatesTab( QWidget * parent, const char * name )
02977 : ConfigModuleTab ( parent, name )
02978 {
02979 QVBoxLayout* vlay = new QVBoxLayout( this, 0, KDialog::spacingHint() );
02980
02981 mWidget = new TemplatesConfiguration( this );
02982 vlay->addWidget( mWidget );
02983
02984 connect( mWidget, SIGNAL( changed() ),
02985 this, SLOT( slotEmitChanged( void ) ) );
02986 }
02987
02988 void ComposerPage::TemplatesTab::doLoadFromGlobalSettings() {
02989 mWidget->loadFromGlobal();
02990 }
02991
02992 void ComposerPage::TemplatesTab::save() {
02993 mWidget->saveToGlobal();
02994 }
02995
02996 QString ComposerPage::CustomTemplatesTab::helpAnchor() const {
02997 return QString::fromLatin1("configure-composer-custom-templates");
02998 }
02999
03000 ComposerPageCustomTemplatesTab::ComposerPageCustomTemplatesTab( QWidget * parent, const char * name )
03001 : ConfigModuleTab ( parent, name )
03002 {
03003 QVBoxLayout* vlay = new QVBoxLayout( this, 0, KDialog::spacingHint() );
03004
03005 mWidget = new CustomTemplates( this );
03006 vlay->addWidget( mWidget );
03007
03008 connect( mWidget, SIGNAL( changed() ),
03009 this, SLOT( slotEmitChanged( void ) ) );
03010 }
03011
03012 void ComposerPage::CustomTemplatesTab::doLoadFromGlobalSettings() {
03013 mWidget->load();
03014 }
03015
03016 void ComposerPage::CustomTemplatesTab::save() {
03017 mWidget->save();
03018 }
03019
03020 QString ComposerPage::SubjectTab::helpAnchor() const {
03021 return QString::fromLatin1("configure-composer-subject");
03022 }
03023
03024 ComposerPageSubjectTab::ComposerPageSubjectTab( QWidget * parent, const char * name )
03025 : ConfigModuleTab( parent, name )
03026 {
03027
03028 QVBoxLayout *vlay;
03029 QGroupBox *group;
03030 QLabel *label;
03031
03032
03033 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
03034
03035 group = new QVGroupBox( i18n("Repl&y Subject Prefixes"), this );
03036 group->layout()->setSpacing( KDialog::spacingHint() );
03037
03038
03039 label = new QLabel( i18n("Recognize any sequence of the following prefixes\n"
03040 "(entries are case-insensitive regular expressions):"), group );
03041 label->setAlignment( AlignLeft|WordBreak );
03042
03043
03044 SimpleStringListEditor::ButtonCode buttonCode =
03045 static_cast<SimpleStringListEditor::ButtonCode>( SimpleStringListEditor::Add | SimpleStringListEditor::Remove | SimpleStringListEditor::Modify );
03046 mReplyListEditor =
03047 new SimpleStringListEditor( group, 0, buttonCode,
03048 i18n("A&dd..."), i18n("Re&move"),
03049 i18n("Mod&ify..."),
03050 i18n("Enter new reply prefix:") );
03051 connect( mReplyListEditor, SIGNAL( changed( void ) ),
03052 this, SLOT( slotEmitChanged( void ) ) );
03053
03054
03055 mReplaceReplyPrefixCheck = new QCheckBox(
03056 GlobalSettings::self()->replaceReplyPrefixItem()->label(),
03057 group, "kcfg_ReplaceReplyPrefix" );
03058 connect( mReplaceReplyPrefixCheck, SIGNAL( stateChanged( int ) ),
03059 this, SLOT( slotEmitChanged( void ) ) );
03060
03061 vlay->addWidget( group );
03062
03063
03064 group = new QVGroupBox( i18n("For&ward Subject Prefixes"), this );
03065 group->layout()->setSpacing( KDialog::marginHint() );
03066
03067
03068 label= new QLabel( i18n("Recognize any sequence of the following prefixes\n"
03069 "(entries are case-insensitive regular expressions):"), group );
03070 label->setAlignment( AlignLeft|WordBreak );
03071
03072
03073 mForwardListEditor =
03074 new SimpleStringListEditor( group, 0, buttonCode,
03075 i18n("Add..."),
03076 i18n("Remo&ve"),
03077 i18n("Modify..."),
03078 i18n("Enter new forward prefix:") );
03079 connect( mForwardListEditor, SIGNAL( changed( void ) ),
03080 this, SLOT( slotEmitChanged( void ) ) );
03081
03082
03083 mReplaceForwardPrefixCheck = new QCheckBox(
03084 GlobalSettings::self()->replaceForwardPrefixItem()->label(),
03085 group, "kcfg_ReplaceForwardPrefix" );
03086 connect( mReplaceForwardPrefixCheck, SIGNAL( stateChanged( int ) ),
03087 this, SLOT( slotEmitChanged( void ) ) );
03088
03089 vlay->addWidget( group );
03090 }
03091
03092 void ComposerPage::SubjectTab::doLoadFromGlobalSettings() {
03093 mReplyListEditor->setStringList( GlobalSettings::self()->replyPrefixes() );
03094 mReplaceReplyPrefixCheck->setChecked( GlobalSettings::self()->replaceReplyPrefix() );
03095 mForwardListEditor->setStringList( GlobalSettings::self()->forwardPrefixes() );
03096 mReplaceForwardPrefixCheck->setChecked( GlobalSettings::self()->replaceForwardPrefix() );
03097 }
03098
03099 void ComposerPage::SubjectTab::save() {
03100 GlobalSettings::self()->setReplyPrefixes( mReplyListEditor->stringList() );
03101 GlobalSettings::self()->setForwardPrefixes( mForwardListEditor->stringList() );
03102 }
03103
03104 QString ComposerPage::CharsetTab::helpAnchor() const {
03105 return QString::fromLatin1("configure-composer-charset");
03106 }
03107
03108 ComposerPageCharsetTab::ComposerPageCharsetTab( QWidget * parent, const char * name )
03109 : ConfigModuleTab( parent, name )
03110 {
03111
03112 QVBoxLayout *vlay;
03113 QLabel *label;
03114
03115 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
03116
03117 label = new QLabel( i18n("This list is checked for every outgoing message "
03118 "from the top to the bottom for a charset that "
03119 "contains all required characters."), this );
03120 label->setAlignment( WordBreak);
03121 vlay->addWidget( label );
03122
03123 mCharsetListEditor =
03124 new SimpleStringListEditor( this, 0, SimpleStringListEditor::All,
03125 i18n("A&dd..."), i18n("Remo&ve"),
03126 i18n("&Modify..."), i18n("Enter charset:") );
03127 connect( mCharsetListEditor, SIGNAL( changed( void ) ),
03128 this, SLOT( slotEmitChanged( void ) ) );
03129
03130 vlay->addWidget( mCharsetListEditor, 1 );
03131
03132 mKeepReplyCharsetCheck = new QCheckBox( i18n("&Keep original charset when "
03133 "replying or forwarding (if "
03134 "possible)"), this );
03135 connect( mKeepReplyCharsetCheck, SIGNAL ( stateChanged( int ) ),
03136 this, SLOT( slotEmitChanged( void ) ) );
03137 vlay->addWidget( mKeepReplyCharsetCheck );
03138
03139 connect( mCharsetListEditor, SIGNAL(aboutToAdd(QString&)),
03140 this, SLOT(slotVerifyCharset(QString&)) );
03141 }
03142
03143 void ComposerPage::CharsetTab::slotVerifyCharset( QString & charset ) {
03144 if ( charset.isEmpty() ) return;
03145
03146
03147
03148 if ( charset.lower() == QString::fromLatin1("us-ascii") ) {
03149 charset = QString::fromLatin1("us-ascii");
03150 return;
03151 }
03152
03153 if ( charset.lower() == QString::fromLatin1("locale") ) {
03154 charset = QString::fromLatin1("%1 (locale)")
03155 .arg( QCString( kmkernel->networkCodec()->mimeName() ).lower() );
03156 return;
03157 }
03158
03159 bool ok = false;
03160 QTextCodec *codec = KGlobal::charsets()->codecForName( charset, ok );
03161 if ( ok && codec ) {
03162 charset = QString::fromLatin1( codec->mimeName() ).lower();
03163 return;
03164 }
03165
03166 KMessageBox::sorry( this, i18n("This charset is not supported.") );
03167 charset = QString::null;
03168 }
03169
03170 void ComposerPage::CharsetTab::doLoadOther() {
03171 KConfigGroup composer( KMKernel::config(), "Composer" );
03172
03173 QStringList charsets = composer.readListEntry( "pref-charsets" );
03174 for ( QStringList::Iterator it = charsets.begin() ;
03175 it != charsets.end() ; ++it )
03176 if ( (*it) == QString::fromLatin1("locale") ) {
03177 QCString cset = kmkernel->networkCodec()->mimeName();
03178 KPIM::kAsciiToLower( cset.data() );
03179 (*it) = QString("%1 (locale)").arg( cset );
03180 }
03181
03182 mCharsetListEditor->setStringList( charsets );
03183 mKeepReplyCharsetCheck->setChecked( !composer.readBoolEntry( "force-reply-charset", false ) );
03184 }
03185
03186 void ComposerPage::CharsetTab::save() {
03187 KConfigGroup composer( KMKernel::config(), "Composer" );
03188
03189 QStringList charsetList = mCharsetListEditor->stringList();
03190 QStringList::Iterator it = charsetList.begin();
03191 for ( ; it != charsetList.end() ; ++it )
03192 if ( (*it).endsWith("(locale)") )
03193 (*it) = "locale";
03194 composer.writeEntry( "pref-charsets", charsetList );
03195 composer.writeEntry( "force-reply-charset",
03196 !mKeepReplyCharsetCheck->isChecked() );
03197 }
03198
03199 QString ComposerPage::HeadersTab::helpAnchor() const {
03200 return QString::fromLatin1("configure-composer-headers");
03201 }
03202
03203 ComposerPageHeadersTab::ComposerPageHeadersTab( QWidget * parent, const char * name )
03204 : ConfigModuleTab( parent, name )
03205 {
03206
03207 QVBoxLayout *vlay;
03208 QHBoxLayout *hlay;
03209 QGridLayout *glay;
03210 QLabel *label;
03211 QPushButton *button;
03212
03213 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
03214
03215
03216 mCreateOwnMessageIdCheck =
03217 new QCheckBox( i18n("&Use custom message-id suffix"), this );
03218 connect( mCreateOwnMessageIdCheck, SIGNAL ( stateChanged( int ) ),
03219 this, SLOT( slotEmitChanged( void ) ) );
03220 vlay->addWidget( mCreateOwnMessageIdCheck );
03221
03222
03223 hlay = new QHBoxLayout( vlay );
03224 mMessageIdSuffixEdit = new KLineEdit( this );
03225
03226 mMessageIdSuffixValidator =
03227 new QRegExpValidator( QRegExp( "[a-zA-Z0-9+-]+(?:\\.[a-zA-Z0-9+-]+)*" ), this );
03228 mMessageIdSuffixEdit->setValidator( mMessageIdSuffixValidator );
03229 label = new QLabel( mMessageIdSuffixEdit,
03230 i18n("Custom message-&id suffix:"), this );
03231 label->setEnabled( false );
03232 mMessageIdSuffixEdit->setEnabled( false );
03233 hlay->addWidget( label );
03234 hlay->addWidget( mMessageIdSuffixEdit, 1 );
03235 connect( mCreateOwnMessageIdCheck, SIGNAL(toggled(bool) ),
03236 label, SLOT(setEnabled(bool)) );
03237 connect( mCreateOwnMessageIdCheck, SIGNAL(toggled(bool) ),
03238 mMessageIdSuffixEdit, SLOT(setEnabled(bool)) );
03239 connect( mMessageIdSuffixEdit, SIGNAL( textChanged( const QString& ) ),
03240 this, SLOT( slotEmitChanged( void ) ) );
03241
03242
03243 vlay->addWidget( new KSeparator( KSeparator::HLine, this ) );
03244 vlay->addWidget( new QLabel( i18n("Define custom mime header fields:"), this) );
03245
03246
03247 glay = new QGridLayout( vlay, 5, 3 );
03248 glay->setRowStretch( 2, 1 );
03249 glay->setColStretch( 1, 1 );
03250 mTagList = new ListView( this, "tagList" );
03251 mTagList->addColumn( i18n("Name") );
03252 mTagList->addColumn( i18n("Value") );
03253 mTagList->setAllColumnsShowFocus( true );
03254 mTagList->setSorting( -1 );
03255 connect( mTagList, SIGNAL(selectionChanged()),
03256 this, SLOT(slotMimeHeaderSelectionChanged()) );
03257 glay->addMultiCellWidget( mTagList, 0, 2, 0, 1 );
03258
03259
03260 button = new QPushButton( i18n("Ne&w"), this );
03261 connect( button, SIGNAL(clicked()), this, SLOT(slotNewMimeHeader()) );
03262 button->setAutoDefault( false );
03263 glay->addWidget( button, 0, 2 );
03264 mRemoveHeaderButton = new QPushButton( i18n("Re&move"), this );
03265 connect( mRemoveHeaderButton, SIGNAL(clicked()),
03266 this, SLOT(slotRemoveMimeHeader()) );
03267 button->setAutoDefault( false );
03268 glay->addWidget( mRemoveHeaderButton, 1, 2 );
03269
03270
03271 mTagNameEdit = new KLineEdit( this );
03272 mTagNameEdit->setEnabled( false );
03273 mTagNameLabel = new QLabel( mTagNameEdit, i18n("&Name:"), this );
03274 mTagNameLabel->setEnabled( false );
03275 glay->addWidget( mTagNameLabel, 3, 0 );
03276 glay->addWidget( mTagNameEdit, 3, 1 );
03277 connect( mTagNameEdit, SIGNAL(textChanged(const QString&)),
03278 this, SLOT(slotMimeHeaderNameChanged(const QString&)) );
03279
03280 mTagValueEdit = new KLineEdit( this );
03281 mTagValueEdit->setEnabled( false );
03282 mTagValueLabel = new QLabel( mTagValueEdit, i18n("&Value:"), this );
03283 mTagValueLabel->setEnabled( false );
03284 glay->addWidget( mTagValueLabel, 4, 0 );
03285 glay->addWidget( mTagValueEdit, 4, 1 );
03286 connect( mTagValueEdit, SIGNAL(textChanged(const QString&)),
03287 this, SLOT(slotMimeHeaderValueChanged(const QString&)) );
03288 }
03289
03290 void ComposerPage::HeadersTab::slotMimeHeaderSelectionChanged()
03291 {
03292 QListViewItem * item = mTagList->selectedItem();
03293
03294 if ( item ) {
03295 mTagNameEdit->setText( item->text( 0 ) );
03296 mTagValueEdit->setText( item->text( 1 ) );
03297 } else {
03298 mTagNameEdit->clear();
03299 mTagValueEdit->clear();
03300 }
03301 mRemoveHeaderButton->setEnabled( item );
03302 mTagNameEdit->setEnabled( item );
03303 mTagValueEdit->setEnabled( item );
03304 mTagNameLabel->setEnabled( item );
03305 mTagValueLabel->setEnabled( item );
03306 }
03307
03308
03309 void ComposerPage::HeadersTab::slotMimeHeaderNameChanged( const QString & text ) {
03310
03311
03312 QListViewItem * item = mTagList->selectedItem();
03313 if ( item )
03314 item->setText( 0, text );
03315 emit changed( true );
03316 }
03317
03318
03319 void ComposerPage::HeadersTab::slotMimeHeaderValueChanged( const QString & text ) {
03320
03321
03322 QListViewItem * item = mTagList->selectedItem();
03323 if ( item )
03324 item->setText( 1, text );
03325 emit changed( true );
03326 }
03327
03328
03329 void ComposerPage::HeadersTab::slotNewMimeHeader()
03330 {
03331 QListViewItem *listItem = new QListViewItem( mTagList );
03332 mTagList->setCurrentItem( listItem );
03333 mTagList->setSelected( listItem, true );
03334 emit changed( true );
03335 }
03336
03337
03338 void ComposerPage::HeadersTab::slotRemoveMimeHeader()
03339 {
03340
03341 QListViewItem * item = mTagList->selectedItem();
03342 if ( !item ) {
03343 kdDebug(5006) << "==================================================\n"
03344 << "Error: Remove button was pressed although no custom header was selected\n"
03345 << "==================================================\n";
03346 return;
03347 }
03348
03349 QListViewItem * below = item->nextSibling();
03350 delete item;
03351
03352 if ( below )
03353 mTagList->setSelected( below, true );
03354 else if ( mTagList->lastItem() )
03355 mTagList->setSelected( mTagList->lastItem(), true );
03356 emit changed( true );
03357 }
03358
03359 void ComposerPage::HeadersTab::doLoadOther() {
03360 KConfigGroup general( KMKernel::config(), "General" );
03361
03362 QString suffix = general.readEntry( "myMessageIdSuffix" );
03363 mMessageIdSuffixEdit->setText( suffix );
03364 bool state = ( !suffix.isEmpty() &&
03365 general.readBoolEntry( "useCustomMessageIdSuffix", false ) );
03366 mCreateOwnMessageIdCheck->setChecked( state );
03367
03368 mTagList->clear();
03369 mTagNameEdit->clear();
03370 mTagValueEdit->clear();
03371
03372 QListViewItem * item = 0;
03373
03374 int count = general.readNumEntry( "mime-header-count", 0 );
03375 for( int i = 0 ; i < count ; i++ ) {
03376 KConfigGroup config( KMKernel::config(),
03377 QCString("Mime #") + QCString().setNum(i) );
03378 QString name = config.readEntry( "name" );
03379 QString value = config.readEntry( "value" );
03380 if( !name.isEmpty() )
03381 item = new QListViewItem( mTagList, item, name, value );
03382 }
03383 if ( mTagList->childCount() ) {
03384 mTagList->setCurrentItem( mTagList->firstChild() );
03385 mTagList->setSelected( mTagList->firstChild(), true );
03386 }
03387 else {
03388
03389 mRemoveHeaderButton->setEnabled( false );
03390 }
03391 }
03392
03393 void ComposerPage::HeadersTab::save() {
03394 KConfigGroup general( KMKernel::config(), "General" );
03395
03396 general.writeEntry( "useCustomMessageIdSuffix",
03397 mCreateOwnMessageIdCheck->isChecked() );
03398 general.writeEntry( "myMessageIdSuffix",
03399 mMessageIdSuffixEdit->text() );
03400
03401 int numValidEntries = 0;
03402 QListViewItem * item = mTagList->firstChild();
03403 for ( ; item ; item = item->itemBelow() )
03404 if( !item->text(0).isEmpty() ) {
03405 KConfigGroup config( KMKernel::config(), QCString("Mime #")
03406 + QCString().setNum( numValidEntries ) );
03407 config.writeEntry( "name", item->text( 0 ) );
03408 config.writeEntry( "value", item->text( 1 ) );
03409 numValidEntries++;
03410 }
03411 general.writeEntry( "mime-header-count", numValidEntries );
03412 }
03413
03414 QString ComposerPage::AttachmentsTab::helpAnchor() const {
03415 return QString::fromLatin1("configure-composer-attachments");
03416 }
03417
03418 ComposerPageAttachmentsTab::ComposerPageAttachmentsTab( QWidget * parent,
03419 const char * name )
03420 : ConfigModuleTab( parent, name ) {
03421
03422 QVBoxLayout *vlay;
03423 QLabel *label;
03424
03425 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
03426
03427
03428 mOutlookCompatibleCheck =
03429 new QCheckBox( i18n( "Outlook-compatible attachment naming" ), this );
03430 mOutlookCompatibleCheck->setChecked( false );
03431 QToolTip::add( mOutlookCompatibleCheck, i18n(
03432 "Turn this option on to make Outlook(tm) understand attachment names "
03433 "containing non-English characters" ) );
03434 connect( mOutlookCompatibleCheck, SIGNAL( stateChanged( int ) ),
03435 this, SLOT( slotEmitChanged( void ) ) );
03436 connect( mOutlookCompatibleCheck, SIGNAL( clicked() ),
03437 this, SLOT( slotOutlookCompatibleClicked() ) );
03438 vlay->addWidget( mOutlookCompatibleCheck );
03439 vlay->addSpacing( 5 );
03440
03441
03442 mMissingAttachmentDetectionCheck =
03443 new QCheckBox( i18n("E&nable detection of missing attachments"), this );
03444 mMissingAttachmentDetectionCheck->setChecked( true );
03445 connect( mMissingAttachmentDetectionCheck, SIGNAL( stateChanged( int ) ),
03446 this, SLOT( slotEmitChanged( void ) ) );
03447 vlay->addWidget( mMissingAttachmentDetectionCheck );
03448
03449
03450 label = new QLabel( i18n("Recognize any of the following key words as "
03451 "intention to attach a file:"), this );
03452 label->setAlignment( AlignLeft|WordBreak );
03453 vlay->addWidget( label );
03454
03455 SimpleStringListEditor::ButtonCode buttonCode =
03456 static_cast<SimpleStringListEditor::ButtonCode>( SimpleStringListEditor::Add | SimpleStringListEditor::Remove | SimpleStringListEditor::Modify );
03457 mAttachWordsListEditor =
03458 new SimpleStringListEditor( this, 0, buttonCode,
03459 i18n("A&dd..."), i18n("Re&move"),
03460 i18n("Mod&ify..."),
03461 i18n("Enter new key word:") );
03462 connect( mAttachWordsListEditor, SIGNAL( changed( void ) ),
03463 this, SLOT( slotEmitChanged( void ) ) );
03464 vlay->addWidget( mAttachWordsListEditor );
03465
03466 connect( mMissingAttachmentDetectionCheck, SIGNAL(toggled(bool) ),
03467 label, SLOT(setEnabled(bool)) );
03468 connect( mMissingAttachmentDetectionCheck, SIGNAL(toggled(bool) ),
03469 mAttachWordsListEditor, SLOT(setEnabled(bool)) );
03470 }
03471
03472 void ComposerPage::AttachmentsTab::doLoadFromGlobalSettings() {
03473 mOutlookCompatibleCheck->setChecked(
03474 GlobalSettings::self()->outlookCompatibleAttachments() );
03475 mMissingAttachmentDetectionCheck->setChecked(
03476 GlobalSettings::self()->showForgottenAttachmentWarning() );
03477 QStringList attachWordsList = GlobalSettings::self()->attachmentKeywords();
03478 if ( attachWordsList.isEmpty() ) {
03479
03480 attachWordsList << QString::fromLatin1("attachment")
03481 << QString::fromLatin1("attached");
03482 if ( QString::fromLatin1("attachment") != i18n("attachment") )
03483 attachWordsList << i18n("attachment");
03484 if ( QString::fromLatin1("attached") != i18n("attached") )
03485 attachWordsList << i18n("attached");
03486 }
03487
03488 mAttachWordsListEditor->setStringList( attachWordsList );
03489 }
03490
03491 void ComposerPage::AttachmentsTab::save() {
03492 GlobalSettings::self()->setOutlookCompatibleAttachments(
03493 mOutlookCompatibleCheck->isChecked() );
03494 GlobalSettings::self()->setShowForgottenAttachmentWarning(
03495 mMissingAttachmentDetectionCheck->isChecked() );
03496 GlobalSettings::self()->setAttachmentKeywords(
03497 mAttachWordsListEditor->stringList() );
03498 }
03499
03500 void ComposerPageAttachmentsTab::slotOutlookCompatibleClicked()
03501 {
03502 if (mOutlookCompatibleCheck->isChecked()) {
03503 KMessageBox::information(0,i18n("You have chosen to "
03504 "encode attachment names containing non-English characters in a way that "
03505 "is understood by Outlook(tm) and other mail clients that do not "
03506 "support standard-compliant encoded attachment names.\n"
03507 "Note that KMail may create non-standard compliant messages, "
03508 "and consequently it is possible that your messages will not be "
03509 "understood by standard-compliant mail clients; so, unless you have no "
03510 "other choice, you should not enable this option." ) );
03511 }
03512 }
03513
03514
03515
03516
03517
03518
03519 QString SecurityPage::helpAnchor() const {
03520 return QString::fromLatin1("configure-security");
03521 }
03522
03523 SecurityPage::SecurityPage( QWidget * parent, const char * name )
03524 : ConfigModuleWithTabs( parent, name )
03525 {
03526
03527
03528
03529 mGeneralTab = new GeneralTab();
03530 addTab( mGeneralTab, i18n("&Reading") );
03531
03532
03533
03534
03535 mComposerCryptoTab = new ComposerCryptoTab();
03536 addTab( mComposerCryptoTab, i18n("Composing") );
03537
03538
03539
03540
03541 mWarningTab = new WarningTab();
03542 addTab( mWarningTab, i18n("Warnings") );
03543
03544
03545
03546
03547 mSMimeTab = new SMimeTab();
03548 addTab( mSMimeTab, i18n("S/MIME &Validation") );
03549
03550
03551
03552
03553 mCryptPlugTab = new CryptPlugTab();
03554 addTab( mCryptPlugTab, i18n("Crypto Backe&nds") );
03555 load();
03556 }
03557
03558
03559 void SecurityPage::installProfile( KConfig * profile ) {
03560 mGeneralTab->installProfile( profile );
03561 mComposerCryptoTab->installProfile( profile );
03562 mWarningTab->installProfile( profile );
03563 mSMimeTab->installProfile( profile );
03564 }
03565
03566 QString SecurityPage::GeneralTab::helpAnchor() const {
03567 return QString::fromLatin1("configure-security-reading");
03568 }
03569
03570 SecurityPageGeneralTab::SecurityPageGeneralTab( QWidget * parent, const char * name )
03571 : ConfigModuleTab ( parent, name )
03572 {
03573
03574 QVBoxLayout *vlay;
03575 QHBox *hbox;
03576 QGroupBox *group;
03577 QRadioButton *radio;
03578 KActiveLabel *label;
03579 QWidget *w;
03580 QString msg;
03581
03582 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
03583
03584
03585 QString htmlWhatsThis = i18n( "<qt><p>Messages sometimes come in both formats. "
03586 "This option controls whether you want the HTML part or the plain "
03587 "text part to be displayed.</p>"
03588 "<p>Displaying the HTML part makes the message look better, "
03589 "but at the same time increases the risk of security holes "
03590 "being exploited.</p>"
03591 "<p>Displaying the plain text part loses much of the message's "
03592 "formatting, but makes it almost <em>impossible</em> "
03593 "to exploit security holes in the HTML renderer (Konqueror).</p>"
03594 "<p>The option below guards against one common misuse of HTML "
03595 "messages, but it cannot guard against security issues that were "
03596 "not known at the time this version of KMail was written.</p>"
03597 "<p>It is therefore advisable to <em>not</em> prefer HTML to "
03598 "plain text.</p>"
03599 "<p><b>Note:</b> You can set this option on a per-folder basis "
03600 "from the <i>Folder</i> menu of KMail's main window.</p></qt>" );
03601
03602 QString externalWhatsThis = i18n( "<qt><p>Some mail advertisements are in HTML "
03603 "and contain references to, for example, images that the advertisers"
03604 " employ to find out that you have read their message "
03605 "("web bugs").</p>"
03606 "<p>There is no valid reason to load images off the Internet like "
03607 "this, since the sender can always attach the required images "
03608 "directly to the message.</p>"
03609 "<p>To guard from such a misuse of the HTML displaying feature "
03610 "of KMail, this option is <em>disabled</em> by default.</p>"
03611 "<p>However, if you wish to, for example, view images in HTML "
03612 "messages that were not attached to it, you can enable this "
03613 "option, but you should be aware of the possible problem.</p></qt>" );
03614
03615 QString receiptWhatsThis = i18n( "<qt><h3>Message Disposition "
03616 "Notification Policy</h3>"
03617 "<p>MDNs are a generalization of what is commonly called <b>read "
03618 "receipt</b>. The message author requests a disposition "
03619 "notification to be sent and the receiver's mail program "
03620 "generates a reply from which the author can learn what "
03621 "happened to his message. Common disposition types include "
03622 "<b>displayed</b> (i.e. read), <b>deleted</b> and <b>dispatched</b> "
03623 "(e.g. forwarded).</p>"
03624 "<p>The following options are available to control KMail's "
03625 "sending of MDNs:</p>"
03626 "<ul>"
03627 "<li><em>Ignore</em>: Ignores any request for disposition "
03628 "notifications. No MDN will ever be sent automatically "
03629 "(recommended).</li>"
03630 "<li><em>Ask</em>: Answers requests only after asking the user "
03631 "for permission. This way, you can send MDNs for selected "
03632 "messages while denying or ignoring them for others.</li>"
03633 "<li><em>Deny</em>: Always sends a <b>denied</b> notification. This "
03634 "is only <em>slightly</em> better than always sending MDNs. "
03635 "The author will still know that the messages has been acted "
03636 "upon, he just cannot tell whether it was deleted or read etc.</li>"
03637 "<li><em>Always send</em>: Always sends the requested "
03638 "disposition notification. That means that the author of the "
03639 "message gets to know when the message was acted upon and, "
03640 "in addition, what happened to it (displayed, deleted, "
03641 "etc.). This option is strongly discouraged, but since it "
03642 "makes much sense e.g. for customer relationship management, "
03643 "it has been made available.</li>"
03644 "</ul></qt>" );
03645
03646
03647
03648 group = new QVGroupBox( i18n( "HTML Messages" ), this );
03649 group->layout()->setSpacing( KDialog::spacingHint() );
03650
03651 mHtmlMailCheck = new QCheckBox( i18n("Prefer H&TML to plain text"), group );
03652 QWhatsThis::add( mHtmlMailCheck, htmlWhatsThis );
03653 connect( mHtmlMailCheck, SIGNAL( stateChanged( int ) ),
03654 this, SLOT( slotEmitChanged( void ) ) );
03655 mExternalReferences = new QCheckBox( i18n("Allow messages to load e&xternal "
03656 "references from the Internet" ), group );
03657 QWhatsThis::add( mExternalReferences, externalWhatsThis );
03658 connect( mExternalReferences, SIGNAL( stateChanged( int ) ),
03659 this, SLOT( slotEmitChanged( void ) ) );
03660 label = new KActiveLabel( i18n("<b>WARNING:</b> Allowing HTML in email may "
03661 "increase the risk that your system will be "
03662 "compromised by present and anticipated security "
03663 "exploits. <a href=\"whatsthis:%1\">More about "
03664 "HTML mails...</a> <a href=\"whatsthis:%2\">More "
03665 "about external references...</a>")
03666 .arg(htmlWhatsThis).arg(externalWhatsThis),
03667 group );
03668
03669 vlay->addWidget( group );
03670
03671
03672 group = new QVGroupBox( i18n("Message Disposition Notifications"), this );
03673 group->layout()->setSpacing( KDialog::spacingHint() );
03674
03675
03676
03677 mMDNGroup = new QButtonGroup( group );
03678 mMDNGroup->hide();
03679 connect( mMDNGroup, SIGNAL( clicked( int ) ),
03680 this, SLOT( slotEmitChanged( void ) ) );
03681 hbox = new QHBox( group );
03682 hbox->setSpacing( KDialog::spacingHint() );
03683
03684 (void)new QLabel( i18n("Send policy:"), hbox );
03685
03686 radio = new QRadioButton( i18n("&Ignore"), hbox );
03687 mMDNGroup->insert( radio );
03688
03689 radio = new QRadioButton( i18n("As&k"), hbox );
03690 mMDNGroup->insert( radio );
03691
03692 radio = new QRadioButton( i18n("&Deny"), hbox );
03693 mMDNGroup->insert( radio );
03694
03695 radio = new QRadioButton( i18n("Al&ways send"), hbox );
03696 mMDNGroup->insert( radio );
03697
03698 for ( int i = 0 ; i < mMDNGroup->count() ; ++i )
03699 QWhatsThis::add( mMDNGroup->find( i ), receiptWhatsThis );
03700
03701 w = new QWidget( hbox );
03702 hbox->setStretchFactor( w, 1 );
03703
03704
03705 mOrigQuoteGroup = new QButtonGroup( group );
03706 mOrigQuoteGroup->hide();
03707 connect( mOrigQuoteGroup, SIGNAL( clicked( int ) ),
03708 this, SLOT( slotEmitChanged( void ) ) );
03709
03710 hbox = new QHBox( group );
03711 hbox->setSpacing( KDialog::spacingHint() );
03712
03713 (void)new QLabel( i18n("Quote original message:"), hbox );
03714
03715 radio = new QRadioButton( i18n("Nothin&g"), hbox );
03716 mOrigQuoteGroup->insert( radio );
03717
03718 radio = new QRadioButton( i18n("&Full message"), hbox );
03719 mOrigQuoteGroup->insert( radio );
03720
03721 radio = new QRadioButton( i18n("Onl&y headers"), hbox );
03722 mOrigQuoteGroup->insert( radio );
03723
03724 w = new QWidget( hbox );
03725 hbox->setStretchFactor( w, 1 );
03726
03727 mNoMDNsWhenEncryptedCheck = new QCheckBox( i18n("Do not send MDNs in response to encrypted messages"), group );
03728 connect( mNoMDNsWhenEncryptedCheck, SIGNAL(toggled(bool)), SLOT(slotEmitChanged()) );
03729
03730
03731 label = new KActiveLabel( i18n("<b>WARNING:</b> Unconditionally returning "
03732 "confirmations undermines your privacy. "
03733 "<a href=\"whatsthis:%1\">More...</a>")
03734 .arg(receiptWhatsThis),
03735 group );
03736
03737 vlay->addWidget( group );
03738
03739
03740 group = new QVGroupBox( i18n( "Certificate && Key Bundle Attachments" ), this );
03741 group->layout()->setSpacing( KDialog::spacingHint() );
03742
03743 mAutomaticallyImportAttachedKeysCheck = new QCheckBox( i18n("Automatically import keys and certificates"), group );
03744 connect( mAutomaticallyImportAttachedKeysCheck, SIGNAL(toggled(bool)), SLOT(slotEmitChanged()) );
03745
03746 vlay->addWidget( group );
03747
03748
03749
03750 vlay->addStretch( 10 );
03751 }
03752
03753 void SecurityPage::GeneralTab::doLoadOther() {
03754 const KConfigGroup reader( KMKernel::config(), "Reader" );
03755
03756 mHtmlMailCheck->setChecked( reader.readBoolEntry( "htmlMail", false ) );
03757 mExternalReferences->setChecked( reader.readBoolEntry( "htmlLoadExternal", false ) );
03758 mAutomaticallyImportAttachedKeysCheck->setChecked( reader.readBoolEntry( "AutoImportKeys", false ) );
03759
03760 const KConfigGroup mdn( KMKernel::config(), "MDN" );
03761
03762 int num = mdn.readNumEntry( "default-policy", 0 );
03763 if ( num < 0 || num >= mMDNGroup->count() ) num = 0;
03764 mMDNGroup->setButton( num );
03765 num = mdn.readNumEntry( "quote-message", 0 );
03766 if ( num < 0 || num >= mOrigQuoteGroup->count() ) num = 0;
03767 mOrigQuoteGroup->setButton( num );
03768 mNoMDNsWhenEncryptedCheck->setChecked(mdn.readBoolEntry( "not-send-when-encrypted", true ));
03769 }
03770
03771 void SecurityPage::GeneralTab::installProfile( KConfig * profile ) {
03772 const KConfigGroup reader( profile, "Reader" );
03773 const KConfigGroup mdn( profile, "MDN" );
03774
03775 if ( reader.hasKey( "htmlMail" ) )
03776 mHtmlMailCheck->setChecked( reader.readBoolEntry( "htmlMail" ) );
03777 if ( reader.hasKey( "htmlLoadExternal" ) )
03778 mExternalReferences->setChecked( reader.readBoolEntry( "htmlLoadExternal" ) );
03779 if ( reader.hasKey( "AutoImportKeys" ) )
03780 mAutomaticallyImportAttachedKeysCheck->setChecked( reader.readBoolEntry( "AutoImportKeys" ) );
03781
03782 if ( mdn.hasKey( "default-policy" ) ) {
03783 int num = mdn.readNumEntry( "default-policy" );
03784 if ( num < 0 || num >= mMDNGroup->count() ) num = 0;
03785 mMDNGroup->setButton( num );
03786 }
03787 if ( mdn.hasKey( "quote-message" ) ) {
03788 int num = mdn.readNumEntry( "quote-message" );
03789 if ( num < 0 || num >= mOrigQuoteGroup->count() ) num = 0;
03790 mOrigQuoteGroup->setButton( num );
03791 }
03792 if ( mdn.hasKey( "not-send-when-encrypted" ) )
03793 mNoMDNsWhenEncryptedCheck->setChecked(mdn.readBoolEntry( "not-send-when-encrypted" ));
03794 }
03795
03796 void SecurityPage::GeneralTab::save() {
03797 KConfigGroup reader( KMKernel::config(), "Reader" );
03798 KConfigGroup mdn( KMKernel::config(), "MDN" );
03799
03800 if (reader.readBoolEntry( "htmlMail", false ) != mHtmlMailCheck->isChecked())
03801 {
03802 if (KMessageBox::warningContinueCancel(this, i18n("Changing the global "
03803 "HTML setting will override all folder specific values."), QString::null,
03804 KStdGuiItem::cont(), "htmlMailOverride") == KMessageBox::Continue)
03805 {
03806 reader.writeEntry( "htmlMail", mHtmlMailCheck->isChecked() );
03807 QStringList names;
03808 QValueList<QGuardedPtr<KMFolder> > folders;
03809 kmkernel->folderMgr()->createFolderList(&names, &folders);
03810 kmkernel->imapFolderMgr()->createFolderList(&names, &folders);
03811 kmkernel->dimapFolderMgr()->createFolderList(&names, &folders);
03812 kmkernel->searchFolderMgr()->createFolderList(&names, &folders);
03813 for (QValueList<QGuardedPtr<KMFolder> >::iterator it = folders.begin();
03814 it != folders.end(); ++it)
03815 {
03816 if (*it)
03817 {
03818 KConfigGroupSaver saver(KMKernel::config(),
03819 "Folder-" + (*it)->idString());
03820 KMKernel::config()->writeEntry("htmlMailOverride", false);
03821 }
03822 }
03823 }
03824 }
03825 reader.writeEntry( "htmlLoadExternal", mExternalReferences->isChecked() );
03826 reader.writeEntry( "AutoImportKeys", mAutomaticallyImportAttachedKeysCheck->isChecked() );
03827 mdn.writeEntry( "default-policy", mMDNGroup->id( mMDNGroup->selected() ) );
03828 mdn.writeEntry( "quote-message", mOrigQuoteGroup->id( mOrigQuoteGroup->selected() ) );
03829 mdn.writeEntry( "not-send-when-encrypted", mNoMDNsWhenEncryptedCheck->isChecked() );
03830 }
03831
03832
03833 QString SecurityPage::ComposerCryptoTab::helpAnchor() const {
03834 return QString::fromLatin1("configure-security-composing");
03835 }
03836
03837 SecurityPageComposerCryptoTab::SecurityPageComposerCryptoTab( QWidget * parent, const char * name )
03838 : ConfigModuleTab ( parent, name )
03839 {
03840
03841 QVBoxLayout* vlay = new QVBoxLayout( this, 0, 0 );
03842
03843 mWidget = new ComposerCryptoConfiguration( this );
03844 connect( mWidget->mAutoSignature, SIGNAL( toggled(bool) ), this, SLOT( slotEmitChanged() ) );
03845 connect( mWidget->mEncToSelf, SIGNAL( toggled(bool) ), this, SLOT( slotEmitChanged() ) );
03846 connect( mWidget->mShowEncryptionResult, SIGNAL( toggled(bool) ), this, SLOT( slotEmitChanged() ) );
03847 connect( mWidget->mShowKeyApprovalDlg, SIGNAL( toggled(bool) ), this, SLOT( slotEmitChanged() ) );
03848 connect( mWidget->mAutoEncrypt, SIGNAL( toggled(bool) ), this, SLOT( slotEmitChanged() ) );
03849 connect( mWidget->mNeverEncryptWhenSavingInDrafts, SIGNAL( toggled(bool) ), this, SLOT( slotEmitChanged() ) );
03850 connect( mWidget->mStoreEncrypted, SIGNAL( toggled(bool) ), this, SLOT( slotEmitChanged() ) );
03851 vlay->addWidget( mWidget );
03852 }
03853
03854 void SecurityPage::ComposerCryptoTab::doLoadOther() {
03855 const KConfigGroup composer( KMKernel::config(), "Composer" );
03856
03857
03858
03859 mWidget->mAutoSignature->setChecked( composer.readBoolEntry( "pgp-auto-sign", false ) );
03860
03861 mWidget->mEncToSelf->setChecked( composer.readBoolEntry( "crypto-encrypt-to-self", true ) );
03862 mWidget->mShowEncryptionResult->setChecked( false );
03863 mWidget->mShowEncryptionResult->hide();
03864 mWidget->mShowKeyApprovalDlg->setChecked( composer.readBoolEntry( "crypto-show-keys-for-approval", true ) );
03865
03866 mWidget->mAutoEncrypt->setChecked( composer.readBoolEntry( "pgp-auto-encrypt", false ) );
03867 mWidget->mNeverEncryptWhenSavingInDrafts->setChecked( composer.readBoolEntry( "never-encrypt-drafts", true ) );
03868
03869 mWidget->mStoreEncrypted->setChecked( composer.readBoolEntry( "crypto-store-encrypted", true ) );
03870 }
03871
03872 void SecurityPage::ComposerCryptoTab::installProfile( KConfig * profile ) {
03873 const KConfigGroup composer( profile, "Composer" );
03874
03875 if ( composer.hasKey( "pgp-auto-sign" ) )
03876 mWidget->mAutoSignature->setChecked( composer.readBoolEntry( "pgp-auto-sign" ) );
03877
03878 if ( composer.hasKey( "crypto-encrypt-to-self" ) )
03879 mWidget->mEncToSelf->setChecked( composer.readBoolEntry( "crypto-encrypt-to-self" ) );
03880 if ( composer.hasKey( "crypto-show-encryption-result" ) )
03881 mWidget->mShowEncryptionResult->setChecked( composer.readBoolEntry( "crypto-show-encryption-result" ) );
03882 if ( composer.hasKey( "crypto-show-keys-for-approval" ) )
03883 mWidget->mShowKeyApprovalDlg->setChecked( composer.readBoolEntry( "crypto-show-keys-for-approval" ) );
03884 if ( composer.hasKey( "pgp-auto-encrypt" ) )
03885 mWidget->mAutoEncrypt->setChecked( composer.readBoolEntry( "pgp-auto-encrypt" ) );
03886 if ( composer.hasKey( "never-encrypt-drafts" ) )
03887 mWidget->mNeverEncryptWhenSavingInDrafts->setChecked( composer.readBoolEntry( "never-encrypt-drafts" ) );
03888
03889 if ( composer.hasKey( "crypto-store-encrypted" ) )
03890 mWidget->mStoreEncrypted->setChecked( composer.readBoolEntry( "crypto-store-encrypted" ) );
03891 }
03892
03893 void SecurityPage::ComposerCryptoTab::save() {
03894 KConfigGroup composer( KMKernel::config(), "Composer" );
03895
03896 composer.writeEntry( "pgp-auto-sign", mWidget->mAutoSignature->isChecked() );
03897
03898 composer.writeEntry( "crypto-encrypt-to-self", mWidget->mEncToSelf->isChecked() );
03899 composer.writeEntry( "crypto-show-encryption-result", mWidget->mShowEncryptionResult->isChecked() );
03900 composer.writeEntry( "crypto-show-keys-for-approval", mWidget->mShowKeyApprovalDlg->isChecked() );
03901
03902 composer.writeEntry( "pgp-auto-encrypt", mWidget->mAutoEncrypt->isChecked() );
03903 composer.writeEntry( "never-encrypt-drafts", mWidget->mNeverEncryptWhenSavingInDrafts->isChecked() );
03904
03905 composer.writeEntry( "crypto-store-encrypted", mWidget->mStoreEncrypted->isChecked() );
03906 }
03907
03908 QString SecurityPage::WarningTab::helpAnchor() const {
03909 return QString::fromLatin1("configure-security-warnings");
03910 }
03911
03912 SecurityPageWarningTab::SecurityPageWarningTab( QWidget * parent, const char * name )
03913 : ConfigModuleTab( parent, name )
03914 {
03915
03916 QVBoxLayout* vlay = new QVBoxLayout( this, 0, 0 );
03917
03918 mWidget = new WarningConfiguration( this );
03919 vlay->addWidget( mWidget );
03920
03921 connect( mWidget->warnGroupBox, SIGNAL(toggled(bool)), SLOT(slotEmitChanged()) );
03922 connect( mWidget->mWarnUnsigned, SIGNAL(toggled(bool)), SLOT(slotEmitChanged()) );
03923 connect( mWidget->warnUnencryptedCB, SIGNAL(toggled(bool)), SLOT(slotEmitChanged()) );
03924 connect( mWidget->warnReceiverNotInCertificateCB, SIGNAL(toggled(bool)), SLOT(slotEmitChanged()) );
03925 connect( mWidget->mWarnSignKeyExpiresSB, SIGNAL( valueChanged( int ) ), SLOT( slotEmitChanged() ) );
03926 connect( mWidget->mWarnSignChainCertExpiresSB, SIGNAL( valueChanged( int ) ), SLOT( slotEmitChanged() ) );
03927 connect( mWidget->mWarnSignRootCertExpiresSB, SIGNAL( valueChanged( int ) ), SLOT( slotEmitChanged() ) );
03928
03929 connect( mWidget->mWarnEncrKeyExpiresSB, SIGNAL( valueChanged( int ) ), SLOT( slotEmitChanged() ) );
03930 connect( mWidget->mWarnEncrChainCertExpiresSB, SIGNAL( valueChanged( int ) ), SLOT( slotEmitChanged() ) );
03931 connect( mWidget->mWarnEncrRootCertExpiresSB, SIGNAL( valueChanged( int ) ), SLOT( slotEmitChanged() ) );
03932
03933 connect( mWidget->enableAllWarningsPB, SIGNAL(clicked()),
03934 SLOT(slotReenableAllWarningsClicked()) );
03935 }
03936
03937 void SecurityPage::WarningTab::doLoadOther() {
03938 const KConfigGroup composer( KMKernel::config(), "Composer" );
03939
03940 mWidget->warnUnencryptedCB->setChecked( composer.readBoolEntry( "crypto-warning-unencrypted", false ) );
03941 mWidget->mWarnUnsigned->setChecked( composer.readBoolEntry( "crypto-warning-unsigned", false ) );
03942 mWidget->warnReceiverNotInCertificateCB->setChecked( composer.readBoolEntry( "crypto-warn-recv-not-in-cert", true ) );
03943
03944
03945
03946 mWidget->warnGroupBox->setChecked( composer.readBoolEntry( "crypto-warn-when-near-expire", true ) );
03947
03948 mWidget->mWarnSignKeyExpiresSB->setValue( composer.readNumEntry( "crypto-warn-sign-key-near-expire-int", 14 ) );
03949 mWidget->mWarnSignChainCertExpiresSB->setValue( composer.readNumEntry( "crypto-warn-sign-chaincert-near-expire-int", 14 ) );
03950 mWidget->mWarnSignRootCertExpiresSB->setValue( composer.readNumEntry( "crypto-warn-sign-root-near-expire-int", 14 ) );
03951
03952 mWidget->mWarnEncrKeyExpiresSB->setValue( composer.readNumEntry( "crypto-warn-encr-key-near-expire-int", 14 ) );
03953 mWidget->mWarnEncrChainCertExpiresSB->setValue( composer.readNumEntry( "crypto-warn-encr-chaincert-near-expire-int", 14 ) );
03954 mWidget->mWarnEncrRootCertExpiresSB->setValue( composer.readNumEntry( "crypto-warn-encr-root-near-expire-int", 14 ) );
03955
03956 mWidget->enableAllWarningsPB->setEnabled( true );
03957 }
03958
03959 void SecurityPage::WarningTab::installProfile( KConfig * profile ) {
03960 const KConfigGroup composer( profile, "Composer" );
03961
03962 if ( composer.hasKey( "crypto-warning-unencrypted" ) )
03963 mWidget->warnUnencryptedCB->setChecked( composer.readBoolEntry( "crypto-warning-unencrypted" ) );
03964 if ( composer.hasKey( "crypto-warning-unsigned" ) )
03965 mWidget->mWarnUnsigned->setChecked( composer.readBoolEntry( "crypto-warning-unsigned" ) );
03966 if ( composer.hasKey( "crypto-warn-recv-not-in-cert" ) )
03967 mWidget->warnReceiverNotInCertificateCB->setChecked( composer.readBoolEntry( "crypto-warn-recv-not-in-cert" ) );
03968
03969 if ( composer.hasKey( "crypto-warn-when-near-expire" ) )
03970 mWidget->warnGroupBox->setChecked( composer.readBoolEntry( "crypto-warn-when-near-expire" ) );
03971
03972 if ( composer.hasKey( "crypto-warn-sign-key-near-expire-int" ) )
03973 mWidget->mWarnSignKeyExpiresSB->setValue( composer.readNumEntry( "crypto-warn-sign-key-near-expire-int" ) );
03974 if ( composer.hasKey( "crypto-warn-sign-chaincert-near-expire-int" ) )
03975 mWidget->mWarnSignChainCertExpiresSB->setValue( composer.readNumEntry( "crypto-warn-sign-chaincert-near-expire-int" ) );
03976 if ( composer.hasKey( "crypto-warn-sign-root-near-expire-int" ) )
03977 mWidget->mWarnSignRootCertExpiresSB->setValue( composer.readNumEntry( "crypto-warn-sign-root-near-expire-int" ) );
03978
03979 if ( composer.hasKey( "crypto-warn-encr-key-near-expire-int" ) )
03980 mWidget->mWarnEncrKeyExpiresSB->setValue( composer.readNumEntry( "crypto-warn-encr-key-near-expire-int" ) );
03981 if ( composer.hasKey( "crypto-warn-encr-chaincert-near-expire-int" ) )
03982 mWidget->mWarnEncrChainCertExpiresSB->setValue( composer.readNumEntry( "crypto-warn-encr-chaincert-near-expire-int" ) );
03983 if ( composer.hasKey( "crypto-warn-encr-root-near-expire-int" ) )
03984 mWidget->mWarnEncrRootCertExpiresSB->setValue( composer.readNumEntry( "crypto-warn-encr-root-near-expire-int" ) );
03985 }
03986
03987 void SecurityPage::WarningTab::save() {
03988 KConfigGroup composer( KMKernel::config(), "Composer" );
03989
03990 composer.writeEntry( "crypto-warn-recv-not-in-cert", mWidget->warnReceiverNotInCertificateCB->isChecked() );
03991 composer.writeEntry( "crypto-warning-unencrypted", mWidget->warnUnencryptedCB->isChecked() );
03992 composer.writeEntry( "crypto-warning-unsigned", mWidget->mWarnUnsigned->isChecked() );
03993
03994 composer.writeEntry( "crypto-warn-when-near-expire", mWidget->warnGroupBox->isChecked() );
03995 composer.writeEntry( "crypto-warn-sign-key-near-expire-int",
03996 mWidget->mWarnSignKeyExpiresSB->value() );
03997 composer.writeEntry( "crypto-warn-sign-chaincert-near-expire-int",
03998 mWidget->mWarnSignChainCertExpiresSB->value() );
03999 composer.writeEntry( "crypto-warn-sign-root-near-expire-int",
04000 mWidget->mWarnSignRootCertExpiresSB->value() );
04001
04002 composer.writeEntry( "crypto-warn-encr-key-near-expire-int",
04003 mWidget->mWarnEncrKeyExpiresSB->value() );
04004 composer.writeEntry( "crypto-warn-encr-chaincert-near-expire-int",
04005 mWidget->mWarnEncrChainCertExpiresSB->value() );
04006 composer.writeEntry( "crypto-warn-encr-root-near-expire-int",
04007 mWidget->mWarnEncrRootCertExpiresSB->value() );
04008 }
04009
04010 void SecurityPage::WarningTab::slotReenableAllWarningsClicked() {
04011 KMessageBox::enableAllMessages();
04012 mWidget->enableAllWarningsPB->setEnabled( false );
04013 }
04014
04016
04017 QString SecurityPage::SMimeTab::helpAnchor() const {
04018 return QString::fromLatin1("configure-security-smime-validation");
04019 }
04020
04021 SecurityPageSMimeTab::SecurityPageSMimeTab( QWidget * parent, const char * name )
04022 : ConfigModuleTab( parent, name )
04023 {
04024
04025 QVBoxLayout* vlay = new QVBoxLayout( this, 0, 0 );
04026
04027 mWidget = new SMimeConfiguration( this );
04028 vlay->addWidget( mWidget );
04029
04030
04031 QButtonGroup* bg = new QButtonGroup( mWidget );
04032 bg->hide();
04033 bg->insert( mWidget->CRLRB );
04034 bg->insert( mWidget->OCSPRB );
04035
04036
04037 mWidget->OCSPResponderSignature->setAllowedKeys(
04038 Kleo::KeySelectionDialog::SMIMEKeys
04039 | Kleo::KeySelectionDialog::TrustedKeys
04040 | Kleo::KeySelectionDialog::ValidKeys
04041 | Kleo::KeySelectionDialog::SigningKeys
04042 | Kleo::KeySelectionDialog::PublicKeys );
04043 mWidget->OCSPResponderSignature->setMultipleKeysEnabled( false );
04044
04045 mConfig = Kleo::CryptoBackendFactory::instance()->config();
04046
04047 connect( mWidget->CRLRB, SIGNAL( toggled( bool ) ), this, SLOT( slotEmitChanged() ) );
04048 connect( mWidget->OCSPRB, SIGNAL( toggled( bool ) ), this, SLOT( slotEmitChanged() ) );
04049 connect( mWidget->OCSPResponderURL, SIGNAL( textChanged( const QString& ) ), this, SLOT( slotEmitChanged() ) );
04050 connect( mWidget->OCSPResponderSignature, SIGNAL( changed() ), this, SLOT( slotEmitChanged() ) );
04051 connect( mWidget->doNotCheckCertPolicyCB, SIGNAL( toggled( bool ) ), this, SLOT( slotEmitChanged() ) );
04052 connect( mWidget->neverConsultCB, SIGNAL( toggled( bool ) ), this, SLOT( slotEmitChanged() ) );
04053 connect( mWidget->fetchMissingCB, SIGNAL( toggled( bool ) ), this, SLOT( slotEmitChanged() ) );
04054
04055 connect( mWidget->ignoreServiceURLCB, SIGNAL( toggled( bool ) ), this, SLOT( slotEmitChanged() ) );
04056 connect( mWidget->ignoreHTTPDPCB, SIGNAL( toggled( bool ) ), this, SLOT( slotEmitChanged() ) );
04057 connect( mWidget->disableHTTPCB, SIGNAL( toggled( bool ) ), this, SLOT( slotEmitChanged() ) );
04058 connect( mWidget->honorHTTPProxyRB, SIGNAL( toggled( bool ) ), this, SLOT( slotEmitChanged() ) );
04059 connect( mWidget->useCustomHTTPProxyRB, SIGNAL( toggled( bool ) ), this, SLOT( slotEmitChanged() ) );
04060 connect( mWidget->customHTTPProxy, SIGNAL( textChanged( const QString& ) ), this, SLOT( slotEmitChanged() ) );
04061 connect( mWidget->ignoreLDAPDPCB, SIGNAL( toggled( bool ) ), this, SLOT( slotEmitChanged() ) );
04062 connect( mWidget->disableLDAPCB, SIGNAL( toggled( bool ) ), this, SLOT( slotEmitChanged() ) );
04063 connect( mWidget->customLDAPProxy, SIGNAL( textChanged( const QString& ) ), this, SLOT( slotEmitChanged() ) );
04064
04065 connect( mWidget->disableHTTPCB, SIGNAL( toggled( bool ) ),
04066 this, SLOT( slotUpdateHTTPActions() ) );
04067 connect( mWidget->ignoreHTTPDPCB, SIGNAL( toggled( bool ) ),
04068 this, SLOT( slotUpdateHTTPActions() ) );
04069
04070
04071 QButtonGroup* bgHTTPProxy = new QButtonGroup( mWidget );
04072 bgHTTPProxy->hide();
04073 bgHTTPProxy->insert( mWidget->honorHTTPProxyRB );
04074 bgHTTPProxy->insert( mWidget->useCustomHTTPProxyRB );
04075
04076 if ( !connectDCOPSignal( 0, "KPIM::CryptoConfig", "changed()",
04077 "load()", false ) )
04078 kdError(5650) << "SecurityPageSMimeTab: connection to CryptoConfig's changed() failed" << endl;
04079
04080 }
04081
04082 SecurityPageSMimeTab::~SecurityPageSMimeTab()
04083 {
04084 }
04085
04086 static void disableDirmngrWidget( QWidget* w ) {
04087 w->setEnabled( false );
04088 QWhatsThis::remove( w );
04089 QWhatsThis::add( w, i18n( "This option requires dirmngr >= 0.9.0" ) );
04090 }
04091
04092 static void initializeDirmngrCheckbox( QCheckBox* cb, Kleo::CryptoConfigEntry* entry ) {
04093 if ( entry )
04094 cb->setChecked( entry->boolValue() );
04095 else
04096 disableDirmngrWidget( cb );
04097 }
04098
04099 struct SMIMECryptoConfigEntries {
04100 SMIMECryptoConfigEntries( Kleo::CryptoConfig* config )
04101 : mConfig( config ) {
04102
04103
04104 mCheckUsingOCSPConfigEntry = configEntry( "gpgsm", "Security", "enable-ocsp", Kleo::CryptoConfigEntry::ArgType_None, false );
04105 mEnableOCSPsendingConfigEntry = configEntry( "dirmngr", "OCSP", "allow-ocsp", Kleo::CryptoConfigEntry::ArgType_None, false );
04106 mDoNotCheckCertPolicyConfigEntry = configEntry( "gpgsm", "Security", "disable-policy-checks", Kleo::CryptoConfigEntry::ArgType_None, false );
04107 mNeverConsultConfigEntry = configEntry( "gpgsm", "Security", "disable-crl-checks", Kleo::CryptoConfigEntry::ArgType_None, false );
04108 mFetchMissingConfigEntry = configEntry( "gpgsm", "Security", "auto-issuer-key-retrieve", Kleo::CryptoConfigEntry::ArgType_None, false );
04109
04110 mIgnoreServiceURLEntry = configEntry( "dirmngr", "OCSP", "ignore-ocsp-service-url", Kleo::CryptoConfigEntry::ArgType_None, false );
04111 mIgnoreHTTPDPEntry = configEntry( "dirmngr", "HTTP", "ignore-http-dp", Kleo::CryptoConfigEntry::ArgType_None, false );
04112 mDisableHTTPEntry = configEntry( "dirmngr", "HTTP", "disable-http", Kleo::CryptoConfigEntry::ArgType_None, false );
04113 mHonorHTTPProxy = configEntry( "dirmngr", "HTTP", "honor-http-proxy", Kleo::CryptoConfigEntry::ArgType_None, false );
04114
04115 mIgnoreLDAPDPEntry = configEntry( "dirmngr", "LDAP", "ignore-ldap-dp", Kleo::CryptoConfigEntry::ArgType_None, false );
04116 mDisableLDAPEntry = configEntry( "dirmngr", "LDAP", "disable-ldap", Kleo::CryptoConfigEntry::ArgType_None, false );
04117
04118 mOCSPResponderURLConfigEntry = configEntry( "dirmngr", "OCSP", "ocsp-responder", Kleo::CryptoConfigEntry::ArgType_String, false );
04119 mOCSPResponderSignature = configEntry( "dirmngr", "OCSP", "ocsp-signer", Kleo::CryptoConfigEntry::ArgType_String, false );
04120 mCustomHTTPProxy = configEntry( "dirmngr", "HTTP", "http-proxy", Kleo::CryptoConfigEntry::ArgType_String, false );
04121 mCustomLDAPProxy = configEntry( "dirmngr", "LDAP", "ldap-proxy", Kleo::CryptoConfigEntry::ArgType_String, false );
04122 }
04123
04124 Kleo::CryptoConfigEntry* configEntry( const char* componentName,
04125 const char* groupName,
04126 const char* entryName,
04127 int argType,
04128 bool isList );
04129
04130
04131 Kleo::CryptoConfigEntry* mCheckUsingOCSPConfigEntry;
04132 Kleo::CryptoConfigEntry* mEnableOCSPsendingConfigEntry;
04133 Kleo::CryptoConfigEntry* mDoNotCheckCertPolicyConfigEntry;
04134 Kleo::CryptoConfigEntry* mNeverConsultConfigEntry;
04135 Kleo::CryptoConfigEntry* mFetchMissingConfigEntry;
04136 Kleo::CryptoConfigEntry* mIgnoreServiceURLEntry;
04137 Kleo::CryptoConfigEntry* mIgnoreHTTPDPEntry;
04138 Kleo::CryptoConfigEntry* mDisableHTTPEntry;
04139 Kleo::CryptoConfigEntry* mHonorHTTPProxy;
04140 Kleo::CryptoConfigEntry* mIgnoreLDAPDPEntry;
04141 Kleo::CryptoConfigEntry* mDisableLDAPEntry;
04142
04143 Kleo::CryptoConfigEntry* mOCSPResponderURLConfigEntry;
04144 Kleo::CryptoConfigEntry* mOCSPResponderSignature;
04145 Kleo::CryptoConfigEntry* mCustomHTTPProxy;
04146 Kleo::CryptoConfigEntry* mCustomLDAPProxy;
04147
04148 Kleo::CryptoConfig* mConfig;
04149 };
04150
04151 void SecurityPage::SMimeTab::doLoadOther() {
04152 if ( !mConfig ) {
04153 setEnabled( false );
04154 return;
04155 }
04156
04157
04158
04159 mConfig->clear();
04160
04161
04162
04163
04164 SMIMECryptoConfigEntries e( mConfig );
04165
04166
04167
04168 if ( e.mCheckUsingOCSPConfigEntry ) {
04169 bool b = e.mCheckUsingOCSPConfigEntry->boolValue();
04170 mWidget->OCSPRB->setChecked( b );
04171 mWidget->CRLRB->setChecked( !b );
04172 mWidget->OCSPGroupBox->setEnabled( b );
04173 } else {
04174 mWidget->OCSPGroupBox->setEnabled( false );
04175 }
04176 if ( e.mDoNotCheckCertPolicyConfigEntry )
04177 mWidget->doNotCheckCertPolicyCB->setChecked( e.mDoNotCheckCertPolicyConfigEntry->boolValue() );
04178 if ( e.mNeverConsultConfigEntry )
04179 mWidget->neverConsultCB->setChecked( e.mNeverConsultConfigEntry->boolValue() );
04180 if ( e.mFetchMissingConfigEntry )
04181 mWidget->fetchMissingCB->setChecked( e.mFetchMissingConfigEntry->boolValue() );
04182
04183 if ( e.mOCSPResponderURLConfigEntry )
04184 mWidget->OCSPResponderURL->setText( e.mOCSPResponderURLConfigEntry->stringValue() );
04185 if ( e.mOCSPResponderSignature ) {
04186 mWidget->OCSPResponderSignature->setFingerprint( e.mOCSPResponderSignature->stringValue() );
04187 }
04188
04189
04190 initializeDirmngrCheckbox( mWidget->ignoreServiceURLCB, e.mIgnoreServiceURLEntry );
04191 initializeDirmngrCheckbox( mWidget->ignoreHTTPDPCB, e.mIgnoreHTTPDPEntry );
04192 initializeDirmngrCheckbox( mWidget->disableHTTPCB, e.mDisableHTTPEntry );
04193 initializeDirmngrCheckbox( mWidget->ignoreLDAPDPCB, e.mIgnoreLDAPDPEntry );
04194 initializeDirmngrCheckbox( mWidget->disableLDAPCB, e.mDisableLDAPEntry );
04195 if ( e.mCustomHTTPProxy ) {
04196 QString systemProxy = QString::fromLocal8Bit( getenv( "http_proxy" ) );
04197 if ( systemProxy.isEmpty() )
04198 systemProxy = i18n( "no proxy" );
04199 mWidget->systemHTTPProxy->setText( i18n( "(Current system setting: %1)" ).arg( systemProxy ) );
04200 bool honor = e.mHonorHTTPProxy && e.mHonorHTTPProxy->boolValue();
04201 mWidget->honorHTTPProxyRB->setChecked( honor );
04202 mWidget->useCustomHTTPProxyRB->setChecked( !honor );
04203 mWidget->customHTTPProxy->setText( e.mCustomHTTPProxy->stringValue() );
04204 } else {
04205 disableDirmngrWidget( mWidget->honorHTTPProxyRB );
04206 disableDirmngrWidget( mWidget->useCustomHTTPProxyRB );
04207 disableDirmngrWidget( mWidget->systemHTTPProxy );
04208 disableDirmngrWidget( mWidget->customHTTPProxy );
04209 }
04210 if ( e.mCustomLDAPProxy )
04211 mWidget->customLDAPProxy->setText( e.mCustomLDAPProxy->stringValue() );
04212 else {
04213 disableDirmngrWidget( mWidget->customLDAPProxy );
04214 disableDirmngrWidget( mWidget->customLDAPLabel );
04215 }
04216 slotUpdateHTTPActions();
04217 }
04218
04219 void SecurityPage::SMimeTab::slotUpdateHTTPActions() {
04220 mWidget->ignoreHTTPDPCB->setEnabled( !mWidget->disableHTTPCB->isChecked() );
04221
04222
04223 bool enableProxySettings = !mWidget->disableHTTPCB->isChecked()
04224 && mWidget->ignoreHTTPDPCB->isChecked();
04225 mWidget->systemHTTPProxy->setEnabled( enableProxySettings );
04226 mWidget->useCustomHTTPProxyRB->setEnabled( enableProxySettings );
04227 mWidget->honorHTTPProxyRB->setEnabled( enableProxySettings );
04228 mWidget->customHTTPProxy->setEnabled( enableProxySettings );
04229 }
04230
04231 void SecurityPage::SMimeTab::installProfile( KConfig * ) {
04232 }
04233
04234 static void saveCheckBoxToKleoEntry( QCheckBox* cb, Kleo::CryptoConfigEntry* entry ) {
04235 const bool b = cb->isChecked();
04236 if ( entry && entry->boolValue() != b )
04237 entry->setBoolValue( b );
04238 }
04239
04240 void SecurityPage::SMimeTab::save() {
04241 if ( !mConfig ) {
04242 return;
04243 }
04244
04245
04246
04247 SMIMECryptoConfigEntries e( mConfig );
04248
04249 bool b = mWidget->OCSPRB->isChecked();
04250 if ( e.mCheckUsingOCSPConfigEntry && e.mCheckUsingOCSPConfigEntry->boolValue() != b )
04251 e.mCheckUsingOCSPConfigEntry->setBoolValue( b );
04252
04253 if ( e.mEnableOCSPsendingConfigEntry && e.mEnableOCSPsendingConfigEntry->boolValue() != b )
04254 e.mEnableOCSPsendingConfigEntry->setBoolValue( b );
04255
04256 saveCheckBoxToKleoEntry( mWidget->doNotCheckCertPolicyCB, e.mDoNotCheckCertPolicyConfigEntry );
04257 saveCheckBoxToKleoEntry( mWidget->neverConsultCB, e.mNeverConsultConfigEntry );
04258 saveCheckBoxToKleoEntry( mWidget->fetchMissingCB, e.mFetchMissingConfigEntry );
04259
04260 QString txt = mWidget->OCSPResponderURL->text();
04261 if ( e.mOCSPResponderURLConfigEntry && e.mOCSPResponderURLConfigEntry->stringValue() != txt )
04262 e.mOCSPResponderURLConfigEntry->setStringValue( txt );
04263
04264 txt = mWidget->OCSPResponderSignature->fingerprint();
04265 if ( e.mOCSPResponderSignature && e.mOCSPResponderSignature->stringValue() != txt ) {
04266 e.mOCSPResponderSignature->setStringValue( txt );
04267 }
04268
04269
04270 saveCheckBoxToKleoEntry( mWidget->ignoreServiceURLCB, e.mIgnoreServiceURLEntry );
04271 saveCheckBoxToKleoEntry( mWidget->ignoreHTTPDPCB, e.mIgnoreHTTPDPEntry );
04272 saveCheckBoxToKleoEntry( mWidget->disableHTTPCB, e.mDisableHTTPEntry );
04273 saveCheckBoxToKleoEntry( mWidget->ignoreLDAPDPCB, e.mIgnoreLDAPDPEntry );
04274 saveCheckBoxToKleoEntry( mWidget->disableLDAPCB, e.mDisableLDAPEntry );
04275 if ( e.mCustomHTTPProxy ) {
04276 const bool honor = mWidget->honorHTTPProxyRB->isChecked();
04277 if ( e.mHonorHTTPProxy && e.mHonorHTTPProxy->boolValue() != honor )
04278 e.mHonorHTTPProxy->setBoolValue( honor );
04279
04280 QString chosenProxy = mWidget->customHTTPProxy->text();
04281 if ( chosenProxy != e.mCustomHTTPProxy->stringValue() )
04282 e.mCustomHTTPProxy->setStringValue( chosenProxy );
04283 }
04284 txt = mWidget->customLDAPProxy->text();
04285 if ( e.mCustomLDAPProxy && e.mCustomLDAPProxy->stringValue() != txt )
04286 e.mCustomLDAPProxy->setStringValue( mWidget->customLDAPProxy->text() );
04287
04288 mConfig->sync( true );
04289 }
04290
04291 bool SecurityPageSMimeTab::process(const QCString &fun, const QByteArray &data, QCString& replyType, QByteArray &replyData)
04292 {
04293 if ( fun == "load()" ) {
04294 replyType = "void";
04295 load();
04296 } else {
04297 return DCOPObject::process( fun, data, replyType, replyData );
04298 }
04299 return true;
04300 }
04301
04302 QCStringList SecurityPageSMimeTab::interfaces()
04303 {
04304 QCStringList ifaces = DCOPObject::interfaces();
04305 ifaces += "SecurityPageSMimeTab";
04306 return ifaces;
04307 }
04308
04309 QCStringList SecurityPageSMimeTab::functions()
04310 {
04311
04312 return DCOPObject::functions();
04313 }
04314
04315 Kleo::CryptoConfigEntry* SMIMECryptoConfigEntries::configEntry( const char* componentName,
04316 const char* groupName,
04317 const char* entryName,
04318 int argType,
04319 bool isList )
04320 {
04321 Kleo::CryptoConfigEntry* entry = mConfig->entry( componentName, groupName, entryName );
04322 if ( !entry ) {
04323 kdWarning(5006) << QString( "Backend error: gpgconf doesn't seem to know the entry for %1/%2/%3" ).arg( componentName, groupName, entryName ) << endl;
04324 return 0;
04325 }
04326 if( entry->argType() != argType || entry->isList() != isList ) {
04327 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;
04328 return 0;
04329 }
04330 return entry;
04331 }
04332
04334
04335 QString SecurityPage::CryptPlugTab::helpAnchor() const {
04336 return QString::fromLatin1("configure-security-crypto-backends");
04337 }
04338
04339 SecurityPageCryptPlugTab::SecurityPageCryptPlugTab( QWidget * parent, const char * name )
04340 : ConfigModuleTab( parent, name )
04341 {
04342 QVBoxLayout * vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
04343
04344 mBackendConfig = Kleo::CryptoBackendFactory::instance()->configWidget( this, "mBackendConfig" );
04345 connect( mBackendConfig, SIGNAL( changed( bool ) ), this, SIGNAL( changed( bool ) ) );
04346
04347 vlay->addWidget( mBackendConfig );
04348 }
04349
04350 SecurityPageCryptPlugTab::~SecurityPageCryptPlugTab()
04351 {
04352
04353 }
04354
04355 void SecurityPage::CryptPlugTab::doLoadOther() {
04356 mBackendConfig->load();
04357 }
04358
04359 void SecurityPage::CryptPlugTab::save() {
04360 mBackendConfig->save();
04361 }
04362
04363
04364
04365
04366
04367
04368 QString MiscPage::helpAnchor() const {
04369 return QString::fromLatin1("configure-misc");
04370 }
04371
04372 MiscPage::MiscPage( QWidget * parent, const char * name )
04373 : ConfigModuleWithTabs( parent, name )
04374 {
04375 mFolderTab = new FolderTab();
04376 addTab( mFolderTab, i18n("&Folders") );
04377
04378 mGroupwareTab = new GroupwareTab();
04379 addTab( mGroupwareTab, i18n("&Groupware") );
04380 load();
04381 }
04382
04383 QString MiscPage::FolderTab::helpAnchor() const {
04384 return QString::fromLatin1("configure-misc-folders");
04385 }
04386
04387 MiscPageFolderTab::MiscPageFolderTab( QWidget * parent, const char * name )
04388 : ConfigModuleTab( parent, name )
04389 {
04390
04391 QVBoxLayout *vlay;
04392 QHBoxLayout *hlay;
04393 QLabel *label;
04394
04395 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
04396
04397
04398 mEmptyFolderConfirmCheck =
04399 new QCheckBox( i18n("Corresponds to Folder->Move All Messages to Trash",
04400 "Ask for co&nfirmation before moving all messages to "
04401 "trash"),
04402 this );
04403 vlay->addWidget( mEmptyFolderConfirmCheck );
04404 connect( mEmptyFolderConfirmCheck, SIGNAL( stateChanged( int ) ),
04405 this, SLOT( slotEmitChanged( void ) ) );
04406 mExcludeImportantFromExpiry =
04407 new QCheckBox( i18n("E&xclude important messages from expiry"), this );
04408 vlay->addWidget( mExcludeImportantFromExpiry );
04409 connect( mExcludeImportantFromExpiry, SIGNAL( stateChanged( int ) ),
04410 this, SLOT( slotEmitChanged( void ) ) );
04411
04412
04413 hlay = new QHBoxLayout( vlay );
04414 mLoopOnGotoUnread = new QComboBox( false, this );
04415 label = new QLabel( mLoopOnGotoUnread,
04416 i18n("to be continued with \"do not loop\", \"loop in current folder\", "
04417 "and \"loop in all folders\".",
04418 "When trying to find unread messages:"), this );
04419 mLoopOnGotoUnread->insertStringList( QStringList()
04420 << i18n("continuation of \"When trying to find unread messages:\"",
04421 "Do not Loop")
04422 << i18n("continuation of \"When trying to find unread messages:\"",
04423 "Loop in Current Folder")
04424 << i18n("continuation of \"When trying to find unread messages:\"",
04425 "Loop in All Folders"));
04426 hlay->addWidget( label );
04427 hlay->addWidget( mLoopOnGotoUnread, 1 );
04428 connect( mLoopOnGotoUnread, SIGNAL( activated( int ) ),
04429 this, SLOT( slotEmitChanged( void ) ) );
04430
04431
04432 hlay = new QHBoxLayout( vlay );
04433 mActionEnterFolder = new QComboBox( false, this );
04434 label = new QLabel( mActionEnterFolder,
04435 i18n("to be continued with \"jump to first new message\", "
04436 "\"jump to first unread or new message\","
04437 "and \"jump to last selected message\".",
04438 "When entering a folder:"), this );
04439 mActionEnterFolder->insertStringList( QStringList()
04440 << i18n("continuation of \"When entering a folder:\"",
04441 "Jump to First New Message")
04442 << i18n("continuation of \"When entering a folder:\"",
04443 "Jump to First Unread or New Message")
04444 << i18n("continuation of \"When entering a folder:\"",
04445 "Jump to Last Selected Message"));
04446 hlay->addWidget( label );
04447 hlay->addWidget( mActionEnterFolder, 1 );
04448 connect( mActionEnterFolder, SIGNAL( activated( int ) ),
04449 this, SLOT( slotEmitChanged( void ) ) );
04450
04451 hlay = new QHBoxLayout( vlay );
04452 mDelayedMarkAsRead = new QCheckBox( i18n("Mar&k selected message as read after"), this );
04453 hlay->addWidget( mDelayedMarkAsRead );
04454 mDelayedMarkTime = new KIntSpinBox( 0 , 60 , 1,
04455 0 , 10 , this);
04456 mDelayedMarkTime->setSuffix( i18n(" sec") );
04457 mDelayedMarkTime->setEnabled( false );
04458 hlay->addWidget( mDelayedMarkTime );
04459 hlay->addStretch( 1 );
04460 connect( mDelayedMarkTime, SIGNAL( valueChanged( int ) ),
04461 this, SLOT( slotEmitChanged( void ) ) );
04462 connect( mDelayedMarkAsRead, SIGNAL(toggled(bool)),
04463 mDelayedMarkTime, SLOT(setEnabled(bool)));
04464 connect( mDelayedMarkAsRead, SIGNAL(toggled(bool)),
04465 this , SLOT(slotEmitChanged( void )));
04466
04467
04468 mShowPopupAfterDnD =
04469 new QCheckBox( i18n("Ask for action after &dragging messages to another folder"), this );
04470 vlay->addWidget( mShowPopupAfterDnD );
04471 connect( mShowPopupAfterDnD, SIGNAL( stateChanged( int ) ),
04472 this, SLOT( slotEmitChanged( void ) ) );
04473
04474
04475 hlay = new QHBoxLayout( vlay );
04476 mMailboxPrefCombo = new QComboBox( false, this );
04477 label = new QLabel( mMailboxPrefCombo,
04478 i18n("to be continued with \"flat files\" and "
04479 "\"directories\", resp.",
04480 "By default, &message folders on disk are:"), this );
04481 mMailboxPrefCombo->insertStringList( QStringList()
04482 << i18n("continuation of \"By default, &message folders on disk are\"",
04483 "Flat Files (\"mbox\" format)")
04484 << i18n("continuation of \"By default, &message folders on disk are\"",
04485 "Directories (\"maildir\" format)") );
04486 hlay->addWidget( label );
04487 hlay->addWidget( mMailboxPrefCombo, 1 );
04488 connect( mMailboxPrefCombo, SIGNAL( activated( int ) ),
04489 this, SLOT( slotEmitChanged( void ) ) );
04490
04491
04492 hlay = new QHBoxLayout( vlay );
04493 mOnStartupOpenFolder = new FolderRequester( this,
04494 kmkernel->getKMMainWidget()->folderTree() );
04495 label = new QLabel( mOnStartupOpenFolder,
04496 i18n("Open this folder on startup:"), this );
04497 hlay->addWidget( label );
04498 hlay->addWidget( mOnStartupOpenFolder, 1 );
04499 connect( mOnStartupOpenFolder, SIGNAL( folderChanged( KMFolder* ) ),
04500 this, SLOT( slotEmitChanged( void ) ) );
04501
04502
04503 hlay = new QHBoxLayout( vlay );
04504 mEmptyTrashCheck = new QCheckBox( i18n("Empty local &trash folder on program exit"),
04505 this );
04506 hlay->addWidget( mEmptyTrashCheck );
04507 connect( mEmptyTrashCheck, SIGNAL( stateChanged( int ) ),
04508 this, SLOT( slotEmitChanged( void ) ) );
04509
04510 #ifdef HAVE_INDEXLIB
04511
04512 mIndexingEnabled = new QCheckBox( i18n("Enable full text &indexing"), this );
04513 vlay->addWidget( mIndexingEnabled );
04514 connect( mIndexingEnabled, SIGNAL( stateChanged( int ) ),
04515 this, SLOT( slotEmitChanged( void ) ) );
04516 #endif
04517
04518
04519 hlay = new QHBoxLayout( vlay );
04520 mQuotaCmbBox = new QComboBox( false, this );
04521 label = new QLabel( mQuotaCmbBox,
04522 i18n("Quota units: "), this );
04523 mQuotaCmbBox->insertStringList( QStringList()
04524 << i18n("KB")
04525 << i18n("MB")
04526 << i18n("GB") );
04527 hlay->addWidget( label );
04528 hlay->addWidget( mQuotaCmbBox, 1 );
04529 connect( mQuotaCmbBox, SIGNAL( activated( int ) ), this, SLOT( slotEmitChanged( void ) ) );
04530
04531 vlay->addStretch( 1 );
04532
04533
04534 QString msg = i18n( "what's this help",
04535 "<qt><p>This selects which mailbox format will be "
04536 "the default for local folders:</p>"
04537 "<p><b>mbox:</b> KMail's mail "
04538 "folders are represented by a single file each. "
04539 "Individual messages are separated from each other by a "
04540 "line starting with \"From \". This saves space on "
04541 "disk, but may be less robust, e.g. when moving messages "
04542 "between folders.</p>"
04543 "<p><b>maildir:</b> KMail's mail folders are "
04544 "represented by real folders on disk. Individual messages "
04545 "are separate files. This may waste a bit of space on "
04546 "disk, but should be more robust, e.g. when moving "
04547 "messages between folders.</p></qt>");
04548 QWhatsThis::add( mMailboxPrefCombo, msg );
04549 QWhatsThis::add( label, msg );
04550
04551 msg = i18n( "what's this help",
04552 "<qt><p>When jumping to the next unread message, it may occur "
04553 "that no more unread messages are below the current message.</p>"
04554 "<p><b>Do not loop:</b> The search will stop at the last message in "
04555 "the current folder.</p>"
04556 "<p><b>Loop in current folder:</b> The search will continue at the "
04557 "top of the message list, but not go to another folder.</p>"
04558 "<p><b>Loop in all folders:</b> The search will continue at the top of "
04559 "the message list. If no unread messages are found it will then continue "
04560 "to the next folder.</p>"
04561 "<p>Similarly, when searching for the previous unread message, "
04562 "the search will start from the bottom of the message list and continue to "
04563 "the previous folder depending on which option is selected.</p></qt>" );
04564 QWhatsThis::add( mLoopOnGotoUnread, msg );
04565
04566 #ifdef HAVE_INDEXLIB
04567
04568 msg = i18n( "what's this help",
04569 "<qt><p>Full text indexing allows very fast searches on the content "
04570 "of your messages. When enabled, the search dialog will work very fast. "
04571 "Also, the search tool bar will select messages based on content.</p>"
04572 "<p>It takes up a certain amount of disk space "
04573 "(about half the disk space for the messages).</p>"
04574 "<p>After enabling, the index will need to be built, but you can continue to use KMail "
04575 "while this operation is running.</p>"
04576 "</qt>"
04577 );
04578
04579 QWhatsThis::add( mIndexingEnabled, msg );
04580 #endif
04581 }
04582
04583 void MiscPage::FolderTab::doLoadFromGlobalSettings() {
04584 mExcludeImportantFromExpiry->setChecked( GlobalSettings::self()->excludeImportantMailFromExpiry() );
04585
04586 mLoopOnGotoUnread->setCurrentItem( GlobalSettings::self()->loopOnGotoUnread() );
04587 mActionEnterFolder->setCurrentItem( GlobalSettings::self()->actionEnterFolder() );
04588 mDelayedMarkAsRead->setChecked( GlobalSettings::self()->delayedMarkAsRead() );
04589 mDelayedMarkTime->setValue( GlobalSettings::self()->delayedMarkTime() );
04590 mShowPopupAfterDnD->setChecked( GlobalSettings::self()->showPopupAfterDnD() );
04591 mQuotaCmbBox->setCurrentItem( GlobalSettings::self()->quotaUnit() );
04592 }
04593
04594 void MiscPage::FolderTab::doLoadOther() {
04595 KConfigGroup general( KMKernel::config(), "General" );
04596
04597 mEmptyTrashCheck->setChecked( general.readBoolEntry( "empty-trash-on-exit", true ) );
04598 mOnStartupOpenFolder->setFolder( general.readEntry( "startupFolder",
04599 kmkernel->inboxFolder()->idString() ) );
04600 mEmptyFolderConfirmCheck->setChecked( general.readBoolEntry( "confirm-before-empty", true ) );
04601
04602 int num = general.readNumEntry("default-mailbox-format", 1 );
04603 if ( num < 0 || num > 1 ) num = 1;
04604 mMailboxPrefCombo->setCurrentItem( num );
04605
04606 #ifdef HAVE_INDEXLIB
04607 mIndexingEnabled->setChecked( kmkernel->msgIndex() && kmkernel->msgIndex()->isEnabled() );
04608 #endif
04609 }
04610
04611 void MiscPage::FolderTab::save() {
04612 KConfigGroup general( KMKernel::config(), "General" );
04613
04614 general.writeEntry( "empty-trash-on-exit", mEmptyTrashCheck->isChecked() );
04615 general.writeEntry( "confirm-before-empty", mEmptyFolderConfirmCheck->isChecked() );
04616 general.writeEntry( "default-mailbox-format", mMailboxPrefCombo->currentItem() );
04617 general.writeEntry( "startupFolder", mOnStartupOpenFolder->folder() ?
04618 mOnStartupOpenFolder->folder()->idString() : QString::null );
04619
04620 GlobalSettings::self()->setDelayedMarkAsRead( mDelayedMarkAsRead->isChecked() );
04621 GlobalSettings::self()->setDelayedMarkTime( mDelayedMarkTime->value() );
04622 GlobalSettings::self()->setActionEnterFolder( mActionEnterFolder->currentItem() );
04623 GlobalSettings::self()->setLoopOnGotoUnread( mLoopOnGotoUnread->currentItem() );
04624 GlobalSettings::self()->setShowPopupAfterDnD( mShowPopupAfterDnD->isChecked() );
04625 GlobalSettings::self()->setExcludeImportantMailFromExpiry(
04626 mExcludeImportantFromExpiry->isChecked() );
04627 GlobalSettings::self()->setQuotaUnit( mQuotaCmbBox->currentItem() );
04628 #ifdef HAVE_INDEXLIB
04629 if ( kmkernel->msgIndex() ) kmkernel->msgIndex()->setEnabled( mIndexingEnabled->isChecked() );
04630 #endif
04631 }
04632
04633 QString MiscPage::GroupwareTab::helpAnchor() const {
04634 return QString::fromLatin1("configure-misc-groupware");
04635 }
04636
04637 MiscPageGroupwareTab::MiscPageGroupwareTab( QWidget* parent, const char* name )
04638 : ConfigModuleTab( parent, name )
04639 {
04640 QBoxLayout* vlay = new QVBoxLayout( this, KDialog::marginHint(),
04641 KDialog::spacingHint() );
04642 vlay->setAutoAdd( true );
04643
04644
04645 QVGroupBox* b1 = new QVGroupBox( i18n("&IMAP Resource Folder Options"),
04646 this );
04647
04648 mEnableImapResCB =
04649 new QCheckBox( i18n("&Enable IMAP resource functionality"), b1 );
04650 QToolTip::add( mEnableImapResCB, i18n( "This enables the IMAP storage for "
04651 "the Kontact applications" ) );
04652 QWhatsThis::add( mEnableImapResCB,
04653 i18n( GlobalSettings::self()->theIMAPResourceEnabledItem()->whatsThis().utf8() ) );
04654 connect( mEnableImapResCB, SIGNAL( stateChanged( int ) ),
04655 this, SLOT( slotEmitChanged( void ) ) );
04656
04657 mBox = new QWidget( b1 );
04658 QGridLayout* grid = new QGridLayout( mBox, 4, 2, 0, KDialog::spacingHint() );
04659 grid->setColStretch( 1, 1 );
04660 connect( mEnableImapResCB, SIGNAL( toggled(bool) ),
04661 mBox, SLOT( setEnabled(bool) ) );
04662
04663 QLabel* storageFormatLA = new QLabel( i18n("&Format used for the groupware folders:"),
04664 mBox );
04665 QString toolTip = i18n( "Choose the format to use to store the contents of the groupware folders." );
04666 QString whatsThis = i18n( GlobalSettings::self()
04667 ->theIMAPResourceStorageFormatItem()->whatsThis().utf8() );
04668 grid->addWidget( storageFormatLA, 0, 0 );
04669 QToolTip::add( storageFormatLA, toolTip );
04670 QWhatsThis::add( storageFormatLA, whatsThis );
04671 mStorageFormatCombo = new QComboBox( false, mBox );
04672 storageFormatLA->setBuddy( mStorageFormatCombo );
04673 QStringList formatLst;
04674 formatLst << i18n("Standard (Ical / Vcard)") << i18n("Kolab (XML)");
04675 mStorageFormatCombo->insertStringList( formatLst );
04676 grid->addWidget( mStorageFormatCombo, 0, 1 );
04677 QToolTip::add( mStorageFormatCombo, toolTip );
04678 QWhatsThis::add( mStorageFormatCombo, whatsThis );
04679 connect( mStorageFormatCombo, SIGNAL( activated( int ) ),
04680 this, SLOT( slotStorageFormatChanged( int ) ) );
04681
04682 QLabel* languageLA = new QLabel( i18n("&Language of the groupware folders:"),
04683 mBox );
04684
04685 toolTip = i18n( "Set the language of the folder names" );
04686 whatsThis = i18n( GlobalSettings::self()
04687 ->theIMAPResourceFolderLanguageItem()->whatsThis().utf8() );
04688 grid->addWidget( languageLA, 1, 0 );
04689 QToolTip::add( languageLA, toolTip );
04690 QWhatsThis::add( languageLA, whatsThis );
04691 mLanguageCombo = new QComboBox( false, mBox );
04692 languageLA->setBuddy( mLanguageCombo );
04693 QStringList lst;
04694 lst << i18n("English") << i18n("German") << i18n("French") << i18n("Dutch");
04695 mLanguageCombo->insertStringList( lst );
04696 grid->addWidget( mLanguageCombo, 1, 1 );
04697 QToolTip::add( mLanguageCombo, toolTip );
04698 QWhatsThis::add( mLanguageCombo, whatsThis );
04699 connect( mLanguageCombo, SIGNAL( activated( int ) ),
04700 this, SLOT( slotEmitChanged( void ) ) );
04701
04702 mFolderComboLabel = new QLabel( mBox );
04703 toolTip = i18n( "Set the parent of the resource folders" );
04704 whatsThis = i18n( GlobalSettings::self()->theIMAPResourceFolderParentItem()->whatsThis().utf8() );
04705 QToolTip::add( mFolderComboLabel, toolTip );
04706 QWhatsThis::add( mFolderComboLabel, whatsThis );
04707 grid->addWidget( mFolderComboLabel, 2, 0 );
04708
04709 mFolderComboStack = new QWidgetStack( mBox );
04710 grid->addWidget( mFolderComboStack, 2, 1 );
04711
04712
04713
04714 mFolderCombo = new FolderRequester( mBox,
04715 kmkernel->getKMMainWidget()->folderTree() );
04716 mFolderComboStack->addWidget( mFolderCombo, 0 );
04717 QToolTip::add( mFolderCombo, toolTip );
04718 QWhatsThis::add( mFolderCombo, whatsThis );
04719 connect( mFolderCombo, SIGNAL( folderChanged( KMFolder* ) ),
04720 this, SLOT( slotEmitChanged() ) );
04721
04722
04723
04724
04725 mAccountCombo = new KMail::AccountComboBox( mBox );
04726 mFolderComboStack->addWidget( mAccountCombo, 1 );
04727 QToolTip::add( mAccountCombo, toolTip );
04728 QWhatsThis::add( mAccountCombo, whatsThis );
04729 connect( mAccountCombo, SIGNAL( activated( int ) ),
04730 this, SLOT( slotEmitChanged() ) );
04731
04732 mHideGroupwareFolders = new QCheckBox( i18n( "&Hide groupware folders" ),
04733 mBox, "HideGroupwareFoldersBox" );
04734 grid->addMultiCellWidget( mHideGroupwareFolders, 3, 3, 0, 0 );
04735 QToolTip::add( mHideGroupwareFolders,
04736 i18n( "When this is checked, you will not see the IMAP "
04737 "resource folders in the folder tree." ) );
04738 QWhatsThis::add( mHideGroupwareFolders, i18n( GlobalSettings::self()
04739 ->hideGroupwareFoldersItem()->whatsThis().utf8() ) );
04740 connect( mHideGroupwareFolders, SIGNAL( toggled( bool ) ),
04741 this, SLOT( slotEmitChanged() ) );
04742
04743 mOnlyShowGroupwareFolders = new QCheckBox( i18n( "&Only show groupware folders for this account" ),
04744 mBox, "OnlyGroupwareFoldersBox" );
04745 grid->addMultiCellWidget( mOnlyShowGroupwareFolders, 3, 3, 1, 1 );
04746 QToolTip::add( mOnlyShowGroupwareFolders,
04747 i18n( "When this is checked, you will not see normal "
04748 "mail folders in the folder tree for the account "
04749 "configured for groupware." ) );
04750 QWhatsThis::add( mOnlyShowGroupwareFolders, i18n( GlobalSettings::self()
04751 ->showOnlyGroupwareFoldersForGroupwareAccountItem()->whatsThis().utf8() ) );
04752 connect( mOnlyShowGroupwareFolders, SIGNAL( toggled( bool ) ),
04753 this, SLOT( slotEmitChanged() ) );
04754
04755
04756 b1 = new QVGroupBox( i18n("Groupware Compatibility && Legacy Options"), this );
04757
04758 gBox = new QVBox( b1 );
04759 #if 0
04760
04761 mEnableGwCB = new QCheckBox( i18n("&Enable groupware functionality"), b1 );
04762 gBox->setSpacing( KDialog::spacingHint() );
04763 connect( mEnableGwCB, SIGNAL( toggled(bool) ),
04764 gBox, SLOT( setEnabled(bool) ) );
04765 connect( mEnableGwCB, SIGNAL( stateChanged( int ) ),
04766 this, SLOT( slotEmitChanged( void ) ) );
04767 #endif
04768 mEnableGwCB = 0;
04769 mLegacyMangleFromTo = new QCheckBox( i18n( "Mangle From:/To: headers in replies to invitations" ), gBox );
04770 QToolTip::add( mLegacyMangleFromTo, i18n( "Turn this option on in order to make Outlook(tm) understand your answers to invitation replies" ) );
04771 QWhatsThis::add( mLegacyMangleFromTo, i18n( GlobalSettings::self()->
04772 legacyMangleFromToHeadersItem()->whatsThis().utf8() ) );
04773 connect( mLegacyMangleFromTo, SIGNAL( stateChanged( int ) ),
04774 this, SLOT( slotEmitChanged( void ) ) );
04775 mLegacyBodyInvites = new QCheckBox( i18n( "Send invitations in the mail body" ), gBox );
04776 QToolTip::add( mLegacyBodyInvites, i18n( "Turn this option on in order to make Outlook(tm) understand your answers to invitations" ) );
04777 QWhatsThis::add( mLegacyMangleFromTo, i18n( GlobalSettings::self()->
04778 legacyBodyInvitesItem()->whatsThis().utf8() ) );
04779 connect( mLegacyBodyInvites, SIGNAL( toggled( bool ) ),
04780 this, SLOT( slotLegacyBodyInvitesToggled( bool ) ) );
04781 connect( mLegacyBodyInvites, SIGNAL( stateChanged( int ) ),
04782 this, SLOT( slotEmitChanged( void ) ) );
04783
04784 mExchangeCompatibleInvitations = new QCheckBox( i18n( "Exchange compatible invitation naming" ), gBox );
04785 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." ) );
04786 QWhatsThis::add( mExchangeCompatibleInvitations, i18n( GlobalSettings::self()->
04787 exchangeCompatibleInvitationsItem()->whatsThis().utf8() ) );
04788 connect( mExchangeCompatibleInvitations, SIGNAL( stateChanged( int ) ),
04789 this, SLOT( slotEmitChanged( void ) ) );
04790
04791 mAutomaticSending = new QCheckBox( i18n( "Automatic invitation sending" ), gBox );
04792 QToolTip::add( mAutomaticSending, i18n( "When this is on, the user will not see the mail composer window. Invitation mails are sent automatically" ) );
04793 QWhatsThis::add( mAutomaticSending, i18n( GlobalSettings::self()->
04794 automaticSendingItem()->whatsThis().utf8() ) );
04795 connect( mAutomaticSending, SIGNAL( stateChanged( int ) ),
04796 this, SLOT( slotEmitChanged( void ) ) );
04797
04798
04799 new QLabel( this );
04800 }
04801
04802 void MiscPageGroupwareTab::slotLegacyBodyInvitesToggled( bool on )
04803 {
04804 if ( on ) {
04805 QString txt = i18n( "<qt>Invitations are normally sent as attachments to "
04806 "a mail. This switch changes the invitation mails to "
04807 "be sent in the text of the mail instead; this is "
04808 "necessary to send invitations and replies to "
04809 "Microsoft Outlook.<br>But, when you do this, you no "
04810 "longer get descriptive text that mail programs "
04811 "can read; so, to people who have email programs "
04812 "that do not understand the invitations, the "
04813 "resulting messages look very odd.<br>People that have email "
04814 "programs that do understand invitations will still "
04815 "be able to work with this.</qt>" );
04816 KMessageBox::information( this, txt, QString::null,
04817 "LegacyBodyInvitesWarning" );
04818 }
04819
04820
04821 mAutomaticSending->setEnabled( !mLegacyBodyInvites->isChecked() );
04822 }
04823
04824 void MiscPage::GroupwareTab::doLoadFromGlobalSettings() {
04825 if ( mEnableGwCB ) {
04826 mEnableGwCB->setChecked( GlobalSettings::self()->groupwareEnabled() );
04827 gBox->setEnabled( mEnableGwCB->isChecked() );
04828 }
04829
04830 mLegacyMangleFromTo->setChecked( GlobalSettings::self()->legacyMangleFromToHeaders() );
04831 mLegacyBodyInvites->blockSignals( true );
04832
04833 mLegacyBodyInvites->setChecked( GlobalSettings::self()->legacyBodyInvites() );
04834 mLegacyBodyInvites->blockSignals( false );
04835
04836 mExchangeCompatibleInvitations->setChecked( GlobalSettings::self()->exchangeCompatibleInvitations() );
04837
04838 mAutomaticSending->setChecked( GlobalSettings::self()->automaticSending() );
04839 mAutomaticSending->setEnabled( !mLegacyBodyInvites->isChecked() );
04840
04841
04842 mEnableImapResCB->setChecked( GlobalSettings::self()->theIMAPResourceEnabled() );
04843 mBox->setEnabled( mEnableImapResCB->isChecked() );
04844
04845 mHideGroupwareFolders->setChecked( GlobalSettings::self()->hideGroupwareFolders() );
04846 int i = GlobalSettings::self()->theIMAPResourceFolderLanguage();
04847 mLanguageCombo->setCurrentItem(i);
04848 i = GlobalSettings::self()->theIMAPResourceStorageFormat();
04849 mStorageFormatCombo->setCurrentItem(i);
04850 slotStorageFormatChanged( i );
04851 mOnlyShowGroupwareFolders->setChecked( GlobalSettings::self()->showOnlyGroupwareFoldersForGroupwareAccount() );
04852
04853 QString folderId( GlobalSettings::self()->theIMAPResourceFolderParent() );
04854 if( !folderId.isNull() && kmkernel->findFolderById( folderId ) ) {
04855 mFolderCombo->setFolder( folderId );
04856 } else {
04857
04858 mFolderCombo->setFolder( i18n( "<Choose a Folder>" ) );
04859 }
04860
04861 KMAccount* selectedAccount = 0;
04862 int accountId = GlobalSettings::self()->theIMAPResourceAccount();
04863 if ( accountId )
04864 selectedAccount = kmkernel->acctMgr()->find( accountId );
04865 else {
04866
04867 for( KMAccount *a = kmkernel->acctMgr()->first(); a!=0;
04868 a = kmkernel->acctMgr()->next() ) {
04869 if( a->folder() && a->folder()->child() ) {
04870
04871 KMFolderNode *node;
04872 for (node = a->folder()->child()->first(); node; node = a->folder()->child()->next())
04873 if (!node->isDir() && node->name() == "INBOX") break;
04874
04875 if ( node && static_cast<KMFolder*>(node)->idString() == folderId ) {
04876 selectedAccount = a;
04877 break;
04878 }
04879 }
04880 }
04881 }
04882 if ( selectedAccount )
04883 mAccountCombo->setCurrentAccount( selectedAccount );
04884 else if ( GlobalSettings::self()->theIMAPResourceStorageFormat() == 1 )
04885 kdDebug(5006) << "Folder " << folderId << " not found as an account's inbox" << endl;
04886 }
04887
04888 void MiscPage::GroupwareTab::save() {
04889 KConfigGroup groupware( KMKernel::config(), "Groupware" );
04890
04891
04892 if ( mEnableGwCB ) {
04893 groupware.writeEntry( "GroupwareEnabled", mEnableGwCB->isChecked() );
04894 }
04895 groupware.writeEntry( "LegacyMangleFromToHeaders", mLegacyMangleFromTo->isChecked() );
04896 groupware.writeEntry( "LegacyBodyInvites", mLegacyBodyInvites->isChecked() );
04897 groupware.writeEntry( "ExchangeCompatibleInvitations", mExchangeCompatibleInvitations->isChecked() );
04898 groupware.writeEntry( "AutomaticSending", mAutomaticSending->isChecked() );
04899
04900 if ( mEnableGwCB ) {
04901 GlobalSettings::self()->setGroupwareEnabled( mEnableGwCB->isChecked() );
04902 }
04903 GlobalSettings::self()->setLegacyMangleFromToHeaders( mLegacyMangleFromTo->isChecked() );
04904 GlobalSettings::self()->setLegacyBodyInvites( mLegacyBodyInvites->isChecked() );
04905 GlobalSettings::self()->setExchangeCompatibleInvitations( mExchangeCompatibleInvitations->isChecked() );
04906 GlobalSettings::self()->setAutomaticSending( mAutomaticSending->isChecked() );
04907
04908 int format = mStorageFormatCombo->currentItem();
04909 GlobalSettings::self()->setTheIMAPResourceStorageFormat( format );
04910
04911
04912 GlobalSettings::self()->setHideGroupwareFolders( mHideGroupwareFolders->isChecked() );
04913 GlobalSettings::self()->setShowOnlyGroupwareFoldersForGroupwareAccount( mOnlyShowGroupwareFolders->isChecked() );
04914
04915
04916
04917 QString folderId;
04918 if ( format == 0 ) {
04919 KMFolder* folder = mFolderCombo->folder();
04920 if ( folder )
04921 folderId = folder->idString();
04922 } else {
04923
04924 KMAccount* acct = mAccountCombo->currentAccount();
04925 if ( acct ) {
04926 folderId = QString( ".%1.directory/INBOX" ).arg( acct->id() );
04927 GlobalSettings::self()->setTheIMAPResourceAccount( acct->id() );
04928 }
04929 }
04930
04931 bool enabled = mEnableImapResCB->isChecked() && !folderId.isEmpty();
04932 GlobalSettings::self()->setTheIMAPResourceEnabled( enabled );
04933 GlobalSettings::self()->setTheIMAPResourceFolderLanguage( mLanguageCombo->currentItem() );
04934 GlobalSettings::self()->setTheIMAPResourceFolderParent( folderId );
04935 }
04936
04937 void MiscPage::GroupwareTab::slotStorageFormatChanged( int format )
04938 {
04939 mLanguageCombo->setEnabled( format == 0 );
04940 mFolderComboStack->raiseWidget( format );
04941 if ( format == 0 ) {
04942 mFolderComboLabel->setText( i18n("&Resource folders are subfolders of:") );
04943 mFolderComboLabel->setBuddy( mFolderCombo );
04944 } else {
04945 mFolderComboLabel->setText( i18n("&Resource folders are in account:") );
04946 mFolderComboLabel->setBuddy( mAccountCombo );
04947 }
04948 slotEmitChanged();
04949 }
04950
04951
04952
04953
04954
04955
04956
04957 AccountUpdater::AccountUpdater(ImapAccountBase *account)
04958 : QObject()
04959 {
04960 mAccount = account;
04961 }
04962
04963 void AccountUpdater::update()
04964 {
04965 connect( mAccount, SIGNAL( connectionResult(int, const QString&) ),
04966 this, SLOT( namespacesFetched() ) );
04967 mAccount->makeConnection();
04968 }
04969
04970 void AccountUpdater::namespacesFetched()
04971 {
04972 mAccount->setCheckingMail( true );
04973 mAccount->processNewMail( false );
04974 deleteLater();
04975 }
04976
04977 #undef DIM
04978
04979
04980 #include "configuredialog.moc"