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