kmail

listjob.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2004 Carsten Burghardt <burghardt@kde.org>
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; version 2 of the License
00007  *
00008  *  This program is distributed in the hope that it will be useful,
00009  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  *  GNU General Public License for more details.
00012  *
00013  *  You should have received a copy of the GNU General Public License
00014  *  along with this program; if not, write to the Free Software
00015  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00016  *
00017  *  In addition, as a special exception, the copyright holders give
00018  *  permission to link the code of this program with any edition of
00019  *  the Qt library by Trolltech AS, Norway (or with modified versions
00020  *  of Qt that use the same license as Qt), and distribute linked
00021  *  combinations including the two.  You must obey the GNU General
00022  *  Public License in all respects for all of the code used other than
00023  *  Qt.  If you modify this file, you may extend this exception to
00024  *  your version of the file, but you are not obligated to do so.  If
00025  *  you do not wish to do so, delete this exception statement from
00026  *  your version.
00027  */
00028 
00029 #include "listjob.h"
00030 #include "kmessagebox.h"
00031 #include "kmfolderimap.h"
00032 #include "kmfoldercachedimap.h"
00033 #include "kmacctimap.h"
00034 #include "kmacctcachedimap.h"
00035 #include "folderstorage.h"
00036 #include "kmfolder.h"
00037 #include "progressmanager.h"
00038 using KPIM::ProgressManager;
00039 
00040 #include <kdebug.h>
00041 #include <kurl.h>
00042 #include <kio/scheduler.h>
00043 #include <kio/job.h>
00044 #include <kio/global.h>
00045 #include <klocale.h>
00046 
00047 #include <qstylesheet.h>
00048 
00049 #include <stdlib.h>
00050 
00051 using namespace KMail;
00052 
00053 ListJob::ListJob( ImapAccountBase* account, ImapAccountBase::ListType type,
00054     FolderStorage* storage, const QString& path, bool complete,
00055     KPIM::ProgressItem* item )
00056  : FolderJob( 0, tOther, (storage ? storage->folder() : 0) ),
00057    mStorage( storage ), mAccount( account ), mType( type ),
00058    mComplete( complete ),
00059    mHonorLocalSubscription( false ), mPath( path ),
00060    mParentProgressItem( item )
00061 {
00062 }
00063 
00064 ListJob::~ListJob()
00065 {
00066 }
00067 
00068 void ListJob::execute()
00069 {
00070   if ( mAccount->makeConnection() == ImapAccountBase::Error )
00071   {
00072     kdWarning(5006) << "ListJob - got no connection" << endl;
00073     delete this;
00074     return;
00075   } else if ( mAccount->makeConnection() == ImapAccountBase::Connecting )
00076   {
00077     // We'll wait for the connectionResult signal from the account.
00078     kdDebug(5006) << "ListJob - waiting for connection" << endl;
00079     connect( mAccount, SIGNAL( connectionResult(int, const QString&) ),
00080         this, SLOT( slotConnectionResult(int, const QString&) ) );
00081     return;
00082   }
00083   // this is needed until we have a common base class for d(imap)
00084   if ( mPath.isEmpty() )
00085   {
00086     if ( mStorage && mStorage->folderType() == KMFolderTypeImap ) {
00087       mPath = static_cast<KMFolderImap*>(mStorage)->imapPath();
00088     } else if ( mStorage && mStorage->folderType() == KMFolderTypeCachedImap ) {
00089       mPath = static_cast<KMFolderCachedImap*>(mStorage)->imapPath();
00090     } else {
00091       kdError(5006) << "ListJob - no valid path and no folder given" << endl;
00092       delete this;
00093       return;
00094     }
00095   }
00096   if ( mNamespace.isEmpty() && mStorage )
00097   {
00098     mNamespace = mAccount->namespaceForFolder( mStorage );
00099   }
00100   // create jobData
00101   ImapAccountBase::jobData jd;
00102   jd.total = 1; jd.done = 0;
00103   jd.cancellable = true;
00104   jd.parent = mDestFolder;
00105   jd.onlySubscribed = ( mType == ImapAccountBase::ListSubscribed ||
00106                         mType == ImapAccountBase::ListSubscribedNoCheck ||
00107                         mType == ImapAccountBase::ListFolderOnlySubscribed );
00108   jd.path = mPath;
00109   jd.curNamespace = mNamespace;
00110   if ( mParentProgressItem )
00111   {
00112     QString escapedStatus = mDestFolder ? QStyleSheet::escape( mDestFolder->prettyURL() )
00113                                         : QString::null;
00114     jd.progressItem = ProgressManager::createProgressItem(
00115         mParentProgressItem,
00116         "ListDir" + ProgressManager::getUniqueID(),
00117         escapedStatus,
00118         i18n("retrieving folders"),
00119         false,
00120         mAccount->useSSL() || mAccount->useTLS() );
00121     mParentProgressItem->setStatus( escapedStatus );
00122   }
00123 
00124   // make the URL
00125   QString ltype = "LIST";
00126   if ( mType == ImapAccountBase::ListSubscribed ||
00127        mType == ImapAccountBase::ListFolderOnlySubscribed )
00128     ltype = "LSUB";
00129   else if ( mType == ImapAccountBase::ListSubscribedNoCheck )
00130     ltype = "LSUBNOCHECK";
00131 
00132   QString section;
00133   if ( mComplete )
00134     section = ";SECTION=COMPLETE";
00135   else if ( mType == ImapAccountBase::ListFolderOnly ||
00136             mType == ImapAccountBase::ListFolderOnlySubscribed )
00137     section = ";SECTION=FOLDERONLY";
00138 
00139   KURL url = mAccount->getUrl();
00140   url.setPath( mPath
00141       + ";TYPE=" + ltype
00142       + section );
00143   // go
00144   //kdDebug(5006) << "start listjob for " << url.path() << endl;
00145   KIO::SimpleJob *job = KIO::listDir( url, false );
00146   KIO::Scheduler::assignJobToSlave( mAccount->slave(), job );
00147   mAccount->insertJob( job, jd );
00148   connect( job, SIGNAL(result(KIO::Job *)),
00149       this, SLOT(slotListResult(KIO::Job *)) );
00150   connect( job, SIGNAL(entries(KIO::Job *, const KIO::UDSEntryList &)),
00151       this, SLOT(slotListEntries(KIO::Job *, const KIO::UDSEntryList &)) );
00152 }
00153 
00154 void ListJob::slotConnectionResult( int errorCode, const QString& errorMsg )
00155 {
00156   Q_UNUSED( errorMsg );
00157   if ( !errorCode )
00158     execute();
00159   else {
00160     if ( mParentProgressItem )
00161       mParentProgressItem->setComplete();
00162     delete this;
00163   }
00164 }
00165 
00166 void ListJob::slotListResult( KIO::Job* job )
00167 {
00168   ImapAccountBase::JobIterator it = mAccount->findJob( job );
00169   if ( it == mAccount->jobsEnd() )
00170   {
00171     delete this;
00172     return;
00173   }
00174   if ( job->error() )
00175   {
00176     mAccount->handleJobError( job,
00177         i18n( "Error while listing folder %1: " ).arg((*it).path),
00178         true );
00179   } else
00180   {
00181     // transport the information, include the jobData
00182     emit receivedFolders( mSubfolderNames, mSubfolderPaths,
00183         mSubfolderMimeTypes, mSubfolderAttributes, *it );
00184     mAccount->removeJob( it );
00185   }
00186   delete this;
00187 }
00188 
00189 void ListJob::slotListEntries( KIO::Job* job, const KIO::UDSEntryList& uds )
00190 {
00191   ImapAccountBase::JobIterator it = mAccount->findJob( job );
00192   if ( it == mAccount->jobsEnd() )
00193   {
00194     delete this;
00195     return;
00196   }
00197   if( (*it).progressItem )
00198     (*it).progressItem->setProgress( 50 );
00199   QString name;
00200   KURL url;
00201   QString mimeType;
00202   QString attributes;
00203   for ( KIO::UDSEntryList::ConstIterator udsIt = uds.begin();
00204         udsIt != uds.end(); udsIt++ )
00205   {
00206     mimeType = QString::null;
00207     attributes = QString::null;
00208     for ( KIO::UDSEntry::ConstIterator eIt = (*udsIt).begin();
00209           eIt != (*udsIt).end(); eIt++ )
00210     {
00211       // get the needed information
00212       if ( (*eIt).m_uds == KIO::UDS_NAME )
00213         name = (*eIt).m_str;
00214       else if ( (*eIt).m_uds == KIO::UDS_URL )
00215         url = KURL((*eIt).m_str, 106); // utf-8
00216       else if ( (*eIt).m_uds == KIO::UDS_MIME_TYPE )
00217         mimeType = (*eIt).m_str;
00218       else if ( (*eIt).m_uds == KIO::UDS_EXTRA )
00219         attributes = (*eIt).m_str;
00220     }
00221     if ( (mimeType == "inode/directory" || mimeType == "message/digest"
00222           || mimeType == "message/directory")
00223          && name != ".." && (mAccount->hiddenFolders() || name.at(0) != '.') )
00224     {
00225       if ( mHonorLocalSubscription && mAccount->onlyLocallySubscribedFolders()
00226         && !mAccount->locallySubscribedTo( url.path() ) ) {
00227           continue;
00228       }
00229 
00230       // Some servers send _lots_ of duplicates
00231       // This check is too slow for huge lists
00232       if ( mSubfolderPaths.count() > 100 ||
00233            mSubfolderPaths.findIndex(url.path()) == -1 )
00234       {
00235         mSubfolderNames.append( name );
00236         mSubfolderPaths.append( url.path() );
00237         mSubfolderMimeTypes.append( mimeType );
00238         mSubfolderAttributes.append( attributes );
00239       }
00240     }
00241   }
00242 }
00243 
00244 
00245 void KMail::ListJob::setHonorLocalSubscription( bool value )
00246 {
00247   mHonorLocalSubscription = value;
00248 }
00249 
00250 bool KMail::ListJob::honorLocalSubscription() const
00251 {
00252   return mHonorLocalSubscription;
00253 }
00254 
00255 #include "listjob.moc"