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