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