From proko2:

Fix for deletion of folders with subfolders: those need to be removed first
(thanks Carsten for the hint). This is simply achieved by adding the imap paths
of all subfolders to the account's mDeletedFolders list, and at sync time,
asking the server to delete all those at the same time - in reverse order.

svn path=/branches/KDE_3_4_BRANCH/kdepim/; revision=395820
wilder-work
David Faure 21 years ago
parent 85fa8fecb8
commit 1b59ad1df7
  1. 2
      cachedimapjob.cpp
  2. 44
      kmacctcachedimap.cpp
  3. 16
      kmacctcachedimap.h
  4. 4
      kmfoldercachedimap.cpp
  5. 2
      kmmainwidget.cpp

@ -545,6 +545,8 @@ void CachedImapJob::slotDeleteNextFolder( KIO::Job *job )
return;
}
mAccount->removeDeletedFolder( (*it).path );
if( job->error() ) {
mAccount->handleJobError( job, i18n( "Error while deleting folder %1 on the server: " ).arg( (*it).path ) + '\n' );
delete this;

@ -267,7 +267,10 @@ void KMAcctCachedImap::postProcessNewMail( KMFolderCachedImap* folder, bool )
// instead of the user being stuck with "can't delete" every time.
// And we do it for _all_ deleted folders, even those that were deleted on the server in the first place (slotListResult).
// Otherwise this might have side effects much later (e.g. when regaining permissions to a folder we could see before)
#if 0 // this opens a race: delete a folder during a sync (after the sync checked that folder), and it'll be forgotten...
mDeletedFolders.clear();
#endif
mPreviouslyDeletedFolders.clear();
}
@ -367,9 +370,46 @@ void KMAcctCachedImap::invalidateIMAPFolders( KMFolderCachedImap* folder )
}
//-----------------------------------------------------------------------------
void KMAcctCachedImap::addDeletedFolder( const QString& subFolderPath )
void KMAcctCachedImap::addDeletedFolder( KMFolder* folder )
{
mDeletedFolders.append( subFolderPath );
if ( folder->folderType() != KMFolderTypeCachedImap )
return;
KMFolderCachedImap* storage = static_cast<KMFolderCachedImap*>(folder->storage());
addDeletedFolder( storage->imapPath() );
kdDebug(5006) << k_funcinfo << storage->imapPath() << endl;
// Add all child folders too
if( folder && folder->child() ) {
KMFolderNode *node = folder->child()->first();
while( node ) {
if( !node->isDir() ) {
addDeletedFolder( static_cast<KMFolder*>( node ) ); // recurse
}
node = folder->child()->next();
}
}
}
void KMAcctCachedImap::addDeletedFolder( const QString& imapPath )
{
mDeletedFolders << imapPath;
}
QStringList KMAcctCachedImap::deletedFolderPaths( const QString& subFolderPath ) const
{
QStringList lst;
for ( QStringList::const_iterator it = mDeletedFolders.begin(); it != mDeletedFolders.end(); ++it ) {
if ( (*it).startsWith( subFolderPath ) )
// We must reverse the order, so that sub sub sub folders are deleted first
lst.prepend( *it );
}
for ( QStringList::const_iterator it = mPreviouslyDeletedFolders.begin(); it != mPreviouslyDeletedFolders.end(); ++it ) {
if ( (*it).startsWith( subFolderPath ) )
lst.prepend( *it );
}
kdDebug(5006) << "KMAcctCachedImap::deletedFolderPaths for " << subFolderPath << " returning: " << lst << endl;
Q_ASSERT( !lst.isEmpty() );
return lst;
}
bool KMAcctCachedImap::isDeletedFolder( const QString& subFolderPath ) const

@ -38,6 +38,7 @@
class KMFolderCachedImap;
class KMFolderTreeItem;
class KMFolder;
namespace KMail {
class FolderJob;
class ImapJob;
@ -108,9 +109,15 @@ public:
virtual void invalidateIMAPFolders( KMFolderCachedImap* );
/**
* Remember that a folder got explicitely deleted
* Remember that a folder got explicitely deleted - including all child folders
*/
void addDeletedFolder( const QString& subFolderPath );
void addDeletedFolder( KMFolder* folder );
/**
* Remember that a folder got explicitely deleted - NOT including all child folders
* This is used when renaming a folder.
*/
void addDeletedFolder( const QString& imapPath );
/**
* Ask if a folder was explicitely deleted in this session
@ -122,6 +129,11 @@ public:
*/
bool isPreviouslyDeletedFolder( const QString& subFolderPath ) const;
/**
* return the imap path to the deleted folder, as well as the paths for any child folders
*/
QStringList deletedFolderPaths( const QString& subFolderPath ) const;
/**
* Remove folder from the "deleted folders" list
*/

@ -393,7 +393,7 @@ int KMFolderCachedImap::rename( const QString& aName,
// Make the change appear to the user with setLabel, but we'll do the change
// on the server during the next sync. The name() is the name at the time of
// the last sync. Only rename if the new one is different. If it's the same,
// the last sync. Only rename if the new one is different. If it's the same,
// don't rename, but also make sure the rename is reset, in the case of
// A -> B -> A renames.
if ( name() != aName )
@ -1584,7 +1584,7 @@ void KMFolderCachedImap::listDirectory2() {
if ( locallyDeleted ) {
kdDebug(5006) << subfolderPath << " was deleted locally => delete on server." << endl;
foldersForDeletionOnServer << subfolderPath;
foldersForDeletionOnServer += mAccount->deletedFolderPaths( subfolderPath ); // grab all subsubfolders too
} else {
kdDebug(5006) << subfolderPath << " is a new folder on the server => create local cache" << endl;
KMFolder* newFolder = folder()->child()->createFolder(mSubfolderNames[i], false, KMFolderTypeCachedImap);

@ -1078,7 +1078,7 @@ void KMMainWidget::slotRemoveFolder()
KMFolderCachedImap* storage = static_cast<KMFolderCachedImap*>( mFolder->storage() );
KMAcctCachedImap* acct = storage->account();
if ( acct )
acct->addDeletedFolder( storage->imapPath() );
acct->addDeletedFolder( mFolder );
kmkernel->dimapFolderMgr()->remove(mFolder);
}

Loading…
Cancel
Save