mirror of
https://bitbucket.org/smil3y/kde-playground.git
synced 2025-02-24 10:52:52 +00:00
170 lines
6.2 KiB
C++
170 lines
6.2 KiB
C++
/*
|
|
Copyright (c) 2010 Klarälvdalens Datakonsult AB,
|
|
a KDAB Group company <info@kdab.com>
|
|
Author: Tobias Koenig <tokoe@kdab.com>
|
|
|
|
This library is free software; you can redistribute it and/or modify it
|
|
under the terms of the GNU Library General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or (at your
|
|
option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
|
License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to the
|
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
02110-1301, USA.
|
|
*/
|
|
|
|
#include "removecollectionrecursivetask.h"
|
|
|
|
#include <akonadi/kmime/messageflags.h>
|
|
#include <kimap/deletejob.h>
|
|
#include <kimap/expungejob.h>
|
|
#include <kimap/selectjob.h>
|
|
#include <kimap/storejob.h>
|
|
#include <kimap/closejob.h>
|
|
#include <klocale.h>
|
|
|
|
Q_DECLARE_METATYPE( KIMAP::DeleteJob* )
|
|
|
|
RemoveCollectionRecursiveTask::RemoveCollectionRecursiveTask( ResourceStateInterface::Ptr resource, QObject *parent )
|
|
: ResourceTask( CancelIfNoSession, resource, parent ),
|
|
mSession( 0 ), mFolderFound( false )
|
|
{
|
|
}
|
|
|
|
RemoveCollectionRecursiveTask::~RemoveCollectionRecursiveTask()
|
|
{
|
|
}
|
|
|
|
void RemoveCollectionRecursiveTask::doStart( KIMAP::Session *session )
|
|
{
|
|
mSession = session;
|
|
|
|
mFolderFound = false;
|
|
KIMAP::ListJob *listJob = new KIMAP::ListJob( session );
|
|
listJob->setIncludeUnsubscribed( !isSubscriptionEnabled() );
|
|
listJob->setQueriedNamespaces( serverNamespaces() );
|
|
connect( listJob, SIGNAL(mailBoxesReceived(QList<KIMAP::MailBoxDescriptor>,QList<QList<QByteArray> >)),
|
|
this, SLOT(onMailBoxesReceived(QList<KIMAP::MailBoxDescriptor>,QList<QList<QByteArray> >)) );
|
|
connect( listJob, SIGNAL(result(KJob*)), SLOT(onJobDone(KJob*)) );
|
|
listJob->start();
|
|
}
|
|
|
|
void RemoveCollectionRecursiveTask::onMailBoxesReceived( const QList< KIMAP::MailBoxDescriptor > &descriptors,
|
|
const QList< QList<QByteArray> >& )
|
|
{
|
|
const QString mailBox = mailBoxForCollection( collection() );
|
|
|
|
// We have to delete the deepest-nested folders first, so
|
|
// we use a map here that has the level of nesting as key.
|
|
QMultiMap<int, KIMAP::MailBoxDescriptor > foldersToDelete;
|
|
|
|
for ( int i = 0; i < descriptors.size(); ++i ) {
|
|
const KIMAP::MailBoxDescriptor descriptor = descriptors[ i ];
|
|
|
|
if ( descriptor.name == mailBox || descriptor.name.startsWith( mailBox + descriptor.separator ) ) { // a sub folder to delete
|
|
const QStringList pathParts = descriptor.name.split( descriptor.separator );
|
|
foldersToDelete.insert( pathParts.count(), descriptor );
|
|
}
|
|
}
|
|
|
|
if ( foldersToDelete.isEmpty() ) {
|
|
return;
|
|
}
|
|
|
|
mFolderFound = true;
|
|
|
|
// Now start the actual deletion work
|
|
mFolderIterator.reset( new QMapIterator<int, KIMAP::MailBoxDescriptor >( foldersToDelete ) );
|
|
mFolderIterator->toBack(); // we start with largest nesting value first
|
|
|
|
deleteNextMailbox();
|
|
}
|
|
|
|
void RemoveCollectionRecursiveTask::deleteNextMailbox()
|
|
{
|
|
if ( !mFolderIterator->hasPrevious() ) {
|
|
changeProcessed(); // finish the job
|
|
return;
|
|
}
|
|
|
|
mFolderIterator->previous();
|
|
const KIMAP::MailBoxDescriptor &descriptor = mFolderIterator->value();
|
|
kDebug() << descriptor.name;
|
|
|
|
// first select the mailbox
|
|
KIMAP::SelectJob *selectJob = new KIMAP::SelectJob( mSession );
|
|
selectJob->setMailBox( descriptor.name );
|
|
connect( selectJob, SIGNAL(result(KJob*)), SLOT(onJobDone(KJob*)) );
|
|
selectJob->start();
|
|
|
|
// mark all items as deleted
|
|
// This step shouldn't be required, but apparently some servers don't allow deleting, non empty mailboxes (although they should).
|
|
KIMAP::ImapSet allItems;
|
|
allItems.add( KIMAP::ImapInterval( 1, 0 ) ); // means 1:*
|
|
KIMAP::StoreJob *storeJob = new KIMAP::StoreJob( mSession );
|
|
storeJob->setSequenceSet( allItems );
|
|
storeJob->setFlags( KIMAP::MessageFlags() << Akonadi::MessageFlags::Deleted );
|
|
storeJob->setMode( KIMAP::StoreJob::AppendFlags );
|
|
// The result is explicitly ignored, since this can fail in the case of an empty folder
|
|
storeJob->start();
|
|
|
|
// Some IMAP servers don't allow deleting an opened mailbox, so make sure
|
|
// it's not opened (https://bugs.kde.org/show_bug.cgi?id=324932). CLOSE will
|
|
// also trigger EXPUNGE to take care of the messages deleted above
|
|
KIMAP::CloseJob *closeJob = new KIMAP::CloseJob( mSession );
|
|
closeJob->setProperty( "folderDescriptor", descriptor.name );
|
|
connect( closeJob, SIGNAL(result(KJob*)), SLOT(onCloseJobDone(KJob*)) );
|
|
closeJob->start();
|
|
}
|
|
|
|
void RemoveCollectionRecursiveTask::onCloseJobDone( KJob* job )
|
|
{
|
|
if ( job->error() ) {
|
|
changeProcessed();
|
|
kDebug( 5327 ) << "Failed to close the folder, resync the folder tree";
|
|
emitWarning( i18n( "Failed to delete the folder, restoring folder list." ) );
|
|
synchronizeCollectionTree();
|
|
} else {
|
|
KIMAP::DeleteJob *deleteJob = new KIMAP::DeleteJob( mSession );
|
|
deleteJob->setMailBox( job->property( "folderDescriptor" ).toString() );
|
|
connect( deleteJob, SIGNAL(result(KJob*)), SLOT(onDeleteJobDone(KJob*)) );
|
|
deleteJob->start();
|
|
}
|
|
}
|
|
|
|
|
|
void RemoveCollectionRecursiveTask::onDeleteJobDone( KJob* job )
|
|
{
|
|
if ( job->error() ) {
|
|
changeProcessed();
|
|
|
|
kDebug( 5327 ) << "Failed to delete the folder, resync the folder tree";
|
|
emitWarning( i18n( "Failed to delete the folder, restoring folder list." ) );
|
|
synchronizeCollectionTree();
|
|
} else {
|
|
deleteNextMailbox();
|
|
}
|
|
}
|
|
|
|
void RemoveCollectionRecursiveTask::onJobDone( KJob* job )
|
|
{
|
|
if ( job->error() ) {
|
|
changeProcessed();
|
|
|
|
kDebug( 5327 ) << "Failed to delete the folder, resync the folder tree";
|
|
emitWarning( i18n( "Failed to delete the folder, restoring folder list." ) );
|
|
synchronizeCollectionTree();
|
|
} else if ( !mFolderFound ) {
|
|
changeProcessed();
|
|
kDebug( 5327 ) << "Failed to find the folder to be deleted, resync the folder tree";
|
|
emitWarning( i18n( "Failed to find the folder to be deleted, restoring folder list." ) );
|
|
synchronizeCollectionTree();
|
|
}
|
|
}
|
|
|