2 This file is part of Kig, a KDE program for Interactive Geometry...
3 Copyright (C) 2002 Dominique Devriese <devriese@kde.org>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 #include "kig_commands.h"
22 #include "kig_commands.moc"
25 #include "kig_document.h"
28 #include "../modes/mode.h"
29 #include "../objects/object_imp.h"
30 #include "../objects/object_drawer.h"
31 #include "../misc/calcpaths.h"
32 #include "../misc/coordinate_system.h"
40 class KigCommand::Private
43 Private( KigPart
& d
) : doc( d
) {};
45 vector
<KigCommandTask
*> tasks
;
48 KigCommand::KigCommand( KigPart
& doc
, const QString
& name
)
49 : KNamedCommand(name
), d( new Private( doc
) )
53 KigCommand::~KigCommand()
55 for ( uint i
= 0; i
< d
->tasks
.size(); ++i
)
60 void KigCommand::execute()
62 for ( uint i
= 0; i
< d
->tasks
.size(); ++i
)
63 d
->tasks
[i
]->execute( d
->doc
);
64 d
->doc
.redrawScreen();
67 void KigCommand::unexecute()
69 for ( uint i
= 0; i
< d
->tasks
.size(); ++i
)
70 d
->tasks
[i
]->unexecute( d
->doc
);
71 d
->doc
.redrawScreen();
74 void KigCommand::addTask( KigCommandTask
* t
)
76 d
->tasks
.push_back( t
);
79 KigCommand
* KigCommand::removeCommand( KigPart
& doc
, ObjectHolder
* o
)
81 std::vector
<ObjectHolder
*> os
;
83 return removeCommand( doc
, os
);
86 KigCommand
* KigCommand::addCommand( KigPart
& doc
, ObjectHolder
* o
)
88 std::vector
<ObjectHolder
*> os
;
90 return addCommand( doc
, os
);
93 KigCommand
* KigCommand::removeCommand( KigPart
& doc
, const std::vector
<ObjectHolder
*>& os
)
95 assert( os
.size() > 0 );
98 text
= os
.back()->imp()->type()->removeAStatement();
100 text
= i18n( "Remove %1 Objects" ).arg( os
.size() );
101 KigCommand
* ret
= new KigCommand( doc
, text
);
102 ret
->addTask( new RemoveObjectsTask( os
) );
106 KigCommand
* KigCommand::addCommand( KigPart
& doc
, const std::vector
<ObjectHolder
*>& os
)
109 if ( os
.size() == 1 )
110 text
= os
.back()->imp()->type()->addAStatement();
112 text
= i18n( "Add %1 Objects" ).arg( os
.size() );
113 KigCommand
* ret
= new KigCommand( doc
, text
);
114 ret
->addTask( new AddObjectsTask( os
) );
118 KigCommand
* KigCommand::changeCoordSystemCommand( KigPart
& doc
, CoordinateSystem
* s
)
120 QString text
= CoordinateSystemFactory::setCoordinateSystemStatement( s
->id() );
121 KigCommand
* ret
= new KigCommand( doc
, text
);
122 ret
->addTask( new ChangeCoordSystemTask( s
) );
126 KigCommandTask::KigCommandTask()
130 KigCommandTask::~KigCommandTask()
134 AddObjectsTask::AddObjectsTask( const std::vector
<ObjectHolder
*>& os
)
135 : KigCommandTask(), undone( true ), mobjs( os
)
139 void AddObjectsTask::execute( KigPart
& doc
)
141 doc
._addObjects( mobjs
);
145 void AddObjectsTask::unexecute( KigPart
& doc
)
147 doc
._delObjects( mobjs
);
151 AddObjectsTask::~AddObjectsTask()
154 for ( std::vector
<ObjectHolder
*>::iterator i
= mobjs
.begin();
155 i
!= mobjs
.end(); ++i
)
159 RemoveObjectsTask::RemoveObjectsTask( const std::vector
<ObjectHolder
*>& os
)
160 : AddObjectsTask( os
)
165 void RemoveObjectsTask::execute( KigPart
& doc
)
167 AddObjectsTask::unexecute( doc
);
170 void RemoveObjectsTask::unexecute( KigPart
& doc
)
172 AddObjectsTask::execute( doc
);
175 ChangeObjectConstCalcerTask::ChangeObjectConstCalcerTask( ObjectConstCalcer
* calcer
, ObjectImp
* newimp
)
176 : KigCommandTask(), mcalcer( calcer
), mnewimp( newimp
)
180 void ChangeObjectConstCalcerTask::execute( KigPart
& doc
)
182 mnewimp
= mcalcer
->switchImp( mnewimp
);
184 std::set
<ObjectCalcer
*> allchildren
= getAllChildren( mcalcer
.get() );
185 std::vector
<ObjectCalcer
*> allchildrenvect( allchildren
.begin(), allchildren
.end() );
186 allchildrenvect
= calcPath( allchildrenvect
);
187 for ( std::vector
<ObjectCalcer
*>::iterator i
= allchildrenvect
.begin();
188 i
!= allchildrenvect
.end(); ++i
)
189 ( *i
)->calc( doc
.document() );
192 void ChangeObjectConstCalcerTask::unexecute( KigPart
& doc
)
197 struct MoveDataStruct
199 ObjectConstCalcer
* o
;
201 MoveDataStruct( ObjectConstCalcer
* io
, ObjectImp
* oi
)
202 : o( io
), oldimp( oi
) { }
205 class MonitorDataObjects::Private
208 vector
<MoveDataStruct
> movedata
;
211 MonitorDataObjects::MonitorDataObjects( const std::vector
<ObjectCalcer
*>& objs
)
217 void MonitorDataObjects::monitor( const std::vector
<ObjectCalcer
*>& objs
)
219 for ( std::vector
<ObjectCalcer
*>::const_iterator i
= objs
.begin(); i
!= objs
.end(); ++i
)
220 if ( dynamic_cast<ObjectConstCalcer
*>( *i
) )
222 MoveDataStruct
n( static_cast<ObjectConstCalcer
*>( *i
), (*i
)->imp()->copy() );
223 d
->movedata
.push_back( n
);
227 void MonitorDataObjects::finish( KigCommand
* comm
)
229 for ( uint i
= 0; i
< d
->movedata
.size(); ++i
)
231 ObjectConstCalcer
* o
= d
->movedata
[i
].o
;
232 if ( ! d
->movedata
[i
].oldimp
->equals( *o
->imp() ) )
234 ObjectImp
* newimp
= o
->switchImp( d
->movedata
[i
].oldimp
);
235 comm
->addTask( new ChangeObjectConstCalcerTask( o
, newimp
) );
238 delete d
->movedata
[i
].oldimp
;
243 MonitorDataObjects::~MonitorDataObjects()
245 assert( d
->movedata
.empty() );
249 ChangeCoordSystemTask::ChangeCoordSystemTask( CoordinateSystem
* s
)
250 : KigCommandTask(), mcs( s
)
254 void ChangeCoordSystemTask::execute( KigPart
& doc
)
256 mcs
= doc
.document().switchCoordinateSystem( mcs
);
257 std::vector
<ObjectCalcer
*> calcpath
= calcPath( getAllCalcers( doc
.document().objects() ) );
258 for ( std::vector
<ObjectCalcer
*>::iterator i
= calcpath
.begin(); i
!= calcpath
.end(); ++i
)
259 ( *i
)->calc( doc
.document() );
260 doc
.coordSystemChanged( doc
.document().coordinateSystem().id() );
263 void ChangeCoordSystemTask::unexecute( KigPart
& doc
)
268 ChangeCoordSystemTask::~ChangeCoordSystemTask()
273 class ChangeParentsAndTypeTask::Private
277 std::vector
<ObjectCalcer::shared_ptr
> newparents
;
278 const ObjectType
* newtype
;
281 ChangeParentsAndTypeTask::~ChangeParentsAndTypeTask()
286 ChangeParentsAndTypeTask::ChangeParentsAndTypeTask(
287 ObjectTypeCalcer
* o
, const std::vector
<ObjectCalcer
*>& newparents
,
288 const ObjectType
* newtype
)
289 : KigCommandTask(), d( new Private
)
292 std::copy( newparents
.begin(), newparents
.end(),
293 std::back_inserter( d
->newparents
) );
294 d
->newtype
= newtype
;
297 void ChangeParentsAndTypeTask::execute( KigPart
& doc
)
299 const ObjectType
* oldtype
= d
->o
->type();
300 d
->o
->setType( d
->newtype
);
301 d
->newtype
= oldtype
;
303 std::vector
<ObjectCalcer
*> oldparentso
= d
->o
->parents();
304 std::vector
<ObjectCalcer::shared_ptr
> oldparents(
305 oldparentso
.begin(), oldparentso
.end() );
306 std::vector
<ObjectCalcer
*> newparents
;
307 for ( std::vector
<ObjectCalcer::shared_ptr
>::iterator i
= d
->newparents
.begin();
308 i
!= d
->newparents
.end(); ++i
)
309 newparents
.push_back( i
->get() );
310 d
->o
->setParents( newparents
);
311 d
->newparents
= oldparents
;
313 for ( std::vector
<ObjectCalcer
*>::iterator i
= newparents
.begin(); i
!= newparents
.end(); ++i
)
314 ( *i
)->calc( doc
.document() );
315 d
->o
->calc( doc
.document() );
316 std::set
<ObjectCalcer
*> allchildren
= getAllChildren( d
->o
);
317 std::vector
<ObjectCalcer
*> allchildrenvect( allchildren
.begin(), allchildren
.end() );
318 allchildrenvect
= calcPath( allchildrenvect
);
319 for ( std::vector
<ObjectCalcer
*>::iterator i
= allchildrenvect
.begin();
320 i
!= allchildrenvect
.end(); ++i
)
321 ( *i
)->calc( doc
.document() );
324 void ChangeParentsAndTypeTask::unexecute( KigPart
& doc
)
329 class KigViewShownRectChangeTask::Private
332 Private( KigWidget
& view
, const Rect
& r
) : v( view
), rect( r
) { };
337 KigViewShownRectChangeTask::KigViewShownRectChangeTask(
338 KigWidget
& v
, const Rect
& newrect
)
341 d
= new Private( v
, newrect
);
344 KigViewShownRectChangeTask::~KigViewShownRectChangeTask()
349 void KigViewShownRectChangeTask::execute( KigPart
& doc
)
351 Rect oldrect
= d
->v
.showingRect();
352 d
->v
.setShowingRect( d
->rect
);
353 doc
.mode()->redrawScreen( &d
->v
);
354 d
->v
.updateScrollBars();
358 void KigViewShownRectChangeTask::unexecute( KigPart
& doc
)
363 ChangeObjectDrawerTask::~ChangeObjectDrawerTask()
368 ChangeObjectDrawerTask::ChangeObjectDrawerTask(
369 ObjectHolder
* holder
, ObjectDrawer
* newdrawer
)
370 : KigCommandTask(), mholder( holder
), mnewdrawer( newdrawer
)
374 void ChangeObjectDrawerTask::execute( KigPart
& )
376 mnewdrawer
= mholder
->switchDrawer( mnewdrawer
);
379 void ChangeObjectDrawerTask::unexecute( KigPart
& doc
)
384 MonitorDataObjects::MonitorDataObjects( ObjectCalcer
* c
)
387 if ( dynamic_cast<ObjectConstCalcer
*>( c
) )
389 MoveDataStruct
n( static_cast<ObjectConstCalcer
*>( c
), c
->imp()->copy() );
390 d
->movedata
.push_back( n
);
394 ChangeObjectConstCalcerTask::~ChangeObjectConstCalcerTask()