⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rs_undo.cpp

📁 qcad2.05可用于windows和linux的源码
💻 CPP
字号:
/****************************************************************************** $Id: rs_undo.cpp 1938 2004-12-09 23:09:53Z andrew $**** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.**** This file is part of the qcadlib Library project.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** Licensees holding valid qcadlib Professional Edition licenses may use ** this file in accordance with the qcadlib Commercial License** Agreement provided with the Software.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.ribbonsoft.com for further details.**** Contact info@ribbonsoft.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "rs_undo.h"/** * Default constructor. */RS_Undo::RS_Undo() {    undoList.setAutoDelete(true);    undoPointer = -1;    currentCycle = NULL;}/** * @return Number of Cycles that can be undone. */int RS_Undo::countUndoCycles() {    RS_DEBUG->print("RS_Undo::countUndoCycles");    return undoPointer+1;}/** * @return Number of Cycles that can be redone. */int RS_Undo::countRedoCycles() {    RS_DEBUG->print("RS_Undo::countRedoCycles");    return (int)undoList.count()-1-undoPointer;}/** * Adds an Undo Cycle at the current position in the list. * All Cycles after the new one are removed and the Undoabels * on them deleted. */void RS_Undo::addUndoCycle(RS_UndoCycle* i) {    RS_DEBUG->print("RS_Undo::addUndoCycle");	    undoList.insert(++undoPointer, i);	    RS_DEBUG->print("RS_Undo::addUndoCycle: ok");}/** * Starts a new cycle for one undo step. Every undoable that is * added after calling this method goes into this cycle. */void RS_Undo::startUndoCycle() {    RS_DEBUG->print("RS_Undo::startUndoCycle");    // definitely delete Undo Cycles and all Undoables in them    //   that cannot be redone now:    while ((int)undoList.count()>undoPointer+1 && (int)undoList.count()>0) {        RS_UndoCycle* l = undoList.last();        if (l!=NULL) {            RS_Undoable* u=NULL;            bool done = false;            do {                u = l->getFirstUndoable();                if (u!=NULL) {                    // Remove the pointer from _all_ cycles:					for (RS_UndoCycle* l2=undoList.first(); l2!=NULL; 						l2=undoList.next()) {						l2->removeUndoable(u);					}                    // Delete the Undoable for good:                    if (u->isUndone()) {                        removeUndoable(u);                    }                } else {                    done = true;                }            } while(!done);        }        // Remove obsolete undo cycles:        undoList.removeLast();    }	    currentCycle = new RS_UndoCycle();}/** * Adds an undoable to the current undo cycle. */void RS_Undo::addUndoable(RS_Undoable* u) {    RS_DEBUG->print("RS_Undo::addUndoable");	    if (currentCycle!=NULL) {        currentCycle->addUndoable(u);    } else {        RS_DEBUG->print(RS_Debug::D_WARNING,			"RS_Undo::addUndoable(): No undo cycle active.");    }}/** * Ends the current undo cycle. */void RS_Undo::endUndoCycle() {    addUndoCycle(currentCycle);    currentCycle = NULL;}/** * Undoes the last undo cycle. */void RS_Undo::undo() {    RS_DEBUG->print("RS_Undo::undo");    if (undoPointer>=0) {        RS_UndoCycle* i = undoList.at(undoPointer);        if (i!=NULL) {            for (RS_Undoable* u=i->undoables.first();                    u!=NULL; u=i->undoables.next()) {                u->changeUndoState();            }            undoPointer--;        }    }}/** * Redoes the undo cycle which was at last undone. */void RS_Undo::redo() {    RS_DEBUG->print("RS_Undo::redo");    if (undoPointer+1<(int)undoList.count()) {        undoPointer++;        RS_UndoCycle* i = undoList.at(undoPointer);        if (i!=NULL) {            for (RS_Undoable* u=i->undoables.first();                    u!=NULL; u=i->undoables.next()) {                u->changeUndoState();            }        }    }}/** * @return The undo item that is next if we're about to undo * or NULL. */RS_UndoCycle* RS_Undo::getUndoCycle() {	RS_UndoCycle* ret = NULL;	    RS_DEBUG->print("RS_Undo::getUndoCycle");    if (undoPointer>=0 && undoPointer<(int)undoList.count()) {        ret = undoList.at(undoPointer);    }    RS_DEBUG->print("RS_Undo::getUndoCycle: OK");    return ret;}/** * @return The redo item that is next if we're about to redo * or NULL. */RS_UndoCycle* RS_Undo::getRedoCycle() {    RS_DEBUG->print("RS_Undo::getRedoCycle");    if (undoPointer+1>=0 && undoPointer+1<(int)undoList.count()) {        return undoList.at(undoPointer+1);    }    return NULL;}/** * Dumps the undo list to stdout. */std::ostream& operator << (std::ostream& os, RS_Undo& l) {    os << "Undo List: " <<  "\n";    os << " Pointer is at: " << l.undoPointer << "\n";    for (RS_UndoCycle* i = l.undoList.first();            i!=NULL; i = l.undoList.next()) {        if (l.undoList.at()==l.undoPointer) {            os << " -->";        }		else {            os << "    ";		}        os << *i << "\n";    }    return os;}/** * Testing Undoables, Undo Cycles and the Undo container. */#ifdef RS_TESTbool RS_Undo::test() {    int i, k;    RS_UndoStub undo;    //RS_UndoCycle* c1;    RS_Undoable* u1;    std::cout << "Testing RS_Undo\n";    std::cout << "  Adding 500 cycles..";    // Add 500 Undo Cycles with i Undoables in every Cycle    for (i=1; i<=500; ++i) {        //c1 = new RS_UndoCycle();		undo.startUndoCycle();        for (k=1; k<=i; ++k) {            u1 = new RS_Undoable();            //c1->			undo.addUndoable(u1);        }        //undo.addUndoCycle(c1);		undo.endUndoCycle();    }    std::cout << "OK\n";    assert(undo.countUndoCycles()==500);    assert(undo.countRedoCycles()==0);    std::cout << "  Undo 500 cycles..";    // Undo all 500 cycles    for (i=1; i<=500; ++i) {        undo.undo();    }    std::cout << "OK\n";    assert(undo.countUndoCycles()==0);    assert(undo.countRedoCycles()==500);    std::cout << "  Redo 500 cycles..";    // Redo all 500 cycles    for (i=1; i<=500; ++i) {        undo.redo();    }    std::cout << "OK\n";    assert(undo.countUndoCycles()==500);    assert(undo.countRedoCycles()==0);    std::cout << "  Undo 250 cycles..";    // Undo all 500 cycles    for (i=1; i<=250; ++i) {        undo.undo();    }    std::cout << "OK\n";    assert(undo.countUndoCycles()==250);    assert(undo.countRedoCycles()==250);    std::cout << "  Adding 10 cycles..";    for (i=1; i<=10; ++i) {        //c1 = new RS_UndoCycle();		undo.startUndoCycle();        for (k=1; k<=10; ++k) {            u1 = new RS_Undoable();            //c1->addUndoable(u1);			undo.addUndoable(u1);        }        //undo.addUndoCycle(c1);		undo.endUndoCycle();    }    std::cout << "OK\n";    assert(undo.countUndoCycles()==260);    assert(undo.countRedoCycles()==0);    std::cout << "  Undo 5 cycles..";    for (i=1; i<=5; ++i) {        undo.undo();    }    std::cout << "OK\n";    assert(undo.countUndoCycles()==255);    assert(undo.countRedoCycles()==5);    std::cout << "  Redo 5 cycles..";    for (i=1; i<=5; ++i) {        undo.redo();    }    std::cout << "OK\n";    assert(undo.countUndoCycles()==260);    assert(undo.countRedoCycles()==0);    std::cout << "  Undo 15 cycles..";    for (i=1; i<=15; ++i) {        undo.undo();    }    std::cout << "OK\n";    assert(undo.countUndoCycles()==245);    assert(undo.countRedoCycles()==15);    std::cout << "  Adding 1 cycle..";    for (i=1; i<=1; ++i) {        //c1 = new RS_UndoCycle();		undo.startUndoCycle();        for (k=1; k<=10; ++k) {            u1 = new RS_Undoable();            //c1->addUndoable(u1);			undo.addUndoable(u1);        }        //undo.addUndoCycle(c1);		undo.endUndoCycle();    }    std::cout << "OK\n";    assert(undo.countUndoCycles()==246);    assert(undo.countRedoCycles()==0);    return true;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -