00001
00029 #include "renamejob.h"
00030 #include "kmfolderimap.h"
00031 #include "kmfoldercachedimap.h"
00032 #include "folderstorage.h"
00033 #include "kmfolder.h"
00034 #include "kmfolderdir.h"
00035 #include "kmfoldertype.h"
00036 #include "kmfoldermgr.h"
00037 #include "imapaccountbase.h"
00038 #include "kmacctimap.h"
00039 #include "kmacctcachedimap.h"
00040 #include "kmcommands.h"
00041 #include "kmmsgbase.h"
00042 #include "undostack.h"
00043
00044 #include <kdebug.h>
00045 #include <kurl.h>
00046 #include <kio/scheduler.h>
00047 #include <kio/job.h>
00048 #include <kio/global.h>
00049 #include <klocale.h>
00050 #include <config.h>
00051
00052 #include <qmap.h>
00053
00054 using namespace KMail;
00055
00056 RenameJob::RenameJob( FolderStorage* storage, const QString& newName,
00057 KMFolderDir* newParent )
00058 : FolderJob( 0, tOther, (storage ? storage->folder() : 0) ),
00059 mStorage( storage ), mNewParent( newParent ),
00060 mNewName( newName ), mNewFolder( 0 )
00061 {
00062 mOldName = storage->name();
00063 if ( storage->folderType() == KMFolderTypeImap ) {
00064 mOldImapPath = static_cast<KMFolderImap*>(storage)->imapPath();
00065 } else if ( storage->folderType() == KMFolderTypeCachedImap ) {
00066 mOldImapPath = static_cast<KMFolderCachedImap*>(storage)->imapPath();
00067 }
00068 }
00069
00070 RenameJob::~RenameJob()
00071 {
00072 }
00073
00074 void RenameJob::execute()
00075 {
00076 if ( mNewParent )
00077 {
00078
00079 KMFolderType type = mStorage->folderType();
00080 if ( ( type == KMFolderTypeMbox || type == KMFolderTypeMaildir ) &&
00081 mNewParent->type() == KMStandardDir )
00082 {
00083
00084 mStorage->rename( mNewName, mNewParent );
00085 emit renameDone( mNewName, true );
00086 deleteLater();
00087 return;
00088 }
00089
00090 KMFolderMgr* folderMgr = kmkernel->folderMgr();
00091 if ( mNewParent->type() == KMImapDir ) {
00092 folderMgr = kmkernel->imapFolderMgr();
00093 } else if ( mNewParent->type() == KMDImapDir ) {
00094 folderMgr = kmkernel->dimapFolderMgr();
00095 }
00096
00097
00098 KConfig *config = KMKernel::config();
00099 KConfigGroupSaver saver(config, "General");
00100 int deftype = config->readNumEntry("default-mailbox-format", 1);
00101 if ( deftype < 0 || deftype > 1 ) deftype = 1;
00102
00103
00104 KMFolderType typenew =
00105 ( deftype == 0 ) ? KMFolderTypeMbox : KMFolderTypeMaildir;
00106 if ( mNewParent->owner() )
00107 typenew = mNewParent->owner()->folderType();
00108
00109 mNewFolder = folderMgr->createFolder( mNewName, false, typenew, mNewParent );
00110 if ( !mNewFolder )
00111 {
00112 kdWarning(5006) << k_funcinfo << "could not create folder" << endl;
00113 emit renameDone( mNewName, false );
00114 deleteLater();
00115 return;
00116 }
00117 kdDebug(5006)<< "RenameJob::rename - " << mStorage->folder()->idString()
00118 << " |=> " << mNewFolder->idString() << endl;
00119
00120 if ( mNewParent->type() == KMImapDir )
00121 {
00122
00123
00124 connect( kmkernel->imapFolderMgr(), SIGNAL( changed() ),
00125 this, SLOT( slotMoveMessages() ) );
00126 KMFolderImap* imapFolder =
00127 static_cast<KMFolderImap*>(mNewParent->owner()->storage());
00128 imapFolder->createFolder( mNewName );
00129 } else if ( mNewParent->type() == KMDImapDir )
00130 {
00131 KMFolderCachedImap* newStorage = static_cast<KMFolderCachedImap*>(mNewFolder->storage());
00132 KMFolderCachedImap* owner = static_cast<KMFolderCachedImap*>(mNewParent->owner()->storage());
00133 newStorage->initializeFrom( owner );
00134 slotMoveMessages();
00135 } else
00136 {
00137
00138 slotMoveMessages();
00139 }
00140 } else
00141 {
00142
00143 if ( mStorage->folderType() != KMFolderTypeImap )
00144 {
00145
00146 mStorage->rename( mNewName );
00147 emit renameDone( mNewName, true );
00148 deleteLater();
00149 return;
00150 }
00151 if ( mOldImapPath.isEmpty() )
00152 {
00153
00154 emit renameDone( mNewName, false );
00155 deleteLater();
00156 return;
00157 } else if ( mOldName == mNewName || mOldImapPath == "/INBOX/" ) {
00158 emit renameDone( mNewName, true );
00159 deleteLater();
00160 return;
00161 }
00162 ImapAccountBase* account = static_cast<KMFolderImap*>(mStorage)->account();
00163
00164 mNewImapPath = mOldImapPath;
00165 mNewImapPath = mNewImapPath.replace( mOldName, mNewName );
00166 KURL src( account->getUrl() );
00167 src.setPath( mOldImapPath );
00168 KURL dst( account->getUrl() );
00169 dst.setPath( mNewImapPath );
00170 KIO::SimpleJob *job = KIO::rename( src, dst, true );
00171 kdDebug(5006)<< "RenameJob::rename - " << src.prettyURL()
00172 << " |=> " << dst.prettyURL() << endl;
00173 ImapAccountBase::jobData jd( src.url() );
00174 account->insertJob( job, jd );
00175 KIO::Scheduler::assignJobToSlave( account->slave(), job );
00176 connect( job, SIGNAL(result(KIO::Job*)),
00177 SLOT(slotRenameResult(KIO::Job*)) );
00178 }
00179 }
00180
00181 void RenameJob::slotRenameResult( KIO::Job *job )
00182 {
00183 ImapAccountBase* account = static_cast<KMFolderImap*>(mStorage)->account();
00184 ImapAccountBase::JobIterator it = account->findJob(job);
00185 if ( it == account->jobsEnd() )
00186 {
00187 emit renameDone( mNewName, false );
00188 deleteLater();
00189 return;
00190 }
00191 if ( job->error() )
00192 {
00193 account->handleJobError( job, i18n("Error while renaming a folder.") );
00194 emit renameDone( mNewName, false );
00195 deleteLater();
00196 return;
00197 }
00198 account->removeJob(it);
00199
00200 if ( mStorage->folderType() == KMFolderTypeImap )
00201 static_cast<KMFolderImap*>(mStorage)->setImapPath( mNewImapPath );
00202
00203 account->changeSubscription( false, mOldImapPath );
00204
00205 account->changeSubscription( true, mNewImapPath );
00206
00207
00208 mStorage->rename( mNewName );
00209
00210 emit renameDone( mNewName, true );
00211 deleteLater();
00212 }
00213
00214 void RenameJob::slotMoveMessages()
00215 {
00216 kdDebug(5006) << k_funcinfo << endl;
00217 disconnect( kmkernel->imapFolderMgr(), SIGNAL( changed() ),
00218 this, SLOT( slotMoveMessages() ) );
00219 mStorage->blockSignals( true );
00220
00221 QPtrList<KMMsgBase> msgList;
00222 for ( int i = 0; i < mStorage->count(); i++ )
00223 {
00224 KMMsgBase* msgBase = mStorage->getMsgBase( i );
00225 assert( msgBase );
00226 msgList.append( msgBase );
00227 }
00228 if ( msgList.count() == 0 )
00229 {
00230 slotMoveCompleted( 0 );
00231 } else
00232 {
00233 KMCommand *command = new KMMoveCommand( mNewFolder, msgList );
00234 connect( command, SIGNAL( completed( KMCommand * ) ),
00235 this, SLOT( slotMoveCompleted( KMCommand * ) ) );
00236 command->start();
00237 }
00238 }
00239
00240 void RenameJob::slotMoveCompleted( KMCommand* command )
00241 {
00242 kdDebug(5006) << k_funcinfo << (command?command->result():0) << endl;
00243 disconnect( command, SIGNAL( completed( KMCommand * ) ),
00244 this, SLOT( slotMoveCompleted( KMCommand * ) ) );
00245 if ( !command || command->result() == KMCommand::OK )
00246 {
00247 kdDebug(5006) << "deleting old folder" << endl;
00248
00249
00250 QString oldconfig = "Folder-" + mStorage->folder()->idString();
00251 KConfig* config = KMKernel::config();
00252 QMap<QString, QString> entries = config->entryMap( oldconfig );
00253 KConfigGroupSaver saver(config, "Folder-" + mNewFolder->idString());
00254 for ( QMap<QString, QString>::Iterator it = entries.begin();
00255 it != entries.end(); ++it )
00256 {
00257 if ( it.key() == "Id" || it.key() == "ImapPath" ||
00258 it.key() == "UidValidity" )
00259 continue;
00260 config->writeEntry( it.key(), it.data() );
00261 }
00262 mNewFolder->readConfig( config );
00263
00264
00265 mStorage->blockSignals( false );
00266 if ( mStorage->folderType() == KMFolderTypeImap )
00267 {
00268 kmkernel->imapFolderMgr()->remove( mStorage->folder() );
00269 } else if ( mStorage->folderType() == KMFolderTypeCachedImap )
00270 {
00271
00272 KMAcctCachedImap* acct = static_cast<KMFolderCachedImap*>(mStorage)->account();
00273 if ( acct )
00274 acct->addDeletedFolder( mOldImapPath );
00275 kmkernel->dimapFolderMgr()->remove( mStorage->folder() );
00276 } else if ( mStorage->folderType() == KMFolderTypeSearch )
00277 {
00278
00279 kdWarning(5006) << k_funcinfo << "cannot remove a search folder" << endl;
00280 } else {
00281 kmkernel->folderMgr()->remove( mStorage->folder() );
00282 }
00283
00284 emit renameDone( mNewName, true );
00285 } else
00286 {
00287 kdDebug(5006) << "rollback - deleting folder" << endl;
00288
00289 kmkernel->undoStack()->undo();
00290
00291 if ( mNewFolder->folderType() == KMFolderTypeImap )
00292 {
00293 kmkernel->imapFolderMgr()->remove( mNewFolder );
00294 } else if ( mNewFolder->folderType() == KMFolderTypeCachedImap )
00295 {
00296
00297 KMFolderCachedImap* folder = static_cast<KMFolderCachedImap*>(mNewFolder->storage());
00298 KMAcctCachedImap* acct = folder->account();
00299 if ( acct )
00300 acct->addDeletedFolder( folder->imapPath() );
00301 kmkernel->dimapFolderMgr()->remove( mNewFolder );
00302 } else if ( mNewFolder->folderType() == KMFolderTypeSearch )
00303 {
00304
00305 kdWarning(5006) << k_funcinfo << "cannot remove a search folder" << endl;
00306 } else {
00307 kmkernel->folderMgr()->remove( mNewFolder );
00308 }
00309
00310 emit renameDone( mNewName, false );
00311 }
00312 deleteLater();
00313 }
00314
00315 #include "renamejob.moc"