diff options
Diffstat (limited to 'experimental/tqtinterface/qt4/src/kernel/tqobject.cpp')
-rw-r--r-- | experimental/tqtinterface/qt4/src/kernel/tqobject.cpp | 3666 |
1 files changed, 3666 insertions, 0 deletions
diff --git a/experimental/tqtinterface/qt4/src/kernel/tqobject.cpp b/experimental/tqtinterface/qt4/src/kernel/tqobject.cpp new file mode 100644 index 000000000..9bec0241f --- /dev/null +++ b/experimental/tqtinterface/qt4/src/kernel/tqobject.cpp @@ -0,0 +1,3666 @@ +/**************************************************************************** +** +** Implementation of TQObject class +** +****************************************************************************/ + +#include "tqtglobaldefines.h" + +#ifdef USE_QT4 + +#include "tqobject.h" +#include "tqwidget.h" + +#include "tqvariant.h" +#include "tqapplication.h" +#include "tqobject.h" +#include "tqobjectlist.h" +#include "tqsignalslotimp.h" +#include "tqregexp.h" +#include "tqmetaobject.h" +#include <private/tqucom_p.h> +#include "tqucomextra_p.h" +#include "tqptrvector.h" +#include "tqlayout.h" +#include <Qt/qabstracteventdispatcher.h> + +#ifdef TQT_THREAD_SUPPORT +#include <tqmutex.h> +#include <private/tqmutexpool_p.h> +#endif + +#include <ctype.h> + +// Event functions, implemented in qapplication_xxx.cpp + +// int qStartTimer( int interval, TQObject *obj ); +// bool tqKillTimer( int id ); +// bool tqKillTimer( TQObject *obj ); + +#ifndef TQT_NO_USERDATA +class TQObjectPrivate : public TQPtrVector<TQObjectUserData> +{ +public: + TQObjectPrivate( uint s ) : TQPtrVector<TQObjectUserData>(s){ setAutoDelete( TRUE ); } +}; +#else +class TQObjectPrivate { +} +#endif + +class TQSenderObjectList : public TQObjectList, public TQShared +{ +public: + TQSenderObjectList() : currentSender( 0 ) { } + TQObject *currentSender; +}; + +/*! + \class TQt tqnamespace.h + + \brief The TQt class is a namespace for miscellaneous identifiers + that need to be global-like. + + \ingroup misc + + Normally, you can ignore this class. TQObject and a few other + classes inherit it, so all the identifiers in the TQt namespace are + normally usable without qualification. + + However, you may occasionally need to say \c TQt::black instead of + just \c black, particularly in static utility functions (such as + many class factories). + +*/ + +TQObject::TQObject( TQT_BASE_OBJECT_NAME *tqparent, const char *name ) : TQT_BASE_OBJECT_NAME ( tqparent ) { + setObjectName(QString::fromAscii(name)); + TQT_TQOBJECT_REQUIRED_INITIALIZATION(tqparent) +} + +const char * TQObject::name(const char *defaultName) const { + TQString s = objectName(); + return s.isEmpty()?defaultName:s.latin1_helper(); +} + +void TQObject::insertChild( TQObject *object ) { + TQChildEvent *e = new TQChildEvent( (QEvent::Type)TQEvent::ChildInserted, object ); + QApplication::postEvent( this, e ); + object->setParent(this); +} + +void TQObject::removeChild( TQObject *object ) { + object->setParent(0); +} + +void TQObject::setName(const char *aName) { + setObjectName(aName); +} + +TQVariant TQObject::property( const char *name ) const { + return TQT_TQVARIANT_OBJECT(TQT_BASE_OBJECT_NAME::property(name)); +} + +// Qt4 handler interface +bool TQObject::eventFilter( QObject *q, QEvent *e ) { + return eventFilter(static_cast<TQObject*>(q), static_cast<TQEvent*>(e)); +} + +bool TQObject::event( QEvent *e ) { + return event(static_cast<TQEvent*>(e)); +} + +bool TQObject::checkConnectArgs(const char *signal, const TQT_BASE_OBJECT_NAME*, const char *member) { + return QMetaObject::checkConnectArgs(signal, member); +} + +void TQObject::timerEvent(QTimerEvent *e) { + timerEvent(static_cast<TQTimerEvent*>(e)); +} + +void TQObject::childEvent(QChildEvent *e) { + TQT_TQOBJECT_CHILDEVENT_CONDITIONAL childEvent(static_cast<TQChildEvent*>(e)); +} + +void TQObject::customEvent(QEvent *e) { + customEvent(static_cast<TQCustomEvent*>(e)); +} + +// [FIXME] +// Verify that this is truly equivalent to its Qt3 counterpart! +void TQObject::activate_signal( int signal ) { + QMetaMethod method = metaObject()->method(signal); + method.invoke(this, Qt::QueuedConnection); +} + +void TQObject::tqt_handle_qt_destroyed(QObject* obj) { + emit destroyed(TQT_TQOBJECT(obj)); +} + +bool TQObject::tqsignalsBlocked() const { + return signalsBlocked(); +} + +/*! + \enum Orientation + + This type is used to signify an object's orientation. + + \value Horizontal + \value Vertical + + Orientation is used with TQScrollBar for example. +*/ + +// See http://doc.trolltech.com/4.0/porting4.html#qobject +// [FIXME] Yet ANOTHER feature missing in Qt4...kinda gets old doesn't it? +// Just think of having to "fix" it 50 times in the Trinity source code (without TQt), each and every time the Qt API changes! + +const TQObjectList *objectTrees() { + printf("[WARNING] static const TQObjectList *objectTrees() unimplemented\n\r"); + return 0; +} + +const TQObjectList TQObject::objectTreesListObject() { + printf("[WARNING] const TQObjectList *objectTreesListObject() unimplemented\n\r"); + return TQObjectList(); +} + +TQObject *TQObject::tqparent() const { + return static_cast<TQObject*>(parent()); +} + +TQObjectList TQObject::childrenListObject() { + QObjectList qlr; + TQObjectList tqt_tqobject_list; + qlr = this->children(); + tqt_tqobject_list.clear(); + for (int i = 0; i < qlr.size(); ++i) { + tqt_tqobject_list.append(static_cast<TQObject*>(qlr.at(i))); + } + return tqt_tqobject_list; +} + +const TQObjectList TQObject::childrenListObject() const { + QObjectList qlr; + TQObjectList tqt_tqobject_list; + qlr = this->children(); + tqt_tqobject_list.clear(); + for (int i = 0; i < qlr.size(); ++i) { + tqt_tqobject_list.append(static_cast<TQObject*>(qlr.at(i))); + } + return tqt_tqobject_list; +} + +const char *TQObject::tqname() const { + if (dynamic_cast<const TQObject*>(static_cast<const QObject*>(this))) { + static_object_name = TQT_OBJECT_NAME_HANDLER(objectName()); + return static_object_name.ascii(); + } + else { + if (dynamic_cast<const TQWidget*>(static_cast<const QWidget*>(static_cast<const QObject*>(this)))) { + return TQT_TQWIDGET_CONST(this)->tqname(); + } + else if (dynamic_cast<const TQLayout*>(static_cast<const QLayout*>(static_cast<const QObject*>(this)))) { + return dynamic_cast<const TQLayout*>(static_cast<const QLayout*>(static_cast<const QObject*>(this)))->tqname(); + } + else if (dynamic_cast<const TQApplication*>(static_cast<const QApplication*>(static_cast<const QObject*>(this)))) { + return dynamic_cast<const TQApplication*>(static_cast<const QApplication*>(static_cast<const QObject*>(this)))->tqname(); + } + printf("[WARNING] Attempted to call TQObject::tqname() on an object without a constructed TQObject object or base object. Returning \"\"\n\r"); + return ""; + } +} + +const char *TQObject::name() const { + if (dynamic_cast<const TQObject*>(static_cast<const QObject*>(this))) { + static_object_name = TQT_OBJECT_NAME_HANDLER(objectName()); + return static_object_name.ascii(); + } + else { + if (dynamic_cast<const TQWidget*>(static_cast<const QWidget*>(static_cast<const QObject*>(this)))) { + return TQT_TQWIDGET_CONST(this)->name(); + } + else if (dynamic_cast<const TQLayout*>(static_cast<const QLayout*>(static_cast<const QObject*>(this)))) { + return dynamic_cast<const TQLayout*>(static_cast<const QLayout*>(static_cast<const QObject*>(this)))->name(); + } + else if (dynamic_cast<const TQApplication*>(static_cast<const QApplication*>(static_cast<const QObject*>(this)))) { + return dynamic_cast<const TQApplication*>(static_cast<const QApplication*>(static_cast<const QObject*>(this)))->name(); + } + printf("[WARNING] Attempted to call TQObject::name() on an object without a constructed TQObject object or base object. Returning \"\"\n\r"); + return ""; + } +} + +/*! \internal + TQT_BASE_OBJECT_NAME::child is compat but needs to call itself recursively, + that's why we need this helper. +*/ +static TQT_BASE_OBJECT_NAME *qChildHelper(const char *objName, const char *inheritsClass, + bool recursiveSearch, const QObjectList &children) +{ + if (children.isEmpty()) + return 0; + + bool onlyWidgets = (inheritsClass && qstrcmp(inheritsClass, "QWidget") == 0); + const QLatin1String oName(objName); + for (int i = 0; i < children.size(); ++i) { + TQT_BASE_OBJECT_NAME *obj = children.at(i); + if (onlyWidgets) { + if (obj->isWidgetType() && (!objName || obj->objectName() == oName)) + return obj; + } else if ((!inheritsClass || obj->inherits(inheritsClass)) + && (!objName || obj->objectName() == oName)) + return obj; + if (recursiveSearch && (obj = qChildHelper(objName, inheritsClass, + recursiveSearch, obj->children()))) + return obj; + } + return 0; +} + +TQObject *TQObject::child( const char *objName, const char *inheritsClass, bool recursiveSearch ) { + return static_cast<TQObject*>(qChildHelper(objName, inheritsClass, recursiveSearch, children())); +} + +#ifndef TQT_NO_PRELIMINARY_SIGNAL_SPY +/* + Preliminary signal spy + */ +TQ_EXPORT TQObject* qt_preliminary_signal_spy = 0; +static TQObject* qt_spy_signal_sender = 0; + +// static void qt_spy_signal( TQObject* sender, int signal, TQUObject* o ) +// { +// QMetaObject* mo = sender->metaObject(); +// while ( mo && signal - mo->signalOffset() < 0 ) +// mo = mo->superClass(); +// if ( !mo ) +// return; +// const TQMetaData* sigData = mo->signal( signal - mo->signalOffset() ); +// if ( !sigData ) +// return; +// TQCString s; +// mo = sender->tqmetaObject(); +// while ( mo ) { +// s.sprintf( "%s_%s", mo->className(), sigData->name ); +// int slot = qt_preliminary_signal_spy->tqmetaObject()->tqfindSlot( s, TRUE ); +// if ( slot >= 0 ) { +// #ifdef TQT_THREAD_SUPPORT +// // protect access to qt_spy_signal_sender +// void * const address = &qt_spy_signal_sender; +// TQMutexLocker locker( tqt_global_mutexpool ? +// tqt_global_mutexpool->get( address ) : 0 ); +// #endif // TQT_THREAD_SUPPORT +// +// TQObject* old_sender = qt_spy_signal_sender; +// qt_spy_signal_sender = sender; +// qt_preliminary_signal_spy->qt_invoke( slot, o ); +// qt_spy_signal_sender = old_sender; +// break; +// } +// mo = mo->superClass(); +// } +// } + +/* + End Preliminary signal spy + */ +#endif // TQT_NO_PRELIMINARY_SIGNAL_SPY + +// +// Remove white space from TQT_SIGNAL and TQT_SLOT names. +// Internal for TQObject::connect() and TQObject::disconnect() +// + +static inline bool isIdentChar( char x ) +{ // Avoid bug in isalnum + return x == '_' || (x >= '0' && x <= '9') || + (x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z'); +} + +static inline bool isSpace( char x ) +{ +#if defined(TQ_CC_BOR) + /* + Borland C++ 4.5 has a weird isspace() bug. + isspace() usually works, but not here. + This implementation is sufficient for our internal use: rmWS() + */ + return (uchar) x <= 32; +#else + return isspace( (uchar) x ); +#endif +} + +static TQCString qt_rmWS( const char *s ) +{ + TQCString result( tqstrlen(s)+1 ); + char *d = result.data(); + char last = 0; + while( *s && isSpace(*s) ) // skip leading space + s++; + while ( *s ) { + while ( *s && !isSpace(*s) ) + last = *d++ = *s++; + while ( *s && isSpace(*s) ) + s++; + if ( *s && isIdentChar(*s) && isIdentChar(last) ) + last = *d++ = ' '; + } + *d = '\0'; + result.truncate( (int)(d - result.data()) ); + int void_pos = result.tqfind("(void)"); + if ( void_pos >= 0 ) + result.remove( void_pos+1, (uint)strlen("void") ); + return result; +} + +TQConnectionList *TQObject::tqreceivers( const char* signal ) const +{ + TQConnectionList* clist = new TQConnectionList; + clist->setAutoDelete( TRUE ); + if (receivers(signal) > 0) { + printf("[WARNING] TQConnectionList *TQObject::tqreceivers( const char* signal ) is UNIMPLEMENTED and connected signals were detected!\n\r"); + } + return clist; +} + +TQConnectionList *TQObject::tqreceivers( int signal ) const +{ + TQConnectionList* clist = new TQConnectionList; + clist->setAutoDelete( TRUE ); + printf("[WARNING] TQConnectionList *TQObject::tqreceivers( int signal ) const UNIMPLEMENTED\n\r"); + return clist; +} + +/*! \internal + + Returns a list of objects/slot pairs that are connected to the + \a signal, or 0 if nothing is connected to it. +*/ + +// TQConnectionList *TQObject::tqreceivers( const char* signal ) const +// { +// if ( connections && signal ) { +// if ( *signal == '2' ) { // tag == 2, i.e. signal +// TQCString s = qt_rmWS( signal+1 ); +// return tqreceivers( metaObject()->indexOfSignal( (const char*)s ) ); +// } else { +// return tqreceivers( metaObject()->indexOfSignal(signal ) ); +// } +// } +// return 0; +// } + +/*! \internal + + Returns a list of objects/slot pairs that are connected to the + signal, or 0 if nothing is connected to it. +*/ + +// TQConnectionList *TQObject::tqreceivers( int signal ) const +// { +// #ifndef TQT_NO_PRELIMINARY_SIGNAL_SPY +// if ( qt_preliminary_signal_spy && signal >= 0 ) { +// if ( !connections ) { +// TQObject* that = (TQObject*) this; +// that->connections = new TQSignalVec( signal+1 ); +// that->connections->setAutoDelete( TRUE ); +// } +// if ( !connections->at( signal ) ) { +// TQConnectionList* clist = new TQConnectionList; +// clist->setAutoDelete( TRUE ); +// connections->insert( signal, clist ); +// return clist; +// } +// } +// #endif +// if ( connections && signal >= 0 ) +// return connections->at( signal ); +// return 0; +// } + +#if 0 + +/*! + \internal + + Signal activation with the most frequently used parameter/argument + types. All other combinations are generated by the meta object + compiler. + */ +void TQObject::activate_signal( int signal ) +{ +#ifndef TQT_NO_PRELIMINARY_SIGNAL_SPY + if ( qt_preliminary_signal_spy ) { + if ( !tqsignalsBlocked() && signal >= 0 && + ( !connections || !connections->at( signal ) ) ) { + TQUObject o[1]; + qt_spy_signal( this, signal, o ); + return; + } + } +#endif + + if ( !connections || tqsignalsBlocked() || signal < 0 ) + return; + TQConnectionList *clist = connections->at( signal ); + if ( !clist ) + return; + TQUObject o[1]; + activate_signal( clist, o ); +} + +#endif + +/*! \internal */ + +void TQObject::activate_signal( TQConnectionList *clist, TQUObject *o ) +{ + if ( !clist ) + return; + +// #ifndef TQT_NO_PRELIMINARY_SIGNAL_SPY +// if ( qt_preliminary_signal_spy ) +// qt_spy_signal( this, connections->tqfindRef( clist), o ); +// #endif + + TQObject *object; + TQSenderObjectList* sol; + TQObject* oldSender = 0; + TQConnection *c; + if ( clist->count() == 1 ) { // save iterator + c = clist->first(); + object = c->object(); + sol = object->senderObjects; + if ( sol ) { + oldSender = sol->currentSender; + sol->ref(); + sol->currentSender = this; + } + if ( c->memberType() == TQSIGNAL_CODE ) { +// object->qt_emit( c->member(), o ); + QMetaMethod method = metaObject()->method(c->member()); + method.invoke(this, Qt::QueuedConnection); + } + else { +// object->qt_invoke( c->member(), o ); + QMetaMethod method = metaObject()->method(c->member()); + method.invoke(this, Qt::QueuedConnection); + } + if ( sol ) { + sol->currentSender = oldSender; + if ( sol->deref() ) + delete sol; + } + } else { + TQConnection *cd = 0; + TQConnectionListIt it(*clist); + while ( (c=it.current()) ) { + ++it; + if ( c == cd ) + continue; + cd = c; + object = c->object(); + sol = object->senderObjects; + if ( sol ) { + oldSender = sol->currentSender; + sol->ref(); + sol->currentSender = this; + } + if ( c->memberType() == TQSIGNAL_CODE ) { +// object->qt_emit( c->member(), o ); + QMetaMethod method = metaObject()->method(c->member()); + method.invoke(this, Qt::QueuedConnection); + } + else { +// object->qt_invoke( c->member(), o ); + QMetaMethod method = metaObject()->method(c->member()); + method.invoke(this, Qt::QueuedConnection); + } + if (sol ) { + sol->currentSender = oldSender; + if ( sol->deref() ) + delete sol; + } + } + } +} + +/*! + \overload void TQObject::activate_signal( int signal, int ) +*/ + +/*! + \overload void TQObject::activate_signal( int signal, double ) +*/ + +/*! + \overload void TQObject::activate_signal( int signal, TQString ) +*/ + +/*! + \fn void TQObject::activate_signal_bool( int signal, bool ) + \internal + + Like the above functions, but since bool is sometimes + only a typedef it cannot be a simple overload. +*/ + +// #ifndef TQT_NO_PRELIMINARY_SIGNAL_SPY +// #define ACTIVATE_SIGNAL_WITH_PARAM(FNAME,TYPE) \ +// void TQObject::FNAME( int signal, TYPE param ) \ +// { \ +// if ( qt_preliminary_signal_spy ) { \ +// if ( !tqsignalsBlocked() && signal >= 0 && \ +// ( !connections || !connections->at( signal ) ) ) { \ +// TQUObject o[2]; \ +// static_TQUType_##TYPE.set( o+1, param ); \ +// qt_spy_signal( this, signal, o ); \ +// return; \ +// } \ +// } \ +// if ( !connections || tqsignalsBlocked() || signal < 0 ) \ +// return; \ +// TQConnectionList *clist = connections->at( signal ); \ +// if ( !clist ) \ +// return; \ +// TQUObject o[2]; \ +// static_TQUType_##TYPE.set( o+1, param ); \ +// activate_signal( clist, o ); \ +// } +// #else +// #define ACTIVATE_SIGNAL_WITH_PARAM(FNAME,TYPE) \ +// void TQObject::FNAME( int signal, TYPE param ) \ +// { \ +// if ( !connections || tqsignalsBlocked() || signal < 0 ) \ +// return; \ +// TQConnectionList *clist = connections->at( signal ); \ +// if ( !clist ) \ +// return; \ +// TQUObject o[2]; \ +// static_TQUType_##TYPE.set( o+1, param ); \ +// activate_signal( clist, o ); \ +// } +// +// #endif +// // We don't want to duplicate too much text so... +// +// ACTIVATE_SIGNAL_WITH_PARAM( activate_signal, int ) +// ACTIVATE_SIGNAL_WITH_PARAM( activate_signal, double ) +// ACTIVATE_SIGNAL_WITH_PARAM( activate_signal, TQString ) +// ACTIVATE_SIGNAL_WITH_PARAM( activate_signal_bool, bool ) + +static void objSearch( TQObjectList *result, + TQObjectList *list, + const char *inheritsClass, + bool onlyWidgets, + const char *objName, + TQRegExp *rx, + bool recurse ) +{ + if ( !list || list->isEmpty() ) // nothing to search + return; + TQObject *obj = list->first(); + while ( obj ) { + bool ok = TRUE; + if ( onlyWidgets ) + ok = obj->isWidgetType(); + else if ( inheritsClass && !obj->inherits(inheritsClass) ) + ok = FALSE; + if ( ok ) { + if ( objName ) + ok = ( qstrcmp(objName,obj->name()) == 0 ); +#ifndef TQT_NO_REGEXP + else if ( rx ) + ok = ( rx->search(TQString::tqfromLatin1(obj->name())) != -1 ); +#endif + } + if ( ok ) // match! + result->append( obj ); + if ( recurse && !obj->childrenListObject().isEmpty() ) { + TQObjectList tqlist = obj->childrenListObject(); + objSearch( result, &tqlist, inheritsClass, + onlyWidgets, objName, rx, recurse ); + } + obj = list->next(); + } +} + +/*! + Searches the tqchildren and optionally grandtqchildren of this object, + and returns a list of those objects that are named or that match + \a objName and inherit \a inheritsClass. If \a inheritsClass is 0 + (the default), all classes match. If \a objName is 0 (the + default), all object names match. + + If \a regexpMatch is TRUE (the default), \a objName is a regular + expression that the objects's names must match. The syntax is that + of a TQRegExp. If \a regexpMatch is FALSE, \a objName is a string + and object names must match it exactly. + + Note that \a inheritsClass uses single inheritance from TQObject, + the way inherits() does. According to inherits(), TQMenuBar + inherits TQWidget but not TQMenuData. This does not quite match + reality, but is the best that can be done on the wide variety of + compilers TQt supports. + + Finally, if \a recursiveSearch is TRUE (the default), queryList() + searches \e{n}th-generation as well as first-generation tqchildren. + + If all this seems a bit complex for your needs, the simpler + child() function may be what you want. + + This somewhat contrived example disables all the buttons in this + window: + \code + TQObjectList *l = tqtopLevelWidget()->queryList( "TQButton" ); + TQObjectListIt it( *l ); // iterate over the buttons + TQObject *obj; + + while ( (obj = it.current()) != 0 ) { + // for each found object... + ++it; + ((TQButton*)obj)->setEnabled( FALSE ); + } + delete l; // delete the list, not the objects + \endcode + + The TQObjectList class is defined in the \c tqobjectlist.h header + file. + + \warning Delete the list as soon you have finished using it. The + list tqcontains pointers that may become invalid at almost any time + without notice (as soon as the user closes a window you may have + dangling pointers, for example). + + \sa child() childrenListObject(), tqparent(), inherits(), name(), TQRegExp +*/ + +TQObjectList *TQObject::queryList( const char *inheritsClass, + const char *objName, + bool regexpMatch, + bool recursiveSearch ) const +{ + TQObjectList *list = new TQObjectList; + TQ_CHECK_PTR( list ); + bool onlyWidgets = ( inheritsClass && qstrcmp(inheritsClass, "TQWidget") == 0 ); +#ifndef TQT_NO_REGEXP + if ( regexpMatch && objName ) { // regexp matching + TQRegExp rx(TQString::tqfromLatin1(objName)); + TQObjectList tqlist = childrenListObject(); + objSearch( list, &tqlist, inheritsClass, onlyWidgets, + 0, &rx, recursiveSearch ); + } else +#endif + { + TQObjectList tqlist = childrenListObject(); + objSearch( list, &tqlist, inheritsClass, onlyWidgets, + objName, 0, recursiveSearch ); + } + return list; +} + +/*! + Normlizes the signal or slot definition \a signalSlot by removing + unnecessary whitespace. +*/ + +TQCString TQObject::normalizeSignalSlot( const char *signalSlot ) +{ + if ( !signalSlot ) + return TQCString(); + return qt_rmWS( signalSlot ); +} + +TQMetaObject *TQObject::tqmetaObject() const { + return const_cast<TQMetaObject*>(static_cast<const TQMetaObject*>(metaObject())); +} + +// TQMetaObject* TQObject::tqstaticMetaObject() +// { +// return const_cast<TQMetaObject*>(static_cast<const TQMetaObject*>(&TQT_BASE_OBJECT_NAME::staticMetaObject)); +// } + +TQMetaObject* tqstaticMetaObject_helper(const QMetaObject* mobj) +{ + return const_cast<TQMetaObject*>(static_cast<const TQMetaObject*>(mobj)); +} + +/*! + This virtual function receives events to an object and should + return TRUE if the event \a e was recognized and processed. + + The event() function can be reimplemented to customize the + behavior of an object. + + \sa installEventFilter(), timerEvent(), TQApplication::sendEvent(), + TQApplication::postEvent(), TQWidget::event() +*/ + +bool TQObject::event( TQEvent *e ) +{ +#if defined(TQT_CHECK_NULL) + if ( e == 0 ) + qWarning( "TQObject::event: Null events are not permitted" ); +#endif +// if ( eventFilters ) { // try filters +// if ( activate_filters(e) ) // stopped by a filter +// return TRUE; +// } +// + switch ( e->type() ) { +// case TQEvent::Timer: +// timerEvent( (TQTimerEvent*)e ); +// return TRUE; +// +// case TQEvent::DeferredDelete: +// delete this; +// return TRUE; +// +// default: +// if ( e->type() >= TQEvent::User ) { +// customEvent( (TQCustomEvent*) e ); +// return TRUE; +// } +// break; +// } + + case TQEvent::ChildInserted: +// case TQEvent::ChildRemoved: // Causes a recursion loop if uncommented + childEvent( (TQChildEvent*)e ); + return TRUE; + + default: + return QObject::event(e); + } + + return FALSE; +} + +/*! + This event handler can be reimplemented in a subclass to receive + timer events for the object. + + TQTimer provides a higher-level interface to the timer + functionality, and also more general information about timers. + + \sa startTimer(), killTimer(), killTimers(), event() +*/ + +void TQObject::timerEvent( TQTimerEvent * ) +{ +} + + +/*! + This event handler can be reimplemented in a subclass to receive + child events. + + Child events are sent to objects when tqchildren are inserted or + removed. + + Note that events with TQEvent::type() \c TQEvent::ChildInserted are + posted (with \l{TQApplication::postEvent()}) to make sure that the + child's construction is completed before this function is called. + + If a child is removed immediately after it is inserted, the \c + ChildInserted event may be suppressed, but the \c ChildRemoved + event will always be sent. In such cases it is possible that there + will be a \c ChildRemoved event without a corresponding \c + ChildInserted event. + + If you change state based on \c ChildInserted events, call + TQWidget::constPolish(), or do + \code + TQApplication::sendPostedEvents( this, TQEvent::ChildInserted ); + \endcode + in functions that depend on the state. One notable example is + TQWidget::tqsizeHint(). + + \sa event(), TQChildEvent +*/ + +void TQObject::childEvent( TQChildEvent * ) +{ +} + +/*! + This event handler can be reimplemented in a subclass to receive + custom events. Custom events are user-defined events with a type + value at least as large as the "User" item of the \l TQEvent::Type + enum, and is typically a TQCustomEvent or TQCustomEvent subclass. + + \sa event(), TQCustomEvent +*/ +void TQObject::customEvent( TQCustomEvent * ) +{ +} + +/*! + Filters events if this object has been installed as an event + filter for the \a watched object. + + In your reimplementation of this function, if you want to filter + the event \a e, out, i.e. stop it being handled further, return + TRUE; otherwise return FALSE. + + Example: + \code + class MyMainWindow : public TQMainWindow + { + public: + MyMainWindow( TQWidget *tqparent = 0, const char *name = 0 ); + + protected: + bool eventFilter( TQObject *obj, TQEvent *ev ); + + private: + TQTextEdit *textEdit; + }; + + MyMainWindow::MyMainWindow( TQWidget *tqparent, const char *name ) + : TQMainWindow( tqparent, name ) + { + textEdit = new TQTextEdit( this ); + setCentralWidget( textEdit ); + textEdit->installEventFilter( this ); + } + + bool MyMainWindow::eventFilter( TQObject *obj, TQEvent *ev ) + { + if ( obj == textEdit ) { + if ( e->type() == TQEvent::KeyPress ) { + TQKeyEvent *k = (TQKeyEvent*)ev; + qDebug( "Ate key press %d", k->key() ); + return TRUE; + } else { + return FALSE; + } + } else { + // pass the event on to the tqparent class + return TQMainWindow::eventFilter( obj, ev ); + } + } + \endcode + + Notice in the example above that unhandled events are passed to + the base class's eventFilter() function, since the base class + might have reimplemented eventFilter() for its own internal + purposes. + + \warning If you delete the receiver object in this function, be + sure to return TRUE. Otherwise, TQt will forward the event to the + deleted object and the program might crash. + + \sa installEventFilter() +*/ + +bool TQObject::eventFilter( TQObject * /* watched */, TQEvent * /* e */ ) +{ + return FALSE; +} + +/*! + \relates TQObject + + Returns a pointer to the object named \a name that inherits \a + type and with a given \a tqparent. + + Returns 0 if there is no such child. + + \code + TQListBox *c = (TQListBox *) qt_tqfind_obj_child( myWidget, "TQListBox", + "my list box" ); + if ( c ) + c->insertItem( "another string" ); + \endcode +*/ + +void *qt_tqfind_obj_child( TQObject *tqparent, const char *type, const char *name ) +{ + if ( !tqparent->childrenListObject().isEmpty() ) { + TQObjectListIt it( tqparent->childrenListObject() ); + TQObject *obj; + while ( (obj = it.current()) ) { + ++it; + if ( qstrcmp(name,obj->name()) == 0 && + obj->inherits(type) ) + return obj; + } + } + return 0; +} + +/*! + Kills all timers that this object has started. + + \warning Using this function can cause hard-to-find bugs: it kills + timers started by sub- and superclasses as well as those started + by you, which is often not what you want. We recommend using a + TQTimer or perhaps killTimer(). + + \sa timerEvent(), startTimer(), killTimer() +*/ + +void TQObject::killTimers() +{ + QAbstractEventDispatcher *qed = QAbstractEventDispatcher::instance(); + qed->unregisterTimers(this); +} + +bool TQObject::isA( const char *classname ) const +{ + if (tqstrcmp(classname, metaObject()->className()) == 0) return true; + else { + TQString cn = metaObject()->className(); + if (cn[0] == 'T') + cn = cn.remove(0,1); + return (tqstrcmp(classname, cn.ascii()) == 0); + } +} + +bool TQObject::inherits( const char *classname ) const { + if (QObject::inherits(classname)) return true; + else { + TQString cn = classname; + if (cn[0] != 'T') + cn = cn.prepend('T'); + return QObject::inherits(cn.ascii()); + } +} + +#else // USE_QT4 + +/**************************************************************************** +** +** Implementation of TQObject class +** +** Created : 930418 +** +** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA. +** +** This file is part of the kernel module of the TQt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "tqvariant.h" +#include "tqapplication.h" +#include "tqobject.h" +#include "tqobjectlist.h" +#include "tqsignalslotimp.h" +#include "tqregexp.h" +#include "tqmetaobject.h" +#include <private/tqucom_p.h> +#include "tqucomextra_p.h" +#include "tqptrvector.h" + +#ifdef TQT_THREAD_SUPPORT +#include <tqmutex.h> +#include <private/tqmutexpool_p.h> +#endif + +#include <ctype.h> + + +#ifndef TQT_NO_USERDATA +class TQObjectPrivate : public TQPtrVector<TQObjectUserData> +{ +public: + TQObjectPrivate( uint s ) : TQPtrVector<TQObjectUserData>(s){ setAutoDelete( TRUE ); } +}; +#else +class TQObjectPrivate { +} +#endif + +class TQSenderObjectList : public TQObjectList, public TQShared +{ +public: + TQSenderObjectList() : currentSender( 0 ) { } + TQObject *currentSender; +}; + +/*! + \class TQt tqnamespace.h + + \brief The TQt class is a namespace for miscellaneous identifiers + that need to be global-like. + + \ingroup misc + + Normally, you can ignore this class. TQObject and a few other + classes inherit it, so all the identifiers in the TQt namespace are + normally usable without qualification. + + However, you may occasionally need to say \c TQt::black instead of + just \c black, particularly in static utility functions (such as + many class factories). + +*/ + +/*! + \enum Orientation + + This type is used to signify an object's orientation. + + \value Horizontal + \value Vertical + + Orientation is used with TQScrollBar for example. +*/ + + +/*! + \class TQObject tqobject.h + \brief The TQObject class is the base class of all TQt objects. + + \ingroup objectmodel + \mainclass + \reentrant + + TQObject is the heart of the \link object.html TQt object model. + \endlink The central feature in this model is a very powerful + mechanism for seamless object communication called \link + Q_SIGNALSandQ_SLOTS.html Q_SIGNALS and Q_SLOTS \endlink. You can + connect a signal to a slot with connect() and destroy the + connection with disconnect(). To avoid never ending notification + loops you can temporarily block Q_SIGNALS with blockSignals(). The + protected functions connectNotify() and disconnectNotify() make it + possible to track connections. + + TQObjects organize themselves in object trees. When you create a + TQObject with another object as tqparent, the object will + automatically do an insertChild() on the tqparent and thus show up + in the tqparent's childrenListObject() list. The tqparent takes ownership of the + object i.e. it will automatically delete its tqchildren in its + destructor. You can look for an object by name and optionally type + using child() or queryList(), and get the list of tree roots using + objectTrees(). + + Every object has an object name() and can report its className() + and whether it inherits() another class in the TQObject inheritance + hierarchy. + + When an object is deleted, it emits a destroyed() signal. You can + catch this signal to avoid dangling references to TQObjects. The + TQGuardedPtr class provides an elegant way to use this feature. + + TQObjects can receive events through event() and filter the events + of other objects. See installEventFilter() and eventFilter() for + details. A convenience handler, childEvent(), can be reimplemented + to catch child events. + + Last but not least, TQObject provides the basic timer support in + TQt; see TQTimer for high-level support for timers. + + Notice that the TQ_OBJECT macro is mandatory for any object that + implements Q_SIGNALS, Q_SLOTS or properties. You also need to run the + \link tqmoc.html tqmoc program (Meta Object Compiler) \endlink on the + source file. We strongly recommend the use of this macro in \e all + subclasses of TQObject regardless of whether or not they actually + use Q_SIGNALS, Q_SLOTS and properties, since failure to do so may lead + certain functions to exhibit undefined behaviour. + + All TQt widgets inherit TQObject. The convenience function + isWidgetType() returns whether an object is actually a widget. It + is much faster than inherits( "TQWidget" ). + + Some TQObject functions, e.g. childrenListObject(), objectTrees() and + queryList() return a TQObjectList. A TQObjectList is a TQPtrList of + TQObjects. TQObjectLists support the same operations as TQPtrLists + and have an iterator class, TQObjectListIt. +*/ + + +// +// Remove white space from TQT_SIGNAL and TQT_SLOT names. +// Internal for TQObject::connect() and TQObject::disconnect() +// + +static inline bool isIdentChar( char x ) +{ // Avoid bug in isalnum + return x == '_' || (x >= '0' && x <= '9') || + (x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z'); +} + +static inline bool isSpace( char x ) +{ +#if defined(TQ_CC_BOR) + /* + Borland C++ 4.5 has a weird isspace() bug. + isspace() usually works, but not here. + This implementation is sufficient for our internal use: rmWS() + */ + return (uchar) x <= 32; +#else + return isspace( (uchar) x ); +#endif +} + +static TQCString qt_rmWS( const char *s ) +{ + TQCString result( tqstrlen(s)+1 ); + char *d = result.data(); + char last = 0; + while( *s && isSpace(*s) ) // skip leading space + s++; + while ( *s ) { + while ( *s && !isSpace(*s) ) + last = *d++ = *s++; + while ( *s && isSpace(*s) ) + s++; + if ( *s && isIdentChar(*s) && isIdentChar(last) ) + last = *d++ = ' '; + } + *d = '\0'; + result.truncate( (int)(d - result.data()) ); + int void_pos = result.tqfind("(void)"); + if ( void_pos >= 0 ) + result.remove( void_pos+1, (uint)strlen("void") ); + return result; +} + + +// Event functions, implemented in qapplication_xxx.cpp + +int qStartTimer( int interval, TQObject *obj ); +bool qKillTimer( int id ); +bool qKillTimer( TQObject *obj ); + +static void removeObjFromList( TQObjectList *objList, const TQObject *obj, + bool single=FALSE ) +{ + if ( !objList ) + return; + int index = objList->tqfindRef( obj ); + while ( index >= 0 ) { + objList->remove(); + if ( single ) + return; + index = objList->tqfindNextRef( obj ); + } +} + + +/*! + \relates TQObject + + Returns a pointer to the object named \a name that inherits \a + type and with a given \a tqparent. + + Returns 0 if there is no such child. + + \code + TQListBox *c = (TQListBox *) qt_tqfind_obj_child( myWidget, "TQListBox", + "my list box" ); + if ( c ) + c->insertItem( "another string" ); + \endcode +*/ + +void *qt_tqfind_obj_child( TQObject *tqparent, const char *type, const char *name ) +{ + if ( !tqparent->childrenListObject().isEmpty() ) { + TQObjectListIt it( tqparent->childrenListObject() ); + TQObject *obj; + while ( (obj = it.current()) ) { + ++it; + if ( qstrcmp(name,obj->name()) == 0 && + obj->inherits(type) ) + return obj; + } + } + return 0; +} + + + +#ifndef TQT_NO_PRELIMINARY_SIGNAL_SPY +/* + Preliminary signal spy + */ +TQ_EXPORT TQObject* qt_preliminary_signal_spy = 0; +static TQObject* qt_spy_signal_sender = 0; + +static void qt_spy_signal( TQObject* sender, int signal, TQUObject* o ) +{ + TQMetaObject* mo = sender->tqmetaObject(); + while ( mo && signal - mo->signalOffset() < 0 ) + mo = mo->superClass(); + if ( !mo ) + return; + const TQMetaData* sigData = mo->signal( signal - mo->signalOffset() ); + if ( !sigData ) + return; + TQCString s; + mo = sender->tqmetaObject(); + while ( mo ) { + s.sprintf( "%s_%s", mo->className(), sigData->name ); + int slot = qt_preliminary_signal_spy->tqmetaObject()->tqfindSlot( s, TRUE ); + if ( slot >= 0 ) { +#ifdef TQT_THREAD_SUPPORT + // protect access to qt_spy_signal_sender + void * const address = &qt_spy_signal_sender; + TQMutexLocker locker( tqt_global_mutexpool ? + tqt_global_mutexpool->get( address ) : 0 ); +#endif // TQT_THREAD_SUPPORT + + TQObject* old_sender = qt_spy_signal_sender; + qt_spy_signal_sender = sender; + qt_preliminary_signal_spy->qt_invoke( slot, o ); + qt_spy_signal_sender = old_sender; + break; + } + mo = mo->superClass(); + } +} + +/* + End Preliminary signal spy + */ +#endif // TQT_NO_PRELIMINARY_SIGNAL_SPY + +static TQObjectList* object_trees = 0; + +#ifdef TQT_THREAD_SUPPORT +static TQMutex *obj_trees_mutex = 0; +#endif + +static void cleanup_object_trees() +{ + delete object_trees; + object_trees = 0; +#ifdef TQT_THREAD_SUPPORT + delete obj_trees_mutex; + obj_trees_mutex = 0; +#endif +} + +static void ensure_object_trees() +{ + object_trees = new TQObjectList; + qAddPostRoutine( cleanup_object_trees ); +} + +static void insert_tree( TQObject* obj ) +{ +#ifdef TQT_THREAD_SUPPORT + if ( !obj_trees_mutex ) + obj_trees_mutex = new TQMutex(); + TQMutexLocker locker( obj_trees_mutex ); +#endif + if ( !object_trees ) + ensure_object_trees(); + object_trees->insert(0, obj ); +} + +static void remove_tree( TQObject* obj ) +{ + if ( object_trees ) { +#ifdef TQT_THREAD_SUPPORT + TQMutexLocker locker( obj_trees_mutex ); +#endif + object_trees->removeRef( obj ); + } +} + + +/***************************************************************************** + TQObject member functions + *****************************************************************************/ + +/*! + Constructs an object called \a name with tqparent object, \a tqparent. + + The tqparent of an object may be viewed as the object's owner. For + instance, a \link TQDialog dialog box\endlink is the tqparent of the + "OK" and "Cancel" buttons it tqcontains. + + The destructor of a tqparent object destroys all child objects. + + Setting \a tqparent to 0 constructs an object with no tqparent. If the + object is a widget, it will become a top-level window. + + The object name is some text that can be used to identify a + TQObject. It's particularly useful in conjunction with \link + designer-manual.book <i>TQt Designer</i>\endlink. You can tqfind an + object by name (and type) using child(). To tqfind several objects + use queryList(). + + \sa tqparent(), name(), child(), queryList() +*/ + +TQObject::TQObject( TQObject *tqparent, const char *name ) + : + isSignal( FALSE ), // assume not a signal object + isWidget( FALSE ), // assume not a widget object + pendTimer( FALSE ), // no timers yet + blockSig( FALSE ), // not blocking Q_SIGNALS + wasDeleted( FALSE ), // double-delete catcher + isTree( FALSE ), // no tree yet + objname( name ? qstrdup(name) : 0 ), // set object name + parentObj( 0 ), // no tqparent yet. It is set by insertChild() + childObjects( 0 ), // no tqchildren yet + connections( 0 ), // no connections yet + senderObjects( 0 ), // no Q_SIGNALS connected yet + eventFilters( 0 ), // no filters installed + postedEvents( 0 ), // no events posted + d( 0 ) +{ + if ( !metaObj ) // will create object dict + (void) staticMetaObject(); + + if ( tqparent ) { // add object to tqparent + tqparent->insertChild( this ); + } else { + insert_tree( this ); + isTree = TRUE; + } +} + + +/*! + Destroys the object, deleting all its child objects. + + All Q_SIGNALS to and from the object are automatically disconnected. + + \warning All child objects are deleted. If any of these objects + are on the stack or global, sooner or later your program will + crash. We do not recommend holding pointers to child objects from + outside the tqparent. If you still do, the TQObject::destroyed() + signal gives you an opportunity to detect when an object is + destroyed. + + \warning Deleting a TQObject while pending events are waiting to be + delivered can cause a crash. You must not delete the TQObject + directly from a thread that is not the GUI thread. Use the + TQObject::deleteLater() method instead, which will cause the event + loop to delete the object after all pending events have been + delivered to the object. +*/ + +TQObject::~TQObject() +{ + if ( wasDeleted ) { +#if defined(TQT_DEBUG) + qWarning( "Double TQObject deletion detected." ); +#endif + return; + } + wasDeleted = 1; + blockSig = 0; // unblock Q_SIGNALS to keep TQGuardedPtr happy + emit destroyed( this ); + emit destroyed(); + if ( objname ) + delete [] (char*)objname; + objname = 0; + if ( pendTimer ) // might be pending timers + qKillTimer( this ); + TQApplication::removePostedEvents( this ); + if ( isTree ) { + remove_tree( this ); // remove from global root list + isTree = FALSE; + } + if ( parentObj ) // remove it from tqparent object + parentObj->removeChild( this ); + register TQObject *obj; + if ( senderObjects ) { // disconnect from senders + TQSenderObjectList *tmp = senderObjects; + senderObjects = 0; + obj = tmp->first(); + while ( obj ) { // for all senders... + obj->disconnect( this ); + obj = tmp->next(); + } + if ( tmp->deref() ) + delete tmp; + } + if ( connections ) { // disconnect tqreceivers + for ( int i = 0; i < (int) connections->size(); i++ ) { + TQConnectionList* clist = (*connections)[i]; // for each signal... + if ( !clist ) + continue; + register TQConnection *c; + TQConnectionListIt cit(*clist); + while( (c=cit.current()) ) { // for each connected slot... + ++cit; + if ( (obj=c->object()) ) + removeObjFromList( obj->senderObjects, this ); + } + } + delete connections; + connections = 0; + } + if ( eventFilters ) { + delete eventFilters; + eventFilters = 0; + } + if ( childObjects ) { // delete tqchildren objects + TQObjectListIt it(*childObjects); + while ( (obj=it.current()) ) { + ++it; + obj->parentObj = 0; + childObjects->removeRef( obj ); + delete obj; + } + delete childObjects; + } + + delete d; +} + + +/*! + \fn TQMetaObject *TQObject::tqmetaObject() const + + Returns a pointer to the meta object of this object. + + A meta object tqcontains information about a class that inherits + TQObject, e.g. class name, superclass name, properties, Q_SIGNALS and + Q_SLOTS. Every class that tqcontains the TQ_OBJECT macro will also have + a meta object. + + The meta object information is required by the signal/slot + connection mechanism and the property system. The functions isA() + and inherits() also make use of the meta object. +*/ + +/*! + \fn const char *TQObject::className() const + + Returns the class name of this object. + + This function is generated by the \link metaobjects.html Meta + Object Compiler. \endlink + + \warning This function will return the wrong name if the class + definition lacks the TQ_OBJECT macro. + + \sa name(), inherits(), isA(), isWidgetType() +*/ + +/*! + Returns TRUE if this object is an instance of the class \a clname; + otherwise returns FALSE. + + Example: + \code + TQTimer *t = new TQTimer; // TQTimer inherits TQObject + t->isA( "TQTimer" ); // returns TRUE + t->isA( "TQObject" ); // returns FALSE + \endcode + + \sa inherits() tqmetaObject() +*/ + +bool TQObject::isA( const char *clname ) const +{ + return qstrcmp( clname, className() ) == 0; +} + +/*! + Returns TRUE if this object is an instance of a class that + inherits \a clname, and \a clname inherits TQObject; otherwise + returns FALSE. + + A class is considered to inherit itself. + + Example: + \code + TQTimer *t = new TQTimer; // TQTimer inherits TQObject + t->inherits( "TQTimer" ); // returns TRUE + t->inherits( "TQObject" ); // returns TRUE + t->inherits( "TQButton" ); // returns FALSE + + // TQScrollBar inherits TQWidget and TQRangeControl + TQScrollBar *s = new TQScrollBar( 0 ); + s->inherits( "TQWidget" ); // returns TRUE + s->inherits( "TQRangeControl" ); // returns FALSE + \endcode + + (\l TQRangeControl is not a TQObject.) + + \sa isA(), tqmetaObject() +*/ + +bool TQObject::inherits( const char *clname ) const +{ + return tqmetaObject()->inherits( clname ); +} + +/*! + \internal + + Returns TRUE if \a object inherits \a superClass within + the meta object inheritance chain; otherwise returns FALSE. + + \sa inherits() +*/ +void *qt_inheritedBy( TQMetaObject *superClass, const TQObject *object ) +{ + if (!object) + return 0; + register TQMetaObject *mo = object->tqmetaObject(); + while (mo) { + if (mo == superClass) + return (void*)object; + mo = mo->superClass(); + } + return 0; +} + +/*! + \property TQObject::name + + \brief the name of this object + + You can tqfind an object by name (and type) using child(). You can + tqfind a set of objects with queryList(). + + The object name is set by the constructor or by the setName() + function. The object name is not very useful in the current + version of TQt, but will become increasingly important in the + future. + + If the object does not have a name, the name() function returns + "unnamed", so printf() (used in qDebug()) will not be asked to + output a null pointer. If you want a null pointer to be returned + for unnamed objects, you can call name( 0 ). + + \code + qDebug( "MyClass::setPrecision(): (%s) invalid precision %f", + name(), newPrecision ); + \endcode + + \sa className(), child(), queryList() +*/ + +const char * TQObject::name() const +{ + // If you change the name here, the builder will be broken + return objname ? objname : "unnamed"; +} + +/*! + Sets the object's name to \a name. +*/ +void TQObject::setName( const char *name ) +{ + if ( objname ) + delete [] (char*) objname; + objname = name ? qstrdup(name) : 0; +} + +/*! + \overload + + Returns the name of this object, or \a defaultName if the object + does not have a name. +*/ + +const char * TQObject::name( const char * defaultName ) const +{ + return objname ? objname : defaultName; +} + + +/*! + Searches the tqchildren and optionally grandtqchildren of this object, + and returns a child that is called \a objName that inherits \a + inheritsClass. If \a inheritsClass is 0 (the default), any class + matches. + + If \a recursiveSearch is TRUE (the default), child() performs a + depth-first search of the object's tqchildren. + + If there is no such object, this function returns 0. If there are + more than one, the first one found is retured; if you need all of + them, use queryList(). +*/ +TQObject* TQObject::child( const char *objName, const char *inheritsClass, + bool recursiveSearch ) +{ + if ( childrenListObject().isEmpty() ) + return 0; + + bool onlyWidgets = ( inheritsClass && qstrcmp( inheritsClass, "TQWidget" ) == 0 ); + TQObjectListIt it( childrenListObject() ); + TQObject *obj; + while ( ( obj = it.current() ) ) { + ++it; + if ( onlyWidgets ) { + if ( obj->isWidgetType() && ( !objName || qstrcmp( objName, obj->name() ) == 0 ) ) + break; + } else if ( ( !inheritsClass || obj->inherits(inheritsClass) ) && ( !objName || qstrcmp( objName, obj->name() ) == 0 ) ) + break; + if ( recursiveSearch && (obj = obj->child( objName, inheritsClass, recursiveSearch ) ) ) + break; + } + return obj; +} + +/*! + \fn bool TQObject::isWidgetType() const + + Returns TRUE if the object is a widget; otherwise returns FALSE. + + Calling this function is equivalent to calling + inherits("TQWidget"), except that it is much faster. +*/ + +/*! + \fn bool TQObject::highPriority() const + + Returns TRUE if the object is a high-priority object, or FALSE if + it is a standard-priority object. + + High-priority objects are placed first in TQObject's list of + tqchildren on the assumption that they will be referenced very + often. +*/ + + +/*! + This virtual function receives events to an object and should + return TRUE if the event \a e was recognized and processed. + + The event() function can be reimplemented to customize the + behavior of an object. + + \sa installEventFilter(), timerEvent(), TQApplication::sendEvent(), + TQApplication::postEvent(), TQWidget::event() +*/ + +bool TQObject::event( TQEvent *e ) +{ +#if defined(TQT_CHECK_NULL) + if ( e == 0 ) + qWarning( "TQObject::event: Null events are not permitted" ); +#endif + if ( eventFilters ) { // try filters + if ( activate_filters(e) ) // stopped by a filter + return TRUE; + } + + switch ( e->type() ) { + case TQEvent::Timer: + timerEvent( (TQTimerEvent*)e ); + return TRUE; + + case TQEvent::ChildInserted: + case TQEvent::ChildRemoved: + childEvent( (TQChildEvent*)e ); + return TRUE; + + case TQEvent::DeferredDelete: + delete this; + return TRUE; + + default: + if ( e->type() >= TQEvent::User ) { + customEvent( (TQCustomEvent*) e ); + return TRUE; + } + break; + } + return FALSE; +} + +/*! + This event handler can be reimplemented in a subclass to receive + timer events for the object. + + TQTimer provides a higher-level interface to the timer + functionality, and also more general information about timers. + + \sa startTimer(), killTimer(), killTimers(), event() +*/ + +void TQObject::timerEvent( TQTimerEvent * ) +{ +} + + +/*! + This event handler can be reimplemented in a subclass to receive + child events. + + Child events are sent to objects when tqchildren are inserted or + removed. + + Note that events with TQEvent::type() \c TQEvent::ChildInserted are + posted (with \l{TQApplication::postEvent()}) to make sure that the + child's construction is completed before this function is called. + + If a child is removed immediately after it is inserted, the \c + ChildInserted event may be suppressed, but the \c ChildRemoved + event will always be sent. In such cases it is possible that there + will be a \c ChildRemoved event without a corresponding \c + ChildInserted event. + + If you change state based on \c ChildInserted events, call + TQWidget::constPolish(), or do + \code + TQApplication::sendPostedEvents( this, TQEvent::ChildInserted ); + \endcode + in functions that depend on the state. One notable example is + TQWidget::tqsizeHint(). + + \sa event(), TQChildEvent +*/ + +void TQObject::childEvent( TQChildEvent * ) +{ +} + +/*! + This event handler can be reimplemented in a subclass to receive + custom events. Custom events are user-defined events with a type + value at least as large as the "User" item of the \l TQEvent::Type + enum, and is typically a TQCustomEvent or TQCustomEvent subclass. + + \sa event(), TQCustomEvent +*/ +void TQObject::customEvent( TQCustomEvent * ) +{ +} + + + +/*! + Filters events if this object has been installed as an event + filter for the \a watched object. + + In your reimplementation of this function, if you want to filter + the event \a e, out, i.e. stop it being handled further, return + TRUE; otherwise return FALSE. + + Example: + \code + class MyMainWindow : public TQMainWindow + { + public: + MyMainWindow( TQWidget *tqparent = 0, const char *name = 0 ); + + protected: + bool eventFilter( TQObject *obj, TQEvent *ev ); + + private: + TQTextEdit *textEdit; + }; + + MyMainWindow::MyMainWindow( TQWidget *tqparent, const char *name ) + : TQMainWindow( tqparent, name ) + { + textEdit = new TQTextEdit( this ); + setCentralWidget( textEdit ); + textEdit->installEventFilter( this ); + } + + bool MyMainWindow::eventFilter( TQObject *obj, TQEvent *ev ) + { + if ( obj == textEdit ) { + if ( e->type() == TQEvent::KeyPress ) { + TQKeyEvent *k = (TQKeyEvent*)ev; + qDebug( "Ate key press %d", k->key() ); + return TRUE; + } else { + return FALSE; + } + } else { + // pass the event on to the tqparent class + return TQMainWindow::eventFilter( obj, ev ); + } + } + \endcode + + Notice in the example above that unhandled events are passed to + the base class's eventFilter() function, since the base class + might have reimplemented eventFilter() for its own internal + purposes. + + \warning If you delete the receiver object in this function, be + sure to return TRUE. Otherwise, TQt will forward the event to the + deleted object and the program might crash. + + \sa installEventFilter() +*/ + +bool TQObject::eventFilter( TQObject * /* watched */, TQEvent * /* e */ ) +{ + return FALSE; +} + + +/*! + \internal + Activates all event filters for this object. + This function is normally called from TQObject::event() or TQWidget::event(). +*/ + +bool TQObject::activate_filters( TQEvent *e ) +{ + if ( !eventFilters ) // no event filter + return FALSE; + TQObjectListIt it( *eventFilters ); + register TQObject *obj = it.current(); + while ( obj ) { // send to all filters + ++it; // until one returns TRUE + if ( obj->eventFilter(this,e) ) { + return TRUE; + } + obj = it.current(); + } + return FALSE; // don't do anything with it +} + + +/*! + \fn bool TQObject::tqsignalsBlocked() const + + Returns TRUE if Q_SIGNALS are blocked; otherwise returns FALSE. + + Signals are not blocked by default. + + \sa blockSignals() +*/ + +/*! + Blocks Q_SIGNALS if \a block is TRUE, or unblocks Q_SIGNALS if \a + block is FALSE. + + Emitted Q_SIGNALS disappear into hyperspace if Q_SIGNALS are blocked. + Note that the destroyed() Q_SIGNALS will be emitted even if the Q_SIGNALS + for this object have been blocked. +*/ + +void TQObject::blockSignals( bool block ) +{ + blockSig = block; +} + + +// +// The timer flag hasTimer is set when startTimer is called. +// It is not reset when killing the timer because more than +// one timer might be active. +// + +/*! + Starts a timer and returns a timer identifier, or returns zero if + it could not start a timer. + + A timer event will occur every \a interval milliseconds until + killTimer() or killTimers() is called. If \a interval is 0, then + the timer event occurs once every time there are no more window + system events to process. + + The virtual timerEvent() function is called with the TQTimerEvent + event parameter class when a timer event occurs. Reimplement this + function to get timer events. + + If multiple timers are running, the TQTimerEvent::timerId() can be + used to tqfind out which timer was activated. + + Example: + \code + class MyObject : public TQObject + { + TQ_OBJECT + public: + MyObject( TQObject *tqparent = 0, const char *name = 0 ); + + protected: + void timerEvent( TQTimerEvent * ); + }; + + MyObject::MyObject( TQObject *tqparent, const char *name ) + : TQObject( tqparent, name ) + { + startTimer( 50 ); // 50-millisecond timer + startTimer( 1000 ); // 1-second timer + startTimer( 60000 ); // 1-minute timer + } + + void MyObject::timerEvent( TQTimerEvent *e ) + { + qDebug( "timer event, id %d", e->timerId() ); + } + \endcode + + Note that TQTimer's accuracy depends on the underlying operating + system and hardware. Most platforms support an accuracy of 20 ms; + some provide more. If TQt is unable to deliver the requested + number of timer clicks, it will silently discard some. + + The TQTimer class provides a high-level programming interface with + one-shot timers and timer Q_SIGNALS instead of events. + + \sa timerEvent(), killTimer(), killTimers(), TQEventLoop::awake(), + TQEventLoop::aboutToBlock() +*/ + +int TQObject::startTimer( int interval ) +{ + pendTimer = TRUE; // set timer flag + return qStartTimer( interval, (TQObject *)this ); +} + +/*! + Kills the timer with timer identifier, \a id. + + The timer identifier is returned by startTimer() when a timer + event is started. + + \sa timerEvent(), startTimer(), killTimers() +*/ + +void TQObject::killTimer( int id ) +{ + qKillTimer( id ); +} + +/*! + Kills all timers that this object has started. + + \warning Using this function can cause hard-to-tqfind bugs: it kills + timers started by sub- and superclasses as well as those started + by you, which is often not what you want. We recommend using a + TQTimer or perhaps killTimer(). + + \sa timerEvent(), startTimer(), killTimer() +*/ + +void TQObject::killTimers() +{ + qKillTimer( this ); +} + +static void objSearch( TQObjectList *result, + TQObjectList *list, + const char *inheritsClass, + bool onlyWidgets, + const char *objName, + TQRegExp *rx, + bool recurse ) +{ + if ( !list || list->isEmpty() ) // nothing to search + return; + TQObject *obj = list->first(); + while ( obj ) { + bool ok = TRUE; + if ( onlyWidgets ) + ok = obj->isWidgetType(); + else if ( inheritsClass && !obj->inherits(inheritsClass) ) + ok = FALSE; + if ( ok ) { + if ( objName ) + ok = ( qstrcmp(objName,obj->name()) == 0 ); +#ifndef TQT_NO_REGEXP + else if ( rx ) + ok = ( rx->search(TQString::tqfromLatin1(obj->name())) != -1 ); +#endif + } + if ( ok ) // match! + result->append( obj ); + if ( recurse && !obj->childrenListObject().isEmpty ) { + TQObjectList tqlist = obj->childrenListObject(); + objSearch( result, &tqlist, inheritsClass, + onlyWidgets, objName, rx, recurse ); + } + obj = list->next(); + } +} + +/*! + \fn TQObject *TQObject::tqparent() const + + Returns a pointer to the tqparent object. + + \sa childrenListObject() +*/ + +/*! + \fn const TQObjectList *TQObject::childrenListObject() const + + Returns a list of child objects, or 0 if this object has no + tqchildren. + + The TQObjectList class is defined in the \c tqobjectlist.h header + file. + + The first child added is the \link TQPtrList::first() first\endlink + object in the list and the last child added is the \link + TQPtrList::last() last\endlink object in the list, i.e. new + tqchildren are appended at the end. + + Note that the list order changes when TQWidget tqchildren are \link + TQWidget::raise() raised\endlink or \link TQWidget::lower() + lowered.\endlink A widget that is raised becomes the last object + in the list, and a widget that is lowered becomes the first object + in the list. + + \sa child(), queryList(), tqparent(), insertChild(), removeChild() +*/ + + +/*! + Returns a pointer to the list of all object trees (their root + objects), or 0 if there are no objects. + + The TQObjectList class is defined in the \c tqobjectlist.h header + file. + + The most recent root object created is the \link TQPtrList::first() + first\endlink object in the list and the first root object added + is the \link TQPtrList::last() last\endlink object in the list. + + \sa childrenListObject(), tqparent(), insertChild(), removeChild() +*/ +const TQObjectList *TQObject::objectTrees() +{ + return object_trees; +} + + +/*! + Searches the tqchildren and optionally grandtqchildren of this object, + and returns a list of those objects that are named or that match + \a objName and inherit \a inheritsClass. If \a inheritsClass is 0 + (the default), all classes match. If \a objName is 0 (the + default), all object names match. + + If \a regexpMatch is TRUE (the default), \a objName is a regular + expression that the objects's names must match. The syntax is that + of a TQRegExp. If \a regexpMatch is FALSE, \a objName is a string + and object names must match it exactly. + + Note that \a inheritsClass uses single inheritance from TQObject, + the way inherits() does. According to inherits(), TQMenuBar + inherits TQWidget but not TQMenuData. This does not quite match + reality, but is the best that can be done on the wide variety of + compilers TQt supports. + + Finally, if \a recursiveSearch is TRUE (the default), queryList() + searches \e{n}th-generation as well as first-generation tqchildren. + + If all this seems a bit complex for your needs, the simpler + child() function may be what you want. + + This somewhat contrived example disables all the buttons in this + window: + \code + TQObjectList *l = tqtopLevelWidget()->queryList( "TQButton" ); + TQObjectListIt it( *l ); // iterate over the buttons + TQObject *obj; + + while ( (obj = it.current()) != 0 ) { + // for each found object... + ++it; + ((TQButton*)obj)->setEnabled( FALSE ); + } + delete l; // delete the list, not the objects + \endcode + + The TQObjectList class is defined in the \c tqobjectlist.h header + file. + + \warning Delete the list as soon you have finished using it. The + list tqcontains pointers that may become invalid at almost any time + without notice (as soon as the user closes a window you may have + dangling pointers, for example). + + \sa child() childrenListObject(), tqparent(), inherits(), name(), TQRegExp +*/ + +TQObjectList *TQObject::queryList( const char *inheritsClass, + const char *objName, + bool regexpMatch, + bool recursiveSearch ) const +{ + TQObjectList *list = new TQObjectList; + TQ_CHECK_PTR( list ); + bool onlyWidgets = ( inheritsClass && qstrcmp(inheritsClass, "TQWidget") == 0 ); +#ifndef TQT_NO_REGEXP + if ( regexpMatch && objName ) { // regexp matching + TQRegExp rx(TQString::tqfromLatin1(objName)); + TQObjectList tqlist = childrenListObject(); + objSearch( list, &tqlist, inheritsClass, onlyWidgets, + 0, &rx, recursiveSearch ); + } else +#endif + { + TQObjectList tqlist = childrenListObject(); + objSearch( list, &tqlist, inheritsClass, onlyWidgets, + objName, 0, recursiveSearch ); + } + return list; +} + +/*! \internal + + Returns a list of objects/slot pairs that are connected to the + \a signal, or 0 if nothing is connected to it. +*/ + +TQConnectionList *TQObject::tqreceivers( const char* signal ) const +{ + if ( connections && signal ) { + if ( *signal == '2' ) { // tag == 2, i.e. signal + TQCString s = qt_rmWS( signal+1 ); + return tqreceivers( tqmetaObject()->tqfindSignal( (const char*)s, TRUE ) ); + } else { + return tqreceivers( tqmetaObject()->tqfindSignal(signal, TRUE ) ); + } + } + return 0; +} + +/*! \internal + + Returns a list of objects/slot pairs that are connected to the + signal, or 0 if nothing is connected to it. +*/ + +TQConnectionList *TQObject::tqreceivers( int signal ) const +{ +#ifndef TQT_NO_PRELIMINARY_SIGNAL_SPY + if ( qt_preliminary_signal_spy && signal >= 0 ) { + if ( !connections ) { + TQObject* that = (TQObject*) this; + that->connections = new TQSignalVec( signal+1 ); + that->connections->setAutoDelete( TRUE ); + } + if ( !connections->at( signal ) ) { + TQConnectionList* clist = new TQConnectionList; + clist->setAutoDelete( TRUE ); + connections->insert( signal, clist ); + return clist; + } + } +#endif + if ( connections && signal >= 0 ) + return connections->at( signal ); + return 0; +} + + +/*! + Inserts an object \a obj into the list of child objects. + + \warning This function cannot be used to make one widget the child + widget of another widget. Child widgets can only be created by + setting the tqparent widget in the constructor or by calling + TQWidget::reparent(). + + \sa removeChild(), TQWidget::reparent() +*/ + +void TQObject::insertChild( TQObject *obj ) +{ + if ( obj->isTree ) { + remove_tree( obj ); + obj->isTree = FALSE; + } + if ( obj->parentObj && obj->parentObj != this ) { +#if defined(TQT_CHECK_STATE) + if ( obj->parentObj != this && obj->isWidgetType() ) + qWarning( "TQObject::insertChild: Cannot reparent a widget, " + "use TQWidget::reparent() instead" ); +#endif + obj->parentObj->removeChild( obj ); + } + + if ( !childObjects ) { + childObjects = new TQObjectList; + TQ_CHECK_PTR( childObjects ); + } else if ( obj->parentObj == this ) { +#if defined(TQT_CHECK_STATE) + qWarning( "TQObject::insertChild: Object %s::%s already in list", + obj->className(), obj->name( "unnamed" ) ); +#endif + return; + } + obj->parentObj = this; + childObjects->append( obj ); + + TQChildEvent *e = new TQChildEvent( TQEvent::ChildInserted, obj ); + TQApplication::postEvent( this, e ); +} + +/*! + Removes the child object \a obj from the list of tqchildren. + + \warning This function will not remove a child widget from the + screen. It will only remove it from the tqparent widget's list of + tqchildren. + + \sa insertChild(), TQWidget::reparent() +*/ + +void TQObject::removeChild( TQObject *obj ) +{ + if ( childObjects && childObjects->removeRef(obj) ) { + obj->parentObj = 0; + if ( !obj->wasDeleted ) { + insert_tree( obj ); // it's a root object now + obj->isTree = TRUE; + } + if ( childObjects->isEmpty() ) { + delete childObjects; // last child removed + childObjects = 0; // reset tqchildren list + } + + // remove events must be sent, not posted!!! + TQChildEvent ce( TQEvent::ChildRemoved, obj ); + TQApplication::sendEvent( this, &ce ); + } +} + + +/*! + \fn void TQObject::installEventFilter( const TQObject *filterObj ) + + Installs an event filter \a filterObj on this object. For example: + \code + monitoredObj->installEventFilter( filterObj ); + \endcode + + An event filter is an object that receives all events that are + sent to this object. The filter can either stop the event or + forward it to this object. The event filter \a filterObj receives + events via its eventFilter() function. The eventFilter() function + must return TRUE if the event should be filtered, (i.e. stopped); + otherwise it must return FALSE. + + If multiple event filters are installed on a single object, the + filter that was installed last is activated first. + + Here's a \c KeyPressEater class that eats the key presses of its + monitored objects: + \code + class KeyPressEater : public TQObject + { + ... + protected: + bool eventFilter( TQObject *o, TQEvent *e ); + }; + + bool KeyPressEater::eventFilter( TQObject *o, TQEvent *e ) + { + if ( e->type() == TQEvent::KeyPress ) { + // special processing for key press + TQKeyEvent *k = (TQKeyEvent *)e; + qDebug( "Ate key press %d", k->key() ); + return TRUE; // eat event + } else { + // standard event processing + return FALSE; + } + } + \endcode + + And here's how to install it on two widgets: + \code + KeyPressEater *keyPressEater = new KeyPressEater( this ); + TQPushButton *pushButton = new TQPushButton( this ); + TQListView *listView = new TQListView( this ); + + pushButton->installEventFilter( keyPressEater ); + listView->installEventFilter( keyPressEater ); + \endcode + + The TQAccel class, for example, uses this technique to intercept + accelerator key presses. + + \warning If you delete the receiver object in your eventFilter() + function, be sure to return TRUE. If you return FALSE, TQt sends + the event to the deleted object and the program will crash. + + \sa removeEventFilter(), eventFilter(), event() +*/ + +void TQObject::installEventFilter( const TQObject *obj ) +{ + if ( !obj ) + return; + if ( eventFilters ) { + int c = eventFilters->tqfindRef( obj ); + if ( c >= 0 ) + eventFilters->take( c ); + disconnect( obj, TQT_SIGNAL(destroyed(TQObject*)), + this, TQT_SLOT(cleanupEventFilter(TQObject*)) ); + } else { + eventFilters = new TQObjectList; + TQ_CHECK_PTR( eventFilters ); + } + eventFilters->insert( 0, obj ); + connect( obj, TQT_SIGNAL(destroyed(TQObject*)), this, TQT_SLOT(cleanupEventFilter(TQObject*)) ); +} + +/*! + Removes an event filter object \a obj from this object. The + request is ignored if such an event filter has not been installed. + + All event filters for this object are automatically removed when + this object is destroyed. + + It is always safe to remove an event filter, even during event + filter activation (i.e. from the eventFilter() function). + + \sa installEventFilter(), eventFilter(), event() +*/ + +void TQObject::removeEventFilter( const TQObject *obj ) +{ + if ( eventFilters && eventFilters->removeRef(obj) ) { + if ( eventFilters->isEmpty() ) { // last event filter removed + delete eventFilters; + eventFilters = 0; // reset event filter list + } + disconnect( obj, TQT_SIGNAL(destroyed(TQObject*)), + this, TQT_SLOT(cleanupEventFilter(TQObject*)) ); + } +} + + +/***************************************************************************** + Signal connection management + *****************************************************************************/ + +#if defined(TQT_CHECK_RANGE) + +static bool check_signal_macro( const TQObject *sender, const char *signal, + const char *func, const char *op ) +{ + int sigcode = (int)(*signal) - '0'; + if ( sigcode != TQSIGNAL_CODE ) { + if ( sigcode == TQSLOT_CODE ) + qWarning( "TQObject::%s: Attempt to %s non-signal %s::%s", + func, op, sender->className(), signal+1 ); + else + qWarning( "TQObject::%s: Use the TQT_SIGNAL macro to %s %s::%s", + func, op, sender->className(), signal ); + return FALSE; + } + return TRUE; +} + +static bool check_member_code( int code, const TQObject *object, + const char *member, const char *func ) +{ + if ( code != TQSLOT_CODE && code != TQSIGNAL_CODE ) { + qWarning( "TQObject::%s: Use the TQT_SLOT or TQT_SIGNAL macro to " + "%s %s::%s", func, func, object->className(), member ); + return FALSE; + } + return TRUE; +} + +static void err_member_notfound( int code, const TQObject *object, + const char *member, const char *func ) +{ + const char *type = 0; + switch ( code ) { + case TQSLOT_CODE: type = "slot"; break; + case TQSIGNAL_CODE: type = "signal"; break; + } + if ( strchr(member,')') == 0 ) // common typing mistake + qWarning( "TQObject::%s: Parentheses expected, %s %s::%s", + func, type, object->className(), member ); + else + qWarning( "TQObject::%s: No such %s %s::%s", + func, type, object->className(), member ); +} + + +static void err_info_about_objects( const char * func, + const TQObject * sender, + const TQObject * receiver ) +{ + const char * a = sender->name(), * b = receiver->name(); + if ( a ) + qWarning( "TQObject::%s: (sender name: '%s')", func, a ); + if ( b ) + qWarning( "TQObject::%s: (receiver name: '%s')", func, b ); +} + +static void err_info_about_candidates( int code, + const TQMetaObject* mo, + const char* member, + const char *func ) +{ + if ( strstr(member,"const char*") ) { + // porting help + TQCString newname = member; + int p; + while ( (p=newname.tqfind("const char*")) >= 0 ) { + newname.tqreplace(p, 11, "const TQString&"); + } + const TQMetaData *rm = 0; + switch ( code ) { + case TQSLOT_CODE: + rm = mo->slot( mo->tqfindSlot( newname, TRUE ), TRUE ); + break; + case TQSIGNAL_CODE: + rm = mo->signal( mo->tqfindSignal( newname, TRUE ), TRUE ); + break; + } + if ( rm ) { + qWarning("TQObject::%s: Candidate: %s", func, newname.data()); + } + } +} + + +#endif // TQT_CHECK_RANGE + + +/*! + Returns a pointer to the object that sent the signal, if called in + a slot activated by a signal; otherwise it returns 0. The pointer + is valid only during the execution of the slot that calls this + function. + + The pointer returned by this function becomes invalid if the + sender is destroyed, or if the slot is disconnected from the + sender's signal. + + \warning This function violates the object-oriented principle of + modularity. However, getting access to the sender might be useful + when many Q_SIGNALS are connected to a single slot. The sender is + undefined if the slot is called as a normal C++ function. +*/ + +const TQObject *TQObject::sender() +{ +#ifndef TQT_NO_PRELIMINARY_SIGNAL_SPY + if ( this == qt_preliminary_signal_spy ) { +# ifdef TQT_THREAD_SUPPORT + // protect access to qt_spy_signal_sender + void * const address = &qt_spy_signal_sender; + TQMutexLocker locker( tqt_global_mutexpool ? + tqt_global_mutexpool->get( address ) : 0 ); +# endif // TQT_THREAD_SUPPORT + return qt_spy_signal_sender; + } +#endif + if ( senderObjects && + senderObjects->currentSender && + /* + * currentSender may be a dangling pointer in case the object + * it was pointing to was destructed from inside a slot. Thus + * verify it still is contained inside the senderObjects list + * which gets cleaned on both destruction and disconnect. + */ + + senderObjects->tqfindRef( senderObjects->currentSender ) != -1 ) + return senderObjects->currentSender; + return 0; +} + + +/*! + \fn void TQObject::connectNotify( const char *signal ) + + This virtual function is called when something has been connected + to \a signal in this object. + + \warning This function violates the object-oriented principle of + modularity. However, it might be useful when you need to perform + expensive initialization only if something is connected to a + signal. + + \sa connect(), disconnectNotify() +*/ + +void TQObject::connectNotify( const char * ) +{ +} + +/*! + \fn void TQObject::disconnectNotify( const char *signal ) + + This virtual function is called when something has been + disconnected from \a signal in this object. + + \warning This function violates the object-oriented principle of + modularity. However, it might be useful for optimizing access to + expensive resources. + + \sa disconnect(), connectNotify() +*/ + +void TQObject::disconnectNotify( const char * ) +{ +} + + +/*! + \fn bool TQObject::checkConnectArgs( const char *signal, const TQObject *receiver, const char *member ) + + Returns TRUE if the \a signal and the \a member arguments are + compatible; otherwise returns FALSE. (The \a receiver argument is + currently ignored.) + + \warning We recommend that you use the default implementation and + do not reimplement this function. + + \omit + TRUE: "signal(<anything>)", "member()" + TRUE: "signal(a,b,c)", "member(a,b,c)" + TRUE: "signal(a,b,c)", "member(a,b)", "member(a)" etc. + FALSE: "signal(const a)", "member(a)" + FALSE: "signal(a)", "member(const a)" + FALSE: "signal(a)", "member(b)" + FALSE: "signal(a)", "member(a,b)" + \endomit +*/ + +bool TQObject::checkConnectArgs( const char *signal, + const TQObject *, + const char *member ) +{ + const char *s1 = signal; + const char *s2 = member; + while ( *s1++ != '(' ) { } // scan to first '(' + while ( *s2++ != '(' ) { } + if ( *s2 == ')' || qstrcmp(s1,s2) == 0 ) // member has no args or + return TRUE; // exact match + int s1len = tqstrlen(s1); + int s2len = tqstrlen(s2); + if ( s2len < s1len && tqstrncmp(s1,s2,s2len-1)==0 && s1[s2len-1]==',' ) + return TRUE; // member has less args + return FALSE; +} + +/*! + Normlizes the signal or slot definition \a signalSlot by removing + unnecessary whitespace. +*/ + +TQCString TQObject::normalizeSignalSlot( const char *signalSlot ) +{ + if ( !signalSlot ) + return TQCString(); + return qt_rmWS( signalSlot ); +} + + + +/*! + \overload bool TQObject::connect( const TQObject *sender, const char *signal, const char *member ) const + + Connects \a signal from the \a sender object to this object's \a + member. + + Equivalent to: \c{TQObject::connect(sender, signal, this, member)}. + + \sa disconnect() +*/ + +/*! + Connects \a signal from the \a sender object to \a member in object + \a receiver, and returns TRUE if the connection succeeds; otherwise + returns FALSE. + + You must use the TQT_SIGNAL() and TQT_SLOT() macros when specifying the \a signal + and the \a member, for example: + \code + TQLabel *label = new TQLabel; + TQScrollBar *scroll = new TQScrollBar; + TQObject::connect( scroll, TQT_SIGNAL(valueChanged(int)), + label, TQT_SLOT(setNum(int)) ); + \endcode + + This example ensures that the label always displays the current + scroll bar value. Note that the signal and Q_SLOTS parameters must not + contain any variable names, only the type. E.g. the following would + not work and return FALSE: + TQObject::connect( scroll, TQT_SIGNAL(valueChanged(int v)), + label, TQT_SLOT(setNum(int v)) ); + + A signal can also be connected to another signal: + + \code + class MyWidget : public TQWidget + { + TQ_OBJECT + public: + MyWidget(); + + Q_SIGNALS: + void myUsefulSignal(); + + private: + TQPushButton *aButton; + }; + + MyWidget::MyWidget() + { + aButton = new TQPushButton( this ); + connect( aButton, TQT_SIGNAL(clicked()), TQT_SIGNAL(myUsefulSignal()) ); + } + \endcode + + In this example, the MyWidget constructor relays a signal from a + private member variable, and makes it available under a name that + relates to MyWidget. + + A signal can be connected to many Q_SLOTS and Q_SIGNALS. Many Q_SIGNALS + can be connected to one slot. + + If a signal is connected to several Q_SLOTS, the Q_SLOTS are activated + in an arbitrary order when the signal is emitted. + + The function returns TRUE if it successfully connects the signal + to the slot. It will return FALSE if it cannot create the + connection, for example, if TQObject is unable to verify the + existence of either \a signal or \a member, or if their signatures + aren't compatible. + + A signal is emitted for \e{every} connection you make, so if you + duplicate a connection, two Q_SIGNALS will be emitted. You can + always break a connection using \c{disconnect()}. + + \sa disconnect() +*/ + +bool TQObject::connect( const TQObject *sender, const char *signal, + const TQObject *receiver, const char *member ) +{ +#if defined(TQT_CHECK_NULL) + if ( sender == 0 || receiver == 0 || signal == 0 || member == 0 ) { + qWarning( "TQObject::connect: Cannot connect %s::%s to %s::%s", + sender ? sender->className() : "(null)", + signal ? signal+1 : "(null)", + receiver ? receiver->className() : "(null)", + member ? member+1 : "(null)" ); + return FALSE; + } +#endif + TQMetaObject *smeta = sender->tqmetaObject(); + +#if defined(TQT_CHECK_RANGE) + if ( !check_signal_macro( sender, signal, "connect", "bind" ) ) + return FALSE; +#endif + TQCString nw_signal(signal); // Assume already normalized + ++signal; // skip member type code + + int signal_index = smeta->tqfindSignal( signal, TRUE ); + if ( signal_index < 0 ) { // normalize and retry + nw_signal = qt_rmWS( signal-1 ); // remove whitespace + signal = nw_signal.data()+1; // skip member type code + signal_index = smeta->tqfindSignal( signal, TRUE ); + } + + if ( signal_index < 0 ) { // no such signal +#if defined(TQT_CHECK_RANGE) + err_member_notfound( TQSIGNAL_CODE, sender, signal, "connect" ); + err_info_about_candidates( TQSIGNAL_CODE, smeta, signal, "connect" ); + err_info_about_objects( "connect", sender, receiver ); +#endif + return FALSE; + } + const TQMetaData *sm = smeta->signal( signal_index, TRUE ); + signal = sm->name; // use name from meta object + + int membcode = member[0] - '0'; // get member code + + TQObject *s = (TQObject *)sender; // we need to change them + TQObject *r = (TQObject *)receiver; // internally + +#if defined(TQT_CHECK_RANGE) + if ( !check_member_code( membcode, r, member, "connect" ) ) + return FALSE; +#endif + member++; // skip code + + TQCString nw_member ; + TQMetaObject *rmeta = r->tqmetaObject(); + int member_index = -1; + switch ( membcode ) { // get receiver member + case TQSLOT_CODE: + member_index = rmeta->tqfindSlot( member, TRUE ); + if ( member_index < 0 ) { // normalize and retry + nw_member = qt_rmWS(member); // remove whitespace + member = nw_member; + member_index = rmeta->tqfindSlot( member, TRUE ); + } + break; + case TQSIGNAL_CODE: + member_index = rmeta->tqfindSignal( member, TRUE ); + if ( member_index < 0 ) { // normalize and retry + nw_member = qt_rmWS(member); // remove whitespace + member = nw_member; + member_index = rmeta->tqfindSignal( member, TRUE ); + } + break; + } + if ( member_index < 0 ) { +#if defined(TQT_CHECK_RANGE) + err_member_notfound( membcode, r, member, "connect" ); + err_info_about_candidates( membcode, rmeta, member, "connect" ); + err_info_about_objects( "connect", sender, receiver ); +#endif + return FALSE; + } +#if defined(TQT_CHECK_RANGE) + if ( !s->checkConnectArgs(signal,receiver,member) ) { + qWarning( "TQObject::connect: Incompatible sender/receiver arguments" + "\n\t%s::%s --> %s::%s", + s->className(), signal, + r->className(), member ); + return FALSE; + } else { + const TQMetaData *rm = membcode == TQSLOT_CODE ? + rmeta->slot( member_index, TRUE ) : + rmeta->signal( member_index, TRUE ); + if ( rm ) { + int si = 0; + int ri = 0; + while ( si < sm->method->count && ri < rm->method->count ) { + if ( sm->method->parameters[si].inOut == TQUParameter::Out ) + si++; + else if ( rm->method->parameters[ri].inOut == TQUParameter::Out ) + ri++; + else if ( !TQUType::isEqual( sm->method->parameters[si++].type, + rm->method->parameters[ri++].type ) ) { + if ( ( TQUType::isEqual( sm->method->parameters[si-1].type, &static_TQUType_ptr ) + && TQUType::isEqual( rm->method->parameters[ri-1].type, &static_TQUType_varptr ) ) + || ( TQUType::isEqual( sm->method->parameters[si-1].type, &static_TQUType_varptr ) + && TQUType::isEqual( rm->method->parameters[ri-1].type, &static_TQUType_ptr ) ) ) + continue; // varptr got introduced in 3.1 and is binary compatible with ptr + qWarning( "TQObject::connect: Incompatible sender/receiver marshalling" + "\n\t%s::%s --> %s::%s", + s->className(), signal, + r->className(), member ); + return FALSE; + } + } + } + } +#endif + connectInternal( sender, signal_index, receiver, membcode, member_index ); + s->connectNotify( nw_signal ); + return TRUE; +} + +/*! \internal */ + +void TQObject::connectInternal( const TQObject *sender, int signal_index, const TQObject *receiver, + int membcode, int member_index ) +{ + TQObject *s = (TQObject*)sender; + TQObject *r = (TQObject*)receiver; + + if ( !s->connections ) { // create connections lookup table + s->connections = new TQSignalVec( signal_index+1 ); + TQ_CHECK_PTR( s->connections ); + s->connections->setAutoDelete( TRUE ); + } + + TQConnectionList *clist = s->connections->at( signal_index ); + if ( !clist ) { // create receiver list + clist = new TQConnectionList; + TQ_CHECK_PTR( clist ); + clist->setAutoDelete( TRUE ); + s->connections->insert( signal_index, clist ); + } + + TQMetaObject *rmeta = r->tqmetaObject(); + const TQMetaData *rm = 0; + + switch ( membcode ) { // get receiver member + case TQSLOT_CODE: + rm = rmeta->slot( member_index, TRUE ); + break; + case TQSIGNAL_CODE: + rm = rmeta->signal( member_index, TRUE ); + break; + } + + TQConnection *c = new TQConnection( r, member_index, rm ? rm->name : "qt_invoke", membcode ); + TQ_CHECK_PTR( c ); + clist->append( c ); + if ( !r->senderObjects ) // create list of senders + r->senderObjects = new TQSenderObjectList; + r->senderObjects->append( s ); // add sender to list +} + + +/*! + \overload bool TQObject::disconnect( const char *signal, const TQObject *receiver, const char *member ) + + Disconnects \a signal from \a member of \a receiver. + + A signal-slot connection is removed when either of the objects + involved are destroyed. +*/ + +/*! + \overload bool TQObject::disconnect( const TQObject *receiver, const char *member ) + + Disconnects all Q_SIGNALS in this object from \a receiver's \a + member. + + A signal-slot connection is removed when either of the objects + involved are destroyed. +*/ + +/*! + Disconnects \a signal in object \a sender from \a member in object + \a receiver. + + A signal-slot connection is removed when either of the objects + involved are destroyed. + + disconnect() is typically used in three ways, as the following + examples demonstrate. + \list 1 + \i Disconnect everything connected to an object's Q_SIGNALS: + \code + disconnect( myObject, 0, 0, 0 ); + \endcode + equivalent to the non-static overloaded function + \code + myObject->disconnect(); + \endcode + \i Disconnect everything connected to a specific signal: + \code + disconnect( myObject, TQT_SIGNAL(mySignal()), 0, 0 ); + \endcode + equivalent to the non-static overloaded function + \code + myObject->disconnect( TQT_SIGNAL(mySignal()) ); + \endcode + \i Disconnect a specific receiver: + \code + disconnect( myObject, 0, myReceiver, 0 ); + \endcode + equivalent to the non-static overloaded function + \code + myObject->disconnect( myReceiver ); + \endcode + \endlist + + 0 may be used as a wildcard, meaning "any signal", "any receiving + object", or "any slot in the receiving object", respectively. + + The \a sender may never be 0. (You cannot disconnect Q_SIGNALS from + more than one object in a single call.) + + If \a signal is 0, it disconnects \a receiver and \a member from + any signal. If not, only the specified signal is disconnected. + + If \a receiver is 0, it disconnects anything connected to \a + signal. If not, Q_SLOTS in objects other than \a receiver are not + disconnected. + + If \a member is 0, it disconnects anything that is connected to \a + receiver. If not, only Q_SLOTS named \a member will be disconnected, + and all other Q_SLOTS are left alone. The \a member must be 0 if \a + receiver is left out, so you cannot disconnect a + specifically-named slot on all objects. + + \sa connect() +*/ + +bool TQObject::disconnect( const TQObject *sender, const char *signal, + const TQObject *receiver, const char *member ) +{ +#if defined(TQT_CHECK_NULL) + if ( sender == 0 || (receiver == 0 && member != 0) ) { + qWarning( "TQObject::disconnect: Unexpected null parameter" ); + return FALSE; + } +#endif + if ( !sender->connections ) // no connected Q_SIGNALS + return FALSE; + TQObject *s = (TQObject *)sender; + TQObject *r = (TQObject *)receiver; + int member_index = -1; + int membcode = -1; + TQCString nw_member; + if ( member ) { + membcode = member[0] - '0'; +#if defined(TQT_CHECK_RANGE) + if ( !check_member_code( membcode, r, member, "disconnect" ) ) + return FALSE; +#endif + ++member; + TQMetaObject *rmeta = r->tqmetaObject(); + + switch ( membcode ) { // get receiver member + case TQSLOT_CODE: + member_index = rmeta->tqfindSlot( member, TRUE ); + if ( member_index < 0 ) { // normalize and retry + nw_member = qt_rmWS(member); // remove whitespace + member = nw_member; + member_index = rmeta->tqfindSlot( member, TRUE ); + } + break; + case TQSIGNAL_CODE: + member_index = rmeta->tqfindSignal( member, TRUE ); + if ( member_index < 0 ) { // normalize and retry + nw_member = qt_rmWS(member); // remove whitespace + member = nw_member; + member_index = rmeta->tqfindSignal( member, TRUE ); + } + break; + } + if ( member_index < 0 ) { // no such member +#if defined(TQT_CHECK_RANGE) + err_member_notfound( membcode, r, member, "disconnect" ); + err_info_about_candidates( membcode, rmeta, member, "connect" ); + err_info_about_objects( "disconnect", sender, receiver ); +#endif + return FALSE; + } + } + + if ( signal == 0 ) { // any/all Q_SIGNALS + if ( disconnectInternal( s, -1, r, membcode, member_index ) ) + s->disconnectNotify( 0 ); + else + return FALSE; + } else { // specific signal +#if defined(TQT_CHECK_RANGE) + if ( !check_signal_macro( s, signal, "disconnect", "unbind" ) ) + return FALSE; +#endif + TQCString nw_signal(signal); // Assume already normalized + ++signal; // skip member type code + + TQMetaObject *smeta = s->tqmetaObject(); + if ( !smeta ) // no meta object + return FALSE; + int signal_index = smeta->tqfindSignal( signal, TRUE ); + if ( signal_index < 0 ) { // normalize and retry + nw_signal = qt_rmWS( signal-1 ); // remove whitespace + signal = nw_signal.data()+1; // skip member type code + signal_index = smeta->tqfindSignal( signal, TRUE ); + } + if ( signal_index < 0 ) { +#if defined(TQT_CHECK_RANGE) + qWarning( "TQObject::disconnect: No such signal %s::%s", + s->className(), signal ); +#endif + return FALSE; + } + + /* compatibility and safety: If a receiver has several Q_SLOTS + * with the same name, disconnect them all*/ + bool res = FALSE; + if ( membcode == TQSLOT_CODE && r ) { + TQMetaObject * rmeta = r->tqmetaObject(); + do { + int mi = rmeta->tqfindSlot( member ); + if ( mi != -1 ) + res |= disconnectInternal( s, signal_index, r, membcode, mi ); + } while ( (rmeta = rmeta->superClass()) ); + } else { + res = disconnectInternal( s, signal_index, r, membcode, member_index ); + } + if ( res ) + s->disconnectNotify( nw_signal ); + return res; + } + return TRUE; +} + +/*! \internal */ + +bool TQObject::disconnectInternal( const TQObject *sender, int signal_index, + const TQObject *receiver, int membcode, int member_index ) +{ + TQObject *s = (TQObject*)sender; + TQObject *r = (TQObject*)receiver; + + if ( !s->connections ) + return FALSE; + + bool success = FALSE; + TQConnectionList *clist; + register TQConnection *c; + if ( signal_index == -1 ) { + for ( int i = 0; i < (int) s->connections->size(); i++ ) { + clist = (*s->connections)[i]; // for all Q_SIGNALS... + if ( !clist ) + continue; + c = clist->first(); + while ( c ) { // for all tqreceivers... + if ( r == 0 ) { // remove all tqreceivers + removeObjFromList( c->object()->senderObjects, s ); + success = TRUE; + c = clist->next(); + } else if ( r == c->object() && + ( member_index == -1 || + member_index == c->member() && c->memberType() == membcode ) ) { + removeObjFromList( c->object()->senderObjects, s, TRUE ); + success = TRUE; + clist->remove(); + c = clist->current(); + } else { + c = clist->next(); + } + } + if ( r == 0 ) // disconnect all tqreceivers + s->connections->insert( i, 0 ); + } + } else { + clist = s->connections->at( signal_index ); + if ( !clist ) + return FALSE; + + c = clist->first(); + while ( c ) { // for all tqreceivers... + if ( r == 0 ) { // remove all tqreceivers + removeObjFromList( c->object()->senderObjects, s, TRUE ); + success = TRUE; + c = clist->next(); + } else if ( r == c->object() && + ( member_index == -1 || + member_index == c->member() && c->memberType() == membcode ) ) { + removeObjFromList( c->object()->senderObjects, s, TRUE ); + success = TRUE; + clist->remove(); + c = clist->current(); + } else { + c = clist->next(); + } + } + if ( r == 0 ) // disconnect all tqreceivers + s->connections->insert( signal_index, 0 ); + } + return success; +} + +/*! + \fn TQObject::destroyed() + + This signal is emitted when the object is being destroyed. + + Note that the signal is emitted by the TQObject destructor, so + the object's virtual table is already degenerated at this point, + and it is not safe to call any functions on the object emitting + the signal. This signal can not be blocked. + + All the objects's tqchildren are destroyed immediately after this + signal is emitted. +*/ + +/*! + \overload TQObject::destroyed( TQObject* obj) + + This signal is emitted immediately before the object \a obj is + destroyed, and can not be blocked. + + All the objects's tqchildren are destroyed immediately after this + signal is emitted. +*/ + +/*! + Performs a deferred deletion of this object. + + Instead of an immediate deletion this function schedules a + deferred delete event for processing when TQt returns to the main + event loop. +*/ +void TQObject::deleteLater() +{ + TQApplication::postEvent( this, new TQEvent( TQEvent::DeferredDelete) ); +} + +/*! + This slot is connected to the destroyed() signal of other objects + that have installed event filters on this object. When the other + object, \a obj, is destroyed, we want to remove its event filter. +*/ + +void TQObject::cleanupEventFilter(TQObject* obj) +{ + removeEventFilter( obj ); +} + + +/*! + \fn TQString TQObject::tr( const char *sourceText, const char * comment ) + \reentrant + + Returns a translated version of \a sourceText, or \a sourceText + itself if there is no appropriate translated version. The + translation context is TQObject with \a comment (0 by default). + All TQObject subclasses using the TQ_OBJECT macro automatically have + a reimplementation of this function with the subclass name as + context. + + \warning This method is reentrant only if all translators are + installed \e before calling this method. Installing or removing + translators while performing translations is not supported. Doing + so will probably result in crashes or other undesirable behavior. + + \sa trUtf8() TQApplication::translate() + \link i18n.html Internationalization with TQt\endlink +*/ + +/*! + \fn TQString TQObject::trUtf8( const char *sourceText, + const char *comment ) + \reentrant + + Returns a translated version of \a sourceText, or + TQString::fromUtf8(\a sourceText) if there is no appropriate + version. It is otherwise identical to tr(\a sourceText, \a + comment). + + \warning This method is reentrant only if all translators are + installed \e before calling this method. Installing or removing + translators while performing translations is not supported. Doing + so will probably result in crashes or other undesirable behavior. + + \sa tr() TQApplication::translate() +*/ + +static TQMetaObjectCleanUp cleanUp_TQt = TQMetaObjectCleanUp( "TQObject", &TQObject::staticMetaObject ); + +TQMetaObject* TQObject::staticTQtMetaObject() +{ + static TQMetaObject* qtMetaObject = 0; + if ( qtMetaObject ) + return qtMetaObject; + +#ifndef TQT_NO_PROPERTIES + static const TQMetaEnum::Item enum_0[] = { + { "AlignLeft", (int) TQt::AlignLeft }, + { "AlignRight", (int) TQt::AlignRight }, + { "AlignHCenter", (int) TQt::AlignHCenter }, + { "AlignTop", (int) TQt::AlignTop }, + { "AlignBottom", (int) TQt::AlignBottom }, + { "AlignVCenter", (int) TQt::AlignVCenter }, + { "AlignCenter", (int) TQt::AlignCenter }, + { "AlignAuto", (int) TQt::AlignAuto }, + { "AlignJustify", (int) TQt::AlignJustify }, + { "WordBreak", (int) TQt::WordBreak } + }; + + static const TQMetaEnum::Item enum_1[] = { + { "Horizontal", (int) Qt::Horizontal }, + { "Vertical", (int) Qt::Vertical } + }; + + static const TQMetaEnum::Item enum_2[] = { + { "PlainText", (int) TQt::PlainText }, + { "RichText", (int) TQt::RichText }, + { "AutoText", (int) TQt::AutoText }, + { "LogText", (int) TQt::LogText } + }; + + static const TQMetaEnum::Item enum_3[] = { + { "NoBackground", (int) TQt::NoBackground }, + { "PaletteForeground", (int) TQt::PaletteForeground }, + { "PaletteButton", (int) TQt::PaletteButton }, + { "PaletteLight", (int) TQt::PaletteLight }, + { "PaletteMidlight", (int) TQt::PaletteMidlight }, + { "PaletteDark", (int) TQt::PaletteDark }, + { "PaletteMid", (int) TQt::PaletteMid }, + { "PaletteText", (int) TQt::PaletteText }, + { "PaletteBrightText", (int) TQt::PaletteBrightText }, + { "PaletteBase", (int) TQt::PaletteBase }, + { "PaletteBackground", (int) TQt::PaletteBackground }, + { "PaletteShadow", (int) TQt::PaletteShadow }, + { "PaletteHighlight", (int) TQt::PaletteHighlight }, + { "PaletteHighlightedText", (int) TQt::PaletteHighlightedText }, + { "PaletteButtonText", (int) TQt::PaletteButtonText }, + { "PaletteLink", (int) TQt::PaletteLink }, + { "PaletteLinkVisited", (int) TQt::PaletteLinkVisited } + }; + + static const TQMetaEnum::Item enum_4[] = { + { "TextDate", (int) TQt::TextDate }, + { "ISODate", (int) TQt::ISODate }, + { "LocalDate", (int) TQt::LocalDate } + }; + + + static const TQMetaEnum enum_tbl[] = { + { "Alignment", 10, enum_0, TRUE }, + { "Orientation", 2, enum_1, FALSE }, + { "TextFormat", 4, enum_2, FALSE }, + { "BackgroundMode", 17, enum_3, FALSE }, + { "DateFormat", 3, enum_4, FALSE } + }; +#endif + + qtMetaObject = new TQMetaObject( "TQt", 0, + 0, 0, + 0, 0, +#ifndef TQT_NO_PROPERTIES + 0, 0, + enum_tbl, 5, +#endif + 0, 0 ); + cleanUp_TQt.setMetaObject( qtMetaObject ); + + return qtMetaObject; +} + +/*! + \internal + + Signal activation with the most frequently used parameter/argument + types. All other combinations are generated by the meta object + compiler. + */ +void TQObject::activate_signal( int signal ) +{ +#ifndef TQT_NO_PRELIMINARY_SIGNAL_SPY + if ( qt_preliminary_signal_spy ) { + if ( !tqsignalsBlocked() && signal >= 0 && + ( !connections || !connections->at( signal ) ) ) { + TQUObject o[1]; + qt_spy_signal( this, signal, o ); + return; + } + } +#endif + + if ( !connections || tqsignalsBlocked() || signal < 0 ) + return; + TQConnectionList *clist = connections->at( signal ); + if ( !clist ) + return; + TQUObject o[1]; + activate_signal( clist, o ); +} + +/*! \internal */ + +void TQObject::activate_signal( TQConnectionList *clist, TQUObject *o ) +{ + if ( !clist ) + return; + +#ifndef TQT_NO_PRELIMINARY_SIGNAL_SPY + if ( qt_preliminary_signal_spy ) + qt_spy_signal( this, connections->tqfindRef( clist), o ); +#endif + + TQObject *object; + TQSenderObjectList* sol; + TQObject* oldSender = 0; + TQConnection *c; + if ( clist->count() == 1 ) { // save iterator + c = clist->first(); + object = c->object(); + sol = object->senderObjects; + if ( sol ) { + oldSender = sol->currentSender; + sol->ref(); + sol->currentSender = this; + } + if ( c->memberType() == TQSIGNAL_CODE ) + object->qt_emit( c->member(), o ); + else + object->qt_invoke( c->member(), o ); + if ( sol ) { + sol->currentSender = oldSender; + if ( sol->deref() ) + delete sol; + } + } else { + TQConnection *cd = 0; + TQConnectionListIt it(*clist); + while ( (c=it.current()) ) { + ++it; + if ( c == cd ) + continue; + cd = c; + object = c->object(); + sol = object->senderObjects; + if ( sol ) { + oldSender = sol->currentSender; + sol->ref(); + sol->currentSender = this; + } + if ( c->memberType() == TQSIGNAL_CODE ) + object->qt_emit( c->member(), o ); + else + object->qt_invoke( c->member(), o ); + if (sol ) { + sol->currentSender = oldSender; + if ( sol->deref() ) + delete sol; + } + } + } +} + +/*! + \overload void TQObject::activate_signal( int signal, int ) +*/ + +/*! + \overload void TQObject::activate_signal( int signal, double ) +*/ + +/*! + \overload void TQObject::activate_signal( int signal, TQString ) +*/ + +/*! + \fn void TQObject::activate_signal_bool( int signal, bool ) + \internal + + Like the above functions, but since bool is sometimes + only a typedef it cannot be a simple overload. +*/ + +#ifndef TQT_NO_PRELIMINARY_SIGNAL_SPY +#define ACTIVATE_SIGNAL_WITH_PARAM(FNAME,TYPE) \ +void TQObject::FNAME( int signal, TYPE param ) \ +{ \ + if ( qt_preliminary_signal_spy ) { \ + if ( !tqsignalsBlocked() && signal >= 0 && \ + ( !connections || !connections->at( signal ) ) ) { \ + TQUObject o[2]; \ + static_TQUType_##TYPE.set( o+1, param ); \ + qt_spy_signal( this, signal, o ); \ + return; \ + } \ + } \ + if ( !connections || tqsignalsBlocked() || signal < 0 ) \ + return; \ + TQConnectionList *clist = connections->at( signal ); \ + if ( !clist ) \ + return; \ + TQUObject o[2]; \ + static_TQUType_##TYPE.set( o+1, param ); \ + activate_signal( clist, o ); \ +} +#else +#define ACTIVATE_SIGNAL_WITH_PARAM(FNAME,TYPE) \ +void TQObject::FNAME( int signal, TYPE param ) \ +{ \ + if ( !connections || tqsignalsBlocked() || signal < 0 ) \ + return; \ + TQConnectionList *clist = connections->at( signal ); \ + if ( !clist ) \ + return; \ + TQUObject o[2]; \ + static_TQUType_##TYPE.set( o+1, param ); \ + activate_signal( clist, o ); \ +} + +#endif +// We don't want to duplicate too much text so... + +ACTIVATE_SIGNAL_WITH_PARAM( activate_signal, int ) +ACTIVATE_SIGNAL_WITH_PARAM( activate_signal, double ) +ACTIVATE_SIGNAL_WITH_PARAM( activate_signal, TQString ) +ACTIVATE_SIGNAL_WITH_PARAM( activate_signal_bool, bool ) + + +/***************************************************************************** + TQObject debugging output routines. + *****************************************************************************/ + +static void dumpRecursive( int level, TQObject *object ) +{ +#if defined(TQT_DEBUG) + if ( object ) { + TQString buf; + buf.fill( '\t', level/2 ); + if ( level % 2 ) + buf += " "; + const char *name = object->name(); + TQString flags=""; + if ( tqApp->tqfocusWidget() == object ) + flags += 'F'; + if ( object->isWidgetType() ) { + TQWidget * w = (TQWidget *)object; + if ( w->isVisible() ) { + TQString t( "<%1,%2,%3,%4>" ); + flags += t.arg(w->x()).arg(w->y()).arg(w->width()).arg(w->height()); + } else { + flags += 'I'; + } + } + qDebug( "%s%s::%s %s", (const char*)buf, object->className(), name, + flags.latin1() ); + if ( !object->childrenListObject().isEmpty() ) { + TQObjectListIt it(object->childrenListObject()); + TQObject * c; + while ( (c=it.current()) != 0 ) { + ++it; + dumpRecursive( level+1, c ); + } + } + } +#else + TQ_UNUSED( level ) + TQ_UNUSED( object ) +#endif +} + +/*! + Dumps a tree of tqchildren to the debug output. + + This function is useful for debugging, but does nothing if the + library has been compiled in release mode (i.e. without debugging + information). +*/ + +void TQObject::dumpObjectTree() +{ + dumpRecursive( 0, this ); +} + +/*! + Dumps information about signal connections, etc. for this object + to the debug output. + + This function is useful for debugging, but does nothing if the + library has been compiled in release mode (i.e. without debugging + information). +*/ + +void TQObject::dumpObjectInfo() +{ +#if defined(TQT_DEBUG) + qDebug( "OBJECT %s::%s", className(), name( "unnamed" ) ); + int n = 0; + qDebug( " SIGNALS OUT" ); + if ( connections ) { + TQConnectionList *clist; + for ( uint i = 0; i < connections->size(); i++ ) { + if ( ( clist = connections->at( i ) ) ) { + qDebug( "\t%s", tqmetaObject()->signal( i, TRUE )->name ); + n++; + register TQConnection *c; + TQConnectionListIt cit(*clist); + while ( (c=cit.current()) ) { + ++cit; + qDebug( "\t --> %s::%s %s", c->object()->className(), + c->object()->name( "unnamed" ), c->memberName() ); + } + } + } + } + if ( n == 0 ) + qDebug( "\t<None>" ); + + qDebug( " SIGNALS IN" ); + n = 0; + if ( senderObjects ) { + TQObject *sender = senderObjects->first(); + while ( sender ) { + qDebug( "\t%s::%s", + sender->className(), sender->name( "unnamed" ) ); + n++; + sender = senderObjects->next(); + } + } + if ( n == 0 ) + qDebug( "\t<None>" ); +#endif +} + +#ifndef TQT_NO_PROPERTIES + +/*! + Sets the value of the object's \a name property to \a value. + + Returns TRUE if the operation was successful; otherwise returns + FALSE. + + Information about all available properties is provided through the + tqmetaObject(). + + \sa property(), tqmetaObject(), TQMetaObject::propertyNames(), TQMetaObject::property() +*/ +bool TQObject::setProperty( const char *name, const TQVariant& value ) +{ + if ( !value.isValid() ) + return FALSE; + + TQVariant v = value; + + TQMetaObject* meta = tqmetaObject(); + if ( !meta ) + return FALSE; + int id = meta->tqfindProperty( name, TRUE ); + const TQMetaProperty* p = meta->property( id, TRUE ); + if ( !p || !p->isValid() || !p->writable() ) { + qWarning( "%s::setProperty( \"%s\", value ) failed: property invalid, read-only or does not exist", + className(), name ); + return FALSE; + } + + if ( p->isEnumType() ) { + if ( v.type() == TQVariant::String || v.type() == TQVariant::CString ) { + if ( p->isSetType() ) { + TQString s = value.toString(); + // TQStrList does not support split, use TQStringList for that. + TQStringList l = TQStringList::split( '|', s ); + TQStrList keys; + for ( TQStringList::Iterator it = l.begin(); it != l.end(); ++it ) + keys.append( (*it).stripWhiteSpace().latin1() ); + v = TQVariant( p->keysToValue( keys ) ); + } else { + v = TQVariant( p->keyToValue( value.toCString().data() ) ); + } + } else if ( v.type() != TQVariant::Int && v.type() != TQVariant::UInt ) { + return FALSE; + } + return qt_property( id, 0, &v ); + } + + TQVariant::Type type = (TQVariant::Type)(p->flags >> 24); + if ( type == TQVariant::Invalid ) + type = TQVariant::nameToType( p->type() ); + if ( type != TQVariant::Invalid && !v.canCast( type ) ) + return FALSE; + return qt_property( id, 0, &v ); +} + +/*! + Returns the value of the object's \a name property. + + If no such property exists, the returned variant is invalid. + + Information about all available properties are provided through + the tqmetaObject(). + + \sa setProperty(), TQVariant::isValid(), tqmetaObject(), + TQMetaObject::propertyNames(), TQMetaObject::property() +*/ +TQVariant TQObject::property( const char *name ) const +{ + TQVariant v; + TQMetaObject* meta = tqmetaObject(); + if ( !meta ) + return v; + int id = meta->tqfindProperty( name, TRUE ); + const TQMetaProperty* p = meta->property( id, TRUE ); + if ( !p || !p->isValid() ) { + qWarning( "%s::property( \"%s\" ) failed: property invalid or does not exist", + className(), name ); + return v; + } + TQObject* that = (TQObject*) this; // tqmoc ensures constness for the qt_property call + that->qt_property( id, 1, &v ); + return v; +} + +#endif // TQT_NO_PROPERTIES + +#ifndef TQT_NO_USERDATA +/*!\internal + */ +uint TQObject::registerUserData() +{ + static int user_data_registration = 0; + return user_data_registration++; +} + +/*!\internal + */ +TQObjectUserData::~TQObjectUserData() +{ +} + +/*!\internal + */ +void TQObject::setUserData( uint id, TQObjectUserData* data) +{ + if ( !d ) + d = new TQObjectPrivate( id+1 ); + if ( id >= d->size() ) + d->resize( id+1 ); + d->insert( id, data ); +} + +/*!\internal + */ +TQObjectUserData* TQObject::userData( uint id ) const +{ + if ( d && id < d->size() ) + return d->at( id ); + return 0; +} + +#endif // TQT_NO_USERDATA + +#endif // USE_QT4
\ No newline at end of file |