kmail

undostack.cpp

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     info->destFolder->open();
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     info->destFolder->close();
00106     delete info;
00107   }
00108   else
00109   {
00110     // Sorry.. stack is empty..
00111     KMessageBox::sorry( kmkernel->mainWin(), i18n("There is nothing to undo."));
00112   }
00113 }
00114 
00115 void
00116 UndoStack::pushSingleAction(ulong serNum, KMFolder *folder, KMFolder *destFolder)
00117 {
00118   int id = newUndoAction( folder, destFolder );
00119   addMsgToAction( id, serNum );
00120 }
00121 
00122 void
00123 UndoStack::msgDestroyed( KMMsgBase* /*msg*/)
00124 {
00125   /*
00126    for(UndoInfo *info = mStack.first(); info; )
00127    {
00128       if (info->msgIdMD5 == msg->msgIdMD5())
00129       {
00130          mStack.removeRef( info );
00131          info = mStack.current();
00132       }
00133       else
00134          info = mStack.next();
00135    }
00136   */
00137 }
00138 
00139 void
00140 UndoStack::folderDestroyed( KMFolder *folder)
00141 {
00142    for( UndoInfo *info = mStack.first(); info; )
00143    {
00144       if ( (info->srcFolder == folder) ||
00145        (info->destFolder == folder) )
00146       {
00147          mStack.removeRef( info );
00148          info = mStack.current();
00149       }
00150       else
00151          info = mStack.next();
00152    }
00153    emit undoStackChanged();
00154 }
00155 
00156 }
00157 
00158 #include "undostack.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys