ctkVTKObjectEventsObserver.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. /*=========================================================================
  2. Library: CTK
  3. Copyright (c) 2010 Kitware Inc.
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.commontk.org/LICENSE
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. =========================================================================*/
  14. // Qt includes
  15. #include <QStringList>
  16. #include <QVariant>
  17. #include <QList>
  18. #include <QHash>
  19. #include <QDebug>
  20. // CTK includes
  21. #include "ctkVTKObjectEventsObserver.h"
  22. #include "ctkVTKConnection.h"
  23. // VTK includes
  24. #include <vtkObject.h>
  25. #include <vtkSmartPointer.h>
  26. //-----------------------------------------------------------------------------
  27. class ctkVTKObjectEventsObserverPrivate: public ctkPrivate<ctkVTKObjectEventsObserver>
  28. {
  29. public:
  30. ctkVTKObjectEventsObserverPrivate();
  31. ///
  32. /// Check if a connection has already been added
  33. bool containsConnection(vtkObject* vtk_obj, unsigned long vtk_event,
  34. const QObject* qt_obj, const char* qt_slot);
  35. ///
  36. /// Return a reference toward the corresponding connection or 0 if doesn't exist
  37. ctkVTKConnection* findConnection(const QString& id);
  38. ///
  39. /// Return a reference toward the corresponding connection or 0 if doesn't exist
  40. ctkVTKConnection* findConnection(vtkObject* vtk_obj, unsigned long vtk_event,
  41. const QObject* qt_obj, const char* qt_slot);
  42. ///
  43. /// Return all the references that match the given parameters
  44. QList<ctkVTKConnection*> findConnections(vtkObject* vtk_obj, unsigned long vtk_event,
  45. const QObject* qt_obj, const char* qt_slot);
  46. inline QList<ctkVTKConnection*> connections()const
  47. {
  48. return ctk_p()->findChildren<ctkVTKConnection*>();
  49. }
  50. bool AllEnabled;
  51. bool AllBlocked;
  52. };
  53. //-----------------------------------------------------------------------------
  54. // ctkVTKObjectEventsObserver methods
  55. //-----------------------------------------------------------------------------
  56. ctkVTKObjectEventsObserver::ctkVTKObjectEventsObserver(QObject* _parent):Superclass(_parent)
  57. {
  58. CTK_INIT_PRIVATE(ctkVTKObjectEventsObserver);
  59. this->setProperty("QVTK_OBJECT", true);
  60. }
  61. //-----------------------------------------------------------------------------
  62. void ctkVTKObjectEventsObserver::printAdditionalInfo()
  63. {
  64. this->Superclass::dumpObjectInfo();
  65. CTK_D(ctkVTKObjectEventsObserver);
  66. qDebug() << "ctkVTKObjectEventsObserver:" << this << endl
  67. << " AllEnabled:" << d->AllEnabled << endl
  68. << " AllBlocked:" << d->AllBlocked << endl
  69. << " Parent:" << (this->parent()?this->parent()->objectName():"NULL") << endl
  70. << " Connection count:" << d->connections().count();
  71. // Loop through all connection
  72. foreach (ctkVTKConnection* connection, d->connections())
  73. {
  74. connection->printAdditionalInfo();
  75. }
  76. }
  77. //-----------------------------------------------------------------------------
  78. bool ctkVTKObjectEventsObserver::allEnabled()const
  79. {
  80. return ctk_d()->AllEnabled;
  81. }
  82. //-----------------------------------------------------------------------------
  83. void ctkVTKObjectEventsObserver::setAllEnabled(bool enable)
  84. {
  85. CTK_D(ctkVTKObjectEventsObserver);
  86. // FIXME: maybe a particular module has been enabled/disabled
  87. if (d->AllEnabled == enable)
  88. {
  89. return;
  90. }
  91. // Loop through VTKQtConnections to enable/disable
  92. foreach(ctkVTKConnection* connection, d->connections())
  93. {
  94. connection->setEnabled(enable);
  95. }
  96. d->AllEnabled = enable;
  97. }
  98. //-----------------------------------------------------------------------------
  99. QString ctkVTKObjectEventsObserver::addConnection(vtkObject* old_vtk_obj, vtkObject* vtk_obj,
  100. unsigned long vtk_event, const QObject* qt_obj, const char* qt_slot, float priority)
  101. {
  102. QString connectionId;
  103. if (old_vtk_obj)
  104. {
  105. // Check that old_object and new_object are the same type
  106. if (vtk_obj && !vtk_obj->IsA(old_vtk_obj->GetClassName()))
  107. {
  108. qCritical() << "Old vtkObject (type:" << old_vtk_obj->GetClassName() << ") to disconnect and "
  109. << "the new VtkObject (type:" << vtk_obj->GetClassName() << ") to connect"
  110. << "should have the same type.";
  111. return connectionId;
  112. }
  113. // Disconnect old vtkObject
  114. this->removeConnection(old_vtk_obj, vtk_event, qt_obj, qt_slot);
  115. }
  116. if (vtk_obj)
  117. {
  118. connectionId = this->addConnection(vtk_obj, vtk_event, qt_obj, qt_slot, priority);
  119. }
  120. return connectionId;
  121. }
  122. //-----------------------------------------------------------------------------
  123. QString ctkVTKObjectEventsObserver::reconnection(vtkObject* vtk_obj,
  124. unsigned long vtk_event, const QObject* qt_obj,
  125. const char* qt_slot, float priority)
  126. {
  127. QString connectionId;
  128. this->removeConnection(0, vtk_event, qt_obj, qt_slot);
  129. if (vtk_obj)
  130. {
  131. connectionId = this->addConnection(vtk_obj, vtk_event, qt_obj, qt_slot, priority);
  132. }
  133. return connectionId;
  134. }
  135. //-----------------------------------------------------------------------------
  136. QString ctkVTKObjectEventsObserver::addConnection(vtkObject* vtk_obj, unsigned long vtk_event,
  137. const QObject* qt_obj, const char* qt_slot, float priority)
  138. {
  139. CTK_D(ctkVTKObjectEventsObserver);
  140. if (!ctkVTKConnection::ValidateParameters(vtk_obj, vtk_event, qt_obj, qt_slot))
  141. {
  142. qDebug() << "ctkVTKObjectEventsObserver::addConnection(...) - Invalid parameters - "
  143. << ctkVTKConnection::shortDescription(vtk_obj, vtk_event, qt_obj, qt_slot);
  144. return QString();
  145. }
  146. // Check if such event is already observed
  147. if (d->containsConnection(vtk_obj, vtk_event, qt_obj, qt_slot))
  148. {
  149. qWarning() << "ctkVTKObjectEventsObserver::addConnection - [vtkObject:"
  150. << vtk_obj->GetClassName()
  151. << ", event:" << vtk_event << "]"
  152. << " is already connected with [qObject:" << qt_obj->objectName()
  153. << ", slot:" << qt_slot << "]";
  154. return QString();
  155. }
  156. // Instantiate a new connection, set its parameters and add it to the list
  157. ctkVTKConnection * connection = new ctkVTKConnection(this);
  158. connection->SetParameters(vtk_obj, vtk_event, qt_obj, qt_slot, priority);
  159. // If required, establish connection
  160. connection->setEnabled(d->AllEnabled);
  161. connection->setBlocked(d->AllBlocked);
  162. return connection->id();
  163. }
  164. //-----------------------------------------------------------------------------
  165. void ctkVTKObjectEventsObserver::blockAllConnections(bool block)
  166. {
  167. CTK_D(ctkVTKObjectEventsObserver);
  168. this->printAdditionalInfo();
  169. if (d->AllBlocked == block) { return; }
  170. foreach (ctkVTKConnection* connection, d->connections())
  171. {
  172. connection->setBlocked(block);
  173. }
  174. d->AllBlocked = block;
  175. }
  176. //-----------------------------------------------------------------------------
  177. void ctkVTKObjectEventsObserver::blockConnection(const QString& id, bool blocked)
  178. {
  179. CTK_D(ctkVTKObjectEventsObserver);
  180. ctkVTKConnection* connection = d->findConnection(id);
  181. if (connection == 0)
  182. {
  183. return;
  184. }
  185. connection->setBlocked(blocked);
  186. }
  187. //-----------------------------------------------------------------------------
  188. int ctkVTKObjectEventsObserver::blockConnection(bool block, vtkObject* vtk_obj,
  189. unsigned long vtk_event, const QObject* qt_obj)
  190. {
  191. CTK_D(ctkVTKObjectEventsObserver);
  192. if (!vtk_obj)
  193. {
  194. qDebug() << "ctkVTKObjectEventsObserver::blockConnectionRecursive"
  195. << "- Failed to " << (block?"block":"unblock") <<" connection"
  196. << "- vtkObject is NULL";
  197. return 0;
  198. }
  199. QList<ctkVTKConnection*> connections =
  200. d->findConnections(vtk_obj, vtk_event, qt_obj, 0);
  201. foreach (ctkVTKConnection* connection, connections)
  202. {
  203. connection->setBlocked(block);
  204. }
  205. return connections.size();
  206. }
  207. //-----------------------------------------------------------------------------
  208. int ctkVTKObjectEventsObserver::removeConnection(vtkObject* vtk_obj, unsigned long vtk_event,
  209. const QObject* qt_obj, const char* qt_slot)
  210. {
  211. CTK_D(ctkVTKObjectEventsObserver);
  212. QList<ctkVTKConnection*> connections =
  213. d->findConnections(vtk_obj, vtk_event, qt_obj, qt_slot);
  214. foreach (ctkVTKConnection* connection, connections)
  215. {
  216. connection->deleteConnection();
  217. }
  218. return connections.count();
  219. }
  220. //-----------------------------------------------------------------------------
  221. // ctkVTKObjectEventsObserverPrivate methods
  222. //-----------------------------------------------------------------------------
  223. ctkVTKObjectEventsObserverPrivate::ctkVTKObjectEventsObserverPrivate()
  224. {
  225. this->AllEnabled = true;
  226. this->AllBlocked = false;
  227. }
  228. //-----------------------------------------------------------------------------
  229. bool ctkVTKObjectEventsObserverPrivate::containsConnection(vtkObject* vtk_obj, unsigned long vtk_event,
  230. const QObject* qt_obj, const char* qt_slot)
  231. {
  232. return (this->findConnection(vtk_obj, vtk_event, qt_obj, qt_slot) != 0);
  233. }
  234. //-----------------------------------------------------------------------------
  235. ctkVTKConnection*
  236. ctkVTKObjectEventsObserverPrivate::findConnection(const QString& id)
  237. {
  238. foreach(ctkVTKConnection* connection, this->connections())
  239. {
  240. if (connection->id() == id)
  241. {
  242. return connection;
  243. }
  244. }
  245. return 0;
  246. }
  247. //-----------------------------------------------------------------------------
  248. ctkVTKConnection*
  249. ctkVTKObjectEventsObserverPrivate::findConnection(vtkObject* vtk_obj, unsigned long vtk_event,
  250. const QObject* qt_obj, const char* qt_slot)
  251. {
  252. QList<ctkVTKConnection*> foundConnections =
  253. this->findConnections(vtk_obj, vtk_event, qt_obj, qt_slot);
  254. return foundConnections.size() ? foundConnections[0] : 0;
  255. }
  256. //-----------------------------------------------------------------------------
  257. QList<ctkVTKConnection*>
  258. ctkVTKObjectEventsObserverPrivate::findConnections(
  259. vtkObject* vtk_obj, unsigned long vtk_event,
  260. const QObject* qt_obj, const char* qt_slot)
  261. {
  262. bool all_info = true;
  263. if(qt_slot == NULL || qt_obj == NULL || vtk_event == vtkCommand::NoEvent)
  264. {
  265. all_info = false;
  266. }
  267. QList<ctkVTKConnection*> foundConnections;
  268. // Loop through all connection
  269. foreach (ctkVTKConnection* connection, this->connections())
  270. {
  271. if (connection->isEqual(vtk_obj, vtk_event, qt_obj, qt_slot))
  272. {
  273. foundConnections.append(connection);
  274. if (all_info)
  275. {
  276. break;
  277. }
  278. }
  279. }
  280. return foundConnections;
  281. }