1 /*=========================================================================
2 
3   Copyright 2004 Sandia Corporation.
4   Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
5   license for use of this work by or on behalf of the
6   U.S. Government. Redistribution and use in source and binary forms, with
7   or without modification, are permitted provided that this Notice and any
8   statement of authorship are reproduced on all copies.
9 
10 =========================================================================*/
11 
12 /*========================================================================
13  For general information about using VTK and Qt, see:
14  http://www.trolltech.com/products/3rdparty/vtksupport.html
15 =========================================================================*/
16 
17 /*========================================================================
18  !!! WARNING for those who want to contribute code to this file.
19  !!! If you use a commercial edition of Qt, you can modify this code.
20  !!! If you use an open source version of Qt, you are free to modify
21  !!! and use this code within the guidelines of the GPL license.
22  !!! Unfortunately, you cannot contribute the changes back into this
23  !!! file.  Doing so creates a conflict between the GPL and BSD-like VTK
24  !!! license.
25 =========================================================================*/
26 
27 #include "vtkQtConnection.h"
28 #include "vtkCallbackCommand.h"
29 #include "vtkEventQtSlotConnect.h"
30 
31 #include <qmetaobject.h>
32 #include <qobject.h>
33 
34 // constructor
vtkQtConnection(vtkEventQtSlotConnect * owner)35 vtkQtConnection::vtkQtConnection(vtkEventQtSlotConnect* owner)
36   : Owner(owner)
37 {
38   this->Callback = vtkCallbackCommand::New();
39   this->Callback->SetCallback(vtkQtConnection::DoCallback);
40   this->Callback->SetClientData(this);
41   this->VTKObject = nullptr;
42   this->QtObject = nullptr;
43   this->ClientData = nullptr;
44   this->VTKEvent = vtkCommand::NoEvent;
45 }
46 
47 // destructor, disconnect if necessary
~vtkQtConnection()48 vtkQtConnection::~vtkQtConnection()
49 {
50   if (this->VTKObject)
51   {
52     this->VTKObject->RemoveObserver(this->Callback);
53     // Qt takes care of disconnecting slots
54   }
55   this->Callback->Delete();
56 }
57 
DoCallback(vtkObject * vtk_obj,unsigned long event,void * client_data,void * call_data)58 void vtkQtConnection::DoCallback(
59   vtkObject* vtk_obj, unsigned long event, void* client_data, void* call_data)
60 {
61   vtkQtConnection* conn = static_cast<vtkQtConnection*>(client_data);
62   conn->Execute(vtk_obj, event, call_data);
63 }
64 
65 // callback from VTK to emit signal
Execute(vtkObject * caller,unsigned long e,void * call_data)66 void vtkQtConnection::Execute(vtkObject* caller, unsigned long e, void* call_data)
67 {
68   if (e != vtkCommand::DeleteEvent || (this->VTKEvent == vtkCommand::DeleteEvent))
69   {
70     Q_EMIT EmitExecute(caller, e, ClientData, call_data, this->Callback);
71   }
72 
73   if (e == vtkCommand::DeleteEvent)
74   {
75     this->Owner->Disconnect(this->VTKObject, this->VTKEvent, this->QtObject,
76       this->QtSlot.toUtf8().data(), this->ClientData);
77   }
78 }
79 
IsConnection(vtkObject * vtk_obj,unsigned long e,const QObject * qt_obj,const char * slot,void * client_data)80 bool vtkQtConnection::IsConnection(
81   vtkObject* vtk_obj, unsigned long e, const QObject* qt_obj, const char* slot, void* client_data)
82 {
83   if (this->VTKObject != vtk_obj)
84     return false;
85 
86   if (e != vtkCommand::NoEvent && e != this->VTKEvent)
87     return false;
88 
89   if (qt_obj && qt_obj != this->QtObject)
90     return false;
91 
92   if (slot && this->QtSlot != slot)
93     return false;
94 
95   if (client_data && this->ClientData != client_data)
96     return false;
97 
98   return true;
99 }
100 
101 // set the connection
SetConnection(vtkObject * vtk_obj,unsigned long e,const QObject * qt_obj,const char * slot,void * client_data,float priority,Qt::ConnectionType type)102 void vtkQtConnection::SetConnection(vtkObject* vtk_obj, unsigned long e, const QObject* qt_obj,
103   const char* slot, void* client_data, float priority, Qt::ConnectionType type)
104 {
105   // keep track of what we connected
106   this->VTKObject = vtk_obj;
107   this->QtObject = qt_obj;
108   this->VTKEvent = e;
109   this->ClientData = client_data;
110   this->QtSlot = slot;
111 
112   // make a connection between this and the vtk object
113   vtk_obj->AddObserver(e, this->Callback, priority);
114 
115   if (e != vtkCommand::DeleteEvent)
116   {
117     vtk_obj->AddObserver(vtkCommand::DeleteEvent, this->Callback);
118   }
119 
120   // make a connection between this and the Qt object
121   qt_obj->connect(
122     this, SIGNAL(EmitExecute(vtkObject*, unsigned long, void*, void*, vtkCommand*)), slot, type);
123   QObject::connect(qt_obj, SIGNAL(destroyed(QObject*)), this, SLOT(deleteConnection()));
124 }
125 
deleteConnection()126 void vtkQtConnection::deleteConnection()
127 {
128   this->Owner->RemoveConnection(this);
129 }
130 
PrintSelf(ostream & os,vtkIndent indent)131 void vtkQtConnection::PrintSelf(ostream& os, vtkIndent indent)
132 {
133   if (this->VTKObject && this->QtObject)
134   {
135     os << indent << this->VTKObject->GetClassName() << ":"
136        << vtkCommand::GetStringFromEventId(this->VTKEvent) << "  <---->  "
137        << this->QtObject->metaObject()->className() << "::" << this->QtSlot.toUtf8().data() << "\n";
138   }
139 }
140