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 ...
Definition: folderstorage.h:80
virtual int rename(const TQString &newName, KMFolderDir *aParent=0)
Physically rename the folder.
virtual KMFolderType folderType() const
Returns the type of this folder.
Definition: folderstorage.h:96
virtual void updateChildrenState()
Updates the hasChildren() state.
void close(const char *owner, bool force=false)
Close folder.
virtual ChildrenState hasChildren() const
Returns if the folder has children, has no children or we don't know.
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
TQString idString() const
Returns a string that can be used to identify this folder.
Definition: kmfolder.cpp:705
void readConfig(TDEConfig *config)
This is used by the storage to read the folder specific configuration.
Definition: kmfolder.cpp:161
KMFolderDir * child() const
Returns the folder directory associated with this node or 0 if no such directory exists.
Definition: kmfolder.h:157
Copy a hierarchy of folders somewhere else in the folder tree.
Definition: copyfolderjob.h:51
KMFolder * targetFolder() const
Returns the newly created target folder.
Definition: copyfolderjob.h:69
void folderCopyComplete(bool success)
All messages are copied so remove the original folder.
Definition: renamejob.cpp:190
void renameDone(TQString newName, bool success)
Emitted when the job is done, check the success bool.
void slotRenameResult(TDEIO::Job *job)
Rename the folder.
Definition: renamejob.cpp:157
folderdiaquotatab.h
Definition: aboutdata.cpp:40