Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
QmitkPointListModel.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include "QmitkPointListModel.h"
18 #include "mitkInteractionConst.h"
19 #include "mitkPointOperation.h"
20 #include "mitkRenderingManager.h"
21 #include <itkCommand.h>
22 #include <mitkInteractionConst.h>
23 #include <mitkInternalEvent.h>
25 
26 QmitkPointListModel::QmitkPointListModel(mitk::DataNode *pointSetNode, int t, QObject *parent)
27  : QAbstractListModel(parent),
28  m_PointSetNode(NULL),
29  m_PointSetModifiedObserverTag(0),
30  m_PointSetDeletedObserverTag(0),
31  m_TimeStep(t)
32 {
33  ObserveNewPointSet(pointSetNode);
34 }
35 
36 Qt::ItemFlags QmitkPointListModel::flags(const QModelIndex & /*index*/) const
37 {
38  // no editing so far, return default (enabled, selectable)
39  return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
40 }
41 
43 {
44  this->ObserveNewPointSet(NULL);
45 }
46 
48 {
49  this->ObserveNewPointSet(pointSetNode);
50  QAbstractListModel::beginResetModel();
51  QAbstractListModel::endResetModel();
52  emit SignalUpdateSelection();
53 }
54 
56 {
58 }
59 
61 {
62  m_TimeStep = t;
63  QAbstractListModel::beginResetModel();
64  QAbstractListModel::endResetModel();
65  emit SignalUpdateSelection();
66 }
67 
69 {
70  return m_TimeStep;
71 }
72 
74 {
75  // remove old observers
76  if (m_PointSetNode != NULL)
77  {
78  try // here sometimes an exception is thrown which leads to a crash. So catch this exception but give an error
79  // message. See bug 18316 for details.
80  {
81  mitk::PointSet::Pointer oldPointSet = dynamic_cast<mitk::PointSet *>(m_PointSetNode->GetData());
82  if (oldPointSet.IsNotNull())
83  {
84  oldPointSet->RemoveObserver(m_PointSetModifiedObserverTag);
85  oldPointSet->RemoveObserver(m_PointSetDeletedObserverTag);
86  }
87  }
88  catch (std::exception &e)
89  {
90  MITK_ERROR << "Exception while removing observer from old point set node: " << e.what();
91  }
92  }
93 
94  // get the new pointset
95  mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(pointSetNode);
96 
97  m_PointSetNode = pointSetNode;
98 
99  if (pointSet.IsNotNull())
100  {
101  // add new observer for modified if necessary
104  modCommand->SetCallbackFunction(this, &QmitkPointListModel::OnPointSetChanged);
105  m_PointSetModifiedObserverTag = pointSet->AddObserver(itk::ModifiedEvent(), modCommand);
106 
107  // add new observer for detele if necessary
110  delCommand->SetCallbackFunction(this, &QmitkPointListModel::OnPointSetDeleted);
111  m_PointSetDeletedObserverTag = pointSet->AddObserver(itk::DeleteEvent(), delCommand);
112  }
113  else
114  {
117  }
118 }
119 
120 void QmitkPointListModel::OnPointSetChanged(const itk::EventObject &)
121 {
122  QAbstractListModel::beginResetModel();
123  QAbstractListModel::endResetModel();
124  emit SignalUpdateSelection();
125 }
126 
127 void QmitkPointListModel::OnPointSetDeleted(const itk::EventObject &)
128 {
130  if (ps)
131  {
132  ps->RemoveObserver(m_PointSetModifiedObserverTag);
133  ps->RemoveObserver(m_PointSetDeletedObserverTag);
134  }
135 
138  QAbstractListModel::beginResetModel();
139  QAbstractListModel::endResetModel();
140 }
141 
142 int QmitkPointListModel::rowCount(const QModelIndex &) const
143 {
145  if (pointSet.IsNotNull())
146  {
147  return pointSet->GetSize(m_TimeStep);
148  }
149  else
150  {
151  return 0;
152  }
153 }
154 
155 QVariant QmitkPointListModel::data(const QModelIndex &index, int role) const
156 {
158 
159  if (pointSet.IsNull())
160  {
161  return QVariant();
162  }
163 
164  if (!index.isValid())
165  {
166  return QVariant();
167  }
168 
169  if (index.row() >= pointSet->GetSize(m_TimeStep))
170  {
171  return QVariant();
172  }
173 
174  if (role == Qt::DisplayRole)
175  {
176  mitk::PointSet::PointsContainer::ElementIdentifier id;
178  bool pointFound = this->GetPointForModelIndex(index, p, id);
179  if (pointFound == false)
180  return QVariant();
181 
182  QString s = QString("%0: (%1, %2, %3)").arg(id, 3).arg(p[0], 0, 'f', 3).arg(p[1], 0, 'f', 3).arg(p[2], 0, 'f', 3);
183  return QVariant(s);
184  }
185  else
186  {
187  return QVariant();
188  }
189 }
190 
191 QVariant QmitkPointListModel::headerData(int section, Qt::Orientation orientation, int role) const
192 {
193  if (role != Qt::DisplayRole)
194  {
195  return QVariant();
196  }
197 
198  if (orientation == Qt::Horizontal)
199  {
200  return QString("Coordinates").arg(section);
201  }
202  else
203  {
204  return QString("Row %1").arg(section);
205  }
206 }
207 
208 bool QmitkPointListModel::GetPointForModelIndex(const QModelIndex &index,
211 {
213  if (pointSet.IsNull())
214  return false;
215 
216  if ((index.row() < 0) || (index.row() >= (int)pointSet->GetPointSet(m_TimeStep)->GetPoints()->Size()))
217  return false;
218 
219  // get the nth. element, if it exists.
220  // we can not use the index directly, because PointSet uses a map container,
221  // where the index is not necessarily the same as the key.
222  // Therefore we have to count the elements
223  mitk::PointSet::PointsContainer::Iterator it = pointSet->GetPointSet(m_TimeStep)->GetPoints()->Begin();
224  for (int i = 0; i < index.row(); ++i)
225  {
226  ++it;
227 
228  if (it == pointSet->GetPointSet(m_TimeStep)->GetPoints()->End())
229  return false;
230  }
231 
232  if (it != pointSet->GetPointSet(m_TimeStep)->GetPoints()->End()) // not at the end,
233  {
234  p = it->Value();
235  id = it->Index();
236  return true;
237  }
238 
239  return false;
240 }
241 
243 {
245  if (pointSet.IsNull())
246  return false;
247 
248  mitk::PointSet::PointsContainer::Pointer points = pointSet->GetPointSet(m_TimeStep)->GetPoints();
249 
250  if (points->IndexExists(id) == false)
251  return false;
252 
253  unsigned int idx = 0;
254  for (mitk::PointSet::PointsContainer::Iterator it = points->Begin(); it != points->End(); ++it)
255  {
256  if (it->Index() == id) // we found the correct element
257  {
258  index = this->index(idx);
259  return true;
260  }
261 
262  idx++;
263  }
264 
265  return false; // nothing found
266 }
267 
269 {
271  if (pointSet.IsNull())
272  return;
273 
275  selectedID = pointSet->SearchSelectedPoint(m_TimeStep);
276  mitk::ScalarType tsInMS = pointSet->GetTimeGeometry()->TimeStepToTimePoint(m_TimeStep);
277  mitk::PointOperation *doOp =
278  new mitk::PointOperation(mitk::OpMOVEPOINTUP, tsInMS, pointSet->GetPoint(selectedID, m_TimeStep), selectedID, true);
279  pointSet->ExecuteOperation(doOp);
280  mitk::RenderingManager::GetInstance()->RequestUpdateAll(); // Workaround for update problem in Pointset/Mapper
281 }
282 
284 {
286  if (pointSet.IsNull())
287  return;
288 
290  selectedID = pointSet->SearchSelectedPoint(m_TimeStep);
291  mitk::ScalarType tsInMS = pointSet->GetTimeGeometry()->TimeStepToTimePoint(m_TimeStep);
293  mitk::OpMOVEPOINTDOWN, tsInMS, pointSet->GetPoint(selectedID, m_TimeStep), selectedID, true);
294  pointSet->ExecuteOperation(doOp);
295  mitk::RenderingManager::GetInstance()->RequestUpdateAll(); // Workaround for update problem in Pointset/Mapper
296 }
297 
299 {
301  if (pointSet.IsNull())
302  return;
303 
305  selectedID = pointSet->SearchSelectedPoint(m_TimeStep);
306  mitk::ScalarType tsInMS = pointSet->GetTimeGeometry()->TimeStepToTimePoint(m_TimeStep);
307  mitk::PointOperation *doOp =
308  new mitk::PointOperation(mitk::OpREMOVE, tsInMS, pointSet->GetPoint(selectedID, m_TimeStep), selectedID, true);
309  pointSet->ExecuteOperation(doOp);
310  mitk::RenderingManager::GetInstance()->RequestUpdateAll(); // Workaround for update problem in Pointset/Mapper
311 }
312 
314 {
315  if (node != NULL)
316  {
317  mitk::PointSet::Pointer pointSet = dynamic_cast<mitk::PointSet *>(node->GetData());
318  if (pointSet.IsNotNull())
319  return pointSet;
320  }
321  return NULL;
322 }
itk::SmartPointer< Self > Pointer
QVariant data(const QModelIndex &index, int role) const override
interface of QAbstractListModel
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
interface of QAbstractListModel
QmitkPointListModel(mitk::DataNode *=NULL, int t=0, QObject *parent=0)
#define MITK_ERROR
Definition: mitkLogMacros.h:24
double ScalarType
int rowCount(const QModelIndex &parent=QModelIndex()) const override
interface of QAbstractListModel
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
Constants for most interaction classes, due to the generic StateMachines.
void SetTimeStep(int t)
which time step to display/model
unsigned int m_PointSetDeletedObserverTag
void SetPointSetNode(mitk::DataNode *pointSetNode)
which point set to work on
void ObserveNewPointSet(mitk::DataNode *pointSetNode)
internally observe different point set
DataType::PointIdentifier PointIdentifier
Definition: mitkPointSet.h:135
void OnPointSetChanged(const itk::EventObject &e)
itk observer for point set "modified" events
bool GetPointForModelIndex(const QModelIndex &index, mitk::PointSet::PointType &p, mitk::PointSet::PointIdentifier &id) const
get point and point ID that correspond to a given QModelIndex
int GetTimeStep() const
which time step to display/model
Data structure which stores a set of points. Superclass of mitk::Mesh.
Definition: mitkPointSet.h:79
static RenderingManager * GetInstance()
Operation that handles all actions on one Point.
Qt::ItemFlags flags(const QModelIndex &) const override
unsigned int m_PointSetModifiedObserverTag
mitk::PointSet * CheckForPointSetInNode(mitk::DataNode *node) const
mitk::DataNode * m_PointSetNode
void OnPointSetDeleted(const itk::EventObject &e)
itk observer for point set "delete" events
void SignalUpdateSelection()
bool GetModelIndexForPointID(mitk::PointSet::PointIdentifier id, QModelIndex &index) const
returns a QModelIndex for a given point ID
mitk::PointSet * GetPointSet() const
which point set to work on
void RequestUpdateAll(RequestType type=REQUEST_UPDATE_ALL)
Class for nodes of the DataTree.
Definition: mitkDataNode.h:66
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.