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