00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "renamejob.h"
00030 #include "copyfolderjob.h"
00031 #include "kmfolderimap.h"
00032 #include "kmfoldercachedimap.h"
00033 #include "folderstorage.h"
00034 #include "kmfolder.h"
00035 #include "kmfolderdir.h"
00036 #include "kmfoldermgr.h"
00037 #include "imapaccountbase.h"
00038 #include "kmacctimap.h"
00039 #include "kmacctcachedimap.h"
00040 #include "kmmsgbase.h"
00041
00042 #include <kdebug.h>
00043 #include <kurl.h>
00044 #include <kio/scheduler.h>
00045 #include <kio/job.h>
00046 #include <kio/global.h>
00047 #include <klocale.h>
00048 #include <config.h>
00049
00050 #include <qmap.h>
00051
00052 using namespace KMail;
00053
00054 template <typename T> static QStringList imapPaths( FolderStorage* storage )
00055 {
00056 QStringList rv;
00057 rv.append( static_cast<T>( storage )->imapPath() );
00058 KMFolderDir* dir = storage->folder()->child();
00059 if ( dir ) {
00060 KMFolderNode *node = dir->first();
00061 while ( node ) {
00062 if ( !node->isDir() ) {
00063 rv += imapPaths<T>( static_cast<KMFolder*>( node )->storage() );
00064 }
00065 node = dir->next();
00066 }
00067 }
00068 return rv;
00069 }
00070
00071 RenameJob::RenameJob( FolderStorage* storage, const QString& newName,
00072 KMFolderDir* newParent )
00073 : FolderJob( 0, tOther, (storage ? storage->folder() : 0) ),
00074 mStorage( storage ), mNewParent( newParent ),
00075 mNewName( newName ), mNewFolder( 0 ), mCopyFolderJob( 0 )
00076 {
00077 mStorageTempOpened = 0;
00078 if ( storage ) {
00079 mOldName = storage->name();
00080 if ( storage->folderType() == KMFolderTypeImap ) {
00081 mOldImapPath = static_cast<KMFolderImap*>(storage)->imapPath();
00082
00083 } else if ( storage->folderType() == KMFolderTypeCachedImap ) {
00084 mOldImapPath = static_cast<KMFolderCachedImap*>(storage)->imapPath();
00085 mOldImapPaths = imapPaths<KMFolderCachedImap*>( storage );
00086 }
00087 }
00088 }
00089
00090 RenameJob::~RenameJob()
00091 {
00092 }
00093
00094
00095 void RenameJob::execute()
00096 {
00097 if ( mNewParent )
00098 {
00099
00100 KMFolderType type = mStorage->folderType();
00101 if ( ( type == KMFolderTypeMbox || type == KMFolderTypeMaildir ) &&
00102 mNewParent->type() == KMStandardDir &&
00103 mStorage->folderType() != KMFolderTypeCachedImap )
00104 {
00105
00106 mStorage->rename( mNewName, mNewParent );
00107 emit renameDone( mNewName, true );
00108 deleteLater();
00109 return;
00110 }
00111
00112 mCopyFolderJob = new CopyFolderJob( mStorage, mNewParent );
00113 connect( mCopyFolderJob, SIGNAL(folderCopyComplete(bool)), SLOT(folderCopyComplete(bool)) );
00114 mCopyFolderJob->execute();
00115
00116 } else
00117 {
00118
00119 if ( mStorage->folderType() != KMFolderTypeImap )
00120 {
00121
00122 mStorage->rename( mNewName );
00123 emit renameDone( mNewName, true );
00124 deleteLater();
00125 return;
00126 }
00127 if ( mOldImapPath.isEmpty() )
00128 {
00129
00130 emit renameDone( mNewName, false );
00131 deleteLater();
00132 return;
00133 } else if ( mOldName == mNewName || mOldImapPath == "/INBOX/" ) {
00134 emit renameDone( mNewName, true );
00135 deleteLater();
00136 return;
00137 }
00138 ImapAccountBase* account = static_cast<KMFolderImap*>(mStorage)->account();
00139
00140 mNewImapPath = mOldImapPath;
00141 mNewImapPath = mNewImapPath.replace( mOldName, mNewName );
00142 KURL src( account->getUrl() );
00143 src.setPath( mOldImapPath );
00144 KURL dst( account->getUrl() );
00145 dst.setPath( mNewImapPath );
00146 KIO::SimpleJob *job = KIO::rename( src, dst, true );
00147 kdDebug(5006)<< "RenameJob::rename - " << src.prettyURL()
00148 << " |=> " << dst.prettyURL() << endl;
00149 ImapAccountBase::jobData jd( src.url() );
00150 account->insertJob( job, jd );
00151 KIO::Scheduler::assignJobToSlave( account->slave(), job );
00152 connect( job, SIGNAL(result(KIO::Job*)),
00153 SLOT(slotRenameResult(KIO::Job*)) );
00154 }
00155 }
00156
00157 void RenameJob::slotRenameResult( KIO::Job *job )
00158 {
00159 ImapAccountBase* account = static_cast<KMFolderImap*>(mStorage)->account();
00160 ImapAccountBase::JobIterator it = account->findJob(job);
00161 if ( it == account->jobsEnd() )
00162 {
00163 emit renameDone( mNewName, false );
00164 deleteLater();
00165 return;
00166 }
00167 if ( job->error() )
00168 {
00169 account->handleJobError( job, i18n("Error while renaming a folder.") );
00170 emit renameDone( mNewName, false );
00171 deleteLater();
00172 return;
00173 }
00174 account->removeJob(it);
00175
00176 if ( mStorage->folderType() == KMFolderTypeImap )
00177 static_cast<KMFolderImap*>(mStorage)->setImapPath( mNewImapPath );
00178
00179 account->changeSubscription( false, mOldImapPath );
00180
00181 account->changeSubscription( true, mNewImapPath );
00182
00183
00184 mStorage->rename( mNewName );
00185
00186 emit renameDone( mNewName, true );
00187 deleteLater();
00188 }
00189
00190 void RenameJob::folderCopyComplete(bool success)
00191 {
00192 kdDebug(5006) << k_funcinfo << success << endl;
00193 if ( !success ) {
00194 kdWarning(5006) << k_funcinfo << "could not copy folder" << endl;
00195 emit renameDone( mNewName, false );
00196 deleteLater();
00197 return;
00198 }
00199 mNewFolder = mCopyFolderJob->targetFolder();
00200 mCopyFolderJob = 0;
00201
00202 if ( mStorageTempOpened ) {
00203 mStorageTempOpened->close( "renamejob" );
00204 mStorageTempOpened = 0;
00205 }
00206
00207 kdDebug(5006) << "deleting old folder" << endl;
00208
00209
00210 QString oldconfig = "Folder-" + mStorage->folder()->idString();
00211 KConfig* config = KMKernel::config();
00212 QMap<QString, QString> entries = config->entryMap( oldconfig );
00213 KConfigGroupSaver saver(config, "Folder-" + mNewFolder->idString());
00214 for ( QMap<QString, QString>::Iterator it = entries.begin();
00215 it != entries.end(); ++it )
00216 {
00217 if ( it.key() == "Id" || it.key() == "ImapPath" ||
00218 it.key() == "UidValidity" )
00219 continue;
00220 config->writeEntry( it.key(), it.data() );
00221 }
00222 mNewFolder->readConfig( config );
00223
00224 if ( mNewFolder->child() &&
00225 ( mNewFolder->storage()->hasChildren() == FolderStorage::HasNoChildren ) )
00226 mNewFolder->storage()->updateChildrenState();
00227
00228
00229 mStorage->blockSignals( false );
00230 if ( mStorage->folderType() == KMFolderTypeImap )
00231 {
00232 kmkernel->imapFolderMgr()->remove( mStorage->folder() );
00233 } else if ( mStorage->folderType() == KMFolderTypeCachedImap )
00234 {
00235
00236 KMAcctCachedImap* acct = static_cast<KMFolderCachedImap*>(mStorage)->account();
00237 if ( acct ) {
00238 for ( QStringList::ConstIterator it = mOldImapPaths.constBegin(); it != mOldImapPaths.constEnd(); ++it )
00239 acct->addDeletedFolder( *it );
00240 }
00241 kmkernel->dimapFolderMgr()->remove( mStorage->folder() );
00242 } else if ( mStorage->folderType() == KMFolderTypeSearch )
00243 {
00244
00245 kdWarning(5006) << k_funcinfo << "cannot remove a search folder" << endl;
00246 } else {
00247 kmkernel->folderMgr()->remove( mStorage->folder() );
00248 }
00249
00250 emit renameDone( mNewName, true );
00251 }
00252
00253 #include "renamejob.moc"