moved kdeaccessibility kdeaddons kdeadmin kdeartwork kdebindings kdeedu kdegames...
[kdeedu.git] / kig / objects / object_calcer.cc
blob0b4601495aba216320d514b07c3f80d9f82663cb
1 // Copyright (C) 2003 Dominique Devriese <devriese@kde.org>
3 // This program is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU General Public License
5 // as published by the Free Software Foundation; either version 2
6 // of the License, or (at your option) any later version.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
16 // 02111-1307, USA.
18 #include "object_calcer.h"
20 #include "object_holder.h"
21 #include "object_imp.h"
22 #include "object_type.h"
23 #include "../misc/coordinate.h"
24 #include "common.h"
26 #include <algorithm>
27 #include <set>
29 void ObjectTypeCalcer::calc( const KigDocument& doc )
31 Args a;
32 a.reserve( mparents.size() );
33 std::transform( mparents.begin(), mparents.end(),
34 std::back_inserter( a ), std::mem_fun( &ObjectCalcer::imp ) );
35 ObjectImp* n = mtype->calc( a, doc );
36 delete mimp;
37 mimp = n;
40 ObjectTypeCalcer::ObjectTypeCalcer( const ObjectType* type,
41 const std::vector<ObjectCalcer*>& parents, bool sort )
42 : mparents( ( sort )?type->sortArgs( parents ):parents ), mtype( type ), mimp( 0 )
44 std::for_each( mparents.begin(), mparents.end(),
45 std::bind2nd( std::mem_fun( &ObjectCalcer::addChild ), this ) );
48 ObjectCalcer::~ObjectCalcer()
52 ObjectConstCalcer::ObjectConstCalcer( ObjectImp* imp )
53 : mimp( imp )
57 ObjectConstCalcer::~ObjectConstCalcer()
59 delete mimp;
62 const ObjectImp* ObjectConstCalcer::imp() const
64 return mimp;
67 void ObjectConstCalcer::calc( const KigDocument& )
71 std::vector<ObjectCalcer*> ObjectConstCalcer::parents() const
73 // we have no parents..
74 return std::vector<ObjectCalcer*>();
77 void ObjectCalcer::ref()
79 ++refcount;
82 void ObjectCalcer::deref()
84 if ( --refcount <= 0 ) delete this;
87 void intrusive_ptr_add_ref( ObjectCalcer* p )
89 p->ref();
92 void intrusive_ptr_release( ObjectCalcer* p )
94 p->deref();
97 const ObjectImp* ObjectTypeCalcer::imp() const
99 return mimp;
102 std::vector<ObjectCalcer*> ObjectTypeCalcer::parents() const
104 return mparents;
107 void ObjectCalcer::addChild( ObjectCalcer* c )
109 mchildren.push_back( c );
110 ref();
113 void ObjectCalcer::delChild( ObjectCalcer* c )
115 std::vector<ObjectCalcer*>::iterator i = std::find( mchildren.begin(), mchildren.end(), c );
116 assert( i != mchildren.end() );
118 mchildren.erase( i );
119 deref();
122 ObjectTypeCalcer::~ObjectTypeCalcer()
124 std::for_each( mparents.begin(), mparents.end(),
125 std::bind2nd( std::mem_fun( &ObjectCalcer::delChild ), this ) );
126 delete mimp;
129 const ObjectType* ObjectTypeCalcer::type() const
131 return mtype;
134 ObjectPropertyCalcer::ObjectPropertyCalcer( ObjectCalcer* parent, int propid )
135 : mimp( 0 ), mparent( parent ), mpropid( propid )
137 // Some weird C++ thing prevents me from calling protected members
138 // of ObjectCalcer on mparent.. This is an ugly workaround..
139 ( mparent->*&ObjectCalcer::addChild )( this );
140 //mparent->addChild( this );
143 ObjectPropertyCalcer::~ObjectPropertyCalcer()
145 // Some weird C++ thing prevents me from calling protected members
146 // of ObjectCalcer on mparent.. This is an ugly workaround..
147 ( mparent->*&ObjectCalcer::delChild )( this );
148 //mparent->delChild( this );
149 delete mimp;
152 const ObjectImp* ObjectPropertyCalcer::imp() const
154 return mimp;
157 std::vector<ObjectCalcer*> ObjectPropertyCalcer::parents() const
159 std::vector<ObjectCalcer*> ret;
160 ret.push_back( mparent );
161 return ret;
164 void ObjectPropertyCalcer::calc( const KigDocument& doc )
166 ObjectImp* n = mparent->imp()->property( mpropid, doc );
167 delete mimp;
168 mimp = n;
171 ObjectImp* ObjectConstCalcer::switchImp( ObjectImp* newimp )
173 ObjectImp* ret = mimp;
174 mimp = newimp;
175 return ret;
178 std::vector<ObjectCalcer*> ObjectCalcer::children() const
180 return mchildren;
183 const ObjectImpType* ObjectPropertyCalcer::impRequirement(
184 ObjectCalcer*, const std::vector<ObjectCalcer*>& ) const
186 return mparent->imp()->impRequirementForProperty( mpropid );
189 const ObjectImpType* ObjectConstCalcer::impRequirement(
190 ObjectCalcer*, const std::vector<ObjectCalcer*>& ) const
192 assert( false );
193 return ObjectImp::stype();
196 const ObjectImpType* ObjectTypeCalcer::impRequirement(
197 ObjectCalcer* o, const std::vector<ObjectCalcer*>& os ) const
199 Args args;
200 args.reserve( mparents.size() );
201 std::transform(
202 os.begin(), os.end(),
203 std::back_inserter( args ),
204 std::mem_fun( &ObjectCalcer::imp ) );
205 assert( std::find( args.begin(), args.end(), o->imp() ) != args.end() );
206 return mtype->impRequirement( o->imp(), args );
209 int ObjectPropertyCalcer::propId() const
211 return mpropid;
214 void ObjectConstCalcer::setImp( ObjectImp* newimp )
216 delete switchImp( newimp );
219 void ObjectTypeCalcer::setParents( const std::vector<ObjectCalcer*> np )
221 std::for_each( np.begin(), np.end(),
222 std::bind2nd( std::mem_fun( &ObjectCalcer::addChild ), this ) );
223 std::for_each( mparents.begin(), mparents.end(),
224 std::bind2nd( std::mem_fun( &ObjectCalcer::delChild ), this ) );
225 mparents = np;
228 void ObjectTypeCalcer::setType( const ObjectType* t )
230 mtype = t;
233 bool ObjectCalcer::canMove() const
235 return false;
238 bool ObjectCalcer::isFreelyTranslatable() const
240 return false;
243 Coordinate ObjectCalcer::moveReferencePoint() const
245 assert( false );
246 return Coordinate::invalidCoord();
249 void ObjectCalcer::move( const Coordinate&, const KigDocument& )
251 assert( false );
254 bool ObjectTypeCalcer::canMove() const
256 return mtype->canMove( *this );
259 bool ObjectTypeCalcer::isFreelyTranslatable() const
261 return mtype->isFreelyTranslatable( *this );
264 Coordinate ObjectTypeCalcer::moveReferencePoint() const
266 return mtype->moveReferencePoint( *this );
269 void ObjectTypeCalcer::move( const Coordinate& to, const KigDocument& doc )
271 // we need to check if type can in fact move, because this check is
272 // not done for us in all circumstances ( e.g. LineABType::move uses
273 // move on its parents to move them ), and the ObjectType's depend
274 // on move only being called if canMove() returns true..
275 if ( mtype->canMove( *this ) )
276 mtype->move( *this, to, doc );
279 ObjectCalcer* ObjectPropertyCalcer::parent() const
281 return mparent;
284 ObjectCalcer::ObjectCalcer()
285 : refcount( 0 )
289 std::vector<ObjectCalcer*> ObjectCalcer::movableParents() const
291 return std::vector<ObjectCalcer*>();
294 std::vector<ObjectCalcer*> ObjectTypeCalcer::movableParents() const
296 return mtype->movableParents( *this );
299 bool ObjectConstCalcer::isDefinedOnOrThrough( const ObjectCalcer* ) const
301 return false;
304 bool ObjectPropertyCalcer::isDefinedOnOrThrough( const ObjectCalcer* o ) const
306 return o == mparent &&
307 mparent->imp()->isPropertyDefinedOnOrThroughThisImp( propId() );
310 bool ObjectTypeCalcer::isDefinedOnOrThrough( const ObjectCalcer* o ) const
312 Args args;
313 args.reserve( mparents.size() );
314 std::transform(
315 mparents.begin(), mparents.end(),
316 std::back_inserter( args ),
317 std::mem_fun( &ObjectCalcer::imp ) );
318 if ( std::find( args.begin(), args.end(), o->imp() ) == args.end() )
319 return false;
321 return mtype->isDefinedOnOrThrough( o->imp(), args );