Implement "Copy folder to" which allows one to copy a hierarchy of folders

to somewhere else in the tree. Works for all source folder types but not
for online imap or search target folders. Part of this is the result of
a merge of the "Move folder to" functionality in HEAD since some of the
infrastructure can be shared. The "move to" part is disabled, though,
since it appears to be somewhat buggy and lose metainformation, such
as folder types, for example. ContentsType (mail, event, etc) information
is retained for the copies. A few const correctness fixes here and there.

svn path=/branches/proko2/kdepim/; revision=404928
wilder-work
Till Adam 21 years ago
parent 52b7138c8e
commit 4b0d2e5d3a
  1. 2
      Makefile.am
  2. 203
      copyfolderjob.cpp
  3. 98
      copyfolderjob.h
  4. 7
      kmacctcachedimap.cpp
  5. 6
      kmacctcachedimap.h
  6. 5
      kmfolder.cpp
  7. 3
      kmfolder.h
  8. 2
      kmfolderdir.h
  9. 2
      kmfolderimap.h
  10. 35
      kmfoldermgr.cpp
  11. 12
      kmfoldermgr.h
  12. 169
      kmfoldertree.cpp
  13. 23
      kmfoldertree.h
  14. 36
      renamejob.cpp

@ -96,7 +96,7 @@ libkmailprivate_la_SOURCES = kmmessage.cpp kmmainwin.cpp configuredialog.cpp \
headerlistquicksearch.cpp acljobs.cpp folderdiaacltab.cpp \
partnodebodypart.cpp \
expirejob.cpp compactionjob.cpp jobscheduler.cpp callback.cpp \
listjob.cpp \
listjob.cpp renamejob.cpp copyfolderjob.cpp \
composercryptoconfiguration.ui \
warningconfiguration.ui smimeconfiguration.ui annotationjobs.cpp \
accountcombobox.cpp

