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