|
|
|
/**
|
|
|
|
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 TQString& 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 );
|
|
|
|
TQString 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 )
|
|
|
|
{
|
|
|
|
TQString 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 )
|
|
|
|
{
|
|
|
|
TQString 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;
|
|
|
|
}
|
|
|
|
|