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();