Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
QmitkPointListView.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 (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include "QmitkPointListView.h"
14 
15 #include "QmitkEditPointDialog.h"
16 #include "QmitkPointListModel.h"
17 #include "QmitkRenderWindow.h"
18 #include "QmitkStdMultiWidget.h"
19 
20 #include "mitkRenderingManager.h"
21 
22 #include <QKeyEvent>
23 #include <QMenu>
24 #include <QMessageBox>
25 #include <QPalette>
26 #include <QTimer>
27 
29  : QListView(parent),
30  m_PointListModel(new QmitkPointListModel()),
31  m_SelfCall(false),
32  m_showFading(false),
33  m_MultiWidget(nullptr)
34 {
35  QListView::setAlternatingRowColors(true);
36 
37  QListView::setSelectionBehavior(QAbstractItemView::SelectItems);
38  QListView::setSelectionMode(QAbstractItemView::SingleSelection);
39  QListView::setModel(m_PointListModel);
40  QString tooltip = QString("Use the F2/F3 keys to move a point up/down, the Del key to remove a point\nand the mouse "
41  "wheel to change the timestep.\n\nTimeStep:\t%1")
42  .arg(0);
43  QListView::setToolTip(tooltip);
44  this->setContextMenuPolicy(Qt::CustomContextMenu);
45 
46  this->setMinimumHeight(40);
47 
48  this->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
49 
50  connect(m_PointListModel, SIGNAL(SignalUpdateSelection()), this, SLOT(OnPointSetSelectionChanged()));
51 
52  connect(this, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(OnPointDoubleClicked(const QModelIndex &)));
53 
54  connect(QListView::selectionModel(),
55  SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
56  this,
57  SLOT(OnListViewSelectionChanged(const QItemSelection &, const QItemSelection &)));
58 
59  connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(ctxMenu(const QPoint &)));
60 }
61 
63 {
64  delete m_PointListModel;
65 }
66 
68 {
69  m_PointListModel->SetPointSetNode(pointSetNode);
70 }
71 
73 {
74  return m_PointListModel->GetPointSet();
75 }
76 
78 {
79  m_MultiWidget = multiWidget;
80  if (nullptr != m_MultiWidget)
81  {
85  }
86 }
87 
89 {
90  return m_MultiWidget;
91 }
92 
93 void QmitkPointListView::OnPointDoubleClicked(const QModelIndex &index)
94 {
98  QmitkEditPointDialog _EditPointDialog(this);
100  _EditPointDialog.exec();
101 }
102 
104 {
105  const mitk::PointSet *pointSet = m_PointListModel->GetPointSet();
106  if (pointSet == nullptr)
107  return;
108 
109  // update this view's selection status as a result to changes in the point set data structure
110  m_SelfCall = true;
111  int timeStep = m_PointListModel->GetTimeStep();
112 
113  if (pointSet->GetNumberOfSelected(timeStep) > 1)
114  {
115  MITK_ERROR << "Point set has multiple selected points. This view is not designed for more than one selected point.";
116  }
117 
118  int selectedIndex = pointSet->SearchSelectedPoint(timeStep);
119 
120  if (selectedIndex == -1) // no selected point is found
121  {
122  m_SelfCall = false;
123  return;
124  }
125 
126  QModelIndex index;
127 
128  bool modelIndexOkay = m_PointListModel->GetModelIndexForPointID(selectedIndex, index);
129 
130  if (modelIndexOkay == true)
131  QListView::selectionModel()->select(index, QItemSelectionModel::ClearAndSelect);
132 
134 
135  m_SelfCall = false;
136 }
137 
138 void QmitkPointListView::OnListViewSelectionChanged(const QItemSelection &selected,
139  const QItemSelection & /*deselected*/)
140 {
141  if (m_SelfCall)
142  return;
143 
144  mitk::PointSet *pointSet = const_cast<mitk::PointSet *>(m_PointListModel->GetPointSet());
145 
146  if (pointSet == nullptr)
147  return;
148 
149  // (take care that this widget doesn't react to self-induced changes by setting m_SelfCall)
150  m_SelfCall = true;
151 
152  // update selection of all points in pointset: select the one(s) that are selected in the view, deselect all others
153  QModelIndexList selectedIndexes = selected.indexes();
154 
155  // only call setSelectInfo on a point set with 'selected = true' if you deselcted the other entries
156  int indexToSelect = -1;
157 
158  for (mitk::PointSet::PointsContainer::Iterator it =
159  pointSet->GetPointSet(m_PointListModel->GetTimeStep())->GetPoints()->Begin();
160  it != pointSet->GetPointSet(m_PointListModel->GetTimeStep())->GetPoints()->End();
161  ++it)
162  {
163  QModelIndex index;
164  if (m_PointListModel->GetModelIndexForPointID(it->Index(), index))
165  {
166  if (selectedIndexes.indexOf(index) != -1) // index is found in the selected indices list
167  {
168  indexToSelect = it->Index();
169  }
170  else
171  {
172  pointSet->SetSelectInfo(it->Index(), false, m_PointListModel->GetTimeStep());
173  }
174  }
175  }
176 
177  // force selection of only one index after deselecting the others
178  if (indexToSelect > -1) {
179  pointSet->SetSelectInfo(indexToSelect, true, m_PointListModel->GetTimeStep());
180 
181  mitk::Point3D p = pointSet->GetPoint(indexToSelect, m_PointListModel->GetTimeStep());
182 
183  for (auto snc : m_Sncs)
184  snc->SelectSliceByPoint(p);
185  }
186 
187  m_SelfCall = false;
188 
190 
192 }
193 
195 {
196  if (m_PointListModel == nullptr)
197  return;
198 
199  int key = e->key();
200 
201  switch (key)
202  {
203  case Qt::Key_F2:
205  break;
206  case Qt::Key_F3:
208  break;
209  case Qt::Key_Delete:
211  break;
212  default:
213  break;
214  }
215 }
216 
217 void QmitkPointListView::wheelEvent(QWheelEvent *event)
218 {
220  (int)(m_PointListModel->GetPointSet()->GetTimeSteps()) == 1)
221  return;
222 
223  int whe = event->delta();
225  unsigned int numberOfTS = ps->GetTimeSteps();
226 
227  if (numberOfTS == 1)
228  return;
229  int currentTS = this->m_PointListModel->GetTimeStep();
230  if (whe > 0)
231  {
232  if ((currentTS + 1 >= (int)numberOfTS))
233  return;
234 
235  this->m_PointListModel->SetTimeStep(++currentTS);
236  }
237  else
238  {
239  if ((currentTS <= 0))
240  return;
241  this->m_PointListModel->SetTimeStep(--currentTS);
242  }
243 
244  QString tooltip = QString("Use the F2/F3 keys to move a point up/down, the Del key to remove a point\nand the mouse "
245  "wheel to change the timestep.\n\nTimeStep:\t%1")
246  .arg(currentTS);
247  this->setToolTip(tooltip);
248 
249  emit SignalTimeStepChanged(currentTS);
250 }
251 
252 void QmitkPointListView::ctxMenu(const QPoint &pos)
253 {
254  QMenu *menu = new QMenu;
255 
256  // add Fading check
257  QAction *showFading = new QAction(this);
258  showFading->setCheckable(false); // TODO: reset when fading is working
259  showFading->setEnabled(false); // TODO: reset when fading is working
260  showFading->setText("Fade TimeStep");
261  connect(showFading, SIGNAL(triggered(bool)), this, SLOT(SetFading(bool)));
262  menu->addAction(showFading);
263 
264  // add Clear action
265  QAction *clearList = new QAction(this);
266  clearList->setText("Clear List");
267  connect(clearList, SIGNAL(triggered()), this, SLOT(ClearPointList()));
268  menu->addAction(clearList);
269 
270  // add Clear TimeStep action
271  QAction *clearTS = new QAction(this);
272  clearTS->setText("Clear current time step");
273  connect(clearTS, SIGNAL(triggered()), this, SLOT(ClearPointListTS()));
274  menu->addAction(clearTS);
275 
276  menu->exec(this->mapToGlobal(pos));
277 }
278 
280 {
281  m_showFading = onOff;
282 }
283 
285 {
287  return;
289  if (curPS->GetSize() == 0)
290  return;
291 
292  switch (QMessageBox::question(this,
293  tr("Clear Points"),
294  tr("Remove all points from the displayed list?"),
295  QMessageBox::Yes | QMessageBox::No,
296  QMessageBox::No))
297  {
298  case QMessageBox::Yes:
299  {
301  mitk::PointSet::PointsContainer *curPsPoints;
302  while (!curPS->IsEmptyTimeStep(0))
303  {
304  curPsPoints = curPS->GetPointSet()->GetPoints();
305  it = curPsPoints->Begin();
306  curPS->SetSelectInfo(it->Index(), true);
308  }
310  break;
311  }
312  case QMessageBox::No:
313  default:
314  break;
315  }
316 }
317 
319 {
320 }
321 
323 {
324  if (snc == nullptr)
325  return;
326  m_Sncs.insert(snc);
327 }
328 
330 {
331  if (snc == nullptr)
332  return;
333  m_Sncs.erase(snc);
334 }
QmitkRenderWindow * GetRenderWindow3() const
DataType::PointsContainerIterator PointsIterator
Definition: mitkPointSet.h:135
A dialog for editing points directly (coordinates) via TextEdits.
QmitkRenderWindow * GetRenderWindow2() const
void SetMultiWidget(QmitkStdMultiWidget *multiWidget)
If Multiwidget is set, the crosshair is automatically centering to the selected point As an alternati...
void AddSliceNavigationController(mitk::SliceNavigationController *snc)
Add a mitk::SliceNavigationController instance.
void OnPointDoubleClicked(const QModelIndex &index)
Filtering double click event for editing point coordinates via a dialog.
QmitkStdMultiWidget * GetMultiWidget() const
return the QmitkStdMultiWidget that is used for updating render window crosshair
#define MITK_ERROR
Definition: mitkLogMacros.h:20
void wheelEvent(QWheelEvent *event) override
change timestep of the current pointset by mouse wheel
virtual int SearchSelectedPoint(int t=0) const
searches a selected point and returns the id of that point. If no point is found, then -1 is returned...
mitk::PointSet * GetPointSet() const
which point set to work on
const mitk::PointSet * GetPointSet() const
which point set to work on
void SetTimeStep(int t)
which time step to display/model
virtual void SetSelectInfo(int position, bool selected, int t=0)
Controls the selection of the slice the associated BaseRenderer will display.
void SetPointSetNode(mitk::DataNode *pointSetNode)
which point set to work on
void SignalTimeStepChanged(int)
DataType::PointIdentifier PointIdentifier
Definition: mitkPointSet.h:133
std::set< mitk::SliceNavigationController * > m_Sncs
QmitkPointListModel * m_PointListModel
QmitkRenderWindow * GetRenderWindow1() const
Data structure which stores a set of points. Superclass of mitk::Mesh.
Definition: mitkPointSet.h:75
The &#39;QmitkStdMultiWidget&#39; is a &#39;QmitkAbstractMultiWidget&#39; that is used to display multiple render win...
virtual int GetNumberOfSelected(int t=0) const
returns the number of selected points
static RenderingManager * GetInstance()
The custom viewer plugin implements simple viewer functionality presented in a customized look and feel It was developed to demonstrate extensibility and customizability of the blueberry application framework As an example for the GUI customization capabilities provided by the BlueBerry application the custom viewer plugin was developed It features simple viewer functionality presented in a customized look and feel The custom viewer consists of two i e a viewer perspective and a DICOM perspective As part of the viewer an instance of QmitkDataManagerView allows for data selection Visualization of the selected data is then performed by a simple render window view According data can either be directly loaded from file or be imported as DICOM data DICOM import functionality is accessible from the DICOM perspective incorporating the QmitkDicomExternalDataWidget The customization of Qt Stylesheets is used to give the application a non native look and feel This is further emphasized by a Tab Widget like unification of the perspectives with the according perspective bar In addition to an absence of menu
int GetTimeStep() const
which time step to display/model
virtual DataType::Pointer GetPointSet(int t=0) const
returns the pointset
void SetFading(bool onOff)
Turn TimeStep Fading On/Off.
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
void OnListViewSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
called when the selection of the view widget changes
bool GetModelIndexForPointID(mitk::PointSet::PointIdentifier id, QModelIndex &index) const
returns a QModelIndex for a given point ID
QmitkPointListView(QWidget *parent=nullptr)
DataType::PointsContainer PointsContainer
Definition: mitkPointSet.h:134
void ClearPointListTS()
delete all points in the list in the current timestep
void OnPointSetSelectionChanged()
called when the point set data structure changes
void keyPressEvent(QKeyEvent *e) override
react to F2, F3 and DEL keys
unsigned int GetTimeSteps() const
Get the number of time steps from the TimeGeometry As the base data has not a data vector given by it...
Definition: mitkBaseData.h:355
virtual mitk::SliceNavigationController * GetSliceNavigationController()
PointType GetPoint(PointIdentifier id, int t=0) const
Get the point with ID id in world coordinates.
void ClearPointList()
Delete all points in the list.
QmitkStdMultiWidget * m_MultiWidget
used to position the planes on a selected point
void ctxMenu(const QPoint &pos)
open ContextMenu
void RequestUpdateAll(RequestType type=REQUEST_UPDATE_ALL)
void SetPointSetNode(mitk::DataNode *pointSetNode)
assign a point set for observation
Class for nodes of the DataTree.
Definition: mitkDataNode.h:57
void SignalPointSelectionChanged()
this signal is emmitted, if the selection of a point in the pointset is changed
void RemoveSliceNavigationController(mitk::SliceNavigationController *snc)
Remove a mitk::SliceNavigationController instance.
void SetPoint(mitk::PointSet *_PointSet, mitk::PointSet::PointIdentifier _PointId, int timestep=0)