source: vendor/trolltech/current/src/kernel/qobject.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 78.3 KB
Line 
1/****************************************************************************
2** $Id: qobject.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Implementation of QObject class
5**
6** Created : 930418
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the kernel module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qvariant.h"
39#include "qapplication.h"
40#include "qobject.h"
41#include "qobjectlist.h"
42#include "qsignalslotimp.h"
43#include "qregexp.h"
44#include "qmetaobject.h"
45#include <private/qucom_p.h>
46#include "qucomextra_p.h"
47#include "qptrvector.h"
48
49#ifdef QT_THREAD_SUPPORT
50#include <qmutex.h>
51#include <private/qmutexpool_p.h>
52#endif
53
54#include <ctype.h>
55
56
57#ifndef QT_NO_USERDATA
58class QObjectPrivate : public QPtrVector<QObjectUserData>
59{
60public:
61 QObjectPrivate( uint s ) : QPtrVector<QObjectUserData>(s){ setAutoDelete( TRUE ); }
62};
63#else
64class QObjectPrivate {
65}
66#endif
67
68class QSenderObjectList : public QObjectList, public QShared
69{
70public:
71 QSenderObjectList() : currentSender( 0 ) { }
72 QObject *currentSender;
73};
74
75/*!
76 \class Qt qnamespace.h
77
78 \brief The Qt class is a namespace for miscellaneous identifiers
79 that need to be global-like.
80
81 \ingroup misc
82
83 Normally, you can ignore this class. QObject and a few other
84 classes inherit it, so all the identifiers in the Qt namespace are
85 normally usable without qualification.
86
87 However, you may occasionally need to say \c Qt::black instead of
88 just \c black, particularly in static utility functions (such as
89 many class factories).
90
91*/
92
93/*!
94 \enum Qt::Orientation
95
96 This type is used to signify an object's orientation.
97
98 \value Horizontal
99 \value Vertical
100
101 Orientation is used with QScrollBar for example.
102*/
103
104
105/*!
106 \class QObject qobject.h
107 \brief The QObject class is the base class of all Qt objects.
108
109 \ingroup objectmodel
110 \mainclass
111 \reentrant
112
113 QObject is the heart of the \link object.html Qt object model.
114 \endlink The central feature in this model is a very powerful
115 mechanism for seamless object communication called \link
116 signalsandslots.html signals and slots \endlink. You can
117 connect a signal to a slot with connect() and destroy the
118 connection with disconnect(). To avoid never ending notification
119 loops you can temporarily block signals with blockSignals(). The
120 protected functions connectNotify() and disconnectNotify() make it
121 possible to track connections.
122
123 QObjects organize themselves in object trees. When you create a
124 QObject with another object as parent, the object will
125 automatically do an insertChild() on the parent and thus show up
126 in the parent's children() list. The parent takes ownership of the
127 object i.e. it will automatically delete its children in its
128 destructor. You can look for an object by name and optionally type
129 using child() or queryList(), and get the list of tree roots using
130 objectTrees().
131
132 Every object has an object name() and can report its className()
133 and whether it inherits() another class in the QObject inheritance
134 hierarchy.
135
136 When an object is deleted, it emits a destroyed() signal. You can
137 catch this signal to avoid dangling references to QObjects. The
138 QGuardedPtr class provides an elegant way to use this feature.
139
140 QObjects can receive events through event() and filter the events
141 of other objects. See installEventFilter() and eventFilter() for
142 details. A convenience handler, childEvent(), can be reimplemented
143 to catch child events.
144
145 Last but not least, QObject provides the basic timer support in
146 Qt; see QTimer for high-level support for timers.
147
148 Notice that the Q_OBJECT macro is mandatory for any object that
149 implements signals, slots or properties. You also need to run the
150 \link moc.html moc program (Meta Object Compiler) \endlink on the
151 source file. We strongly recommend the use of this macro in \e all
152 subclasses of QObject regardless of whether or not they actually
153 use signals, slots and properties, since failure to do so may lead
154 certain functions to exhibit undefined behaviour.
155
156 All Qt widgets inherit QObject. The convenience function
157 isWidgetType() returns whether an object is actually a widget. It
158 is much faster than inherits( "QWidget" ).
159
160 Some QObject functions, e.g. children(), objectTrees() and
161 queryList() return a QObjectList. A QObjectList is a QPtrList of
162 QObjects. QObjectLists support the same operations as QPtrLists
163 and have an iterator class, QObjectListIt.
164*/
165
166
167//
168// Remove white space from SIGNAL and SLOT names.
169// Internal for QObject::connect() and QObject::disconnect()
170//
171
172static inline bool isIdentChar( char x )
173{ // Avoid bug in isalnum
174 return x == '_' || (x >= '0' && x <= '9') ||
175 (x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z');
176}
177
178static inline bool isSpace( char x )
179{
180#if defined(Q_CC_BOR)
181 /*
182 Borland C++ 4.5 has a weird isspace() bug.
183 isspace() usually works, but not here.
184 This implementation is sufficient for our internal use: rmWS()
185 */
186 return (uchar) x <= 32;
187#else
188 return isspace( (uchar) x );
189#endif
190}
191
192static QCString qt_rmWS( const char *s )
193{
194 QCString result( qstrlen(s)+1 );
195 char *d = result.data();
196 char last = 0;
197 while( *s && isSpace(*s) ) // skip leading space
198 s++;
199 while ( *s ) {
200 while ( *s && !isSpace(*s) )
201 last = *d++ = *s++;
202 while ( *s && isSpace(*s) )
203 s++;
204 if ( *s && isIdentChar(*s) && isIdentChar(last) )
205 last = *d++ = ' ';
206 }
207 *d = '\0';
208 result.truncate( (int)(d - result.data()) );
209 int void_pos = result.find("(void)");
210 if ( void_pos >= 0 )
211 result.remove( void_pos+1, (uint)strlen("void") );
212 return result;
213}
214
215
216// Event functions, implemented in qapplication_xxx.cpp
217
218int qStartTimer( int interval, QObject *obj );
219bool qKillTimer( int id );
220bool qKillTimer( QObject *obj );
221
222static void removeObjFromList( QObjectList *objList, const QObject *obj,
223 bool single=FALSE )
224{
225 if ( !objList )
226 return;
227 int index = objList->findRef( obj );
228 while ( index >= 0 ) {
229 objList->remove();
230 if ( single )
231 return;
232 index = objList->findNextRef( obj );
233 }
234}
235
236
237/*!
238 \relates QObject
239
240 Returns a pointer to the object named \a name that inherits \a
241 type and with a given \a parent.
242
243 Returns 0 if there is no such child.
244
245 \code
246 QListBox *c = (QListBox *) qt_find_obj_child( myWidget, "QListBox",
247 "my list box" );
248 if ( c )
249 c->insertItem( "another string" );
250 \endcode
251*/
252
253void *qt_find_obj_child( QObject *parent, const char *type, const char *name )
254{
255 const QObjectList *list = parent->children();
256 if ( list ) {
257 QObjectListIt it( *list );
258 QObject *obj;
259 while ( (obj = it.current()) ) {
260 ++it;
261 if ( qstrcmp(name,obj->name()) == 0 &&
262 obj->inherits(type) )
263 return obj;
264 }
265 }
266 return 0;
267}
268
269
270
271#ifndef QT_NO_PRELIMINARY_SIGNAL_SPY
272/*
273 Preliminary signal spy
274 */
275Q_EXPORT QObject* qt_preliminary_signal_spy = 0;
276static QObject* qt_spy_signal_sender = 0;
277
278static void qt_spy_signal( QObject* sender, int signal, QUObject* o )
279{
280 QMetaObject* mo = sender->metaObject();
281 while ( mo && signal - mo->signalOffset() < 0 )
282 mo = mo->superClass();
283 if ( !mo )
284 return;
285 const QMetaData* sigData = mo->signal( signal - mo->signalOffset() );
286 if ( !sigData )
287 return;
288 QCString s;
289 mo = sender->metaObject();
290 while ( mo ) {
291 s.sprintf( "%s_%s", mo->className(), sigData->name );
292 int slot = qt_preliminary_signal_spy->metaObject()->findSlot( s, TRUE );
293 if ( slot >= 0 ) {
294#ifdef QT_THREAD_SUPPORT
295 // protect access to qt_spy_signal_sender
296 void * const address = &qt_spy_signal_sender;
297 QMutexLocker locker( qt_global_mutexpool ?
298 qt_global_mutexpool->get( address ) : 0 );
299#endif // QT_THREAD_SUPPORT
300
301 QObject* old_sender = qt_spy_signal_sender;
302 qt_spy_signal_sender = sender;
303 qt_preliminary_signal_spy->qt_invoke( slot, o );
304 qt_spy_signal_sender = old_sender;
305 break;
306 }
307 mo = mo->superClass();
308 }
309}
310
311/*
312 End Preliminary signal spy
313 */
314#endif // QT_NO_PRELIMINARY_SIGNAL_SPY
315
316static QObjectList* object_trees = 0;
317
318#ifdef QT_THREAD_SUPPORT
319static QMutex *obj_trees_mutex = 0;
320#endif
321
322static void cleanup_object_trees()
323{
324 delete object_trees;
325 object_trees = 0;
326#ifdef QT_THREAD_SUPPORT
327 delete obj_trees_mutex;
328 obj_trees_mutex = 0;
329#endif
330}
331
332static void ensure_object_trees()
333{
334 object_trees = new QObjectList;
335 qAddPostRoutine( cleanup_object_trees );
336}
337
338static void insert_tree( QObject* obj )
339{
340#ifdef QT_THREAD_SUPPORT
341 if ( !obj_trees_mutex )
342 obj_trees_mutex = new QMutex();
343 QMutexLocker locker( obj_trees_mutex );
344#endif
345 if ( !object_trees )
346 ensure_object_trees();
347 object_trees->insert(0, obj );
348}
349
350static void remove_tree( QObject* obj )
351{
352 if ( object_trees ) {
353#ifdef QT_THREAD_SUPPORT
354 QMutexLocker locker( obj_trees_mutex );
355#endif
356 object_trees->removeRef( obj );
357 }
358}
359
360
361/*****************************************************************************
362 QObject member functions
363 *****************************************************************************/
364
365/*!
366 Constructs an object called \a name with parent object, \a parent.
367
368 The parent of an object may be viewed as the object's owner. For
369 instance, a \link QDialog dialog box\endlink is the parent of the
370 "OK" and "Cancel" buttons it contains.
371
372 The destructor of a parent object destroys all child objects.
373
374 Setting \a parent to 0 constructs an object with no parent. If the
375 object is a widget, it will become a top-level window.
376
377 The object name is some text that can be used to identify a
378 QObject. It's particularly useful in conjunction with \link
379 designer-manual.book <i>Qt Designer</i>\endlink. You can find an
380 object by name (and type) using child(). To find several objects
381 use queryList().
382
383 \sa parent(), name(), child(), queryList()
384*/
385
386QObject::QObject( QObject *parent, const char *name )
387 :
388 isSignal( FALSE ), // assume not a signal object
389 isWidget( FALSE ), // assume not a widget object
390 pendTimer( FALSE ), // no timers yet
391 blockSig( FALSE ), // not blocking signals
392 wasDeleted( FALSE ), // double-delete catcher
393 isTree( FALSE ), // no tree yet
394 objname( name ? qstrdup(name) : 0 ), // set object name
395 parentObj( 0 ), // no parent yet. It is set by insertChild()
396 childObjects( 0 ), // no children yet
397 connections( 0 ), // no connections yet
398 senderObjects( 0 ), // no signals connected yet
399 eventFilters( 0 ), // no filters installed
400 postedEvents( 0 ), // no events posted
401 d( 0 )
402{
403 if ( !metaObj ) // will create object dict
404 (void) staticMetaObject();
405
406 if ( parent ) { // add object to parent
407 parent->insertChild( this );
408 } else {
409 insert_tree( this );
410 isTree = TRUE;
411 }
412}
413
414
415/*!
416 Destroys the object, deleting all its child objects.
417
418 All signals to and from the object are automatically disconnected.
419
420 \warning All child objects are deleted. If any of these objects
421 are on the stack or global, sooner or later your program will
422 crash. We do not recommend holding pointers to child objects from
423 outside the parent. If you still do, the QObject::destroyed()
424 signal gives you an opportunity to detect when an object is
425 destroyed.
426
427 \warning Deleting a QObject while pending events are waiting to be
428 delivered can cause a crash. You must not delete the QObject
429 directly from a thread that is not the GUI thread. Use the
430 QObject::deleteLater() method instead, which will cause the event
431 loop to delete the object after all pending events have been
432 delivered to the object.
433*/
434
435QObject::~QObject()
436{
437 if ( wasDeleted ) {
438#if defined(QT_DEBUG)
439 qWarning( "Double QObject deletion detected." );
440#endif
441 return;
442 }
443 wasDeleted = 1;
444 blockSig = 0; // unblock signals to keep QGuardedPtr happy
445 emit destroyed( this );
446 emit destroyed();
447 if ( objname )
448 delete [] (char*)objname;
449 objname = 0;
450 if ( pendTimer ) // might be pending timers
451 qKillTimer( this );
452 QApplication::removePostedEvents( this );
453 if ( isTree ) {
454 remove_tree( this ); // remove from global root list
455 isTree = FALSE;
456 }
457 if ( parentObj ) // remove it from parent object
458 parentObj->removeChild( this );
459 register QObject *obj;
460 if ( senderObjects ) { // disconnect from senders
461 QSenderObjectList *tmp = senderObjects;
462 senderObjects = 0;
463 obj = tmp->first();
464 while ( obj ) { // for all senders...
465 obj->disconnect( this );
466 obj = tmp->next();
467 }
468 if ( tmp->deref() )
469 delete tmp;
470 }
471 if ( connections ) { // disconnect receivers
472 for ( int i = 0; i < (int) connections->size(); i++ ) {
473 QConnectionList* clist = (*connections)[i]; // for each signal...
474 if ( !clist )
475 continue;
476 register QConnection *c;
477 QConnectionListIt cit(*clist);
478 while( (c=cit.current()) ) { // for each connected slot...
479 ++cit;
480 if ( (obj=c->object()) )
481 removeObjFromList( obj->senderObjects, this );
482 }
483 }
484 delete connections;
485 connections = 0;
486 }
487 if ( eventFilters ) {
488 delete eventFilters;
489 eventFilters = 0;
490 }
491 if ( childObjects ) { // delete children objects
492 QObjectListIt it(*childObjects);
493 while ( (obj=it.current()) ) {
494 ++it;
495 obj->parentObj = 0;
496 childObjects->removeRef( obj );
497 delete obj;
498 }
499 delete childObjects;
500 }
501
502 delete d;
503}
504
505
506/*!
507 \fn QMetaObject *QObject::metaObject() const
508
509 Returns a pointer to the meta object of this object.
510
511 A meta object contains information about a class that inherits
512 QObject, e.g. class name, superclass name, properties, signals and
513 slots. Every class that contains the Q_OBJECT macro will also have
514 a meta object.
515
516 The meta object information is required by the signal/slot
517 connection mechanism and the property system. The functions isA()
518 and inherits() also make use of the meta object.
519*/
520
521/*!
522 \fn const char *QObject::className() const
523
524 Returns the class name of this object.
525
526 This function is generated by the \link metaobjects.html Meta
527 Object Compiler. \endlink
528
529 \warning This function will return the wrong name if the class
530 definition lacks the Q_OBJECT macro.
531
532 \sa name(), inherits(), isA(), isWidgetType()
533*/
534
535/*!
536 Returns TRUE if this object is an instance of the class \a clname;
537 otherwise returns FALSE.
538
539 Example:
540 \code
541 QTimer *t = new QTimer; // QTimer inherits QObject
542 t->isA( "QTimer" ); // returns TRUE
543 t->isA( "QObject" ); // returns FALSE
544 \endcode
545
546 \sa inherits() metaObject()
547*/
548
549bool QObject::isA( const char *clname ) const
550{
551 return qstrcmp( clname, className() ) == 0;
552}
553
554/*!
555 Returns TRUE if this object is an instance of a class that
556 inherits \a clname, and \a clname inherits QObject; otherwise
557 returns FALSE.
558
559 A class is considered to inherit itself.
560
561 Example:
562 \code
563 QTimer *t = new QTimer; // QTimer inherits QObject
564 t->inherits( "QTimer" ); // returns TRUE
565 t->inherits( "QObject" ); // returns TRUE
566 t->inherits( "QButton" ); // returns FALSE
567
568 // QScrollBar inherits QWidget and QRangeControl
569 QScrollBar *s = new QScrollBar( 0 );
570 s->inherits( "QWidget" ); // returns TRUE
571 s->inherits( "QRangeControl" ); // returns FALSE
572 \endcode
573
574 (\l QRangeControl is not a QObject.)
575
576 \sa isA(), metaObject()
577*/
578
579bool QObject::inherits( const char *clname ) const
580{
581 return metaObject()->inherits( clname );
582}
583
584/*!
585 \internal
586
587 Returns TRUE if \a object inherits \a superClass within
588 the meta object inheritance chain; otherwise returns FALSE.
589
590 \sa inherits()
591*/
592void *qt_inheritedBy( QMetaObject *superClass, const QObject *object )
593{
594 if (!object)
595 return 0;
596 register QMetaObject *mo = object->metaObject();
597 while (mo) {
598 if (mo == superClass)
599 return (void*)object;
600 mo = mo->superClass();
601 }
602 return 0;
603}
604
605/*!
606 \property QObject::name
607
608 \brief the name of this object
609
610 You can find an object by name (and type) using child(). You can
611 find a set of objects with queryList().
612
613 The object name is set by the constructor or by the setName()
614 function. The object name is not very useful in the current
615 version of Qt, but will become increasingly important in the
616 future.
617
618 If the object does not have a name, the name() function returns
619 "unnamed", so printf() (used in qDebug()) will not be asked to
620 output a null pointer. If you want a null pointer to be returned
621 for unnamed objects, you can call name( 0 ).
622
623 \code
624 qDebug( "MyClass::setPrecision(): (%s) invalid precision %f",
625 name(), newPrecision );
626 \endcode
627
628 \sa className(), child(), queryList()
629*/
630
631const char * QObject::name() const
632{
633 // If you change the name here, the builder will be broken
634 return objname ? objname : "unnamed";
635}
636
637/*!
638 Sets the object's name to \a name.
639*/
640void QObject::setName( const char *name )
641{
642 if ( objname )
643 delete [] (char*) objname;
644 objname = name ? qstrdup(name) : 0;
645}
646
647/*!
648 \overload
649
650 Returns the name of this object, or \a defaultName if the object
651 does not have a name.
652*/
653
654const char * QObject::name( const char * defaultName ) const
655{
656 return objname ? objname : defaultName;
657}
658
659
660/*!
661 Searches the children and optionally grandchildren of this object,
662 and returns a child that is called \a objName that inherits \a
663 inheritsClass. If \a inheritsClass is 0 (the default), any class
664 matches.
665
666 If \a recursiveSearch is TRUE (the default), child() performs a
667 depth-first search of the object's children.
668
669 If there is no such object, this function returns 0. If there are
670 more than one, the first one found is retured; if you need all of
671 them, use queryList().
672*/
673QObject* QObject::child( const char *objName, const char *inheritsClass,
674 bool recursiveSearch )
675{
676 const QObjectList *list = children();
677 if ( !list )
678 return 0;
679
680 bool onlyWidgets = ( inheritsClass && qstrcmp( inheritsClass, "QWidget" ) == 0 );
681 QObjectListIt it( *list );
682 QObject *obj;
683 while ( ( obj = it.current() ) ) {
684 ++it;
685 if ( onlyWidgets ) {
686 if ( obj->isWidgetType() && ( !objName || qstrcmp( objName, obj->name() ) == 0 ) )
687 break;
688 } else if ( ( !inheritsClass || obj->inherits(inheritsClass) ) && ( !objName || qstrcmp( objName, obj->name() ) == 0 ) )
689 break;
690 if ( recursiveSearch && (obj = obj->child( objName, inheritsClass, recursiveSearch ) ) )
691 break;
692 }
693 return obj;
694}
695
696/*!
697 \fn bool QObject::isWidgetType() const
698
699 Returns TRUE if the object is a widget; otherwise returns FALSE.
700
701 Calling this function is equivalent to calling
702 inherits("QWidget"), except that it is much faster.
703*/
704
705/*!
706 \fn bool QObject::highPriority() const
707
708 Returns TRUE if the object is a high-priority object, or FALSE if
709 it is a standard-priority object.
710
711 High-priority objects are placed first in QObject's list of
712 children on the assumption that they will be referenced very
713 often.
714*/
715
716
717/*!
718 This virtual function receives events to an object and should
719 return TRUE if the event \a e was recognized and processed.
720
721 The event() function can be reimplemented to customize the
722 behavior of an object.
723
724 \sa installEventFilter(), timerEvent(), QApplication::sendEvent(),
725 QApplication::postEvent(), QWidget::event()
726*/
727
728bool QObject::event( QEvent *e )
729{
730#if defined(QT_CHECK_NULL)
731 if ( e == 0 )
732 qWarning( "QObject::event: Null events are not permitted" );
733#endif
734 if ( eventFilters ) { // try filters
735 if ( activate_filters(e) ) // stopped by a filter
736 return TRUE;
737 }
738
739 switch ( e->type() ) {
740 case QEvent::Timer:
741 timerEvent( (QTimerEvent*)e );
742 return TRUE;
743
744 case QEvent::ChildInserted:
745 case QEvent::ChildRemoved:
746 childEvent( (QChildEvent*)e );
747 return TRUE;
748
749 case QEvent::DeferredDelete:
750 delete this;
751 return TRUE;
752
753 default:
754 if ( e->type() >= QEvent::User ) {
755 customEvent( (QCustomEvent*) e );
756 return TRUE;
757 }
758 break;
759 }
760 return FALSE;
761}
762
763/*!
764 This event handler can be reimplemented in a subclass to receive
765 timer events for the object.
766
767 QTimer provides a higher-level interface to the timer
768 functionality, and also more general information about timers.
769
770 \sa startTimer(), killTimer(), killTimers(), event()
771*/
772
773void QObject::timerEvent( QTimerEvent * )
774{
775}
776
777
778/*!
779 This event handler can be reimplemented in a subclass to receive
780 child events.
781
782 Child events are sent to objects when children are inserted or
783 removed.
784
785 Note that events with QEvent::type() \c QEvent::ChildInserted are
786 posted (with \l{QApplication::postEvent()}) to make sure that the
787 child's construction is completed before this function is called.
788
789 If a child is removed immediately after it is inserted, the \c
790 ChildInserted event may be suppressed, but the \c ChildRemoved
791 event will always be sent. In such cases it is possible that there
792 will be a \c ChildRemoved event without a corresponding \c
793 ChildInserted event.
794
795 If you change state based on \c ChildInserted events, call
796 QWidget::constPolish(), or do
797 \code
798 QApplication::sendPostedEvents( this, QEvent::ChildInserted );
799 \endcode
800 in functions that depend on the state. One notable example is
801 QWidget::sizeHint().
802
803 \sa event(), QChildEvent
804*/
805
806void QObject::childEvent( QChildEvent * )
807{
808}
809
810/*!
811 This event handler can be reimplemented in a subclass to receive
812 custom events. Custom events are user-defined events with a type
813 value at least as large as the "User" item of the \l QEvent::Type
814 enum, and is typically a QCustomEvent or QCustomEvent subclass.
815
816 \sa event(), QCustomEvent
817*/
818void QObject::customEvent( QCustomEvent * )
819{
820}
821
822
823
824/*!
825 Filters events if this object has been installed as an event
826 filter for the \a watched object.
827
828 In your reimplementation of this function, if you want to filter
829 the event \a e, out, i.e. stop it being handled further, return
830 TRUE; otherwise return FALSE.
831
832 Example:
833 \code
834 class MyMainWindow : public QMainWindow
835 {
836 public:
837 MyMainWindow( QWidget *parent = 0, const char *name = 0 );
838
839 protected:
840 bool eventFilter( QObject *obj, QEvent *ev );
841
842 private:
843 QTextEdit *textEdit;
844 };
845
846 MyMainWindow::MyMainWindow( QWidget *parent, const char *name )
847 : QMainWindow( parent, name )
848 {
849 textEdit = new QTextEdit( this );
850 setCentralWidget( textEdit );
851 textEdit->installEventFilter( this );
852 }
853
854 bool MyMainWindow::eventFilter( QObject *obj, QEvent *ev )
855 {
856 if ( obj == textEdit ) {
857 if ( e->type() == QEvent::KeyPress ) {
858 qDebug( "Ate key press %d", k->key() );
859 return TRUE;
860 } else {
861 return FALSE;
862 }
863 } else {
864 // pass the event on to the parent class
865 return QMainWindow::eventFilter( obj, ev );
866 }
867 }
868 \endcode
869
870 Notice in the example above that unhandled events are passed to
871 the base class's eventFilter() function, since the base class
872 might have reimplemented eventFilter() for its own internal
873 purposes.
874
875 \warning If you delete the receiver object in this function, be
876 sure to return TRUE. Otherwise, Qt will forward the event to the
877 deleted object and the program might crash.
878
879 \sa installEventFilter()
880*/
881
882bool QObject::eventFilter( QObject * /* watched */, QEvent * /* e */ )
883{
884 return FALSE;
885}
886
887
888/*!
889 \internal
890 Activates all event filters for this object.
891 This function is normally called from QObject::event() or QWidget::event().
892*/
893
894bool QObject::activate_filters( QEvent *e )
895{
896 if ( !eventFilters ) // no event filter
897 return FALSE;
898 QObjectListIt it( *eventFilters );
899 register QObject *obj = it.current();
900 while ( obj ) { // send to all filters
901 ++it; // until one returns TRUE
902 if ( obj->eventFilter(this,e) ) {
903 return TRUE;
904 }
905 obj = it.current();
906 }
907 return FALSE; // don't do anything with it
908}
909
910
911/*!
912 \fn bool QObject::signalsBlocked() const
913
914 Returns TRUE if signals are blocked; otherwise returns FALSE.
915
916 Signals are not blocked by default.
917
918 \sa blockSignals()
919*/
920
921/*!
922 Blocks signals if \a block is TRUE, or unblocks signals if \a
923 block is FALSE.
924
925 Emitted signals disappear into hyperspace if signals are blocked.
926 Note that the destroyed() signals will be emitted even if the signals
927 for this object have been blocked.
928*/
929
930void QObject::blockSignals( bool block )
931{
932 blockSig = block;
933}
934
935
936//
937// The timer flag hasTimer is set when startTimer is called.
938// It is not reset when killing the timer because more than
939// one timer might be active.
940//
941
942/*!
943 Starts a timer and returns a timer identifier, or returns zero if
944 it could not start a timer.
945
946 A timer event will occur every \a interval milliseconds until
947 killTimer() or killTimers() is called. If \a interval is 0, then
948 the timer event occurs once every time there are no more window
949 system events to process.
950
951 The virtual timerEvent() function is called with the QTimerEvent
952 event parameter class when a timer event occurs. Reimplement this
953 function to get timer events.
954
955 If multiple timers are running, the QTimerEvent::timerId() can be
956 used to find out which timer was activated.
957
958 Example:
959 \code
960 class MyObject : public QObject
961 {
962 Q_OBJECT
963 public:
964 MyObject( QObject *parent = 0, const char *name = 0 );
965
966 protected:
967 void timerEvent( QTimerEvent * );
968 };
969
970 MyObject::MyObject( QObject *parent, const char *name )
971 : QObject( parent, name )
972 {
973 startTimer( 50 ); // 50-millisecond timer
974 startTimer( 1000 ); // 1-second timer
975 startTimer( 60000 ); // 1-minute timer
976 }
977
978 void MyObject::timerEvent( QTimerEvent *e )
979 {
980 qDebug( "timer event, id %d", e->timerId() );
981 }
982 \endcode
983
984 There is practically no upper limit for the interval value (more
985 than one year is possible). Note that QTimer's accuracy depends on
986 the underlying operating system and hardware. Most platforms
987 support an accuracy of 20ms; some provide more. If Qt is unable to
988 deliver the requested number of timer clicks, it will silently
989 discard some.
990
991 The QTimer class provides a high-level programming interface with
992 one-shot timers and timer signals instead of events.
993
994 \sa timerEvent(), killTimer(), killTimers()
995*/
996
997int QObject::startTimer( int interval )
998{
999 pendTimer = TRUE; // set timer flag
1000 return qStartTimer( interval, (QObject *)this );
1001}
1002
1003/*!
1004 Kills the timer with timer identifier, \a id.
1005
1006 The timer identifier is returned by startTimer() when a timer
1007 event is started.
1008
1009 \sa timerEvent(), startTimer(), killTimers()
1010*/
1011
1012void QObject::killTimer( int id )
1013{
1014 qKillTimer( id );
1015}
1016
1017/*!
1018 Kills all timers that this object has started.
1019
1020 \warning Using this function can cause hard-to-find bugs: it kills
1021 timers started by sub- and superclasses as well as those started
1022 by you, which is often not what you want. We recommend using a
1023 QTimer or perhaps killTimer().
1024
1025 \sa timerEvent(), startTimer(), killTimer()
1026*/
1027
1028void QObject::killTimers()
1029{
1030 qKillTimer( this );
1031}
1032
1033static void objSearch( QObjectList *result,
1034 QObjectList *list,
1035 const char *inheritsClass,
1036 bool onlyWidgets,
1037 const char *objName,
1038 QRegExp *rx,
1039 bool recurse )
1040{
1041 if ( !list || list->isEmpty() ) // nothing to search
1042 return;
1043 QObject *obj = list->first();
1044 while ( obj ) {
1045 bool ok = TRUE;
1046 if ( onlyWidgets )
1047 ok = obj->isWidgetType();
1048 else if ( inheritsClass && !obj->inherits(inheritsClass) )
1049 ok = FALSE;
1050 if ( ok ) {
1051 if ( objName )
1052 ok = ( qstrcmp(objName,obj->name()) == 0 );
1053#ifndef QT_NO_REGEXP
1054 else if ( rx )
1055 ok = ( rx->search(QString::fromLatin1(obj->name())) != -1 );
1056#endif
1057 }
1058 if ( ok ) // match!
1059 result->append( obj );
1060 if ( recurse && obj->children() )
1061 objSearch( result, (QObjectList *)obj->children(), inheritsClass,
1062 onlyWidgets, objName, rx, recurse );
1063 obj = list->next();
1064 }
1065}
1066
1067/*!
1068 \fn QObject *QObject::parent() const
1069
1070 Returns a pointer to the parent object.
1071
1072 \sa children()
1073*/
1074
1075/*!
1076 \fn const QObjectList *QObject::children() const
1077
1078 Returns a list of child objects, or 0 if this object has no
1079 children.
1080
1081 The QObjectList class is defined in the \c qobjectlist.h header
1082 file.
1083
1084 The first child added is the \link QPtrList::first() first\endlink
1085 object in the list and the last child added is the \link
1086 QPtrList::last() last\endlink object in the list, i.e. new
1087 children are appended at the end.
1088
1089 Note that the list order changes when QWidget children are \link
1090 QWidget::raise() raised\endlink or \link QWidget::lower()
1091 lowered.\endlink A widget that is raised becomes the last object
1092 in the list, and a widget that is lowered becomes the first object
1093 in the list.
1094
1095 \sa child(), queryList(), parent(), insertChild(), removeChild()
1096*/
1097
1098
1099/*!
1100 Returns a pointer to the list of all object trees (their root
1101 objects), or 0 if there are no objects.
1102
1103 The QObjectList class is defined in the \c qobjectlist.h header
1104 file.
1105
1106 The most recent root object created is the \link QPtrList::first()
1107 first\endlink object in the list and the first root object added
1108 is the \link QPtrList::last() last\endlink object in the list.
1109
1110 \sa children(), parent(), insertChild(), removeChild()
1111*/
1112const QObjectList *QObject::objectTrees()
1113{
1114 return object_trees;
1115}
1116
1117
1118/*!
1119 Searches the children and optionally grandchildren of this object,
1120 and returns a list of those objects that are named or that match
1121 \a objName and inherit \a inheritsClass. If \a inheritsClass is 0
1122 (the default), all classes match. If \a objName is 0 (the
1123 default), all object names match.
1124
1125 If \a regexpMatch is TRUE (the default), \a objName is a regular
1126 expression that the objects's names must match. The syntax is that
1127 of a QRegExp. If \a regexpMatch is FALSE, \a objName is a string
1128 and object names must match it exactly.
1129
1130 Note that \a inheritsClass uses single inheritance from QObject,
1131 the way inherits() does. According to inherits(), QMenuBar
1132 inherits QWidget but not QMenuData. This does not quite match
1133 reality, but is the best that can be done on the wide variety of
1134 compilers Qt supports.
1135
1136 Finally, if \a recursiveSearch is TRUE (the default), queryList()
1137 searches \e{n}th-generation as well as first-generation children.
1138
1139 If all this seems a bit complex for your needs, the simpler
1140 child() function may be what you want.
1141
1142 This somewhat contrived example disables all the buttons in this
1143 window:
1144 \code
1145 QObjectList *l = topLevelWidget()->queryList( "QButton" );
1146 QObjectListIt it( *l ); // iterate over the buttons
1147 QObject *obj;
1148
1149 while ( (obj = it.current()) != 0 ) {
1150 // for each found object...
1151 ++it;
1152 ((QButton*)obj)->setEnabled( FALSE );
1153 }
1154 delete l; // delete the list, not the objects
1155 \endcode
1156
1157 The QObjectList class is defined in the \c qobjectlist.h header
1158 file.
1159
1160 \warning Delete the list as soon you have finished using it. The
1161 list contains pointers that may become invalid at almost any time
1162 without notice (as soon as the user closes a window you may have
1163 dangling pointers, for example).
1164
1165 \sa child() children(), parent(), inherits(), name(), QRegExp
1166*/
1167
1168QObjectList *QObject::queryList( const char *inheritsClass,
1169 const char *objName,
1170 bool regexpMatch,
1171 bool recursiveSearch ) const
1172{
1173 QObjectList *list = new QObjectList;
1174 Q_CHECK_PTR( list );
1175 bool onlyWidgets = ( inheritsClass && qstrcmp(inheritsClass, "QWidget") == 0 );
1176#ifndef QT_NO_REGEXP
1177 if ( regexpMatch && objName ) { // regexp matching
1178 QRegExp rx(QString::fromLatin1(objName));
1179 objSearch( list, (QObjectList *)children(), inheritsClass, onlyWidgets,
1180 0, &rx, recursiveSearch );
1181 } else
1182#endif
1183 {
1184 objSearch( list, (QObjectList *)children(), inheritsClass, onlyWidgets,
1185 objName, 0, recursiveSearch );
1186 }
1187 return list;
1188}
1189
1190/*! \internal
1191
1192 Returns a list of objects/slot pairs that are connected to the
1193 \a signal, or 0 if nothing is connected to it.
1194*/
1195
1196QConnectionList *QObject::receivers( const char* signal ) const
1197{
1198 if ( connections && signal ) {
1199 if ( *signal == '2' ) { // tag == 2, i.e. signal
1200 QCString s = qt_rmWS( signal+1 );
1201 return receivers( metaObject()->findSignal( (const char*)s, TRUE ) );
1202 } else {
1203 return receivers( metaObject()->findSignal(signal, TRUE ) );
1204 }
1205 }
1206 return 0;
1207}
1208
1209/*! \internal
1210
1211 Returns a list of objects/slot pairs that are connected to the
1212 signal, or 0 if nothing is connected to it.
1213*/
1214
1215QConnectionList *QObject::receivers( int signal ) const
1216{
1217#ifndef QT_NO_PRELIMINARY_SIGNAL_SPY
1218 if ( qt_preliminary_signal_spy && signal >= 0 ) {
1219 if ( !connections ) {
1220 QObject* that = (QObject*) this;
1221 that->connections = new QSignalVec( signal+1 );
1222 that->connections->setAutoDelete( TRUE );
1223 }
1224 if ( !connections->at( signal ) ) {
1225 QConnectionList* clist = new QConnectionList;
1226 clist->setAutoDelete( TRUE );
1227 connections->insert( signal, clist );
1228 return clist;
1229 }
1230 }
1231#endif
1232 if ( connections && signal >= 0 )
1233 return connections->at( signal );
1234 return 0;
1235}
1236
1237
1238/*!
1239 Inserts an object \a obj into the list of child objects.
1240
1241 \warning This function cannot be used to make one widget the child
1242 widget of another widget. Child widgets can only be created by
1243 setting the parent widget in the constructor or by calling
1244 QWidget::reparent().
1245
1246 \sa removeChild(), QWidget::reparent()
1247*/
1248
1249void QObject::insertChild( QObject *obj )
1250{
1251 if ( obj->isTree ) {
1252 remove_tree( obj );
1253 obj->isTree = FALSE;
1254 }
1255 if ( obj->parentObj && obj->parentObj != this ) {
1256#if defined(QT_CHECK_STATE)
1257 if ( obj->parentObj != this && obj->isWidgetType() )
1258 qWarning( "QObject::insertChild: Cannot reparent a widget, "
1259 "use QWidget::reparent() instead" );
1260#endif
1261 obj->parentObj->removeChild( obj );
1262 }
1263
1264 if ( !childObjects ) {
1265 childObjects = new QObjectList;
1266 Q_CHECK_PTR( childObjects );
1267 } else if ( obj->parentObj == this ) {
1268#if defined(QT_CHECK_STATE)
1269 qWarning( "QObject::insertChild: Object %s::%s already in list",
1270 obj->className(), obj->name( "unnamed" ) );
1271#endif
1272 return;
1273 }
1274 obj->parentObj = this;
1275 childObjects->append( obj );
1276
1277 QChildEvent *e = new QChildEvent( QEvent::ChildInserted, obj );
1278 QApplication::postEvent( this, e );
1279}
1280
1281/*!
1282 Removes the child object \a obj from the list of children.
1283
1284 \warning This function will not remove a child widget from the
1285 screen. It will only remove it from the parent widget's list of
1286 children.
1287
1288 \sa insertChild(), QWidget::reparent()
1289*/
1290
1291void QObject::removeChild( QObject *obj )
1292{
1293 if ( childObjects && childObjects->removeRef(obj) ) {
1294 obj->parentObj = 0;
1295 if ( !obj->wasDeleted ) {
1296 insert_tree( obj ); // it's a root object now
1297 obj->isTree = TRUE;
1298 }
1299 if ( childObjects->isEmpty() ) {
1300 delete childObjects; // last child removed
1301 childObjects = 0; // reset children list
1302 }
1303
1304 // remove events must be sent, not posted!!!
1305 QChildEvent ce( QEvent::ChildRemoved, obj );
1306 QApplication::sendEvent( this, &ce );
1307 }
1308}
1309
1310
1311/*!
1312 \fn void QObject::installEventFilter( const QObject *filterObj )
1313
1314 Installs an event filter \a filterObj on this object. For example:
1315 \code
1316 monitoredObj->installEventFilter( filterObj );
1317 \endcode
1318
1319 An event filter is an object that receives all events that are
1320 sent to this object. The filter can either stop the event or
1321 forward it to this object. The event filter \a filterObj receives
1322 events via its eventFilter() function. The eventFilter() function
1323 must return TRUE if the event should be filtered, (i.e. stopped);
1324 otherwise it must return FALSE.
1325
1326 If multiple event filters are installed on a single object, the
1327 filter that was installed last is activated first.
1328
1329 Here's a \c KeyPressEater class that eats the key presses of its
1330 monitored objects:
1331 \code
1332 class KeyPressEater : public QObject
1333 {
1334 ...
1335 protected:
1336 bool eventFilter( QObject *o, QEvent *e );
1337 };
1338
1339 bool KeyPressEater::eventFilter( QObject *o, QEvent *e )
1340 {
1341 if ( e->type() == QEvent::KeyPress ) {
1342 // special processing for key press
1343 QKeyEvent *k = (QKeyEvent *)e;
1344 qDebug( "Ate key press %d", k->key() );
1345 return TRUE; // eat event
1346 } else {
1347 // standard event processing
1348 return FALSE;
1349 }
1350 }
1351 \endcode
1352
1353 And here's how to install it on two widgets:
1354 \code
1355 KeyPressEater *keyPressEater = new KeyPressEater( this );
1356 QPushButton *pushButton = new QPushButton( this );
1357 QListView *listView = new QListView( this );
1358
1359 pushButton->installEventFilter( keyPressEater );
1360 listView->installEventFilter( keyPressEater );
1361 \endcode
1362
1363 The QAccel class, for example, uses this technique to intercept
1364 accelerator key presses.
1365
1366 \warning If you delete the receiver object in your eventFilter()
1367 function, be sure to return TRUE. If you return FALSE, Qt sends
1368 the event to the deleted object and the program will crash.
1369
1370 \sa removeEventFilter(), eventFilter(), event()
1371*/
1372
1373void QObject::installEventFilter( const QObject *obj )
1374{
1375 if ( !obj )
1376 return;
1377 if ( eventFilters ) {
1378 int c = eventFilters->findRef( obj );
1379 if ( c >= 0 )
1380 eventFilters->take( c );
1381 disconnect( obj, SIGNAL(destroyed(QObject*)),
1382 this, SLOT(cleanupEventFilter(QObject*)) );
1383 } else {
1384 eventFilters = new QObjectList;
1385 Q_CHECK_PTR( eventFilters );
1386 }
1387 eventFilters->insert( 0, obj );
1388 connect( obj, SIGNAL(destroyed(QObject*)), this, SLOT(cleanupEventFilter(QObject*)) );
1389}
1390
1391/*!
1392 Removes an event filter object \a obj from this object. The
1393 request is ignored if such an event filter has not been installed.
1394
1395 All event filters for this object are automatically removed when
1396 this object is destroyed.
1397
1398 It is always safe to remove an event filter, even during event
1399 filter activation (i.e. from the eventFilter() function).
1400
1401 \sa installEventFilter(), eventFilter(), event()
1402*/
1403
1404void QObject::removeEventFilter( const QObject *obj )
1405{
1406 if ( eventFilters && eventFilters->removeRef(obj) ) {
1407 if ( eventFilters->isEmpty() ) { // last event filter removed
1408 delete eventFilters;
1409 eventFilters = 0; // reset event filter list
1410 }
1411 disconnect( obj, SIGNAL(destroyed(QObject*)),
1412 this, SLOT(cleanupEventFilter(QObject*)) );
1413 }
1414}
1415
1416
1417/*****************************************************************************
1418 Signal connection management
1419 *****************************************************************************/
1420
1421#if defined(QT_CHECK_RANGE)
1422
1423static bool check_signal_macro( const QObject *sender, const char *signal,
1424 const char *func, const char *op )
1425{
1426 int sigcode = (int)(*signal) - '0';
1427 if ( sigcode != QSIGNAL_CODE ) {
1428 if ( sigcode == QSLOT_CODE )
1429 qWarning( "QObject::%s: Attempt to %s non-signal %s::%s",
1430 func, op, sender->className(), signal+1 );
1431 else
1432 qWarning( "QObject::%s: Use the SIGNAL macro to %s %s::%s",
1433 func, op, sender->className(), signal );
1434 return FALSE;
1435 }
1436 return TRUE;
1437}
1438
1439static bool check_member_code( int code, const QObject *object,
1440 const char *member, const char *func )
1441{
1442 if ( code != QSLOT_CODE && code != QSIGNAL_CODE ) {
1443 qWarning( "QObject::%s: Use the SLOT or SIGNAL macro to "
1444 "%s %s::%s", func, func, object->className(), member );
1445 return FALSE;
1446 }
1447 return TRUE;
1448}
1449
1450static void err_member_notfound( int code, const QObject *object,
1451 const char *member, const char *func )
1452{
1453 const char *type = 0;
1454 switch ( code ) {
1455 case QSLOT_CODE: type = "slot"; break;
1456 case QSIGNAL_CODE: type = "signal"; break;
1457 }
1458 if ( strchr(member,')') == 0 ) // common typing mistake
1459 qWarning( "QObject::%s: Parentheses expected, %s %s::%s",
1460 func, type, object->className(), member );
1461 else
1462 qWarning( "QObject::%s: No such %s %s::%s",
1463 func, type, object->className(), member );
1464}
1465
1466
1467static void err_info_about_objects( const char * func,
1468 const QObject * sender,
1469 const QObject * receiver )
1470{
1471 const char * a = sender->name(), * b = receiver->name();
1472 if ( a )
1473 qWarning( "QObject::%s: (sender name: '%s')", func, a );
1474 if ( b )
1475 qWarning( "QObject::%s: (receiver name: '%s')", func, b );
1476}
1477
1478static void err_info_about_candidates( int code,
1479 const QMetaObject* mo,
1480 const char* member,
1481 const char *func )
1482{
1483 if ( strstr(member,"const char*") ) {
1484 // porting help
1485 QCString newname = member;
1486 int p;
1487 while ( (p=newname.find("const char*")) >= 0 ) {
1488 newname.replace(p, 11, "const QString&");
1489 }
1490 const QMetaData *rm = 0;
1491 switch ( code ) {
1492 case QSLOT_CODE:
1493 rm = mo->slot( mo->findSlot( newname, TRUE ), TRUE );
1494 break;
1495 case QSIGNAL_CODE:
1496 rm = mo->signal( mo->findSignal( newname, TRUE ), TRUE );
1497 break;
1498 }
1499 if ( rm ) {
1500 qWarning("QObject::%s: Candidate: %s", func, newname.data());
1501 }
1502 }
1503}
1504
1505
1506#endif // QT_CHECK_RANGE
1507
1508
1509/*!
1510 Returns a pointer to the object that sent the signal, if called in
1511 a slot activated by a signal; otherwise it returns 0. The pointer
1512 is valid only during the execution of the slot that calls this
1513 function.
1514
1515 The pointer returned by this function becomes invalid if the
1516 sender is destroyed, or if the slot is disconnected from the
1517 sender's signal.
1518
1519 \warning This function violates the object-oriented principle of
1520 modularity. However, getting access to the sender might be useful
1521 when many signals are connected to a single slot. The sender is
1522 undefined if the slot is called as a normal C++ function.
1523*/
1524
1525const QObject *QObject::sender()
1526{
1527#ifndef QT_NO_PRELIMINARY_SIGNAL_SPY
1528 if ( this == qt_preliminary_signal_spy ) {
1529# ifdef QT_THREAD_SUPPORT
1530 // protect access to qt_spy_signal_sender
1531 void * const address = &qt_spy_signal_sender;
1532 QMutexLocker locker( qt_global_mutexpool ?
1533 qt_global_mutexpool->get( address ) : 0 );
1534# endif // QT_THREAD_SUPPORT
1535 return qt_spy_signal_sender;
1536 }
1537#endif
1538 if ( senderObjects &&
1539 senderObjects->currentSender &&
1540 /*
1541 * currentSender may be a dangling pointer in case the object
1542 * it was pointing to was destructed from inside a slot. Thus
1543 * verify it still is contained inside the senderObjects list
1544 * which gets cleaned on both destruction and disconnect.
1545 */
1546
1547 senderObjects->findRef( senderObjects->currentSender ) != -1 )
1548 return senderObjects->currentSender;
1549 return 0;
1550}
1551
1552
1553/*!
1554 \fn void QObject::connectNotify( const char *signal )
1555
1556 This virtual function is called when something has been connected
1557 to \a signal in this object.
1558
1559 \warning This function violates the object-oriented principle of
1560 modularity. However, it might be useful when you need to perform
1561 expensive initialization only if something is connected to a
1562 signal.
1563
1564 \sa connect(), disconnectNotify()
1565*/
1566
1567void QObject::connectNotify( const char * )
1568{
1569}
1570
1571/*!
1572 \fn void QObject::disconnectNotify( const char *signal )
1573
1574 This virtual function is called when something has been
1575 disconnected from \a signal in this object.
1576
1577 \warning This function violates the object-oriented principle of
1578 modularity. However, it might be useful for optimizing access to
1579 expensive resources.
1580
1581 \sa disconnect(), connectNotify()
1582*/
1583
1584void QObject::disconnectNotify( const char * )
1585{
1586}
1587
1588
1589/*!
1590 \fn bool QObject::checkConnectArgs( const char *signal, const QObject *receiver, const char *member )
1591
1592 Returns TRUE if the \a signal and the \a member arguments are
1593 compatible; otherwise returns FALSE. (The \a receiver argument is
1594 currently ignored.)
1595
1596 \warning We recommend that you use the default implementation and
1597 do not reimplement this function.
1598
1599 \omit
1600 TRUE: "signal(<anything>)", "member()"
1601 TRUE: "signal(a,b,c)", "member(a,b,c)"
1602 TRUE: "signal(a,b,c)", "member(a,b)", "member(a)" etc.
1603 FALSE: "signal(const a)", "member(a)"
1604 FALSE: "signal(a)", "member(const a)"
1605 FALSE: "signal(a)", "member(b)"
1606 FALSE: "signal(a)", "member(a,b)"
1607 \endomit
1608*/
1609
1610bool QObject::checkConnectArgs( const char *signal,
1611 const QObject *,
1612 const char *member )
1613{
1614 const char *s1 = signal;
1615 const char *s2 = member;
1616 while ( *s1++ != '(' ) { } // scan to first '('
1617 while ( *s2++ != '(' ) { }
1618 if ( *s2 == ')' || qstrcmp(s1,s2) == 0 ) // member has no args or
1619 return TRUE; // exact match
1620 int s1len = qstrlen(s1);
1621 int s2len = qstrlen(s2);
1622 if ( s2len < s1len && qstrncmp(s1,s2,s2len-1)==0 && s1[s2len-1]==',' )
1623 return TRUE; // member has less args
1624 return FALSE;
1625}
1626
1627/*!
1628 Normlizes the signal or slot definition \a signalSlot by removing
1629 unnecessary whitespace.
1630*/
1631
1632QCString QObject::normalizeSignalSlot( const char *signalSlot )
1633{
1634 if ( !signalSlot )
1635 return QCString();
1636 return qt_rmWS( signalSlot );
1637}
1638
1639
1640
1641/*!
1642 \overload bool QObject::connect( const QObject *sender, const char *signal, const char *member ) const
1643
1644 Connects \a signal from the \a sender object to this object's \a
1645 member.
1646
1647 Equivalent to: \c{QObject::connect(sender, signal, this, member)}.
1648
1649 \sa disconnect()
1650*/
1651
1652/*!
1653 Connects \a signal from the \a sender object to \a member in object
1654 \a receiver, and returns TRUE if the connection succeeds; otherwise
1655 returns FALSE.
1656
1657 You must use the SIGNAL() and SLOT() macros when specifying the \a signal
1658 and the \a member, for example:
1659 \code
1660 QLabel *label = new QLabel;
1661 QScrollBar *scroll = new QScrollBar;
1662 QObject::connect( scroll, SIGNAL(valueChanged(int)),
1663 label, SLOT(setNum(int)) );
1664 \endcode
1665
1666 This example ensures that the label always displays the current
1667 scroll bar value. Note that the signal and slots parameters must not
1668 contain any variable names, only the type. E.g. the following would
1669 not work and return FALSE:
1670 QObject::connect( scroll, SIGNAL(valueChanged(int v)),
1671 label, SLOT(setNum(int v)) );
1672
1673 A signal can also be connected to another signal:
1674
1675 \code
1676 class MyWidget : public QWidget
1677 {
1678 Q_OBJECT
1679 public:
1680 MyWidget();
1681
1682 signals:
1683 void myUsefulSignal();
1684
1685 private:
1686 QPushButton *aButton;
1687 };
1688
1689 MyWidget::MyWidget()
1690 {
1691 aButton = new QPushButton( this );
1692 connect( aButton, SIGNAL(clicked()), SIGNAL(myUsefulSignal()) );
1693 }
1694 \endcode
1695
1696 In this example, the MyWidget constructor relays a signal from a
1697 private member variable, and makes it available under a name that
1698 relates to MyWidget.
1699
1700 A signal can be connected to many slots and signals. Many signals
1701 can be connected to one slot.
1702
1703 If a signal is connected to several slots, the slots are activated
1704 in an arbitrary order when the signal is emitted.
1705
1706 The function returns TRUE if it successfully connects the signal
1707 to the slot. It will return FALSE if it cannot create the
1708 connection, for example, if QObject is unable to verify the
1709 existence of either \a signal or \a member, or if their signatures
1710 aren't compatible.
1711
1712 A signal is emitted for \e{every} connection you make, so if you
1713 duplicate a connection, two signals will be emitted. You can
1714 always break a connection using \c{disconnect()}.
1715
1716 \sa disconnect()
1717*/
1718
1719bool QObject::connect( const QObject *sender, const char *signal,
1720 const QObject *receiver, const char *member )
1721{
1722#if defined(QT_CHECK_NULL)
1723 if ( sender == 0 || receiver == 0 || signal == 0 || member == 0 ) {
1724 qWarning( "QObject::connect: Cannot connect %s::%s to %s::%s",
1725 sender ? sender->className() : "(null)",
1726 signal ? signal+1 : "(null)",
1727 receiver ? receiver->className() : "(null)",
1728 member ? member+1 : "(null)" );
1729 return FALSE;
1730 }
1731#endif
1732 QMetaObject *smeta = sender->metaObject();
1733
1734#if defined(QT_CHECK_RANGE)
1735 if ( !check_signal_macro( sender, signal, "connect", "bind" ) )
1736 return FALSE;
1737#endif
1738 QCString nw_signal(signal); // Assume already normalized
1739 ++signal; // skip member type code
1740
1741 int signal_index = smeta->findSignal( signal, TRUE );
1742 if ( signal_index < 0 ) { // normalize and retry
1743 nw_signal = qt_rmWS( signal-1 ); // remove whitespace
1744 signal = nw_signal.data()+1; // skip member type code
1745 signal_index = smeta->findSignal( signal, TRUE );
1746 }
1747
1748 if ( signal_index < 0 ) { // no such signal
1749#if defined(QT_CHECK_RANGE)
1750 err_member_notfound( QSIGNAL_CODE, sender, signal, "connect" );
1751 err_info_about_candidates( QSIGNAL_CODE, smeta, signal, "connect" );
1752 err_info_about_objects( "connect", sender, receiver );
1753#endif
1754 return FALSE;
1755 }
1756 const QMetaData *sm = smeta->signal( signal_index, TRUE );
1757 signal = sm->name; // use name from meta object
1758
1759 int membcode = member[0] - '0'; // get member code
1760
1761 QObject *s = (QObject *)sender; // we need to change them
1762 QObject *r = (QObject *)receiver; // internally
1763
1764#if defined(QT_CHECK_RANGE)
1765 if ( !check_member_code( membcode, r, member, "connect" ) )
1766 return FALSE;
1767#endif
1768 member++; // skip code
1769
1770 QCString nw_member ;
1771 QMetaObject *rmeta = r->metaObject();
1772 int member_index = -1;
1773 switch ( membcode ) { // get receiver member
1774 case QSLOT_CODE:
1775 member_index = rmeta->findSlot( member, TRUE );
1776 if ( member_index < 0 ) { // normalize and retry
1777 nw_member = qt_rmWS(member); // remove whitespace
1778 member = nw_member;
1779 member_index = rmeta->findSlot( member, TRUE );
1780 }
1781 break;
1782 case QSIGNAL_CODE:
1783 member_index = rmeta->findSignal( member, TRUE );
1784 if ( member_index < 0 ) { // normalize and retry
1785 nw_member = qt_rmWS(member); // remove whitespace
1786 member = nw_member;
1787 member_index = rmeta->findSignal( member, TRUE );
1788 }
1789 break;
1790 }
1791 if ( member_index < 0 ) {
1792#if defined(QT_CHECK_RANGE)
1793 err_member_notfound( membcode, r, member, "connect" );
1794 err_info_about_candidates( membcode, rmeta, member, "connect" );
1795 err_info_about_objects( "connect", sender, receiver );
1796#endif
1797 return FALSE;
1798 }
1799#if defined(QT_CHECK_RANGE)
1800 if ( !s->checkConnectArgs(signal,receiver,member) ) {
1801 qWarning( "QObject::connect: Incompatible sender/receiver arguments"
1802 "\n\t%s::%s --> %s::%s",
1803 s->className(), signal,
1804 r->className(), member );
1805 return FALSE;
1806 } else {
1807 const QMetaData *rm = membcode == QSLOT_CODE ?
1808 rmeta->slot( member_index, TRUE ) :
1809 rmeta->signal( member_index, TRUE );
1810 if ( rm ) {
1811 int si = 0;
1812 int ri = 0;
1813 while ( si < sm->method->count && ri < rm->method->count ) {
1814 if ( sm->method->parameters[si].inOut == QUParameter::Out )
1815 si++;
1816 else if ( rm->method->parameters[ri].inOut == QUParameter::Out )
1817 ri++;
1818 else if ( !QUType::isEqual( sm->method->parameters[si++].type,
1819 rm->method->parameters[ri++].type ) ) {
1820 if ( ( QUType::isEqual( sm->method->parameters[si-1].type, &static_QUType_ptr )
1821 && QUType::isEqual( rm->method->parameters[ri-1].type, &static_QUType_varptr ) )
1822 || ( QUType::isEqual( sm->method->parameters[si-1].type, &static_QUType_varptr )
1823 && QUType::isEqual( rm->method->parameters[ri-1].type, &static_QUType_ptr ) ) )
1824 continue; // varptr got introduced in 3.1 and is binary compatible with ptr
1825 qWarning( "QObject::connect: Incompatible sender/receiver marshalling"
1826 "\n\t%s::%s --> %s::%s",
1827 s->className(), signal,
1828 r->className(), member );
1829 return FALSE;
1830 }
1831 }
1832 }
1833 }
1834#endif
1835 connectInternal( sender, signal_index, receiver, membcode, member_index );
1836 s->connectNotify( nw_signal );
1837 return TRUE;
1838}
1839
1840/*! \internal */
1841
1842void QObject::connectInternal( const QObject *sender, int signal_index, const QObject *receiver,
1843 int membcode, int member_index )
1844{
1845 QObject *s = (QObject*)sender;
1846 QObject *r = (QObject*)receiver;
1847
1848 if ( !s->connections ) { // create connections lookup table
1849 s->connections = new QSignalVec( signal_index+1 );
1850 Q_CHECK_PTR( s->connections );
1851 s->connections->setAutoDelete( TRUE );
1852 }
1853
1854 QConnectionList *clist = s->connections->at( signal_index );
1855 if ( !clist ) { // create receiver list
1856 clist = new QConnectionList;
1857 Q_CHECK_PTR( clist );
1858 clist->setAutoDelete( TRUE );
1859 s->connections->insert( signal_index, clist );
1860 }
1861
1862 QMetaObject *rmeta = r->metaObject();
1863 const QMetaData *rm = 0;
1864
1865 switch ( membcode ) { // get receiver member
1866 case QSLOT_CODE:
1867 rm = rmeta->slot( member_index, TRUE );
1868 break;
1869 case QSIGNAL_CODE:
1870 rm = rmeta->signal( member_index, TRUE );
1871 break;
1872 }
1873
1874 QConnection *c = new QConnection( r, member_index, rm ? rm->name : "qt_invoke", membcode );
1875 Q_CHECK_PTR( c );
1876 clist->append( c );
1877 if ( !r->senderObjects ) // create list of senders
1878 r->senderObjects = new QSenderObjectList;
1879 r->senderObjects->append( s ); // add sender to list
1880}
1881
1882
1883/*!
1884 \overload bool QObject::disconnect( const char *signal, const QObject *receiver, const char *member )
1885
1886 Disconnects \a signal from \a member of \a receiver.
1887
1888 A signal-slot connection is removed when either of the objects
1889 involved are destroyed.
1890*/
1891
1892/*!
1893 \overload bool QObject::disconnect( const QObject *receiver, const char *member )
1894
1895 Disconnects all signals in this object from \a receiver's \a
1896 member.
1897
1898 A signal-slot connection is removed when either of the objects
1899 involved are destroyed.
1900*/
1901
1902/*!
1903 Disconnects \a signal in object \a sender from \a member in object
1904 \a receiver.
1905
1906 A signal-slot connection is removed when either of the objects
1907 involved are destroyed.
1908
1909 disconnect() is typically used in three ways, as the following
1910 examples demonstrate.
1911 \list 1
1912 \i Disconnect everything connected to an object's signals:
1913 \code
1914 disconnect( myObject, 0, 0, 0 );
1915 \endcode
1916 equivalent to the non-static overloaded function
1917 \code
1918 myObject->disconnect();
1919 \endcode
1920 \i Disconnect everything connected to a specific signal:
1921 \code
1922 disconnect( myObject, SIGNAL(mySignal()), 0, 0 );
1923 \endcode
1924 equivalent to the non-static overloaded function
1925 \code
1926 myObject->disconnect( SIGNAL(mySignal()) );
1927 \endcode
1928 \i Disconnect a specific receiver:
1929 \code
1930 disconnect( myObject, 0, myReceiver, 0 );
1931 \endcode
1932 equivalent to the non-static overloaded function
1933 \code
1934 myObject->disconnect( myReceiver );
1935 \endcode
1936 \endlist
1937
1938 0 may be used as a wildcard, meaning "any signal", "any receiving
1939 object", or "any slot in the receiving object", respectively.
1940
1941 The \a sender may never be 0. (You cannot disconnect signals from
1942 more than one object in a single call.)
1943
1944 If \a signal is 0, it disconnects \a receiver and \a member from
1945 any signal. If not, only the specified signal is disconnected.
1946
1947 If \a receiver is 0, it disconnects anything connected to \a
1948 signal. If not, slots in objects other than \a receiver are not
1949 disconnected.
1950
1951 If \a member is 0, it disconnects anything that is connected to \a
1952 receiver. If not, only slots named \a member will be disconnected,
1953 and all other slots are left alone. The \a member must be 0 if \a
1954 receiver is left out, so you cannot disconnect a
1955 specifically-named slot on all objects.
1956
1957 \sa connect()
1958*/
1959
1960bool QObject::disconnect( const QObject *sender, const char *signal,
1961 const QObject *receiver, const char *member )
1962{
1963#if defined(QT_CHECK_NULL)
1964 if ( sender == 0 || (receiver == 0 && member != 0) ) {
1965 qWarning( "QObject::disconnect: Unexpected null parameter" );
1966 return FALSE;
1967 }
1968#endif
1969 if ( !sender->connections ) // no connected signals
1970 return FALSE;
1971 QObject *s = (QObject *)sender;
1972 QObject *r = (QObject *)receiver;
1973 int member_index = -1;
1974 int membcode = -1;
1975 QCString nw_member;
1976 if ( member ) {
1977 membcode = member[0] - '0';
1978#if defined(QT_CHECK_RANGE)
1979 if ( !check_member_code( membcode, r, member, "disconnect" ) )
1980 return FALSE;
1981#endif
1982 ++member;
1983 QMetaObject *rmeta = r->metaObject();
1984
1985 switch ( membcode ) { // get receiver member
1986 case QSLOT_CODE:
1987 member_index = rmeta->findSlot( member, TRUE );
1988 if ( member_index < 0 ) { // normalize and retry
1989 nw_member = qt_rmWS(member); // remove whitespace
1990 member = nw_member;
1991 member_index = rmeta->findSlot( member, TRUE );
1992 }
1993 break;
1994 case QSIGNAL_CODE:
1995 member_index = rmeta->findSignal( member, TRUE );
1996 if ( member_index < 0 ) { // normalize and retry
1997 nw_member = qt_rmWS(member); // remove whitespace
1998 member = nw_member;
1999 member_index = rmeta->findSignal( member, TRUE );
2000 }
2001 break;
2002 }
2003 if ( member_index < 0 ) { // no such member
2004#if defined(QT_CHECK_RANGE)
2005 err_member_notfound( membcode, r, member, "disconnect" );
2006 err_info_about_candidates( membcode, rmeta, member, "connect" );
2007 err_info_about_objects( "disconnect", sender, receiver );
2008#endif
2009 return FALSE;
2010 }
2011 }
2012
2013 if ( signal == 0 ) { // any/all signals
2014 if ( disconnectInternal( s, -1, r, membcode, member_index ) )
2015 s->disconnectNotify( 0 );
2016 else
2017 return FALSE;
2018 } else { // specific signal
2019#if defined(QT_CHECK_RANGE)
2020 if ( !check_signal_macro( s, signal, "disconnect", "unbind" ) )
2021 return FALSE;
2022#endif
2023 QCString nw_signal(signal); // Assume already normalized
2024 ++signal; // skip member type code
2025
2026 QMetaObject *smeta = s->metaObject();
2027 if ( !smeta ) // no meta object
2028 return FALSE;
2029 int signal_index = smeta->findSignal( signal, TRUE );
2030 if ( signal_index < 0 ) { // normalize and retry
2031 nw_signal = qt_rmWS( signal-1 ); // remove whitespace
2032 signal = nw_signal.data()+1; // skip member type code
2033 signal_index = smeta->findSignal( signal, TRUE );
2034 }
2035 if ( signal_index < 0 ) {
2036#if defined(QT_CHECK_RANGE)
2037 qWarning( "QObject::disconnect: No such signal %s::%s",
2038 s->className(), signal );
2039#endif
2040 return FALSE;
2041 }
2042
2043 /* compatibility and safety: If a receiver has several slots
2044 * with the same name, disconnect them all*/
2045 bool res = FALSE;
2046 if ( membcode == QSLOT_CODE && r ) {
2047 QMetaObject * rmeta = r->metaObject();
2048 do {
2049 int mi = rmeta->findSlot( member );
2050 if ( mi != -1 )
2051 res |= disconnectInternal( s, signal_index, r, membcode, mi );
2052 } while ( (rmeta = rmeta->superClass()) );
2053 } else {
2054 res = disconnectInternal( s, signal_index, r, membcode, member_index );
2055 }
2056 if ( res )
2057 s->disconnectNotify( nw_signal );
2058 return res;
2059 }
2060 return TRUE;
2061}
2062
2063/*! \internal */
2064
2065bool QObject::disconnectInternal( const QObject *sender, int signal_index,
2066 const QObject *receiver, int membcode, int member_index )
2067{
2068 QObject *s = (QObject*)sender;
2069 QObject *r = (QObject*)receiver;
2070
2071 if ( !s->connections )
2072 return FALSE;
2073
2074 bool success = FALSE;
2075 QConnectionList *clist;
2076 register QConnection *c;
2077 if ( signal_index == -1 ) {
2078 for ( int i = 0; i < (int) s->connections->size(); i++ ) {
2079 clist = (*s->connections)[i]; // for all signals...
2080 if ( !clist )
2081 continue;
2082 c = clist->first();
2083 while ( c ) { // for all receivers...
2084 if ( r == 0 ) { // remove all receivers
2085 removeObjFromList( c->object()->senderObjects, s );
2086 success = TRUE;
2087 c = clist->next();
2088 } else if ( r == c->object() &&
2089 ( member_index == -1 ||
2090 member_index == c->member() && c->memberType() == membcode ) ) {
2091 removeObjFromList( c->object()->senderObjects, s );
2092 success = TRUE;
2093 clist->remove();
2094 c = clist->current();
2095 } else {
2096 c = clist->next();
2097 }
2098 }
2099 if ( r == 0 ) // disconnect all receivers
2100 s->connections->insert( i, 0 );
2101 }
2102 } else {
2103 clist = s->connections->at( signal_index );
2104 if ( !clist )
2105 return FALSE;
2106
2107 c = clist->first();
2108 while ( c ) { // for all receivers...
2109 if ( r == 0 ) { // remove all receivers
2110 removeObjFromList( c->object()->senderObjects, s, TRUE );
2111 success = TRUE;
2112 c = clist->next();
2113 } else if ( r == c->object() &&
2114 ( member_index == -1 ||
2115 member_index == c->member() && c->memberType() == membcode ) ) {
2116 removeObjFromList( c->object()->senderObjects, s, TRUE );
2117 success = TRUE;
2118 clist->remove();
2119 c = clist->current();
2120 } else {
2121 c = clist->next();
2122 }
2123 }
2124 if ( r == 0 ) // disconnect all receivers
2125 s->connections->insert( signal_index, 0 );
2126 }
2127 return success;
2128}
2129
2130/*!
2131 \fn QObject::destroyed()
2132
2133 This signal is emitted when the object is being destroyed.
2134
2135 Note that the signal is emitted by the QObject destructor, so
2136 the object's virtual table is already degenerated at this point,
2137 and it is not safe to call any functions on the object emitting
2138 the signal. This signal can not be blocked.
2139
2140 All the objects's children are destroyed immediately after this
2141 signal is emitted.
2142*/
2143
2144/*!
2145 \overload QObject::destroyed( QObject* obj)
2146
2147 This signal is emitted immediately before the object \a obj is
2148 destroyed, and can not be blocked.
2149
2150 All the objects's children are destroyed immediately after this
2151 signal is emitted.
2152*/
2153
2154/*!
2155 Performs a deferred deletion of this object.
2156
2157 Instead of an immediate deletion this function schedules a
2158 deferred delete event for processing when Qt returns to the main
2159 event loop.
2160*/
2161void QObject::deleteLater()
2162{
2163 QApplication::postEvent( this, new QEvent( QEvent::DeferredDelete) );
2164}
2165
2166/*!
2167 This slot is connected to the destroyed() signal of other objects
2168 that have installed event filters on this object. When the other
2169 object, \a obj, is destroyed, we want to remove its event filter.
2170*/
2171
2172void QObject::cleanupEventFilter(QObject* obj)
2173{
2174 removeEventFilter( obj );
2175}
2176
2177
2178/*!
2179 \fn QString QObject::tr( const char *sourceText, const char * comment )
2180 \reentrant
2181
2182 Returns a translated version of \a sourceText, or \a sourceText
2183 itself if there is no appropriate translated version. The
2184 translation context is QObject with \a comment (0 by default).
2185 All QObject subclasses using the Q_OBJECT macro automatically have
2186 a reimplementation of this function with the subclass name as
2187 context.
2188
2189 \warning This method is reentrant only if all translators are
2190 installed \e before calling this method. Installing or removing
2191 translators while performing translations is not supported. Doing
2192 so will probably result in crashes or other undesirable behavior.
2193
2194 \sa trUtf8() QApplication::translate()
2195 \link i18n.html Internationalization with Qt\endlink
2196*/
2197
2198/*!
2199 \fn QString QObject::trUtf8( const char *sourceText,
2200 const char *comment )
2201 \reentrant
2202
2203 Returns a translated version of \a sourceText, or
2204 QString::fromUtf8(\a sourceText) if there is no appropriate
2205 version. It is otherwise identical to tr(\a sourceText, \a
2206 comment).
2207
2208 \warning This method is reentrant only if all translators are
2209 installed \e before calling this method. Installing or removing
2210 translators while performing translations is not supported. Doing
2211 so will probably result in crashes or other undesirable behavior.
2212
2213 \sa tr() QApplication::translate()
2214*/
2215
2216static QMetaObjectCleanUp cleanUp_Qt = QMetaObjectCleanUp( "QObject", &QObject::staticMetaObject );
2217
2218QMetaObject* QObject::staticQtMetaObject()
2219{
2220 static QMetaObject* qtMetaObject = 0;
2221 if ( qtMetaObject )
2222 return qtMetaObject;
2223
2224#ifndef QT_NO_PROPERTIES
2225 static const QMetaEnum::Item enum_0[] = {
2226 { "AlignLeft", (int) Qt::AlignLeft },
2227 { "AlignRight", (int) Qt::AlignRight },
2228 { "AlignHCenter", (int) Qt::AlignHCenter },
2229 { "AlignTop", (int) Qt::AlignTop },
2230 { "AlignBottom", (int) Qt::AlignBottom },
2231 { "AlignVCenter", (int) Qt::AlignVCenter },
2232 { "AlignCenter", (int) Qt::AlignCenter },
2233 { "AlignAuto", (int) Qt::AlignAuto },
2234 { "AlignJustify", (int) Qt::AlignJustify },
2235 { "WordBreak", (int) Qt::WordBreak }
2236 };
2237
2238 static const QMetaEnum::Item enum_1[] = {
2239 { "Horizontal", (int) Qt::Horizontal },
2240 { "Vertical", (int) Qt::Vertical }
2241 };
2242
2243 static const QMetaEnum::Item enum_2[] = {
2244 { "PlainText", (int) Qt::PlainText },
2245 { "RichText", (int) Qt::RichText },
2246 { "AutoText", (int) Qt::AutoText },
2247 { "LogText", (int) Qt::LogText }
2248 };
2249
2250 static const QMetaEnum::Item enum_3[] = {
2251 { "NoBackground", (int) Qt::NoBackground },
2252 { "PaletteForeground", (int) Qt::PaletteForeground },
2253 { "PaletteButton", (int) Qt::PaletteButton },
2254 { "PaletteLight", (int) Qt::PaletteLight },
2255 { "PaletteMidlight", (int) Qt::PaletteMidlight },
2256 { "PaletteDark", (int) Qt::PaletteDark },
2257 { "PaletteMid", (int) Qt::PaletteMid },
2258 { "PaletteText", (int) Qt::PaletteText },
2259 { "PaletteBrightText", (int) Qt::PaletteBrightText },
2260 { "PaletteBase", (int) Qt::PaletteBase },
2261 { "PaletteBackground", (int) Qt::PaletteBackground },
2262 { "PaletteShadow", (int) Qt::PaletteShadow },
2263 { "PaletteHighlight", (int) Qt::PaletteHighlight },
2264 { "PaletteHighlightedText", (int) Qt::PaletteHighlightedText },
2265 { "PaletteButtonText", (int) Qt::PaletteButtonText },
2266 { "PaletteLink", (int) Qt::PaletteLink },
2267 { "PaletteLinkVisited", (int) Qt::PaletteLinkVisited }
2268 };
2269
2270 static const QMetaEnum::Item enum_4[] = {
2271 { "TextDate", (int) Qt::TextDate },
2272 { "ISODate", (int) Qt::ISODate },
2273 { "LocalDate", (int) Qt::LocalDate }
2274 };
2275
2276
2277 static const QMetaEnum enum_tbl[] = {
2278 { "Alignment", 10, enum_0, TRUE },
2279 { "Orientation", 2, enum_1, FALSE },
2280 { "TextFormat", 4, enum_2, FALSE },
2281 { "BackgroundMode", 17, enum_3, FALSE },
2282 { "DateFormat", 3, enum_4, FALSE }
2283 };
2284#endif
2285
2286 qtMetaObject = new QMetaObject( "Qt", 0,
2287 0, 0,
2288 0, 0,
2289#ifndef QT_NO_PROPERTIES
2290 0, 0,
2291 enum_tbl, 5,
2292#endif
2293 0, 0 );
2294 cleanUp_Qt.setMetaObject( qtMetaObject );
2295
2296 return qtMetaObject;
2297}
2298
2299/*!
2300 \internal
2301
2302 Signal activation with the most frequently used parameter/argument
2303 types. All other combinations are generated by the meta object
2304 compiler.
2305 */
2306void QObject::activate_signal( int signal )
2307{
2308#ifndef QT_NO_PRELIMINARY_SIGNAL_SPY
2309 if ( qt_preliminary_signal_spy ) {
2310 if ( !signalsBlocked() && signal >= 0 &&
2311 ( !connections || !connections->at( signal ) ) ) {
2312 QUObject o[1];
2313 qt_spy_signal( this, signal, o );
2314 return;
2315 }
2316 }
2317#endif
2318
2319 if ( !connections || signalsBlocked() || signal < 0 )
2320 return;
2321 QConnectionList *clist = connections->at( signal );
2322 if ( !clist )
2323 return;
2324 QUObject o[1];
2325 activate_signal( clist, o );
2326}
2327
2328/*! \internal */
2329
2330void QObject::activate_signal( QConnectionList *clist, QUObject *o )
2331{
2332 if ( !clist )
2333 return;
2334
2335#ifndef QT_NO_PRELIMINARY_SIGNAL_SPY
2336 if ( qt_preliminary_signal_spy )
2337 qt_spy_signal( this, connections->findRef( clist), o );
2338#endif
2339
2340 QObject *object;
2341 QSenderObjectList* sol;
2342 QObject* oldSender = 0;
2343 QConnection *c;
2344 if ( clist->count() == 1 ) { // save iterator
2345 c = clist->first();
2346 object = c->object();
2347 sol = object->senderObjects;
2348 if ( sol ) {
2349 oldSender = sol->currentSender;
2350 sol->ref();
2351 sol->currentSender = this;
2352 }
2353 if ( c->memberType() == QSIGNAL_CODE )
2354 object->qt_emit( c->member(), o );
2355 else
2356 object->qt_invoke( c->member(), o );
2357 if ( sol ) {
2358 sol->currentSender = oldSender;
2359 if ( sol->deref() )
2360 delete sol;
2361 }
2362 } else {
2363 QConnection *cd = 0;
2364 QConnectionListIt it(*clist);
2365 while ( (c=it.current()) ) {
2366 ++it;
2367 if ( c == cd )
2368 continue;
2369 cd = c;
2370 object = c->object();
2371 sol = object->senderObjects;
2372 if ( sol ) {
2373 oldSender = sol->currentSender;
2374 sol->ref();
2375 sol->currentSender = this;
2376 }
2377 if ( c->memberType() == QSIGNAL_CODE )
2378 object->qt_emit( c->member(), o );
2379 else
2380 object->qt_invoke( c->member(), o );
2381 if (sol ) {
2382 sol->currentSender = oldSender;
2383 if ( sol->deref() )
2384 delete sol;
2385 }
2386 }
2387 }
2388}
2389
2390/*!
2391 \overload void QObject::activate_signal( int signal, int )
2392*/
2393
2394/*!
2395 \overload void QObject::activate_signal( int signal, double )
2396*/
2397
2398/*!
2399 \overload void QObject::activate_signal( int signal, QString )
2400*/
2401
2402/*!
2403 \fn void QObject::activate_signal_bool( int signal, bool )
2404 \internal
2405
2406 Like the above functions, but since bool is sometimes
2407 only a typedef it cannot be a simple overload.
2408*/
2409
2410#ifndef QT_NO_PRELIMINARY_SIGNAL_SPY
2411#define ACTIVATE_SIGNAL_WITH_PARAM(FNAME,TYPE) \
2412void QObject::FNAME( int signal, TYPE param ) \
2413{ \
2414 if ( qt_preliminary_signal_spy ) { \
2415 if ( !signalsBlocked() && signal >= 0 && \
2416 ( !connections || !connections->at( signal ) ) ) { \
2417 QUObject o[2]; \
2418 static_QUType_##TYPE.set( o+1, param ); \
2419 qt_spy_signal( this, signal, o ); \
2420 return; \
2421 } \
2422 } \
2423 if ( !connections || signalsBlocked() || signal < 0 ) \
2424 return; \
2425 QConnectionList *clist = connections->at( signal ); \
2426 if ( !clist ) \
2427 return; \
2428 QUObject o[2]; \
2429 static_QUType_##TYPE.set( o+1, param ); \
2430 activate_signal( clist, o ); \
2431}
2432#else
2433#define ACTIVATE_SIGNAL_WITH_PARAM(FNAME,TYPE) \
2434void QObject::FNAME( int signal, TYPE param ) \
2435{ \
2436 if ( !connections || signalsBlocked() || signal < 0 ) \
2437 return; \
2438 QConnectionList *clist = connections->at( signal ); \
2439 if ( !clist ) \
2440 return; \
2441 QUObject o[2]; \
2442 static_QUType_##TYPE.set( o+1, param ); \
2443 activate_signal( clist, o ); \
2444}
2445
2446#endif
2447// We don't want to duplicate too much text so...
2448
2449ACTIVATE_SIGNAL_WITH_PARAM( activate_signal, int )
2450ACTIVATE_SIGNAL_WITH_PARAM( activate_signal, double )
2451ACTIVATE_SIGNAL_WITH_PARAM( activate_signal, QString )
2452ACTIVATE_SIGNAL_WITH_PARAM( activate_signal_bool, bool )
2453
2454
2455/*****************************************************************************
2456 QObject debugging output routines.
2457 *****************************************************************************/
2458
2459static void dumpRecursive( int level, QObject *object )
2460{
2461#if defined(QT_DEBUG)
2462 if ( object ) {
2463 QString buf;
2464 buf.fill( '\t', level/2 );
2465 if ( level % 2 )
2466 buf += " ";
2467 const char *name = object->name();
2468 QString flags="";
2469 if ( qApp->focusWidget() == object )
2470 flags += 'F';
2471 if ( object->isWidgetType() ) {
2472 QWidget * w = (QWidget *)object;
2473 if ( w->isVisible() ) {
2474 QString t( "<%1,%2,%3,%4>" );
2475 flags += t.arg(w->x()).arg(w->y()).arg(w->width()).arg(w->height());
2476 } else {
2477 flags += 'I';
2478 }
2479 }
2480 qDebug( "%s%s::%s %s", (const char*)buf, object->className(), name,
2481 flags.latin1() );
2482 if ( object->children() ) {
2483 QObjectListIt it(*object->children());
2484 QObject * c;
2485 while ( (c=it.current()) != 0 ) {
2486 ++it;
2487 dumpRecursive( level+1, c );
2488 }
2489 }
2490 }
2491#else
2492 Q_UNUSED( level )
2493 Q_UNUSED( object )
2494#endif
2495}
2496
2497/*!
2498 Dumps a tree of children to the debug output.
2499
2500 This function is useful for debugging, but does nothing if the
2501 library has been compiled in release mode (i.e. without debugging
2502 information).
2503*/
2504
2505void QObject::dumpObjectTree()
2506{
2507 dumpRecursive( 0, this );
2508}
2509
2510/*!
2511 Dumps information about signal connections, etc. for this object
2512 to the debug output.
2513
2514 This function is useful for debugging, but does nothing if the
2515 library has been compiled in release mode (i.e. without debugging
2516 information).
2517*/
2518
2519void QObject::dumpObjectInfo()
2520{
2521#if defined(QT_DEBUG)
2522 qDebug( "OBJECT %s::%s", className(), name( "unnamed" ) );
2523 int n = 0;
2524 qDebug( " SIGNALS OUT" );
2525 if ( connections ) {
2526 QConnectionList *clist;
2527 for ( uint i = 0; i < connections->size(); i++ ) {
2528 if ( ( clist = connections->at( i ) ) ) {
2529 qDebug( "\t%s", metaObject()->signal( i, TRUE )->name );
2530 n++;
2531 register QConnection *c;
2532 QConnectionListIt cit(*clist);
2533 while ( (c=cit.current()) ) {
2534 ++cit;
2535 qDebug( "\t --> %s::%s %s", c->object()->className(),
2536 c->object()->name( "unnamed" ), c->memberName() );
2537 }
2538 }
2539 }
2540 }
2541 if ( n == 0 )
2542 qDebug( "\t<None>" );
2543
2544 qDebug( " SIGNALS IN" );
2545 n = 0;
2546 if ( senderObjects ) {
2547 QObject *sender = senderObjects->first();
2548 while ( sender ) {
2549 qDebug( "\t%s::%s",
2550 sender->className(), sender->name( "unnamed" ) );
2551 n++;
2552 sender = senderObjects->next();
2553 }
2554 }
2555 if ( n == 0 )
2556 qDebug( "\t<None>" );
2557#endif
2558}
2559
2560#ifndef QT_NO_PROPERTIES
2561
2562/*!
2563 Sets the value of the object's \a name property to \a value.
2564
2565 Returns TRUE if the operation was successful; otherwise returns
2566 FALSE.
2567
2568 Information about all available properties is provided through the
2569 metaObject().
2570
2571 \sa property(), metaObject(), QMetaObject::propertyNames(), QMetaObject::property()
2572*/
2573bool QObject::setProperty( const char *name, const QVariant& value )
2574{
2575 if ( !value.isValid() )
2576 return FALSE;
2577
2578 QVariant v = value;
2579
2580 QMetaObject* meta = metaObject();
2581 if ( !meta )
2582 return FALSE;
2583 int id = meta->findProperty( name, TRUE );
2584 const QMetaProperty* p = meta->property( id, TRUE );
2585 if ( !p || !p->isValid() || !p->writable() ) {
2586 qWarning( "%s::setProperty( \"%s\", value ) failed: property invalid, read-only or does not exist",
2587 className(), name );
2588 return FALSE;
2589 }
2590
2591 if ( p->isEnumType() ) {
2592 if ( v.type() == QVariant::String || v.type() == QVariant::CString ) {
2593 if ( p->isSetType() ) {
2594 QString s = value.toString();
2595 // QStrList does not support split, use QStringList for that.
2596 QStringList l = QStringList::split( '|', s );
2597 QStrList keys;
2598 for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it )
2599 keys.append( (*it).stripWhiteSpace().latin1() );
2600 v = QVariant( p->keysToValue( keys ) );
2601 } else {
2602 v = QVariant( p->keyToValue( value.toCString().data() ) );
2603 }
2604 } else if ( v.type() != QVariant::Int && v.type() != QVariant::UInt ) {
2605 return FALSE;
2606 }
2607 return qt_property( id, 0, &v );
2608 }
2609
2610 QVariant::Type type = (QVariant::Type)(p->flags >> 24);
2611 if ( type == QVariant::Invalid )
2612 type = QVariant::nameToType( p->type() );
2613 if ( type != QVariant::Invalid && !v.canCast( type ) )
2614 return FALSE;
2615 return qt_property( id, 0, &v );
2616}
2617
2618/*!
2619 Returns the value of the object's \a name property.
2620
2621 If no such property exists, the returned variant is invalid.
2622
2623 Information about all available properties are provided through
2624 the metaObject().
2625
2626 \sa setProperty(), QVariant::isValid(), metaObject(),
2627 QMetaObject::propertyNames(), QMetaObject::property()
2628*/
2629QVariant QObject::property( const char *name ) const
2630{
2631 QVariant v;
2632 QMetaObject* meta = metaObject();
2633 if ( !meta )
2634 return v;
2635 int id = meta->findProperty( name, TRUE );
2636 const QMetaProperty* p = meta->property( id, TRUE );
2637 if ( !p || !p->isValid() ) {
2638 qWarning( "%s::property( \"%s\" ) failed: property invalid or does not exist",
2639 className(), name );
2640 return v;
2641 }
2642 QObject* that = (QObject*) this; // moc ensures constness for the qt_property call
2643 that->qt_property( id, 1, &v );
2644 return v;
2645}
2646
2647#endif // QT_NO_PROPERTIES
2648
2649#ifndef QT_NO_USERDATA
2650/*!\internal
2651 */
2652uint QObject::registerUserData()
2653{
2654 static int user_data_registration = 0;
2655 return user_data_registration++;
2656}
2657
2658/*!\internal
2659 */
2660QObjectUserData::~QObjectUserData()
2661{
2662}
2663
2664/*!\internal
2665 */
2666void QObject::setUserData( uint id, QObjectUserData* data)
2667{
2668 if ( !d )
2669 d = new QObjectPrivate( id+1 );
2670 if ( id >= d->size() )
2671 d->resize( id+1 );
2672 d->insert( id, data );
2673}
2674
2675/*!\internal
2676 */
2677QObjectUserData* QObject::userData( uint id ) const
2678{
2679 if ( d && id < d->size() )
2680 return d->at( id );
2681 return 0;
2682}
2683
2684#endif // QT_NO_USERDATA
Note: See TracBrowser for help on using the repository browser.