Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TQObject.cxx
Go to the documentation of this file.
1// @(#)root/base:$Id: 5d6810ad46b864564f576f88aa9b154789d91d48 $
2// Author: Valeriy Onuchin & Fons Rademakers 15/10/2000
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/** \class TQObject
13\ingroup Base
14
15This is the ROOT implementation of the Qt object communication
16mechanism (see also http://www.troll.no/qt/metaobjects.html)
17
18Signals and slots are used for communication between objects.
19When an object has changed in some way that might be interesting
20for the outside world, it emits a signal to tell whoever is
21listening. All slots that are connected to this signal will be
22activated (called). It is even possible to connect a signal
23directly to another signal (this will emit the second signal
24immediately whenever the first is emitted.) There is no limitation
25on the number of slots that can be connected to a signal.
26The slots will be activated in the order they were connected
27to the signal. This mechanism allows objects to be easily reused,
28because the object that emits a signal does not need to know
29to which objects the signals are connected.
30Together, signals and slots make up a powerfull component
31programming mechanism.
32
33### Signals
34
35~~~ {.cpp}
36 Destroyed()
37~~~
38Signal emitted when object is destroyed.
39This signal could be connected to some garbage-collector object.
40
41~~~ {.cpp}
42 ChangedBy(const char *method_name)
43~~~
44This signal is emitted when some important data members of
45the object were changed. method_name parameter can be used
46as an identifier of the modifier method.
47
48~~~ {.cpp}
49 Message(const char *msg)
50~~~
51
52General purpose message signal
53*/
54
55#include "TQObject.h"
56#include "TQConnection.h"
57#include "THashList.h"
58#include "TPRegexp.h"
59#include "TROOT.h"
60#include "TBuffer.h"
61#include "TClass.h"
62#include "TMethod.h"
63#include "TBaseClass.h"
64#include "TDataType.h"
65#include "TInterpreter.h"
66#include "TQClass.h"
67#include "TError.h"
68#include <iostream>
69#include "RQ_OBJECT.h"
70#include "TVirtualMutex.h"
71#include "RConfigure.h"
72#include "strlcpy.h"
73
74void *gTQSender; // A pointer to the object that sent the last signal.
75 // Getting access to the sender might be practical
76 // when many signals are connected to a single slot.
77
79
80
81////////////////////////////////////////////////////////////////////////////////
82/// Removes "const" words and blanks from full (with prototype)
83/// method name and resolve any typedefs in the method signature.
84/// If a null or empty string is passed in, an empty string
85/// is returned.
86///
87/// Example:
88/// ~~~ {.cpp}
89/// CompressName(" Draw(const char *, const char *,
90/// Option_t * , Int_t , Int_t)");
91/// ~~~
92/// returns the string "Draw(char*,char*,char*,int,int)".
93
95{
97 if (res.IsNull())
98 return res;
99
100 {
101 static TVirtualMutex * lock = nullptr;
102 R__LOCKGUARD2(lock);
103
104 static TPMERegexp *constRe = nullptr, *wspaceRe = nullptr;
105 if (constRe == nullptr) {
106 constRe = new TPMERegexp("(?<=\\(|\\s|,|&|\\*)const(?=\\s|,|\\)|&|\\*)", "go");
107 wspaceRe = new TPMERegexp("\\s+(?=([^\"]*\"[^\"]*\")*[^\"]*$)", "go");
108 }
109 constRe ->Substitute(res, "");
110 wspaceRe->Substitute(res, "");
111 }
112
113 TStringToken methargs(res, "\\(|\\)", kTRUE);
114
115 methargs.NextToken();
116 res = methargs;
117 res += "(";
118
119 methargs.NextToken();
120 TStringToken arg(methargs, ",");
121 while (arg.NextToken())
122 {
123 Int_t pri = arg.Length() - 1;
124 Char_t prc = 0;
125 if (arg[pri] == '*' || arg[pri] == '&') {
126 prc = arg[pri];
127 arg.Remove(pri);
128 }
129 TDataType *dt = gROOT->GetType(arg.Data());
130 if (dt) {
131 res += dt->GetFullTypeName();
132 } else {
133 res += arg;
134 }
135 if (prc) res += prc;
136 if (!arg.AtEnd()) res += ",";
137 }
138 res += ")";
139 return res;
140}
141
142namespace {
143
144////////////////////////////////////////////////////////////////////////////////
145/// Almost the same as TClass::GetMethodWithPrototype().
146
147TMethod *GetMethodWithPrototype(TClass *cl, const char *method,
148 const char *proto, Int_t &nargs)
149{
150 nargs = 0;
151
152 if (!gInterpreter || cl == nullptr) return nullptr;
153
155 if (m) nargs = m->GetNargs();
156 return m;
157}
158
159////////////////////////////////////////////////////////////////////////////////
160/// Almost the same as TClass::GetMethod().
161
162static TMethod *GetMethod(TClass *cl, const char *method, const char *params)
163{
164 if (!gInterpreter || cl == nullptr) return nullptr;
165 return cl->GetMethod(method,params);
166}
167
168}
169
170////////////////////////////////////////////////////////////////////////////////
171/// Checking of consistency of sender/receiver methods/arguments.
172/// Returns -1 on error, otherwise number or arguments of signal function.
173/// Static method.
174
176 TClass *sender_class, const char *signal,
177 TClass *receiver_class, const char *slot)
178{
179 auto len = strlen(signal)+1;
180 char *signal_method = new char[len];
182
183 char *signal_proto;
184 char *tmp;
185
186 if ((signal_proto = strchr(signal_method,'('))) {
187 // substitute first '(' symbol with '\0'
188 *signal_proto++ = '\0';
189 // substitute last ')' symbol with '\0'
190 if ((tmp = strrchr(signal_proto,')'))) *tmp = '\0';
191 }
192
193 if (!signal_proto) signal_proto = (char*)""; // avoid zero strings
194
195 // if delegation object TQObjSender is used get the real sender class
197 sender_class = TClass::GetClass(sender->GetSenderClassName());
198 if (!sender_class) {
199 ::Error("TQObject::CheckConnectArgs", "for signal/slot consistency\n"
200 "checking need to specify class name as argument to "
201 "RQ_OBJECT macro");
202 delete [] signal_method;
203 return -1;
204 }
205 }
206
207 Int_t nargs;
208 TMethod *signalMethod = GetMethodWithPrototype(sender_class,
211 nargs);
212 if (!signalMethod) {
213 ::Error("TQObject::CheckConnectArgs", "signal %s::%s(%s) does not exist",
215 delete [] signal_method;
216 return -1;
217 }
219
220#if defined(CHECK_COMMENT_STRING)
221 const char *comment = 0;
222 if (signalMethod != (TMethod *) -1) // -1 in case of interpreted class
223 comment = signalMethod->GetCommentString();
224
225 if (!comment || !comment[0] || strstr(comment,"*SIGNAL")){
226 ::Error("TQObject::CheckConnectArgs",
227 "signal %s::%s(%s), to declare signal use comment //*SIGNAL*",
229 delete [] signal_method;
230 return -1;
231 }
232#endif
233
234 // cleaning
235 delete [] signal_method;
236
237 auto len2 = strlen(slot)+1;
238 char *slot_method = new char[len2];
240
241 char *slot_proto;
242 char *slot_params = nullptr;
243
244 if ((slot_proto = strchr(slot_method,'('))) {
245
246 // substitute first '(' symbol with '\0'
247 *slot_proto++ = '\0';
248
249 // substitute last ')' symbol with '\0'
250 if ((tmp = strrchr(slot_proto,')'))) *tmp = '\0';
251 }
252
253 if (!slot_proto) slot_proto = (char*)""; // avoid zero strings
254 if ((slot_params = strchr(slot_proto,'='))) *slot_params = ' ';
255
256 TFunction *slotMethod = nullptr;
257 if (!receiver_class) {
258 // case of slot_method is compiled/intrepreted function
259 slotMethod = gROOT->GetGlobalFunction(slot_method,nullptr,kFALSE);
260 } else {
262 GetMethodWithPrototype(receiver_class,
265 nargs) :
266 GetMethod(receiver_class,
268 }
269
270 if (!slotMethod) {
271 if (!slot_params) {
272 ::Error("TQObject::CheckConnectArgs", "slot %s(%s) does not exist",
273 receiver_class ? Form("%s::%s", receiver_class->GetName(),
275 } else {
276 ::Error("TQObject::CheckConnectArgs", "slot %s(%s) does not exist",
277 receiver_class ? Form("%s::%s", receiver_class->GetName(),
279 }
280 delete [] slot_method;
281 return -1;
282 }
283
284#if defined(CHECK_ARGS_NUMBER)
285 if (slotMethod != (TMethod *) -1 && slotMethod->GetNargsOpt() >= 0 &&
286 nsigargs < (slotMethod->GetNargs() - slotMethod->GetNargsOpt())) {
287 ::Error("TQObject::CheckConnectArgs",
288 "inconsistency in numbers of arguments");
289 delete [] slot_method;
290 return -1;
291 }
292#endif
293
294 // cleaning
295 delete [] slot_method;
296
297 return nsigargs;
298}
299
300/** \class TQConnectionList
301 TQConnectionList is the named list of connections,
302 see also TQConnection class.
303*/
304
305class TQConnectionList : public TList {
306
307private:
308 Int_t fSignalArgs; // number of arguments in signal function
309
310public:
313 ~TQConnectionList() override;
314
315 Bool_t Disconnect(void *receiver = nullptr, const char *slot_name = nullptr);
316 Int_t GetNargs() const { return fSignalArgs; }
317 void ls(Option_t *option = "") const override;
318};
319
320////////////////////////////////////////////////////////////////////////////////
321/// Destructor.
322
324{
325 TIter next(this);
327
328 while ((connection = (TQConnection*)next())) {
329 // remove this from feed back reference list
330 connection->Remove(this);
331 if (connection->IsEmpty()) delete connection;
332 }
333 Clear("nodelete");
334}
335
336////////////////////////////////////////////////////////////////////////////////
337/// Remove connection from the list. For more info see
338/// TQObject::Disconnect()
339
341{
342 TQConnection *connection = nullptr;
344
346 TObjLink *savlnk; // savlnk is used when link is deleted
347
348 while (lnk) {
349 connection = (TQConnection*)lnk->GetObject();
350 const char *name = connection->GetName();
351 void *obj = connection->GetReceiver();
352
353 if (!slot_name || !slot_name[0]
354 || !strcmp(name,slot_name)) {
355
356 if (!receiver || (receiver == obj)) {
358 savlnk = lnk->Next(); // keep next link ..
359 Remove(lnk);
360 lnk = savlnk; // current link == saved ...
361 connection->Remove(this); // remove back reference
362 if (connection->IsEmpty()) SafeDelete(connection);
363 continue; // .. continue from saved link
364 }
365 }
366 lnk = lnk->Next();
367 }
368 return return_value;
369}
370
371////////////////////////////////////////////////////////////////////////////////
372/// List signal name and list all connections in this signal list.
373
375{
376 std::cout << "TQConnectionList:" << "\t" << GetName() << std::endl;
377 ((TQConnectionList*)this)->R__FOR_EACH(TQConnection,Print)(option);
378}
379
380
381////////////////////////////////////////////////////////////////////////////////
382/// TQObject Constructor.
383/// Comment:
384/// - In order to minimize memory allocation fListOfSignals and
385/// fListOfConnections are allocated only if it is neccesary
386/// - When fListOfSignals/fListOfConnections are empty they will
387/// be deleted
388
390{
391 fListOfSignals = nullptr;
392 fListOfConnections = nullptr;
394}
395
396////////////////////////////////////////////////////////////////////////////////
397/// TQObject Destructor.
398/// - delete all connections and signal list
399
401{
402 if (!gROOT) return;
403
404 Destroyed(); // emit "Destroyed()" signal
405
406 if (fListOfSignals) {
408 SafeDelete(fListOfSignals); // delete list of signals
409 }
410
411 // loop over all connections and remove references to this object
412 if (fListOfConnections) {
415
416 while ((connection = (TQConnection*)next_connection())) {
418 TQConnectionList *list;
419 while ((list = (TQConnectionList*)next_list())) {
420 list->Remove(connection);
421 if (list->IsEmpty()) SafeDelete(list);
422 }
423 }
425 }
426}
427
428////////////////////////////////////////////////////////////////////////////////
429/// Returns pointer to list of signals of this class.
430
432{
433 TQClass *qcl = nullptr;
434
435 qcl = dynamic_cast<TQClass*>(IsA());
436
437 return qcl ? qcl->fListOfSignals : nullptr; //!!
438}
439
440////////////////////////////////////////////////////////////////////////////////
441/// Collect class signal lists from class cls and all its
442/// base-classes.
443///
444/// The recursive traversal is not performed for classes not
445/// deriving from TQClass.
446
448{
449 TQClass *qcl = dynamic_cast<TQClass*>(cls);
450 if (qcl)
451 {
452 if (qcl->fListOfSignals)
453 list.Add(qcl->fListOfSignals);
454
455 // Descend into base-classes.
456 TIter next_base_class(cls->GetListOfBases());
457 TBaseClass *base;
458 while ((base = (TBaseClass*) next_base_class()))
459 {
461 }
462 }
463}
464
465////////////////////////////////////////////////////////////////////////////////
466/// 1. If slot_name = 0 => makes signal defined by the signal_name
467/// to be the first in the fListOfSignals, this decreases
468/// the time for lookup.
469/// 2. If slot_name != 0 => makes slot defined by the slot_name
470/// to be executed first when signal_name is emitted.
471/// Signal name is not compressed.
472
473void TQObject::HighPriority(const char *signal_name, const char *slot_name)
474{
475 if (!fListOfSignals) return;
478
479 if (!clist) return; // not found
480 if (!slot_name) { // update list of signal lists
481 fListOfSignals->Remove(clist); // remove and add first
483 return;
484 } else { // slot_name != 0 , update signal list
485 TQConnection *con = (TQConnection*) clist->FindObject(slot_name);
486 if (!con) return; // not found
487 clist->Remove(con); // remove and add as first
488 clist->AddFirst(con);
489 }
490}
491
492////////////////////////////////////////////////////////////////////////////////
493/// 1. If slot_name = 0 => makes signal defined by the signal_name
494/// to be the last in the fListOfSignals, this increase the time
495/// for lookup.
496/// 2. If slot_name != 0 => makes slot defined by the slot_name
497/// to be executed last when signal_name is emitted.
498/// Signal name is not compressed.
499
500void TQObject::LowPriority(const char *signal_name, const char *slot_name)
501{
502 if (!fListOfSignals) return;
505
506 if (!clist) return;
507 if (!slot_name) {
508 fListOfSignals->Remove(clist); // remove and add first
510 return;
511 } else { // slot_name != 0 , update signal list
512 TQConnection *con = (TQConnection*) clist->FindObject(slot_name);
513 if (!con) return;
514 clist->Remove(con); // remove and add as last
515 clist->AddLast(con);
516 }
517}
518
519////////////////////////////////////////////////////////////////////////////////
520/// Return true if there is any object connected to this signal.
521/// Only checks for object signals.
522
524{
525 if (!fListOfSignals)
526 return kFALSE;
527
529
530 return (fListOfSignals->FindObject(signal) != nullptr);
531}
532
533////////////////////////////////////////////////////////////////////////////////
534/// Return number of signals for this object.
535/// Only checks for object signals.
536
538{
539 if (fListOfSignals)
540 return fListOfSignals->GetSize();
541 return 0;
542}
543
544////////////////////////////////////////////////////////////////////////////////
545/// Return number of connections for this object.
546
548{
550 return fListOfConnections->GetSize();
551 return 0;
552}
553
554
555////////////////////////////////////////////////////////////////////////////////
556/// Create connection between sender and receiver.
557/// Receiver class needs to have a dictionary.
558
560 const char *signal,
561 TClass *cl,
562 void *receiver,
563 const char *slot)
564{
565 // sender should be TQObject
566 if (!sender->IsA()->InheritsFrom(TQObject::Class()))
567 return kFALSE;
568
569 // remove "const" and strip blanks
572
573 // check consistency of signal/slot methods/args
575 if ((nsigargs = CheckConnectArgs(sender, sender->IsA(), signal_name, cl, slot_name)) == -1)
576 return kFALSE;
577
578 if (!sender->fListOfSignals)
579 sender->fListOfSignals = new THashList();
580
582 sender->fListOfSignals->FindObject(signal_name);
583
584 if (!clist) {
586 sender->fListOfSignals->Add(clist);
587 }
588
589 TIter next(clist);
590 TQConnection *connection = nullptr;
591
592 while ((connection = (TQConnection*)next())) {
593 if (!strcmp(slot_name,connection->GetName()) &&
594 (receiver == connection->GetReceiver())) break;
595 }
596
597 if (!connection)
599
600 // check to prevent multiple entries
601 if (!clist->FindObject(connection)) {
602 clist->Add(connection);
603 if (!connection->FindObject(clist)) connection->Add(clist);
604 sender->Connected(signal_name);
605 }
606
607 return kTRUE;
608}
609
610////////////////////////////////////////////////////////////////////////////////
611/// This method allows to make connection from any object
612/// of the same class to the receiver object.
613/// Receiver class needs to have a dictionary.
614
616 const char *signal,
617 TClass *cl,
618 void *receiver,
619 const char *slot)
620{
622
623 // sender class should be TQObject (i.e. TQClass)
624 if (!sender || !sender->IsA()->InheritsFrom(TQObject::Class()))
625 return kFALSE;
626
627 TList *slist = ((TQClass*)sender)->fListOfSignals;
630
631 // check consistency of signal/slot methods/args
633 if ((nsigargs = CheckConnectArgs(nullptr, sender, signal_name, cl, slot_name)) == -1)
634 return kFALSE;
635
636 if (!slist)
637 ((TQClass*)sender)->fListOfSignals = slist = new THashList();
638
640
641 if (!clist) {
643 slist->Add(clist);
644 }
645
646 TQConnection *connection = nullptr;
647 TIter next(clist);
648
649 while ((connection = (TQConnection*)next())) {
650 if (!strcmp(slot_name,connection->GetName()) &&
651 (receiver == connection->GetReceiver())) break;
652 }
653
654 if (!connection)
656
657 // check to prevent multiple entries
658 if (!clist->FindObject(connection)) {
659 clist->Add(connection);
660 if (!connection->FindObject(clist)) connection->Add(clist);
661 ((TQClass*)sender)->Connected(signal_name);
662 }
663
664 return kTRUE;
665}
666
667////////////////////////////////////////////////////////////////////////////////
668/// Create connection between sender and receiver.
669/// Signal and slot string must have a form:
670/// "Draw(char*, Option_t* ,Int_t)"
671/// All blanks and "const" words will be removed,
672///
673/// cl != 0 - class name, it can be class with or
674/// without dictionary, e.g interpreted class.
675/// Example:
676/// ~~~ {.cpp}
677/// TGButton *myButton;
678/// TH2F *myHist;
679///
680/// TQObject::Connect(myButton,"Clicked()",
681/// "TH2F", myHist,"Draw(Option_t*)");
682/// ~~~
683/// cl == 0 - corresponds to function (interpereted or global)
684/// the name of the function is defined by the slot string,
685/// parameter receiver should be 0.
686/// Example:
687/// ~~~ {.cpp}
688/// TGButton *myButton;
689/// TH2F *myHist;
690///
691/// TQObject::Connect(myButton,"Clicked()",
692/// 0, 0,"hsimple()");
693/// ~~~
694/// Warning:
695/// If receiver is class not derived from TQObject and going to be
696/// deleted, disconnect all connections to this receiver.
697/// In case of class derived from TQObject it is done automatically.
698
700 const char *signal,
701 const char *cl,
702 void *receiver,
703 const char *slot)
704{
705 if (cl) {
708 }
709
710 // the following is the case of receiver class without dictionary
711 // e.g. interpreted class or function.
712
713 // sender should be TQObject
714 if (!sender->IsA()->InheritsFrom(TQObject::Class()))
715 return kFALSE;
716
717 // remove "const" and strip blanks
720
721 // check consistency of signal/slot methods/args
723 if ((nsigargs = CheckConnectArgs(sender, sender->IsA(), signal_name, nullptr, slot_name)) == -1)
724 return kFALSE;
725
726 if (!sender->fListOfSignals) sender->fListOfSignals = new THashList();
727
729 sender->fListOfSignals->FindObject(signal_name);
730
731 if (!clist) {
733 sender->fListOfSignals->Add(clist);
734 }
735
736 TQConnection *connection = nullptr;
737 TIter next(clist);
738
739 while ((connection = (TQConnection*)next())) {
740 if (!strcmp(slot_name,connection->GetName()) &&
741 (receiver == connection->GetReceiver())) break;
742 }
743
744 if (!connection)
746
747 // check to prevent multiple entries
748 if (!clist->FindObject(connection)) {
749 clist->Add(connection);
750 if (!connection->FindObject(clist)) connection->Add(clist);
751 sender->Connected(signal_name);
752 }
753
754 return kTRUE;
755}
756
757////////////////////////////////////////////////////////////////////////////////
758/// This method allows to make a connection from any object
759/// of the same class to a single slot.
760/// Signal and slot string must have a form:
761/// "Draw(char*, Option_t* ,Int_t)"
762/// All blanks and "const" words will be removed,
763///
764/// cl != 0 - class name, it can be class with or
765/// without dictionary, e.g interpreted class.
766/// Example:
767/// ~~~ {.cpp}
768/// TGButton *myButton;
769/// TH2F *myHist;
770///
771/// TQObject::Connect("TGButton", "Clicked()",
772/// "TH2F", myHist, "Draw(Option_t*)");
773/// ~~~
774/// cl == 0 - corresponds to function (interpereted or global)
775/// the name of the function is defined by the slot string,
776/// parameter receiver should be 0.
777/// Example:
778/// ~~~ {.cpp}
779/// TGButton *myButton;
780/// TH2F *myHist;
781///
782/// TQObject::Connect("TGButton", "Clicked()",
783/// 0, 0, "hsimple()");
784/// ~~~
785/// Warning:
786///
787/// If receiver class not derived from TQObject and going to be
788/// deleted, disconnect all connections to this receiver.
789/// In case of class derived from TQObject it is done automatically.
790
792 const char *signal,
793 const char *cl,
794 void *receiver,
795 const char *slot)
796{
797 if (cl) {
800 slot);
801 }
802
803 // the following is case of receiver class without dictionary
804 // e.g. interpreted class or function.
805
807
808 // sender class should be TQObject (i.e. TQClass)
809 if (!sender || !sender->IsA()->InheritsFrom(TQObject::Class()))
810 return kFALSE;
811
812 TList *slist = ((TQClass*)sender)->fListOfSignals;
813
816
817 // check consistency of signal/slot methods/args
819 if ((nsigargs = CheckConnectArgs(nullptr, sender, signal_name, nullptr, slot_name)) == -1)
820 return kFALSE;
821
822 if (!slist) {
823 slist = ((TQClass*)sender)->fListOfSignals = new THashList();
824 }
825
827 slist->FindObject(signal_name);
828
829 if (!clist) {
831 slist->Add(clist);
832 }
833
834 TQConnection *connection = nullptr;
835 TIter next(clist);
836
837 while ((connection = (TQConnection*)next())) {
838 if (!strcmp(slot_name,connection->GetName()) &&
839 (receiver == connection->GetReceiver())) break;
840 }
841
842 if (!connection)
844
845 // check to prevent multiple entries
846 if (!clist->FindObject(connection)) {
847 clist->Add(connection);
848 if (!connection->FindObject(clist)) connection->Add(clist);
849 ((TQClass*)sender)->Connected(signal_name);
850 }
851
852 return kTRUE;
853}
854
855////////////////////////////////////////////////////////////////////////////////
856/// Non-static method is used to connect from the signal
857/// of this object to the receiver slot.
858///
859/// Warning! No check on consistency of sender/receiver
860/// classes/methods.
861///
862/// This method makes possible to have connection/signals from
863/// interpreted class. See also RQ_OBJECT.h.
864
866 const char *receiver_class,
867 void *receiver,
868 const char *slot)
869{
870 // remove "const" and strip blanks
873
874 // check consistency of signal/slot methods/args
875 TClass *cl = nullptr;
876 if (receiver_class)
879 if ((nsigargs = CheckConnectArgs(this, IsA(), signal_name, cl, slot_name)) == -1)
880 return kFALSE;
881
883
886
887 if (!clist) {
890 }
891
892 TIter next(clist);
893 TQConnection *connection = nullptr;
894
895 while ((connection = (TQConnection*)next())) {
896 if (!strcmp(slot_name,connection->GetName()) &&
897 (receiver == connection->GetReceiver())) break;
898 }
899
900 if (!connection)
902
903 // check to prevent multiple entries
904 if (!clist->FindObject(connection)) {
905 clist->Add(connection);
906 if (!connection->FindObject(clist)) connection->Add(clist);
908 }
909
910 return kTRUE;
911}
912
913////////////////////////////////////////////////////////////////////////////////
914/// Disconnects signal in object sender from slot_method in
915/// object receiver. For objects derived from TQObject signal-slot
916/// connection is removed when either of the objects involved
917/// are destroyed.
918///
919/// Disconnect() is typically used in three ways, as the following
920/// examples shows:
921///
922/// - Disconnect everything connected to an object's signals:
923/// ~~~ {.cpp}
924/// Disconnect(myObject);
925/// ~~~
926/// - Disconnect everything connected to a signal:
927/// ~~~ {.cpp}
928/// Disconnect(myObject, "mySignal()");
929/// ~~~
930/// - Disconnect a specific receiver:
931/// ~~~ {.cpp}
932/// Disconnect(myObject, 0, myReceiver, 0);
933/// ~~~
934///
935/// 0 may be used as a wildcard in three of the four arguments,
936/// meaning "any signal", "any receiving object" or
937/// "any slot in the receiving object", respectively.
938///
939/// The sender has no default and may never be 0
940/// (you cannot disconnect signals from more than one object).
941///
942/// If signal is 0, it disconnects receiver and slot_method
943/// from any signal. If not, only the specified signal is
944/// disconnected.
945///
946/// If receiver is 0, it disconnects anything connected to signal.
947/// If not, slots in objects other than receiver are not
948/// disconnected
949///
950/// If slot_method is 0, it disconnects anything that is connected
951/// to receiver. If not, only slots named slot_method will be
952/// disconnected, and all other slots are left alone.
953/// The slot_method must be 0 if receiver is left out, so you
954/// cannot disconnect a specifically-named slot on all objects.
955
957 const char *signal,
958 void *receiver,
959 const char *slot)
960{
963
964 if (!sender->GetListOfSignals()) return kFALSE;
965
968
969 TQConnectionList *slist = nullptr;
970 TIter next_signal(sender->GetListOfSignals());
971
972 while ((slist = (TQConnectionList*)next_signal())) {
973 if (!signal || signal_name.IsNull()) { // disconnect all signals
974 next_return = slist->Disconnect(receiver,slot_name);
976
977 if (slist->IsEmpty()) {
978 sender->GetListOfSignals()->Remove(slist);
979 SafeDelete(slist); // delete empty list
980 }
981 } else if (signal && !strcmp(signal_name,slist->GetName())) {
982 next_return = slist->Disconnect(receiver,slot_name);
984
985 if (slist->IsEmpty()) {
986 sender->GetListOfSignals()->Remove(slist);
987 SafeDelete(slist); // delete empty list
988 break;
989 }
990 }
991 }
992
993 if (sender->GetListOfSignals() && sender->GetListOfSignals()->IsEmpty()) {
994 SafeDelete(sender->fListOfSignals);
995 }
996
997 return return_value;
998}
999
1000////////////////////////////////////////////////////////////////////////////////
1001/// Disconnects "class signal". The class is defined by class_name.
1002/// See also Connect(class_name,signal,receiver,slot).
1003
1005 const char *signal,
1006 void *receiver,
1007 const char *slot)
1008{
1010
1011 // sender should be TQClass (which derives from TQObject)
1012 if (!sender || !sender->IsA()->InheritsFrom(TQObject::Class()))
1013 return kFALSE;
1014
1015 TQClass *qcl = (TQClass*)sender; // cast TClass to TQClass
1016 return Disconnect(qcl, signal, receiver, slot);
1017}
1018
1019////////////////////////////////////////////////////////////////////////////////
1020/// Disconnects signal of this object from slot of receiver.
1021/// Equivalent to Disconnect(this, signal, receiver, slot)
1022
1024 void *receiver,
1025 const char *slot)
1026{
1027 return Disconnect(this, signal, receiver, slot);
1028}
1029
1030////////////////////////////////////////////////////////////////////////////////
1031/// Stream an object of class TQObject.
1032
1034{
1035 if (R__b.IsReading()) {
1036 // nothing to read
1037 } else {
1038 // nothing to write
1039 }
1040}
1041
1042////////////////////////////////////////////////////////////////////////////////
1043/// Returns true if all signals are blocked.
1044
1049
1050////////////////////////////////////////////////////////////////////////////////
1051/// Block or unblock all signals. Returns the previous block status.
1052
1059
1060////////////////////////////////////////////////////////////////////////////////
1061/// Global function which simplifies making connection in interpreted ROOT session
1062///
1063/// ConnectCINT - connects to interpreter(CINT) command
1064
1065Bool_t ConnectCINT(TQObject *sender, const char *signal, const char *slot)
1066{
1067 TString str = "ProcessLine(=";
1068 str += '"';
1069 str += slot;
1070 str += '"';
1071 str += ")";
1072 return TQObject::Connect(sender, signal, "TInterpreter",
1073 gInterpreter, str.Data());
1074}
#define SafeDelete(p)
Definition RConfig.hxx:533
#define b(i)
Definition RSha256.hxx:100
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:77
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
char Char_t
Character 1 byte (char)
Definition RtypesCore.h:51
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
char name[80]
Definition TGX11.cxx:110
#define gInterpreter
void * gTQSender
Definition TQObject.cxx:74
Bool_t ConnectCINT(TQObject *sender, const char *signal, const char *slot)
Global function which simplifies making connection in interpreted ROOT session.
#define gROOT
Definition TROOT.h:411
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2495
#define R__LOCKGUARD2(mutex)
const char * proto
Definition civetweb.c:18822
Each class (see TClass) has a linked list of its base class(es).
Definition TBaseClass.h:33
TClass * GetClassPointer(Bool_t load=kTRUE)
Get pointer to the base class TClass.
Buffer base class used for serializing objects.
Definition TBuffer.h:43
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:84
TMethod * GetMethod(const char *method, const char *params, Bool_t objectIsConst=kFALSE)
Find the best method (if there is one) matching the parameters.
Definition TClass.cxx:4438
TMethod * GetMethodWithPrototype(const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch)
Find the method with a given prototype.
Definition TClass.cxx:4483
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition TClass.cxx:2973
const char * GetName() const override
Return name of this collection.
TString fName
void Print(Option_t *option="") const override
Default print for collections, calls Print(option, 1).
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Basic data type descriptor (datatype information is obtained from CINT).
Definition TDataType.h:44
Global functions class (global functions are obtained from CINT).
Definition TFunction.h:30
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition THashList.h:34
A doubly linked list.
Definition TList.h:38
void Clear(Option_t *option="") override
Remove all objects from the list.
Definition TList.cxx:399
TObject * FindObject(const char *name) const override
Find an object in this list using its name.
Definition TList.cxx:575
void Add(TObject *obj) override
Definition TList.h:81
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:819
void AddLast(TObject *obj) override
Add object at the end of the list.
Definition TList.cxx:149
virtual TObjLink * FirstLink() const
Definition TList.h:102
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:467
void AddFirst(TObject *obj) override
Add object at the beginning of the list.
Definition TList.cxx:97
Each ROOT class (see TClass) has a linked list of methods.
Definition TMethod.h:38
Wrapper for PCRE library (Perl Compatible Regular Expressions).
Definition TPRegexp.h:97
TQConnectionList is the named list of connections, see also TQConnection class.
Definition TQObject.cxx:305
void ls(Option_t *option="") const override
List signal name and list all connections in this signal list.
Definition TQObject.cxx:374
TQConnectionList(const char *name, Int_t nsigargs)
Definition TQObject.cxx:311
Bool_t Disconnect(void *receiver=nullptr, const char *slot_name=nullptr)
Remove connection from the list.
Definition TQObject.cxx:340
~TQConnectionList() override
Destructor.
Definition TQObject.cxx:323
Int_t GetNargs() const
Definition TQObject.cxx:316
TQConnection class is an internal class, used in the object communication mechanism.
static TClass * Class()
This is the ROOT implementation of the Qt object communication mechanism (see also http://www....
Definition TQObject.h:48
static Int_t CheckConnectArgs(TQObject *sender, TClass *sender_class, const char *signal, TClass *receiver_class, const char *slot)
Checking of consistency of sender/receiver methods/arguments.
Definition TQObject.cxx:175
virtual Int_t NumberOfConnections() const
Return number of connections for this object.
Definition TQObject.cxx:547
TQObject()
TQObject Constructor.
Definition TQObject.cxx:389
void CollectClassSignalLists(TList &list, TClass *cls)
Collect class signal lists from class cls and all its base-classes.
Definition TQObject.cxx:447
static Bool_t BlockAllSignals(Bool_t b)
Block or unblock all signals. Returns the previous block status.
Bool_t fSignalsBlocked
list of connections to this object
Definition TQObject.h:53
static TString CompressName(const char *method_name)
Removes "const" words and blanks from full (with prototype) method name and resolve any typedefs in t...
Definition TQObject.cxx:94
TList * GetListOfClassSignals() const
Returns pointer to list of signals of this class.
Definition TQObject.cxx:431
static Bool_t fgAllSignalsBlocked
flag used for suppression of signals
Definition TQObject.h:55
virtual Int_t NumberOfSignals() const
Return number of signals for this object.
Definition TQObject.cxx:537
virtual void Destroyed()
Definition TQObject.h:197
virtual ~TQObject()
TQObject Destructor.
Definition TQObject.cxx:400
virtual void Streamer(TBuffer &)
Stream an object of class TQObject.
TList * fListOfSignals
Definition TQObject.h:51
TList * fListOfConnections
list of signals from this object
Definition TQObject.h:52
Bool_t Connect(const char *signal, const char *receiver_class, void *receiver, const char *slot)
Non-static method is used to connect from the signal of this object to the receiver slot.
Definition TQObject.cxx:865
virtual Bool_t HasConnection(const char *signal_name) const
Return true if there is any object connected to this signal.
Definition TQObject.cxx:523
static Bool_t ConnectToClass(TQObject *sender, const char *signal, TClass *receiver_class, void *receiver, const char *slot)
Create connection between sender and receiver.
Definition TQObject.cxx:559
virtual TClass * IsA() const
Definition TQObject.h:229
virtual void LowPriority(const char *signal_name, const char *slot_name=nullptr)
Definition TQObject.cxx:500
Bool_t Disconnect(const char *signal=nullptr, void *receiver=nullptr, const char *slot=nullptr)
Disconnects signal of this object from slot of receiver.
static Bool_t AreAllSignalsBlocked()
Returns true if all signals are blocked.
virtual void HighPriority(const char *signal_name, const char *slot_name=nullptr)
Definition TQObject.cxx:473
static TClass * Class()
virtual void Connected(const char *)
Definition TQObject.h:194
Provides iteration through tokens of a given string.
Definition TPRegexp.h:143
Bool_t AtEnd() const
Definition TPRegexp.h:156
Bool_t NextToken()
Get the next token, it is stored in this TString.
Basic string class.
Definition TString.h:138
Ssiz_t Length() const
Definition TString.h:425
const char * Data() const
Definition TString.h:384
Bool_t IsNull() const
Definition TString.h:422
TString & Remove(Ssiz_t pos)
Definition TString.h:693
This class implements a mutex interface.
RPY_EXPORTED TCppMethod_t GetMethod(TCppScope_t scope, TCppIndex_t imeth)
TMarker m
Definition textangle.C:8