kmail

undostack.cpp

Go to the documentation of this file.
00001 /*
00002     This file is part of KMail
00003 
00004     Copyright (C) 1999 Waldo Bastian (bastian@kde.org)
00005     Copyright (c) 2003 Zack Rusin <zack@kde.org>
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU General Public License
00009     version 2 as published by the Free Software Foundation.
00010 
00011     This software is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this library; see the file COPYING. If not, write to
00018     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019     Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #ifdef HAVE_CONFIG_H
00023 #include <config.h>
00024 #endif
00025 
00026 #include "undostack.h"
00027 
00028 #include "kmmainwin.h"
00029 #include "kmfolder.h"
00030 #include "kmmsgdict.h"
00031 
00032 #include <kmessagebox.h>
00033 #include <klocale.h>
00034 #include <kdebug.h>
00035 
00036 namespace KMail {
00037 
00038 UndoStack::UndoStack(int size)
00039   : QObject(0, "undostack"), mSize(size), mLastId(0),
00040     mCachedInfo(0)
00041 {
00042    mStack.setAutoDelete(true);
00043 }
00044 
00045 void UndoStack::clear()
00046 {
00047    mStack.clear();
00048 }
00049 
00050 int UndoStack::newUndoAction( KMFolder *srcFolder, KMFolder *destFolder )
00051 {
00052   UndoInfo *info = new UndoInfo;
00053   info->id         = ++mLastId;
00054   info->srcFolder  = srcFolder;
00055   info->destFolder = destFolder;
00056   if ((int) mStack.count() == mSize)
00057     mStack.removeLast();
00058   mStack.prepend( info );
00059   emit undoStackChanged();
00060   return info->id;
00061 }
00062 
00063 void UndoStack::addMsgToAction( int undoId, ulong serNum )
00064 {
00065   if ( !mCachedInfo || mCachedInfo->id != undoId ) {
00066     QPtrListIterator<UndoInfo> itr( mStack );
00067     while ( itr.current() ) {
00068       if ( itr.current()->id == undoId ) {
00069         mCachedInfo = itr.current();
00070         break;
00071       }
00072       ++itr;
00073     }
00074   }
00075 
00076   Q_ASSERT( mCachedInfo );
00077   mCachedInfo->serNums.append( serNum );
00078 }
00079 
00080 void UndoStack::undo()
00081 {
00082   KMMessage *msg;
00083   ulong serNum;
00084   int idx = -1;
00085   KMFolder *curFolder;
00086   if ( mStack.count() > 0 )
00087   {
00088     UndoInfo *info = mStack.take(0);
00089     emit undoStackChanged();
00090     QValueList<ulong>::iterator itr;
00091     KMFolderOpener openDestFolder(info->destFolder, "undodest");
00092     for( itr = info->serNums.begin(); itr != info->serNums.end(); ++itr ) {
00093       serNum = *itr;
00094       KMMsgDict::instance()->getLocation(serNum, &curFolder, &idx);
00095       if ( idx == -1 || curFolder != info->destFolder ) {
00096         kdDebug(5006)<<"Serious undo error!"<<endl;
00097         delete info;
00098         return;
00099       }
00100       msg = curFolder->getMsg( idx );
00101       info->srcFolder->moveMsg( msg );
00102       if ( info->srcFolder->count() > 1 )
00103         info->srcFolder->unGetMsg( info->srcFolder->count() - 1 );
00104     }
00105     delete info;
00106   }
00107   else
00108   {
00109     // Sorry.. stack is empty..
00110     KMessageBox::sorry( kmkernel->mainWin(), i18n("There is nothing to undo."));
00111   }
00112 }
00113 
00114 void
00115 UndoStack::pushSingleAction(ulong serNum, KMFolder *folder, KMFolder *destFolder)
00116 {
00117   int id = newUndoAction( folder, destFolder );
00118   addMsgToAction( id, serNum );
00119 }
00120 
00121 void
00122 UndoStack::msgDestroyed( KMMsgBase* /*msg*/)
00123 {
00124   /*
00125    for(UndoInfo *info = mStack.first(); info; )
00126    {
00127       if (info->msgIdMD5 == msg->msgIdMD5())
00128       {
00129          mStack.removeRef( info );
00130          info = mStack.current();
00131       }
00132       else
00133          info = mStack.next();
00134    }
00135   */
00136 }
00137 
00138 void
00139 UndoStack::folderDestroyed( KMFolder *folder)
00140 {
00141    for( UndoInfo *info = mStack.first(); info; )
00142    {
00143       if ( (info->srcFolder == folder) ||
00144        (info->destFolder == folder) )
00145       {
00146          mStack.removeRef( info );
00147          info = mStack.current();
00148       }
00149       else
00150          info = mStack.next();
00151    }
00152    emit undoStackChanged();
00153 }
00154 
00155 }
00156 
00157 #include "undostack.moc"