kmail

renamejob.cpp
1/*
2 * Copyright (c) 2004 Carsten Burghardt <burghardt@kde.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 *
17 * In addition, as a special exception, the copyright holders give
18 * permission to link the code of this program with any edition of
19 * the TQt library by Trolltech AS, Norway (or with modified versions
20 * of TQt that use the same license as TQt), and distribute linked
21 * combinations including the two. You must obey the GNU General
22 * Public License in all respects for all of the code used other than
23 * TQt. If you modify this file, you may extend this exception to
24 * your version of the file, but you are not obligated to do so. If
25 * you do not wish to do so, delete this exception statement from
26 * your version.
27 */
28
29#include "renamejob.h"
30#include "copyfolderjob.h"
31#include "kmfolderimap.h"
32#include "kmfoldercachedimap.h"
33#include "folderstorage.h"
34#include "kmfolder.h"
35#include "kmfolderdir.h"
36#include "kmfoldermgr.h"
37#include "imapaccountbase.h"
38#include "kmacctimap.h"
39#include "kmacctcachedimap.h"
40#include "kmmsgbase.h"
41
42#include <kdebug.h>
43#include <kurl.h>
44#include <tdeio/scheduler.h>
45#include <tdeio/job.h>
46#include <tdeio/global.h>
47#include <tdelocale.h>
48#include <config.h>
49
50#include <tqmap.h>
51
52using namespace KMail;
53
54template <typename T> static TQStringList imapPaths( FolderStorage* storage )
55{
56 TQStringList rv;
57 rv.append( static_cast<T>( storage )->imapPath() );
58 KMFolderDir* dir = storage->folder()->child();
59 if ( dir ) {
60 KMFolderNode *node = dir->first();
61 while ( node ) {
62 if ( !node->isDir() ) {
63 rv += imapPaths<T>( static_cast<KMFolder*>( node )->storage() );
64 }
65 node = dir->next();
66 }
67 }
68 return rv;
69}
70
71RenameJob::RenameJob( FolderStorage* storage, const TQString& newName,
72 KMFolderDir* newParent )
73 : FolderJob( 0, tOther, (storage ? storage->folder() : 0) ),
74 mStorage( storage ), mNewParent( newParent ),
75 mNewName( newName ), mNewFolder( 0 ), mCopyFolderJob( 0 )
76{
77 mStorageTempOpened = 0;
78 if ( storage ) {
79 mOldName = storage->name();
80 if ( storage->folderType() == KMFolderTypeImap ) {
81 mOldImapPath = static_cast<KMFolderImap*>(storage)->imapPath();
82// mOldImapPaths = imapPaths<KMFolderImap*>( storage );
83 } else if ( storage->folderType() == KMFolderTypeCachedImap ) {
84 mOldImapPath = static_cast<KMFolderCachedImap*>(storage)->imapPath();
85 mOldImapPaths = imapPaths<KMFolderCachedImap*>( storage );
86 }
87 }
88}
89
90RenameJob::~RenameJob()
91{
92}
93
94// FIXME: move on the server for online imap given source and target are on the same server
95void RenameJob::execute()
96{
97 if ( mNewParent )
98 {
99 // move the folder to a different parent
100 KMFolderType type = mStorage->folderType();
101 if ( ( type == KMFolderTypeMbox || type == KMFolderTypeMaildir ) &&
102 mNewParent->type() == KMStandardDir &&
103 mStorage->folderType() != KMFolderTypeCachedImap )
104 {
105 // local folders can handle this on their own
106 mStorage->rename( mNewName, mNewParent );
107 emit renameDone( mNewName, true );
108 deleteLater();
109 return;
110 }
111 // copy to the new folder
112 mCopyFolderJob = new CopyFolderJob( mStorage, mNewParent );
113 connect( mCopyFolderJob, TQ_SIGNAL(folderCopyComplete(bool)), TQ_SLOT(folderCopyComplete(bool)) );
114 mCopyFolderJob->execute();
115
116 } else
117 {
118 // only rename the folder
119 if ( mStorage->folderType() != KMFolderTypeImap )
120 {
121 // local and dimap folder handle this directly
122 mStorage->rename( mNewName );
123 emit renameDone( mNewName, true );
124 deleteLater();
125 return;
126 }
127 if ( mOldImapPath.isEmpty() )
128 {
129 // sanity
130 emit renameDone( mNewName, false );
131 deleteLater();
132 return;
133 } else if ( mOldName == mNewName || mOldImapPath == "/INBOX/" ) {
134 emit renameDone( mNewName, true ); // noop
135 deleteLater();
136 return;
137 }
138 ImapAccountBase* account = static_cast<KMFolderImap*>(mStorage)->account();
139 // first rename it on the server
140 mNewImapPath = mOldImapPath;
141 mNewImapPath = mNewImapPath.replace( mOldName, mNewName );
142 KURL src( account->getUrl() );
143 src.setPath( mOldImapPath );
144 KURL dst( account->getUrl() );
145 dst.setPath( mNewImapPath );
146 TDEIO::SimpleJob *job = TDEIO::rename( src, dst, true );
147 kdDebug(5006)<< "RenameJob::rename - " << src.prettyURL()
148 << " |=> " << dst.prettyURL() << endl;
149 ImapAccountBase::jobData jd( src.url() );
150 account->insertJob( job, jd );
151 TDEIO::Scheduler::assignJobToSlave( account->slave(), job );
152 connect( job, TQ_SIGNAL(result(TDEIO::Job*)),
153 TQ_SLOT(slotRenameResult(TDEIO::Job*)) );
154 }
155}
156
157void RenameJob::slotRenameResult( TDEIO::Job *job )
158{
159 ImapAccountBase* account = static_cast<KMFolderImap*>(mStorage)->account();
160 ImapAccountBase::JobIterator it = account->findJob(job);
161 if ( it == account->jobsEnd() )
162 {
163 emit renameDone( mNewName, false );
164 deleteLater();
165 return;
166 }
167 if ( job->error() )
168 {
169 account->handleJobError( job, i18n("Error while renaming a folder.") );
170 emit renameDone( mNewName, false );
171 deleteLater();
172 return;
173 }
174 account->removeJob(it);
175 // set the new path
176 if ( mStorage->folderType() == KMFolderTypeImap )
177 static_cast<KMFolderImap*>(mStorage)->setImapPath( mNewImapPath );
178 // unsubscribe old (we don't want ghosts)
179 account->changeSubscription( false, mOldImapPath );
180 // subscribe new
181 account->changeSubscription( true, mNewImapPath );
182
183 // local part (will set the new name)
184 mStorage->rename( mNewName );
185
186 emit renameDone( mNewName, true );
187 deleteLater();
188}
189
191{
192 kdDebug(5006) << k_funcinfo << success << endl;
193 if ( !success ) {
194 kdWarning(5006) << k_funcinfo << "could not copy folder" << endl;
195 emit renameDone( mNewName, false );
196 deleteLater();
197 return;
198 }
199 mNewFolder = mCopyFolderJob->targetFolder();
200 mCopyFolderJob = 0;
201
202 if ( mStorageTempOpened ) {
203 mStorageTempOpened->close( "renamejob" );
204 mStorageTempOpened = 0;
205 }
206
207 kdDebug(5006) << "deleting old folder" << endl;
208 // move complete or not necessary
209 // save our settings
210 TQString oldconfig = "Folder-" + mStorage->folder()->idString();
211 TDEConfig* config = KMKernel::config();
212 TQMap<TQString, TQString> entries = config->entryMap( oldconfig );
213 TDEConfigGroupSaver saver(config, "Folder-" + mNewFolder->idString());
214 for ( TQMap<TQString, TQString>::Iterator it = entries.begin();
215 it != entries.end(); ++it )
216 {
217 if ( it.key() == "Id" || it.key() == "ImapPath" ||
218 it.key() == "UidValidity" )
219 continue;
220 config->writeEntry( it.key(), it.data() );
221 }
222 mNewFolder->readConfig( config );
223 // make sure the children state is correct
224 if ( mNewFolder->child() &&
225 ( mNewFolder->storage()->hasChildren() == FolderStorage::HasNoChildren ) )
226 mNewFolder->storage()->updateChildrenState();
227
228 // delete the old folder
229 mStorage->blockSignals( false );
230 if ( mStorage->folderType() == KMFolderTypeImap )
231 {
232 kmkernel->imapFolderMgr()->remove( mStorage->folder() );
233 } else if ( mStorage->folderType() == KMFolderTypeCachedImap )
234 {
235 // tell the account (see KMFolderCachedImap::listDirectory2)
236 KMAcctCachedImap* acct = static_cast<KMFolderCachedImap*>(mStorage)->account();
237 if ( acct ) {
238 for ( TQStringList::ConstIterator it = mOldImapPaths.constBegin(); it != mOldImapPaths.constEnd(); ++it )
239 acct->addDeletedFolder( *it );
240 }
241 kmkernel->dimapFolderMgr()->remove( mStorage->folder() );
242 } else if ( mStorage->folderType() == KMFolderTypeSearch )
243 {
244 // invalid
245 kdWarning(5006) << k_funcinfo << "cannot remove a search folder" << endl;
246 } else {
247 kmkernel->folderMgr()->remove( mStorage->folder() );
248 }
249
250 emit renameDone( mNewName, true );
251}
252
253#include "renamejob.moc"
The FolderStorage class is the bass class for the storage related aspects of a collection of mail (a ...
virtual int rename(const TQString &newName, KMFolderDir *aParent=0)
Physically rename the folder.
virtual KMFolderType folderType() const
Returns the type of this folder.
KMail list that manages the contents of one directory that may contain folders and/or other directori...
Definition kmfolderdir.h:16
Mail folder.
Definition kmfolder.h:69
KMFolderDir * child() const
Returns the folder directory associated with this node or 0 if no such directory exists.
Definition kmfolder.h:157
void folderCopyComplete(bool success)
All messages are copied so remove the original folder.
void renameDone(TQString newName, bool success)
Emitted when the job is done, check the success bool.
void slotRenameResult(TDEIO::Job *job)
Rename the folder.
RenameJob(FolderStorage *storage, const TQString &newName, KMFolderDir *newParent=0)
Create a new job.
Definition renamejob.cpp:71
folderdiaquotatab.h
Definition aboutdata.cpp:40