00001
00021 #ifdef HAVE_CONFIG_H
00022 #include <config.h>
00023 #endif
00024
00025 #include "kmacctcachedimap.h"
00026 using KMail::SieveConfig;
00027
00028 #include "imapprogressdialog.h"
00029 using KMail::IMAPProgressDialog;
00030
00031 #include "kmbroadcaststatus.h"
00032 #include "kmfoldertree.h"
00033 #include "kmfoldermgr.h"
00034 #include "kmfiltermgr.h"
00035 #include "kmfoldercachedimap.h"
00036 #include "kmmainwin.h"
00037 #include "kmkernel.h"
00038
00039 #include <kio/passdlg.h>
00040 #include <kio/scheduler.h>
00041 #include <kio/slave.h>
00042 #include <kmessagebox.h>
00043 #include <kdebug.h>
00044 #include <kstandarddirs.h>
00045 #include <kapplication.h>
00046 #include <kconfig.h>
00047
00048
00049 KMAcctCachedImap::KMAcctCachedImap( KMAcctMgr* aOwner,
00050 const QString& aAccountName )
00051 : KMail::ImapAccountBase( aOwner, aAccountName ), mFolder( 0 ),
00052 mProgressDialogEnabled( true ), mSyncActive( false )
00053 {
00054
00055 mAutoExpunge = false;
00056
00057 connect(KMBroadcastStatus::instance(), SIGNAL(signalAbortRequested()),
00058 this, SLOT(slotAbortRequested()));
00059 connect(&mIdleTimer, SIGNAL(timeout()), SLOT(slotIdleTimeout()));
00060 }
00061
00062
00063
00064 KMAcctCachedImap::~KMAcctCachedImap()
00065 {
00066 killAllJobs( true );
00067 delete mProgressDlg;
00068 }
00069
00070
00071
00072 QString KMAcctCachedImap::type() const
00073 {
00074 return "cachedimap";
00075 }
00076
00077 void KMAcctCachedImap::init() {
00078 ImapAccountBase::init();
00079
00080 setProgressDialogEnabled( true );
00081 }
00082
00083
00084 void KMAcctCachedImap::pseudoAssign( const KMAccount * a ) {
00085 mIdleTimer.stop();
00086 killAllJobs( true );
00087 if (mFolder)
00088 {
00089 mFolder->setContentState(KMFolderCachedImap::imapNoInformation);
00090 mFolder->setSubfolderState(KMFolderCachedImap::imapNoInformation);
00091 }
00092
00093 setProgressDialogEnabled(static_cast<const KMAcctCachedImap*>(a)->isProgressDialogEnabled());
00094
00095 ImapAccountBase::pseudoAssign( a );
00096 }
00097
00098 void KMAcctCachedImap::setPrefixHook() {
00099 if ( mFolder ) mFolder->setImapPath( prefix() );
00100 }
00101
00102
00103 void KMAcctCachedImap::setImapFolder(KMFolderCachedImap *aFolder)
00104 {
00105 mFolder = aFolder;
00106 mFolder->setImapPath(mPrefix);
00107 mFolder->setAccount( this );
00108 }
00109
00110
00111
00112 void KMAcctCachedImap::setAutoExpunge( bool )
00113 {
00114
00115 mAutoExpunge = false;
00116 }
00117
00118
00119 void KMAcctCachedImap::slotSlaveError(KIO::Slave *aSlave, int errorCode,
00120 const QString &errorMsg)
00121 {
00122 if (aSlave != mSlave) return;
00123 if (errorCode == KIO::ERR_SLAVE_DIED) slaveDied();
00124 if (errorCode == KIO::ERR_COULD_NOT_LOGIN) mAskAgain = TRUE;
00125
00126
00127
00128
00129 if ( !mErrorDialogIsActive )
00130 {
00131 mErrorDialogIsActive = true;
00132 KMessageBox::messageBox(kapp->activeWindow(), KMessageBox::Error,
00133 KIO::buildErrorString(errorCode, errorMsg),
00134 i18n("Error"));
00135 mErrorDialogIsActive = false;
00136 } else
00137 kdDebug(5006) << "suppressing error:" << errorMsg << endl;
00138
00139 mSyncActive = false;
00140 }
00141
00142
00143
00144 void KMAcctCachedImap::displayProgress()
00145 {
00146 if (mProgressEnabled == mapJobData.isEmpty())
00147 {
00148 mProgressEnabled = !mapJobData.isEmpty();
00149 KMBroadcastStatus::instance()->setStatusProgressEnable( "I" + mName,
00150 mProgressEnabled );
00151 if (!mProgressEnabled) kmkernel->filterMgr()->deref(true);
00152 }
00153 mIdle = FALSE;
00154 if( mapJobData.isEmpty() )
00155 mIdleTimer.start(0);
00156 else
00157 mIdleTimer.stop();
00158 int total = 0, done = 0;
00159
00160 for (QMap<KIO::Job*, jobData>::Iterator it = mapJobData.begin();
00161 it != mapJobData.end(); ++it)
00162 {
00163 total += (*it).total;
00164 if( (*it).parent )
00165 done += static_cast<KMFolderCachedImap*>((*it).parent)->progress();
00166 else
00167 done += (*it).done;
00168 }
00169 if (total == 0)
00170 {
00171 mTotal = 0;
00172 return;
00173 }
00174
00175
00176 KMBroadcastStatus::instance()->setStatusProgressPercent( "I" + mName,
00177 done / total );
00178
00179 }
00180
00181
00182
00183 void KMAcctCachedImap::slotIdleTimeout()
00184 {
00185 if (true)
00186 {
00187 if (mSlave) KIO::Scheduler::disconnectSlave(mSlave);
00188 mSlave = NULL;
00189 mIdleTimer.stop();
00190 } else {
00191 if (mSlave)
00192 {
00193 QByteArray packedArgs;
00194 QDataStream stream( packedArgs, IO_WriteOnly);
00195
00196 stream << (int) 'N';
00197
00198 KIO::SimpleJob *job = KIO::special(getUrl(), packedArgs, FALSE);
00199 KIO::Scheduler::assignJobToSlave(mSlave, job);
00200 connect(job, SIGNAL(result(KIO::Job *)),
00201 this, SLOT(slotSimpleResult(KIO::Job *)));
00202 }
00203 else mIdleTimer.stop();
00204 }
00205 }
00206
00207
00208
00209 void KMAcctCachedImap::slotAbortRequested()
00210 {
00211 killAllJobs();
00212 }
00213
00214
00215
00216 void KMAcctCachedImap::killAllJobs( bool disconnectSlave )
00217 {
00218 QMap<KIO::Job*, jobData>::Iterator it = mapJobData.begin();
00219 for (it = mapJobData.begin(); it != mapJobData.end(); ++it)
00220 if ((*it).parent)
00221 {
00222 KMFolderCachedImap *fld = static_cast<KMFolderCachedImap*>((*it).parent);
00223 fld->resetSyncState();
00224 fld->setContentState(KMFolderCachedImap::imapNoInformation);
00225 fld->setSubfolderState(KMFolderCachedImap::imapNoInformation);
00226 fld->sendFolderComplete(FALSE);
00227 }
00228 if (mSlave && mapJobData.begin() != mapJobData.end())
00229 {
00230 mSlave->kill();
00231 mSlave = 0;
00232 }
00233 mapJobData.clear();
00234
00235
00236 for( QPtrListIterator<CachedImapJob> it( mJobList ); it.current(); ++it )
00237 it.current()->setPassiveDestructor( true );
00238 mJobList.setAutoDelete(true);
00239 mJobList.clear();
00240 mJobList.setAutoDelete(false);
00241 displayProgress();
00242
00243 if ( disconnectSlave && slave() ) {
00244 KIO::Scheduler::disconnectSlave( slave() );
00245 mSlave = 0;
00246 }
00247
00248
00249 mSyncActive = false;
00250 }
00251
00252
00253
00254 void KMAcctCachedImap::killJobsForItem(KMFolderTreeItem * fti)
00255 {
00256 QMap<KIO::Job *, jobData>::Iterator it = mapJobData.begin();
00257 while (it != mapJobData.end())
00258 {
00259 if (it.data().parent == fti->folder())
00260 {
00261 killAllJobs();
00262 break;
00263 }
00264 else ++it;
00265 }
00266 }
00267
00268
00269
00270 void KMAcctCachedImap::slotSimpleResult(KIO::Job * job)
00271 {
00272 JobIterator it = findJob( job );
00273 bool quiet = false;
00274 if (it != mapJobData.end())
00275 {
00276 quiet = (*it).quiet;
00277 removeJob(it);
00278 }
00279 if (job->error())
00280 {
00281 if (!quiet) slotSlaveError(mSlave, job->error(),
00282 job->errorText() );
00283 if (job->error() == KIO::ERR_SLAVE_DIED) slaveDied();
00284 mSyncActive = false;
00285 }
00286 displayProgress();
00287 }
00288
00289
00290
00291 void KMAcctCachedImap::processNewMail( KMFolderCachedImap* folder,
00292 bool interactive )
00293 {
00294
00295 mAutoExpunge = false;
00296
00297
00298 if( mSyncActive ) {
00299 kdDebug(5006) << "Already processing new mail, won't start again\n";
00300 return;
00301 }
00302 mSyncActive = true;
00303
00304 emit newMailsProcessed(-1);
00305 if( interactive && isProgressDialogEnabled() ) {
00306 imapProgressDialog()->clear();
00307 imapProgressDialog()->show();
00308 imapProgressDialog()->raise();
00309 }
00310
00311 folder->setAccount(this);
00312 connect(folder, SIGNAL(folderComplete(KMFolderCachedImap*, bool)),
00313 this, SLOT(postProcessNewMail(KMFolderCachedImap*, bool)));
00314 folder->serverSync( interactive && isProgressDialogEnabled() );
00315 checkDone(false, 0);
00316 }
00317
00318 void KMAcctCachedImap::postProcessNewMail( KMFolderCachedImap* folder, bool )
00319 {
00320 mSyncActive = false;
00321 setCheckingMail( false );
00322 emit finishedCheck(false);
00323 disconnect(folder, SIGNAL(folderComplete(KMFolderCachedImap*, bool)),
00324 this, SLOT(postProcessNewMail(KMFolderCachedImap*, bool)));
00325
00326 }
00327
00328
00329
00330
00331
00332
00333
00334 void KMAcctCachedImap::readConfig( KConfig & config ) {
00335 ImapAccountBase::readConfig( config );
00336 setProgressDialogEnabled( config.readBoolEntry( "progressdialog", true ) );
00337 }
00338
00339 void KMAcctCachedImap::writeConfig( KConfig & config ) {
00340 ImapAccountBase::writeConfig( config );
00341 config.writeEntry( "progressdialog", isProgressDialogEnabled() );
00342 }
00343
00344 void KMAcctCachedImap::invalidateIMAPFolders()
00345 {
00346 invalidateIMAPFolders( mFolder );
00347 }
00348
00349 void KMAcctCachedImap::invalidateIMAPFolders( KMFolderCachedImap* folder )
00350 {
00351 folder->setAccount(this);
00352
00353 QStringList strList;
00354 QValueList<QGuardedPtr<KMFolder> > folderList;
00355 kmkernel->dimapFolderMgr()->createFolderList( &strList, &folderList,
00356 folder->child(), QString::null,
00357 false );
00358 QValueList<QGuardedPtr<KMFolder> >::Iterator it;
00359 mCountRemainChecks = 0;
00360 mCountLastUnread = 0;
00361
00362 if( folderList.count() > 0 )
00363 for( it = folderList.begin(); it != folderList.end(); ++it ) {
00364 KMFolder *folder = *it;
00365 if( folder && folder->folderType() == KMFolderTypeCachedImap ) {
00366 KMFolderCachedImap *cfolder = static_cast<KMFolderCachedImap*>(folder);
00367
00368 cfolder->setUidValidity("INVALID");
00369 cfolder->writeUidCache();
00370 }
00371 }
00372 folder->setUidValidity("INVALID");
00373 folder->writeUidCache();
00374
00375 processNewMail(false);
00376 }
00377
00378
00379 void KMAcctCachedImap::listDirectory(QString path, bool onlySubscribed,
00380 bool secondStep, KMFolder* parent, bool reset)
00381 {
00382 ImapAccountBase::listDirectory( path, onlySubscribed, secondStep, parent, reset );
00383 }
00384
00385
00386 void KMAcctCachedImap::listDirectory()
00387 {
00388 mFolder->listDirectory();
00389 }
00390
00391 IMAPProgressDialog* KMAcctCachedImap::imapProgressDialog() const
00392 {
00393 if( !mProgressDlg ) {
00394 mProgressDlg = new IMAPProgressDialog( KMKernel::self()->mainWin() );
00395 }
00396 return mProgressDlg;
00397 }
00398
00399 #include "kmacctcachedimap.moc"