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
00031 #include "simplestringlisteditor.h"
00032 #include "accountdialog.h"
00033 #include "colorlistbox.h"
00034 #include "kmacctmgr.h"
00035 #include "kmacctseldlg.h"
00036 #include "kmsender.h"
00037 #include "kmtopwidget.h"
00038 #include "kmtransport.h"
00039 #include "kmfoldermgr.h"
00040 #include "kmgroupware.h"
00041 #include "kmailicalifaceimpl.h"
00042 #include "cryptplugconfigdialog.h"
00043 #include "kmidentity.h"
00044 #include "identitymanager.h"
00045 #include "identitylistview.h"
00046 #include "kcursorsaver.h"
00047 #include "cryptplugwrapperlist.h"
00048 #include "kmkernel.h"
00049
00050 using KMail::IdentityListView;
00051 using KMail::IdentityListViewItem;
00052 #include "identitydialog.h"
00053 using KMail::IdentityDialog;
00054
00055
00056 #include <kpgpui.h>
00057 #include <kmime_util.h>
00058 using KMime::DateFormatter;
00059
00060
00061
00062 #include <klocale.h>
00063 #include <kapplication.h>
00064 #include <kcharsets.h>
00065 #include <kdebug.h>
00066 #include <knuminput.h>
00067 #include <kfontdialog.h>
00068 #include <kmessagebox.h>
00069 #include <kurlrequester.h>
00070 #include <kseparator.h>
00071 #include <kiconloader.h>
00072 #include <kstandarddirs.h>
00073 #include <kwin.h>
00074 #include <knotifydialog.h>
00075 #include <kconfig.h>
00076 #include <kactivelabel.h>
00077
00078
00079 #include <qvalidator.h>
00080 #include <qwhatsthis.h>
00081 #include <qvgroupbox.h>
00082 #include <qvbox.h>
00083 #include <qvbuttongroup.h>
00084 #include <qhbuttongroup.h>
00085 #include <qtooltip.h>
00086 #include <qlabel.h>
00087 #include <qtextcodec.h>
00088 #include <qheader.h>
00089 #include <qpopupmenu.h>
00090
00091
00092 #include <assert.h>
00093
00094 #ifndef _PATH_SENDMAIL
00095 #define _PATH_SENDMAIL "/usr/sbin/sendmail"
00096 #endif
00097
00098 #ifdef DIM
00099 #undef DIM
00100 #endif
00101 #define DIM(x) sizeof(x) / sizeof(*x)
00102
00103 namespace {
00104
00105 struct EnumConfigEntryItem {
00106 const char * key;
00107 const char * desc;
00108 };
00109 struct EnumConfigEntry {
00110 const char * group;
00111 const char * key;
00112 const char * desc;
00113 const EnumConfigEntryItem * items;
00114 int numItems;
00115 int defaultItem;
00116 };
00117 struct BoolConfigEntry {
00118 const char * group;
00119 const char * key;
00120 const char * desc;
00121 bool defaultValue;
00122 };
00123
00124 static const char * lockedDownWarning =
00125 I18N_NOOP("<qt><p>This setting has been fixed by your administrator.</p>"
00126 "<p>If you think this is an error, please contact him.</p></qt>");
00127
00128 void checkLockDown( QWidget * w, const KConfigBase & c, const char * key ) {
00129 if ( c.entryIsImmutable( key ) ) {
00130 w->setEnabled( false );
00131 QToolTip::add( w, i18n( lockedDownWarning ) );
00132 } else {
00133 QToolTip::remove( w );
00134 }
00135 }
00136
00137 void populate( QButtonGroup * g, const EnumConfigEntry & e ) {
00138 g->setTitle( i18n( e.desc ) );
00139 g->layout()->setSpacing( KDialog::spacingHint() );
00140 for ( int i = 0 ; i < e.numItems ; ++i )
00141 g->insert( new QRadioButton( i18n( e.items[i].desc ), g ), i );
00142 }
00143
00144 void populate( QCheckBox * b, const BoolConfigEntry & e ) {
00145 b->setText( i18n( e.desc ) );
00146 }
00147
00148 void load( QCheckBox * b, const KConfigBase & c, const BoolConfigEntry & e ) {
00149 Q_ASSERT( c.group() == e.group );
00150 checkLockDown( b, c, e.key );
00151 b->setChecked( c.readBoolEntry( e.key, e.defaultValue ) );
00152 }
00153
00154 void load( QButtonGroup * g, const KConfigBase & c, const EnumConfigEntry & e ) {
00155 Q_ASSERT( c.group() == e.group );
00156 Q_ASSERT( g->count() == e.numItems );
00157 checkLockDown( g, c, e.key );
00158 const QString s = c.readEntry( e.key, e.items[e.defaultItem].key );
00159 for ( int i = 0 ; i < e.numItems ; ++i )
00160 if ( s == e.items[i].key ) {
00161 g->setButton( i );
00162 return;
00163 }
00164 g->setButton( e.defaultItem );
00165 }
00166
00167 void save( QCheckBox * b, KConfigBase & c, const BoolConfigEntry & e ) {
00168 Q_ASSERT( c.group() == e.group );
00169 c.writeEntry( e.key, b->isChecked() );
00170 }
00171
00172 void save( QButtonGroup * g, KConfigBase & c, const EnumConfigEntry & e ) {
00173 Q_ASSERT( c.group() == e.group );
00174 Q_ASSERT( g->count() == e.numItems );
00175 c.writeEntry( e.key, e.items[ g->id( g->selected() ) ].key );
00176 }
00177
00178 template <typename T_Widget, typename T_Entry>
00179 inline void loadProfile( T_Widget * g, const KConfigBase & c, const T_Entry & e ) {
00180 if ( c.hasKey( e.key ) )
00181 load( g, c, e );
00182 }
00183
00184
00185 inline QPixmap loadIcon( const char * name ) {
00186 return KGlobal::instance()->iconLoader()
00187 ->loadIcon( QString::fromLatin1(name), KIcon::NoGroup, KIcon::SizeMedium );
00188 }
00189
00190 }
00191
00192
00193 ConfigureDialog::ConfigureDialog( QWidget *parent, const char *name,
00194 bool modal )
00195 : KDialogBase( IconList, i18n("Configure"), Help|Apply|Ok|Cancel|User1,
00196 Ok, parent, name, modal, true, i18n("&Load Profile...") ),
00197 mProfileDialog( 0 )
00198 {
00199 KWin::setIcons( winId(), kapp->icon(), kapp->miniIcon() );
00200
00201
00202 setIconListAllVisible( true );
00203
00204 connect( this, SIGNAL(cancelClicked()), this, SLOT(slotCancelOrClose()) );
00205
00206 QWidget *page;
00207 QVBoxLayout *vlay;
00208 ConfigurationPage *configPage;
00209
00210
00211 page = addPage( IdentityPage::iconLabel(), IdentityPage::title(),
00212 loadIcon( IdentityPage::iconName() ) );
00213 vlay = new QVBoxLayout( page, 0, spacingHint() );
00214 configPage = new IdentityPage( page );
00215 vlay->addWidget( configPage );
00216 configPage->setPageIndex( pageIndex( page ) );
00217 mPages.append( configPage );
00218
00219
00220 page = addPage( NetworkPage::iconLabel(), NetworkPage::title(),
00221 loadIcon( NetworkPage::iconName() ) );
00222 vlay = new QVBoxLayout( page, 0, spacingHint() );
00223 configPage = new NetworkPage( page );
00224 vlay->addWidget( configPage );
00225 configPage->setPageIndex( pageIndex( page ) );
00226 mPages.append( configPage );
00227
00228
00229
00230
00231 connect( configPage, SIGNAL(transportListChanged(const QStringList &)),
00232 mPages.getFirst(), SLOT(slotUpdateTransportCombo(const QStringList &)) );
00233
00234
00235 page = addPage( AppearancePage::iconLabel(), AppearancePage::title(),
00236 loadIcon( AppearancePage::iconName() ) );
00237 vlay = new QVBoxLayout( page, 0, spacingHint() );
00238 configPage = new AppearancePage( page );
00239 vlay->addWidget( configPage );
00240 configPage->setPageIndex( pageIndex( page ) );
00241 mPages.append( configPage );
00242
00243
00244 page = addPage( ComposerPage::iconLabel(), ComposerPage::title(),
00245 loadIcon( ComposerPage::iconName() ) );
00246 vlay = new QVBoxLayout( page, 0, spacingHint() );
00247 configPage = new ComposerPage( page );
00248 vlay->addWidget( configPage );
00249 configPage->setPageIndex( pageIndex( page ) );
00250 mPages.append( configPage );
00251
00252
00253 page = addPage( SecurityPage::iconLabel(), SecurityPage::title(),
00254 loadIcon( SecurityPage::iconName() ) );
00255 vlay = new QVBoxLayout( page, 0, spacingHint() );
00256 configPage = new SecurityPage( page );
00257 vlay->addWidget( configPage );
00258 configPage->setPageIndex( pageIndex( page ) );
00259 mPages.append( configPage );
00260
00261
00262 page = addPage( MiscPage::iconLabel(), MiscPage::title(),
00263 loadIcon( MiscPage::iconName() ) );
00264 vlay = new QVBoxLayout( page, 0, spacingHint() );
00265 configPage = new MiscPage( page );
00266 vlay->addWidget( configPage );
00267 configPage->setPageIndex( pageIndex( page ) );
00268 mPages.append( configPage );
00269 }
00270
00271
00272 ConfigureDialog::~ConfigureDialog() {
00273 }
00274
00275
00276 void ConfigureDialog::show() {
00277
00278 if( !isVisible() )
00279 setup();
00280 KDialogBase::show();
00281 }
00282
00283 void ConfigureDialog::slotCancelOrClose() {
00284 for ( QPtrListIterator<ConfigurationPage> it( mPages ) ; it.current() ; ++it )
00285 it.current()->dismiss();
00286 }
00287
00288 void ConfigureDialog::slotOk() {
00289 apply( true );
00290 accept();
00291 }
00292
00293
00294 void ConfigureDialog::slotApply() {
00295 apply( false );
00296 }
00297
00298 void ConfigureDialog::slotHelp() {
00299 const int activePage = activePageIndex();
00300 if ( activePage >= 0 && (unsigned int)activePage < mPages.count() )
00301 kapp->invokeHelp( mPages.at( activePage )->helpAnchor() );
00302 else
00303 kdDebug(5006) << "ConfigureDialog::slotHelp(): no page selected???"
00304 << endl;
00305 }
00306
00307 void ConfigureDialog::slotUser1() {
00308 if ( mProfileDialog ) {
00309 mProfileDialog->raise();
00310 return;
00311 }
00312 mProfileDialog = new ProfileDialog( this, "mProfileDialog" );
00313 connect( mProfileDialog, SIGNAL(profileSelected(KConfig*)),
00314 SLOT(slotInstallProfile(KConfig*)) );
00315 mProfileDialog->show();
00316 }
00317
00318 void ConfigureDialog::setup() {
00319 for ( QPtrListIterator<ConfigurationPage> it( mPages ) ; it.current() ; ++it )
00320 it.current()->setup();
00321 }
00322
00323 void ConfigureDialog::slotInstallProfile( KConfig * profile ) {
00324 for ( QPtrListIterator<ConfigurationPage> it( mPages ) ; it.current() ; ++it )
00325 it.current()->installProfile( profile );
00326 }
00327
00328 void ConfigureDialog::apply( bool everything ) {
00329 const int activePage = activePageIndex();
00330
00331 if ( !everything )
00332 mPages.at( activePage )->apply();
00333 else
00334 for ( QPtrListIterator<ConfigurationPage> it( mPages ) ; it.current() ; ++it )
00335 it.current()->apply();
00336
00337
00338
00339
00340 KMMessage::readConfig();
00341 KCursorSaver busy(KBusyPtr::busy());
00342
00343 emit configChanged();
00344 }
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354 QString IdentityPage::iconLabel() {
00355 return i18n("Identities");
00356 }
00357
00358 QString IdentityPage::title() {
00359 return i18n("Manage Identities");
00360 }
00361
00362 const char * IdentityPage::iconName() {
00363 return "identity";
00364 }
00365
00366 QString IdentityPage::helpAnchor() const {
00367 return QString::fromLatin1("configure-identity");
00368 }
00369
00370 IdentityPage::IdentityPage( QWidget * parent, const char * name )
00371 : ConfigurationPage( parent, name ),
00372 mIdentityDialog( 0 )
00373 {
00374 QHBoxLayout * hlay = new QHBoxLayout( this, 0, KDialog::spacingHint() );
00375
00376 mIdentityList = new IdentityListView( this );
00377 connect( mIdentityList, SIGNAL(selectionChanged(QListViewItem*)),
00378 SLOT(slotIdentitySelectionChanged(QListViewItem*)) );
00379 connect( mIdentityList, SIGNAL(itemRenamed(QListViewItem*,const QString&,int)),
00380 SLOT(slotRenameIdentity(QListViewItem*,const QString&,int)) );
00381 connect( mIdentityList, SIGNAL(doubleClicked(QListViewItem*,const QPoint&,int)),
00382 SLOT(slotModifyIdentity()) );
00383 connect( mIdentityList, SIGNAL(contextMenu(KListView*,QListViewItem*,const QPoint&)),
00384 SLOT(slotContextMenu(KListView*,QListViewItem*,const QPoint&)) );
00385
00386
00387 hlay->addWidget( mIdentityList, 1 );
00388
00389 QVBoxLayout * vlay = new QVBoxLayout( hlay );
00390
00391 QPushButton * button = new QPushButton( i18n("&New..."), this );
00392 mModifyButton = new QPushButton( i18n("&Modify..."), this );
00393 mRenameButton = new QPushButton( i18n("&Rename"), this );
00394 mRemoveButton = new QPushButton( i18n("Remo&ve"), this );
00395 mSetAsDefaultButton = new QPushButton( i18n("Set as &Default"), this );
00396 button->setAutoDefault( false );
00397 mModifyButton->setAutoDefault( false );
00398 mModifyButton->setEnabled( false );
00399 mRenameButton->setAutoDefault( false );
00400 mRenameButton->setEnabled( false );
00401 mRemoveButton->setAutoDefault( false );
00402 mRemoveButton->setEnabled( false );
00403 mSetAsDefaultButton->setAutoDefault( false );
00404 mSetAsDefaultButton->setEnabled( false );
00405 connect( button, SIGNAL(clicked()),
00406 this, SLOT(slotNewIdentity()) );
00407 connect( mModifyButton, SIGNAL(clicked()),
00408 this, SLOT(slotModifyIdentity()) );
00409 connect( mRenameButton, SIGNAL(clicked()),
00410 this, SLOT(slotRenameIdentity()) );
00411 connect( mRemoveButton, SIGNAL(clicked()),
00412 this, SLOT(slotRemoveIdentity()) );
00413 connect( mSetAsDefaultButton, SIGNAL(clicked()),
00414 this, SLOT(slotSetAsDefault()) );
00415 vlay->addWidget( button );
00416 vlay->addWidget( mModifyButton );
00417 vlay->addWidget( mRenameButton );
00418 vlay->addWidget( mRemoveButton );
00419 vlay->addWidget( mSetAsDefaultButton );
00420 vlay->addStretch( 1 );
00421 }
00422
00423 void IdentityPage::setup()
00424 {
00425 kdDebug(5006) << "IdentityPage::setup()" << endl;
00426 IdentityManager * im = kmkernel->identityManager();
00427 mOldNumberOfIdentities = im->shadowIdentities().count();
00428
00429 mIdentityList->clear();
00430
00431 QListViewItem * item = 0;
00432 for ( IdentityManager::Iterator it = im->begin() ; it != im->end() ; ++it )
00433 item = new IdentityListViewItem( mIdentityList, item, *it );
00434 mIdentityList->setSelected( mIdentityList->currentItem(), true );
00435 }
00436
00437 void IdentityPage::apply() {
00438 assert( !mIdentityDialog );
00439
00440 kmkernel->identityManager()->sort();
00441 kmkernel->identityManager()->commit();
00442
00443 if( mOldNumberOfIdentities < 2 && mIdentityList->childCount() > 1 ) {
00444
00445
00446 KConfigGroup composer( KMKernel::config(), "Composer" );
00447 int showHeaders = composer.readNumEntry( "headers", HDR_STANDARD );
00448 showHeaders |= HDR_IDENTITY;
00449 composer.writeEntry( "headers", showHeaders );
00450 }
00451
00452 if( mOldNumberOfIdentities > 1 && mIdentityList->childCount() < 2 ) {
00453
00454 KConfigGroup composer( KMKernel::config(), "Composer" );
00455 int showHeaders = composer.readNumEntry( "headers", HDR_STANDARD );
00456 showHeaders &= ~HDR_IDENTITY;
00457 composer.writeEntry( "headers", showHeaders );
00458 }
00459 }
00460
00461 void IdentityPage::dismiss() {
00462 assert( !mIdentityDialog );
00463 kmkernel->identityManager()->rollback();
00464 }
00465
00466 void IdentityPage::slotNewIdentity()
00467 {
00468 assert( !mIdentityDialog );
00469
00470 IdentityManager * im = kmkernel->identityManager();
00471 NewIdentityDialog dialog( im->shadowIdentities(), this, "new", true );
00472
00473 if( dialog.exec() == QDialog::Accepted ) {
00474 QString identityName = dialog.identityName().stripWhiteSpace();
00475 assert( !identityName.isEmpty() );
00476
00477
00478
00479
00480 switch ( dialog.duplicateMode() ) {
00481 case NewIdentityDialog::ExistingEntry:
00482 {
00483 KMIdentity & dupThis = im->identityForName( dialog.duplicateIdentity() );
00484 im->newFromExisting( dupThis, identityName );
00485 break;
00486 }
00487 case NewIdentityDialog::ControlCenter:
00488 im->newFromControlCenter( identityName );
00489 break;
00490 case NewIdentityDialog::Empty:
00491 im->newFromScratch( identityName );
00492 default: ;
00493 }
00494
00495
00496
00497
00498 KMIdentity & newIdent = im->identityForName( identityName );
00499 QListViewItem * item = mIdentityList->selectedItem();
00500 if ( item )
00501 item = item->itemAbove();
00502 mIdentityList->setSelected( new IdentityListViewItem( mIdentityList,
00503 item,
00504 newIdent ), true );
00505 slotModifyIdentity();
00506 }
00507 }
00508
00509 void IdentityPage::slotModifyIdentity() {
00510 assert( !mIdentityDialog );
00511
00512 IdentityListViewItem * item =
00513 dynamic_cast<IdentityListViewItem*>( mIdentityList->selectedItem() );
00514 if ( !item ) return;
00515
00516 mIdentityDialog = new IdentityDialog( this );
00517 mIdentityDialog->setIdentity( item->identity() );
00518
00519
00520 if ( mIdentityDialog->exec() == QDialog::Accepted ) {
00521 mIdentityDialog->updateIdentity( item->identity() );
00522 item->redisplay();
00523 }
00524
00525 delete mIdentityDialog;
00526 mIdentityDialog = 0;
00527 }
00528
00529 void IdentityPage::slotRemoveIdentity()
00530 {
00531 assert( !mIdentityDialog );
00532
00533 IdentityManager * im = kmkernel->identityManager();
00534 kdFatal( im->shadowIdentities().count() < 2 )
00535 << "Attempted to remove the last identity!" << endl;
00536
00537 IdentityListViewItem * item =
00538 dynamic_cast<IdentityListViewItem*>( mIdentityList->selectedItem() );
00539 if ( !item ) return;
00540
00541 QString msg = i18n("<qt>Do you really want to remove the identity named "
00542 "<b>%1</b>?</qt>").arg( item->identity().identityName() );
00543 if( KMessageBox::warningYesNo( this, msg ) == KMessageBox::Yes )
00544 if ( im->removeIdentity( item->identity().identityName() ) ) {
00545 delete item;
00546 mIdentityList->setSelected( mIdentityList->currentItem(), true );
00547 refreshList();
00548 }
00549 }
00550
00551 void IdentityPage::slotRenameIdentity() {
00552 assert( !mIdentityDialog );
00553
00554 QListViewItem * item = mIdentityList->selectedItem();
00555 if ( !item ) return;
00556
00557 mIdentityList->rename( item, 0 );
00558 }
00559
00560 void IdentityPage::slotRenameIdentity( QListViewItem * i,
00561 const QString & s, int col ) {
00562 assert( col == 0 );
00563 Q_UNUSED( col );
00564
00565 IdentityListViewItem * item = dynamic_cast<IdentityListViewItem*>( i );
00566 if ( !item ) return;
00567
00568 QString newName = s.stripWhiteSpace();
00569 if ( !newName.isEmpty() &&
00570 !kmkernel->identityManager()->shadowIdentities().contains( newName ) ) {
00571 KMIdentity & ident = item->identity();
00572 ident.setIdentityName( newName );
00573 }
00574 item->redisplay();
00575 }
00576
00577 void IdentityPage::slotContextMenu( KListView *, QListViewItem * i,
00578 const QPoint & pos ) {
00579 IdentityListViewItem * item = dynamic_cast<IdentityListViewItem*>( i );
00580
00581 QPopupMenu * menu = new QPopupMenu( this );
00582 menu->insertItem( i18n("New..."), this, SLOT(slotNewIdentity()) );
00583 if ( item ) {
00584 menu->insertItem( i18n("Modify..."), this, SLOT(slotModifyIdentity()) );
00585 if ( mIdentityList->childCount() > 1 )
00586 menu->insertItem( i18n("Remove"), this, SLOT(slotRemoveIdentity()) );
00587 if ( !item->identity().isDefault() )
00588 menu->insertItem( i18n("Set as Default"), this, SLOT(slotSetAsDefault()) );
00589 }
00590 menu->exec( pos );
00591 delete menu;
00592 }
00593
00594
00595 void IdentityPage::slotSetAsDefault() {
00596 assert( !mIdentityDialog );
00597
00598 IdentityListViewItem * item =
00599 dynamic_cast<IdentityListViewItem*>( mIdentityList->selectedItem() );
00600 if ( !item ) return;
00601
00602 IdentityManager * im = kmkernel->identityManager();
00603 im->setAsDefault( item->identity().identityName() );
00604 refreshList();
00605 }
00606
00607 void IdentityPage::refreshList() {
00608 for ( QListViewItemIterator it( mIdentityList ) ; it.current() ; ++it ) {
00609 IdentityListViewItem * item =
00610 dynamic_cast<IdentityListViewItem*>(it.current());
00611 if ( item )
00612 item->redisplay();
00613 }
00614 }
00615
00616 void IdentityPage::slotIdentitySelectionChanged( QListViewItem * i ) {
00617 kdDebug(5006) << "IdentityPage::slotIdentitySelectionChanged( " << i << " )" << endl;
00618
00619 IdentityListViewItem * item = dynamic_cast<IdentityListViewItem*>( i );
00620
00621 if ( !item ) return;
00622
00623 mRemoveButton->setEnabled( item && mIdentityList->childCount() > 1 );
00624 mModifyButton->setEnabled( item );
00625 mRenameButton->setEnabled( item );
00626 mSetAsDefaultButton->setEnabled( item && !item->identity().isDefault() );
00627 }
00628
00629 void IdentityPage::slotUpdateTransportCombo( const QStringList & sl )
00630 {
00631 if ( mIdentityDialog ) mIdentityDialog->slotUpdateTransportCombo( sl );
00632 }
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642 QString NetworkPage::iconLabel() {
00643 return i18n("Network");
00644 }
00645
00646 QString NetworkPage::title() {
00647 return i18n("Setup for Sending and Receiving Messages");
00648 }
00649
00650 const char * NetworkPage::iconName() {
00651 return "network";
00652 }
00653
00654 QString NetworkPage::helpAnchor() const {
00655 return QString::fromLatin1("configure-network");
00656 }
00657
00658 NetworkPage::NetworkPage( QWidget * parent, const char * name )
00659 : TabbedConfigurationPage( parent, name )
00660 {
00661
00662
00663
00664 mSendingTab = new SendingTab();
00665 addTab( mSendingTab, mSendingTab->title() );
00666 connect( mSendingTab, SIGNAL(transportListChanged(const QStringList&)),
00667 this, SIGNAL(transportListChanged(const QStringList&)) );
00668
00669
00670
00671
00672 mReceivingTab = new ReceivingTab();
00673 addTab( mReceivingTab, mReceivingTab->title() );
00674
00675 connect( mReceivingTab, SIGNAL(accountListChanged(const QStringList &)),
00676 this, SIGNAL(accountListChanged(const QStringList &)) );
00677 }
00678
00679 QString NetworkPage::SendingTab::title() {
00680 return i18n("&Sending");
00681 }
00682
00683 QString NetworkPage::SendingTab::helpAnchor() const {
00684 return QString::fromLatin1("configure-network-sending");
00685 }
00686
00687 NetworkPageSendingTab::NetworkPageSendingTab( QWidget * parent, const char * name )
00688 : ConfigurationPage( parent, name )
00689 {
00690 mTransportInfoList.setAutoDelete( true );
00691
00692 QVBoxLayout *vlay;
00693 QVBoxLayout *btn_vlay;
00694 QHBoxLayout *hlay;
00695 QGridLayout *glay;
00696 QPushButton *button;
00697 QGroupBox *group;
00698
00699 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
00700
00701 vlay->addWidget( new QLabel( i18n("Outgoing accounts (add at least one):"), this ) );
00702
00703
00704 hlay = new QHBoxLayout();
00705 vlay->addLayout( hlay, 10 );
00706
00707
00708
00709 mTransportList = new ListView( this, "transportList", 5 );
00710 mTransportList->addColumn( i18n("Name") );
00711 mTransportList->addColumn( i18n("Type") );
00712 mTransportList->setAllColumnsShowFocus( true );
00713 mTransportList->setFrameStyle( QFrame::WinPanel + QFrame::Sunken );
00714 mTransportList->setSorting( -1 );
00715 connect( mTransportList, SIGNAL(selectionChanged()),
00716 this, SLOT(slotTransportSelected()) );
00717 connect( mTransportList, SIGNAL(doubleClicked( QListViewItem *)),
00718 this, SLOT(slotModifySelectedTransport()) );
00719 hlay->addWidget( mTransportList, 1 );
00720
00721
00722 btn_vlay = new QVBoxLayout( hlay );
00723
00724
00725 button = new QPushButton( i18n("A&dd..."), this );
00726 button->setAutoDefault( false );
00727 connect( button, SIGNAL(clicked()),
00728 this, SLOT(slotAddTransport()) );
00729 btn_vlay->addWidget( button );
00730
00731
00732 mModifyTransportButton = new QPushButton( i18n("&Modify..."), this );
00733 mModifyTransportButton->setAutoDefault( false );
00734 mModifyTransportButton->setEnabled( false );
00735 connect( mModifyTransportButton, SIGNAL(clicked()),
00736 this, SLOT(slotModifySelectedTransport()) );
00737 btn_vlay->addWidget( mModifyTransportButton );
00738
00739
00740 mRemoveTransportButton = new QPushButton( i18n("R&emove"), this );
00741 mRemoveTransportButton->setAutoDefault( false );
00742 mRemoveTransportButton->setEnabled( false );
00743 connect( mRemoveTransportButton, SIGNAL(clicked()),
00744 this, SLOT(slotRemoveSelectedTransport()) );
00745 btn_vlay->addWidget( mRemoveTransportButton );
00746
00747
00748
00749 mTransportUpButton = new QPushButton( QString::null, this );
00750 mTransportUpButton->setPixmap( BarIcon( "up", KIcon::SizeSmall ) );
00751
00752 mTransportUpButton->setAutoDefault( false );
00753 mTransportUpButton->setEnabled( false );
00754 connect( mTransportUpButton, SIGNAL(clicked()),
00755 this, SLOT(slotTransportUp()) );
00756 btn_vlay->addWidget( mTransportUpButton );
00757
00758
00759
00760 mTransportDownButton = new QPushButton( QString::null, this );
00761 mTransportDownButton->setPixmap( BarIcon( "down", KIcon::SizeSmall ) );
00762
00763 mTransportDownButton->setAutoDefault( false );
00764 mTransportDownButton->setEnabled( false );
00765 connect( mTransportDownButton, SIGNAL(clicked()),
00766 this, SLOT(slotTransportDown()) );
00767 btn_vlay->addWidget( mTransportDownButton );
00768 btn_vlay->addStretch( 1 );
00769
00770
00771 group = new QGroupBox( 0, Qt::Vertical,
00772 i18n("Common Options"), this );
00773 vlay->addWidget(group);
00774
00775
00776 glay = new QGridLayout( group->layout(), 5, 3, KDialog::spacingHint() );
00777 glay->setColStretch( 2, 10 );
00778
00779
00780 mConfirmSendCheck = new QCheckBox( i18n("Confirm &before send"), group );
00781 glay->addMultiCellWidget( mConfirmSendCheck, 0, 0, 0, 1 );
00782
00783
00784 mSendOutboxCheck =
00785 new QCheckBox(i18n("Send messages in outbox &folder on check"), group );
00786 glay->addMultiCellWidget( mSendOutboxCheck, 1, 1, 0, 1 );
00787
00788
00789 mSendMethodCombo = new QComboBox( false, group );
00790 mSendMethodCombo->insertStringList( QStringList()
00791 << i18n("Send Now")
00792 << i18n("Send Later") );
00793 glay->addWidget( mSendMethodCombo, 2, 1 );
00794
00795
00796
00797 mMessagePropertyCombo = new QComboBox( false, group );
00798 mMessagePropertyCombo->insertStringList( QStringList()
00799 << i18n("Allow 8-bit")
00800 << i18n("MIME Compliant (Quoted Printable)") );
00801 glay->addWidget( mMessagePropertyCombo, 3, 1 );
00802
00803
00804 mDefaultDomainEdit = new KLineEdit( group );
00805 glay->addMultiCellWidget( mDefaultDomainEdit, 4, 4, 1, 2 );
00806
00807
00808 glay->addWidget( new QLabel( mSendMethodCombo,
00809 i18n("Defa&ult send method:"), group ), 2, 0 );
00810 glay->addWidget( new QLabel( mMessagePropertyCombo,
00811 i18n("Message &property:"), group ), 3, 0 );
00812 QLabel *l = new QLabel( mDefaultDomainEdit,
00813 i18n("Defaul&t domain:"), group );
00814 glay->addWidget( l, 4, 0 );
00815
00816
00817 QString msg = i18n( "<qt><p>The default domain is used to complete email "
00818 "addresses that only consist of the user's name."
00819 "</p></qt>" );
00820 QWhatsThis::add( l, msg );
00821 QWhatsThis::add( mDefaultDomainEdit, msg );
00822 }
00823
00824
00825 void NetworkPage::SendingTab::slotTransportSelected()
00826 {
00827 QListViewItem *cur = mTransportList->currentItem();
00828 mModifyTransportButton->setEnabled( cur );
00829 mRemoveTransportButton->setEnabled( cur );
00830 mTransportDownButton->setEnabled( cur && cur->itemBelow() );
00831 mTransportUpButton->setEnabled( cur && cur->itemAbove() );
00832 }
00833
00834
00835 static inline QString uniqueName( const QStringList & list,
00836 const QString & name )
00837 {
00838 int suffix = 1;
00839 QString result = name;
00840 while ( list.find( result ) != list.end() ) {
00841 result = i18n("%1: name; %2: number appended to it to make it unique "
00842 "among a list of names", "%1 %2")
00843 .arg( name ).arg( suffix );
00844 suffix++;
00845 }
00846 return result;
00847 }
00848
00849 void NetworkPage::SendingTab::slotAddTransport()
00850 {
00851 int transportType;
00852
00853 {
00854 KMTransportSelDlg selDialog( this );
00855 if ( selDialog.exec() != QDialog::Accepted ) return;
00856 transportType = selDialog.selected();
00857 }
00858
00859 KMTransportInfo *transportInfo = new KMTransportInfo();
00860 switch ( transportType ) {
00861 case 0:
00862 transportInfo->type = QString::fromLatin1("smtp");
00863 break;
00864 case 1:
00865 transportInfo->type = QString::fromLatin1("sendmail");
00866 transportInfo->name = i18n("Sendmail");
00867 transportInfo->host = _PATH_SENDMAIL;
00868 break;
00869 default:
00870 assert( 0 );
00871 }
00872
00873 KMTransportDialog dialog( i18n("Add Transport"), transportInfo, this );
00874
00875
00876
00877 QStringList transportNames;
00878 QPtrListIterator<KMTransportInfo> it( mTransportInfoList );
00879 for ( it.toFirst() ; it.current() ; ++it )
00880 transportNames << (*it)->name;
00881
00882 if( dialog.exec() != QDialog::Accepted ) {
00883 delete transportInfo;
00884 return;
00885 }
00886
00887
00888
00889 transportInfo->name = uniqueName( transportNames, transportInfo->name );
00890
00891 transportNames << transportInfo->name;
00892 mTransportInfoList.append( transportInfo );
00893
00894
00895
00896 QListViewItem *lastItem = mTransportList->firstChild();
00897 QString typeDisplayName;
00898 if ( lastItem )
00899 while ( lastItem->nextSibling() )
00900 lastItem = lastItem->nextSibling();
00901 if ( lastItem )
00902 typeDisplayName = transportInfo->type;
00903 else
00904 typeDisplayName = i18n("%1: type of transport. Result used in "
00905 "Configure->Network->Sending listview, \"type\" "
00906 "column, first row, to indicate that this is the "
00907 "default transport", "%1 (Default)")
00908 .arg( transportInfo->type );
00909 (void) new QListViewItem( mTransportList, lastItem, transportInfo->name,
00910 typeDisplayName );
00911
00912
00913 emit transportListChanged( transportNames );
00914 }
00915
00916 void NetworkPage::SendingTab::slotModifySelectedTransport()
00917 {
00918 QListViewItem *item = mTransportList->currentItem();
00919 if ( !item ) return;
00920
00921 QPtrListIterator<KMTransportInfo> it( mTransportInfoList );
00922 for ( it.toFirst() ; it.current() ; ++it )
00923 if ( (*it)->name == item->text(0) ) break;
00924 if ( !it.current() ) return;
00925
00926 KMTransportDialog dialog( i18n("Modify Transport"), (*it), this );
00927
00928 if ( dialog.exec() != QDialog::Accepted ) return;
00929
00930
00931
00932 QStringList transportNames;
00933 QPtrListIterator<KMTransportInfo> jt( mTransportInfoList );
00934 int entryLocation = -1;
00935 for ( jt.toFirst() ; jt.current() ; ++jt )
00936 if ( jt != it )
00937 transportNames << (*jt)->name;
00938 else
00939 entryLocation = transportNames.count();
00940 assert( entryLocation >= 0 );
00941
00942
00943 (*it)->name = uniqueName( transportNames, (*it)->name );
00944
00945 item->setText( 0, (*it)->name );
00946
00947
00948 transportNames.insert( transportNames.at( entryLocation ), (*it)->name );
00949 emit transportListChanged( transportNames );
00950 }
00951
00952
00953 void NetworkPage::SendingTab::slotRemoveSelectedTransport()
00954 {
00955 QListViewItem *item = mTransportList->currentItem();
00956 if ( !item ) return;
00957
00958 QPtrListIterator<KMTransportInfo> it( mTransportInfoList );
00959 for ( it.toFirst() ; it.current() ; ++it )
00960 if ( (*it)->name == item->text(0) ) break;
00961 if ( !it.current() ) return;
00962
00963 QListViewItem *newCurrent = item->itemBelow();
00964 if ( !newCurrent ) newCurrent = item->itemAbove();
00965
00966 if ( newCurrent ) {
00967 mTransportList->setCurrentItem( newCurrent );
00968 mTransportList->setSelected( newCurrent, true );
00969 }
00970
00971 delete item;
00972 mTransportInfoList.remove( it );
00973
00974 QStringList transportNames;
00975 for ( it.toFirst() ; it.current() ; ++it )
00976 transportNames << (*it)->name;
00977 emit transportListChanged( transportNames );
00978 }
00979
00980
00981 void NetworkPage::SendingTab::slotTransportUp()
00982 {
00983 QListViewItem *item = mTransportList->selectedItem();
00984 if ( !item ) return;
00985 QListViewItem *above = item->itemAbove();
00986 if ( !above ) return;
00987
00988
00989
00990 KMTransportInfo *ti, *ti2 = 0;
00991 int i = 0;
00992 for (ti = mTransportInfoList.first(); ti;
00993 ti2 = ti, ti = mTransportInfoList.next(), i++)
00994 if (ti->name == item->text(0)) break;
00995 if (!ti || !ti2) return;
00996 ti = mTransportInfoList.take(i);
00997 mTransportInfoList.insert(i-1, ti);
00998
00999
01000 item->setText(0, ti2->name);
01001 item->setText(1, ti2->type);
01002 above->setText(0, ti->name);
01003 if ( above->itemAbove() )
01004
01005 above->setText( 1, ti->type );
01006 else
01007
01008 above->setText( 1, i18n("%1: type of transport. Result used in "
01009 "Configure->Network->Sending listview, \"type\" "
01010 "column, first row, to indicate that this is the "
01011 "default transport", "%1 (Default)")
01012 .arg( ti->type ) );
01013
01014 mTransportList->setCurrentItem( above );
01015 mTransportList->setSelected( above, true );
01016 }
01017
01018
01019 void NetworkPage::SendingTab::slotTransportDown()
01020 {
01021 QListViewItem * item = mTransportList->selectedItem();
01022 if ( !item ) return;
01023 QListViewItem * below = item->itemBelow();
01024 if ( !below ) return;
01025
01026 KMTransportInfo *ti, *ti2 = 0;
01027 int i = 0;
01028 for (ti = mTransportInfoList.first(); ti;
01029 ti = mTransportInfoList.next(), i++)
01030 if (ti->name == item->text(0)) break;
01031 ti2 = mTransportInfoList.next();
01032 if (!ti || !ti2) return;
01033 ti = mTransportInfoList.take(i);
01034 mTransportInfoList.insert(i+1, ti);
01035
01036 item->setText(0, ti2->name);
01037 below->setText(0, ti->name);
01038 below->setText(1, ti->type);
01039 if ( item->itemAbove() )
01040 item->setText( 1, ti2->type );
01041 else
01042 item->setText( 1, i18n("%1: type of transport. Result used in "
01043 "Configure->Network->Sending listview, \"type\" "
01044 "column, first row, to indicate that this is the "
01045 "default transport", "%1 (Default)")
01046 .arg( ti2->type ) );
01047
01048
01049 mTransportList->setCurrentItem(below);
01050 mTransportList->setSelected(below, TRUE);
01051 }
01052
01053 void NetworkPage::SendingTab::setup() {
01054 KConfigGroup general( KMKernel::config(), "General");
01055 KConfigGroup composer( KMKernel::config(), "Composer");
01056
01057 int numTransports = general.readNumEntry("transports", 0);
01058
01059 QListViewItem *top = 0;
01060 mTransportInfoList.clear();
01061 mTransportList->clear();
01062 QStringList transportNames;
01063 for ( int i = 1 ; i <= numTransports ; i++ ) {
01064 KMTransportInfo *ti = new KMTransportInfo();
01065 ti->readConfig(i);
01066 mTransportInfoList.append( ti );
01067 transportNames << ti->name;
01068 top = new QListViewItem( mTransportList, top, ti->name, ti->type );
01069 }
01070 emit transportListChanged( transportNames );
01071
01072 QListViewItem *listItem = mTransportList->firstChild();
01073 if ( listItem ) {
01074 listItem->setText( 1, i18n("%1: type of transport. Result used in "
01075 "Configure->Network->Sending listview, "
01076 "\"type\" column, first row, to indicate "
01077 "that this is the default transport",
01078 "%1 (Default)").arg( listItem->text(1) ) );
01079 mTransportList->setCurrentItem( listItem );
01080 mTransportList->setSelected( listItem, true );
01081 }
01082
01083 mSendMethodCombo->setCurrentItem(
01084 kmkernel->msgSender()->sendImmediate() ? 0 : 1 );
01085 mMessagePropertyCombo->setCurrentItem(
01086 kmkernel->msgSender()->sendQuotedPrintable() ? 1 : 0 );
01087 mSendOutboxCheck->setChecked( general.readBoolEntry( "sendOnCheck",
01088 false ) );
01089
01090 mConfirmSendCheck->setChecked( composer.readBoolEntry( "confirm-before-send",
01091 false ) );
01092 QString str = general.readEntry( "Default domain" );
01093 if( str.isEmpty() )
01094 {
01095
01096
01097
01098 char buffer[256];
01099 if ( !gethostname( buffer, 255 ) )
01100
01101 buffer[255] = 0;
01102 else
01103 buffer[0] = 0;
01104 str = QString::fromLatin1( *buffer ? buffer : "localhost" );
01105 }
01106 mDefaultDomainEdit->setText( str );
01107 }
01108
01109
01110 void NetworkPage::SendingTab::apply() {
01111 KConfigGroup general( KMKernel::config(), "General" );
01112 KConfigGroup composer( KMKernel::config(), "Composer" );
01113
01114
01115 general.writeEntry( "transports", mTransportInfoList.count() );
01116 QPtrListIterator<KMTransportInfo> it( mTransportInfoList );
01117 for ( int i = 1 ; it.current() ; ++it, ++i )
01118 (*it)->writeConfig(i);
01119
01120
01121 general.writeEntry( "sendOnCheck", mSendOutboxCheck->isChecked() );
01122 kmkernel->msgSender()->setSendImmediate(
01123 mSendMethodCombo->currentItem() == 0 );
01124 kmkernel->msgSender()->setSendQuotedPrintable(
01125 mMessagePropertyCombo->currentItem() == 1 );
01126 kmkernel->msgSender()->writeConfig( false );
01127 composer.writeEntry("confirm-before-send", mConfirmSendCheck->isChecked() );
01128 general.writeEntry( "Default domain", mDefaultDomainEdit->text() );
01129 }
01130
01131
01132
01133 QString NetworkPage::ReceivingTab::title() {
01134 return i18n("&Receiving");
01135 }
01136
01137 QString NetworkPage::ReceivingTab::helpAnchor() const {
01138 return QString::fromLatin1("configure-network-receiving");
01139 }
01140
01141 NetworkPageReceivingTab::NetworkPageReceivingTab( QWidget * parent, const char * name )
01142 : ConfigurationPage ( parent, name )
01143 {
01144
01145 QVBoxLayout *vlay;
01146 QVBoxLayout *btn_vlay;
01147 QHBoxLayout *hlay;
01148 QPushButton *button;
01149 QGroupBox *group;
01150
01151 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
01152
01153
01154 vlay->addWidget( new QLabel( i18n("Incoming accounts (add at least one):"), this ) );
01155
01156
01157 hlay = new QHBoxLayout();
01158 vlay->addLayout( hlay, 10 );
01159
01160
01161 mAccountList = new ListView( this, "accountList", 5 );
01162 mAccountList->addColumn( i18n("Name") );
01163 mAccountList->addColumn( i18n("Type") );
01164 mAccountList->addColumn( i18n("Folder") );
01165 mAccountList->setAllColumnsShowFocus( true );
01166 mAccountList->setFrameStyle( QFrame::WinPanel + QFrame::Sunken );
01167 mAccountList->setSorting( -1 );
01168 connect( mAccountList, SIGNAL(selectionChanged()),
01169 this, SLOT(slotAccountSelected()) );
01170 connect( mAccountList, SIGNAL(doubleClicked( QListViewItem *)),
01171 this, SLOT(slotModifySelectedAccount()) );
01172 hlay->addWidget( mAccountList, 1 );
01173
01174
01175 btn_vlay = new QVBoxLayout( hlay );
01176
01177
01178 button = new QPushButton( i18n("A&dd..."), this );
01179 button->setAutoDefault( false );
01180 connect( button, SIGNAL(clicked()),
01181 this, SLOT(slotAddAccount()) );
01182 btn_vlay->addWidget( button );
01183
01184
01185 mModifyAccountButton = new QPushButton( i18n("&Modify..."), this );
01186 mModifyAccountButton->setAutoDefault( false );
01187 mModifyAccountButton->setEnabled( false );
01188 connect( mModifyAccountButton, SIGNAL(clicked()),
01189 this, SLOT(slotModifySelectedAccount()) );
01190 btn_vlay->addWidget( mModifyAccountButton );
01191
01192
01193 mRemoveAccountButton = new QPushButton( i18n("R&emove"), this );
01194 mRemoveAccountButton->setAutoDefault( false );
01195 mRemoveAccountButton->setEnabled( false );
01196 connect( mRemoveAccountButton, SIGNAL(clicked()),
01197 this, SLOT(slotRemoveSelectedAccount()) );
01198 btn_vlay->addWidget( mRemoveAccountButton );
01199 btn_vlay->addStretch( 1 );
01200
01201 mCheckmailStartupCheck = new QCheckBox( i18n("Chec&k mail on startup"), this );
01202 vlay->addWidget( mCheckmailStartupCheck );
01203
01204
01205 group = new QVGroupBox( i18n("New Mail Notification"), this );
01206 vlay->addWidget( group );
01207 group->layout()->setSpacing( KDialog::spacingHint() );
01208
01209
01210 mBeepNewMailCheck = new QCheckBox(i18n("&Beep"), group );
01211 mBeepNewMailCheck->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding,
01212 QSizePolicy::Fixed ) );
01213
01214 mSystrayCheck = new QCheckBox( i18n("System &tray notification"), group );
01215
01216
01217 QButtonGroup *bgroup = new QButtonGroup(i18n("System Tray Modes"), group);
01218 bgroup->setColumnLayout(0, Qt::Horizontal);
01219 bgroup->layout()->setSpacing( 0 );
01220 bgroup->layout()->setMargin( 0 );
01221 QGridLayout *bgroupLayout = new QGridLayout( bgroup->layout() );
01222 bgroupLayout->setAlignment( Qt::AlignTop );
01223 bgroupLayout->setSpacing( 6 );
01224 bgroupLayout->setMargin( 11 );
01225
01226 mBlinkingSystray = new QRadioButton( i18n("Alwa&ys show system tray"), bgroup);
01227 bgroupLayout->addWidget(mBlinkingSystray, 0, 0);
01228
01229 mSystrayOnNew = new QRadioButton( i18n("Sho&w system tray on new mail"), bgroup);
01230 bgroupLayout->addWidget(mSystrayOnNew, 0, 1);
01231
01232 bgroup->setEnabled( false );
01233 connect( mSystrayCheck, SIGNAL(toggled(bool)),
01234 bgroup, SLOT(setEnabled(bool)) );
01235
01236
01237 mOtherNewMailActionsButton = new QPushButton( i18n("Other Actio&ns"), group );
01238 mOtherNewMailActionsButton->setSizePolicy( QSizePolicy( QSizePolicy::Fixed,
01239 QSizePolicy::Fixed ) );
01240 connect( mOtherNewMailActionsButton, SIGNAL(clicked()),
01241 this, SLOT(slotEditNotifications()) );
01242 }
01243
01244
01245 void NetworkPage::ReceivingTab::slotAccountSelected()
01246 {
01247 QListViewItem * item = mAccountList->selectedItem();
01248 mModifyAccountButton->setEnabled( item );
01249 mRemoveAccountButton->setEnabled( item );
01250 }
01251
01252 QStringList NetworkPage::ReceivingTab::occupiedNames()
01253 {
01254 QStringList accountNames = kmkernel->acctMgr()->getAccounts();
01255
01256 QValueList<ModifiedAccountsType*>::Iterator k;
01257 for (k = mModifiedAccounts.begin(); k != mModifiedAccounts.end(); ++k )
01258 if ((*k)->oldAccount)
01259 accountNames.remove( (*k)->oldAccount->name() );
01260
01261 QValueList< QGuardedPtr<KMAccount> >::Iterator l;
01262 for (l = mAccountsToDelete.begin(); l != mAccountsToDelete.end(); ++l )
01263 if (*l)
01264 accountNames.remove( (*l)->name() );
01265
01266 QValueList< QGuardedPtr<KMAccount> >::Iterator it;
01267 for (it = mNewAccounts.begin(); it != mNewAccounts.end(); ++it )
01268 if (*it)
01269 accountNames += (*it)->name();
01270
01271 QValueList<ModifiedAccountsType*>::Iterator j;
01272 for (j = mModifiedAccounts.begin(); j != mModifiedAccounts.end(); ++j )
01273 accountNames += (*j)->newAccount->name();
01274
01275 return accountNames;
01276 }
01277
01278 void NetworkPage::ReceivingTab::slotAddAccount() {
01279 KMAcctSelDlg accountSelectorDialog( this );
01280 if( accountSelectorDialog.exec() != QDialog::Accepted ) return;
01281
01282 const char *accountType = 0;
01283 switch ( accountSelectorDialog.selected() ) {
01284 case 0: accountType = "local"; break;
01285 case 1: accountType = "pop"; break;
01286 case 2: accountType = "imap"; break;
01287 case 3: accountType = "cachedimap"; break;
01288 case 4: accountType = "maildir"; break;
01289
01290 default:
01291
01292
01293 KMessageBox::sorry( this, i18n("Unknown account type selected") );
01294 return;
01295 }
01296
01297 KMAccount *account
01298 = kmkernel->acctMgr()->create( QString::fromLatin1( accountType ),
01299 i18n("Unnamed") );
01300 if ( !account ) {
01301
01302
01303 KMessageBox::sorry( this, i18n("Unable to create account") );
01304 return;
01305 }
01306
01307 account->init();
01308
01309 AccountDialog dialog( i18n("Add account"), account, this );
01310
01311 QStringList accountNames = occupiedNames();
01312
01313 if( dialog.exec() != QDialog::Accepted ) {
01314 delete account;
01315 return;
01316 }
01317
01318 account->setName( uniqueName( accountNames, account->name() ) );
01319
01320 QListViewItem *after = mAccountList->firstChild();
01321 while ( after && after->nextSibling() )
01322 after = after->nextSibling();
01323
01324 QListViewItem *listItem =
01325 new QListViewItem( mAccountList, after, account->name(), account->type() );
01326 if( account->folder() )
01327 listItem->setText( 2, account->folder()->label() );
01328
01329 mNewAccounts.append( account );
01330 }
01331
01332
01333
01334 void NetworkPage::ReceivingTab::slotModifySelectedAccount()
01335 {
01336 QListViewItem *listItem = mAccountList->selectedItem();
01337 if( !listItem ) return;
01338
01339 KMAccount *account = 0;
01340 QValueList<ModifiedAccountsType*>::Iterator j;
01341 for (j = mModifiedAccounts.begin(); j != mModifiedAccounts.end(); ++j )
01342 if ( (*j)->newAccount->name() == listItem->text(0) ) {
01343 account = (*j)->newAccount;
01344 break;
01345 }
01346
01347 if ( !account ) {
01348 QValueList< QGuardedPtr<KMAccount> >::Iterator it;
01349 for ( it = mNewAccounts.begin() ; it != mNewAccounts.end() ; ++it )
01350 if ( (*it)->name() == listItem->text(0) ) {
01351 account = *it;
01352 break;
01353 }
01354
01355 if ( !account ) {
01356 account = kmkernel->acctMgr()->find( listItem->text(0) );
01357 if( !account ) {
01358
01359 KMessageBox::sorry( this, i18n("Unable to locate account") );
01360 return;
01361 }
01362
01363 ModifiedAccountsType *mod = new ModifiedAccountsType;
01364 mod->oldAccount = account;
01365 mod->newAccount = kmkernel->acctMgr()->create( account->type(),
01366 account->name() );
01367 mod->newAccount->pseudoAssign( account );
01368 mModifiedAccounts.append( mod );
01369 account = mod->newAccount;
01370 }
01371
01372 if( !account ) {
01373
01374 KMessageBox::sorry( this, i18n("Unable to locate account") );
01375 return;
01376 }
01377 }
01378
01379 QStringList accountNames = occupiedNames();
01380 accountNames.remove( account->name() );
01381
01382 AccountDialog dialog( i18n("Modify Account"), account, this );
01383
01384 if( dialog.exec() != QDialog::Accepted ) return;
01385
01386 account->setName( uniqueName( accountNames, account->name() ) );
01387
01388 listItem->setText( 0, account->name() );
01389 listItem->setText( 1, account->type() );
01390 if( account->folder() )
01391 listItem->setText( 2, account->folder()->label() );
01392 }
01393
01394
01395
01396 void NetworkPage::ReceivingTab::slotRemoveSelectedAccount() {
01397 QListViewItem *listItem = mAccountList->selectedItem();
01398 if( !listItem ) return;
01399
01400 KMAccount *acct = 0;
01401 QValueList<ModifiedAccountsType*>::Iterator j;
01402 for ( j = mModifiedAccounts.begin() ; j != mModifiedAccounts.end() ; ++j )
01403 if ( (*j)->newAccount->name() == listItem->text(0) ) {
01404 acct = (*j)->oldAccount;
01405 mAccountsToDelete.append( acct );
01406 mModifiedAccounts.remove( j );
01407 break;
01408 }
01409 if ( !acct ) {
01410 QValueList< QGuardedPtr<KMAccount> >::Iterator it;
01411 for ( it = mNewAccounts.begin() ; it != mNewAccounts.end() ; ++it )
01412 if ( (*it)->name() == listItem->text(0) ) {
01413 acct = *it;
01414 mNewAccounts.remove( it );
01415 break;
01416 }
01417 }
01418 if ( !acct ) {
01419 acct = kmkernel->acctMgr()->find( listItem->text(0) );
01420 if ( acct )
01421 mAccountsToDelete.append( acct );
01422 }
01423 if ( !acct ) {
01424
01425 KMessageBox::sorry( this, i18n("<qt>Unable to locate account <b>%1</b>.</qt>")
01426 .arg(listItem->text(0)) );
01427 return;
01428 }
01429
01430 QListViewItem * item = listItem->itemBelow();
01431 if ( !item ) item = listItem->itemAbove();
01432 delete listItem;
01433
01434 if ( item )
01435 mAccountList->setSelected( item, true );
01436 }
01437
01438 void NetworkPage::ReceivingTab::slotEditNotifications()
01439 {
01440 if(kmkernel->xmlGuiInstance())
01441 KNotifyDialog::configure(this, 0, kmkernel->xmlGuiInstance()->aboutData());
01442 else
01443 KNotifyDialog::configure(this);
01444 }
01445
01446 void NetworkPage::ReceivingTab::setup() {
01447 KConfigGroup general( KMKernel::config(), "General" );
01448
01449 mAccountList->clear();
01450 QListViewItem *top = 0;
01451 for( KMAccount *a = kmkernel->acctMgr()->first(); a!=0;
01452 a = kmkernel->acctMgr()->next() ) {
01453 QListViewItem *listItem =
01454 new QListViewItem( mAccountList, top, a->name(), a->type() );
01455 if( a->folder() )
01456 listItem->setText( 2, a->folder()->label() );
01457 top = listItem;
01458 }
01459
01460 QListViewItem *listItem = mAccountList->firstChild();
01461 if ( listItem ) {
01462 mAccountList->setCurrentItem( listItem );
01463 mAccountList->setSelected( listItem, true );
01464 }
01465
01466 mBeepNewMailCheck->setChecked( general.readBoolEntry("beep-on-mail", false ) );
01467
01468 mSystrayCheck->setChecked( general.readBoolEntry("systray-on-mail", false) );
01469 mBlinkingSystray->setChecked( !general.readBoolEntry("systray-on-new", true) );
01470 mSystrayOnNew->setChecked( general.readBoolEntry("systray-on-new", true) );
01471 mCheckmailStartupCheck->setChecked( general.readBoolEntry("checkmail-startup", false) );
01472 }
01473
01474 void NetworkPage::ReceivingTab::apply() {
01475
01476 QValueList< QGuardedPtr<KMAccount> > newCachedImapAccounts;
01477 QValueList< QGuardedPtr<KMAccount> >::Iterator it;
01478 for (it = mNewAccounts.begin(); it != mNewAccounts.end(); ++it ) {
01479 kmkernel->acctMgr()->add( *it );
01480
01481 if( (*it)->isA( "KMAcctCachedImap" ) ) {
01482 newCachedImapAccounts.append( *it );
01483 }
01484 }
01485
01486 mNewAccounts.clear();
01487
01488
01489 QValueList<ModifiedAccountsType*>::Iterator j;
01490 for ( j = mModifiedAccounts.begin() ; j != mModifiedAccounts.end() ; ++j ) {
01491 (*j)->oldAccount->pseudoAssign( (*j)->newAccount );
01492 delete (*j)->newAccount;
01493 delete (*j);
01494 }
01495 mModifiedAccounts.clear();
01496
01497
01498 for ( it = mAccountsToDelete.begin() ;
01499 it != mAccountsToDelete.end() ; ++it ) {
01500
01501
01502
01503 (*it)->clearPasswd();
01504 kmkernel->acctMgr()->writeConfig( true );
01505 if ( !(*it) || !kmkernel->acctMgr()->remove(*it) )
01506 KMessageBox::sorry( this, i18n("<qt>Unable to locate account <b>%1</b>.</qt>")
01507 .arg( (*it)->name() ) );
01508 }
01509 mAccountsToDelete.clear();
01510
01511
01512 kmkernel->acctMgr()->writeConfig( false );
01513 kmkernel->cleanupImapFolders();
01514
01515
01516 KConfigGroup general( KMKernel::config(), "General" );
01517 general.writeEntry( "beep-on-mail", mBeepNewMailCheck->isChecked() );
01518 general.writeEntry( "systray-on-mail", mSystrayCheck->isChecked() );
01519 general.writeEntry( "systray-on-new", mSystrayOnNew->isChecked() );
01520
01521 general.writeEntry( "checkmail-startup", mCheckmailStartupCheck->isChecked() );
01522
01523
01524 for (it = newCachedImapAccounts.begin(); it != newCachedImapAccounts.end(); ++it ) {
01525 (*it)->processNewMail(false);
01526 }
01527 }
01528
01529 void NetworkPage::ReceivingTab::dismiss() {
01530
01531 for ( QValueList< QGuardedPtr<KMAccount> >::Iterator
01532 it = mNewAccounts.begin() ;
01533 it != mNewAccounts.end() ; ++it )
01534 delete *it;
01535
01536
01537 for ( QValueList< ModifiedAccountsType* >::Iterator
01538 it = mModifiedAccounts.begin() ;
01539 it != mModifiedAccounts.end() ; ++it ) {
01540 delete (*it)->newAccount;
01541 delete (*it);
01542 }
01543
01544
01545 mAccountsToDelete.clear();
01546
01547 mNewAccounts.clear();
01548 mModifiedAccounts.clear();
01549 }
01550
01551
01552
01553
01554
01555
01556
01557 QString AppearancePage::iconLabel() {
01558 return i18n("Appearance");
01559 }
01560
01561 QString AppearancePage::title() {
01562 return i18n("Customize Visual Appearance");
01563 }
01564
01565 const char * AppearancePage::iconName() {
01566 return "looknfeel";
01567 }
01568
01569 QString AppearancePage::helpAnchor() const {
01570 return QString::fromLatin1("configure-appearance");
01571 }
01572
01573 AppearancePage::AppearancePage( QWidget * parent, const char * name )
01574 : TabbedConfigurationPage( parent, name )
01575 {
01576
01577
01578
01579 mFontsTab = new FontsTab();
01580 addTab( mFontsTab, mFontsTab->title() );
01581
01582
01583
01584
01585 mColorsTab = new ColorsTab();
01586 addTab( mColorsTab, mColorsTab->title() );
01587
01588
01589
01590
01591 mLayoutTab = new LayoutTab();
01592 addTab( mLayoutTab, mLayoutTab->title() );
01593
01594
01595
01596
01597 mHeadersTab = new HeadersTab();
01598 addTab( mHeadersTab, mHeadersTab->title() );
01599 }
01600
01601 QString AppearancePage::FontsTab::title() {
01602 return i18n("&Fonts");
01603 }
01604
01605 QString AppearancePage::FontsTab::helpAnchor() const {
01606 return QString::fromLatin1("configure-appearance-fonts");
01607 }
01608
01609 static const struct {
01610 const char * configName;
01611 const char * displayName;
01612 bool enableFamilyAndSize;
01613 bool onlyFixed;
01614 } fontNames[] = {
01615 { "body-font", I18N_NOOP("Message Body"), true, false },
01616 { "list-font", I18N_NOOP("Message List"), true, false },
01617 { "list-date-font", I18N_NOOP("Message List - Date Field"), true, false },
01618 { "folder-font", I18N_NOOP("Folder List"), true, false },
01619 { "quote1-font", I18N_NOOP("Quoted Text - First Level"), false, false },
01620 { "quote2-font", I18N_NOOP("Quoted Text - Second Level"), false, false },
01621 { "quote3-font", I18N_NOOP("Quoted Text - Third Level"), false, false },
01622 { "fixed-font", I18N_NOOP("Fixed Width Font"), true, true },
01623 { "composer-font", I18N_NOOP("Composer"), true, false },
01624 { "print-font", I18N_NOOP("Printing Output"), true, false },
01625 };
01626 static const int numFontNames = sizeof fontNames / sizeof *fontNames;
01627
01628 AppearancePageFontsTab::AppearancePageFontsTab( QWidget * parent, const char * name )
01629 : ConfigurationPage( parent, name ), mActiveFontIndex( -1 )
01630 {
01631 assert( numFontNames == sizeof mFont / sizeof *mFont );
01632
01633 QVBoxLayout *vlay;
01634 QHBoxLayout *hlay;
01635 QLabel *label;
01636
01637
01638 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
01639 mCustomFontCheck = new QCheckBox( i18n("&Use custom fonts"), this );
01640 vlay->addWidget( mCustomFontCheck );
01641 vlay->addWidget( new KSeparator( KSeparator::HLine, this ) );
01642
01643
01644 hlay = new QHBoxLayout( vlay );
01645 mFontLocationCombo = new QComboBox( false, this );
01646 mFontLocationCombo->setEnabled( false );
01647
01648 QStringList fontDescriptions;
01649 for ( int i = 0 ; i < numFontNames ; i++ )
01650 fontDescriptions << i18n( fontNames[i].displayName );
01651 mFontLocationCombo->insertStringList( fontDescriptions );
01652
01653 label = new QLabel( mFontLocationCombo, i18n("Apply &to:"), this );
01654 label->setEnabled( false );
01655 hlay->addWidget( label );
01656
01657 hlay->addWidget( mFontLocationCombo );
01658 hlay->addStretch( 10 );
01659 vlay->addSpacing( KDialog::spacingHint() );
01660 mFontChooser = new KFontChooser( this, "font", false, QStringList(),
01661 false, 4 );
01662 mFontChooser->setEnabled( false );
01663 vlay->addWidget( mFontChooser );
01664
01665
01666 connect( mCustomFontCheck, SIGNAL(toggled(bool)),
01667 label, SLOT(setEnabled(bool)) );
01668 connect( mCustomFontCheck, SIGNAL(toggled(bool)),
01669 mFontLocationCombo, SLOT(setEnabled(bool)) );
01670 connect( mCustomFontCheck, SIGNAL(toggled(bool)),
01671 mFontChooser, SLOT(setEnabled(bool)) );
01672
01673 connect( mFontLocationCombo, SIGNAL(activated(int) ),
01674 this, SLOT(slotFontSelectorChanged(int)) );
01675 }
01676
01677
01678 void AppearancePage::FontsTab::slotFontSelectorChanged( int index )
01679 {
01680 kdDebug(5006) << "slotFontSelectorChanged() called" << endl;
01681 if( index < 0 || index >= mFontLocationCombo->count() )
01682 return;
01683
01684
01685 if( mActiveFontIndex == 0 ) {
01686 mFont[0] = mFontChooser->font();
01687
01688 for ( int i = 0 ; i < numFontNames ; i++ )
01689 if ( !fontNames[i].enableFamilyAndSize ) {
01690
01691
01692
01693 mFont[i].setFamily( mFont[0].family() );
01694 mFont[i].setPointSize( mFont[0].pointSize() );
01695 }
01696 } else if ( mActiveFontIndex > 0 )
01697 mFont[ mActiveFontIndex ] = mFontChooser->font();
01698 mActiveFontIndex = index;
01699
01700
01701
01702 mFontChooser->setFont( mFont[index], fontNames[index].onlyFixed );
01703
01704
01705 mFontChooser->enableColumn( KFontChooser::FamilyList|KFontChooser::SizeList,
01706 fontNames[ index ].enableFamilyAndSize );
01707 }
01708
01709 void AppearancePage::FontsTab::setup() {
01710 KConfigGroup fonts( KMKernel::config(), "Fonts" );
01711
01712 mFont[0] = KGlobalSettings::generalFont();
01713 QFont fixedFont = KGlobalSettings::fixedFont();
01714 for ( int i = 0 ; i < numFontNames ; i++ )
01715 mFont[i] = fonts.readFontEntry( fontNames[i].configName,
01716 (fontNames[i].onlyFixed) ? &fixedFont : &mFont[0] );
01717
01718 mCustomFontCheck->setChecked( !fonts.readBoolEntry( "defaultFonts", true ) );
01719 mFontLocationCombo->setCurrentItem( 0 );
01720
01721 slotFontSelectorChanged( 0 );
01722 }
01723
01724 void AppearancePage::FontsTab::installProfile( KConfig * profile ) {
01725 KConfigGroup fonts( profile, "Fonts" );
01726
01727
01728 bool needChange = false;
01729 for ( int i = 0 ; i < numFontNames ; i++ )
01730 if ( fonts.hasKey( fontNames[i].configName ) ) {
01731 needChange = true;
01732 mFont[i] = fonts.readFontEntry( fontNames[i].configName );
01733 kdDebug(5006) << "got font \"" << fontNames[i].configName
01734 << "\" thusly: \"" << mFont[i].toString() << "\"" << endl;
01735 }
01736 if ( needChange && mFontLocationCombo->currentItem() > 0 )
01737 mFontChooser->setFont( mFont[ mFontLocationCombo->currentItem() ],
01738 fontNames[ mFontLocationCombo->currentItem() ].onlyFixed );
01739
01740 if ( fonts.hasKey( "defaultFonts" ) )
01741 mCustomFontCheck->setChecked( !fonts.readBoolEntry( "defaultFonts" ) );
01742 }
01743
01744 void AppearancePage::FontsTab::apply() {
01745 KConfigGroup fonts( KMKernel::config(), "Fonts" );
01746
01747
01748 if ( mActiveFontIndex >= 0 )
01749 mFont[ mActiveFontIndex ] = mFontChooser->font();
01750
01751 bool customFonts = mCustomFontCheck->isChecked();
01752 fonts.writeEntry( "defaultFonts", !customFonts );
01753 for ( int i = 0 ; i < numFontNames ; i++ )
01754 if ( customFonts || fonts.hasKey( fontNames[i].configName ) )
01755
01756
01757 fonts.writeEntry( fontNames[i].configName, mFont[i] );
01758 }
01759
01760
01761 QString AppearancePage::ColorsTab::title() {
01762 return i18n("Colo&rs");
01763 }
01764
01765 QString AppearancePage::ColorsTab::helpAnchor() const {
01766 return QString::fromLatin1("configure-appearance-colors");
01767 }
01768
01769
01770 static const struct {
01771 const char * configName;
01772 const char * displayName;
01773 } colorNames[] = {
01774 { "BackgroundColor", I18N_NOOP("Composer background") },
01775 { "AltBackgroundColor", I18N_NOOP("Alternative background color") },
01776 { "ForegroundColor", I18N_NOOP("Normal text") },
01777 { "QuotedText1", I18N_NOOP("Quoted text - first level") },
01778 { "QuotedText2", I18N_NOOP("Quoted text - second level") },
01779 { "QuotedText3", I18N_NOOP("Quoted text - third level") },
01780 { "LinkColor", I18N_NOOP("Link") },
01781 { "FollowedColor", I18N_NOOP("Followed link") },
01782 { "MisspelledColor", I18N_NOOP("Misspelled words") },
01783 { "NewMessage", I18N_NOOP("New message") },
01784 { "UnreadMessage", I18N_NOOP("Unread message") },
01785 { "FlagMessage", I18N_NOOP("Important message") },
01786 { "PGPMessageEncr", I18N_NOOP("OpenPGP message - encrypted") },
01787 { "PGPMessageOkKeyOk", I18N_NOOP("OpenPGP message - valid signature with trusted key") },
01788 { "PGPMessageOkKeyBad", I18N_NOOP("OpenPGP message - valid signature with untrusted key") },
01789 { "PGPMessageWarn", I18N_NOOP("OpenPGP message - unchecked signature") },
01790 { "PGPMessageErr", I18N_NOOP("OpenPGP message - bad signature") },
01791 { "HTMLWarningColor", I18N_NOOP("Border around warning prepending HTML messages") },
01792 { "ColorbarBackgroundPlain", I18N_NOOP("HTML status bar background - No HTML message") },
01793 { "ColorbarForegroundPlain", I18N_NOOP("HTML status bar foreground - No HTML message") },
01794 { "ColorbarBackgroundHTML", I18N_NOOP("HTML status bar background - HTML message") },
01795 { "ColorbarForegroundHTML", I18N_NOOP("HTML status bar foreground - HTML message") },
01796 };
01797 static const int numColorNames = sizeof colorNames / sizeof *colorNames;
01798
01799 AppearancePageColorsTab::AppearancePageColorsTab( QWidget * parent, const char * name )
01800 : ConfigurationPage( parent, name )
01801 {
01802
01803 QVBoxLayout *vlay;
01804
01805
01806 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
01807 mCustomColorCheck = new QCheckBox( i18n("&Use custom colors"), this );
01808 vlay->addWidget( mCustomColorCheck );
01809
01810
01811 mColorList = new ColorListBox( this );
01812 mColorList->setEnabled( false );
01813 QStringList modeList;
01814 for ( int i = 0 ; i < numColorNames ; i++ )
01815 mColorList->insertItem( new ColorListItem( i18n( colorNames[i].displayName ) ) );
01816 vlay->addWidget( mColorList, 1 );
01817
01818
01819 mRecycleColorCheck =
01820 new QCheckBox( i18n("Recycle colors on deep "ing"), this );
01821 mRecycleColorCheck->setEnabled( false );
01822 vlay->addWidget( mRecycleColorCheck );
01823
01824
01825 connect( mCustomColorCheck, SIGNAL(toggled(bool)),
01826 mColorList, SLOT(setEnabled(bool)) );
01827 connect( mCustomColorCheck, SIGNAL(toggled(bool)),
01828 mRecycleColorCheck, SLOT(setEnabled(bool)) );
01829 }
01830
01831 void AppearancePage::ColorsTab::setup() {
01832 KConfigGroup reader( KMKernel::config(), "Reader" );
01833
01834 mCustomColorCheck->setChecked( !reader.readBoolEntry( "defaultColors", true ) );
01835 mRecycleColorCheck->setChecked( reader.readBoolEntry( "RecycleQuoteColors", false ) );
01836
01837 static const QColor defaultColor[ numColorNames ] = {
01838 kapp->palette().active().base(),
01839 KGlobalSettings::alternateBackgroundColor(),
01840 kapp->palette().active().text(),
01841 QColor( 0x00, 0x80, 0x00 ),
01842 QColor( 0x00, 0x70, 0x00 ),
01843 QColor( 0x00, 0x60, 0x00 ),
01844 KGlobalSettings::linkColor(),
01845 KGlobalSettings::visitedLinkColor(),
01846 Qt::red,
01847 Qt::red,
01848 Qt::blue,
01849 QColor( 0x00, 0x7F, 0x00 ),
01850 QColor( 0x00, 0x80, 0xFF ),
01851 QColor( 0x40, 0xFF, 0x40 ),
01852 QColor( 0xFF, 0xFF, 0x40 ),
01853 QColor( 0xFF, 0xFF, 0x40 ),
01854 Qt::red,
01855 QColor( 0xFF, 0x40, 0x40 ),
01856 Qt::lightGray,
01857 Qt::black,
01858 Qt::black,
01859 Qt::white,
01860 };
01861
01862 for ( int i = 0 ; i < numColorNames ; i++ )
01863 mColorList->setColor( i,
01864 reader.readColorEntry( colorNames[i].configName, &defaultColor[i] ) );
01865 }
01866
01867 void AppearancePage::ColorsTab::installProfile( KConfig * profile ) {
01868 KConfigGroup reader( profile, "Reader" );
01869
01870 if ( reader.hasKey( "defaultColors" ) )
01871 mCustomColorCheck->setChecked( !reader.readBoolEntry( "defaultColors" ) );
01872 if ( reader.hasKey( "RecycleQuoteColors" ) )
01873 mRecycleColorCheck->setChecked( reader.readBoolEntry( "RecycleQuoteColors" ) );
01874
01875 for ( int i = 0 ; i < numColorNames ; i++ )
01876 if ( reader.hasKey( colorNames[i].configName ) )
01877 mColorList->setColor( i, reader.readColorEntry( colorNames[i].configName ) );
01878 }
01879
01880 void AppearancePage::ColorsTab::apply() {
01881 KConfigGroup reader( KMKernel::config(), "Reader" );
01882
01883 bool customColors = mCustomColorCheck->isChecked();
01884 reader.writeEntry( "defaultColors", !customColors );
01885
01886 for ( int i = 0 ; i < numColorNames ; i++ )
01887
01888
01889 if ( customColors || reader.hasKey( colorNames[i].configName ) )
01890 reader.writeEntry( colorNames[i].configName, mColorList->color(i) );
01891
01892 reader.writeEntry( "RecycleQuoteColors", mRecycleColorCheck->isChecked() );
01893 }
01894
01895 QString AppearancePage::LayoutTab::title() {
01896 return i18n("La&yout");
01897 }
01898
01899 QString AppearancePage::LayoutTab::helpAnchor() const {
01900 return QString::fromLatin1("configure-appearance-layout");
01901 }
01902
01903 static const EnumConfigEntryItem folderListModes[] = {
01904 { "long", I18N_NOOP("Lon&g folder list") },
01905 { "short", I18N_NOOP("Shor&t folder list" ) }
01906 };
01907 static const EnumConfigEntry folderListMode = {
01908 "Geometry", "FolderList", I18N_NOOP("Folder List"),
01909 folderListModes, DIM(folderListModes), 0
01910 };
01911
01912
01913 static const EnumConfigEntryItem mimeTreeLocations[] = {
01914 { "top", I18N_NOOP("Abo&ve the message pane") },
01915 { "bottom", I18N_NOOP("&Below the message pane") }
01916 };
01917 static const EnumConfigEntry mimeTreeLocation = {
01918 "Reader", "MimeTreeLocation", I18N_NOOP("Message Structure Viewer Placement"),
01919 mimeTreeLocations, DIM(mimeTreeLocations), 1
01920 };
01921
01922 static const EnumConfigEntryItem mimeTreeModes[] = {
01923 { "never", I18N_NOOP("Show &never") },
01924 { "smart", I18N_NOOP("Show only for non-plaintext &messages") },
01925 { "always", I18N_NOOP("Show alway&s") }
01926 };
01927 static const EnumConfigEntry mimeTreeMode = {
01928 "Reader", "MimeTreeMode", I18N_NOOP("Message Structure Viewer"),
01929 mimeTreeModes, DIM(mimeTreeModes), 1
01930 };
01931
01932
01933 static const EnumConfigEntryItem readerWindowModes[] = {
01934 { "hide", I18N_NOOP("&Don't show a message preview pane") },
01935 { "below", I18N_NOOP("Show the message preview pane belo&w the message list") },
01936 { "right", I18N_NOOP("Show the message preview pane ne&xt to the message list") }
01937 };
01938 static const EnumConfigEntry readerWindowMode = {
01939 "Geometry", "readerWindowMode", I18N_NOOP("Message Preview Pane"),
01940 readerWindowModes, DIM(readerWindowModes), 1
01941 };
01942
01943 static const BoolConfigEntry showColorbarMode = {
01944 "Reader", "showColorbar", I18N_NOOP("Show HTML stat&us bar"), false
01945 };
01946
01947 AppearancePageLayoutTab::AppearancePageLayoutTab( QWidget * parent, const char * name )
01948 : ConfigurationPage( parent, name )
01949 {
01950
01951 QVBoxLayout * vlay;
01952
01953 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
01954
01955
01956 populate( mShowColorbarCheck = new QCheckBox( this ), showColorbarMode );
01957 vlay->addWidget( mShowColorbarCheck );
01958
01959
01960 populate( mFolderListGroup = new QHButtonGroup( this ), folderListMode );
01961 vlay->addWidget( mFolderListGroup );
01962
01963
01964 populate( mReaderWindowModeGroup = new QVButtonGroup( this ), readerWindowMode );
01965 vlay->addWidget( mReaderWindowModeGroup );
01966
01967
01968 populate( mMIMETreeModeGroup = new QVButtonGroup( this ), mimeTreeMode );
01969 vlay->addWidget( mMIMETreeModeGroup );
01970
01971
01972 populate( mMIMETreeLocationGroup = new QHButtonGroup( this ), mimeTreeLocation );
01973 vlay->addWidget( mMIMETreeLocationGroup );
01974
01975 vlay->addStretch( 10 );
01976 }
01977
01978 void AppearancePage::LayoutTab::setup() {
01979 const KConfigGroup reader( KMKernel::config(), "Reader" );
01980 const KConfigGroup geometry( KMKernel::config(), "Geometry" );
01981
01982 load( mShowColorbarCheck, reader, showColorbarMode );
01983 load( mFolderListGroup, geometry, folderListMode );
01984 load( mMIMETreeLocationGroup, reader, mimeTreeLocation );
01985 load( mMIMETreeModeGroup, reader, mimeTreeMode );
01986 load( mReaderWindowModeGroup, geometry, readerWindowMode );
01987 }
01988
01989 void AppearancePage::LayoutTab::installProfile( KConfig * profile ) {
01990 const KConfigGroup reader( profile, "Reader" );
01991 const KConfigGroup geometry( profile, "Geometry" );
01992
01993 loadProfile( mShowColorbarCheck, reader, showColorbarMode );
01994 loadProfile( mFolderListGroup, geometry, folderListMode );
01995 loadProfile( mMIMETreeLocationGroup, reader, mimeTreeLocation );
01996 loadProfile( mMIMETreeModeGroup, reader, mimeTreeMode );
01997 loadProfile( mReaderWindowModeGroup, geometry, readerWindowMode );
01998 }
01999
02000 void AppearancePage::LayoutTab::apply() {
02001 KConfigGroup reader( KMKernel::config(), "Reader" );
02002 KConfigGroup geometry( KMKernel::config(), "Geometry" );
02003
02004 save( mShowColorbarCheck, reader, showColorbarMode );
02005 save( mFolderListGroup, geometry, folderListMode );
02006 save( mMIMETreeLocationGroup, reader, mimeTreeLocation );
02007 save( mMIMETreeModeGroup, reader, mimeTreeMode );
02008 save( mReaderWindowModeGroup, geometry, readerWindowMode );
02009 }
02010
02011 QString AppearancePage::HeadersTab::title() {
02012 return i18n("H&eaders");
02013 }
02014
02015 QString AppearancePage::HeadersTab::helpAnchor() const {
02016 return QString::fromLatin1("configure-appearance-headers");
02017 }
02018
02019 static const struct {
02020 const char * displayName;
02021 DateFormatter::FormatType dateDisplay;
02022 } dateDisplayConfig[] = {
02023 { I18N_NOOP("Sta&ndard format (%1)"), KMime::DateFormatter::CTime },
02024 { I18N_NOOP("Locali&zed format (%1)"), KMime::DateFormatter::Localized },
02025 { I18N_NOOP("Fancy for&mat (%1)"), KMime::DateFormatter::Fancy },
02026 { I18N_NOOP("C&ustom format (Shift+F1 for help)"),
02027 KMime::DateFormatter::Custom }
02028 };
02029 static const int numDateDisplayConfig =
02030 sizeof dateDisplayConfig / sizeof *dateDisplayConfig;
02031
02032 AppearancePageHeadersTab::AppearancePageHeadersTab( QWidget * parent, const char * name )
02033 : ConfigurationPage( parent, name ),
02034 mCustomDateFormatEdit( 0 )
02035 {
02036
02037 QButtonGroup * group;
02038 QRadioButton * radio;
02039
02040 QVBoxLayout * vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
02041
02042
02043 group = new QVButtonGroup( i18n( "General Options" ), this );
02044 group->layout()->setSpacing( KDialog::spacingHint() );
02045
02046 mMessageSizeCheck = new QCheckBox( i18n("&Display message sizes"), group );
02047
02048 mCryptoIconsCheck = new QCheckBox( i18n( "Show crypto &icons" ), group );
02049
02050 mNestedMessagesCheck =
02051 new QCheckBox( i18n("&Thread list of message headers"), group );
02052
02053 vlay->addWidget( group );
02054
02055
02056 mNestingPolicy =
02057 new QVButtonGroup( i18n("Message Header Threading Options"), this );
02058 mNestingPolicy->layout()->setSpacing( KDialog::spacingHint() );
02059
02060 mNestingPolicy->insert(
02061 new QRadioButton( i18n("Always &keep threads open"),
02062 mNestingPolicy ), 0 );
02063 mNestingPolicy->insert(
02064 new QRadioButton( i18n("Threads default to o&pen"),
02065 mNestingPolicy ), 1 );
02066 mNestingPolicy->insert(
02067 new QRadioButton( i18n("Threads default to clo&sed"),
02068 mNestingPolicy ), 2 );
02069 mNestingPolicy->insert(
02070 new QRadioButton( i18n("Open threads that contain ne&w, unread "
02071 "or important messages and open watched threads."),
02072 mNestingPolicy ), 3 );
02073
02074 vlay->addWidget( mNestingPolicy );
02075
02076
02077 mDateDisplay = new QVButtonGroup( i18n("Date Display"), this );
02078 mDateDisplay->layout()->setSpacing( KDialog::spacingHint() );
02079
02080 for ( int i = 0 ; i < numDateDisplayConfig ; i++ ) {
02081 QString buttonLabel = i18n(dateDisplayConfig[i].displayName);
02082 if ( buttonLabel.contains("%1") )
02083 buttonLabel = buttonLabel.arg( DateFormatter::formatCurrentDate( dateDisplayConfig[i].dateDisplay ) );
02084 radio = new QRadioButton( buttonLabel, mDateDisplay );
02085 mDateDisplay->insert( radio, i );
02086 if ( dateDisplayConfig[i].dateDisplay == DateFormatter::Custom ) {
02087 mCustomDateFormatEdit = new KLineEdit( mDateDisplay );
02088 mCustomDateFormatEdit->setEnabled( false );
02089 connect( radio, SIGNAL(toggled(bool)),
02090 mCustomDateFormatEdit, SLOT(setEnabled(bool)) );
02091 QString customDateWhatsThis =
02092 i18n("<qt><p><strong>These expressions may be used for the date:"
02093 "</strong></p>"
02094 "<ul>"
02095 "<li>d - the day as a number without a leading zero (1-31)</li>"
02096 "<li>dd - the day as a number with a leading zero (01-31)</li>"
02097 "<li>ddd - the abbreviated day name (Mon - Sun)</li>"
02098 "<li>dddd - the long day name (Monday - Sunday)</li>"
02099 "<li>M - the month as a number without a leading zero (1-12)</li>"
02100 "<li>MM - the month as a number with a leading zero (01-12)</li>"
02101 "<li>MMM - the abbreviated month name (Jan - Dec)</li>"
02102 "<li>MMMM - the long month name (January - December)</li>"
02103 "<li>yy - the year as a two digit number (00-99)</li>"
02104 "<li>yyyy - the year as a four digit number (0000-9999)</li>"
02105 "</ul>"
02106 "<p><strong>These expressions may be used for the time:"
02107 "</string></p> "
02108 "<ul>"
02109 "<li>h - the hour without a leading zero (0-23 or 1-12 if AM/PM display)</li>"
02110 "<li>hh - the hour with a leading zero (00-23 or 01-12 if AM/PM display)</li>"
02111 "<li>m - the minutes without a leading zero (0-59)</li>"
02112 "<li>mm - the minutes with a leading zero (00-59)</li>"
02113 "<li>s - the seconds without a leading zero (0-59)</li>"
02114 "<li>ss - the seconds with a leading zero (00-59)</li>"
02115 "<li>z - the milliseconds without leading zeroes (0-999)</li>"
02116 "<li>zzz - the milliseconds with leading zeroes (000-999)</li>"
02117 "<li>AP - switch to AM/PM display. AP will be replaced by either \"AM\" or \"PM\".</li>"
02118 "<li>ap - switch to AM/PM display. ap will be replaced by either \"am\" or \"pm\".</li>"
02119 "<li>Z - time zone in numeric form (-0500)</li>"
02120 "</ul>"
02121 "<p><strong>All other input characters will be ignored."
02122 "</strong></p></qt>");
02123 QWhatsThis::add( mCustomDateFormatEdit, customDateWhatsThis );
02124 QWhatsThis::add( radio, customDateWhatsThis );
02125 }
02126 }
02127
02128 vlay->addWidget( mDateDisplay );
02129
02130 vlay->addStretch( 10 );
02131 }
02132
02133 void AppearancePage::HeadersTab::setup() {
02134 KConfigGroup general( KMKernel::config(), "General" );
02135 KConfigGroup geometry( KMKernel::config(), "Geometry" );
02136
02137
02138 mNestedMessagesCheck->setChecked( geometry.readBoolEntry( "nestedMessages", false ) );
02139 mMessageSizeCheck->setChecked( general.readBoolEntry( "showMessageSize", false ) );
02140 mCryptoIconsCheck->setChecked( general.readBoolEntry( "showCryptoIcons", false ) );
02141
02142
02143 int num = geometry.readNumEntry( "nestingPolicy", 3 );
02144 if ( num < 0 || num > 3 ) num = 3;
02145 mNestingPolicy->setButton( num );
02146
02147
02148 setDateDisplay( general.readNumEntry( "dateFormat", DateFormatter::Fancy ),
02149 general.readEntry( "customDateFormat" ) );
02150 }
02151
02152 void AppearancePage::HeadersTab::setDateDisplay( int num, const QString & format ) {
02153 DateFormatter::FormatType dateDisplay =
02154 static_cast<DateFormatter::FormatType>( num );
02155
02156
02157 if ( dateDisplay == DateFormatter::Custom )
02158 mCustomDateFormatEdit->setText( format );
02159
02160 for ( int i = 0 ; i < numDateDisplayConfig ; i++ )
02161 if ( dateDisplay == dateDisplayConfig[i].dateDisplay ) {
02162 mDateDisplay->setButton( i );
02163 return;
02164 }
02165
02166 mDateDisplay->setButton( numDateDisplayConfig - 2 );
02167 }
02168
02169 void AppearancePage::HeadersTab::installProfile( KConfig * profile ) {
02170 KConfigGroup general( profile, "General" );
02171 KConfigGroup geometry( profile, "Geometry" );
02172
02173 if ( geometry.hasKey( "nestedMessages" ) )
02174 mNestedMessagesCheck->setChecked( geometry.readBoolEntry( "nestedMessages" ) );
02175 if ( general.hasKey( "showMessageSize" ) )
02176 mMessageSizeCheck->setChecked( general.readBoolEntry( "showMessageSize" ) );
02177
02178 if( general.hasKey( "showCryptoIcons" ) )
02179 mCryptoIconsCheck->setChecked( general.readBoolEntry( "showCryptoIcons" ) );
02180
02181 if ( geometry.hasKey( "nestingPolicy" ) ) {
02182 int num = geometry.readNumEntry( "nestingPolicy" );
02183 if ( num < 0 || num > 3 ) num = 3;
02184 mNestingPolicy->setButton( num );
02185 }
02186
02187 if ( general.hasKey( "dateFormat" ) )
02188 setDateDisplay( general.readNumEntry( "dateFormat" ),
02189 general.readEntry( "customDateFormat" ) );
02190 }
02191
02192 void AppearancePage::HeadersTab::apply() {
02193 KConfigGroup general( KMKernel::config(), "General" );
02194 KConfigGroup geometry( KMKernel::config(), "Geometry" );
02195
02196 if ( geometry.readBoolEntry( "nestedMessages", false )
02197 != mNestedMessagesCheck->isChecked() ) {
02198 int result = KMessageBox::warningContinueCancel( this,
02199 i18n("Changing the global threading setting will override "
02200 "all folder specific values."),
02201 QString::null, QString::null, "threadOverride" );
02202 if ( result == KMessageBox::Continue ) {
02203 geometry.writeEntry( "nestedMessages", mNestedMessagesCheck->isChecked() );
02204
02205 QStringList groups = KMKernel::config()->groupList().grep( QRegExp("^Folder-") );
02206 kdDebug(5006) << "groups.count() == " << groups.count() << endl;
02207 for ( QStringList::const_iterator it = groups.begin() ; it != groups.end() ; ++it ) {
02208 KConfigGroup group( KMKernel::config(), *it );
02209 group.deleteEntry( "threadMessagesOverride" );
02210 }
02211 }
02212 }
02213
02214 geometry.writeEntry( "nestingPolicy",
02215 mNestingPolicy->id( mNestingPolicy->selected() ) );
02216 general.writeEntry( "showMessageSize", mMessageSizeCheck->isChecked() );
02217 general.writeEntry( "showCryptoIcons", mCryptoIconsCheck->isChecked() );
02218
02219 int dateDisplayID = mDateDisplay->id( mDateDisplay->selected() );
02220
02221 assert( dateDisplayID >= 0 ); assert( dateDisplayID < numDateDisplayConfig );
02222 general.writeEntry( "dateFormat",
02223 dateDisplayConfig[ dateDisplayID ].dateDisplay );
02224 general.writeEntry( "customDateFormat", mCustomDateFormatEdit->text() );
02225 }
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236 QString ComposerPage::iconLabel() {
02237 return i18n("Composer");
02238 }
02239
02240 const char * ComposerPage::iconName() {
02241 return "edit";
02242 }
02243
02244 QString ComposerPage::title() {
02245 return i18n("Phrases & General Behavior");
02246 }
02247
02248 QString ComposerPage::helpAnchor() const {
02249 return QString::fromLatin1("configure-composer");
02250 }
02251
02252 ComposerPage::ComposerPage( QWidget * parent, const char * name )
02253 : TabbedConfigurationPage( parent, name )
02254 {
02255
02256
02257
02258 mGeneralTab = new GeneralTab();
02259 addTab( mGeneralTab, mGeneralTab->title() );
02260
02261
02262
02263
02264 mPhrasesTab = new PhrasesTab();
02265 addTab( mPhrasesTab, mPhrasesTab->title() );
02266
02267
02268
02269
02270 mSubjectTab = new SubjectTab();
02271 addTab( mSubjectTab, mSubjectTab->title() );
02272
02273
02274
02275
02276 mCharsetTab = new CharsetTab();
02277 addTab( mCharsetTab, mCharsetTab->title() );
02278
02279
02280
02281
02282 mHeadersTab = new HeadersTab();
02283 addTab( mHeadersTab, mHeadersTab->title() );
02284
02285
02286
02287
02288 mAttachmentsTab = new AttachmentsTab();
02289 addTab( mAttachmentsTab, mAttachmentsTab->title() );
02290 }
02291
02292 QString ComposerPage::GeneralTab::title() {
02293 return i18n("&General");
02294 }
02295
02296 QString ComposerPage::GeneralTab::helpAnchor() const {
02297 return QString::fromLatin1("configure-composer-general");
02298 }
02299
02300
02301 ComposerPageGeneralTab::ComposerPageGeneralTab( QWidget * parent, const char * name )
02302 : ConfigurationPage( parent, name )
02303 {
02304
02305 QVBoxLayout *vlay;
02306 QHBoxLayout *hlay;
02307 QGroupBox *group;
02308 QLabel *label;
02309 QHBox *hbox;
02310
02311 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
02312
02313
02314 mAutoAppSignFileCheck =
02315 new QCheckBox( i18n("A&utomatically append signature"), this );
02316 vlay->addWidget( mAutoAppSignFileCheck );
02317
02318 mSmartQuoteCheck = new QCheckBox( i18n("Use smart "ing"), this );
02319 vlay->addWidget( mSmartQuoteCheck );
02320
02321 mAutoRequestMDNCheck = new QCheckBox( i18n("Automatically request &message disposition notifications"), this );
02322 vlay->addWidget( mAutoRequestMDNCheck );
02323
02324
02325
02326 hlay = new QHBoxLayout( vlay );
02327 mWordWrapCheck = new QCheckBox( i18n("Word &wrap at column:"), this );
02328 hlay->addWidget( mWordWrapCheck );
02329 mWrapColumnSpin = new KIntSpinBox( 30, 78, 1,
02330 78, 10 , this );
02331 mWrapColumnSpin->setEnabled( false );
02332 hlay->addWidget( mWrapColumnSpin );
02333 hlay->addStretch( 1 );
02334
02335 connect( mWordWrapCheck, SIGNAL(toggled(bool)),
02336 mWrapColumnSpin, SLOT(setEnabled(bool)) );
02337
02338
02339 group = new QVGroupBox( i18n("External Editor"), this );
02340 group->layout()->setSpacing( KDialog::spacingHint() );
02341
02342 mExternalEditorCheck =
02343 new QCheckBox( i18n("Use e&xternal editor instead of composer"), group );
02344
02345 hbox = new QHBox( group );
02346 label = new QLabel( i18n("Specify e&ditor:"), hbox );
02347 mEditorRequester = new KURLRequester( hbox );
02348 hbox->setStretchFactor( mEditorRequester, 1 );
02349 label->setBuddy( mEditorRequester );
02350 label->setEnabled( false );
02351
02352 mEditorRequester->setFilter( "application/x-executable "
02353 "application/x-shellscript "
02354 "application/x-desktop" );
02355 mEditorRequester->setEnabled( false );
02356 connect( mExternalEditorCheck, SIGNAL(toggled(bool)),
02357 label, SLOT(setEnabled(bool)) );
02358 connect( mExternalEditorCheck, SIGNAL(toggled(bool)),
02359 mEditorRequester, SLOT(setEnabled(bool)) );
02360
02361 label = new QLabel( i18n("<b>%f</b> will be replaced with the "
02362 "filename to edit."), group );
02363 label->setEnabled( false );
02364 connect( mExternalEditorCheck, SIGNAL(toggled(bool)),
02365 label, SLOT(setEnabled(bool)) );
02366
02367 vlay->addWidget( group );
02368 vlay->addStretch( 100 );
02369
02370 QString msg = i18n("<qt><p>Enable this option if you want KMail to request "
02371 "Message Disposition Notifications (MDNs) for each of your "
02372 "outgoing messages.</p>"
02373 "<p>This option only affects the default; "
02374 "you can still enable or disable MDN requesting on a "
02375 "per-message basis in the composer, menu item "
02376 "<em>Options</em>->>"
02377 "<em>Request Disposition Notification</em>.</p></qt>");
02378 QWhatsThis::add( mAutoRequestMDNCheck, msg );
02379 }
02380
02381 void ComposerPage::GeneralTab::setup() {
02382 KConfigGroup composer( KMKernel::config(), "Composer" );
02383 KConfigGroup general( KMKernel::config(), "General" );
02384
02385
02386 bool state = ( composer.readEntry("signature").lower() != "manual" );
02387 mAutoAppSignFileCheck->setChecked( state );
02388 mSmartQuoteCheck->setChecked( composer.readBoolEntry( "smart-quote", true ) );
02389 mAutoRequestMDNCheck->setChecked( composer.readBoolEntry( "request-mdn", false ) );
02390 mWordWrapCheck->setChecked( composer.readBoolEntry( "word-wrap", true ) );
02391 mWrapColumnSpin->setValue( composer.readNumEntry( "break-at", 78 ) );
02392
02393
02394 mExternalEditorCheck->setChecked( general.readBoolEntry( "use-external-editor", false ) );
02395 mEditorRequester->setURL( general.readPathEntry( "external-editor" ) );
02396 }
02397
02398 void ComposerPage::GeneralTab::installProfile( KConfig * profile ) {
02399 KConfigGroup composer( profile, "Composer" );
02400 KConfigGroup general( profile, "General" );
02401
02402 if ( composer.hasKey( "signature" ) ) {
02403 bool state = ( composer.readEntry("signature").lower() == "auto" );
02404 mAutoAppSignFileCheck->setChecked( state );
02405 }
02406 if ( composer.hasKey( "smart-quote" ) )
02407 mSmartQuoteCheck->setChecked( composer.readBoolEntry( "smart-quote" ) );
02408 if ( composer.hasKey( "request-mdn" ) )
02409 mAutoRequestMDNCheck->setChecked( composer.readBoolEntry( "request-mdn" ) );
02410 if ( composer.hasKey( "word-wrap" ) )
02411 mWordWrapCheck->setChecked( composer.readBoolEntry( "word-wrap" ) );
02412 if ( composer.hasKey( "break-at" ) )
02413 mWrapColumnSpin->setValue( composer.readNumEntry( "break-at" ) );
02414
02415 if ( general.hasKey( "use-external-editor" )
02416 && general.hasKey( "external-editor" ) ) {
02417 mExternalEditorCheck->setChecked( general.readBoolEntry( "use-external-editor" ) );
02418 mEditorRequester->setURL( general.readPathEntry( "external-editor" ) );
02419 }
02420 }
02421
02422 void ComposerPage::GeneralTab::apply() {
02423 KConfigGroup general( KMKernel::config(), "General" );
02424 KConfigGroup composer( KMKernel::config(), "Composer" );
02425
02426 general.writeEntry( "use-external-editor", mExternalEditorCheck->isChecked()
02427 && !mEditorRequester->url().isEmpty() );
02428 general.writePathEntry( "external-editor", mEditorRequester->url() );
02429
02430 bool autoSignature = mAutoAppSignFileCheck->isChecked();
02431 composer.writeEntry( "signature", autoSignature ? "auto" : "manual" );
02432 composer.writeEntry( "smart-quote", mSmartQuoteCheck->isChecked() );
02433 composer.writeEntry( "request-mdn", mAutoRequestMDNCheck->isChecked() );
02434 composer.writeEntry( "word-wrap", mWordWrapCheck->isChecked() );
02435 composer.writeEntry( "break-at", mWrapColumnSpin->value() );
02436 }
02437
02438
02439
02440 QString ComposerPage::PhrasesTab::title() {
02441 return i18n("&Phrases");
02442 }
02443
02444 QString ComposerPage::PhrasesTab::helpAnchor() const {
02445 return QString::fromLatin1("configure-composer-phrases");
02446 }
02447
02448 ComposerPagePhrasesTab::ComposerPagePhrasesTab( QWidget * parent, const char * name )
02449 : ConfigurationPage( parent, name )
02450 {
02451
02452 QGridLayout *glay;
02453 QPushButton *button;
02454
02455 glay = new QGridLayout( this, 7, 3, KDialog::spacingHint() );
02456 glay->setMargin( KDialog::marginHint() );
02457 glay->setColStretch( 1, 1 );
02458 glay->setColStretch( 2, 1 );
02459 glay->setRowStretch( 7, 1 );
02460
02461
02462 glay->addMultiCellWidget( new QLabel( i18n("<qt>The following placeholders are "
02463 "supported in the reply phrases:<br>"
02464 "<b>%D</b>: date, <b>%S</b>: subject,<br>"
02465 "<b>%e</b>: sender's address, <b>%F</b>: sender's name, <b>%f</b>: sender's initials,<br>"
02466 "<b>%T</b>: recipient's name, <b>%t</b>: recipient's name and address,<br>"
02467 "<b>%C</b>: carbon copy names, <b>%c</b>: carbon copy names and addresses,<br>"
02468 "<b>%%</b>: percent sign, <b>%_</b>: space, "
02469 "<b>%L</b>: linebreak</qt>"), this ),
02470 0, 0, 0, 2 );
02471
02472
02473 mPhraseLanguageCombo = new LanguageComboBox( false, this );
02474 glay->addWidget( new QLabel( mPhraseLanguageCombo,
02475 i18n("Lang&uage:"), this ), 1, 0 );
02476 glay->addMultiCellWidget( mPhraseLanguageCombo, 1, 1, 1, 2 );
02477 connect( mPhraseLanguageCombo, SIGNAL(activated(const QString&)),
02478 this, SLOT(slotLanguageChanged(const QString&)) );
02479
02480
02481 button = new QPushButton( i18n("A&dd..."), this );
02482 button->setAutoDefault( false );
02483 glay->addWidget( button, 2, 1 );
02484 mRemoveButton = new QPushButton( i18n("Re&move"), this );
02485 mRemoveButton->setAutoDefault( false );
02486 mRemoveButton->setEnabled( false );
02487 glay->addWidget( mRemoveButton, 2, 2 );
02488 connect( button, SIGNAL(clicked()),
02489 this, SLOT(slotNewLanguage()) );
02490 connect( mRemoveButton, SIGNAL(clicked()),
02491 this, SLOT(slotRemoveLanguage()) );
02492
02493
02494 mPhraseReplyEdit = new KLineEdit( this );
02495 glay->addWidget( new QLabel( mPhraseReplyEdit,
02496 i18n("Reply to se&nder:"), this ), 3, 0 );
02497 glay->addMultiCellWidget( mPhraseReplyEdit, 3, 3, 1, 2 );
02498
02499
02500 mPhraseReplyAllEdit = new KLineEdit( this );
02501 glay->addWidget( new QLabel( mPhraseReplyAllEdit,
02502 i18n("Repl&y to all:"), this ), 4, 0 );
02503 glay->addMultiCellWidget( mPhraseReplyAllEdit, 4, 4, 1, 2 );
02504
02505
02506 mPhraseForwardEdit = new KLineEdit( this );
02507 glay->addWidget( new QLabel( mPhraseForwardEdit,
02508 i18n("&Forward:"), this ), 5, 0 );
02509 glay->addMultiCellWidget( mPhraseForwardEdit, 5, 5, 1, 2 );
02510
02511
02512 mPhraseIndentPrefixEdit = new KLineEdit( this );
02513 glay->addWidget( new QLabel( mPhraseIndentPrefixEdit,
02514 i18n("&Quote indicator:"), this ), 6, 0 );
02515 glay->addMultiCellWidget( mPhraseIndentPrefixEdit, 6, 6, 1, 2 );
02516
02517
02518 }
02519
02520
02521 void ComposerPage::PhrasesTab::setLanguageItemInformation( int index ) {
02522 assert( 0 <= index && index < (int)mLanguageList.count() );
02523
02524 LanguageItem &l = *mLanguageList.at( index );
02525
02526 mPhraseReplyEdit->setText( l.mReply );
02527 mPhraseReplyAllEdit->setText( l.mReplyAll );
02528 mPhraseForwardEdit->setText( l.mForward );
02529 mPhraseIndentPrefixEdit->setText( l.mIndentPrefix );
02530 }
02531
02532 void ComposerPage::PhrasesTab::saveActiveLanguageItem() {
02533 int index = mActiveLanguageItem;
02534 if (index == -1) return;
02535 assert( 0 <= index && index < (int)mLanguageList.count() );
02536
02537 LanguageItem &l = *mLanguageList.at( index );
02538
02539 l.mReply = mPhraseReplyEdit->text();
02540 l.mReplyAll = mPhraseReplyAllEdit->text();
02541 l.mForward = mPhraseForwardEdit->text();
02542 l.mIndentPrefix = mPhraseIndentPrefixEdit->text();
02543 }
02544
02545 void ComposerPage::PhrasesTab::slotNewLanguage()
02546 {
02547 NewLanguageDialog dialog( mLanguageList, parentWidget(), "New", true );
02548 if ( dialog.exec() == QDialog::Accepted ) slotAddNewLanguage( dialog.language() );
02549 }
02550
02551 void ComposerPage::PhrasesTab::slotAddNewLanguage( const QString& lang )
02552 {
02553 mPhraseLanguageCombo->setCurrentItem(
02554 mPhraseLanguageCombo->insertLanguage( lang ) );
02555 KLocale locale("kmail");
02556 locale.setLanguage( lang );
02557 mLanguageList.append(
02558 LanguageItem( lang,
02559 locale.translate("On %D, you wrote:"),
02560 locale.translate("On %D, %F wrote:"),
02561 locale.translate("Forwarded Message"),
02562 locale.translate(">%_") ) );
02563 mRemoveButton->setEnabled( true );
02564 slotLanguageChanged( QString::null );
02565 }
02566
02567 void ComposerPage::PhrasesTab::slotRemoveLanguage()
02568 {
02569 assert( mPhraseLanguageCombo->count() > 1 );
02570 int index = mPhraseLanguageCombo->currentItem();
02571 assert( 0 <= index && index < (int)mLanguageList.count() );
02572
02573
02574 mLanguageList.remove( mLanguageList.at( index ) );
02575 mPhraseLanguageCombo->removeItem( index );
02576
02577 if ( index >= (int)mLanguageList.count() ) index--;
02578
02579 mActiveLanguageItem = index;
02580 setLanguageItemInformation( index );
02581 mRemoveButton->setEnabled( mLanguageList.count() > 1 );
02582 }
02583
02584 void ComposerPage::PhrasesTab::slotLanguageChanged( const QString& )
02585 {
02586 int index = mPhraseLanguageCombo->currentItem();
02587 assert( index < (int)mLanguageList.count() );
02588 saveActiveLanguageItem();
02589 mActiveLanguageItem = index;
02590 setLanguageItemInformation( index );
02591 }
02592
02593
02594 void ComposerPage::PhrasesTab::setup() {
02595 KConfigGroup general( KMKernel::config(), "General" );
02596
02597 mLanguageList.clear();
02598 mPhraseLanguageCombo->clear();
02599 mActiveLanguageItem = -1;
02600
02601 int num = general.readNumEntry( "reply-languages", 0 );
02602 int currentNr = general.readNumEntry( "reply-current-language" ,0 );
02603
02604
02605 for ( int i = 0 ; i < num ; i++ ) {
02606 KConfigGroup config( KMKernel::config(),
02607 QCString("KMMessage #") + QCString().setNum(i) );
02608 QString lang = config.readEntry( "language" );
02609 mLanguageList.append(
02610 LanguageItem( lang,
02611 config.readEntry( "phrase-reply" ),
02612 config.readEntry( "phrase-reply-all" ),
02613 config.readEntry( "phrase-forward" ),
02614 config.readEntry( "indent-prefix" ) ) );
02615 mPhraseLanguageCombo->insertLanguage( lang );
02616 }
02617
02618 if ( num == 0 )
02619 slotAddNewLanguage( KGlobal::locale()->language() );
02620
02621 if ( currentNr >= num || currentNr < 0 )
02622 currentNr = 0;
02623
02624 mPhraseLanguageCombo->setCurrentItem( currentNr );
02625 mActiveLanguageItem = currentNr;
02626 setLanguageItemInformation( currentNr );
02627 mRemoveButton->setEnabled( mLanguageList.count() > 1 );
02628 }
02629
02630 void ComposerPage::PhrasesTab::apply() {
02631 KConfigGroup general( KMKernel::config(), "General" );
02632
02633 general.writeEntry( "reply-languages", mLanguageList.count() );
02634 general.writeEntry( "reply-current-language", mPhraseLanguageCombo->currentItem() );
02635
02636 saveActiveLanguageItem();
02637 LanguageItemList::Iterator it = mLanguageList.begin();
02638 for ( int i = 0 ; it != mLanguageList.end() ; ++it, ++i ) {
02639 KConfigGroup config( KMKernel::config(),
02640 QCString("KMMessage #") + QCString().setNum(i) );
02641 config.writeEntry( "language", (*it).mLanguage );
02642 config.writeEntry( "phrase-reply", (*it).mReply );
02643 config.writeEntry( "phrase-reply-all", (*it).mReplyAll );
02644 config.writeEntry( "phrase-forward", (*it).mForward );
02645 config.writeEntry( "indent-prefix", (*it).mIndentPrefix );
02646 }
02647 }
02648
02649
02650
02651 QString ComposerPage::SubjectTab::title() {
02652 return i18n("&Subject");
02653 }
02654
02655 QString ComposerPage::SubjectTab::helpAnchor() const {
02656 return QString::fromLatin1("configure-composer-subject");
02657 }
02658
02659 ComposerPageSubjectTab::ComposerPageSubjectTab( QWidget * parent, const char * name )
02660 : ConfigurationPage( parent, name )
02661 {
02662
02663 QVBoxLayout *vlay;
02664 QGroupBox *group;
02665 QLabel *label;
02666
02667
02668 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
02669
02670 group = new QVGroupBox( i18n("Repl&y Subject Prefixes"), this );
02671 group->layout()->setSpacing( KDialog::spacingHint() );
02672
02673
02674 label = new QLabel( i18n("Recognize any sequence of the following prefixes\n"
02675 "(entries are case-insensitive regular expressions):"), group );
02676 label->setAlignment( AlignLeft|WordBreak );
02677
02678
02679 SimpleStringListEditor::ButtonCode buttonCode =
02680 static_cast<SimpleStringListEditor::ButtonCode>( SimpleStringListEditor::Add | SimpleStringListEditor::Remove | SimpleStringListEditor::Modify );
02681 mReplyListEditor =
02682 new SimpleStringListEditor( group, 0, buttonCode,
02683 i18n("A&dd..."), i18n("Re&move"),
02684 i18n("Mod&ify..."),
02685 i18n("Enter new reply prefix:") );
02686
02687
02688 mReplaceReplyPrefixCheck =
02689 new QCheckBox( i18n("Replace recognized prefi&x with \"Re:\""), group );
02690
02691 vlay->addWidget( group );
02692
02693
02694 group = new QVGroupBox( i18n("For&ward Subject Prefixes"), this );
02695 group->layout()->setSpacing( KDialog::marginHint() );
02696
02697
02698 label= new QLabel( i18n("Recognize any sequence of the following prefixes\n"
02699 "(entries are case-insensitive regular expressions):"), group );
02700 label->setAlignment( AlignLeft|WordBreak );
02701
02702
02703 mForwardListEditor =
02704 new SimpleStringListEditor( group, 0, buttonCode,
02705 i18n("Add..."),
02706 i18n("Remo&ve"),
02707 i18n("Modify..."),
02708 i18n("Enter new forward prefix:") );
02709
02710
02711 mReplaceForwardPrefixCheck =
02712 new QCheckBox( i18n("Replace recognized prefix with \"&Fwd:\""), group );
02713
02714 vlay->addWidget( group );
02715 }
02716
02717 void ComposerPage::SubjectTab::setup() {
02718 KConfigGroup composer( KMKernel::config(), "Composer" );
02719
02720 QStringList prefixList = composer.readListEntry( "reply-prefixes", ',' );
02721 if ( prefixList.isEmpty() )
02722 prefixList << QString::fromLatin1("Re\\s*:")
02723 << QString::fromLatin1("Re\\[\\d+\\]:")
02724 << QString::fromLatin1("Re\\d+:");
02725 mReplyListEditor->setStringList( prefixList );
02726
02727 mReplaceReplyPrefixCheck->setChecked( composer.readBoolEntry("replace-reply-prefix", true ) );
02728
02729 prefixList = composer.readListEntry( "forward-prefixes", ',' );
02730 if ( prefixList.isEmpty() )
02731 prefixList << QString::fromLatin1("Fwd:")
02732 << QString::fromLatin1("FW:");
02733 mForwardListEditor->setStringList( prefixList );
02734
02735 mReplaceForwardPrefixCheck->setChecked( composer.readBoolEntry( "replace-forward-prefix", true ) );
02736 }
02737
02738 void ComposerPage::SubjectTab::apply() {
02739 KConfigGroup composer( KMKernel::config(), "Composer" );
02740
02741
02742 composer.writeEntry( "reply-prefixes", mReplyListEditor->stringList() );
02743 composer.writeEntry( "forward-prefixes", mForwardListEditor->stringList() );
02744 composer.writeEntry( "replace-reply-prefix",
02745 mReplaceReplyPrefixCheck->isChecked() );
02746 composer.writeEntry( "replace-forward-prefix",
02747 mReplaceForwardPrefixCheck->isChecked() );
02748 }
02749
02750
02751
02752 QString ComposerPage::CharsetTab::title() {
02753 return i18n("Cha&rset");
02754 }
02755
02756 QString ComposerPage::CharsetTab::helpAnchor() const {
02757 return QString::fromLatin1("configure-composer-charset");
02758 }
02759
02760 ComposerPageCharsetTab::ComposerPageCharsetTab( QWidget * parent, const char * name )
02761 : ConfigurationPage( parent, name )
02762 {
02763
02764 QVBoxLayout *vlay;
02765 QLabel *label;
02766
02767 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
02768
02769 label = new QLabel( i18n("This list is checked for every outgoing message "
02770 "from the top to the bottom for a charset that "
02771 "contains all required characters."), this );
02772 label->setAlignment( WordBreak);
02773 vlay->addWidget( label );
02774
02775 mCharsetListEditor =
02776 new SimpleStringListEditor( this, 0, SimpleStringListEditor::All,
02777 i18n("A&dd..."), i18n("Remo&ve"),
02778 i18n("&Modify"), i18n("Enter charset:") );
02779 vlay->addWidget( mCharsetListEditor, 1 );
02780
02781 mKeepReplyCharsetCheck = new QCheckBox( i18n("&Keep original charset when "
02782 "replying or forwarding (if "
02783 "possible)."), this );
02784 vlay->addWidget( mKeepReplyCharsetCheck );
02785
02786 connect( mCharsetListEditor, SIGNAL(aboutToAdd(QString&)),
02787 this, SLOT(slotVerifyCharset(QString&)) );
02788 }
02789
02790 void ComposerPage::CharsetTab::slotVerifyCharset( QString & charset ) {
02791 if ( charset.isEmpty() ) return;
02792
02793
02794
02795 if ( charset.lower() == QString::fromLatin1("us-ascii") ) {
02796 charset = QString::fromLatin1("us-ascii");
02797 return;
02798 }
02799
02800 if ( charset.lower() == QString::fromLatin1("locale") ) {
02801 charset = QString::fromLatin1("%1 (locale)")
02802 .arg( QCString( kmkernel->networkCodec()->mimeName() ).lower() );
02803 return;
02804 }
02805
02806 bool ok = false;
02807 QTextCodec *codec = KGlobal::charsets()->codecForName( charset, ok );
02808 if ( ok && codec ) {
02809 charset = QString::fromLatin1( codec->mimeName() ).lower();
02810 return;
02811 }
02812
02813 KMessageBox::sorry( this, i18n("This charset is not supported.") );
02814 charset = QString::null;
02815 }
02816
02817 void ComposerPage::CharsetTab::setup() {
02818 KConfigGroup composer( KMKernel::config(), "Composer" );
02819
02820 QStringList charsets = composer.readListEntry( "pref-charsets" );
02821 for ( QStringList::Iterator it = charsets.begin() ;
02822 it != charsets.end() ; ++it )
02823 if ( (*it) == QString::fromLatin1("locale") )
02824 (*it) = QString("%1 (locale)")
02825 .arg( QCString( kmkernel->networkCodec()->mimeName() ).lower() );
02826
02827 mCharsetListEditor->setStringList( charsets );
02828 mKeepReplyCharsetCheck->setChecked( !composer.readBoolEntry( "force-reply-charset", false ) );
02829 }
02830
02831 void ComposerPage::CharsetTab::apply() {
02832 KConfigGroup composer( KMKernel::config(), "Composer" );
02833
02834 QStringList charsetList = mCharsetListEditor->stringList();
02835 QStringList::Iterator it = charsetList.begin();
02836 for ( ; it != charsetList.end() ; ++it )
02837 if ( (*it).endsWith("(locale)") )
02838 (*it) = "locale";
02839 composer.writeEntry( "pref-charsets", charsetList );
02840 composer.writeEntry( "force-reply-charset",
02841 !mKeepReplyCharsetCheck->isChecked() );
02842 }
02843
02844
02845 QString ComposerPage::HeadersTab::title() {
02846 return i18n("H&eaders");
02847 }
02848
02849 QString ComposerPage::HeadersTab::helpAnchor() const {
02850 return QString::fromLatin1("configure-composer-headers");
02851 }
02852
02853 ComposerPageHeadersTab::ComposerPageHeadersTab( QWidget * parent, const char * name )
02854 : ConfigurationPage( parent, name )
02855 {
02856
02857 QVBoxLayout *vlay;
02858 QHBoxLayout *hlay;
02859 QGridLayout *glay;
02860 QLabel *label;
02861 QPushButton *button;
02862
02863 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
02864
02865
02866 mCreateOwnMessageIdCheck =
02867 new QCheckBox( i18n("&Use custom message-id suffix"), this );
02868 vlay->addWidget( mCreateOwnMessageIdCheck );
02869
02870
02871 hlay = new QHBoxLayout( vlay );
02872 mMessageIdSuffixEdit = new KLineEdit( this );
02873
02874 mMessageIdSuffixValidator =
02875 new QRegExpValidator( QRegExp( "[a-zA-Z0-9+-]+(?:\\.[a-zA-Z0-9+-]+)*" ), this );
02876 mMessageIdSuffixEdit->setValidator( mMessageIdSuffixValidator );
02877 label = new QLabel( mMessageIdSuffixEdit,
02878 i18n("Custom message-&id suffix:"), this );
02879 label->setEnabled( false );
02880 mMessageIdSuffixEdit->setEnabled( false );
02881 hlay->addWidget( label );
02882 hlay->addWidget( mMessageIdSuffixEdit, 1 );
02883 connect( mCreateOwnMessageIdCheck, SIGNAL(toggled(bool) ),
02884 label, SLOT(setEnabled(bool)) );
02885 connect( mCreateOwnMessageIdCheck, SIGNAL(toggled(bool) ),
02886 mMessageIdSuffixEdit, SLOT(setEnabled(bool)) );
02887
02888
02889 vlay->addWidget( new KSeparator( KSeparator::HLine, this ) );
02890 vlay->addWidget( new QLabel( i18n("Define custom mime header fields:"), this) );
02891
02892
02893 glay = new QGridLayout( vlay, 5, 3 );
02894 glay->setRowStretch( 2, 1 );
02895 glay->setColStretch( 1, 1 );
02896 mTagList = new ListView( this, "tagList" );
02897 mTagList->addColumn( i18n("Name") );
02898 mTagList->addColumn( i18n("Value") );
02899 mTagList->setAllColumnsShowFocus( true );
02900 mTagList->setFrameStyle( QFrame::WinPanel | QFrame::Sunken );
02901 mTagList->setSorting( -1 );
02902 connect( mTagList, SIGNAL(selectionChanged()),
02903 this, SLOT(slotMimeHeaderSelectionChanged()) );
02904 glay->addMultiCellWidget( mTagList, 0, 2, 0, 1 );
02905
02906
02907 button = new QPushButton( i18n("Ne&w"), this );
02908 connect( button, SIGNAL(clicked()), this, SLOT(slotNewMimeHeader()) );
02909 button->setAutoDefault( false );
02910 glay->addWidget( button, 0, 2 );
02911 mRemoveHeaderButton = new QPushButton( i18n("Re&move"), this );
02912 connect( mRemoveHeaderButton, SIGNAL(clicked()),
02913 this, SLOT(slotRemoveMimeHeader()) );
02914 button->setAutoDefault( false );
02915 glay->addWidget( mRemoveHeaderButton, 1, 2 );
02916
02917
02918 mTagNameEdit = new KLineEdit( this );
02919 mTagNameEdit->setEnabled( false );
02920 mTagNameLabel = new QLabel( mTagNameEdit, i18n("&Name:"), this );
02921 mTagNameLabel->setEnabled( false );
02922 glay->addWidget( mTagNameLabel, 3, 0 );
02923 glay->addWidget( mTagNameEdit, 3, 1 );
02924 connect( mTagNameEdit, SIGNAL(textChanged(const QString&)),
02925 this, SLOT(slotMimeHeaderNameChanged(const QString&)) );
02926
02927 mTagValueEdit = new KLineEdit( this );
02928 mTagValueEdit->setEnabled( false );
02929 mTagValueLabel = new QLabel( mTagValueEdit, i18n("&Value:"), this );
02930 mTagValueLabel->setEnabled( false );
02931 glay->addWidget( mTagValueLabel, 4, 0 );
02932 glay->addWidget( mTagValueEdit, 4, 1 );
02933 connect( mTagValueEdit, SIGNAL(textChanged(const QString&)),
02934 this, SLOT(slotMimeHeaderValueChanged(const QString&)) );
02935 }
02936
02937 void ComposerPage::HeadersTab::slotMimeHeaderSelectionChanged()
02938 {
02939 QListViewItem * item = mTagList->selectedItem();
02940
02941 if ( item ) {
02942 mTagNameEdit->setText( item->text( 0 ) );
02943 mTagValueEdit->setText( item->text( 1 ) );
02944 } else {
02945 mTagNameEdit->clear();
02946 mTagValueEdit->clear();
02947 }
02948 mRemoveHeaderButton->setEnabled( item );
02949 mTagNameEdit->setEnabled( item );
02950 mTagValueEdit->setEnabled( item );
02951 mTagNameLabel->setEnabled( item );
02952 mTagValueLabel->setEnabled( item );
02953 }
02954
02955
02956 void ComposerPage::HeadersTab::slotMimeHeaderNameChanged( const QString & text ) {
02957
02958
02959 QListViewItem * item = mTagList->selectedItem();
02960 if ( item )
02961 item->setText( 0, text );
02962 }
02963
02964
02965 void ComposerPage::HeadersTab::slotMimeHeaderValueChanged( const QString & text ) {
02966
02967
02968 QListViewItem * item = mTagList->selectedItem();
02969 if ( item )
02970 item->setText( 1, text );
02971 }
02972
02973
02974 void ComposerPage::HeadersTab::slotNewMimeHeader()
02975 {
02976 QListViewItem *listItem = new QListViewItem( mTagList );
02977 mTagList->setCurrentItem( listItem );
02978 mTagList->setSelected( listItem, true );
02979 }
02980
02981
02982 void ComposerPage::HeadersTab::slotRemoveMimeHeader()
02983 {
02984
02985 QListViewItem * item = mTagList->selectedItem();
02986 if ( !item ) {
02987 kdDebug(5006) << "==================================================\n"
02988 << "Error: Remove button was pressed although no custom header was selected\n"
02989 << "==================================================\n";
02990 return;
02991 }
02992
02993 QListViewItem * below = item->nextSibling();
02994 delete item;
02995
02996 if ( below )
02997 mTagList->setSelected( below, true );
02998 else if ( mTagList->lastItem() )
02999 mTagList->setSelected( mTagList->lastItem(), true );
03000 }
03001
03002 void ComposerPage::HeadersTab::setup() {
03003 KConfigGroup general( KMKernel::config(), "General" );
03004
03005 QString suffix = general.readEntry( "myMessageIdSuffix" );
03006 mMessageIdSuffixEdit->setText( suffix );
03007 bool state = ( !suffix.isEmpty() &&
03008 general.readBoolEntry( "useCustomMessageIdSuffix", false ) );
03009 mCreateOwnMessageIdCheck->setChecked( state );
03010
03011 mTagList->clear();
03012 mTagNameEdit->clear();
03013 mTagValueEdit->clear();
03014
03015 QListViewItem * item = 0;
03016
03017 int count = general.readNumEntry( "mime-header-count", 0 );
03018 for( int i = 0 ; i < count ; i++ ) {
03019 KConfigGroup config( KMKernel::config(),
03020 QCString("Mime #") + QCString().setNum(i) );
03021 QString name = config.readEntry( "name" );
03022 QString value = config.readEntry( "value" );
03023 if( !name.isEmpty() )
03024 item = new QListViewItem( mTagList, item, name, value );
03025 }
03026 if ( mTagList->childCount() ) {
03027 mTagList->setCurrentItem( mTagList->firstChild() );
03028 mTagList->setSelected( mTagList->firstChild(), true );
03029 }
03030 else {
03031
03032 mRemoveHeaderButton->setEnabled( false );
03033 }
03034 }
03035
03036 void ComposerPage::HeadersTab::apply() {
03037 KConfigGroup general( KMKernel::config(), "General" );
03038
03039 general.writeEntry( "useCustomMessageIdSuffix",
03040 mCreateOwnMessageIdCheck->isChecked() );
03041 general.writeEntry( "myMessageIdSuffix",
03042 mMessageIdSuffixEdit->text() );
03043
03044 int numValidEntries = 0;
03045 QListViewItem * item = mTagList->firstChild();
03046 for ( ; item ; item = item->itemBelow() )
03047 if( !item->text(0).isEmpty() ) {
03048 KConfigGroup config( KMKernel::config(), QCString("Mime #")
03049 + QCString().setNum( numValidEntries ) );
03050 config.writeEntry( "name", item->text( 0 ) );
03051 config.writeEntry( "value", item->text( 1 ) );
03052 numValidEntries++;
03053 }
03054 general.writeEntry( "mime-header-count", numValidEntries );
03055 }
03056
03057 QString ComposerPage::AttachmentsTab::title() {
03058 return i18n("Config->Composer->Attachments", "A&ttachments");
03059 }
03060
03061 QString ComposerPage::AttachmentsTab::helpAnchor() const {
03062 return QString::fromLatin1("configure-composer-attachments");
03063 }
03064
03065 ComposerPageAttachmentsTab::ComposerPageAttachmentsTab( QWidget * parent,
03066 const char * name )
03067 : ConfigurationPage( parent, name ) {
03068
03069 QVBoxLayout *vlay;
03070 QLabel *label;
03071
03072 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
03073
03074
03075 mMissingAttachmentDetectionCheck =
03076 new QCheckBox( i18n("E&nable detection of missing attachments"), this );
03077 mMissingAttachmentDetectionCheck->setChecked( true );
03078 vlay->addWidget( mMissingAttachmentDetectionCheck );
03079
03080
03081 label = new QLabel( i18n("Recognize any of the following key words as "
03082 "intention to attach a file:"), this );
03083 label->setAlignment( AlignLeft|WordBreak );
03084 vlay->addWidget( label );
03085
03086 SimpleStringListEditor::ButtonCode buttonCode =
03087 static_cast<SimpleStringListEditor::ButtonCode>( SimpleStringListEditor::Add | SimpleStringListEditor::Remove | SimpleStringListEditor::Modify );
03088 mAttachWordsListEditor =
03089 new SimpleStringListEditor( this, 0, buttonCode,
03090 i18n("A&dd..."), i18n("Re&move"),
03091 i18n("Mod&ify..."),
03092 i18n("Enter new key word:") );
03093 vlay->addWidget( mAttachWordsListEditor );
03094
03095 connect( mMissingAttachmentDetectionCheck, SIGNAL(toggled(bool) ),
03096 label, SLOT(setEnabled(bool)) );
03097 connect( mMissingAttachmentDetectionCheck, SIGNAL(toggled(bool) ),
03098 mAttachWordsListEditor, SLOT(setEnabled(bool)) );
03099 }
03100
03101 void ComposerPage::AttachmentsTab::setup() {
03102 KConfigGroup composer( KMKernel::config(), "Composer" );
03103
03104 mMissingAttachmentDetectionCheck->setChecked(
03105 composer.readBoolEntry( "showForgottenAttachmentWarning", true ) );
03106 QStringList attachWordsList =
03107 composer.readListEntry( "attachment-keywords" );
03108 if ( attachWordsList.isEmpty() ) {
03109
03110 attachWordsList << QString::fromLatin1("attachment")
03111 << QString::fromLatin1("attached");
03112 if ( QString::fromLatin1("attachment") != i18n("attachment") )
03113 attachWordsList << i18n("attachment");
03114 if ( QString::fromLatin1("attached") != i18n("attached") )
03115 attachWordsList << i18n("attached");
03116 }
03117
03118 mAttachWordsListEditor->setStringList( attachWordsList );
03119 }
03120
03121 void ComposerPage::AttachmentsTab::apply() {
03122 KConfigGroup composer( KMKernel::config(), "Composer" );
03123 composer.writeEntry( "showForgottenAttachmentWarning",
03124 mMissingAttachmentDetectionCheck->isChecked() );
03125 composer.writeEntry( "attachment-keywords",
03126 mAttachWordsListEditor->stringList() );
03127 }
03128
03129
03130
03131
03132
03133
03134
03135
03136
03137
03138 QString SecurityPage::iconLabel() {
03139 return i18n("Security");
03140 }
03141
03142 const char * SecurityPage::iconName() {
03143 return "encrypted";
03144 }
03145
03146 QString SecurityPage::title() {
03147 return i18n("Security & Privacy Settings");
03148 }
03149
03150 QString SecurityPage::helpAnchor() const {
03151 return QString::fromLatin1("configure-security");
03152 }
03153
03154 SecurityPage::SecurityPage( QWidget * parent, const char * name )
03155 : TabbedConfigurationPage( parent, name )
03156 {
03157
03158
03159
03160 mGeneralTab = new GeneralTab();
03161 addTab( mGeneralTab, mGeneralTab->title() );
03162
03163
03164
03165
03166 mOpenPgpTab = new OpenPgpTab();
03167 addTab( mOpenPgpTab, mOpenPgpTab->title() );
03168
03169
03170
03171
03172 mCryptPlugTab = new CryptPlugTab();
03173 addTab( mCryptPlugTab, mCryptPlugTab->title() );
03174 }
03175
03176 void SecurityPage::setup() {
03177 mGeneralTab->setup();
03178 mOpenPgpTab->setup();
03179 mCryptPlugTab->setup();
03180 }
03181
03182 void SecurityPage::installProfile( KConfig * profile ) {
03183 mGeneralTab->installProfile( profile );
03184 mOpenPgpTab->installProfile( profile );
03185 }
03186
03187 void SecurityPage::apply() {
03188 mGeneralTab->apply();
03189 mOpenPgpTab->apply();
03190 mCryptPlugTab->apply();
03191 }
03192
03193 void SecurityPage::dismiss() {
03194 mCryptPlugTab->dismiss();
03195 }
03196
03197 QString SecurityPage::GeneralTab::title() {
03198 return i18n("&General");
03199 }
03200
03201 QString SecurityPage::GeneralTab::helpAnchor() const {
03202 return QString::fromLatin1("configure-security-general");
03203 }
03204
03205 SecurityPageGeneralTab::SecurityPageGeneralTab( QWidget * parent, const char * name )
03206 : ConfigurationPage ( parent, name )
03207 {
03208
03209 QVBoxLayout *vlay;
03210 QHBox *hbox;
03211 QGroupBox *group;
03212 QRadioButton *radio;
03213 KActiveLabel *label;
03214 QWidget *w;
03215 QString msg;
03216
03217 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
03218
03219
03220 QString htmlWhatsThis = i18n( "<qt><p>Messages sometimes come in both formats. "
03221 "This option controls whether you want the HTML part or the plain "
03222 "text part to be displayed.</p>"
03223 "<p>Displaying the HTML part makes the message look better, "
03224 "but at the same time increases the risk of security holes "
03225 "being exploited.</p>"
03226 "<p>Displaying the plain text part loses much of the message's "
03227 "formatting, but makes it almost <em>impossible</em> "
03228 "to exploit security holes in the HTML renderer (Konqueror).</p>"
03229 "<p>The option below guards against one common misuse of HTML "
03230 "messages, but it cannot guard against security issues that were "
03231 "not known at the time this version of KMail was written.</p>"
03232 "<p>It is therefore advisable to <em>not</em> prefer HTML to "
03233 "plain text.</p>"
03234 "<p><b>Note:</b> You can set this option on a per-folder basis "
03235 "from the <i>Folder</i> menu of KMail's main window.</p></qt>" );
03236
03237 QString externalWhatsThis = i18n( "<qt><p>Some mail advertisements are in HTML "
03238 "and contain references to, for example, images that the advertisers"
03239 " employ to find out that you have read their message "
03240 "("web bugs").</p>"
03241 "<p>There is no valid reason to load images off the Internet like "
03242 "this, since the sender can always attach the required images "
03243 "directly to the message.</p>"
03244 "<p>To guard from such a misuse of the HTML displaying feature "
03245 "of KMail, this option is <em>disabled</em> by default.</p>"
03246 "<p>However, if you wish to, for example, view images in HTML "
03247 "messages that were not attached to it, you can enable this "
03248 "option, but you should be aware of the possible problem.</p></qt>" );
03249
03250 QString confirmationWhatsThis = i18n( "<qt><p>This option enables the "
03251 "<em>unconditional</em> sending of delivery- and read confirmations "
03252 "("receipts").</p>"
03253 "<p>Returning these confirmations (so-called <em>receipts</em>) "
03254 "makes it easy for the sender to track whether and - more "
03255 "importantly - <em>when</em> you read his/her message.</p>"
03256 "<p>You can return <em>delivery</em> confirmations in a "
03257 "fine-grained manner using the "confirm delivery" filter "
03258 "action. We advise against issuing <em>read</em> confirmations "
03259 "at all.</p></qt>");
03260
03261 QString receiptWhatsThis = i18n( "<qt><h3>Message Disposition "
03262 "Notification Policy</h3>"
03263 "<p>MDNs are a generalization of what is commonly called <b>read "
03264 "receipt</b>. The message author requests a disposition "
03265 "notification to be sent and the receiver's mail program "
03266 "generates a reply from which the author can learn what "
03267 "happened to his message. Common disposition types include "
03268 "<b>displayed</b> (i.e. read), <b>deleted</b> and <b>dispatched</b> "
03269 "(e.g. forwarded).</p>"
03270 "<p>The following options are available to control KMail's "
03271 "sending of MDNs:</p>"
03272 "<ul>"
03273 "<li><em>Ignore</em>: Ignores any request for disposition "
03274 "notifications. No MDN will ever be sent automatically "
03275 "(recommended).</li>"
03276 "<li><em>Ask</em>: Answers requests only after asking the user "
03277 "for permission. This way, you can send MDNs for selected "
03278 "messages while denying or ignoring them for others.</li>"
03279 "<li><em>Deny</em>: Always sends a <b>denied</b> notification. This "
03280 "is only <em>slightly</em> better than always sending MDNs. "
03281 "The author will still know that the messages has been acted "
03282 "upon, he just cannot tell whether it was deleted or read etc.</li>"
03283 "<li><em>Always send</em>: Always sends the requested "
03284 "disposition notification. That means that the author of the "
03285 "message gets to know when the message was acted upon and, "
03286 "in addition, what happened to it (displayed, deleted, "
03287 "etc.). This option is strongly discouraged, but since it "
03288 "makes much sense e.g. for customer relationship management, "
03289 "it has been made available.</li>"
03290 "</ul></qt>" );
03291
03292
03293
03294 group = new QVGroupBox( i18n( "HTML Messages" ), this );
03295 group->layout()->setSpacing( KDialog::spacingHint() );
03296
03297 mHtmlMailCheck = new QCheckBox( i18n("Prefer H&TML to plain text"), group );
03298 QWhatsThis::add( mHtmlMailCheck, htmlWhatsThis );
03299 mExternalReferences = new QCheckBox( i18n("Allow messages to load e&xternal "
03300 "references from the Internet" ), group );
03301 QWhatsThis::add( mExternalReferences, externalWhatsThis );
03302 label = new KActiveLabel( i18n("<b>WARNING:</b> Allowing HTML in email may "
03303 "increase the risk that your system will be "
03304 "compromised by present and anticipated security "
03305 "exploits. <a href=\"whatsthis:%1\">More about "
03306 "HTML mails...</a> <a href=\"whatsthis:%2\">More "
03307 "about external references...</a>")
03308 .arg(htmlWhatsThis).arg(externalWhatsThis),
03309 group );
03310
03311 vlay->addWidget( group );
03312
03313
03314 group = new QVGroupBox( i18n( "Delivery Confirmations" ), this );
03315 group->layout()->setSpacing( KDialog::spacingHint() );
03316
03317 mSendReceivedReceiptCheck = new QCheckBox( i18n("Automatically &send delivery confirmations"), group );
03318 QWhatsThis::add( mSendReceivedReceiptCheck, confirmationWhatsThis );
03319
03320 label = new KActiveLabel( i18n( "<b>WARNING:</b> Unconditionally returning "
03321 "confirmations undermines your privacy. "
03322 "<a href=\"whatsthis:%1\">More...</a>")
03323 .arg(confirmationWhatsThis),
03324 group );
03325
03326 vlay->addWidget( group );
03327
03328
03329 group = new QVGroupBox( i18n("Message Disposition Notifications"), this );
03330 group->layout()->setSpacing( KDialog::spacingHint() );
03331
03332
03333
03334 mMDNGroup = new QButtonGroup( group );
03335 mMDNGroup->hide();
03336
03337 hbox = new QHBox( group );
03338 hbox->setSpacing( KDialog::spacingHint() );
03339
03340 (void)new QLabel( i18n("Send policy:"), hbox );
03341
03342 radio = new QRadioButton( i18n("&Ignore"), hbox );
03343 mMDNGroup->insert( radio );
03344
03345 radio = new QRadioButton( i18n("As&k"), hbox );
03346 mMDNGroup->insert( radio );
03347
03348 radio = new QRadioButton( i18n("&Deny"), hbox );
03349 mMDNGroup->insert( radio );
03350
03351 radio = new QRadioButton( i18n("Al&ways send"), hbox );
03352 mMDNGroup->insert( radio );
03353
03354 for ( int i = 0 ; i < mMDNGroup->count() ; ++i )
03355 QWhatsThis::add( mMDNGroup->find( i ), receiptWhatsThis );
03356
03357 w = new QWidget( hbox );
03358 hbox->setStretchFactor( w, 1 );
03359
03360
03361 mOrigQuoteGroup = new QButtonGroup( group );
03362 mOrigQuoteGroup->hide();
03363
03364 hbox = new QHBox( group );
03365 hbox->setSpacing( KDialog::spacingHint() );
03366
03367 (void)new QLabel( i18n("Quote original message:"), hbox );
03368
03369 radio = new QRadioButton( i18n("Nothin&g"), hbox );
03370 mOrigQuoteGroup->insert( radio );
03371
03372 radio = new QRadioButton( i18n("&Full message"), hbox );
03373 mOrigQuoteGroup->insert( radio );
03374
03375 radio = new QRadioButton( i18n("Onl&y headers"), hbox );
03376 mOrigQuoteGroup->insert( radio );
03377
03378 w = new QWidget( hbox );
03379 hbox->setStretchFactor( w, 1 );
03380
03381
03382 label = new KActiveLabel( i18n("<b>WARNING:</b> Unconditionally returning "
03383 "confirmations undermines your privacy. "
03384 "<a href=\"whatsthis:%1\">More...</a>")
03385 .arg(receiptWhatsThis),
03386 group );
03387
03388 vlay->addWidget( group );
03389 vlay->addStretch( 10 );
03390 }
03391
03392 void SecurityPage::GeneralTab::setup() {
03393 KConfigGroup general( KMKernel::config(), "General" );
03394 KConfigGroup reader( KMKernel::config(), "Reader" );
03395
03396 KConfigGroup mdn( KMKernel::config(), "MDN" );
03397
03398 mHtmlMailCheck->setChecked( reader.readBoolEntry( "htmlMail", false ) );
03399 mExternalReferences->setChecked( reader.readBoolEntry( "htmlLoadExternal", false ) );
03400 mSendReceivedReceiptCheck->setChecked( general.readBoolEntry( "send-receipts", false ) );
03401 int num = mdn.readNumEntry( "default-policy", 0 );
03402 if ( num < 0 || num >= mMDNGroup->count() ) num = 0;
03403 mMDNGroup->setButton( num );
03404 num = mdn.readNumEntry( "quote-message", 0 );
03405 if ( num < 0 || num >= mOrigQuoteGroup->count() ) num = 0;
03406 mOrigQuoteGroup->setButton( num );
03407 }
03408
03409 void SecurityPage::GeneralTab::installProfile( KConfig * profile ) {
03410 KConfigGroup general( profile, "General" );
03411 KConfigGroup reader( profile, "Reader" );
03412 KConfigGroup mdn( profile, "MDN" );
03413
03414 if ( reader.hasKey( "htmlMail" ) )
03415 mHtmlMailCheck->setChecked( reader.readBoolEntry( "htmlMail" ) );
03416 if ( reader.hasKey( "htmlLoadExternal" ) )
03417 mExternalReferences->setChecked( reader.readBoolEntry( "htmlLoadExternal" ) );
03418 if ( general.hasKey( "send-receipts" ) )
03419 mSendReceivedReceiptCheck->setChecked( general.readBoolEntry( "send-receipts" ) );
03420 if ( mdn.hasKey( "default-policy" ) ) {
03421 int num = mdn.readNumEntry( "default-policy" );
03422 if ( num < 0 || num >= mMDNGroup->count() ) num = 0;
03423 mMDNGroup->setButton( num );
03424 }
03425 if ( mdn.hasKey( "quote-message" ) ) {
03426 int num = mdn.readNumEntry( "quote-message" );
03427 if ( num < 0 || num >= mOrigQuoteGroup->count() ) num = 0;
03428 mOrigQuoteGroup->setButton( num );
03429 }
03430 }
03431
03432 void SecurityPage::GeneralTab::apply() {
03433 KConfigGroup general( KMKernel::config(), "General" );
03434 KConfigGroup reader( KMKernel::config(), "Reader" );
03435 KConfigGroup mdn( KMKernel::config(), "MDN" );
03436
03437 if (reader.readBoolEntry( "htmlMail", false ) != mHtmlMailCheck->isChecked())
03438 {
03439 if (KMessageBox::warningContinueCancel(this, i18n("Changing the global "
03440 "HTML setting will override all folder specific values."), QString::null,
03441 QString::null, "htmlMailOverride") == KMessageBox::Continue)
03442 {
03443 reader.writeEntry( "htmlMail", mHtmlMailCheck->isChecked() );
03444 QStringList names;
03445 QValueList<QGuardedPtr<KMFolder> > folders;
03446 kmkernel->folderMgr()->createFolderList(&names, &folders);
03447 kmkernel->imapFolderMgr()->createFolderList(&names, &folders);
03448 kmkernel->dimapFolderMgr()->createFolderList(&names, &folders);
03449 kmkernel->searchFolderMgr()->createFolderList(&names, &folders);
03450 for (QValueList<QGuardedPtr<KMFolder> >::iterator it = folders.begin();
03451 it != folders.end(); ++it)
03452 {
03453 if (*it)
03454 {
03455 KConfigGroupSaver saver(KMKernel::config(),
03456 "Folder-" + (*it)->idString());
03457 KMKernel::config()->writeEntry("htmlMailOverride", false);
03458 }
03459 }
03460 }
03461 }
03462 reader.writeEntry( "htmlLoadExternal", mExternalReferences->isChecked() );
03463 general.writeEntry( "send-receipts", mSendReceivedReceiptCheck->isChecked() );
03464 mdn.writeEntry( "default-policy", mMDNGroup->id( mMDNGroup->selected() ) );
03465 mdn.writeEntry( "quote-message", mOrigQuoteGroup->id( mOrigQuoteGroup->selected() ) );
03466 }
03467
03468
03469 QString SecurityPage::OpenPgpTab::title() {
03470 return i18n("Open&PGP");
03471 }
03472
03473 QString SecurityPage::OpenPgpTab::helpAnchor() const {
03474 return QString::fromLatin1("configure-security-pgp");
03475 }
03476
03477 SecurityPageOpenPgpTab::SecurityPageOpenPgpTab( QWidget * parent, const char * name )
03478 : ConfigurationPage ( parent, name )
03479 {
03480
03481 QVBoxLayout *vlay;
03482 QGroupBox *group;
03483 QString msg;
03484
03485 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
03486
03487
03488 mPgpConfig = new Kpgp::Config( this );
03489 group = mPgpConfig->optionsGroupBox();
03490
03491
03492 mPgpAutoSignatureCheck =
03493 new QCheckBox( i18n("Automatically s&ign messages using OpenPGP"),
03494 group );
03495
03496 mPgpAutoEncryptCheck =
03497 new QCheckBox( i18n("Automatically encrypt messages &whenever possible"),
03498 group );
03499
03500 vlay->addWidget( mPgpConfig );
03501
03502 vlay->addStretch( 10 );
03503
03504
03505 msg = i18n( "<qt><p>When this option is enabled, all messages you send "
03506 "will be signed by default. Of course it's still possible to "
03507 "disable signing for each message individually.</p></qt>" );
03508 QWhatsThis::add( mPgpAutoSignatureCheck, msg );
03509
03510 msg = i18n( "<qt><p>When this option is enabled, every message you send "
03511 "will be encrypted whenever encryption is possible and desired. "
03512 "Of course it's still possible to disable the automatic "
03513 "encryption for each message individually.</p></qt>" );
03514 QWhatsThis::add( mPgpAutoEncryptCheck, msg );
03515 }
03516
03517 void SecurityPage::OpenPgpTab::setup() {
03518 KConfigGroup composer( KMKernel::config(), "Composer" );
03519
03520 mPgpConfig->setValues();
03521 mPgpAutoSignatureCheck->setChecked( composer.readBoolEntry( "pgp-auto-sign", false ) );
03522 mPgpAutoEncryptCheck->setChecked( composer.readBoolEntry( "pgp-auto-encrypt", false ) );
03523 }
03524
03525 void SecurityPage::OpenPgpTab::installProfile( KConfig * profile ) {
03526 KConfigGroup composer( profile, "Composer" );
03527
03528 if ( composer.hasKey( "pgp-auto-sign" ) )
03529 mPgpAutoSignatureCheck->setChecked( composer.readBoolEntry( "pgp-auto-sign" ) );
03530 if ( composer.hasKey( "pgp-auto-encrypt" ) )
03531 mPgpAutoEncryptCheck->setChecked( composer.readBoolEntry( "pgp-auto-encrypt" ) );
03532 }
03533
03534 void SecurityPage::OpenPgpTab::apply() {
03535 KConfigGroup composer( KMKernel::config(), "Composer" );
03536
03537 mPgpConfig->applySettings();
03538 composer.writeEntry( "pgp-auto-sign", mPgpAutoSignatureCheck->isChecked() );
03539 composer.writeEntry( "pgp-auto-encrypt", mPgpAutoEncryptCheck->isChecked() );
03540 }
03541
03542 QString SecurityPage::CryptPlugTab::title() {
03543 return i18n("Crypto Plugi&ns");
03544 }
03545
03546 QString SecurityPage::CryptPlugTab::helpAnchor() const {
03547 return QString::null;
03548 }
03549
03550 SecurityPageCryptPlugTab::SecurityPageCryptPlugTab( QWidget * parent, const char * name )
03551 : ConfigurationPage( parent, name )
03552 {
03553 mlistCryptoAdd = new CryptPlugWrapperList();
03554 mlistCryptoAdd->setAutoDelete( false );
03555
03556 QHBoxLayout * hlay = new QHBoxLayout( this, KDialog::marginHint(),
03557 KDialog::spacingHint() );
03558
03559
03560
03561
03562 int row = -1;
03563 QGridLayout * glay = new QGridLayout( hlay, 4, 2 );
03564 glay->setRowStretch( 0, 1 );
03565 glay->setColStretch( 1, 1 );
03566
03567
03568 ++row;
03569 mPlugList = new KListView( this, "mPlugList" );
03570 mPlugList->addColumn( i18n("Name") );
03571 mPlugList->addColumn( i18n("Location") );
03572 mPlugList->addColumn( i18n("Update URL") );
03573 mPlugList->addColumn( i18n("Active") );
03574 mPlugList->addColumn( i18n("Initialized" ) );
03575 mPlugList->setAllColumnsShowFocus( true );
03576 mPlugList->setSorting( -1 );
03577 mPlugList->header()->setClickEnabled( false );
03578 mPlugList->setFullWidth( true );
03579 glay->addMultiCellWidget( mPlugList, row, row, 0, 1 );
03580
03581 connect( mPlugList, SIGNAL(selectionChanged()),
03582 SLOT(slotPlugSelectionChanged()) );
03583
03584
03585 ++row;
03586 mNameEdit = new KLineEdit( this );
03587 mNameEdit->setEnabled( false );
03588 glay->addWidget( new QLabel( mNameEdit, i18n("Na&me:"), this ), row, 0 );
03589 glay->addWidget( mNameEdit, row, 1 );
03590
03591 connect( mNameEdit, SIGNAL(textChanged(const QString&)),
03592 SLOT(slotPlugNameChanged(const QString&)) );
03593
03594
03595 ++row;
03596 mLocationRequester = new KURLRequester( this );
03597 mLocationRequester->setEnabled( false );
03598 glay->addWidget( new QLabel( mLocationRequester, i18n("&Location:"), this ), row, 0 );
03599 glay->addWidget( mLocationRequester, row, 1 );
03600
03601 connect( mLocationRequester, SIGNAL(textChanged(const QString&)),
03602 SLOT(slotPlugLocationChanged(const QString&)) );
03603
03604
03605 ++row;
03606 mUpdateURLEdit = new KLineEdit( this );
03607 mUpdateURLEdit->setEnabled( false );
03608 glay->addWidget( new QLabel( mUpdateURLEdit, i18n("&Update URL:"), this ), row, 0 );
03609 glay->addWidget( mUpdateURLEdit, row, 1 );
03610
03611 connect( mUpdateURLEdit, SIGNAL(textChanged(const QString&)),
03612 SLOT(slotPlugUpdateURLChanged(const QString&)) );
03613
03614
03615
03616
03617 QVBoxLayout * vlay = new QVBoxLayout( hlay );
03618
03619
03620 mNewButton = new QPushButton( i18n("&New"), this );
03621 mNewButton->setAutoDefault( false );
03622 vlay->addWidget( mNewButton );
03623
03624 connect( mNewButton, SIGNAL(clicked()),
03625 SLOT(slotNewPlugIn()) );
03626
03627
03628 mRemoveButton = new QPushButton( i18n("&Remove"), this );
03629 mRemoveButton->setAutoDefault( false );
03630 vlay->addWidget( mRemoveButton );
03631
03632 connect( mRemoveButton, SIGNAL(clicked()),
03633 SLOT(slotDeletePlugIn()) );
03634
03635
03636 mActivateButton = new QPushButton( i18n("Ac&tivate"), this );
03637 mActivateButton->setAutoDefault( false );
03638 vlay->addWidget( mActivateButton );
03639
03640 connect( mActivateButton, SIGNAL(clicked()),
03641 SLOT(slotActivatePlugIn()) );
03642
03643
03644 mConfigureButton = new QPushButton( i18n("Confi&gure..."), this );
03645 mConfigureButton->setAutoDefault( false );
03646 vlay->addWidget( mConfigureButton );
03647
03648 connect( mConfigureButton, SIGNAL(clicked()),
03649 SLOT(slotConfigurePlugIn()) );
03650
03651 vlay->addStretch( 1 );
03652 }
03653
03654 SecurityPageCryptPlugTab::~SecurityPageCryptPlugTab()
03655 {
03656 delete mlistCryptoAdd;
03657 }
03658
03659 void SecurityPage::CryptPlugTab::setup()
03660 {
03661 kdDebug(5006) << "CryptPlugTab::setup(): found "
03662 << kmkernel->cryptPlugList()->count()
03663 << " CryptPlugWrappers." << endl;
03664 mPlugList->clear();
03665
03666
03667 int i = 0;
03668 QListViewItem * top = 0;
03669 for ( CryptPlugWrapperListIterator it( *(kmkernel->cryptPlugList()) ) ;
03670 it.current() ; ++it, ++i ) {
03671 kdDebug(5006) << "processing { \"" << (*it)->displayName()
03672 << "\", \"" << (*it)->libName()
03673 << "\", " << (*it)->active() << " }" << endl;
03674 if( !(*it)->displayName().isEmpty() ) {
03675 top = new QListViewItem( mPlugList, top,
03676 (*it)->displayName(),
03677 (*it)->libName(),
03678 (*it)->updateURL(),
03679 (*it)->active() ? "*" : "",
03680 ( (*it)->initStatus( 0 ) == CryptPlugWrapper::InitStatus_Ok ) ? "*" : "" );
03681 }
03682 }
03683
03684 if( mPlugList->childCount() > 0 ) {
03685 mPlugList->setCurrentItem( mPlugList->firstChild() );
03686 mPlugList->setSelected( mPlugList->firstChild(), true );
03687 }
03688
03689 slotPlugSelectionChanged();
03690 }
03691
03692 void SecurityPage::CryptPlugTab::slotPlugSelectionChanged() {
03693 QListViewItem * item = mPlugList->selectedItem();
03694
03695
03696 mRemoveButton->setEnabled( item );
03697 mActivateButton->setEnabled( item );
03698 mConfigureButton->setEnabled( item );
03699
03700 mNameEdit->setEnabled( item );
03701 mLocationRequester->setEnabled( item );
03702 mUpdateURLEdit->setEnabled( item );
03703
03704
03705 mActivateButton->setText( item && item->text( 3 ).isEmpty() ?
03706 i18n("Ac&tivate") : i18n("Deac&tivate") );
03707
03708
03709 if ( item ) {
03710 mNameEdit->setText( item->text( 0 ) );
03711 mLocationRequester->setURL( item->text( 1 ) );
03712 mUpdateURLEdit->setText( item->text( 2 ) );
03713 } else {
03714 mNameEdit->clear();
03715 mLocationRequester->clear();
03716 mUpdateURLEdit->clear();
03717 }
03718 }
03719
03720 void SecurityPage::CryptPlugTab::dismiss() {
03721 CryptPlugWrapperList * cpl = kmkernel->cryptPlugList();
03722 for ( CryptPlugWrapperListIterator it( *(mlistCryptoAdd) );
03723 it.current(); ++it ) {
03724 CryptPlugWrapper* wrapper = cpl->take( cpl->find( *it ) );
03725 if ( wrapper ) {
03726 QString dummy;
03727 if ( wrapper->initStatus( &dummy ) == CryptPlugWrapper::InitStatus_Ok ) {
03728 wrapper->deinitialize();
03729 }
03730 }
03731 delete wrapper;
03732 wrapper = 0;
03733 }
03734 mlistCryptoAdd->clear();
03735 }
03736
03737 void SecurityPage::CryptPlugTab::apply() {
03738 KConfigGroup general( KMKernel::config(), "General" );
03739
03740 CryptPlugWrapperList * cpl = kmkernel->cryptPlugList();
03741
03742 uint cryptPlugCount = 0;
03743 for ( QListViewItemIterator it( mPlugList ) ; it.current() ; ++it ) {
03744 if ( it.current()->text( 0 ).isEmpty() )
03745 continue;
03746 KConfigGroup config( KMKernel::config(),
03747 QString("CryptPlug #%1").arg( cryptPlugCount ) );
03748 config.writeEntry( "name", it.current()->text( 0 ) );
03749 config.writePathEntry( "location", it.current()->text( 1 ) );
03750 config.writeEntry( "updates", it.current()->text( 2 ) );
03751 config.writeEntry( "active", !it.current()->text( 3 ).isEmpty() );
03752
03753 CryptPlugWrapper * wrapper = cpl->at( cryptPlugCount );
03754 if ( wrapper ) {
03755 wrapper->setDisplayName( it.current()->text( 0 ) );
03756 if ( wrapper->libName() != it.current()->text( 1 ) ) {
03757 wrapper->deinitialize();
03758 wrapper->setLibName( it.current()->text( 1 ) );
03759 CryptPlugWrapper::InitStatus status;
03760 QString errorMsg;
03761 wrapper->initialize( &status, &errorMsg );
03762 if( CryptPlugWrapper::InitStatus_Ok != status )
03763 it.current()->setText( 4, QString::null );
03764 else
03765 it.current()->setText( 4, "*" );
03766 }
03767 wrapper->setUpdateURL( it.current()->text( 2 ) );
03768 wrapper->setActive( !it.current()->text( 3 ).isEmpty() );
03769 }
03770 ++cryptPlugCount;
03771 }
03772
03773
03774 while( cpl->count() > cryptPlugCount ) {
03775 CryptPlugWrapper* wrapper = cpl->take( cryptPlugCount );
03776 if( wrapper ) {
03777 QString dummy;
03778 if ( wrapper->initStatus( &dummy ) == CryptPlugWrapper::InitStatus_Ok ) {
03779 wrapper->deinitialize();
03780 }
03781 }
03782 delete wrapper;
03783 wrapper = 0;
03784 }
03785
03786 mlistCryptoAdd->clear();
03787
03788 general.writeEntry("crypt-plug-count", cryptPlugCount );
03789 }
03790
03791 void SecurityPage::CryptPlugTab::slotPlugNameChanged( const QString & text )
03792 {
03793 QListViewItem * item = mPlugList->selectedItem();
03794 if ( !item ) return;
03795
03796 item->setText( 0, text );
03797 }
03798
03799 void SecurityPage::CryptPlugTab::slotPlugLocationChanged( const QString & text )
03800 {
03801 QListViewItem * item = mPlugList->selectedItem();
03802 if ( !item ) return;
03803
03804 item->setText( 1, text );
03805 }
03806
03807 void SecurityPage::CryptPlugTab::slotPlugUpdateURLChanged( const QString & text )
03808 {
03809 QListViewItem * item = mPlugList->selectedItem();
03810 if ( !item ) return;
03811
03812 item->setText( 2, text );
03813 }
03814
03815 void SecurityPage::CryptPlugTab::slotNewPlugIn()
03816 {
03817 CryptPlugWrapper * newWrapper = new CryptPlugWrapper( this, "", "", "" );
03818 kmkernel->cryptPlugList()->append( newWrapper );
03819 mlistCryptoAdd->append( newWrapper );
03820
03821 QListViewItem * item = new QListViewItem( mPlugList, mPlugList->lastItem() );
03822 mPlugList->setCurrentItem( item );
03823 mPlugList->setSelected( item, true );
03824 mNameEdit->setText( i18n("Unnamed") );
03825 mNameEdit->selectAll();
03826 mNameEdit->setFocus();
03827
03828
03829 }
03830
03831 void SecurityPage::CryptPlugTab::slotDeletePlugIn()
03832 {
03833 QListViewItem * item = mPlugList->selectedItem();
03834 if ( !item ) return;
03835
03836 delete item;
03837 mPlugList->setSelected( mPlugList->currentItem(), true );
03838 }
03839
03840 void SecurityPage::CryptPlugTab::slotConfigurePlugIn() {
03841 CryptPlugWrapperList * cpl = kmkernel->cryptPlugList();
03842 int i = 0;
03843 for ( QListViewItemIterator it( mPlugList ) ; it.current() ; ++it, ++i ) {
03844 if ( it.current()->isSelected() ) {
03845 CryptPlugWrapper * wrapper = cpl->at( i );
03846 if ( wrapper ) {
03847 CryptPlugConfigDialog dialog( wrapper, i, i18n("Configure %1 Plugin").arg( it.current()->text( 0 ) ) );
03848 dialog.exec();
03849 }
03850 break;
03851 }
03852 }
03853 }
03854
03855 void SecurityPage::CryptPlugTab::slotActivatePlugIn()
03856 {
03857 QListViewItem * item = mPlugList->selectedItem();
03858 if ( !item ) return;
03859
03860 CryptPlugWrapperList * cpl = kmkernel->cryptPlugList();
03861
03862
03863 bool activate = ( item->text( 3 ).isEmpty() );
03864
03865
03866 int pos = 0;
03867 for ( QListViewItemIterator it( mPlugList ) ; it.current() ; ++it, ++pos ) {
03868 CryptPlugWrapper * plug = cpl->at( pos );
03869 if( plug ) {
03870 if( it.current()->isSelected() ) {
03871
03872 plug->setActive( activate );
03873 it.current()->setText( 3, activate ? "*" : "" );
03874 } else {
03875
03876 plug->setActive( false );
03877 it.current()->setText( 3, QString::null );
03878 }
03879 }
03880 }
03881 if( activate )
03882 mActivateButton->setText( i18n("Deac&tivate") );
03883 else
03884 mActivateButton->setText( i18n("Ac&tivate") );
03885 }
03886
03887
03888
03889
03890
03891
03892
03893 QString MiscPage::iconLabel() {
03894 return i18n("Misc");
03895 }
03896
03897 const char * MiscPage::iconName() {
03898 return "misc";
03899 }
03900
03901 QString MiscPage::title() {
03902 return i18n("Setting that don't fit elsewhere");
03903 }
03904
03905 QString MiscPage::helpAnchor() const {
03906 return QString::fromLatin1("configure-misc");
03907 }
03908
03909 MiscPage::MiscPage( QWidget * parent, const char * name )
03910 : TabbedConfigurationPage( parent, name )
03911 {
03912 mFolderTab = new FolderTab();
03913 addTab( mFolderTab, mFolderTab->title() );
03914
03915 mGroupwareTab = new GroupwareTab();
03916 addTab( mGroupwareTab, mGroupwareTab->title() );
03917 }
03918
03919 QString MiscPage::FolderTab::title() {
03920 return i18n("&Folders");
03921 }
03922
03923 QString MiscPage::FolderTab::helpAnchor() const {
03924 return QString::fromLatin1("configure-misc-folders");
03925 }
03926
03927 MiscPageFolderTab::MiscPageFolderTab( QWidget * parent, const char * name )
03928 : ConfigurationPage( parent, name )
03929 {
03930
03931 QVBoxLayout *vlay;
03932 QHBoxLayout *hlay;
03933 QGroupBox *group;
03934 QLabel *label;
03935
03936 vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
03937
03938
03939 mEmptyFolderConfirmCheck =
03940 new QCheckBox( i18n("Corresponds to Folder->Move All Messages to Trash",
03941 "Ask for co&nfirmation before moving all messages to "
03942 "trash"),
03943 this );
03944 vlay->addWidget( mEmptyFolderConfirmCheck );
03945 mWarnBeforeExpire =
03946 new QCheckBox( i18n("&Warn before expiring messages"), this );
03947 vlay->addWidget( mWarnBeforeExpire );
03948
03949 hlay = new QHBoxLayout( vlay );
03950 mLoopOnGotoUnread = new QComboBox( false, this );
03951 label = new QLabel( mLoopOnGotoUnread,
03952 i18n("to be continued with \"don't loop\", \"loop in current folder\", "
03953 "and \"loop in all folders\".",
03954 "When trying to find unread messages:"), this );
03955 mLoopOnGotoUnread->insertStringList( QStringList()
03956 << i18n("continuation of \"When trying to find unread messages:\"",
03957 "Don't Loop")
03958 << i18n("continuation of \"When trying to find unread messages:\"",
03959 "Loop in Current Folder")
03960 << i18n("continuation of \"When trying to find unread messages:\"",
03961 "Loop in All Folders"));
03962 hlay->addWidget( label );
03963 hlay->addWidget( mLoopOnGotoUnread, 1 );
03964 mJumpToUnread =
03965 new QCheckBox( i18n("&Jump to first unread message when entering a "
03966 "folder"), this );
03967 vlay->addWidget( mJumpToUnread );
03968
03969 hlay = new QHBoxLayout( vlay );
03970 mDelayedMarkAsRead = new QCheckBox( i18n("Mar&k selected message as read after"), this );
03971 hlay->addWidget( mDelayedMarkAsRead );
03972 mDelayedMarkTime = new KIntSpinBox( 0 , 60 , 1,
03973 0 , 10 , this);
03974 mDelayedMarkTime->setSuffix( i18n(" sec") );
03975 mDelayedMarkTime->setEnabled( false );
03976 hlay->addWidget( mDelayedMarkTime );
03977 hlay->addStretch( 1 );
03978
03979 connect(mDelayedMarkAsRead, SIGNAL(toggled(bool)), mDelayedMarkTime,
03980 SLOT(setEnabled(bool)));
03981
03982
03983 mShowPopupAfterDnD =
03984 new QCheckBox( i18n("Ask for action after &dragging messages to another folder"), this );
03985 vlay->addWidget( mShowPopupAfterDnD );
03986
03987
03988 hlay = new QHBoxLayout( vlay );
03989 mMailboxPrefCombo = new QComboBox( false, this );
03990 label = new QLabel( mMailboxPrefCombo,
03991 i18n("to be continued with \"flat files\" and "
03992 "\"directories\", resp.",
03993 "By default, &message folders on disk are:"), this );
03994 mMailboxPrefCombo->insertStringList( QStringList()
03995 << i18n("continuation of \"By default, &message folders on disk are\"",
03996 "Flat Files (\"mbox\" format)")
03997 << i18n("continuation of \"By default, &message folders on disk are\"",
03998 "Directories (\"maildir\" format)") );
03999 hlay->addWidget( label );
04000 hlay->addWidget( mMailboxPrefCombo, 1 );
04001
04002
04003 hlay = new QHBoxLayout( vlay );
04004 mOnStartupOpenFolder = new KMFolderComboBox( this );
04005 label = new QLabel( mOnStartupOpenFolder,
04006 i18n("Open this folder on startup:"), this );
04007 hlay->addWidget( label );
04008 hlay->addWidget( mOnStartupOpenFolder, 1 );
04009
04010
04011 group = new QVGroupBox( i18n("On Program Exit, "
04012 "Perform Following Tasks"), this );
04013 group->layout()->setSpacing( KDialog::spacingHint() );
04014 mCompactOnExitCheck = new QCheckBox( i18n("Com&pact all folders"), group );
04015 mEmptyTrashCheck = new QCheckBox( i18n("Empty &trash"), group );
04016 mExpireAtExit = new QCheckBox( i18n("&Expire old messages"), group );
04017
04018 vlay->addWidget( group );
04019 vlay->addStretch( 1 );
04020
04021
04022 QString msg = i18n( "what's this help",
04023 "<qt><p>This selects which mailbox format will be "
04024 "the default for local folders:</p>"
04025 "<p><b>mbox:</b> KMail's mail "
04026 "folders are represented by a single file each. "
04027 "Individual messages are separated from each other by a "
04028 "line starting with \"From \". This saves space on "
04029 "disk, but may be less robust, e.g. when moving messages "
04030 "between folders.</p>"
04031 "<p><b>maildir:</b> KMail's mail folders are "
04032 "represented by real folders on disk. Individual messages "
04033 "are separate files. This may waste a bit of space on "
04034 "disk, but should be more robust, e.g. when moving "
04035 "messages between folders.</p></qt>");
04036 QWhatsThis::add( mMailboxPrefCombo, msg );
04037 QWhatsThis::add( label, msg );
04038
04039 msg = i18n( "what's this help",
04040 "<qt><p>When jumping to the next unread message, it may occur "
04041 "that no more unread messages are below the current message.</p>"
04042 "<p><b>Don't loop:</b> The search will stop at the last message in "
04043 "the current folder.</p>"
04044 "<p><b>Loop in current folder:</b> The search will continue at the "
04045 "top of the message list, but not go to another folder.</p>"
04046 "<p><b>Loop in all folders:</b> The search will continue at the top of "
04047 "the message list. If no unread messages are found it will then continue "
04048 "to the next folder.</p>"
04049 "<p>Similarly, when searching for the previous unread message, "
04050 "the search will start from the bottom of the message list and continue to "
04051 "the previous folder depending on which option is selected.</p></qt>" );
04052 QWhatsThis::add( mLoopOnGotoUnread, msg );
04053 }
04054
04055 void MiscPage::FolderTab::setup() {
04056 KConfigGroup general( KMKernel::config(), "General" );
04057 KConfigGroup behaviour( KMKernel::config(), "Behaviour" );
04058
04059 mEmptyTrashCheck->setChecked( general.readBoolEntry( "empty-trash-on-exit", true ) );
04060 mExpireAtExit->setChecked( general.readNumEntry( "when-to-expire", 0 ) );
04061 mWarnBeforeExpire->setChecked( general.readBoolEntry( "warn-before-expire", true ) );
04062 mOnStartupOpenFolder->setFolder( general.readEntry( "startupFolder",
04063 kmkernel->inboxFolder()->idString() ) );
04064 mCompactOnExitCheck->setChecked( general.readBoolEntry( "compact-all-on-exit", true ) );
04065 mEmptyFolderConfirmCheck->setChecked( general.readBoolEntry( "confirm-before-empty", true ) );
04066
04067 mLoopOnGotoUnread->setCurrentItem( behaviour.readNumEntry( "LoopOnGotoUnread", 1 ) );
04068 mJumpToUnread->setChecked( behaviour.readBoolEntry( "JumpToUnread", false ) );
04069 mDelayedMarkAsRead->setChecked( behaviour.readBoolEntry( "DelayedMarkAsRead", true ) );
04070 mDelayedMarkTime->setValue( behaviour.readNumEntry( "DelayedMarkTime", 0 ) );
04071 mShowPopupAfterDnD->setChecked( behaviour.readBoolEntry( "ShowPopupAfterDnD", true ) );
04072
04073 int num = general.readNumEntry("default-mailbox-format", 1 );
04074 if ( num < 0 || num > 1 ) num = 1;
04075 mMailboxPrefCombo->setCurrentItem( num );
04076 }
04077
04078 void MiscPage::FolderTab::apply() {
04079 KConfigGroup general( KMKernel::config(), "General" );
04080 KConfigGroup behaviour( KMKernel::config(), "Behaviour" );
04081
04082 general.writeEntry( "empty-trash-on-exit", mEmptyTrashCheck->isChecked() );
04083 general.writeEntry( "compact-all-on-exit", mCompactOnExitCheck->isChecked() );
04084 general.writeEntry( "confirm-before-empty", mEmptyFolderConfirmCheck->isChecked() );
04085 general.writeEntry( "default-mailbox-format", mMailboxPrefCombo->currentItem() );
04086 general.writeEntry( "warn-before-expire", mWarnBeforeExpire->isChecked() );
04087 general.writeEntry( "startupFolder", mOnStartupOpenFolder->getFolder() ?
04088 mOnStartupOpenFolder->getFolder()->idString() : QString::null );
04089 behaviour.writeEntry( "LoopOnGotoUnread", mLoopOnGotoUnread->currentItem() );
04090 behaviour.writeEntry( "JumpToUnread", mJumpToUnread->isChecked() );
04091 behaviour.writeEntry( "DelayedMarkAsRead", mDelayedMarkAsRead->isChecked() );
04092 behaviour.writeEntry( "DelayedMarkTime", mDelayedMarkTime->value() );
04093 behaviour.writeEntry( "ShowPopupAfterDnD", mShowPopupAfterDnD->isChecked() );
04094
04095 if ( mExpireAtExit->isChecked() )
04096 general.writeEntry( "when-to-expire", expireAtExit );
04097 else
04098 general.writeEntry( "when-to-expire", expireManual );
04099 }
04100
04101
04102 QString MiscPage::GroupwareTab::title() {
04103 return i18n("&Groupware");
04104 }
04105
04106 QString MiscPage::GroupwareTab::helpAnchor() const {
04107 return QString::fromLatin1("configure-misc-groupware");
04108 }
04109
04110 MiscPageGroupwareTab::MiscPageGroupwareTab( QWidget * parent, const char * name )
04111 : ConfigurationPage( parent, name )
04112 {
04113 QBoxLayout* vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
04114 vlay->setAutoAdd( true );
04115
04116
04117 QVGroupBox* b1 = new QVGroupBox( i18n("&IMAP Resource Folder Options"), this );
04118
04119 mEnableImapResCB = new QCheckBox( i18n("&Enable IMAP resource functionality"), b1 );
04120
04121 mBox = new QVBox( b1 );
04122 mBox->setSpacing( KDialog::spacingHint() );
04123 connect( mEnableImapResCB, SIGNAL( toggled(bool) ),
04124 mBox, SLOT( setEnabled(bool) ) );
04125 QLabel* languageLA = new QLabel( i18n("&Language for groupware folders:"), mBox );
04126
04127 mLanguageCombo = new QComboBox( false, mBox );
04128 languageLA->setBuddy( mLanguageCombo );
04129 QStringList lst;
04130 lst << i18n("English") << i18n("German") << i18n("French") << i18n("Dutch");
04131 mLanguageCombo->insertStringList( lst );
04132
04133 QLabel* subfolderLA = new QLabel( i18n("Resource folders are &subfolders of:"), mBox );
04134
04135 mFolderCombo = new KMFolderComboBox( mBox );
04136 subfolderLA->setBuddy( mFolderCombo );
04137
04138
04139 b1 = new QVGroupBox( i18n("Groupware Options"), this );
04140
04141 mEnableGwCB = new QCheckBox( i18n("&Enable groupware functionality"), b1 );
04142 gBox = new QVBox( b1 );
04143 gBox->setSpacing( KDialog::spacingHint() );
04144 connect( mEnableGwCB, SIGNAL( toggled(bool) ),
04145 gBox, SLOT( setEnabled(bool) ) );
04146
04147 mLegacyMangleFromTo = new QCheckBox( i18n( "Legac&y mode: Mangle From:/To: headers in replies to invitations" ), gBox );
04148 QToolTip::add( mLegacyMangleFromTo, i18n( "Turn this option on in order to make Outlook(tm) understand your answers to invitations" ) );
04149
04150 QVGroupBox* resourceVGB = new QVGroupBox( i18n( "Automatic &Resource Management" ), gBox );
04151 mAutoResCB = new QCheckBox( i18n( "&Automatically accept resource requests" ), resourceVGB );
04152 mAutoDeclConflCB = new QCheckBox( i18n( "A&utomatically decline conflicting requests" ), resourceVGB );
04153 mAutoDeclConflCB->setEnabled( false );
04154 connect( mAutoResCB, SIGNAL( toggled( bool ) ),
04155 mAutoDeclConflCB, SLOT( setEnabled( bool ) ) );
04156
04157
04158 new QLabel( this );
04159 }
04160
04161 void MiscPage::GroupwareTab::setup() {
04162
04163 KConfigGroup options( KMKernel::config(), "Groupware" );
04164 mEnableGwCB->setChecked( options.readBoolEntry( "Enabled", true ) );
04165 gBox->setEnabled( mEnableGwCB->isChecked() );
04166 mAutoResCB->setChecked( options.readBoolEntry( "AutoAccept", false ) );
04167 mAutoDeclConflCB->setChecked( options.readBoolEntry( "AutoDeclConflict", false ) );
04168 mLegacyMangleFromTo->setChecked( options.readBoolEntry( "LegacyMangleFromToHeaders", false ) );
04169
04170
04171 KConfigGroup irOptions( KMKernel::config(), "IMAP Resource" );
04172 mEnableImapResCB->setChecked( irOptions.readBoolEntry( "Enabled", false ) );
04173 mBox->setEnabled( mEnableImapResCB->isChecked() );
04174
04175 int i = irOptions.readNumEntry( "Folder Language", 0 );
04176 mLanguageCombo->setCurrentItem(i);
04177
04178 QString folderId = irOptions.readEntry( "Folder Parent" );
04179 if( !folderId.isNull() ) {
04180 mFolderCombo->setFolder( folderId );
04181 }
04182 }
04183
04184 void MiscPage::GroupwareTab::apply() {
04185
04186 KConfigGroup options( KMKernel::config(), "Groupware" );
04187 options.writeEntry( "Enabled", mEnableGwCB->isChecked() );
04188 if ( mEnableGwCB->isChecked() ) {
04189 options.writeEntry( "AutoAccept", mAutoResCB->isChecked() );
04190 options.writeEntry( "AutoDeclConflict", mAutoDeclConflCB->isChecked() );
04191 options.writeEntry( "LegacyMangleFromToHeaders", mLegacyMangleFromTo->isChecked() );
04192 }
04193
04194
04195 KConfigGroup irOptions( KMKernel::config(), "IMAP Resource" );
04196 irOptions.writeEntry( "Enabled", mEnableImapResCB->isChecked() );
04197 if ( mEnableImapResCB->isChecked() ) {
04198 irOptions.writeEntry( "Folder Language", mLanguageCombo->currentItem() );
04199 irOptions.writeEntry( "Folder Parent", mFolderCombo->getFolder()->idString() );
04200 }
04201
04202
04203 kmkernel->groupware().readConfig();
04204 kmkernel->iCalIface().readConfig();
04205 }
04206
04207
04208 #undef DIM
04209
04210
04211 #include "configuredialog.moc"