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 : TQObject(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 TQPtrListIterator<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 TQValueList<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"