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