Salome HOME
Property "isOpen" property added.
[modules/gui.git] / src / SUIT / SUIT_DataObject.cxx
1 #include "SUIT_DataObject.h"
2
3 #include <qobject.h>
4
5 #include "SUIT_DataObjectKey.h"
6
7 #include <iostream> // for cout in dump()
8
9 /*!
10     Constructor
11 */
12
13 SUIT_DataObject::SUIT_DataObject( SUIT_DataObject* p )
14 : myParent( 0 ),
15   mySignal( 0 ),
16   myOpen( false ),
17   myCheck( false )
18 {
19   myChildren.setAutoDelete( true );
20
21   setParent( p );
22 }
23
24 /*!
25     Destructor
26 */
27
28 SUIT_DataObject::~SUIT_DataObject()
29 {
30   if ( mySignal )
31   {
32     mySignal->emitSignal();
33     mySignal->setOwner( 0 );
34   }
35
36   delete mySignal;
37
38   SUIT_DataObject* p = myParent;
39
40   myParent = 0;
41
42   if ( p )
43     p->removeChild( this );
44
45   for ( QPtrListIterator<SUIT_DataObject> it( myChildren ); it.current(); ++it )
46     it.current()->myParent = 0;
47 }
48
49 /*!
50     Returns the root object.
51 */
52
53 SUIT_DataObject* SUIT_DataObject::root() const
54 {
55   return parent() ? parent()->root() : (SUIT_DataObject*)this;
56 }
57
58 /*!
59     Returns the first child object.
60 */
61
62 SUIT_DataObject* SUIT_DataObject::firstChild() const
63 {
64   SUIT_DataObject* child = 0;
65   if ( !myChildren.isEmpty() )
66     child = myChildren.getFirst();
67   return child;
68 }
69
70 /*!
71     Returns the last child object.
72 */
73
74 SUIT_DataObject* SUIT_DataObject::lastChild() const
75 {
76   SUIT_DataObject* child = 0;
77   if ( !myChildren.isEmpty() )
78     child = myChildren.getLast();
79   return child;
80 }
81
82 /*!
83     Returns the number of the child objects.
84 */
85
86 int SUIT_DataObject::childCount() const
87 {
88   return myChildren.count();
89 }
90
91 /*!
92     Returns the index of the specified object in the child list or -1.
93 */
94
95 int SUIT_DataObject::childPos( const SUIT_DataObject* obj ) const
96 {
97   int res = -1;
98
99   int i = 0;
100   for ( DataObjectListIterator it( myChildren ); it.current() && res == -1; ++it, i++ )
101   {
102     if ( it.current() == obj )
103       res = i;
104   }
105
106   return res;
107 }
108
109 /*!
110     Returns the child object with specified index.
111 */
112
113 SUIT_DataObject* SUIT_DataObject::childObject( const int idx ) const
114 {
115   SUIT_DataObject* child = 0;
116
117   if ( idx>= 0 && idx < (int)myChildren.count() )
118   {
119     SUIT_DataObject* that = (SUIT_DataObject*)this;
120     child = that->myChildren.at( idx );
121   }
122
123   return child;
124 }
125
126 /*!
127     Returns the next data object in the child list of the parent.
128 */
129
130 SUIT_DataObject* SUIT_DataObject::nextBrother() const
131 {
132   return myParent ? myParent->childObject( myParent->childPos( this ) + 1 ) : 0;
133 }
134
135 /*!
136     Returns the previous data object in the child list of the parent.
137 */
138
139 SUIT_DataObject* SUIT_DataObject::prevBrother() const
140 {
141   return myParent ? myParent->childObject( myParent->childPos( this ) - 1 ) : 0;
142 }
143
144 /*!
145     Returns 'true' if the object will delete children during destroying
146 */
147
148 bool SUIT_DataObject::autoDeleteChildren() const
149 {
150   return myChildren.autoDelete();
151 }
152
153 /*!
154     Specify should the object delete children during destroying
155 */
156
157 void SUIT_DataObject::setAutoDeleteChildren( const bool on )
158 {
159   myChildren.setAutoDelete( on );
160 }
161
162 /*!
163     Returns the list of the child objects. if 'rec' is 'true' then function get all sub children.
164 */
165
166 void SUIT_DataObject::children( DataObjectList& lst, const bool rec ) const
167 {
168   for ( DataObjectListIterator it( myChildren ); it.current(); ++it )
169   {
170     lst.append( it.current() );
171     if ( rec )
172       it.current()->children( lst, rec );
173   }
174 }
175
176 /*!
177     Returns the list of the child objects. if 'rec' is 'true' then function get all sub children.
178 */
179
180 DataObjectList SUIT_DataObject::children( const bool rec )
181 {
182   DataObjectList lst;
183   children( lst, rec );
184   return lst;
185 }
186
187 /*!
188     Append new child object to the end of the children list
189 */
190
191 void SUIT_DataObject::appendChild( SUIT_DataObject* theObj ) 
192 {
193   insertChild( theObj, myChildren.count() );
194 }
195
196 /*!
197     Insert new child object to the children list at specified position
198 */
199
200 void SUIT_DataObject::insertChild( SUIT_DataObject* theObj, int thePosition )
201 {
202   if ( !theObj || myChildren.find( theObj ) != -1 )
203     return;
204
205   int pos = thePosition < 0 ? myChildren.count() : thePosition;
206   myChildren.insert( QMIN( pos, (int)myChildren.count() ), theObj );
207   theObj->setParent( this );
208 }
209
210 /*!
211     Removes the specified child object reference.
212 */
213
214 void SUIT_DataObject::removeChild( SUIT_DataObject* theObj )
215 {
216   if ( !theObj )
217     return;
218
219   bool ad = myChildren.autoDelete();
220   myChildren.setAutoDelete( false );
221
222   if ( myChildren.remove( theObj ) )
223     theObj->setParent( 0 );
224
225   myChildren.setAutoDelete( ad );
226 }
227
228 /*!
229     Replaces the specified child object by another object.
230 */
231
232 bool SUIT_DataObject::replaceChild( SUIT_DataObject* src, SUIT_DataObject* trg, const bool del )
233 {
234   if ( !src || !trg )
235     return false;
236
237   int idx = childPos( trg );
238   removeChild( trg );
239
240   int pos = childPos( src );
241   if ( pos < 0 )
242   {
243     if ( idx >= 0 )
244       insertChild( trg, idx );
245     return false;
246   }
247
248   insertChild( trg, pos );
249   removeChild( src );
250
251   if ( del )
252     src->deleteLater();
253
254   return true;
255 }
256
257 /*!
258     Transfer the all children from specified object 'obj' to self.
259 */
260
261 void SUIT_DataObject::reparentChildren( const SUIT_DataObject* obj )
262 {
263   DataObjectList lst;
264   obj->children( lst );
265   for ( DataObjectListIterator it( lst ); it.current(); ++it )
266     it.current()->setParent( this );
267 }
268
269 /*!
270     Set the parent object. Remove itself from current parent children
271     and append itself to the new parent children list.
272 */
273
274 void SUIT_DataObject::setParent( SUIT_DataObject* theParent )
275 {
276   if ( theParent == parent() )
277     return;
278
279   if ( parent() )
280     parent()->removeChild( this );
281
282   myParent = theParent;
283
284   if ( parent() )
285     parent()->appendChild( this );
286 }
287
288 /*!
289     Returns the parent object.
290 */
291
292 SUIT_DataObject* SUIT_DataObject::parent() const
293 {
294   return myParent;
295 }
296
297
298 /*!
299     Connect to signal destroyed( SUIT_DataObject* ).
300 */
301
302 bool SUIT_DataObject::connect( QObject* reciever, const char* slot )
303 {
304   if ( !reciever || !slot )
305     return false;
306
307   if ( !mySignal )
308     mySignal = new Signal( this );
309
310   QObject::disconnect( mySignal, SIGNAL( destroyed( SUIT_DataObject* ) ), reciever, slot );
311   return QObject::connect( mySignal, SIGNAL( destroyed( SUIT_DataObject* ) ), reciever, slot );
312 }
313
314 /*!
315     Disconnect from signal destroyed( SUIT_DataObject* ).
316 */
317
318 bool SUIT_DataObject::disconnect( QObject* reciever, const char* slot )
319 {
320   if ( !reciever || !slot )
321     return false;
322
323   if ( !mySignal )
324     return true;
325
326   return QObject::disconnect( mySignal, SIGNAL( destroyed( SUIT_DataObject* ) ), reciever, slot );
327 }
328
329 /*!
330     Returns object name
331 */
332
333 void SUIT_DataObject::deleteLater()
334 {
335   if ( !mySignal )
336     mySignal = new Signal( this );
337   
338   mySignal->emitSignal();
339   mySignal->deleteLater();
340 }
341
342 /*!
343     Returns object name
344 */
345
346 QString SUIT_DataObject::name() const
347 {
348   return QString::null;
349 }
350
351 /*!
352     Returns object icon
353 */
354
355 QPixmap SUIT_DataObject::icon() const
356 {
357   return QPixmap();
358 }
359
360 /*!
361     Returns object text
362 */
363
364 QString SUIT_DataObject::text( const int ) const
365 {
366   return QString::null;
367 }
368
369 /*!
370     Returns object color
371 */
372
373 QColor SUIT_DataObject::color( const ColorRole ) const
374 {
375   return QColor();
376 }
377
378 /*!
379     Returns object tool tip
380 */
381
382 QString SUIT_DataObject::toolTip() const
383 {
384   return QString::null;
385 }
386
387 /*!
388     Returns 'true' if it is possible to drag this object
389 */
390
391 bool SUIT_DataObject::isDragable() const
392 {
393   return false;
394 }
395
396 /*!
397     Returns 'true' if it is possible to drop an object "obj" to this object.
398 */
399
400 bool SUIT_DataObject::isDropAccepted( SUIT_DataObject* )
401 {
402   return false;
403 }
404
405 /*!
406     Returns type of check possibility.
407 */
408
409 SUIT_DataObject::CheckType SUIT_DataObject::checkType() const
410 {
411   return None;
412 }
413
414 /*!
415     Returns the checked state of the object.
416 */
417
418 bool SUIT_DataObject::isOn() const
419 {
420   return myCheck;
421 }
422
423 /*!
424     Sets the checked state of the object.
425 */
426
427 void SUIT_DataObject::setOn( const bool on )
428 {
429   myCheck = on;
430 }
431
432 bool SUIT_DataObject::isOpen() const
433 {
434   return myOpen;
435 }
436
437 void SUIT_DataObject::setOpen( const bool on )
438 {
439   myOpen = on;
440 }
441
442 /*!
443     Returns object personal indentification key.
444 */
445
446 SUIT_DataObjectKey* SUIT_DataObject::key() const
447 {
448   return 0;
449 }
450
451 /*!
452    Dump this data object and its children to cout
453 */
454 void SUIT_DataObject::dump( const int indent ) const
455 {
456   QString strIndent = QString().fill( ' ', indent ); // indentation string 
457   std::cout << strIndent << name() << std::endl;     // dump to cout
458   for ( DataObjectListIterator it( myChildren ); it.current(); ++it ) // iterate all children
459     it.current()->dump( indent + 2 );  // dump every child with indent + 2 spaces
460 }
461
462 /*!
463   Class: SUIT_DataObject::Signal [Internal]
464 */
465
466 SUIT_DataObject::Signal::Signal( SUIT_DataObject* o )
467 : QObject(),
468 myOwner( o )
469 {
470 }
471
472 SUIT_DataObject::Signal::~Signal()
473 {
474   SUIT_DataObject* o = myOwner;
475   myOwner = 0;
476   if ( o )
477   {
478     o->mySignal = 0;
479     delete o;
480   }
481 }
482
483 void SUIT_DataObject::Signal::setOwner( SUIT_DataObject* o )
484 {
485   myOwner = o;
486 }
487
488 void SUIT_DataObject::Signal::emitSignal()
489 {
490   if ( myOwner )
491     emit destroyed( myOwner );
492 }