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