# configelem.cpp

    00001 /***************************************************************************
    00002                           ConfigElem.cpp  -  description
    00003                              -------------------
    00004     begin                : Tue May 9 2000
    00005     copyright            : (C) 2000-2001 by Eggert Ehmke
    00006     email                : eggert.ehmke@berlin.de
    00007  ***************************************************************************/
    00008
    00009 /***************************************************************************
    00010  *                                                                         *
    00011  *   This program is free software; you can redistribute it and/or modify  *
    00012  *   it under the terms of the GNU General Public License as published by  *
    00013  *   the Free Software Foundation; either version 2 of the License, or     *
    00014  *   (at your option) any later version.                                   *
    00015  *                                                                         *
    00016  ***************************************************************************/
    00017
    00018 #include "configelem.h"
    00019
    00020 int const ConfigElem::continueShowHeaders( 0 );
    00021 int const ConfigElem::cancelShowHeaders( 1 );
    00022
    00023
    00024 ConfigElem::ConfigElem( ) : TQObject()
    00025 {
    00026   //initialize account
    00027   init();
    00028
    00029   //set default values
    00030   m_url.setProtocol( "pop3" );
    00031   m_url.setPort( 110 );
    00032   m_bActive = false;
    00033   appConfig = NULL;
    00034   m_strAccount = "";
    00035 }
    00036
    00037 ConfigElem::ConfigElem( ConfigList* config ) : TQObject()
    00038 {
    00039   //initialize account
    00040   init();
    00041
    00042   m_url.setProtocol( "pop3" );
    00043   m_url.setPort (110);
    00044
    00045   m_bActive = false;
    00046
    00047   appConfig = config;
    00048
    00049 }
    00050
    00051 ConfigElem::ConfigElem( ConfigElem* pElem ) : TQObject()
    00052 {
    00053   //initialize account
    00054   init();
    00055
    00056   //set active by default
    00057   m_bActive = pElem->isActive();
    00058
    00059   //copy some interesting stuff from the sample
    00060   //the url object contains all necessary information about the server
    00061   m_strAccount = pElem->getAccountName();
    00062   m_url = pElem->getURL();
    00063   appConfig = pElem->appConfig;
    00064
    00065 }
    00066
    00067 ConfigElem::ConfigElem( ConfigList* config, const TQString& account ) : TQObject()
    00068 {
    00069   //initialize account
    00070   init();
    00071
    00072   //set account name
    00073   m_strAccount = account;
    00074
    00075   //deactivate it by default
    00076   m_bActive = false;
    00077
    00078   //set the pointer to the general app configuration
    00079   appConfig = config;
    00080 }
    00081
    00082 void ConfigElem::init( )
    00083 {
    00084   //initialize timeout timer
    00085   pop3Timer = new TQTimer( this );
    00086   connect( pop3Timer, TQ_SIGNAL( timeout() ), this, TQ_SLOT( slotTimeout() ) );
    00087
    00088   //state is idle
    00089   state = AccountIdle;
    00090
    00091   //create new empty mail list
    00092   m_pshowrecord = new ShowRecord();
    00093
    00094   //the account has no appropriate account list view item yet
    00095   m_pViewItem = NULL;
    00096
    00097   //set default values
    00098   PasswordStorage = DEFAULT_ACCOUNT_PASSWORD_STORAGE;
    00099 }
    00100
    00101
    00102 ConfigElem::~ConfigElem()
    00103 {
    00104   // do not delete m_pshowrecord here
    00105 }
    00106
    00107 void ConfigElem::saveOptions( TQDomDocument& doc, TQDomElement& parent )
    00108 {
    00109   //get application config
    00110   TDEConfig* config = TDEApplication::kApplication()->config();
    00111
    00112   //save the active state
    00113   config->setGroup( getAccountName() );
    00114   config->writeEntry( CONFIG_ENTRY_ACCOUNT_ACTIVE, m_bActive );
    00115   config->sync();
    00116
    00117   //save the stored mails inside this account
    00118   parent.setAttribute( ATTRIBUTE_ACCOUNT_NAME, m_strAccount );
    00119   m_pshowrecord->saveOptions( doc, parent );
    00120 }
    00121
    00122 void ConfigElem::readStoredMails( TQDomElement& parent )
    00123 {
    00124   //get mails
    00125   m_pshowrecord->readStoredMails( parent );
    00126 }
    00127
    00128
    00129 int ConfigElem::count()
    00130 {
    00131   return m_pshowrecord->count();
    00132 }
    00133
    00134 void ConfigElem::applyFilters()
    00135 {
    00136   m_pshowrecord->applyFilters();
    00137 }
    00138
    00139 bool ConfigElem::isActive( ) const
    00140 {
    00141   return m_bActive;
    00142 }
    00143
    00144 void ConfigElem::setActive( bool active )
    00145 {
    00146   m_bActive = active;
    00147 }
    00148
    00149 TQString ConfigElem::getAccountName( ) const
    00150 {
    00151   return m_strAccount;
    00152 }
    00153
    00154 void ConfigElem::setAccountName( TQString name )
    00155 {
    00156   if( name != NULL )
    00157     m_strAccount = name;
    00158 }
    00159
    00160 TQString ConfigElem::getPassword( ) const
    00161 {
    00162   return m_url.pass();
    00163 }
    00164
    00165 void ConfigElem::setPassword( const TQString& password )
    00166 {
    00167     m_url.setPass( password );
    00168 }
    00169
    00170 KURL ConfigElem::getURL( ) const
    00171 {
    00172   return m_url;
    00173 }
    00174
    00175 bool ConfigElem::hasPassword( ) const
    00176 {
    00177   return m_url.hasPass();
    00178 }
    00179
    00180 void ConfigElem::setListViewItem( TQListViewItem* item )
    00181 {
    00182   m_pViewItem = item;
    00183 }
    00184
    00185 TQListViewItem * ConfigElem::getListViewItem( )
    00186 {
    00187   return m_pViewItem;
    00188 }
    00189
    00190 bool ConfigElem::isSelected( ) const
    00191 {
    00192   if( m_pViewItem == NULL )
    00193
    00194     return false;
    00195
    00196   else
    00197
    00198     return m_pViewItem->isSelected();
    00199 }
    00200
    00201 void ConfigElem::clearMailList( )
    00202 {
    00203   if( m_pshowrecord == NULL )
    00204     //there is no mail list yet, create a one
    00205     m_pshowrecord = new ShowRecord;
    00206   else
    00207     //clear the existing mail list
    00208     m_pshowrecord->clear();
    00209 }
    00210
    00211 void ConfigElem::setHost( const TQString& host )
    00212 {
    00213   m_url.setHost( host );
    00214 }
    00215
    00216 void ConfigElem::setProtocol( const TQString& protocol )
    00217 {
    00218   m_url.setProtocol( protocol );
    00219 }
    00220
    00221 void ConfigElem::setPort( unsigned short int port )
    00222 {
    00223   m_url.setPort( port );
    00224 }
    00225
    00226 void ConfigElem::setUser( const TQString & user )
    00227 {
    00228   m_url.setUser( user );
    00229 }
    00230
    00231 TQString ConfigElem::getUser( ) const
    00232 {
    00233   return m_url.user();
    00234 }
    00235
    00236 TQString ConfigElem::getHost( ) const
    00237 {
    00238   return m_url.host();
    00239 }
    00240
    00241 void ConfigElem::deleteSelectedMails( )
    00242 {
    00243   //return if this account has no selected mails or
    00244   //the account is not idle or the account is not active
    00245   if( !m_pshowrecord->hasSelectedMails() || state != AccountIdle || !isActive() )
    00246   {
    00247     emit sigDeleteReady( m_strAccount );
    00248     return;
    00249   }
    00250
    00251   //check whether we have a password for this account
    00252   //if not, ask for it
    00253   //return when no password is available
    00254   if( !assertPassword() )
    00255   {
    00256     emit sigDeleteReady( m_strAccount );
    00257     return;
    00258   }
    00259
    00260   //get the numbers of all selected mails
    00261   MailsToDelete = m_pshowrecord->getSelectedMails();
    00262   if( MailsToDelete.empty() )
    00263   {
    00264     kdError() << "ConfigElem::deleteSelectedMails (Account " << m_strAccount << "): The account has selected mails to delete but ShowRecord::getSelectedMails has returned an empty list." << endl;
    00265     emit sigDeleteReady( m_strAccount );
    00266     return;
    00267   }
    00268
    00269   //set account state
    00270   state = AccountDeleting;
    00271
    00272   //start the deleting of all mails in MailsToDelete
    00273   deleteNextMail();
    00274 }
    00275
    00276 bool ConfigElem::assertPassword( bool force )
    00277 {
    00278   //is a password stored?
    00279   if ( !hasPassword() || force )
    00280   {
    00281     //no password found, we will ask the user!
    00282     //set normal cursor
    00283     while( TQApplication::overrideCursor() )
    00284       TQApplication::restoreOverrideCursor();
    00285
    00286     TQCString password;      //for the password dialog to store the password
    00287     int result = KPasswordDialog::getPassword( password, i18n( "Please type in the password for %1" ).arg( getAccountName() ) );
    00288
    00289     //set waiting cursor
    00290     TQApplication::setOverrideCursor( TQt::waitCursor );
    00291
    00292     //let's look, what the user has done :o)
    00293     if( result == KPasswordDialog::Accepted )
    00294     {
    00295       //the user has clicked OK in the password dialog
    00296       //store the password
    00297       setPassword( password );
    00298
    00299       //save password in file or TDEWallet
    00300       TDEConfig* config = TDEApplication::kApplication()->config();
    00301       config->setGroup( getAccountName() );
    00302
    00303       if( PasswordStorage == CONFIG_VALUE_ACCOUNT_PASSWORD_SAVE_FILE )
    00304         config->writeEntry( CONFIG_ENTRY_ACCOUNT_PASSWORD, crypt( m_url ) );
    00305       else
    00306         config->writeEntry( CONFIG_ENTRY_ACCOUNT_PASSWORD, TQString::null );
    00307
    00308       if( PasswordStorage == CONFIG_VALUE_ACCOUNT_PASSWORD_SAVE_TDEWALLET )
    00309         TDEWalletAccess::savePassword( getAccountName(), m_url.pass() );
    00310
    00311       config->sync();
    00312
    00313       //emit configuration changed signal
    00314       emit sigConfigChanged();
    00315
    00316       //tell we have a password
    00317       return true;
    00318     }
    00319     else
    00320       //the user has clicked Cancel in the password dialog; we don't have a password
    00321       return false;
    00322   }
    00323   else
    00324     //we have already a password for this account
    00325     return true;
    00326
    00327 }
    00328
    00329 void ConfigElem::deleteNextMail( )
    00330 {
    00331   //if the list of mails to delete is empty, finalize the deletion and return
    00332   if( MailsToDelete.empty() )
    00333   {
    00334     commitDeletion();
    00335     return;
    00336   }
    00337
    00338   //start job
    00339   startKIOJob( TQString( "/remove/%1" ).arg( *MailsToDelete.begin() ) );
    00340   connect( pop3Job, TQ_SIGNAL( result( TDEIO::Job* ) ), this, TQ_SLOT( slotMailDeleted( TDEIO::Job* ) ) );
    00341 }
    00342
    00343 void ConfigElem::slotMailDeleted( TDEIO::Job* job )
    00344 {
    00345   //stop timeout timer
    00346   pop3Timer->stop();
    00347
    00348   //check for errors
    00349   //if an error is occured, the deletion will be canceled
    00350   //or will ask for a new password
    00351   if( job->error() == TDEIO::ERR_COULD_NOT_LOGIN )
    00352   {
    00353     //login failed, ask for a new password
    00354     job->showErrorDialog();
    00355     bool res = assertPassword( true );
    00356     if( res == false )
    00357     {
    00358       //we have not got a new password; cancel delete
    00359       slotFinalizeDeletion( NULL );
    00360       return;
    00361     }
    00362     //if we have got a new password, it jumps to the end of the if-statement
    00363   }
    00364   else if( job->error() != 0 )
    00365   {
    00366     //unknown error, show message and cancel delete
    00367     job->showErrorDialog();
    00368     slotFinalizeDeletion( NULL );
    00369     return;
    00370   }
    00371   else
    00372   {
    00373     //operation was successful
    00374     //remove the deleted mail from the internal mail list
    00375     m_pshowrecord->removeMail( *MailsToDelete.begin() );
    00376
    00377     //remove the first item of the list of mails to delete
    00378     MailsToDelete.remove( MailsToDelete.begin() );
    00379
    00380     //if the list of mails to delete is empty, finalize the deletion and return
    00381     if( MailsToDelete.empty() )
    00382     {
    00383       commitDeletion();
    00384       return;
    00385     }
    00386   }
    00387
    00388   //delete next mail in list
    00389   deleteNextMail();
    00390
    00391
    00392 }
    00393
    00394 void ConfigElem::slotFinalizeDeletion( TDEIO::Job* )
    00395 {
    00396   //stop timeout time
    00397   pop3Timer->stop();
    00398
    00399   //set account state to idle
    00400   state = AccountIdle;
    00401
    00402   //emit signal to report the deletion is ready
    00403   emit sigDeleteReady( m_strAccount );
    00404 }
    00405
    00406 void ConfigElem::startKIOJob( const TQString & path )
    00407 {
    00408   TDEIO::MetaData options;           //options for the pop3 job
    00409
    00410   //set options
    00411   options.insert( "progress", "off" );
    00412   options.insert( "pipelining", "off" );
    00413   options.insert( "auth", "TEXT" );
    00414   options.insert( "tls", "off" );
    00415
    00416   //set the given command and parameters
    00417   m_url.setPath( path );
    00418
    00419   //print debug message
    00420   kdDebug() << "ConfigElem::startKIOJob: start TDEIO job on URL " << m_url.url() << endl;
    00421
    00422   //start the job and get handle to it
    00423   pop3Job = TDEIO::get( m_url, false, false );
    00424
    00425   //put options to the job
    00426   pop3Job->addMetaData( options );
    00427
    00428   //start timeout timer
    00429   pop3Timer->start( getTimeoutTime() * 1000, true );
    00430 }
    00431
    00432 Types::AccountState_Type ConfigElem::getState( )
    00433 {
    00434   return state;
    00435 }
    00436
    00437 void ConfigElem::commitDeletion( )
    00438 {
    00439   //start job to commit
    00440   startKIOJob( TQString( "/commit" ) );
    00441   connect( pop3Job, TQ_SIGNAL( result( TDEIO::Job* ) ), this, TQ_SLOT( slotFinalizeDeletion( TDEIO::Job* ) ) );
    00442 }
    00443
    00444 unsigned int ConfigElem::getTimeoutTime( )
    00445 {
    00446   //return default time, if the configuration is not accessable
    00447   if( appConfig == NULL )
    00448     return DEFAULT_TIMEOUT_TIME;
    00449
    00450   //get time from configuration
    00451   unsigned int time = appConfig->getTimeoutTime();
    00452
    00453   //take minimum time, if get time is less
    00454   if( time < MINIMUM_TIMEOUT_TIME )
    00455     time = MINIMUM_TIMEOUT_TIME;
    00456
    00457   return time;
    00458 }
    00459
    00460 void ConfigElem::slotTimeout( )
    00461 {
    00462   //kill a running job
    00463   if( pop3Job != NULL )
    00464     pop3Job->kill( true );
    00465
    00466   //show error message (during refresh if desired only)
    00467   kdError() << "Timeout error!" << endl;
    00468
    00469   if( state != AccountRefreshing || appConfig->showConnectionErrors() )
    00470     KMessageBox::error( NULL, TQString( i18n( "Time out on %1. The operation could not be finished on time" ) ).arg( m_strAccount ), i18n( "Time Out" ) );
    00471
    00472   //call the appropriate finalize methode
    00473   switch( state )
    00474   {
    00475     case AccountIdle        : break;
    00476     case AccountDeleting    : slotFinalizeDeletion( NULL ); break;
    00477     case AccountDownloading : slotFinalizeShowMail( NULL ); break;
    00478     case AccountRefreshing  : cancelRefresh(); break;
    00479
    00480     default : break;
    00481   }
    00482 }
    00483
    00484 TQStringList ConfigElem::getSelectedSubjects( ) const
    00485 {
    00486   return m_pshowrecord->getSelectedSubjects();
    00487 }
    00488
    00489 bool ConfigElem::hasSelectedMails( )
    00490 {
    00491   return m_pshowrecord->hasSelectedMails();
    00492 }
    00493
    00494 void ConfigElem::showSelectedMails( )
    00495 {
    00496   //return if this account has no selected mails or
    00497   //the account is not idle or the account is not active
    00498   if( !m_pshowrecord->hasSelectedMails() || state != AccountIdle || !isActive() )
    00499   {
    00500     emit sigShowBodiesReady( m_strAccount );
    00501     return;
    00502   }
    00503
    00504   //check whether we have a password for this account
    00505   //if not, ask for it
    00506   //return when no password is available
    00507   if( !assertPassword() )
    00508   {
    00509     emit sigShowBodiesReady( m_strAccount );
    00510     return;
    00511   }
    00512
    00513   //get the numbers of all selected mails
    00514   MailsToShow = m_pshowrecord->getSelectedMails();
    00515   if( MailsToShow.empty() )
    00516   {
    00517     kdError() << "ConfigElem::showSelectedMails (Account " << m_strAccount << "): The account has selected mails to show but ShowRecord::getSelectedMails has returned an empty list." << endl;
    00518     emit sigShowBodiesReady( m_strAccount );
    00519     return;
    00520   }
    00521
    00522   //set account state
    00523   state = AccountDownloading;
    00524
    00525   //start the deleting of all mails in MailsToDelete
    00526   showNextMail();
    00527
    00528 }
    00529
    00530 void ConfigElem::showNextMail( )
    00531 {
    00532   //if the list of mails to show is empty, finalize it and return
    00533   if( MailsToShow.empty() )
    00534   {
    00535     slotFinalizeShowMail( NULL );
    00536     return;
    00537   }
    00538
    00539   //clear the class variable mailbody, which contains the downloaded mail body
    00540   mailbody.resize( 0 );
    00541
    00542   //start job
    00543   startKIOJob( TQString( "/download/%1" ).arg( *MailsToShow.begin() ) );
    00544   connect( pop3Job, TQ_SIGNAL( data( TDEIO::Job*, const TQByteArray & ) ), TQ_SLOT( slotDataMailBody( TDEIO::Job*, const TQByteArray & ) ) );
    00545   connect( pop3Job, TQ_SIGNAL( result( TDEIO::Job* ) ), this, TQ_SLOT( slotBodyDownloaded( TDEIO::Job* ) ) );
    00546
    00547 }
    00548
    00549 void ConfigElem::slotBodyDownloaded( TDEIO::Job * job )
    00550 {
    00551   //stop timeout timer
    00552   pop3Timer->stop();
    00553
    00554   //check for errors
    00555   //if an error has occured, the download will be canceled
    00556   //or will ask for a new password
    00557   if( job->error() == TDEIO::ERR_COULD_NOT_LOGIN )
    00558   {
    00559     //login failed, ask for a new password
    00560     job->showErrorDialog();
    00561     bool res = assertPassword( true );
    00562     if( res == false )
    00563     {
    00564       //we have not got a new password; cancel delete
    00565       slotFinalizeShowMail( NULL );
    00566       return;
    00567     }
    00568     //if we have got a new password, jump to the end of the if-statement
    00569   }
    00570   else if( job->error() != 0 )
    00571   {
    00572     job->showErrorDialog();
    00573     slotFinalizeShowMail( NULL );
    00574     return;
    00575   }
    00576   else
    00577   {
    00578     //succesful download
    00579     //show mail
    00580     int currentMail = *MailsToShow.begin();
    00581     TQString tsender = m_pshowrecord->getSenderOf( currentMail );
    00582     TQString tdate = m_pshowrecord->getDateOf( currentMail );
    00583     TQString tsize = m_pshowrecord->getSizeOf( currentMail );
    00584     TQString tsubject = m_pshowrecord->getSubjectOf( currentMail );
    00585     TQString tmailbody( m_pshowrecord->decodeMailBody( mailbody, currentMail, appConfig->allowHTML() ) );
    00586
    00587     //emit signal to notify the opening of a window
    00588     emit sigMessageWindowOpened();
    00589
    00590     //create and open the window
    00591     ShowMailDialog dlg( kapp->mainWidget(), m_strAccount, appConfig->allowHTML(), tsender, tdate, tsize, tsubject, tmailbody );
    00592     int ret = dlg.exec();
    00593
    00594     //emit signal to notify the closing of a window
    00595     emit sigMessageWindowClosed();
    00596
    00597     //cancel the download if desired
    00598     if( ret == KDialogBase::Rejected )
    00599     {
    00600       MailsToShow.clear();
    00601       commitDownloading();
    00602       return;
    00603     }
    00604
    00605     //remove the first item of the list of mails to show
    00606     MailsToShow.remove( MailsToShow.begin() );
    00607
    00608     //if the list of mails is empty, finalize the showing and return
    00609     if( MailsToShow.empty() )
    00610     {
    00611       commitDownloading();
    00612       return;
    00613     }
    00614   }
    00615
    00616
    00617   //show next mail in list
    00618   showNextMail();
    00619 }
    00620
    00621 void ConfigElem::slotFinalizeShowMail( TDEIO::Job* )
    00622 {
    00623   //stop timeout time
    00624   pop3Timer->stop();
    00625
    00626   //set account state to idle
    00627   state = AccountIdle;
    00628
    00629   //emit signal to report the download is ready
    00630   emit sigShowBodiesReady( m_strAccount );
    00631 }
    00632
    00633 void ConfigElem::slotDataMailBody( TDEIO::Job *, const TQByteArray & datas )
    00634 {
    00635   if( !datas.isEmpty() )
    00636   {
    00637     //we get the next part of the mail
    00638     //append it
    00639     uint lastSize = mailbody.size();
    00640     mailbody.resize( lastSize + datas.size() );
    00641     for( uint i = 0; i < datas.size(); i++ )
    00642       mailbody[ lastSize + i ] = datas[ i ];
    00643   }
    00644 }
    00645
    00646 void ConfigElem::commitDownloading( )
    00647 {
    00648   //start job to commit
    00649   startKIOJob( TQString( "/commit" ) );
    00650   connect( pop3Job, TQ_SIGNAL( result( TDEIO::Job* ) ), this, TQ_SLOT( slotFinalizeShowMail( TDEIO::Job* ) ) );
    00651 }
    00652
    00653 void ConfigElem::refreshMailList( )
    00654 {
    00655   //return, if account is not active
    00656   if( !isActive() )
    00657   {
    00658     emit sigRefreshReady( m_strAccount );
    00659     return;
    00660   }
    00661
    00662   //check whether we have a password for this account
    00663   //if not, ask for it
    00664   //return when no password is available
    00665   if( !assertPassword() )
    00666   {
    00667     emit sigRefreshReady( m_strAccount );
    00668     return;
    00669   }
    00670
    00671   //create a new ShowRecord instance
    00672   //When the refresh has finished successfully, this will
    00673   //replace the old mail list
    00674   tempMailList = new ShowRecord();
    00675
    00676   //set account state
    00677   state = AccountRefreshing;
    00678
    00679   //the first step is to get the UIDs
    00680   getUIDs();
    00681 }
    00682
    00683 void ConfigElem::getUIDs( )
    00684 {
    00685   //clears the TQString list, which contains all received UIDs
    00686   receivedUIDs.clear();
    00687
    00688   //start job
    00689   startKIOJob( TQString( "/uidl" ) );
    00690   connect( pop3Job, TQ_SIGNAL( data( TDEIO::Job*, const TQByteArray & ) ), TQ_SLOT( slotReceiveUID( TDEIO::Job*, const TQByteArray & ) ) );
    00691   connect( pop3Job, TQ_SIGNAL( result( TDEIO::Job* ) ), this, TQ_SLOT( slotUIDsReceived( TDEIO::Job* ) ) );
    00692
    00693 }
    00694
    00695 void ConfigElem::slotReceiveUID( TDEIO::Job*, const TQByteArray& data )
    00696 {
    00697   //return, when data is empty
    00698   if( data.isEmpty() ) return;
    00699
    00700  //cast the data to TQString
    00701   TQString uid( data );
    00702
    00703   //insert the uid at the end of the UID list
    00704   receivedUIDs.append( uid );
    00705 }
    00706
    00707 void ConfigElem::slotUIDsReceived( TDEIO::Job * job )
    00708 {
    00709   int number;                 //an extracted mail number
    00710   TQString uid;                //an extracted uid
    00711   bool corruptData = false;   //set to TRUE, if a data is corrupt
    00712   bool isNew = false;         //state of the received mail
    00713
    00714   //stop timeout timer
    00715   pop3Timer->stop();
    00716
    00717   //check for errors
    00718   //if an error has occured, the refresh will be canceled
    00719   //or will ask for a new password
    00720   if( job->error() == TDEIO::ERR_COULD_NOT_LOGIN )
    00721   {
    00722     //login failed, ask for a new password
    00723     job->showErrorDialog();
    00724     bool res = assertPassword( true );
    00725     if( res == true )
    00726     {
    00727       //we have got a new password, try again
    00728       delete tempMailList;
    00729       refreshMailList();
    00730     }
    00731     else
    00732       //we have not got a new password; cancel refresh
    00733       cancelRefresh();
    00734
    00735     return;
    00736   }
    00737   else if( job->error() != 0 )
    00738   {
    00739     //show error message if desired
    00740     if( appConfig->showConnectionErrors() )
    00741       job->showErrorDialog();
    00742
    00743     cancelRefresh();
    00744     return;
    00745   }
    00746
    00747   //analyze UIDs
    00748   if( !receivedUIDs.isEmpty() )
    00749   {
    00750     //iterate over all UIDs in the list
    00751     for ( TQStringList::Iterator it = receivedUIDs.begin(); it != receivedUIDs.end(); ++it )
    00752     {
    00753       TQString line = *it;
    00754
    00755       //every line has the format "number UID", e.g.: 1 bf10d38018de7c1d628d65288d722f6a
    00756       //get the position of the separating space
    00757       int positionOfSpace = line.find( " " );
    00758
    00759       //if no space was found, the line is corrupt
    00760       if( positionOfSpace == -1 )
    00761       {
    00762         kdError() << "ConfigElem::slotUIDsReceived: get a corrupt UID from " << dynamic_cast<TDEIO::SimpleJob*>(job)->url().host() << ". No space. : " << line << endl;
    00763         corruptData = true;
    00764       }
    00765       else
    00766       {
    00767         //extract mail number and uid
    00768         bool isNumber;
    00769         number = line.left( positionOfSpace ).toInt( &isNumber );
    00770         //check number
    00771         if( !isNumber )
    00772         {
    00773           //the first part is not a number
    00774           kdError() << "ConfigElem::slotUIDsReceived: get a corrupt UID from " << dynamic_cast<TDEIO::SimpleJob*>(job)->url().host() << ". No number found at begin. : " << line << endl;
    00775           corruptData = true;
    00776         }
    00777         else
    00778         {
    00779           //number is ok; extract uid
    00780           uid = line.mid( positionOfSpace + 1 );
    00781
    00782           //determine about new mail or not
    00783           if( !m_pshowrecord->hasMail( uid ) )
    00784           {
    00785             //the old list doesn't contain a mail with this uid
    00786             //the mail is new
    00787             isNew = true;
    00788           }
    00789           else if( appConfig->keepNew() && m_pshowrecord->isNew( uid ) )
    00790           {
    00791             //the mail is already in the old list
    00792             //but we will leave the state of formerly new mails, because the user wants it
    00793             isNew = true;
    00794           }
    00795           else
    00796             isNew = false;
    00797
    00798           //append mail to the list
    00799           tempMailList->appendNewMail( number, uid, isNew );
    00800
    00801         }
    00802       }
    00803     }
    00804
    00805     //if the data are ok, start the second step: get sizes
    00806     //otherwise cancel the refresh
    00807     if( !corruptData )
    00808       getSizes();
    00809     else
    00810       cancelRefresh();
    00811   }
    00812   else
    00813   {
    00814     //we haven't received any UIDs. The account has no mails.
    00815     //Commit refresh.
    00816     commitRefresh();
    00817   }
    00818
    00819 }
    00820
    00821 void ConfigElem::cancelRefresh()
    00822 {
    00823   //print error message
    00824   kdError() << m_strAccount << ": " << "Refresh canceled" << endl;
    00825
    00826   //delete the new mail list
    00827   delete tempMailList;
    00828
    00829   //delete old mail list and create a new empty one
    00830   delete m_pshowrecord;
    00831   m_pshowrecord = new ShowRecord();
    00832
    00833   //emit signal
    00834   emit sigRefreshReady( m_strAccount );
    00835
    00836   //set account state to idle
    00837   state = AccountIdle;
    00838
    00839   //we don't need an error message, because the TDEIO job has shown one
    00840 }
    00841
    00842 void ConfigElem::slotFinalizeRefresh( TDEIO::Job* )
    00843 {
    00844   //stop timeout time
    00845   pop3Timer->stop();
    00846
    00847   //delete old mail list
    00848   delete m_pshowrecord;
    00849
    00850   //assign the new list
    00851   if( tempMailList != NULL )
    00852     m_pshowrecord = tempMailList;
    00853   else
    00854     m_pshowrecord = new ShowRecord();
    00855
    00856   //emit signal
    00857   emit sigRefreshReady( m_strAccount );
    00858
    00859   //set account state to idle
    00860   state = AccountIdle;
    00861 }
    00862
    00863 void ConfigElem::commitRefresh( )
    00864 {
    00865   //start job to commit
    00866   startKIOJob( TQString( "/commit" ) );
    00867   connect( pop3Job, TQ_SIGNAL( result( TDEIO::Job* ) ), this, TQ_SLOT( slotFinalizeRefresh( TDEIO::Job* ) ) );
    00868 }
    00869
    00870 void ConfigElem::getSizes( )
    00871 {
    00872   //clears the TQString list, which contains all received UIDs
    00873   receivedSizes.clear();
    00874
    00875   //start job
    00876   startKIOJob( TQString( "/index" ) );
    00877   connect( pop3Job, TQ_SIGNAL( data( TDEIO::Job*, const TQByteArray & ) ), TQ_SLOT( slotReceiveSize( TDEIO::Job*, const TQByteArray & ) ) );
    00878   connect( pop3Job, TQ_SIGNAL( result( TDEIO::Job* ) ), this, TQ_SLOT( slotSizesReceived( TDEIO::Job* ) ) );
    00879
    00880 }
    00881
    00882 void ConfigElem::slotSizesReceived( TDEIO::Job * job )
    00883 {
    00884   int number;                 //an extracted mail number
    00885   long size;                   //an extracted size
    00886   bool corruptData = false;   //set to TRUE, if a data is corrupt
    00887
    00888   //stop timeout timer
    00889   pop3Timer->stop();
    00890
    00891   //check for errors
    00892   //if an error has occured, the refresh will be canceled
    00893   if( job->error() != 0 )
    00894   {
    00895     //show error message if desired
    00896     if( appConfig->showConnectionErrors() )
    00897       job->showErrorDialog();
    00898     cancelRefresh();
    00899     return;
    00900   }
    00901
    00902   //analyze UIDs
    00903   if( !receivedSizes.isEmpty() )
    00904   {
    00905     //iterate over all sizes in the list
    00906     for ( TQStringList::Iterator it = receivedSizes.begin(); it != receivedSizes.end(); ++it )
    00907     {
    00908       TQString line = *it;
    00909
    00910       //every line has the format "number size", e.g.: 1 1234
    00911       //get the position of the separating space
    00912       int positionOfSpace = line.find( " " );
    00913
    00914       //if no space was found, the line is corrupt
    00915       if( positionOfSpace == -1 )
    00916       {
    00917         kdError() << "ConfigElem::slotSizesReceived: get a corrupt size from " << dynamic_cast<TDEIO::SimpleJob*>(job)->url().host() << ". No space. : " << line << endl;
    00918         corruptData = true;
    00919       }
    00920       else
    00921       {
    00922         //extract mail number and size
    00923         bool isNumber;
    00924         number = line.left( positionOfSpace ).toInt( &isNumber );
    00925         //check number
    00926         if( !isNumber )
    00927         {
    00928           //the first part is not a number
    00929           kdError() << "ConfigElem::slotSizesReceived: get a corrupt size from " << dynamic_cast<TDEIO::SimpleJob*>(job)->url().host() << ". No number found at begin. : " << line << endl;
    00930           corruptData = true;
    00931         }
    00932         else
    00933         {
    00934           //number is ok; extract size
    00935           size = line.mid( positionOfSpace + 1 ).toLong( &isNumber );
    00936
    00937           //check size
    00938           if( !isNumber )
    00939           {
    00940             //the second part of the string is not a number
    00941             kdError() << "ConfigElem::slotSizesReceived: get a corrupt size from " << dynamic_cast<TDEIO::SimpleJob*>(job)->url().host() << ". No size found at end. : " << line << endl;
    00942             corruptData = true;
    00943           }
    00944           else
    00945           {
    00946             //size is ok
    00947             //set it
    00948             tempMailList->setSize( number, size );
    00949           }
    00950         }
    00951       }
    00952     }
    00953
    00954     //if the data are ok, start the third step: get headers
    00955     //otherwise cancel the refresh
    00956     if( !corruptData )
    00957       getHeaders();
    00958     else
    00959       cancelRefresh();
    00960   }
    00961 }
    00962
    00963 void ConfigElem::slotReceiveSize( TDEIO::Job *, const TQByteArray & data )
    00964 {
    00965   //return, when data is empty
    00966   if( data.isEmpty() ) return;
    00967
    00968  //cast the data to TQString
    00969   TQString size( data );
    00970
    00971   //insert the uid at the end of the sizes list
    00972   receivedSizes.append( size );
    00973
    00974 }
    00975
    00976 void ConfigElem::getHeaders( )
    00977 {
    00978   //get the numbers of all new mails
    00979   newMails = tempMailList->getNewMails();
    00980   if( newMails.empty() )
    00981   {
    00982     //no new mails available; copy the known headers from the old mail list
    00983     copyHeaders();
    00984     return;
    00985   }
    00986
    00987   //get the headers
    00988   getNextHeader();
    00989 }
    00990
    00991 void ConfigElem::getNextHeader( )
    00992 {
    00993   //if the list of mails empty, copy the known headers from the old mail list
    00994   if( newMails.empty() )
    00995   {
    00996     copyHeaders();
    00997     return;
    00998   }
    00999
    01000   //clear temporary header store
    01001   receivedHeader.resize( 0 );
    01002
    01003   //start job
    01004   startKIOJob( TQString( "/headers/%1" ).arg( *newMails.begin() ) );
    01005   connect( pop3Job, TQ_SIGNAL( data( TDEIO::Job*, const TQByteArray & ) ), this, TQ_SLOT( slotReceiveHeader( TDEIO::Job*, const TQByteArray & ) ) );
    01006   connect( pop3Job, TQ_SIGNAL( result( TDEIO::Job* ) ), this, TQ_SLOT( slotHeaderDownloaded( TDEIO::Job* ) ) );
    01007
    01008 }
    01009
    01010 void ConfigElem::slotHeaderDownloaded( TDEIO::Job * job )
    01011 {
    01012   //stop timeout timer
    01013   pop3Timer->stop();
    01014
    01015   //check for errors
    01016   //if an error is occured, the download will be canceled
    01017   if( job->error() != 0 )
    01018   {
    01019     //show error message if desired
    01020     if( appConfig->showConnectionErrors() )
    01021       job->showErrorDialog();
    01022
    01023     cancelRefresh();
    01024     return;
    01025   }
    01026
    01027   //store header
    01028   tempMailList->setHeader( *newMails.begin(), TQString( receivedHeader ) );
    01029
    01030   //remove the first item of the list of new mails
    01031   newMails.remove( newMails.begin() );
    01032
    01033   //if the list of new mails is empty, copy the headers of old mails to the new list
    01034   if( newMails.empty() )
    01035   {
    01036     copyHeaders();
    01037     return;
    01038   }
    01039
    01040   //get next header
    01041   getNextHeader();
    01042 }
    01043
    01044 void ConfigElem::copyHeaders( )
    01045 {
    01046   //get the UIDs of the old mails in the temporary mail list
    01047   TQStringList UIDs = tempMailList->getUIDsOfOldMails();
    01048
    01049   //iterate over all members of the list,
    01050   //get the header from the old list and store it in the new one
    01051   TQStringList::iterator it;
    01052   for ( it = UIDs.begin(); it != UIDs.end(); ++it )
    01053   {
    01054     TQString header = m_pshowrecord->getHeaderOf( *it );
    01055     tempMailList->setHeader( *it, header );
    01056   }
    01057
    01058   //commit refresh
    01059   commitRefresh();
    01060 }
    01061
    01062 void ConfigElem::slotReceiveHeader( TDEIO::Job *, const TQByteArray & data )
    01063 {
    01064   if( !data.isEmpty() )
    01065   {
    01066     //we get the next part of the mail
    01067     //append it
    01068     uint lastSize = receivedHeader.size();
    01069     receivedHeader.resize( lastSize + data.size() );
    01070     for( uint i = 0; i < data.size(); i++ )
    01071       receivedHeader[ lastSize + i ] = data[ i ];
    01072   }
    01073 }
    01074
    01075 int ConfigElem::getNumberNewMails( )
    01076 {
    01077   return m_pshowrecord->getNumberNewMails();
    01078 }
    01079
    01080 int ConfigElem::getNumberMails( )
    01081 {
    01082   return m_pshowrecord->getNumberMails();
    01083 }
    01084
    01085 long ConfigElem::getTotalSize( )
    01086 {
    01087   return m_pshowrecord->getTotalSize();
    01088 }
    01089
    01090 void ConfigElem::fillMailListView( KshowmailView* view )
    01091 {
    01092   m_pshowrecord->fillMailListView( view, m_strAccount );
    01093 }
    01094
    01095 void ConfigElem::refreshAccountListItem( )
    01096 {
    01097   if( m_pViewItem != NULL )
    01098   {
    01099     if( isActive() )
    01100     {
    01101       m_pViewItem->setText( 4, TQString( "%1" ).arg( getNumberMails(), 3 ) );
    01102       m_pViewItem->setText( 5, TQString( "%1" ).arg( getTotalSize(), 8 ) );
    01103     }
    01104     else
    01105     {
    01106       m_pViewItem->setText( 4, TQString( "???" ) );
    01107       m_pViewItem->setText( 5, TQString( "???" ) );
    01108     }
    01109   }
    01110 }
    01111
    01112 void ConfigElem::killPOP3Job( )
    01113 {
    01114   //just try to kill, if it is not idle
    01115   if( state != AccountIdle )
    01116   {
    01117     //kill a running job
    01118     if( pop3Job != NULL )
    01119       pop3Job->kill( true );
    01120
    01121     //stop timeout timer
    01122     pop3Timer->stop();
    01123
    01124     //call the appropriate finalize method
    01125     switch( state )
    01126     {
    01127       case AccountDeleting    : slotFinalizeDeletion( NULL ); break;
    01128       case AccountDownloading : slotFinalizeShowMail( NULL ); break;
    01129       case AccountRefreshing  : cancelRefresh(); break;
    01130
    01131       default : break;
    01132     }
    01133   }
    01134 }
    01135
    01136 int ConfigElem::showSelectedHeaders( )
    01137 {
    01138   //return, if no mails are selected
    01139   if( !hasSelectedMails() )
    01140     return ConfigElem::continueShowHeaders;
    01141
    01142   //order the mail list to show the headers of the selected mails
    01143   int ret = m_pshowrecord->showSelectedHeaders( m_strAccount );
    01144
    01145   return ret == ShowRecord::continueShowHeaders ? ConfigElem::continueShowHeaders : ConfigElem::cancelShowHeaders;
    01146 }
    01147
    01148 void ConfigElem::printSetup( ) const
    01149 {
    01150   kdDebug() << "Setup of " << m_strAccount << ":" << endl;
    01151   kdDebug() << "Host: " << m_url.host() << endl;
    01152   kdDebug() << "Protocol: " << m_url.protocol() << endl;
    01153   kdDebug() << "Port: " << m_url.port() << endl;
    01154   kdDebug() << "User: " << m_url.user() << endl;
    01155   kdDebug() << "Password: " << m_url.pass() << endl;
    01156
    01157   switch( PasswordStorage )
    01158   {
    01159     case CONFIG_VALUE_ACCOUNT_PASSWORD_DONT_SAVE    : kdDebug() << "Password Storage: don't save" << endl; break;
    01160     case CONFIG_VALUE_ACCOUNT_PASSWORD_SAVE_FILE    : kdDebug() << "Password Storage: save in file" << endl; break;
    01161     case CONFIG_VALUE_ACCOUNT_PASSWORD_SAVE_TDEWALLET : kdDebug() << "Password Storage: use TDEWallet" << endl; break;
    01162     default                                         : kdDebug() << "Password Storage: invalid value" << endl;
    01163
    01164   }
    01165
    01166   kdDebug() << "active: " << m_bActive << endl << endl;
    01167
    01168
    01169 }
    01170
    01171 void ConfigElem::setPasswordStorage( int storage )
    01172 {
    01173   if( storage == CONFIG_VALUE_ACCOUNT_PASSWORD_DONT_SAVE ||
    01174       storage == CONFIG_VALUE_ACCOUNT_PASSWORD_SAVE_FILE ||
    01175       storage == CONFIG_VALUE_ACCOUNT_PASSWORD_SAVE_TDEWALLET )
    01176
    01177     PasswordStorage = storage;
    01178
    01179   else
    01180
    01181     PasswordStorage =  DEFAULT_ACCOUNT_PASSWORD_STORAGE;
    01182 }
    01183
    01184 int ConfigElem::getPasswordStorage( ) const
    01185 {
    01186   return PasswordStorage;
    01187 }
    01188
    01189 TQString ConfigElem::getProtocol( bool upperCase ) const
    01190 {
    01191   if( upperCase )
    01192     return m_url.protocol().upper();
    01193   else
    01194     return m_url.protocol();
    01195 }
    01196
    01197 unsigned short int ConfigElem::getPort( ) const
    01198 {
    01199   return m_url.port();
    01200 }
    01201