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