listjob.cpp
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 TQt library by Trolltech AS, Norway (or with modified versions 00020 * of TQt that use the same license as TQt), 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 * TQt. 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 "tdemessagebox.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 <tdeio/scheduler.h> 00043 #include <tdeio/job.h> 00044 #include <tdeio/global.h> 00045 #include <tdelocale.h> 00046 00047 #include <tqstylesheet.h> 00048 00049 #include <stdlib.h> 00050 00051 using namespace KMail; 00052 00053 ListJob::ListJob( ImapAccountBase* account, ImapAccountBase::ListType type, 00054 FolderStorage* storage, const TQString& 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, TQT_SIGNAL( connectionResult(int, const TQString&) ), 00080 this, TQT_SLOT( slotConnectionResult(int, const TQString&) ) ); 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 TQString escapedStatus = mDestFolder ? TQStyleSheet::escape( mDestFolder->prettyURL() ) 00113 : TQString(); 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 TQString 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 TQString 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 TDEIO::SimpleJob *job = TDEIO::listDir( url, false ); 00146 TDEIO::Scheduler::assignJobToSlave( mAccount->slave(), job ); 00147 mAccount->insertJob( job, jd ); 00148 connect( job, TQT_SIGNAL(result(TDEIO::Job *)), 00149 this, TQT_SLOT(slotListResult(TDEIO::Job *)) ); 00150 connect( job, TQT_SIGNAL(entries(TDEIO::Job *, const TDEIO::UDSEntryList &)), 00151 this, TQT_SLOT(slotListEntries(TDEIO::Job *, const TDEIO::UDSEntryList &)) ); 00152 } 00153 00154 void ListJob::slotConnectionResult( int errorCode, const TQString& 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( TDEIO::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( TDEIO::Job* job, const TDEIO::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 TQString name; 00200 KURL url; 00201 TQString mimeType; 00202 TQString attributes; 00203 for ( TDEIO::UDSEntryList::ConstIterator udsIt = uds.begin(); 00204 udsIt != uds.end(); udsIt++ ) 00205 { 00206 mimeType = TQString(); 00207 attributes = TQString(); 00208 for ( TDEIO::UDSEntry::ConstIterator eIt = (*udsIt).begin(); 00209 eIt != (*udsIt).end(); eIt++ ) 00210 { 00211 // get the needed information 00212 if ( (*eIt).m_uds == TDEIO::UDS_NAME ) 00213 name = (*eIt).m_str; 00214 else if ( (*eIt).m_uds == TDEIO::UDS_URL ) 00215 url = KURL((*eIt).m_str, 106); // utf-8 00216 else if ( (*eIt).m_uds == TDEIO::UDS_MIME_TYPE ) 00217 mimeType = (*eIt).m_str; 00218 else if ( (*eIt).m_uds == TDEIO::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"