www.pudn.com > drawpad.zip > eundo.cpp
#include "stdafx.h"
#include "DrawPadDoc.h"
#include "entity.h"
#include "eundo.h"
UndoBuffer::UndoBuffer()
{
curEventGroup=NULL;
status=0;
}
UndoBuffer::~UndoBuffer()
{
clear();
}
void UndoBuffer::startRecord()
{
EventGroup *lastGroup;
status=1;
if(!eventGroups.IsEmpty()){
lastGroup=eventGroups.GetTail();
if (lastGroup->events.IsEmpty()){
curEventGroup=lastGroup;
return;
}
}
curEventGroup=new EventGroup();
eventGroups.AddTail(curEventGroup);
}
void UndoBuffer::stopRecord()
{
status=0;
}
void UndoBuffer::pushEventItem(EventItem *e)
{
if (curEventGroup!=NULL)
curEventGroup->events.AddTail(e);
}
int UndoBuffer::insertObject(ENT* obj)
{
EventItem *e;
if (status==0)
return 0;
e=new EventItem(EventItem.INSOBJ,obj,0);
pushEventItem(e);
return 1;
}
int UndoBuffer::deleteObject(ENT *obj)
{
EventItem *e;
if (status==0)
return 0;
e=new EventItem(EventItem.DELOBJ,obj,0);
pushEventItem(e);
return 1;
}
int UndoBuffer::modifyObject(ENT *obj)
{
EventItem *e;
ENT *clone;
if (status==0)
return 0;
if ( existObject(obj))
return 1;
clone=obj->Clone();
e=new EventItem(EventItem.MODOBJ,obj,clone);
pushEventItem(e);
return 1;
}
int UndoBuffer::existObject(ENT *obj)
{
POSITION pos=curEventGroup->events.GetHeadPosition();
while(pos!=NULL){
EventItem *e=curEventGroup->events.GetNext(pos);
if (e->obj == obj)
return 1;
}
return 0;
}
int UndoBuffer::modifySysVar(ENT *obj)
{
EventItem *e;
ENT *clone;
if (status==0)
return 0;
clone=obj->Clone();
e=new EventItem(EventItem.DELOBJ,clone,obj);
pushEventItem(e);
return 1;
}
EventItem *UndoBuffer::popEventItem()
{
EventItem *e;
if (curEventGroup==NULL)
return NULL;
if( curEventGroup->events.IsEmpty())
return NULL;
e=curEventGroup->events.GetTail();
curEventGroup->events.RemoveTail();
return e;
}
BOOL UndoBuffer::readyUndo()
{
if( eventGroups.IsEmpty())
return 0;
if( curEventGroup==NULL)
return 0;
if( curEventGroup->events.IsEmpty()){
if(popEventGroup()==0)
return 0;
}
return 1;
}
int UndoBuffer::popEventGroup()
{
if( eventGroups.IsEmpty())
return 0;
delete curEventGroup;
eventGroups.RemoveTail();
if( eventGroups.IsEmpty())
curEventGroup=NULL;
else
curEventGroup = eventGroups.GetTail();
return 1;
}
void UndoBuffer::clear()
{
EventGroup *eg;
EventItem *event;
while(!eventGroups.IsEmpty()){
eg=eventGroups.GetTail();
while(!eg->events.IsEmpty()){
event=eg->events.GetTail();
eg->events.RemoveTail();
if (event->type==EventItem::DELOBJ)
delete event->obj;
else if (event->type==EventItem::MODOBJ) // WUMING +2
delete event->clone;
delete event;
}
eventGroups.RemoveTail();
delete eg;
}
}
// Function: call this to start an undo block
// Use: use UNDO_BEGIN and UNDO_END to define an undo block
// instead of making such a call.
void api_undo_rec_start()
{
CDrawPadDoc *pDoc = CDrawPadDoc::CurrentDoc();
if( pDoc ) {
pDoc->UndoNestLevel ++;
if( pDoc->UndoNestLevel == 1 ) {
pDoc->undoBuf.startRecord();
pDoc->redoBuf.clear();
}
}
}
/*
{
CDrawPadDoc *pDoc = (CDrawPadDoc *)XuGetCurrentDoc();
if( pDoc ) {
pDoc->UndoNestLevel++;
if( pDoc->UndoNestLevel==1 ) {
pDoc->undoBuf.startRecord();
pDoc->redoBuf.clear();
}
}
}
*/
// wuming add ?
void api_undo_rec_stop()
{
CDrawPadDoc *pDoc = CDrawPadDoc::CurrentDoc();
if( pDoc ) {
ASSERT( pDoc->UndoNestLevel > 0 );
pDoc->UndoNestLevel --;
if( pDoc->UndoNestLevel == 0 ) {
pDoc->undoBuf.stopRecord();
}
}
}
/*
{
CDrawPadDoc *pDoc = (CDrawPadDoc *)XuGetCurrentDoc();
if( pDoc ) {
ASSERT(pDoc->UndoNestLevel>0);
if( pDoc->UndoNestLevel==1 ) {
pDoc->undoBuf.stopRecord();
}
pDoc->UndoNestLevel--;
}
}
*/
// is undo available?
// CDrawPadDoc.undoBuf.readyUndo();
// Is redo available?
// CDrawPadDoc.redoBuf.readyUndo();