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.
Kolab issue678.

svn path=/branches/proko2/kdepim/; revision=395795
wilder-work
David Faure 21 years ago
parent 344acd67a4
commit 805dff2b4f
  1. 2
      cachedimapjob.cpp
  2. 39
      kmacctcachedimap.cpp
  3. 8
      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;

@ -277,7 +277,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();
}
@ -379,9 +382,41 @@ void KMAcctCachedImap::invalidateIMAPFolders( KMFolderCachedImap* folder )
}
//-----------------------------------------------------------------------------
void KMAcctCachedImap::addDeletedFolder( const QString& subFolderPath )
void KMAcctCachedImap::addDeletedFolder( KMFolder* folder )
{
if ( folder->folderType() != KMFolderTypeCachedImap )
return;
KMFolderCachedImap* storage = static_cast<KMFolderCachedImap*>(folder->storage());
mDeletedFolders << 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();
}
}
}
QStringList KMAcctCachedImap::deletedFolderPaths( const QString& subFolderPath ) const
{
mDeletedFolders.append( subFolderPath );
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;
@ -113,7 +114,7 @@ public:
/**
* Remember that a folder got explicitely deleted
*/
void addDeletedFolder( const QString& subFolderPath );
void addDeletedFolder( KMFolder* folder );
/**
* Ask if a folder was explicitely deleted in this session
@ -125,6 +126,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
*/

@ -400,7 +400,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 )
@ -1563,7 +1563,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);

@ -1020,7 +1020,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