@ -0,0 +1,203 @@
/**
* Copyright (c) 2005 Till Adam <adam@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of this program with any edition of
* the Qt library by Trolltech AS, Norway (or with modified versions
* of Qt that use the same license as Qt), and distribute linked
* combinations including the two. You must obey the GNU General
* Public License in all respects for all of the code used other than
* Qt. If you modify this file, you may extend this exception to
* your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from
* your version.
*/
#include "copyfolderjob.h"
#include "folderstorage.h"
#include "kmfolder.h"
#include "kmfolderdir.h"
#include "kmfoldertype.h"
#include "kmfoldermgr.h"
#include "kmcommands.h"
#include "kmmsgbase.h"
#include "undostack.h"
#include <kdebug.h>
#include <klocale.h>
#include <config.h>
using namespace KMail;
CopyFolderJob::CopyFolderJob( const FolderStorage* const storage, KMFolderDir* const newParent )
: FolderJob( 0, tOther, (storage ? storage->folder() : 0) ),
mStorage( storage ), mNewParent( newParent ),
mNewFolder( 0 ), mChildFolderNodeIterator( *mStorage->folder()->createChildFolder() ),
mNextChildFolder( 0 )
{
}
CopyFolderJob::~CopyFolderJob()
{
kdDebug(5006) << k_funcinfo << endl;
}
/*
* The basic strategy is to first create the target folder, then copy all the mail
* from the source to the target folder, then recurse for each of the folder's children
*/
void CopyFolderJob::execute()
{
createTargetDir();
copyMessagesToTargetDir();
}
void CopyFolderJob::copyMessagesToTargetDir()
{
// Hmmmm. Tasty hack. Can I have fries with that?
const_cast<FolderStorage*>( mStorage )->blockSignals( true );
// move all messages to the new folder
QPtrList<KMMsgBase> msgList;
for ( int i = 0; i < mStorage->count(); i++ )
{
const KMMsgBase* msgBase = mStorage->getMsgBase( i );
assert( msgBase );
msgList.append( msgBase );
}
if ( msgList.count() == 0 ) {
slotCopyNextChild(); // no contents, check subfolders
const_cast<FolderStorage*>( mStorage )->blockSignals( false );
} else {
KMCommand *command = new KMCopyCommand( mNewFolder, msgList );
connect( command, SIGNAL( completed( KMCommand * ) ),
this, SLOT( slotCopyCompleted( KMCommand * ) ) );
command->start();
}
}
void CopyFolderJob::slotCopyCompleted( KMCommand* command )
{
kdDebug(5006) << k_funcinfo << (command?command->result():0) << endl;
disconnect( command, SIGNAL( completed( KMCommand * ) ),
this, SLOT( slotCopyCompleted( KMCommand * ) ) );
const_cast<FolderStorage*>( mStorage )->blockSignals( false );
if ( command && command->result() != KMCommand::OK ) {
rollback();
}
// if we have children, recurse
if ( mStorage->folder()->child() ) {
slotCopyNextChild();
} else {
emit folderCopyComplete( true );
deleteLater();
}
}
void CopyFolderJob::slotCopyNextChild( bool success )
{
//kdDebug(5006) << k_funcinfo << endl;
if ( mNextChildFolder )
mNextChildFolder->close(); // refcount
// previous sibling failed
if ( !success ) {
kdDebug(5006) << "Failed to copy one subfolder, let's not continue: " << mNewFolder->prettyURL() << endl;
rollback();
emit folderCopyComplete( false );
deleteLater();
}
KMFolderNode* node = mChildFolderNodeIterator.current();
while ( node && node->isDir() ) {
++mChildFolderNodeIterator;
node = mChildFolderNodeIterator.current();
}
if ( node ) {
mNextChildFolder = static_cast<KMFolder*>(node);
++mChildFolderNodeIterator;
} else {
// no more children, we are done
emit folderCopyComplete( true );
deleteLater();
return;
}
KMFolderDir * const dir = mNewFolder->createChildFolder();
if ( !dir ) {
kdDebug(5006) << "Failed to create subfolders of: " << mNewFolder->prettyURL() << endl;
emit folderCopyComplete( false );
deleteLater();
return;
}
// let it do its thing and report back when we are ready to do the next sibling
mNextChildFolder->open(); // refcount
FolderJob* job = new CopyFolderJob( mNextChildFolder->storage(), dir);
connect( job, SIGNAL( folderCopyComplete( bool ) ),
this, SLOT( slotCopyNextChild( bool ) ) );
job->start();
}
// FIXME factor into CreateFolderJob and make async, so it works with online imap
// FIXME this is the same in renamejob. Refactor RenameJob to use a copy job and then delete
void CopyFolderJob::createTargetDir()
{
KMFolderMgr* folderMgr = kmkernel->folderMgr();
if ( mNewParent->type() == KMImapDir ) {
folderMgr = kmkernel->imapFolderMgr();
} else if ( mNewParent->type() == KMDImapDir ) {
folderMgr = kmkernel->dimapFolderMgr();
}
// get the default mailbox type
KConfig * const config = KMKernel::config();
KConfigGroupSaver saver(config, "General");
int deftype = config->readNumEntry("default-mailbox-format", 1);
if ( deftype < 0 || deftype > 1 ) deftype = 1;
// the type of the new folder
KMFolderType typenew =
( deftype == 0 ) ? KMFolderTypeMbox : KMFolderTypeMaildir;
if ( mNewParent->owner() )
typenew = mNewParent->owner()->folderType();
mNewFolder = folderMgr->createFolder( mStorage->name(), false, typenew, mNewParent );
if ( !mNewFolder )
{
kdWarning(5006) << k_funcinfo << "could not create folder" << endl;
emit folderCopyComplete( false );
deleteLater();
return;
}
// inherit the folder type
// FIXME we should probably copy over most if not all settings
mNewFolder->storage()->setContentsType( mStorage->contentsType() );
mNewFolder->storage()->writeConfig();
kdDebug(5006)<< "CopyJob::createTargetDir - " << mStorage->folder()->idString()
<< " |=> " << mNewFolder->idString() << endl;
}
void CopyFolderJob::rollback()
{
// FIXME do something
KMFolderMgr * const folderMgr = mNewFolder->createChildFolder()->manager();
folderMgr->remove( mNewFolder );
emit folderCopyComplete( false );
deleteLater();
}
#include "copyfolderjob.moc"

