Salome HOME
Merge from V6_main_20120808 08Aug12
[modules/gui.git] / src / SUIT / SUIT_DataObject.cxx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // File   : SUIT_DataObject.cxx
24 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
25
26 #include <QVariant>
27
28 #include "SUIT_DataObject.h"
29 #include "SUIT_DataObjectKey.h"
30 #include <cstdio>
31
32 SUIT_DataObject::Signal* SUIT_DataObject::mySignal = 0;
33
34 /*!
35   \class SUIT_DataObject
36   \brief Data object representing the data instance in the tree-like hierarchy.
37
38   Data object represents uniform data tree structure recommended to use in the
39   SUIT-based applications.
40 */
41
42 /*!
43   \brief Constructor.
44
45   Creates the data object with the specified parent.
46   To create the top-level object, pass 0 as parameter.
47
48   \param p parent object
49 */
50 SUIT_DataObject::SUIT_DataObject( SUIT_DataObject* p )
51 : myParent( 0 ),
52   myOpen( false ),
53   myCheck( false ),
54   myAutoDel( true ),
55   _modified( false )
56 {
57   setParent( p );
58   signal()->emitCreated( this );
59 }
60
61 /*!
62   \brief Destructor.
63
64   Destroys all the children if "auto-delete children" flag is set.
65 */
66 SUIT_DataObject::~SUIT_DataObject()
67 {
68   SUIT_DataObject* p = myParent;
69
70   myParent = 0;
71
72   if ( p )
73     p->removeChild( this );
74
75   signal()->emitDestroyed( this );
76
77   for ( DataObjectList::iterator it = myChildren.begin(); it != myChildren.end(); ++it )
78     (*it)->myParent = 0;
79
80   if ( autoDeleteChildren() )
81   {
82     for ( DataObjectList::iterator itr = myChildren.begin(); itr != myChildren.end(); ++itr )
83       delete *itr;
84   }
85 }
86
87 /*!
88   \brief Get the root object.
89   \return root object of the data tree
90 */
91 SUIT_DataObject* SUIT_DataObject::root() const
92 {
93   return parent() ? parent()->root() : (SUIT_DataObject*)this;
94 }
95
96 /*!
97   \brief Get the first child object.
98   \return first child object or 0 if there are no children
99   \sa lastChild()
100 */
101 SUIT_DataObject* SUIT_DataObject::firstChild() const
102 {
103   SUIT_DataObject* child = 0;
104   if ( !myChildren.isEmpty() )
105     child = myChildren.first();
106   return child;
107 }
108
109 /*!
110   \brief Get the last child object.
111   \return last child object or 0 if there are no children
112   \sa firstChild()
113 */
114 SUIT_DataObject* SUIT_DataObject::lastChild() const
115 {
116   SUIT_DataObject* child = 0;
117   if ( !myChildren.isEmpty() )
118     child = myChildren.last();
119   return child;
120 }
121
122 /*!
123   \brief Get the number of the child objects.
124   \return number of the children
125 */
126 int SUIT_DataObject::childCount() const
127 {
128   return myChildren.count();
129 }
130
131 /*!
132   \brief Get the index of the specified object in the child list.
133   \param obj child object
134   \return subobject position or -1 if it does not belong to this object
135 */
136 int SUIT_DataObject::childPos( const SUIT_DataObject* obj ) const
137 {
138   return myChildren.indexOf( (SUIT_DataObject*)obj );
139 }
140
141 /*!
142   \brief Get child object by the specified index.
143   \param idx child object index
144   \return child object or 0 if index is out of range
145 */
146 SUIT_DataObject* SUIT_DataObject::childObject( const int idx ) const
147 {
148   SUIT_DataObject* child = 0;
149
150   if ( idx >= 0 && idx < myChildren.count() )
151     child = myChildren.at( idx );
152
153   return child;
154 }
155
156 /*!
157   \brief Get the object level in the tree structure.
158
159   Root object has level 0.
160
161   \return object level.
162 */
163 int SUIT_DataObject::level() const
164 {
165   int lev = 0;
166   SUIT_DataObject* p = parent();
167   while ( p ) {
168     p = p->parent();
169     lev++;
170   }
171   return lev;
172 }
173
174 /*!
175   \brief Get the position of the data object in its parent's children list
176   \return data object position
177 */
178 int SUIT_DataObject::position() const
179 {
180   return myParent ? myParent->childPos( this ) : 0;
181 }
182
183 /*!
184   \brief Get the next sibling data object in the children list.
185   \return child object or 0 if there is no next sibling
186   \sa prevBrother()
187 */
188 SUIT_DataObject* SUIT_DataObject::nextBrother() const
189 {
190   return myParent ? myParent->childObject( myParent->childPos( this ) + 1 ) : 0;
191 }
192
193 /*!
194   \brief Get the previous sibling data object in the children list.
195   \return child object or 0 if there is no previous sibling
196   \sa nextBrother()
197 */
198 SUIT_DataObject* SUIT_DataObject::prevBrother() const
199 {
200   return myParent ? myParent->childObject( myParent->childPos( this ) - 1 ) : 0;
201 }
202
203 /*!
204   \brief Get "auto-delete children" flag.
205   \return \c true if the object should delete all its children on destroying
206   \sa setAutoDeleteChildren()
207 */
208 bool SUIT_DataObject::autoDeleteChildren() const
209 {
210   return myAutoDel;
211 }
212
213 /*!
214   \brief Set "auto-delete children" flag.
215
216   If this flag is on (default), the object will delete
217   all its children on destroying.
218
219   \param on new flag value
220   \sa autoDeleteChildren()
221 */
222 void SUIT_DataObject::setAutoDeleteChildren( const bool on )
223 {
224   myAutoDel = on;
225 }
226
227 /*!
228   \brief Get all children.
229
230   If parameter \a rec is \c true then function collects all
231   the children recursively.
232
233   \param lst returning list of children
234   \param rec if \c true collect all children recursively
235 */
236 void SUIT_DataObject::children( DataObjectList& lst, const bool rec ) const
237 {
238   for ( DataObjectList::const_iterator it = myChildren.begin(); it != myChildren.end(); ++it )
239   {
240     lst.append( *it );
241     if ( rec )
242       (*it)->children( lst, rec );
243   }
244 }
245
246 /*!
247   \brief Get all children.
248   \override
249
250   If parameter \a rec is \c true then function collects all
251   the children recursively.
252
253   \param rec if \c true collect all children recursively
254   \return list of children
255 */
256 DataObjectList SUIT_DataObject::children( const bool rec )
257 {
258   DataObjectList lst;
259   children( lst, rec );
260   return lst;
261 }
262
263 /*!
264   \brief Add new child object to the end of the children list.
265   \param obj child object being added
266 */
267 void SUIT_DataObject::appendChild( SUIT_DataObject* obj )
268 {
269   insertChild( obj, myChildren.count() );
270 }
271
272 /*!
273   \brief Insert new child object to the list of the children.
274   \param obj child object being added
275   \param position child position
276 */
277 void SUIT_DataObject::insertChild( SUIT_DataObject* obj, int position )
278 {
279   if ( !obj || myChildren.contains( obj ) )
280     return;
281
282   int pos = position < 0 ? myChildren.count() : position;
283   myChildren.insert( qMin( pos, (int)myChildren.count() ), obj );
284   obj->setParent( this );
285   signal()->emitInserted( obj, this );
286 }
287
288 /*!
289   \brief Insert new child object into the list of the children (faster version of insertChild without signal).
290   \param obj child object being added
291   \param position child position
292 */
293 void SUIT_DataObject::insertChildAtPos( SUIT_DataObject* obj, int position )
294 {
295   if ( !obj )return;
296   int pos = position < 0 ? myChildren.count() : position;
297   myChildren.insert( qMin( pos, (int)myChildren.count() ), obj );
298   obj->assignParent( this );
299 }
300
301 /*!
302   \brief Remove the specified child object reference.
303   \param obj child object being removed
304   \param del if \c true, the child object is destroyed
305 */
306 void SUIT_DataObject::removeChild( SUIT_DataObject* obj, const bool del )
307 {
308   if ( !obj )
309     return;
310
311   if ( myChildren.removeAll( obj ) ) {
312     signal()->emitRemoved( obj, this );
313     obj->setParent( 0 );
314
315     if ( del )
316       obj->deleteLater();
317   }
318 }
319
320 /*!
321   \brief Replace the specified child object by another object.
322   \param src child object being replaced
323   \param trg new child object
324   \param del if \c true, the previous object is destroyed
325   \return \c true if the object has been replaced
326 */
327 bool SUIT_DataObject::replaceChild( SUIT_DataObject* src, SUIT_DataObject* trg, const bool del )
328 {
329   if ( !src || !trg )
330     return false;
331
332   int idx = childPos( trg );
333   removeChild( trg );
334
335   int pos = childPos( src );
336   if ( pos < 0 )
337   {
338     if ( idx >= 0 )
339       insertChild( trg, idx );
340     return false;
341   }
342
343   insertChild( trg, pos );
344   removeChild( src );
345
346   if ( del )
347     src->deleteLater();
348
349   return true;
350 }
351
352 /*!
353   \brief Change the parent for all children from specified object to this one.
354   \param obj object which children to be reparented
355 */
356 void SUIT_DataObject::reparentChildren( const SUIT_DataObject* obj )
357 {
358   if ( !obj )
359     return;
360
361   DataObjectList lst;
362   obj->children( lst );
363   for ( DataObjectList::iterator it = lst.begin(); it != lst.end(); ++it )
364     (*it)->setParent( this );
365 }
366
367 /*!
368   \brief Get the parent object.
369   \return parent object or 0 if this is top-level item
370 */
371 SUIT_DataObject* SUIT_DataObject::parent() const
372 {
373   return myParent;
374 }
375
376 /*!
377   \brief Change the parent object.
378   \param p new parent object
379 */
380 void SUIT_DataObject::setParent( SUIT_DataObject* p )
381 {
382   if ( p == parent() )
383     return;
384
385   if ( parent() )
386     parent()->removeChild( this );
387
388   myParent = p;
389
390   if ( parent() )
391     parent()->appendChild( this );
392 }
393
394 void SUIT_DataObject::assignParent( SUIT_DataObject* p )
395 {
396   if ( p == myParent )
397     return;
398
399   myParent = p;
400 }
401
402 /*!
403   \brief Get data object name.
404
405   This method should be re-implemented in the subclasses.
406   Default implementation returns null string.
407
408   \return object name
409 */
410 QString SUIT_DataObject::name() const
411 {
412   return QString();
413 }
414
415 /*!
416   \brief Get object text data for the specified column.
417
418   This method can be re-implemented in the subclasses.
419   Default implementation returns null string.
420
421   Column with \a id = 0 (NameId) is supposed to be used
422   to get the object name (as it does the default implementation).
423
424   \param id column id
425   \return object text data
426 */
427 QString SUIT_DataObject::text( const int id ) const
428 {
429   return id == NameId ? name() : QString();
430 }
431
432 /*!
433   \brief Get data object icon for the specified column.
434
435   This method can be re-implemented in the subclasses.
436   Default implementation returns null pixmap.
437
438   The parameter \a id specifies the column identificator
439
440   \param id column id
441   \return object icon for the specified column
442 */
443 QPixmap SUIT_DataObject::icon( const int /*id*/ ) const
444 {
445   return QPixmap();
446 }
447
448 /*!
449   \brief Get data object color for the specified column.
450
451   This method can be re-implemented in the subclasses.
452   Default implementation returns null color.
453
454   The parameter \a id specifies the column identificator
455
456   \param role color role
457   \param id column id
458   \return object color for the specified column
459 */
460 QColor SUIT_DataObject::color( const ColorRole /*role*/, const int /*id*/ ) const
461 {
462   return QColor();
463 }
464
465 /*!
466   \brief Get data object tooltip for the specified column.
467
468   This method can be re-implemented in the subclasses.
469   Default implementation returns null string.
470
471   The parameter \a id specifies the column identificator
472   (to display, for example, in the tree view widget).
473
474   \param id column id
475   \return object tooltip for the specified column
476 */
477 QString SUIT_DataObject::toolTip( const int /*id*/ ) const
478 {
479   return QString();
480 }
481
482 /*!
483   \brief Get data object status tip for the specified column.
484
485   This method can be re-implemented in the subclasses.
486   Default implementation returns null string.
487
488   The parameter \a id specifies the column identificator
489
490   \param id column id
491   \return object status tip for the specified column
492 */
493 QString SUIT_DataObject::statusTip( const int /*id*/ ) const
494 {
495   return QString();
496 }
497
498 /*!
499   \brief Get data object "what's this" information for the
500          specified column.
501
502   This method can be re-implemented in the subclasses.
503   Default implementation returns null string.
504
505   The parameter \a id specifies the column identificator
506
507   \param id column id
508   \return object "what's this" information for the specified column
509 */
510 QString SUIT_DataObject::whatsThis( const int /*id*/ ) const
511 {
512   return QString();
513 }
514
515 /*!
516   \brief Get data object font for the specified column.
517
518   This method can be re-implemented in the subclasses.
519   Default implementation returns application default font.
520
521   The parameter \a id specifies the column identificator
522
523   \param id column id
524   \return object font for the specified column
525 */
526 QFont SUIT_DataObject::font( const int /*id*/ ) const
527 {
528   return QFont();
529 }
530
531 /*!
532   \brief Get data object text alignment for the specified column.
533
534   This method can be re-implemented in the subclasses.
535   Default implementation returns default alignment which
536   is Qt:AlignLeft.
537
538   The parameter \a id specifies the column identificator
539   (to display, for example, in the tree view widget).
540
541   \param id column id
542   \return object text alignment flags for the specified column
543 */
544 int SUIT_DataObject::alignment( const int /*id*/ ) const
545 {
546   return Qt::AlignLeft;
547 }
548
549 bool SUIT_DataObject::expandable() const
550 {
551   return true;
552 }
553
554 /*!
555   \brief Check if the object is visible.
556
557   This method can be re-implemented in the subclasses.
558   Default implementation returns \c true (all objects are visible by default).
559
560   \return \c true if this object is displayable or \c false otherwise
561 */
562 bool SUIT_DataObject::isVisible() const
563 {
564   return true;
565 }
566
567 /*!
568   \brief Check if the object is draggable.
569
570   This method can be re-implemented in the subclasses.
571   Default implementation returns \c false (all objects could not be dragged).
572
573   \return \c true if it is possible to drag this object
574 */
575 bool SUIT_DataObject::isDraggable() const
576 {
577   return false;
578 }
579
580 /*!
581   \brief Check if the drop operation for this object is possible.
582
583   This method can be re-implemented in the subclasses.
584   Default implementation returns \c false (drop operation is not allowed).
585
586   \return \c true if it is possible to drop one or more objects (currently selected) to this object
587 */
588 bool SUIT_DataObject::isDropAccepted() const
589 {
590   return false;
591 }
592
593 /*!
594   \brief Check if this object is enabled.
595
596   This method can be re-implemented in the subclasses.
597   Default implementation returns \c true (all objects are enabled).
598
599   \return \c true if the user can interact with the item
600 */
601 bool SUIT_DataObject::isEnabled() const
602 {
603   return true;
604 }
605
606 /*!
607   \brief Check if this object is selectable.
608
609   This method can be re-implemented in the subclasses.
610   Default implementation returns \c true (all objects are selectable).
611
612   \return \c true if the item can be selected
613 */
614 bool SUIT_DataObject::isSelectable() const
615 {
616   return true;
617 }
618
619 /*!
620   \brief Check if this object is checkable for the specified column.
621
622   This method can be re-implemented in the subclasses.
623   Default implementation returns \c false (all objects are not checkable).
624
625   \param id column id
626   \return \c true if the item can be checked or unchecked by the user
627   \sa isOn(), setOn()
628 */
629 bool SUIT_DataObject::isCheckable( const int /*id*/ ) const
630 {
631   return false;
632 }
633
634 /*!
635   \brief Check if this object is can't be renamed in place
636
637   This method can be re-implemented in the subclasses.
638   Default implementation returns \c false (all objects can not be renamed).
639
640   \param id column id
641   \return \c true if the item can be renamed by the user in place (e.g. in the Object browser)
642 */
643 bool SUIT_DataObject::renameAllowed( const int /*id*/ ) const
644 {
645   return false;
646 }
647
648 /*!
649   \brief Set name of the this object.
650
651   This method can be re-implemented in the subclasses.
652   Default implementation returns \c false.
653
654   \return \c true if rename operation finished successfully, \c false otherwise.
655 */
656 bool SUIT_DataObject::setName(const QString& /*name*/) {
657   return false;
658 }
659
660 /*!
661   \brief Get the checked state of the object (if it is checkable)
662   for the specified column.
663
664   Default implementation supports the checked state for the first
665   ("Name") column only.
666
667   \param id column id
668   \return checked state of the object for the specified column
669   \sa setOn(), isCheckable()
670 */
671 bool SUIT_DataObject::isOn( const int id ) const
672 {
673   return id == NameId && myCheck;
674 }
675
676 /*!
677   \brief Set the checked state of the object (if it is checkable)
678   for the specified column.
679
680   Default implementation supports the checked state for the first
681   ("Name") column only.
682
683   \param on new checked state of the object for the specified column
684   \param id column id
685   \sa isOn(), isCheckable()
686 */
687 void SUIT_DataObject::setOn( const bool on, const int id )
688 {
689   if( id == NameId )
690     myCheck = on;
691 }
692
693 /*!
694   \brief Get the "opened" state of the object.
695   \return "opened" state of the object
696   \sa setOpen()
697 */
698 bool SUIT_DataObject::isOpen() const
699 {
700   return myOpen;
701 }
702
703 /*!
704   \brief Set the "opened" state of the object.
705   \param on new "opened" state of the object
706   \sa isOpen()
707 */
708 void SUIT_DataObject::setOpen( const bool on )
709 {
710   myOpen = on;
711 }
712
713 /*!
714   \brief Check if the specified column supports custom sorting.
715
716   This method can be re-implemented in the subclasses.
717   Default implementation returns false ("Name" column does not require
718   custom sorting).
719
720   \param id column id
721   \return \c true if column sorting should be customized
722   \sa compare()
723 */
724 bool SUIT_DataObject::customSorting( const int /*id*/ ) const
725 {
726   return false;
727 }
728
729 /*!
730   \brief Compares data from two items for sorting purposes.
731
732   This method can be re-implemented in the subclasses.
733   Default implementation returns false ("Name" column does not require
734   custom sorting).
735
736   This method is called only for those columns for which customSorting()
737   method returns \c true.
738
739   \param left first data to compare
740   \param right second data to compare
741   \param id column id
742   \return result of the comparison
743   \sa customSorting()
744 */
745 bool SUIT_DataObject::compare( const QVariant& /*left*/, const QVariant& /*right*/,
746                                const int /*id*/ ) const
747 {
748   return false;
749 }
750
751 /*!
752   \brief Get the object unique indentification key.
753
754   This method can be re-implemented in the subclasses.
755   Default implementation returns 0.
756
757   \return object key
758 */
759 SUIT_DataObjectKey* SUIT_DataObject::key() const
760 {
761   return 0;
762 }
763
764 /*!
765   \brief Get global signal handler.
766   \return the only instance of the signal handler
767 */
768 SUIT_DataObject::Signal* SUIT_DataObject::signal()
769 {
770   if ( !mySignal )
771     mySignal = new Signal();
772   return mySignal;
773 }
774
775 /*!
776   \brief Connect to the signal handlerx
777   \param sig signal name
778   \param reciever signal receiver object
779   \param slot slot name
780   \return \c true if connection is successfull
781 */
782 bool SUIT_DataObject::connect( const char* sig, QObject* reciever, const char* slot )
783 {
784   if ( !reciever || !slot )
785     return false;
786
787   signal()->disconnect( signal(), sig, reciever, slot );
788   return signal()->connect( signal(), sig, reciever, slot );
789 }
790
791 /*!
792   \brief Disconnect from the signal handler
793   \param sig signal name
794   \param reciever signal receiver object
795   \param slot slot name
796   \return \c true if disconnection is successfull
797 */
798 bool SUIT_DataObject::disconnect( const char* sig, QObject* reciever, const char* slot )
799 {
800   if ( !reciever || !slot )
801     return false;
802   return signal()->disconnect( signal(), sig, reciever, slot );
803 }
804
805 /*!
806   \brief Schedule this object for the late deleting.
807
808   The object will be deleted when control returns to the event loop.
809   Note that entering and leaving a new event loop (e.g., by opening
810   a modal dialog) will not perform the deferred deletion; for the object
811   to be deleted, the control must return to the event loop from which
812   deleteLater() was called.
813 */
814 void SUIT_DataObject::deleteLater()
815 {
816   if ( parent() )
817     parent()->removeChild( this, false ); // to avoid infinite loop!
818   signal()->deleteLater( this );
819 }
820
821 /*!
822   \brief Dump the object tree recursively to the standard output.
823   \param indent current indentation level
824 */
825 void SUIT_DataObject::dump( const int indent ) const
826 {
827   QString strIndent = QString().fill( ' ', indent ); // indentation string
828   printf( "%s%s\n", strIndent.toLatin1().data(), name().toLatin1().data() );
829   for ( DataObjectList::const_iterator it = myChildren.begin(); it != myChildren.end(); ++it )
830     (*it)->dump( indent + 2 );
831 }
832
833 /*!
834   \class SUIT_DataObject::Signal
835   \brief Watcher class, responsible for the emitting signals on behalf of
836   the data objects.
837
838   SUIT_DataObject class does not inherit from QObject for the performance
839   reasons, so it can not use signals/slots mechanism directly.
840   Instead it uses the only Signal object to emit the signals when the data
841   object is created, destroyed, inserted to the parent object or removed
842   from it.
843
844   If some object needs to handle, for example, data object destroying, it can
845   use SUIT_DataObject::signal() method to connect the signal:
846   \code
847   MyHandler* h = new MyHandler();
848   h->connect( SUIT_DataObject::signal(), SIGNAL(destroyed(SUIT_DataObject*)),
849               h, SLOT(onDestroyed(SUIT_DataObject*)) );
850   \endcode
851   The same can be done by using static method SUIT_DataObject::connect().
852   For example,
853   \code
854   MyHandler* h = new MyHandler();
855   SUIT_DataObject::connect( SIGNAL(destroyed(SUIT_DataObject*)),
856                             h, SLOT(onDestroyed(SUIT_DataObject*)));
857   \endcode
858 */
859
860 /*!
861   \brief Constructor.
862 */
863 SUIT_DataObject::Signal::Signal()
864 : QObject()
865 {
866 }
867
868 /*!
869   \brief Destructor.
870
871   Destroys data object which are scheduled for the deleting with the deleteLater().
872 */
873 SUIT_DataObject::Signal::~Signal()
874 {
875   for ( DataObjectList::Iterator it = myDelLaterObjects.begin();
876         it != myDelLaterObjects.end(); ++it ) {
877     delete *it;
878   }
879   myDelLaterObjects.clear();
880 }
881
882 /*!
883   \brief Emit signal about data object creation.
884   \param object data object being created
885 */
886 void SUIT_DataObject::Signal::emitCreated( SUIT_DataObject* object )
887 {
888   if ( object )
889     emit created( object );
890 }
891
892 /*!
893   \brief Emit signal about data object destroying.
894   \param object data object being destroyed
895 */
896 void SUIT_DataObject::Signal::emitDestroyed( SUIT_DataObject* object )
897 {
898   if ( object ) {
899     if ( myDelLaterObjects.contains( object ) )
900       // object is being destroyed after calling deleteLater():
901       // the signal has been already emitted from deleteLater()
902       // we should avoid repeating of the object destroying from
903       // the Signal destructor
904       myDelLaterObjects.removeAll( object );
905     else
906       // object is being destroyed directly or via deleteLater()
907       emit destroyed( object );
908   }
909 }
910
911 /*!
912   \brief Emit signal about data object adding to the parent data object.
913   \param object data object being added
914   \param parent parent data object
915 */
916 void SUIT_DataObject::Signal::emitInserted( SUIT_DataObject* object, SUIT_DataObject* parent )
917 {
918   emit( inserted( object, parent ) );
919 }
920
921 /*!
922   \brief Emit signal about data object removed from the parent data object.
923   \param object data object being removed
924   \param parent parent data object
925 */
926 void SUIT_DataObject::Signal::emitRemoved( SUIT_DataObject* object, SUIT_DataObject* parent )
927 {
928   emit( removed( object, parent ) );
929 }
930
931 /*!
932   \brief Schedule data object for the late deleting.
933   \param object data object to be deleted later
934 */
935 void SUIT_DataObject::Signal::deleteLater( SUIT_DataObject* object )
936 {
937   if ( !myDelLaterObjects.contains( object ) ) {
938     emitDestroyed( object );
939     myDelLaterObjects.append( object );
940   }
941 }
942
943 /*!
944   \brief Updates necessary internal fields of data object
945 */
946 void SUIT_DataObject::update()
947 {
948 }
949
950 /*!
951   \brief return unique group identificator
952
953   Groups of data objects are used for column information search.
954   Each column of data model has one or several registered group id
955   If object has the same group id as one of registered, the information
956   will be shown; the custom id of column will be passed into data() method
957   in order to identify column from point of view of data object
958
959  */
960 int SUIT_DataObject::groupId() const
961 {
962   return 0;
963 }
964 /*!
965   \brief return custom data for data object.
966  */
967 QVariant SUIT_DataObject::customData(Qtx::CustomDataType /*type*/) {
968   return QVariant();
969 }
970 /*!
971   \fn void SUIT_DataObject::Signal::created( SUIT_DataObject* object );
972   \brief Emitted when data object is created.
973   \param object data object being created
974 */
975
976 /*!
977   \fn void SUIT_DataObject::Signal::destroyed( SUIT_DataObject* object );
978   \brief Emitted when data object is destroyed.
979   \param object data object being destroyed
980 */
981
982 /*!
983   \fn void SUIT_DataObject::Signal::inserted( SUIT_DataObject* object, SUIT_DataObject* parent );
984   \brief Emitted when data object is inserted to the parent data object.
985   \param object data object being created
986   \param parent parent data object
987 */
988
989 /*!
990   \fn void SUIT_DataObject::Signal::removed( SUIT_DataObject* object, SUIT_DataObject* parent );
991   \brief Emitted when data object is removed from the parent data object.
992   \param object data object being removed
993   \param parent parent data object
994 */