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 
52 using namespace KMail;
53 
54 template <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 
71 RenameJob::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 
90 RenameJob::~RenameJob()
91 {
92 }
93 
94 // FIXME: move on the server for online imap given source and target are on the same server
95 void 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 
157 void 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
KMFolderDir * child() const
Returns the folder directory associated with this node or 0 if no such directory exists.
Definition: kmfolder.h:157
void readConfig(TDEConfig *config)
This is used by the storage to read the folder specific configuration.
Definition: kmfolder.cpp:161
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
RenameJob(FolderStorage *storage, const TQString &newName, KMFolderDir *newParent=0)
Create a new job.
Definition: renamejob.cpp:71
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