summaryrefslogtreecommitdiffstats
path: root/kig/kig/kig_commands.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kig/kig/kig_commands.cpp')
-rw-r--r--kig/kig/kig_commands.cpp398
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;
+}
+