@ -0,0 +1,98 @@
/**
* Copyright (c) 2005 Till Adam <adam@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of this program with any edition of
* the Qt library by Trolltech AS, Norway (or with modified versions
* of Qt that use the same license as Qt), and distribute linked
* combinations including the two. You must obey the GNU General
* Public License in all respects for all of the code used other than
* Qt. If you modify this file, you may extend this exception to
* your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from
* your version.
*/
#ifndef COPYFOLDERJOB_H
#define COPYFOLDERJOB_H
#include "folderjob.h"
class FolderStorage;
class KMFolderDir;
class KMFolder;
class KMCommand;
class KMFolderNode;
namespace KMail {
/**
* Copy a hierarchy of folders somewhere else in the folder tree. Currently
* online imap folders are not supported as target folders, and the same is
* true for search folders where it does not make much sense for them to be
* target folders.
*/
class CopyFolderJob : public FolderJob
{
Q_OBJECT
public:
/**
* Create a new job
* @param storage of the folder that should be copied
* @param newParent the target parent folder
*/
CopyFolderJob( const FolderStorage* const storage, KMFolderDir* const newParent = 0 );
virtual ~CopyFolderJob();
virtual void execute();
protected slots:
/** Create the target directory under the new parent. */
void createTargetDir();
/** Copy all messages from the original folder to mNewFolder */
void copyMessagesToTargetDir();
/** Called when the CopyCommand has either succesfully completed copying
* the contents of our folder to the new location or failed. */
void slotCopyCompleted( KMCommand *command );
/** Called when the previous sibling's copy operation completed.
* @param success indicates whether the last copy was successful. */
void slotCopyNextChild( bool success = true );
/** Called when one of the operations of the foldre itself or one of it's
* child folders failed and the already created target folder needs to be
* removed again. */
void rollback();
signals:
/** Emitted when the job is done, check the success bool */
void folderCopyComplete( bool success );
protected:
const FolderStorage* const mStorage;
KMFolderDir* const mNewParent;
KMFolder* mNewFolder;
QPtrListIterator<KMFolderNode> mChildFolderNodeIterator;
KMFolder* mNextChildFolder;
};
} // namespace KMail
#endif /* COPYFOLDERJOB_H */

@ -387,7 +387,7 @@ void KMAcctCachedImap::addDeletedFolder( KMFolder* folder )
if ( folder->folderType() != KMFolderTypeCachedImap )
return;
KMFolderCachedImap* storage = static_cast<KMFolderCachedImap*>(folder->storage());
mDeletedFolders << storage->imapPath();
addDeletedFolder( storage->imapPath() );
kdDebug(5006) << k_funcinfo << storage->imapPath() << endl;
// Add all child folders too
@ -402,6 +402,11 @@ void KMAcctCachedImap::addDeletedFolder( KMFolder* folder )
}
}
void KMAcctCachedImap::addDeletedFolder( const QString& imapPath )
{
mDeletedFolders << imapPath;
}
QStringList KMAcctCachedImap::deletedFolderPaths( const QString& subFolderPath ) const
{
QStringList lst;

@ -116,6 +116,12 @@ public:
*/
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
*/

@ -805,4 +805,9 @@ void KMFolder::reallyAddCopyOfMsg( KMMessage* aMsg )
mStorage->reallyAddCopyOfMsg( aMsg );
}
bool KMFolder::isMoveable() const
{
return !isSystemFolder();
}
#include "kmfolder.moc"

@ -497,6 +497,9 @@ public:
bool ignoreNewMail() const { return mIgnoreNewMail; }
void setIgnoreNewMail( bool b ) { mIgnoreNewMail = b; }
/** Returns true if this folder can be moved */
bool isMoveable() const;
signals:
/** Emitted when the status, name, or associated accounts of this
folder changed. */

@ -52,7 +52,7 @@ public:
/** Returns the folder whose children we are holding */
KMFolder* owner() const { return mOwner; }
virtual KMFolderDirType type() { return mDirType; }
virtual KMFolderDirType folderDirType() const { return mDirType; }
protected:
KMFolder * mOwner;

