TQObject.cxx

Go to the documentation of this file.
00001 // @(#)root/base:$Id: TQObject.cxx 29572 2009-07-24 10:59:01Z rdm $
00002 // Author: Valeriy Onuchin & Fons Rademakers   15/10/2000
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // This is the ROOT implementation of the Qt object communication       //
00015 // mechanism (see also http://www.troll.no/qt/metaobjects.html)         //
00016 //                                                                      //
00017 // Signals and slots are used for communication between objects.        //
00018 // When an object has changed in some way that might be interesting     //
00019 // for the outside world, it emits a signal to tell whoever is          //
00020 // listening. All slots that are connected to this signal will be       //
00021 // activated (called). It is even possible to connect a signal          //
00022 // directly to another signal (this will emit the second signal         //
00023 // immediately whenever the first is emitted.) There is no limitation   //
00024 // on the number of slots that can be connected to a signal.            //
00025 // The slots will be activated in the order they were connected         //
00026 // to the signal. This mechanism allows objects to be easily reused,    //
00027 // because the object that emits a signal does not need to know         //
00028 // to which objects the signals are connected.                          //
00029 // Together, signals and slots make up a powerfull component            //
00030 // programming mechanism.                                               //
00031 //                                                                      //
00032 // This implementation is provided by                                   //
00033 // Valeriy Onuchin (onuchin@sirius.ihep.su).                            //
00034 //                                                                      //
00035 //////////////////////////////////////////////////////////////////////////
00036 
00037 //***************************** Signals *****************************
00038 //___________________________________________________________________
00039 //
00040 //             Destroyed()
00041 //
00042 // Signal emitted when object is destroyed.
00043 // This signal could be connected to some garbage-collector object.
00044 //
00045 //___________________________________________________________________
00046 //
00047 //             ChangedBy(const char *method_name)
00048 //
00049 // This signal is emitted when some important data members of
00050 // the object were changed. method_name parameter can be used
00051 // as an identifier of the modifier method.
00052 //
00053 //___________________________________________________________________
00054 //
00055 //             Message(const char *msg)
00056 //
00057 // General purpose message signal
00058 //
00059 /////////////////////////////////////////////////////////////////////
00060 
00061 #include "Varargs.h"
00062 #include "TQObject.h"
00063 #include "TQConnection.h"
00064 #include "THashList.h"
00065 #include "TPRegexp.h"
00066 #include "TROOT.h"
00067 #include "TClass.h"
00068 #include "TSystem.h"
00069 #include "TMethod.h"
00070 #include "TBaseClass.h"
00071 #include "TDataType.h"
00072 #include "TInterpreter.h"
00073 #include "TQClass.h"
00074 #include "TError.h"
00075 #include "Riostream.h"
00076 #include "RQ_OBJECT.h"
00077 #include "TVirtualMutex.h"
00078 #include "Varargs.h"
00079 #include "TInterpreter.h"
00080 #include "RConfigure.h"
00081 
00082 void *gTQSender; // A pointer to the object that sent the last signal.
00083                  // Getting access to the sender might be practical
00084                  // when many signals are connected to a single slot.
00085 
00086 Bool_t TQObject::fgAllSignalsBlocked = kFALSE;
00087 
00088 
00089 ClassImpQ(TQObject)
00090 ClassImpQ(TQObjSender)
00091 ClassImpQ(TQClass)
00092 
00093 ////////////////////////////// internal functions //////////////////////////////
00094 namespace
00095 {
00096 
00097 //______________________________________________________________________________
00098 TString CompressName(const char *method_name)
00099 {
00100    // Removes "const" words and blanks from full (with prototype)
00101    // method name and resolve any typedefs in the method signature.
00102    // If a null or empty string is passed in, an empty string
00103    // is returned.
00104    //
00105    // Example: CompressName(" Draw(const char *, const char *,
00106    //                              Option_t * , Int_t , Int_t)");
00107    // returns the string "Draw(char*,char*,char*,int,int)".
00108 
00109    static TPMERegexp *constRe = 0, *wspaceRe = 0;
00110    static TVirtualMutex *lock = 0;
00111 
00112    R__LOCKGUARD2(lock);
00113 
00114    if (constRe == 0) {
00115       constRe  = new TPMERegexp("(?<=\\(|\\s|,|&|\\*)const(?=\\s|,|\\)|&|\\*)", "go");
00116       wspaceRe = new TPMERegexp("\\s+", "go");
00117    }
00118 
00119    TString res(method_name);
00120    if (res.IsNull())
00121       return res;
00122 
00123    constRe ->Substitute(res, "");
00124    wspaceRe->Substitute(res, "");
00125 
00126    TStringToken methargs(res, "\\(|\\)", kTRUE);
00127 
00128    methargs.NextToken();
00129    res = methargs;
00130    res += "(";
00131 
00132    methargs.NextToken();
00133    TStringToken arg(methargs, ",");
00134    while (arg.NextToken())
00135    {
00136       Int_t  pri = arg.Length() - 1;
00137       Char_t prc = 0;
00138       if (arg[pri] == '*' || arg[pri] == '&') {
00139          prc = arg[pri];
00140          arg.Remove(pri);
00141       }
00142       TDataType *dt = gROOT->GetType(arg.Data());
00143       if (dt) {
00144          res += dt->GetFullTypeName();
00145       } else {
00146          res += arg;
00147       }
00148       if (prc)          res += prc;
00149       if (!arg.AtEnd()) res += ",";
00150    }
00151    res += ")";
00152    return res;
00153 }
00154 
00155 //______________________________________________________________________________
00156 TMethod *GetMethodWithPrototype(TClass *cl, const char *method,
00157                                 const char *proto, Int_t &nargs)
00158 {
00159    // Almost the same as TClass::GetMethodWithPrototype().
00160 
00161    nargs = 0;
00162 
00163    if (!gInterpreter) return 0;
00164    R__LOCKGUARD2(gCINTMutex);
00165 
00166    Long_t faddr = 0;
00167    if (!cl->IsLoaded()) {
00168       // interpreted class
00169       void *clinfo = cl->GetClassInfo();
00170       nargs = gCint->ClassInfo_GetMethodNArg(clinfo,method, proto);
00171       if (nargs >= 0)  return (TMethod *) -1;
00172       nargs = 0;
00173       return 0;
00174    } else {
00175       faddr = (Long_t)gInterpreter->GetInterfaceMethodWithPrototype(cl, method,
00176                                                                     proto);
00177       if (!faddr) return 0;
00178    }
00179 
00180    TMethod *m;
00181    TIter next_method(cl->GetListOfMethods());
00182 
00183    // Look for a method in this class
00184    while ((m = (TMethod *) next_method())) {
00185       if (faddr == (Long_t)m->InterfaceMethod()) {
00186          nargs = m->GetNargs();
00187          return m;
00188       }
00189    }
00190 
00191    TIter next_base(cl->GetListOfBases());
00192    TBaseClass *base;
00193 
00194    // loop over all base classes
00195    while ((base = (TBaseClass *)next_base())) {
00196       TClass *c;
00197       if ((c = base->GetClassPointer())) {
00198          if ((m = GetMethodWithPrototype(c, method, proto, nargs))) return m;
00199       }
00200    }
00201    return 0;
00202 }
00203 
00204 //______________________________________________________________________________
00205 static TMethod *GetMethod(TClass *cl, const char *method, const char *params)
00206 {
00207    // Almost the same as TClass::GetMethod().
00208 
00209    if (!gInterpreter) return 0;
00210    R__LOCKGUARD2(gCINTMutex);
00211 
00212    Long_t faddr = 0;
00213    if (!cl->IsLoaded()) {
00214       // interpreted class
00215       CallFunc_t *func = gCint->CallFunc_Factory();
00216       long         offset;
00217       void *cinfo = cl->GetClassInfo();
00218       gCint->CallFunc_SetFunc(func, cinfo, method, params, &offset);
00219       Bool_t valid = gCint->CallFunc_IsValid(func);
00220       gCint->CallFunc_Delete(func);
00221       if (valid)
00222          return (TMethod *) -1;
00223       return 0;
00224    } else {
00225       faddr = (Long_t)gCint->GetInterfaceMethod(cl, method, params);
00226       if (!faddr) return 0;
00227    }
00228 
00229    TMethod *m;
00230    TIter next_method(cl->GetListOfMethods());
00231 
00232    // Look for a method in this class
00233    while ((m = (TMethod *) next_method())) {
00234       if (faddr == (Long_t)m->InterfaceMethod()) return m;
00235    }
00236 
00237    TIter next_base(cl->GetListOfBases());
00238    TBaseClass *base;
00239 
00240    // loop over all base classes
00241    while ((base = (TBaseClass *)next_base())) {
00242       TClass *c;
00243       if ((c = base->GetClassPointer())) {
00244          if ((m = GetMethod(c,method,params))) return m;
00245       }
00246    }
00247    return 0;
00248 }
00249 
00250 }
00251 ////////////////////////// end of internal functions ///////////////////////////
00252 
00253 
00254 //______________________________________________________________________________
00255 Int_t TQObject::CheckConnectArgs(TQObject *sender,
00256                                  TClass *sender_class, const char *signal,
00257                                  TClass *receiver_class, const char *slot)
00258 {
00259    // Checking of consitency of sender/receiver methods/arguments.
00260    // Returns -1 on error, otherwise number or arguments of signal function.
00261    // Static method.
00262 
00263    char *signal_method = new char[strlen(signal)+1];
00264    if (signal_method) strcpy(signal_method, signal);
00265 
00266    char *signal_proto;
00267    char *tmp;
00268 
00269    if ((signal_proto = strchr(signal_method,'('))) {
00270       // substitute first '(' symbol with '\0'
00271       *signal_proto++ = '\0';
00272       // substitute last ')' symbol with '\0'
00273       if ((tmp = strrchr(signal_proto,')'))) *tmp = '\0';
00274    }
00275 
00276    if (!signal_proto) signal_proto = (char*)""; // avoid zero strings
00277 
00278    // if delegation object TQObjSender is used get the real sender class
00279    if (sender && sender_class == TQObjSender::Class()) {
00280       sender_class = TClass::GetClass(sender->GetSenderClassName());
00281       if (!sender_class) {
00282          ::Error("TQObject::CheckConnectArgs", "for signal/slot consistency\n"
00283                  "checking need to specify class name as argument to "
00284                  "RQ_OBJECT macro");
00285          delete [] signal_method;
00286          return -1;
00287       }
00288    }
00289 
00290    Int_t nargs;
00291    TMethod *signalMethod = GetMethodWithPrototype(sender_class,
00292                                                   signal_method,
00293                                                   signal_proto,
00294                                                   nargs);
00295    if (!signalMethod) {
00296       ::Error("TQObject::CheckConnectArgs",  "signal %s::%s(%s) does not exist",
00297               sender_class->GetName(), signal_method, signal_proto);
00298       delete [] signal_method;
00299       return -1;
00300    }
00301    Int_t nsigargs = nargs;
00302 
00303 #if defined(CHECK_COMMENT_STRING)
00304    const char *comment = 0;
00305    if (signalMethod != (TMethod *) -1)   // -1 in case of interpreted class
00306       comment = signalMethod->GetCommentString();
00307 
00308    if (!comment || !strlen(comment) || strstr(comment,"*SIGNAL")){
00309       ::Error("TQObject::CheckConnectArgs",
00310               "signal %s::%s(%s), to declare signal use comment //*SIGNAL*",
00311       sender_class->GetName(), signal_method, signal_proto);
00312       delete [] signal_method;
00313       return -1;
00314    }
00315 #endif
00316 
00317    // cleaning
00318    delete [] signal_method;
00319 
00320    char *slot_method = new char[strlen(slot)+1];
00321    if (slot_method) strcpy(slot_method, slot);
00322 
00323    char *slot_proto;
00324    char *slot_params = 0;
00325 
00326    if ((slot_proto = strchr(slot_method,'('))) {
00327 
00328       // substitute first '(' symbol with '\0'
00329       *slot_proto++ = '\0';
00330 
00331       // substitute last ')' symbol with '\0'
00332       if ((tmp = strrchr(slot_proto,')'))) *tmp = '\0';
00333    }
00334 
00335    if (!slot_proto) slot_proto = (char*)"";     // avoid zero strings
00336    if ((slot_params = strchr(slot_proto,'='))) *slot_params = ' ';
00337 
00338    TFunction *slotMethod = 0;
00339    if (!receiver_class) {
00340       // case of slot_method is compiled/intrepreted function
00341       slotMethod = (TFunction*)gROOT->GetListOfGlobalFunctions(kTRUE)->
00342                                              FindObject(slot_method);
00343    } else {
00344       slotMethod  = !slot_params ?
00345                           GetMethodWithPrototype(receiver_class,
00346                                                  slot_method,
00347                                                  slot_proto,
00348                                                  nargs) :
00349                           GetMethod(receiver_class,
00350                                     slot_method, slot_params);
00351    }
00352 
00353    if (!slotMethod) {
00354       if (!slot_params) {
00355          ::Error("TQObject::CheckConnectArgs", "slot %s(%s) does not exist",
00356                  receiver_class ? Form("%s::%s", receiver_class->GetName(),
00357                  slot_method) : slot_method, slot_proto);
00358       } else {
00359          ::Error("TQObject::CheckConnectArgs", "slot %s(%s) does not exist",
00360                  receiver_class ? Form("%s::%s", receiver_class->GetName(),
00361                  slot_method) : slot_method, slot_params);
00362       }
00363       delete [] slot_method;
00364       return -1;
00365    }
00366 
00367 #if defined(CHECK_ARGS_NUMBER)
00368    if (slotMethod != (TMethod *) -1 && slotMethod->GetNargsOpt() >= 0 &&
00369        nsigargs < (slotMethod->GetNargs() - slotMethod->GetNargsOpt())) {
00370       ::Error("TQObject::CheckConnectArgs",
00371               "inconsistency in numbers of arguments");
00372       delete [] slot_method;
00373       return -1;
00374    }
00375 #endif
00376 
00377    // cleaning
00378    delete [] slot_method;
00379 
00380    return nsigargs;
00381 }
00382 
00383 ////////////////////////////////////////////////////////////////////////////////
00384 //                                                                            //
00385 //    TQConnectionList is the named list of connections,                      //
00386 //    see also TQConnection class.                                            //
00387 //                                                                            //
00388 ////////////////////////////////////////////////////////////////////////////////
00389 class TQConnectionList : public TList {
00390 
00391 private:
00392    Int_t   fSignalArgs;    // number of arguments in signal function
00393 
00394 public:
00395    TQConnectionList(const char *name, Int_t nsigargs) : TList()
00396       { fName = name; fSignalArgs = nsigargs; }
00397    virtual ~TQConnectionList();
00398 
00399    Bool_t Disconnect(void *receiver=0, const char *slot_name=0);
00400    Int_t  GetNargs() const { return fSignalArgs; }
00401    void   ls(Option_t *option = "") const;
00402 };
00403 
00404 //______________________________________________________________________________
00405 TQConnectionList::~TQConnectionList()
00406 {
00407    // Destructor.
00408 
00409    TIter next(this);
00410    TQConnection *connection;
00411 
00412    while ((connection = (TQConnection*)next())) {
00413       // remove this from feed back reference list
00414       connection->Remove(this);
00415       if (connection->IsEmpty()) delete connection;
00416    }
00417    Clear("nodelete");
00418 }
00419 
00420 //______________________________________________________________________________
00421 Bool_t TQConnectionList::Disconnect(void *receiver, const char *slot_name)
00422 {
00423    // Remove connection from the list. For more info see
00424    // TQObject::Disconnect()
00425 
00426    TQConnection *connection = 0;
00427    Bool_t return_value = kFALSE;
00428 
00429    TObjLink *lnk = FirstLink();
00430    TObjLink *savlnk; // savlnk is used when link is deleted
00431 
00432    while (lnk) {
00433       connection = (TQConnection*)lnk->GetObject();
00434       const char *name = connection->GetName();
00435       void *obj = connection->GetReceiver();
00436 
00437       if (!slot_name || !strlen(slot_name)
00438                      || !strcmp(name,slot_name)) {
00439 
00440          if (!receiver || (receiver == obj)) {
00441             return_value = kTRUE;
00442             savlnk = lnk->Next();   // keep next link ..
00443             Remove(lnk);
00444             lnk = savlnk;           // current link == saved ...
00445             connection->Remove(this);      // remove back reference
00446             if (connection->IsEmpty()) SafeDelete(connection);
00447             continue;               // .. continue from saved link
00448          }
00449       }
00450       lnk = lnk->Next();
00451    }
00452    return return_value;
00453 }
00454 
00455 //______________________________________________________________________________
00456 void TQConnectionList::ls(Option_t *option) const
00457 {
00458    // List signal name and list all connections in this signal list.
00459 
00460    cout <<  "TQConnectionList:" << "\t" << GetName() << endl;
00461    ((TQConnectionList*)this)->R__FOR_EACH(TQConnection,Print)(option);
00462 }
00463 
00464 
00465 //______________________________________________________________________________
00466 TQObject::TQObject()
00467 {
00468    // TQObject Constructor.
00469    // Comment:
00470    //  - In order to minimize memory allocation fListOfSignals and
00471    //    fListOfConnections are allocated only if it is neccesary
00472    //  - When fListOfSignals/fListOfConnections are empty they will
00473    //    be deleted
00474 
00475    fListOfSignals     = 0;
00476    fListOfConnections = 0;
00477    fSignalsBlocked    = kFALSE;
00478 }
00479 
00480 //______________________________________________________________________________
00481 TQObject::~TQObject()
00482 {
00483    // TQObject Destructor.
00484    //    - delete all connections and signal list
00485 
00486    if (!gROOT) return;
00487 
00488    Destroyed();   // emit "Destroyed()" signal
00489 
00490    if (fListOfSignals) {
00491       fListOfSignals->Delete();
00492       SafeDelete(fListOfSignals);   // delete list of signals
00493    }
00494 
00495    // loop over all connections and remove references to this object
00496    if (fListOfConnections) {
00497       TIter next_connection(fListOfConnections);
00498       TQConnection *connection;
00499 
00500       while ((connection = (TQConnection*)next_connection())) {
00501          TIter next_list(connection);
00502          TQConnectionList *list;
00503          while ((list = (TQConnectionList*)next_list())) {
00504             list->Remove(connection);
00505             if (list->IsEmpty()) SafeDelete(list);
00506          }
00507       }
00508       SafeDelete(fListOfConnections);
00509    }
00510 }
00511 
00512 //______________________________________________________________________________
00513 TList *TQObject::GetListOfClassSignals() const
00514 {
00515    // Returns pointer to list of signals of this class.
00516 
00517    TQClass *qcl = 0;
00518 
00519    qcl = dynamic_cast<TQClass*>(IsA());
00520 
00521    return qcl ? qcl->fListOfSignals : 0; //!!
00522 }
00523 
00524 //______________________________________________________________________________
00525 void TQObject::CollectClassSignalLists(TList& list, TClass* cls)
00526 {
00527    // Collect class signal lists from class cls and all its
00528    // base-classes.
00529    //
00530    // The recursive traversal is not performed for classes not
00531    // deriving from TQClass.
00532 
00533    TQClass *qcl = dynamic_cast<TQClass*>(cls);
00534    if (qcl)
00535    {
00536       if (qcl->fListOfSignals)
00537          list.Add(qcl->fListOfSignals);
00538 
00539       // Descend into base-classes.
00540       TIter       next_base_class(cls->GetListOfBases());
00541       TBaseClass *base;
00542       while ((base = (TBaseClass*) next_base_class()))
00543       {
00544          CollectClassSignalLists(list, base->GetClassPointer());
00545       }
00546    }
00547 }
00548 
00549 //______________________________________________________________________________
00550 void TQObject::HighPriority(const char *signal_name, const char *slot_name)
00551 {
00552    // 1. If slot_name = 0 => makes signal defined by the signal_name
00553    //    to be the first in the fListOfSignals, this decreases
00554    //    the time for lookup.
00555    // 2. If slot_name != 0 => makes slot defined by the slot_name
00556    //    to be executed first when signal_name is emitted.
00557    // Signal name is not compressed.
00558 
00559    TQConnectionList *clist = (TQConnectionList*)
00560       fListOfSignals->FindObject(signal_name);
00561 
00562    if (!clist)  return;      // not found
00563    if (!slot_name)  {        // update list of signal lists
00564       fListOfSignals->Remove(clist);   // remove and add first
00565       fListOfSignals->AddFirst(clist);
00566       return;
00567    } else {                   // slot_name != 0 , update signal list
00568       TQConnection *con = (TQConnection*) clist->FindObject(slot_name);
00569       if (!con) return;       // not found
00570       clist->Remove(con);     // remove and add as first
00571       clist->AddFirst(con);
00572    }
00573 }
00574 
00575 //______________________________________________________________________________
00576 void TQObject::LowPriority(const char *signal_name, const char *slot_name)
00577 {
00578    // 1. If slot_name = 0 => makes signal defined by the signal_name
00579    //    to be the last in the fListOfSignals, this increase the time
00580    //    for lookup.
00581    // 2. If slot_name != 0 => makes slot defined by the slot_name
00582    //    to  be executed last when signal_name is emitted.
00583    // Signal name is not compressed.
00584 
00585    TQConnectionList *clist = (TQConnectionList*)
00586       fListOfSignals->FindObject(signal_name);
00587 
00588    if (!clist)   return;
00589    if (!slot_name)  {
00590       fListOfSignals->Remove(clist);   // remove and add first
00591       fListOfSignals->AddLast(clist);
00592       return;
00593    } else  {                  // slot_name != 0 , update signal list
00594       TQConnection *con = (TQConnection*) clist->FindObject(slot_name);
00595       if (!con) return;
00596       clist->Remove(con);     // remove and add as last
00597       clist->AddLast(con);
00598    }
00599 }
00600 
00601 //______________________________________________________________________________
00602 Bool_t TQObject::HasConnection(const char *signal_name) const
00603 {
00604    // Return true if there is any object connected to this signal.
00605    // Only checks for object signals.
00606 
00607    if (!fListOfSignals)
00608       return kFALSE;
00609 
00610    TString signal = CompressName(signal_name);
00611 
00612    return (fListOfSignals->FindObject(signal) != 0);
00613 }
00614 
00615 //______________________________________________________________________________
00616 Int_t TQObject::NumberOfSignals() const
00617 {
00618    // Return number of signals for this object.
00619    // Only checks for object signals.
00620 
00621    if (fListOfSignals)
00622       return fListOfSignals->GetSize();
00623    return 0;
00624 }
00625 
00626 //______________________________________________________________________________
00627 Int_t TQObject::NumberOfConnections() const
00628 {
00629    // Return number of connections for this object.
00630 
00631    if (fListOfConnections)
00632       return fListOfConnections->GetSize();
00633    return 0;
00634 }
00635 
00636 //______________________________________________________________________________
00637 void TQObject::Emit(const char *signal_name)
00638 {
00639    // Acitvate signal without args.
00640    // Example:
00641    //          theButton->Emit("Clicked()");
00642 
00643    if (fSignalsBlocked || fgAllSignalsBlocked) return;
00644 
00645    TList classSigLists;
00646    CollectClassSignalLists(classSigLists, IsA());
00647 
00648    if (classSigLists.IsEmpty() && !fListOfSignals)
00649       return;
00650 
00651    TString signal = CompressName(signal_name);
00652 
00653    register TQConnection *connection = 0;
00654 
00655    // execute class signals
00656    TList *sigList;
00657    TIter  nextSigList(&classSigLists);
00658    while ((sigList = (TList*) nextSigList()))
00659    {
00660       TIter nextcl((TQConnectionList*) sigList->FindObject(signal));
00661       while ((connection = (TQConnection*)nextcl())) {
00662          gTQSender = GetSender();
00663          connection->ExecuteMethod();
00664       }
00665    }
00666    if (!fListOfSignals)
00667       return;
00668 
00669    // execute object signals
00670    TIter next((TQConnectionList*) fListOfSignals->FindObject(signal));
00671    while (fListOfSignals && (connection = (TQConnection*)next())) {
00672       gTQSender = GetSender();
00673       connection->ExecuteMethod();
00674    }
00675 }
00676 
00677 //______________________________________________________________________________
00678 void TQObject::EmitVA(const char *signal_name, Int_t va_(nargs), ...)
00679 {
00680    // Activate signal with variable argument list.
00681    // Example:
00682    //          theButton->EmitVA("Clicked(int,float)", 2, id, fid)
00683 
00684    va_list ap;
00685    va_start(ap, va_(nargs));
00686 
00687    EmitVA(signal_name, va_(nargs), ap);
00688 
00689    va_end(ap);
00690 }
00691 
00692 //______________________________________________________________________________
00693 void TQObject::EmitVA(const char *signal_name, Int_t nargs, va_list ap)
00694 {
00695    // Activate signal with variable argument list.
00696    // For internal use and for var arg EmitVA() in RQ_OBJECT.h.
00697 
00698    if (fSignalsBlocked || fgAllSignalsBlocked) return;
00699 
00700    TList classSigLists;
00701    CollectClassSignalLists(classSigLists, IsA());
00702 
00703    if (classSigLists.IsEmpty() && !fListOfSignals)
00704       return;
00705 
00706    TString signal = CompressName(signal_name);
00707 
00708    register TQConnection *connection = 0;
00709 
00710    // execute class signals
00711    TList *sigList;
00712    TIter  nextSigList(&classSigLists);
00713    while ((sigList = (TList*) nextSigList()))
00714    {
00715       TIter nextcl((TQConnectionList*) sigList->FindObject(signal));
00716       while ((connection = (TQConnection*)nextcl())) {
00717          gTQSender = GetSender();
00718          connection->ExecuteMethod(nargs, ap);
00719       }
00720    }
00721    if (!fListOfSignals)
00722       return;
00723 
00724    // execute object signals
00725    TIter next((TQConnectionList*) fListOfSignals->FindObject(signal));
00726    while (fListOfSignals && (connection = (TQConnection*)next())) {
00727       gTQSender = GetSender();
00728       connection->ExecuteMethod(nargs, ap);
00729    }
00730 }
00731 
00732 //______________________________________________________________________________
00733 void TQObject::Emit(const char *signal_name, Long_t param)
00734 {
00735    // Activate signal with single parameter.
00736    // Example:
00737    //          theButton->Emit("Clicked(int)",id)
00738 
00739    if (fSignalsBlocked || fgAllSignalsBlocked) return;
00740 
00741    TList classSigLists;
00742    CollectClassSignalLists(classSigLists, IsA());
00743 
00744    if (classSigLists.IsEmpty() && !fListOfSignals)
00745       return;
00746 
00747    TString signal = CompressName(signal_name);
00748 
00749    register TQConnection *connection = 0;
00750 
00751    // execute class signals
00752    TList *sigList;
00753    TIter  nextSigList(&classSigLists);
00754    while ((sigList = (TList*) nextSigList()))
00755    {
00756       TIter nextcl((TQConnectionList*) sigList->FindObject(signal));
00757       while ((connection = (TQConnection*)nextcl())) {
00758          gTQSender = GetSender();
00759          connection->ExecuteMethod(param);
00760       }
00761    }
00762    if (!fListOfSignals)
00763       return;
00764 
00765    // execute object signals
00766    TIter next((TQConnectionList*) fListOfSignals->FindObject(signal));
00767    while (fListOfSignals && (connection = (TQConnection*)next())) {
00768       gTQSender = GetSender();
00769       connection->ExecuteMethod(param);
00770    }
00771 }
00772 
00773 //______________________________________________________________________________
00774 void TQObject::Emit(const char *signal_name, Long64_t param)
00775 {
00776    // Activate signal with single parameter.
00777    // Example:
00778    //          theButton->Emit("Progress(Long64_t)",processed)
00779 
00780    if (fSignalsBlocked || fgAllSignalsBlocked) return;
00781 
00782    TList classSigLists;
00783    CollectClassSignalLists(classSigLists, IsA());
00784 
00785    if (classSigLists.IsEmpty() && !fListOfSignals)
00786       return;
00787 
00788    TString signal = CompressName(signal_name);
00789 
00790    register TQConnection *connection = 0;
00791 
00792    // execute class signals
00793    TList *sigList;
00794    TIter  nextSigList(&classSigLists);
00795    while ((sigList = (TList*) nextSigList()))
00796    {
00797       TIter nextcl((TQConnectionList*) sigList->FindObject(signal));
00798       while ((connection = (TQConnection*)nextcl())) {
00799          gTQSender = GetSender();
00800          connection->ExecuteMethod(param);
00801       }
00802    }
00803    if (!fListOfSignals)
00804       return;
00805 
00806    // execute object signals
00807    TIter next((TQConnectionList*) fListOfSignals->FindObject(signal));
00808    while (fListOfSignals && (connection = (TQConnection*)next())) {
00809       gTQSender = GetSender();
00810       connection->ExecuteMethod(param);
00811    }
00812 }
00813 
00814 //______________________________________________________________________________
00815 void TQObject::Emit(const char *signal_name, Double_t param)
00816 {
00817    // Activate signal with single parameter.
00818    // Example:
00819    //          theButton->Emit("Scale(float)",factor)
00820 
00821    if (fSignalsBlocked || fgAllSignalsBlocked) return;
00822 
00823    TList classSigLists;
00824    CollectClassSignalLists(classSigLists, IsA());
00825 
00826    if (classSigLists.IsEmpty() && !fListOfSignals)
00827       return;
00828 
00829    TString signal = CompressName(signal_name);
00830 
00831    register TQConnection *connection = 0;
00832 
00833    // execute class signals
00834    TList *sigList;
00835    TIter  nextSigList(&classSigLists);
00836    while ((sigList = (TList*) nextSigList()))
00837    {
00838       TIter nextcl((TQConnectionList*) sigList->FindObject(signal));
00839       while ((connection = (TQConnection*)nextcl())) {
00840          gTQSender = GetSender();
00841          connection->ExecuteMethod(param);
00842       }
00843    }
00844    if (!fListOfSignals)
00845       return;
00846 
00847    // execute object signals
00848    TIter next((TQConnectionList*) fListOfSignals->FindObject(signal));
00849    while (fListOfSignals && (connection = (TQConnection*)next())) {
00850       gTQSender = GetSender();
00851       connection->ExecuteMethod(param);
00852    }
00853 }
00854 
00855 //______________________________________________________________________________
00856 void TQObject::Emit(const char *signal_name, const char *params)
00857 {
00858    // Activate signal with parameter text string.
00859    // Example:
00860    //          myObject->Emit("Error(char*)","Fatal error");
00861 
00862    if (fSignalsBlocked || fgAllSignalsBlocked) return;
00863 
00864    TList classSigLists;
00865    CollectClassSignalLists(classSigLists, IsA());
00866 
00867    if (classSigLists.IsEmpty() && !fListOfSignals)
00868       return;
00869 
00870    TString signal = CompressName(signal_name);
00871 
00872    register TQConnection *connection = 0;
00873 
00874    // execute class signals
00875    TList *sigList;
00876    TIter  nextSigList(&classSigLists);
00877    while ((sigList = (TList*) nextSigList()))
00878    {
00879       TIter nextcl((TQConnectionList*) sigList->FindObject(signal));
00880       while ((connection = (TQConnection*)nextcl())) {
00881          gTQSender = GetSender();
00882          connection->ExecuteMethod(params);
00883       }
00884    }
00885    if (!fListOfSignals)
00886       return;
00887 
00888    // execute object signals
00889    TIter next((TQConnectionList*) fListOfSignals->FindObject(signal));
00890    while (fListOfSignals && (connection = (TQConnection*)next())) {
00891       gTQSender = GetSender();
00892       connection->ExecuteMethod(params);
00893    }
00894 }
00895 
00896 //______________________________________________________________________________
00897 void TQObject::Emit(const char *signal_name, Long_t *paramArr)
00898 {
00899    // Emit a signal with a varying number of arguments,
00900    // paramArr is an array of the parameters.
00901    // Note: any parameter should be converted to long type.
00902    // Example:
00903    //    TQObject *processor; // data processor
00904    //    TH1F     *hist;      // filled with processor results
00905    //
00906    //    processor->Connect("Evaluated(Float_t,Float_t)",
00907    //                       "TH1F",hist,"Fill12(Axis_t,Axis_t)");
00908    //
00909    //    Long_t args[2];
00910    //    args[0] = (Long_t)processor->GetValue(1);
00911    //    args[1] = (Long_t)processor->GetValue(2);
00912    //
00913    //    processor->Emit("Evaluated(Float_t,Float_t)",args);
00914 
00915    if (fSignalsBlocked || fgAllSignalsBlocked) return;
00916 
00917    TList classSigLists;
00918    CollectClassSignalLists(classSigLists, IsA());
00919 
00920    if (classSigLists.IsEmpty() && !fListOfSignals)
00921       return;
00922 
00923    TString signal = CompressName(signal_name);
00924 
00925    register TQConnectionList *clist  = 0;
00926    register TQConnection *connection = 0;
00927 
00928    // execute class signals
00929    TList *sigList;
00930    TIter  nextSigList(&classSigLists);
00931    while ((sigList = (TList*) nextSigList()))
00932    {
00933       clist = (TQConnectionList*) sigList->FindObject(signal);
00934       TIter nextcl(clist);
00935       while ((connection = (TQConnection*)nextcl())) {
00936          gTQSender = GetSender();
00937          connection->ExecuteMethod(paramArr, clist->GetNargs());
00938       }
00939    }
00940    if (!fListOfSignals)
00941       return;
00942 
00943    // execute object signals
00944    clist = (TQConnectionList*) fListOfSignals->FindObject(signal);
00945    TIter next(clist);
00946    while (fListOfSignals && (connection = (TQConnection*)next())) {
00947       gTQSender = GetSender();
00948       connection->ExecuteMethod(paramArr, clist->GetNargs());
00949    }
00950 }
00951 
00952 //______________________________________________________________________________
00953 Bool_t TQObject::ConnectToClass(TQObject *sender,
00954                                 const char *signal,
00955                                 TClass *cl,
00956                                 void *receiver,
00957                                 const char *slot)
00958 {
00959    // Create connection between sender and receiver.
00960    // Receiver class needs to have a dictionary.
00961 
00962    // sender should be TQObject
00963    if (!sender->IsA()->InheritsFrom(TQObject::Class()))
00964       return kFALSE;
00965 
00966    // remove "const" and strip blanks
00967    TString signal_name = CompressName(signal);
00968    TString slot_name   = CompressName(slot);
00969 
00970    // check consitency of signal/slot methods/args
00971    Int_t nsigargs;
00972    if ((nsigargs = CheckConnectArgs(sender, sender->IsA(), signal_name, cl, slot_name)) == -1)
00973       return kFALSE;
00974 
00975    if (!sender->fListOfSignals)
00976       sender->fListOfSignals = new THashList();
00977 
00978    TQConnectionList *clist = (TQConnectionList*)
00979       sender->fListOfSignals->FindObject(signal_name);
00980 
00981    if (!clist) {
00982       clist = new TQConnectionList(signal_name, nsigargs);
00983       sender->fListOfSignals->Add(clist);
00984    }
00985 
00986    TIter next(clist);
00987    TQConnection *connection = 0;
00988 
00989    while ((connection = (TQConnection*)next())) {
00990       if (!strcmp(slot_name,connection->GetName()) &&
00991           (receiver == connection->GetReceiver())) break;
00992    }
00993 
00994    if (!connection)
00995       connection = new TQConnection(cl, receiver, slot_name);
00996 
00997    // check to prevent multiple entries
00998    if (!clist->FindObject(connection)) {
00999       clist->Add(connection);
01000       if (!connection->FindObject(clist)) connection->Add(clist);
01001       sender->Connected(signal_name);
01002    }
01003 
01004    return kTRUE;
01005 }
01006 
01007 //______________________________________________________________________________
01008 Bool_t TQObject::ConnectToClass(const char *class_name,
01009                                 const char *signal,
01010                                 TClass *cl,
01011                                 void *receiver,
01012                                 const char *slot)
01013 {
01014    // This method allows to make connection from any object
01015    // of the same class to the receiver object.
01016    // Receiver class needs to have a dictionary.
01017 
01018    TClass *sender = TClass::GetClass(class_name);
01019 
01020    // sender class should be TQObject (i.e. TQClass)
01021    if (!sender || !sender->IsA()->InheritsFrom(TQObject::Class()))
01022       return kFALSE;
01023 
01024    TList *slist = ((TQClass*)sender)->fListOfSignals;
01025    TString signal_name = CompressName(signal);
01026    TString slot_name   = CompressName(slot);
01027 
01028    // check consitency of signal/slot methods/args
01029    Int_t nsigargs;
01030    if ((nsigargs = CheckConnectArgs(0, sender, signal_name, cl, slot_name)) == -1)
01031       return kFALSE;
01032 
01033    if (!slist)
01034       ((TQClass*)sender)->fListOfSignals = slist = new THashList();
01035 
01036    TQConnectionList *clist = (TQConnectionList*) slist->FindObject(signal_name);
01037 
01038    if (!clist) {
01039       clist = new TQConnectionList(signal_name, nsigargs);
01040       slist->Add(clist);
01041    }
01042 
01043    TQConnection *connection = 0;
01044    TIter next(clist);
01045 
01046    while ((connection = (TQConnection*)next())) {
01047       if (!strcmp(slot_name,connection->GetName()) &&
01048           (receiver == connection->GetReceiver())) break;
01049    }
01050 
01051    if (!connection)
01052       connection = new TQConnection(cl, receiver, slot_name);
01053 
01054    // check to prevent multiple entries
01055    if (!clist->FindObject(connection)) {
01056       clist->Add(connection);
01057       if (!connection->FindObject(clist)) connection->Add(clist);
01058       ((TQClass*)sender)->Connected(signal_name);
01059    }
01060 
01061    return kTRUE;
01062 }
01063 
01064 //______________________________________________________________________________
01065 Bool_t TQObject::Connect(TQObject *sender,
01066                          const char *signal,
01067                          const char *cl,
01068                          void *receiver,
01069                          const char *slot)
01070 {
01071    // Create connection between sender and receiver.
01072    // Signal and slot string must have a form:
01073    //    "Draw(char*, Option_t* ,Int_t)"
01074    // All blanks and "const" words will be removed,
01075    //
01076    // cl != 0 - class name, it can be class with or
01077    //           without dictionary, e.g interpreted class.
01078    // Example:
01079    //       TGButton *myButton;
01080    //       TH2F     *myHist;
01081    //
01082    //       TQObject::Connect(myButton,"Clicked()",
01083    //                         "TH2F", myHist,"Draw(Option_t*)");
01084    //
01085    // cl == 0 - corresponds to function (interpereted or global)
01086    //           the name of the function is defined by the slot string,
01087    //           parameter receiver should be 0.
01088    // Example:
01089    //       TGButton *myButton;
01090    //       TH2F     *myHist;
01091    //
01092    //       TQObject::Connect(myButton,"Clicked()",
01093    //                         0, 0,"hsimple()");
01094    //
01095    // Warning:
01096    //  If receiver is class not derived from TQObject and going to be
01097    //  deleted, disconnect all connections to this receiver.
01098    //  In case of class derived from TQObject it is done automatically.
01099 
01100    if (cl) {
01101       TClass *rcv_cl = TClass::GetClass(cl);
01102       if (rcv_cl) return ConnectToClass(sender, signal, rcv_cl, receiver, slot);
01103    }
01104 
01105    // the following is the case of receiver class without dictionary
01106    // e.g. interpreted class or function.
01107 
01108    // sender should be TQObject
01109    if (!sender->IsA()->InheritsFrom(TQObject::Class()))
01110       return kFALSE;
01111 
01112    // remove "const" and strip blanks
01113    TString signal_name = CompressName(signal);
01114    TString slot_name   = CompressName(slot);
01115 
01116    // check consitency of signal/slot methods/args
01117    Int_t nsigargs;
01118    if ((nsigargs = CheckConnectArgs(sender, sender->IsA(), signal_name, 0, slot_name)) == -1)
01119       return kFALSE;
01120 
01121    if (!sender->fListOfSignals) sender->fListOfSignals = new THashList();
01122 
01123    TQConnectionList *clist = (TQConnectionList*)
01124       sender->fListOfSignals->FindObject(signal_name);
01125 
01126    if (!clist) {
01127       clist = new TQConnectionList(signal_name, nsigargs);
01128       sender->fListOfSignals->Add(clist);
01129    }
01130 
01131    TQConnection *connection = 0;
01132    TIter next(clist);
01133 
01134    while ((connection = (TQConnection*)next())) {
01135       if (!strcmp(slot_name,connection->GetName()) &&
01136           (receiver == connection->GetReceiver())) break;
01137    }
01138 
01139    if (!connection)
01140       connection = new TQConnection(cl, receiver, slot_name);
01141 
01142    // check to prevent multiple entries
01143    if (!clist->FindObject(connection)) {
01144       clist->Add(connection);
01145       if (!connection->FindObject(clist)) connection->Add(clist);
01146       sender->Connected(signal_name);
01147    }
01148 
01149    return kTRUE;
01150 }
01151 
01152 //______________________________________________________________________________
01153 Bool_t TQObject::Connect(const char *class_name,
01154                          const char *signal,
01155                          const char *cl,
01156                          void *receiver,
01157                          const char *slot)
01158 {
01159    // This method allows to make a connection from any object
01160    // of the same class to a single slot.
01161    // Signal and slot string must have a form:
01162    //    "Draw(char*, Option_t* ,Int_t)"
01163    // All blanks and "const" words will be removed,
01164    //
01165    // cl != 0 - class name, it can be class with or
01166    //           without dictionary, e.g interpreted class.
01167    // Example:
01168    //       TGButton *myButton;
01169    //       TH2F     *myHist;
01170    //
01171    //       TQObject::Connect("TGButton", "Clicked()",
01172    //                         "TH2F", myHist, "Draw(Option_t*)");
01173    //
01174    // cl == 0 - corresponds to function (interpereted or global)
01175    //           the name of the function is defined by the slot string,
01176    //           parameter receiver should be 0.
01177    // Example:
01178    //       TGButton *myButton;
01179    //       TH2F     *myHist;
01180    //
01181    //       TQObject::Connect("TGButton", "Clicked()",
01182    //                         0, 0, "hsimple()");
01183    //
01184    // Warning:
01185    //  If receiver class not derived from TQObject and going to be
01186    //  deleted, disconnect all connections to this receiver.
01187    //  In case of class derived from TQObject it is done automatically.
01188 
01189    if (cl) {
01190       TClass *rcv_cl = TClass::GetClass(cl);
01191       if (rcv_cl) return ConnectToClass(class_name, signal, rcv_cl, receiver,
01192                                         slot);
01193    }
01194 
01195    // the following is case of receiver class without dictionary
01196    // e.g. interpreted class or function.
01197 
01198    TClass *sender = TClass::GetClass(class_name);
01199 
01200    // sender class should be TQObject (i.e. TQClass)
01201    if (!sender || !sender->IsA()->InheritsFrom(TQObject::Class()))
01202       return kFALSE;
01203 
01204    TList *slist = ((TQClass*)sender)->fListOfSignals;
01205 
01206    TString signal_name = CompressName(signal);
01207    TString slot_name   = CompressName(slot);
01208 
01209    // check consitency of signal/slot methods/args
01210    Int_t nsigargs;
01211    if ((nsigargs = CheckConnectArgs(0, sender, signal_name, 0, slot_name)) == -1)
01212       return kFALSE;
01213 
01214    if (!slist) {
01215       slist = ((TQClass*)sender)->fListOfSignals = new THashList();
01216    }
01217 
01218    TQConnectionList *clist = (TQConnectionList*)
01219       slist->FindObject(signal_name);
01220 
01221    if (!clist) {
01222       clist = new TQConnectionList(signal_name, nsigargs);
01223       slist->Add(clist);
01224    }
01225 
01226    TQConnection *connection = 0;
01227    TIter next(clist);
01228 
01229    while ((connection = (TQConnection*)next())) {
01230       if (!strcmp(slot_name,connection->GetName()) &&
01231           (receiver == connection->GetReceiver())) break;
01232    }
01233 
01234    if (!connection)
01235       connection = new TQConnection(cl, receiver, slot_name);
01236 
01237    // check to prevent multiple entries
01238    if (!clist->FindObject(connection)) {
01239       clist->Add(connection);
01240       if (!connection->FindObject(clist)) connection->Add(clist);
01241       ((TQClass*)sender)->Connected(signal_name);
01242    }
01243 
01244    return kTRUE;
01245 }
01246 
01247 //______________________________________________________________________________
01248 Bool_t TQObject::Connect(const char *signal,
01249                          const char *receiver_class,
01250                          void *receiver,
01251                          const char *slot)
01252 {
01253    // Non-static method is used to connect from the signal
01254    // of this object to the receiver slot.
01255    //
01256    // Warning! No check on consistency of sender/receiver
01257    // classes/methods.
01258    //
01259    // This method makes possible to have connection/signals from
01260    // interpreted class. See also RQ_OBJECT.h.
01261 
01262    // remove "const" and strip blanks
01263    TString signal_name = CompressName(signal);
01264    TString slot_name   = CompressName(slot);
01265 
01266    // check consitency of signal/slot methods/args
01267    TClass *cl = 0;
01268    if (receiver_class)
01269       cl = TClass::GetClass(receiver_class);
01270    Int_t nsigargs;
01271    if ((nsigargs = CheckConnectArgs(this, IsA(), signal_name, cl, slot_name)) == -1)
01272       return kFALSE;
01273 
01274    if (!fListOfSignals) fListOfSignals = new THashList();
01275 
01276    TQConnectionList *clist = (TQConnectionList*)
01277       fListOfSignals->FindObject(signal_name);
01278 
01279    if (!clist) {
01280       clist = new TQConnectionList(signal_name, nsigargs);
01281       fListOfSignals->Add(clist);
01282    }
01283 
01284    TIter next(clist);
01285    TQConnection *connection = 0;
01286 
01287    while ((connection = (TQConnection*)next())) {
01288       if (!strcmp(slot_name,connection->GetName()) &&
01289           (receiver == connection->GetReceiver())) break;
01290    }
01291 
01292    if (!connection)
01293       connection = new TQConnection(receiver_class, receiver, slot_name);
01294 
01295    // check to prevent multiple entries
01296    if (!clist->FindObject(connection)) {
01297       clist->Add(connection);
01298       if (!connection->FindObject(clist)) connection->Add(clist);
01299       Connected(signal_name);
01300    }
01301 
01302    return kTRUE;
01303 }
01304 
01305 //______________________________________________________________________________
01306 Bool_t TQObject::Disconnect(TQObject *sender,
01307                             const char *signal,
01308                             void *receiver,
01309                             const char *slot)
01310 {
01311    // Disconnects signal in object sender from slot_method in
01312    // object receiver. For objects derived from TQObject signal-slot
01313    // connection is removed when either of the objects involved
01314    // are destroyed.
01315    //
01316    // Disconnect() is typically used in three ways, as the following
01317    // examples shows:
01318    //
01319    //  - Disconnect everything connected to an object's signals:
01320    //       Disconnect(myObject);
01321    //  - Disconnect everything connected to a signal:
01322    //       Disconnect(myObject, "mySignal()");
01323    //  - Disconnect a specific receiver:
01324    //       Disconnect(myObject, 0, myReceiver, 0);
01325    //
01326    // 0 may be used as a wildcard in three of the four arguments,
01327    // meaning "any signal", "any receiving object" or
01328    // "any slot in the receiving object", respectively.
01329    //
01330    // The sender has no default and may never be 0
01331    // (you cannot disconnect signals from more than one object).
01332    //
01333    // If signal is 0, it disconnects receiver and slot_method
01334    // from any signal. If not, only the specified signal is
01335    // disconnected.
01336    //
01337    // If  receiver is 0, it disconnects anything connected to signal.
01338    // If not, slots in objects other than receiver are not
01339    // disconnected
01340    //
01341    // If slot_method is 0, it disconnects anything that is connected
01342    // to receiver.  If not, only slots named slot_method will be
01343    // disconnected, and all other slots are left alone.
01344    // The slot_method must be 0 if receiver is left out, so you
01345    // cannot disconnect a specifically-named slot on all objects.
01346 
01347    Bool_t return_value = kFALSE;
01348    Bool_t next_return  = kFALSE;
01349 
01350    if (!sender->GetListOfSignals()) return kFALSE;
01351 
01352    TString signal_name = CompressName(signal);
01353    TString slot_name   = CompressName(slot);
01354 
01355    TQConnectionList *slist = 0;
01356    TIter next_signal(sender->GetListOfSignals());
01357 
01358    while ((slist = (TQConnectionList*)next_signal()))   {
01359       if (!signal || signal_name.IsNull()) { // disconnect all signals
01360          next_return = slist->Disconnect(receiver,slot_name);
01361          return_value = return_value || next_return;
01362 
01363          if (slist->IsEmpty()) {
01364             sender->GetListOfSignals()->Remove(slist);
01365             SafeDelete(slist);            // delete empty list
01366          }
01367       } else if (signal && !strcmp(signal_name,slist->GetName())) {
01368          next_return = slist->Disconnect(receiver,slot_name);
01369          return_value = return_value || next_return;
01370 
01371          if (slist->IsEmpty()) {
01372             sender->GetListOfSignals()->Remove(slist);
01373             SafeDelete(slist);            // delete empty list
01374             break;
01375          }
01376       }
01377    }
01378 
01379    if (sender->GetListOfSignals() && sender->GetListOfSignals()->IsEmpty()) {
01380       SafeDelete(sender->fListOfSignals);
01381    }
01382 
01383    return return_value;
01384 }
01385 
01386 //______________________________________________________________________________
01387 Bool_t TQObject::Disconnect(const char *class_name,
01388                             const char *signal,
01389                             void *receiver,
01390                             const char *slot)
01391 {
01392    // Disconnects "class signal". The class is defined by class_name.
01393    // See also Connect(class_name,signal,receiver,slot).
01394 
01395    TClass *sender = TClass::GetClass(class_name);
01396 
01397    // sender should be TQClass (which derives from TQObject)
01398    if (!sender->IsA()->InheritsFrom(TQObject::Class()))
01399       return kFALSE;
01400 
01401    TQClass *qcl = (TQClass*)sender;   // cast TClass to TQClass
01402    return Disconnect(qcl, signal, receiver, slot);
01403 }
01404 
01405 //______________________________________________________________________________
01406 Bool_t TQObject::Disconnect(const char *signal,
01407                             void *receiver,
01408                             const char *slot)
01409 {
01410    // Disconnects signal of this object from slot of receiver.
01411    // Equivalent to Disconnect(this, signal, receiver, slot)
01412 
01413    return Disconnect(this, signal, receiver, slot);
01414 }
01415 
01416 //______________________________________________________________________________
01417 void TQObject::Streamer(TBuffer &R__b)
01418 {
01419    // Stream an object of class TQObject.
01420 
01421    if (R__b.IsReading()) {
01422       // nothing to read
01423    } else {
01424       // nothing to write
01425    }
01426 }
01427 
01428 //______________________________________________________________________________
01429 Bool_t TQObject::AreAllSignalsBlocked()
01430 {
01431    // Returns true if all signals are blocked.
01432 
01433    return fgAllSignalsBlocked;
01434 }
01435 
01436 //______________________________________________________________________________
01437 Bool_t TQObject::BlockAllSignals(Bool_t b)
01438 {
01439    // Block or unblock all signals. Returns the previous block status.
01440 
01441    Bool_t ret = fgAllSignalsBlocked;
01442    fgAllSignalsBlocked = b;
01443    return ret;
01444 }
01445 
01446 //______________________________________________________________________________
01447 void TQObject::LoadRQ_OBJECT()
01448 {
01449    // Load RQ_OBJECT.h which contains the #define RQ_OBJECT needed to
01450    // let interpreted classes connect to signals of compiled classes.
01451 
01452    gCint->LoadText(RQ_OBJECT_STRING1);
01453    gCint->LoadText(RQ_OBJECT_STRING2);
01454    gCint->LoadText(RQ_OBJECT_STRING);
01455 
01456 }
01457 
01458 // Global function which simplifies making connection in interpreted
01459 // ROOT session
01460 //
01461 //  ConnectCINT      - connects to interpreter(CINT) command
01462 
01463 //______________________________________________________________________________
01464 Bool_t ConnectCINT(TQObject *sender, const char *signal, const char *slot)
01465 {
01466    TString str = "ProcessLine(=";
01467    str += '"';
01468    str += slot;
01469    str += '"';
01470    str += ")";
01471    return TQObject::Connect(sender, signal, "TInterpreter",
01472                             gInterpreter, str.Data());
01473 }

Generated on Tue Jul 5 14:11:23 2011 for ROOT_528-00b_version by  doxygen 1.5.1