diff options
Diffstat (limited to 'kig/kig/kig_commands.cpp')
-rw-r--r-- | kig/kig/kig_commands.cpp | 398 |
1 files changed, 398 insertions, 0 deletions
diff --git a/kig/kig/kig_commands.cpp b/kig/kig/kig_commands.cpp new file mode 100644 index 00000000..b9846fa6 --- /dev/null +++ b/kig/kig/kig_commands.cpp @@ -0,0 +1,398 @@ +/** + This file is part of Kig, a KDE program for Interactive Geometry... + Copyright (C) 2002 Dominique Devriese <devriese@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + USA +**/ + +#include "kig_commands.h" +#include "kig_commands.moc" + +#include "kig_part.h" +#include "kig_document.h" +#include "kig_view.h" + +#include "../modes/mode.h" +#include "../objects/object_imp.h" +#include "../objects/object_drawer.h" +#include "../misc/calcpaths.h" +#include "../misc/coordinate_system.h" + +#include <vector> + +using std::vector; +using std::max; +using std::min; + +class KigCommand::Private +{ +public: + Private( KigPart& d ) : doc( d ) {} + KigPart& doc; + vector<KigCommandTask*> tasks; +}; + +KigCommand::KigCommand( KigPart& doc, const QString& name ) + : KNamedCommand(name), d( new Private( doc ) ) +{ +} + +KigCommand::~KigCommand() +{ + for ( uint i = 0; i < d->tasks.size(); ++i ) + delete d->tasks[i]; + delete d; +} + +void KigCommand::execute() +{ + for ( uint i = 0; i < d->tasks.size(); ++i ) + d->tasks[i]->execute( d->doc ); + d->doc.redrawScreen(); +} + +void KigCommand::unexecute() +{ + for ( uint i = 0; i < d->tasks.size(); ++i ) + d->tasks[i]->unexecute( d->doc ); + d->doc.redrawScreen(); +} + +void KigCommand::addTask( KigCommandTask* t ) +{ + d->tasks.push_back( t ); +} + +KigCommand* KigCommand::removeCommand( KigPart& doc, ObjectHolder* o ) +{ + std::vector<ObjectHolder*> os; + os.push_back( o ); + return removeCommand( doc, os ); +} + +KigCommand* KigCommand::addCommand( KigPart& doc, ObjectHolder* o ) +{ + std::vector<ObjectHolder*> os; + os.push_back( o ); + return addCommand( doc, os ); +} + +KigCommand* KigCommand::removeCommand( KigPart& doc, const std::vector<ObjectHolder*>& os ) +{ + assert( os.size() > 0 ); + QString text; + if ( os.size() == 1 ) + text = os.back()->imp()->type()->removeAStatement(); + else + text = i18n( "Remove %1 Objects" ).arg( os.size() ); + KigCommand* ret = new KigCommand( doc, text ); + ret->addTask( new RemoveObjectsTask( os ) ); + return ret; +} + +KigCommand* KigCommand::addCommand( KigPart& doc, const std::vector<ObjectHolder*>& os ) +{ + QString text; + if ( os.size() == 1 ) + text = os.back()->imp()->type()->addAStatement(); + else + text = i18n( "Add %1 Objects" ).arg( os.size() ); + KigCommand* ret = new KigCommand( doc, text ); + ret->addTask( new AddObjectsTask( os ) ); + return ret; +} + +KigCommand* KigCommand::changeCoordSystemCommand( KigPart& doc, CoordinateSystem* s ) +{ + QString text = CoordinateSystemFactory::setCoordinateSystemStatement( s->id() ); + KigCommand* ret = new KigCommand( doc, text ); + ret->addTask( new ChangeCoordSystemTask( s ) ); + return ret; +} + +KigCommandTask::KigCommandTask() +{ +} + +KigCommandTask::~KigCommandTask() +{ +} + +AddObjectsTask::AddObjectsTask( const std::vector<ObjectHolder*>& os) + : KigCommandTask(), undone( true ), mobjs( os ) +{ +} + +void AddObjectsTask::execute( KigPart& doc ) +{ + doc._addObjects( mobjs ); + undone = false; +} + +void AddObjectsTask::unexecute( KigPart& doc ) +{ + doc._delObjects( mobjs ); + undone = true; +} + +AddObjectsTask::~AddObjectsTask() +{ + if ( undone ) + for ( std::vector<ObjectHolder*>::iterator i = mobjs.begin(); + i != mobjs.end(); ++i ) + delete *i; +} + +RemoveObjectsTask::RemoveObjectsTask( const std::vector<ObjectHolder*>& os ) + : AddObjectsTask( os ) +{ + undone = false; +} + +void RemoveObjectsTask::execute( KigPart& doc ) +{ + AddObjectsTask::unexecute( doc ); +} + +void RemoveObjectsTask::unexecute( KigPart& doc ) +{ + AddObjectsTask::execute( doc ); +} + +ChangeObjectConstCalcerTask::ChangeObjectConstCalcerTask( ObjectConstCalcer* calcer, ObjectImp* newimp ) + : KigCommandTask(), mcalcer( calcer ), mnewimp( newimp ) +{ +} + +void ChangeObjectConstCalcerTask::execute( KigPart& doc ) +{ + mnewimp = mcalcer->switchImp( mnewimp ); + + std::set<ObjectCalcer*> allchildren = getAllChildren( mcalcer.get() ); + std::vector<ObjectCalcer*> allchildrenvect( allchildren.begin(), allchildren.end() ); + allchildrenvect = calcPath( allchildrenvect ); + for ( std::vector<ObjectCalcer*>::iterator i = allchildrenvect.begin(); + i != allchildrenvect.end(); ++i ) + ( *i )->calc( doc.document() ); +} + +void ChangeObjectConstCalcerTask::unexecute( KigPart& doc ) +{ + execute( doc ); +} + +struct MoveDataStruct +{ + ObjectConstCalcer* o; + ObjectImp* oldimp; + MoveDataStruct( ObjectConstCalcer* io, ObjectImp* oi ) + : o( io ), oldimp( oi ) { } +}; + +class MonitorDataObjects::Private +{ +public: + vector<MoveDataStruct> movedata; +}; + +MonitorDataObjects::MonitorDataObjects( const std::vector<ObjectCalcer*>& objs ) + : d( new Private ) +{ + monitor( objs ); +} + +void MonitorDataObjects::monitor( const std::vector<ObjectCalcer*>& objs ) +{ + for ( std::vector<ObjectCalcer*>::const_iterator i = objs.begin(); i != objs.end(); ++i ) + if ( dynamic_cast<ObjectConstCalcer*>( *i ) ) + { + MoveDataStruct n( static_cast<ObjectConstCalcer*>( *i ), (*i)->imp()->copy() ); + d->movedata.push_back( n ); + }; +} + +void MonitorDataObjects::finish( KigCommand* comm ) +{ + for ( uint i = 0; i < d->movedata.size(); ++i ) + { + ObjectConstCalcer* o = d->movedata[i].o; + if ( ! d->movedata[i].oldimp->equals( *o->imp() ) ) + { + ObjectImp* newimp = o->switchImp( d->movedata[i].oldimp ); + comm->addTask( new ChangeObjectConstCalcerTask( o, newimp ) ); + } + else + delete d->movedata[i].oldimp; + }; + d->movedata.clear(); +} + +MonitorDataObjects::~MonitorDataObjects() +{ + assert( d->movedata.empty() ); + delete d; +} + +ChangeCoordSystemTask::ChangeCoordSystemTask( CoordinateSystem* s ) + : KigCommandTask(), mcs( s ) +{ +} + +void ChangeCoordSystemTask::execute( KigPart& doc ) +{ + mcs = doc.document().switchCoordinateSystem( mcs ); + std::vector<ObjectCalcer*> calcpath = calcPath( getAllCalcers( doc.document().objects() ) ); + for ( std::vector<ObjectCalcer*>::iterator i = calcpath.begin(); i != calcpath.end(); ++i ) + ( *i )->calc( doc.document() ); + doc.coordSystemChanged( doc.document().coordinateSystem().id() ); +} + +void ChangeCoordSystemTask::unexecute( KigPart& doc ) +{ + execute( doc ); +} + +ChangeCoordSystemTask::~ChangeCoordSystemTask() +{ + delete mcs; +} + +class ChangeParentsAndTypeTask::Private +{ +public: + ObjectTypeCalcer* o; + std::vector<ObjectCalcer::shared_ptr> newparents; + const ObjectType* newtype; +}; + +ChangeParentsAndTypeTask::~ChangeParentsAndTypeTask() +{ + delete d; +} + +ChangeParentsAndTypeTask::ChangeParentsAndTypeTask( + ObjectTypeCalcer* o, const std::vector<ObjectCalcer*>& newparents, + const ObjectType* newtype ) + : KigCommandTask(), d( new Private ) +{ + d->o = o; + std::copy( newparents.begin(), newparents.end(), + std::back_inserter( d->newparents ) ); + d->newtype = newtype; +} + +void ChangeParentsAndTypeTask::execute( KigPart& doc ) +{ + const ObjectType* oldtype = d->o->type(); + d->o->setType( d->newtype ); + d->newtype = oldtype; + + std::vector<ObjectCalcer*> oldparentso = d->o->parents(); + std::vector<ObjectCalcer::shared_ptr> oldparents( + oldparentso.begin(), oldparentso.end() ); + std::vector<ObjectCalcer*> newparents; + for ( std::vector<ObjectCalcer::shared_ptr>::iterator i = d->newparents.begin(); + i != d->newparents.end(); ++i ) + newparents.push_back( i->get() ); + d->o->setParents( newparents ); + d->newparents = oldparents; + + for ( std::vector<ObjectCalcer*>::iterator i = newparents.begin(); i != newparents.end(); ++i ) + ( *i )->calc( doc.document() ); + d->o->calc( doc.document() ); + std::set<ObjectCalcer*> allchildren = getAllChildren( d->o ); + std::vector<ObjectCalcer*> allchildrenvect( allchildren.begin(), allchildren.end() ); + allchildrenvect = calcPath( allchildrenvect ); + for ( std::vector<ObjectCalcer*>::iterator i = allchildrenvect.begin(); + i != allchildrenvect.end(); ++i ) + ( *i )->calc( doc.document() ); +} + +void ChangeParentsAndTypeTask::unexecute( KigPart& doc ) +{ + execute( doc ); +} + +class KigViewShownRectChangeTask::Private +{ +public: + Private( KigWidget& view, const Rect& r ) : v( view ), rect( r ) { } + KigWidget& v; + Rect rect; +}; + +KigViewShownRectChangeTask::KigViewShownRectChangeTask( + KigWidget& v, const Rect& newrect ) + : KigCommandTask() +{ + d = new Private( v, newrect ); +} + +KigViewShownRectChangeTask::~KigViewShownRectChangeTask() +{ + delete d; +} + +void KigViewShownRectChangeTask::execute( KigPart& doc ) +{ + Rect oldrect = d->v.showingRect(); + d->v.setShowingRect( d->rect ); + doc.mode()->redrawScreen( &d->v ); + d->v.updateScrollBars(); + d->rect = oldrect; +} + +void KigViewShownRectChangeTask::unexecute( KigPart& doc ) +{ + execute( doc ); +} + +ChangeObjectDrawerTask::~ChangeObjectDrawerTask() +{ + delete mnewdrawer; +} + +ChangeObjectDrawerTask::ChangeObjectDrawerTask( + ObjectHolder* holder, ObjectDrawer* newdrawer ) + : KigCommandTask(), mholder( holder ), mnewdrawer( newdrawer ) +{ +} + +void ChangeObjectDrawerTask::execute( KigPart& ) +{ + mnewdrawer = mholder->switchDrawer( mnewdrawer ); +} + +void ChangeObjectDrawerTask::unexecute( KigPart& doc ) +{ + execute( doc ); +} + +MonitorDataObjects::MonitorDataObjects( ObjectCalcer* c ) + : d( new Private ) +{ + if ( dynamic_cast<ObjectConstCalcer*>( c ) ) + { + MoveDataStruct n( static_cast<ObjectConstCalcer*>( c ), c->imp()->copy() ); + d->movedata.push_back( n ); + }; +} + +ChangeObjectConstCalcerTask::~ChangeObjectConstCalcerTask() +{ + delete mnewimp; +} + |