@ -98,7 +98,7 @@ public:
virtual KMMessage* getMsg(int idx);
/** The path to the imap folder on the server */
void setImapPath(const QString &path) { mImapPath = path; }
QString imapPath() { return mImapPath; }
QString imapPath() const { return mImapPath; }
/** The highest UID in the folder */
ulong lastUid();

@ -30,6 +30,11 @@
#include "undostack.h"
#include "kmmsgdict.h"
#include "folderstorage.h"
#include "renamejob.h"
#include "copyfolderjob.h"
using KMail::RenameJob;
using KMail::CopyFolderJob;
//-----------------------------------------------------------------------------
KMFolderMgr::KMFolderMgr(const QString& aBasePath, KMFolderDirType dirType):
@ -577,4 +582,34 @@ uint KMFolderMgr::createId()
return newId;
}
//-----------------------------------------------------------------------------
void KMFolderMgr::moveFolder( KMFolder* folder, KMFolderDir *newParent )
{
renameFolder( folder, folder->name(), newParent );
}
//-----------------------------------------------------------------------------
void KMFolderMgr::renameFolder( KMFolder* folder, const QString& newName,
KMFolderDir *newParent )
{
RenameJob* job = new RenameJob( folder->storage(), newName, newParent );
connect( job, SIGNAL( renameDone( QString, bool ) ),
this, SLOT( slotRenameDone( QString, bool ) ) );
job->start();
}
//-----------------------------------------------------------------------------
void KMFolderMgr::copyFolder( KMFolder* folder, KMFolderDir *newParent )
{
kdDebug(5006) << "Copy folder: " << folder->prettyURL() << endl;
CopyFolderJob* job = new CopyFolderJob( folder->storage(), newParent );
job->start();
}
//-----------------------------------------------------------------------------
void KMFolderMgr::slotRenameDone( QString, bool success )
{
kdDebug(5006) << k_funcinfo << success << endl;
}
#include "kmfoldermgr.moc"

@ -124,6 +124,15 @@ public:
/** Create a new unique ID */
uint createId();
/** Move a folder */
void moveFolder( KMFolder* folder, KMFolderDir* newParent );
/** Rename or move a folder */
void renameFolder( KMFolder* folder, const QString& newName,
KMFolderDir* newParent = 0 );
/** Copy a folder */
void copyFolder( KMFolder* folder, KMFolderDir* newParent );
public slots:
/** GUI action: compact all folders that need to be compacted */
void compactAll() { compactAllFolders( true ); }
@ -134,6 +143,9 @@ public slots:
/** Called from KMFolder::remove when the folderstorage was removed */
void removeFolderAux(KMFolder* obsoleteFolder, bool success);
/** Called when the renaming of a folder is done */
void slotRenameDone( QString newName, bool success );
signals:
/** Emitted when the list of folders has changed. This signal is a hook
where clients like the KMFolderTree tree-view can connect. The signal

@ -923,6 +923,22 @@ void KMFolderTree::slotContextMenuRequested( QListViewItem *lvi,
i18n("&New Subfolder..."), this,
SLOT(addChildFolder()));
}
#ifdef DISABLED_BECAUSE_IT_IS_BUGGY
if ( fti->folder()->isMoveable() )
{
QPopupMenu *moveMenu = new QPopupMenu( folderMenu );
folderToPopupMenu( MoveFolder, this, &mMenuToFolder, moveMenu );
folderMenu->insertItem( i18n("&Move Folder To"), moveMenu );
}
#endif
if ( fti->folder()
&& fti->folder()->folderType() != KMFolderTypeImap ) {
// && fti->folder()->folderType() != KMFolderTypeSearch ) {
// copy folder
QPopupMenu *copyMenu = new QPopupMenu( folderMenu );
folderToPopupMenu( CopyFolder, this, &mMenuToFolder, copyMenu );
folderMenu->insertItem( i18n("&Copy Folder To"), copyMenu );
}
// Want to be able to display properties for ALL folders,
// so we can edit expiry properties.
@ -1623,5 +1639,158 @@ void KMFolderTree::showFolder( KMFolder* folder )
}
}
//-----------------------------------------------------------------------------
void KMFolderTree::folderToPopupMenu( MenuAction action, QObject *receiver,
KMMenuToFolder *aMenuToFolder, QPopupMenu *menu, QListViewItem *item )
{
while ( menu->count() )
{
QPopupMenu *popup = menu->findItem( menu->idAt( 0 ) )->popup();
if ( popup )
delete popup;
else
menu->removeItemAt( 0 );
}
// connect the signals
if ( action == MoveMessage || action == MoveFolder )
{
disconnect( menu, SIGNAL(activated(int)), receiver,
SLOT(moveSelectedToFolder(int)) );
connect( menu, SIGNAL(activated(int)), receiver,
SLOT(moveSelectedToFolder(int)) );
} else {
disconnect( menu, SIGNAL(activated(int)), receiver,
SLOT(copySelectedToFolder(int)) );
connect( menu, SIGNAL(activated(int)), receiver,
SLOT(copySelectedToFolder(int)) );
}
if ( !item ) {
item = firstChild();
// avoid a popup menu with the single entry 'Local Folders' if there
// are no IMAP accounts
if ( childCount() == 2 && action != MoveFolder ) { // only 'Local Folders' and 'Searches'
KMFolderTreeItem *fti = static_cast<KMFolderTreeItem*>( item );
if ( fti->protocol() == KFolderTreeItem::Search ) {
// skip 'Searches'
item = item->nextSibling();
fti = static_cast<KMFolderTreeItem*>( item );
}
folderToPopupMenu( action, receiver, aMenuToFolder, menu, fti->firstChild() );
return;
}
}
while ( item )
{
KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>( item );
if ( fti->protocol() == KFolderTreeItem::Search )
{
// skip search folders
item = item->nextSibling();
continue;
}
QString label = fti->text( 0 );
label.replace( "&","&&" );
if ( fti->firstChild() )
{
// new level
QPopupMenu* popup = new QPopupMenu( menu, "subMenu" );
folderToPopupMenu( action, receiver, aMenuToFolder, popup, fti->firstChild() );
bool subMenu = false;
if ( ( action == MoveMessage || action == CopyMessage ) &&
fti->folder() && !fti->folder()->noContent() )
subMenu = true;
if ( ( action == MoveFolder || action == CopyFolder )
&& ( !fti->folder() || ( fti->folder() && !fti->folder()->noChildren() ) ) )
subMenu = true;
if ( subMenu )
{
int menuId;
if ( action == MoveMessage || action == MoveFolder )
menuId = popup->insertItem( i18n("Move to This Folder"), -1, 0 );
else
menuId = popup->insertItem( i18n("Copy to This Folder"), -1, 0 );
popup->insertSeparator( 1 );
aMenuToFolder->insert( menuId, fti->folder() );
}
menu->insertItem( label, popup );
} else
{
// insert an item
int menuId = menu->insertItem( label );
if ( fti->folder() )
aMenuToFolder->insert( menuId, fti->folder() );
bool enabled = (fti->folder() ? true : false);
if ( fti->folder() &&
( fti->folder()->isReadOnly() || fti->folder()->noContent() ) )
enabled = false;
menu->setItemEnabled( menuId, enabled );
}
item = item->nextSibling();
}
}
//-----------------------------------------------------------------------------
void KMFolderTree::moveSelectedToFolder( int menuId )
{
moveOrCopyCurrentFolder( mMenuToFolder[ menuId ], true /*move*/ );
}
//-----------------------------------------------------------------------------
void KMFolderTree::copySelectedToFolder( int menuId )
{
moveOrCopyCurrentFolder( mMenuToFolder[ menuId ], false /*copy, don't move*/ );
}
//-----------------------------------------------------------------------------
void KMFolderTree::moveOrCopyCurrentFolder( KMFolder* destination, bool move )
{
KMFolder* folder = currentFolder();
KMFolderDir* parent = &(kmkernel->folderMgr()->dir());
if ( destination )
parent = destination->createChildFolder();
QString message =
i18n( "<qt>Cannot move or copy folder <b>%1</b> into a subfolder below itself.</qt>" ).
arg( folder->label() );
KMFolderDir* folderDir = parent;
// check that the folder can be moved
if ( folder && folder->child() )
{
while ( folderDir && ( folderDir != &kmkernel->folderMgr()->dir() ) &&
( folderDir != folder->parent() ) )
{
if ( folderDir->findRef( folder ) != -1 )
{
KMessageBox::error( this, message );
return;
}
folderDir = folderDir->parent();
}
}
if( folder && folder->child() && parent &&
( parent->path().find( folder->child()->path() + "/" ) == 0 ) ) {
KMessageBox::error( this, message );
return;
}
if( folder && folder->child()
&& ( parent == folder->child() ) ) {
KMessageBox::error( this, message );
return;
}
if ( move ) {
kdDebug(5006) << "move folder " << currentFolder()->label() << " to "
<< ( destination ? destination->label() : "Local Folders" ) << endl;
kmkernel->folderMgr()->moveFolder( folder, parent );
} else {
kmkernel->folderMgr()->copyFolder( folder, parent );
}
}
#include "kmfoldertree.moc"

