]> SALOME platform Git repositories - modules/gui.git/blob - src/SUIT/SUIT_DataObject.cxx
Salome HOME
add necessary include <qpixmap.h>
[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   SUIT_DataObject* p = myParent;
31
32   myParent = 0;
33
34   if ( p )
35     p->removeChild( this );
36
37   if ( mySignal )
38   {
39     mySignal->emitSignal();
40     mySignal->setOwner( 0 );
41   }
42
43   for ( QPtrListIterator<SUIT_DataObject> it( myChildren ); it.current(); ++it )
44     it.current()->myParent = 0;
45
46   delete mySignal;
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 level of the object in the data tree.
128     0 means that object is top-level.
129 */
130
131 int SUIT_DataObject::level() const
132 {
133   int lev = 0;
134   SUIT_DataObject* p = parent();
135   while ( p ) {
136     p = p->parent();
137     lev++;
138   }
139   return lev;
140 }
141
142 /*!
143     Returns the next data object in the child list of the parent.
144 */
145
146 SUIT_DataObject* SUIT_DataObject::nextBrother() const
147 {
148   return myParent ? myParent->childObject( myParent->childPos( this ) + 1 ) : 0;
149 }
150
151 /*!
152     Returns the previous data object in the child list of the parent.
153 */
154
155 SUIT_DataObject* SUIT_DataObject::prevBrother() const
156 {
157   return myParent ? myParent->childObject( myParent->childPos( this ) - 1 ) : 0;
158 }
159
160 /*!
161     Returns 'true' if the object will delete children during destroying
162 */
163
164 bool SUIT_DataObject::autoDeleteChildren() const
165 {
166   return myChildren.autoDelete();
167 }
168
169 /*!
170     Specify should the object delete children during destroying
171 */
172
173 void SUIT_DataObject::setAutoDeleteChildren( const bool on )
174 {
175   myChildren.setAutoDelete( on );
176 }
177
178 /*!
179     Returns the list of the child objects. if 'rec' is 'true' then function get all sub children.
180 */
181
182 void SUIT_DataObject::children( DataObjectList& lst, const bool rec ) const
183 {
184   for ( DataObjectListIterator it( myChildren ); it.current(); ++it )
185   {
186     lst.append( it.current() );
187     if ( rec )
188       it.current()->children( lst, rec );
189   }
190 }
191
192 /*!
193     Returns the list of the child objects. if 'rec' is 'true' then function get all sub children.
194 */
195
196 DataObjectList SUIT_DataObject::children( const bool rec )
197 {
198   DataObjectList lst;
199   children( lst, rec );
200   return lst;
201 }
202
203 /*!
204     Append new child object to the end of the children list
205 */
206
207 void SUIT_DataObject::appendChild( SUIT_DataObject* theObj ) 
208 {
209   insertChild( theObj, myChildren.count() );
210 }
211
212 /*!
213     Insert new child object to the children list at specified position
214 */
215
216 void SUIT_DataObject::insertChild( SUIT_DataObject* theObj, int thePosition )
217 {
218   if ( !theObj || myChildren.find( theObj ) != -1 )
219     return;
220
221   int pos = thePosition < 0 ? myChildren.count() : thePosition;
222   myChildren.insert( QMIN( pos, (int)myChildren.count() ), theObj );
223   theObj->setParent( this );
224 }
225
226 /*!
227     Removes the specified child object reference.
228 */
229
230 void SUIT_DataObject::removeChild( SUIT_DataObject* theObj )
231 {
232   if ( !theObj )
233     return;
234
235   bool ad = myChildren.autoDelete();
236   myChildren.setAutoDelete( false );
237
238   if ( myChildren.remove( theObj ) )
239     theObj->setParent( 0 );
240
241   myChildren.setAutoDelete( ad );
242 }
243
244 /*!
245     Replaces the specified child object by another object.
246 */
247
248 bool SUIT_DataObject::replaceChild( SUIT_DataObject* src, SUIT_DataObject* trg, const bool del )
249 {
250   if ( !src || !trg )
251     return false;
252
253   int idx = childPos( trg );
254   removeChild( trg );
255
256   int pos = childPos( src );
257   if ( pos < 0 )
258   {
259     if ( idx >= 0 )
260       insertChild( trg, idx );
261     return false;
262   }
263
264   insertChild( trg, pos );
265   removeChild( src );
266
267   if ( del )
268     src->deleteLater();
269
270   return true;
271 }
272
273 /*!
274     Transfer the all children from specified object 'obj' to self.
275 */
276
277 void SUIT_DataObject::reparentChildren( const SUIT_DataObject* obj )
278 {
279   if ( !obj )
280     return;
281
282   DataObjectList lst;
283   obj->children( lst );
284   for ( DataObjectListIterator it( lst ); it.current(); ++it )
285     it.current()->setParent( this );
286 }
287
288 /*!
289     Set the parent object. Remove itself from current parent children
290     and append itself to the new parent children list.
291 */
292
293 void SUIT_DataObject::setParent( SUIT_DataObject* theParent )
294 {
295   if ( theParent == parent() )
296     return;
297
298   if ( parent() )
299     parent()->removeChild( this );
300
301   myParent = theParent;
302
303   if ( parent() )
304     parent()->appendChild( this );
305 }
306
307 /*!
308     Returns the parent object.
309 */
310
311 SUIT_DataObject* SUIT_DataObject::parent() const
312 {
313   return myParent;
314 }
315
316
317 /*!
318     Connect to signal destroyed( SUIT_DataObject* ).
319 */
320
321 bool SUIT_DataObject::connect( QObject* reciever, const char* slot )
322 {
323   if ( !reciever || !slot )
324     return false;
325
326   if ( !mySignal )
327     mySignal = new Signal( this );
328
329   QObject::disconnect( mySignal, SIGNAL( destroyed( SUIT_DataObject* ) ), reciever, slot );
330   return QObject::connect( mySignal, SIGNAL( destroyed( SUIT_DataObject* ) ), reciever, slot );
331 }
332
333 /*!
334     Disconnect from signal destroyed( SUIT_DataObject* ).
335 */
336
337 bool SUIT_DataObject::disconnect( QObject* reciever, const char* slot )
338 {
339   if ( !reciever || !slot )
340     return false;
341
342   if ( !mySignal )
343     return true;
344
345   return QObject::disconnect( mySignal, SIGNAL( destroyed( SUIT_DataObject* ) ), reciever, slot );
346 }
347
348 /*!
349     Returns object name
350 */
351
352 void SUIT_DataObject::deleteLater()
353 {
354   if ( !mySignal )
355     mySignal = new Signal( this );
356   
357   mySignal->emitSignal();
358   mySignal->deleteLater();
359 }
360
361 /*!
362     Returns object name
363 */
364
365 QString SUIT_DataObject::name() const
366 {
367   return QString::null;
368 }
369
370 /*!
371     Returns object icon
372 */
373
374 QPixmap SUIT_DataObject::icon() const
375 {
376   return QPixmap();
377 }
378
379 /*!
380     Returns object text
381 */
382
383 QString SUIT_DataObject::text( const int ) const
384 {
385   return QString::null;
386 }
387
388 /*!
389     Returns object color
390 */
391
392 QColor SUIT_DataObject::color( const ColorRole ) const
393 {
394   return QColor();
395 }
396
397 /*!
398     Returns object tool tip
399 */
400
401 QString SUIT_DataObject::toolTip() const
402 {
403   return QString::null;
404 }
405
406 /*!
407     Returns 'true' if it is possible to drag this object
408 */
409
410 bool SUIT_DataObject::isDragable() const
411 {
412   return false;
413 }
414
415 /*!
416     Returns 'true' if it is possible to drop an object "obj" to this object.
417 */
418
419 bool SUIT_DataObject::isDropAccepted( SUIT_DataObject* )
420 {
421   return false;
422 }
423
424 /*!
425     Returns type of check possibility.
426 */
427
428 SUIT_DataObject::CheckType SUIT_DataObject::checkType() const
429 {
430   return None;
431 }
432
433 /*!
434     Returns the checked state of the object.
435 */
436
437 bool SUIT_DataObject::isOn() const
438 {
439   return myCheck;
440 }
441
442 /*!
443     Sets the checked state of the object.
444 */
445
446 void SUIT_DataObject::setOn( const bool on )
447 {
448   myCheck = on;
449 }
450
451 bool SUIT_DataObject::isOpen() const
452 {
453   return myOpen;
454 }
455
456 void SUIT_DataObject::setOpen( const bool on )
457 {
458   myOpen = on;
459 }
460
461 /*!
462     Returns object personal indentification key.
463 */
464
465 SUIT_DataObjectKey* SUIT_DataObject::key() const
466 {
467   return 0;
468 }
469
470 /*!
471    Dump this data object and its children to cout
472 */
473 void SUIT_DataObject::dump( const int indent ) const
474 {
475   QString strIndent = QString().fill( ' ', indent ); // indentation string 
476   std::cout << strIndent << name() << std::endl;     // dump to cout
477   for ( DataObjectListIterator it( myChildren ); it.current(); ++it ) // iterate all children
478     it.current()->dump( indent + 2 );  // dump every child with indent + 2 spaces
479 }
480
481 /*!
482   Class: SUIT_DataObject::Signal [Internal]
483 */
484
485 SUIT_DataObject::Signal::Signal( SUIT_DataObject* o )
486 : QObject(),
487 myOwner( o )
488 {
489 }
490
491 /*!
492   Destructor.
493 */
494 SUIT_DataObject::Signal::~Signal()
495 {
496   SUIT_DataObject* o = myOwner;
497   myOwner = 0;
498   if ( o )
499   {
500     o->mySignal = 0;
501     delete o;
502   }
503 }
504
505 /*!
506   Set owner \a o.
507 */
508 void SUIT_DataObject::Signal::setOwner( SUIT_DataObject* o )
509 {
510   myOwner = o;
511 }
512
513 /*!
514   emit signal destroed owner.
515 */
516 void SUIT_DataObject::Signal::emitSignal()
517 {
518   if ( myOwner )
519     emit destroyed( myOwner );
520 }