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, SIGNAL( timeout() ), this, 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_KWALLET )
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, SIGNAL( result( TDEIO::Job* ) ), this, 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 KIO 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, SIGNAL( result( TDEIO::Job* ) ), this, 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, SIGNAL( data( TDEIO::Job*, const TQByteArray & ) ), SLOT( slotDataMailBody( TDEIO::Job*, const TQByteArray & ) ) );
00545   connect( pop3Job, SIGNAL( result( TDEIO::Job* ) ), this, 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, SIGNAL( result( TDEIO::Job* ) ), this, 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, SIGNAL( data( TDEIO::Job*, const TQByteArray & ) ), SLOT( slotReceiveUID( TDEIO::Job*, const TQByteArray & ) ) );
00691   connect( pop3Job, SIGNAL( result( TDEIO::Job* ) ), this, 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 KIO 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, SIGNAL( result( TDEIO::Job* ) ), this, 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, SIGNAL( data( TDEIO::Job*, const TQByteArray & ) ), SLOT( slotReceiveSize( TDEIO::Job*, const TQByteArray & ) ) );
00878   connect( pop3Job, SIGNAL( result( TDEIO::Job* ) ), this, 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, SIGNAL( data( TDEIO::Job*, const TQByteArray & ) ), this, SLOT( slotReceiveHeader( TDEIO::Job*, const TQByteArray & ) ) );
01006   connect( pop3Job, SIGNAL( result( TDEIO::Job* ) ), this, 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_KWALLET : 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_KWALLET )
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 

Generated on Thu Jul 5 19:36:06 2007 for kshowmail by  doxygen 1.5.0