@ -172,6 +172,18 @@ public:
{
mFolderToItem.remove( folder );
}
/** Valid actions for the folderToPopup method */
enum MenuAction {
CopyMessage,
MoveMessage,
CopyFolder,
MoveFolder
};
/** Generate a popup menu that contains all folders that can have content */
void folderToPopupMenu( MenuAction action, QObject *receiver, KMMenuToFolder *,
QPopupMenu *menu, QListViewItem *start = 0 );
signals:
/** The selected folder has changed */
@ -269,6 +281,11 @@ protected slots:
void slotNewMessageToMailingList();
/** For RMB move folder */
virtual void moveSelectedToFolder( int menuId );
/** For RMB copy folder */
virtual void copySelectedToFolder( int menuId );
protected:
/** Catch palette changes */
virtual bool event(QEvent *e);
@ -307,6 +324,9 @@ protected:
/** connect all signals */
void connectSignals();
/** Move or copy the current folder to destination */
void moveOrCopyCurrentFolder( KMFolder* destination, bool move=false );
private:
/** total column */
QListViewItemIterator mUpdateIterator;
@ -321,6 +341,9 @@ private:
KMMainWidget *mMainWidget;
bool mReloading;
QMap<const KMFolder*, KMFolderTreeItem*> mFolderToItem;
/** Map menu id into a folder */
KMMenuToFolder mMenuToFolder;
};
#endif

@ -53,7 +53,7 @@
using namespace KMail;
RenameJob::RenameJob( FolderStorage* storage, const QString& newName,
RenameJob::RenameJob( FolderStorage* storage, const QString& newName,
KMFolderDir* newParent )
: FolderJob( 0, tOther, (storage ? storage->folder() : 0) ),
mStorage( storage ), mNewParent( newParent ),
@ -101,7 +101,7 @@ void RenameJob::execute()
if ( deftype < 0 || deftype > 1 ) deftype = 1;
// the type of the new folder
KMFolderType typenew =
KMFolderType typenew =
( deftype == 0 ) ? KMFolderTypeMbox : KMFolderTypeMaildir;
if ( mNewParent->owner() )
typenew = mNewParent->owner()->folderType();
@ -123,7 +123,7 @@ void RenameJob::execute()
// create it on the server and wait for the folderAdded signal
connect( kmkernel->imapFolderMgr(), SIGNAL( changed() ),
this, SLOT( slotMoveMessages() ) );
KMFolderImap* imapFolder =
KMFolderImap* imapFolder =
static_cast<KMFolderImap*>(mNewParent->owner()->storage());
imapFolder->createFolder( mNewName );
} else if ( mNewParent->type() == KMDImapDir )
@ -149,12 +149,12 @@ void RenameJob::execute()
return;
}
if ( mOldImapPath.isEmpty() )
{
{
// sanity
emit renameDone( mNewName, false );
deleteLater();
return;
} else if ( mOldName == mNewName || mOldImapPath == "/INBOX/" ) {
} else if ( mOldName == mNewName ) {
emit renameDone( mNewName, true ); // noop
deleteLater();
return;
@ -225,7 +225,7 @@ void RenameJob::slotMoveMessages()
assert( msgBase );
msgList.append( msgBase );
}
if ( msgList.count() == 0 )
if ( msgList.count() == 0 )
{
slotMoveCompleted( 0 );
} else
@ -242,7 +242,7 @@ void RenameJob::slotMoveCompleted( KMCommand* command )
kdDebug(5006) << k_funcinfo << (command?command->result():0) << endl;
disconnect( command, SIGNAL( completed( KMCommand * ) ),
this, SLOT( slotMoveCompleted( KMCommand * ) ) );
if ( !command || command->result() == KMCommand::OK )
if ( !command || command->result() == KMCommand::OK )
{
kdDebug(5006) << "deleting old folder" << endl;
// move complete or not necessary
@ -251,38 +251,38 @@ void RenameJob::slotMoveCompleted( KMCommand* command )
KConfig* config = KMKernel::config();
QMap<QString, QString> entries = config->entryMap( oldconfig );
KConfigGroupSaver saver(config, "Folder-" + mNewFolder->idString());
for ( QMap<QString, QString>::Iterator it = entries.begin();
it != entries.end(); ++it )
for ( QMap<QString, QString>::Iterator it = entries.begin();
it != entries.end(); ++it )
{
if ( it.key() == "Id" || it.key() == "ImapPath" ||
if ( it.key() == "Id" || it.key() == "ImapPath" ||
it.key() == "UidValidity" )
continue;
config->writeEntry( it.key(), it.data() );
}
mNewFolder->readConfig( config );
// delete the old folder
mStorage->blockSignals( false );
if ( mStorage->folderType() == KMFolderTypeImap )
{
kmkernel->imapFolderMgr()->remove( mStorage->folder() );
} else if ( mStorage->folderType() == KMFolderTypeCachedImap )
} else if ( mStorage->folderType() == KMFolderTypeCachedImap )
{
// tell the account (see KMFolderCachedImap::listDirectory2)
KMAcctCachedImap* acct = static_cast<KMFolderCachedImap*>(mStorage)->account();
if ( acct )
acct->addDeletedFolder( mOldImapPath );
kmkernel->dimapFolderMgr()->remove( mStorage->folder() );
} else if ( mStorage->folderType() == KMFolderTypeSearch )
} else if ( mStorage->folderType() == KMFolderTypeSearch )
{
// invalid
kdWarning(5006) << k_funcinfo << "cannot remove a search folder" << endl;
} else {
kmkernel->folderMgr()->remove( mStorage->folder() );
}
emit renameDone( mNewName, true );
} else
} else
{
kdDebug(5006) << "rollback - deleting folder" << endl;
// move failed - rollback the last transaction
@ -291,7 +291,7 @@ void RenameJob::slotMoveCompleted( KMCommand* command )
if ( mNewFolder->folderType() == KMFolderTypeImap )
{
kmkernel->imapFolderMgr()->remove( mNewFolder );
} else if ( mNewFolder->folderType() == KMFolderTypeCachedImap )
} else if ( mNewFolder->folderType() == KMFolderTypeCachedImap )
{
// tell the account (see KMFolderCachedImap::listDirectory2)
KMFolderCachedImap* folder = static_cast<KMFolderCachedImap*>(mNewFolder->storage());
@ -299,14 +299,14 @@ void RenameJob::slotMoveCompleted( KMCommand* command )
if ( acct )
acct->addDeletedFolder( folder->imapPath() );
kmkernel->dimapFolderMgr()->remove( mNewFolder );
} else if ( mNewFolder->folderType() == KMFolderTypeSearch )
} else if ( mNewFolder->folderType() == KMFolderTypeSearch )
{
// invalid
kdWarning(5006) << k_funcinfo << "cannot remove a search folder" << endl;
} else {
kmkernel->folderMgr()->remove( mNewFolder );
}
emit renameDone( mNewName, false );
}
deleteLater();

Loading…
Cancel
Save