Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
QmitkPointListWidget.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 #include "QmitkPointListWidget.h"
17 
18 #include <QDir>
19 #include <QFileDialog>
20 #include <QHBoxLayout>
21 #include <QMessageBox>
22 #include <mitkIOUtil.h>
23 
24 #include <QmitkEditPointDialog.h>
25 
27 
28 #include <mitkDataInteractor.h>
29 
30 QmitkPointListWidget::QmitkPointListWidget(QWidget *parent, int orientation)
31  : QWidget(parent),
32  m_PointListView(NULL),
33  m_MultiWidget(NULL),
34  m_PointSetNode(NULL),
35  m_Orientation(0),
36  m_MovePointUpBtn(NULL),
37  m_MovePointDownBtn(NULL),
38  m_RemovePointBtn(NULL),
39  m_SavePointsBtn(NULL),
40  m_LoadPointsBtn(NULL),
41  m_ToggleAddPoint(NULL),
42  m_AddPoint(NULL),
43  m_Snc1(NULL),
44  m_Snc2(NULL),
45  m_Snc3(NULL),
46  m_DataInteractor(NULL),
47  m_TimeStep(0),
48  m_EditAllowed(true),
49  m_NodeObserverTag(0)
50 {
52 
53  if (orientation != 0)
54  m_Orientation = orientation;
55 
56  SetupUi();
58  ObserveNewNode(NULL);
59 }
60 
62 {
63  m_DataInteractor = NULL;
64 
66  {
67  m_PointSetNode->RemoveObserver(m_NodeObserverTag);
69  }
70 
71  m_MultiWidget = NULL;
72  delete m_PointListView;
73 }
74 
76 {
77  connect(this->m_LoadPointsBtn, SIGNAL(clicked()), this, SLOT(OnBtnLoadPoints()));
78  connect(this->m_SavePointsBtn, SIGNAL(clicked()), this, SLOT(OnBtnSavePoints()));
79  connect(this->m_MovePointUpBtn, SIGNAL(clicked()), this, SLOT(MoveSelectedPointUp()));
80  connect(this->m_MovePointDownBtn, SIGNAL(clicked()), this, SLOT(MoveSelectedPointDown()));
81  connect(this->m_RemovePointBtn, SIGNAL(clicked()), this, SLOT(RemoveSelectedPoint()));
82  connect(this->m_ToggleAddPoint, SIGNAL(toggled(bool)), this, SLOT(OnBtnAddPoint(bool)));
83  connect(this->m_AddPoint, SIGNAL(clicked()), this, SLOT(OnBtnAddPointManually()));
84  connect(this->m_PointListView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(OnListDoubleClick()));
85  connect(this->m_PointListView, SIGNAL(SignalPointSelectionChanged()), this, SLOT(OnPointSelectionChanged()));
86 }
87 
89 {
90  // Setup the buttons
91 
92  m_ToggleAddPoint = new QPushButton();
93  m_ToggleAddPoint->setMaximumSize(25, 25);
94  m_ToggleAddPoint->setCheckable(true);
95  m_ToggleAddPoint->setToolTip("Toggle point editing (use SHIFT + Left Mouse Button to add Points)");
96  QIcon iconAdd(":/QtWidgetsExt/btnSetPoints.xpm");
97  m_ToggleAddPoint->setIcon(iconAdd);
98 
99  m_AddPoint = new QPushButton();
100  m_AddPoint->setMaximumSize(25, 25);
101  m_AddPoint->setToolTip("Manually add point");
102  QIcon iconAddManually(":/QtWidgetsExt/btnSetPointsManually.xpm");
103  m_AddPoint->setIcon(iconAddManually);
104 
105  m_RemovePointBtn = new QPushButton();
106  m_RemovePointBtn->setMaximumSize(25, 25);
107  const QIcon iconDel(":/QtWidgetsExt/btnClear.xpm");
108  m_RemovePointBtn->setIcon(iconDel);
109  m_RemovePointBtn->setToolTip("Erase one point from list (Hotkey: DEL)");
110 
111  m_MovePointUpBtn = new QPushButton();
112  m_MovePointUpBtn->setMaximumSize(25, 25);
113  const QIcon iconUp(":/QtWidgetsExt/btnUp.xpm");
114  m_MovePointUpBtn->setIcon(iconUp);
115  m_MovePointUpBtn->setToolTip("Swap selected point upwards (Hotkey: F2)");
116 
117  m_MovePointDownBtn = new QPushButton();
118  m_MovePointDownBtn->setMaximumSize(25, 25);
119  const QIcon iconDown(":/QtWidgetsExt/btnDown.xpm");
120  m_MovePointDownBtn->setIcon(iconDown);
121  m_MovePointDownBtn->setToolTip("Swap selected point downwards (Hotkey: F3)");
122 
123  m_SavePointsBtn = new QPushButton();
124  m_SavePointsBtn->setMaximumSize(25, 25);
125  QIcon iconSave(":/QtWidgetsExt/btnSave.xpm");
126  m_SavePointsBtn->setIcon(iconSave);
127  m_SavePointsBtn->setToolTip("Save points to file");
128 
129  m_LoadPointsBtn = new QPushButton();
130  m_LoadPointsBtn->setMaximumSize(25, 25);
131  QIcon iconLoad(":/QtWidgetsExt/btnLoad.xpm");
132  m_LoadPointsBtn->setIcon(iconLoad);
133  m_LoadPointsBtn->setToolTip("Load list of points from file (REPLACES current content)");
134 
135  int i;
136 
137  QBoxLayout *lay1;
138  QBoxLayout *lay2;
139 
140  switch (m_Orientation)
141  {
142  case 0:
143  lay1 = new QVBoxLayout(this);
144  lay2 = new QHBoxLayout();
145  i = 0;
146  break;
147 
148  case 1:
149  lay1 = new QHBoxLayout(this);
150  lay2 = new QVBoxLayout();
151  i = -1;
152  break;
153 
154  case 2:
155  lay1 = new QHBoxLayout(this);
156  lay2 = new QVBoxLayout();
157  i = 0;
158  break;
159 
160  default:
161  lay1 = new QVBoxLayout(this);
162  lay2 = new QHBoxLayout();
163  i = -1;
164  break;
165  }
166 
167  // setup Layouts
168 
169  this->setLayout(lay1);
170  lay1->addLayout(lay2);
171 
172  lay2->stretch(true);
173  lay2->addWidget(m_ToggleAddPoint);
174  lay2->addWidget(m_AddPoint);
175  lay2->addWidget(m_RemovePointBtn);
176  lay2->addWidget(m_MovePointUpBtn);
177  lay2->addWidget(m_MovePointDownBtn);
178  lay2->addWidget(m_SavePointsBtn);
179  lay2->addWidget(m_LoadPointsBtn);
180 
181  lay1->insertWidget(i, m_PointListView);
182  this->setLayout(lay1);
183 }
184 
186 {
187  if (newPs == NULL)
188  return;
189 
190  this->m_PointSetNode->SetData(newPs);
191  dynamic_cast<QmitkPointListModel *>(this->m_PointListView->model())->SetPointSetNode(m_PointSetNode);
193 }
194 
196 {
197  if (m_DataInteractor.IsNotNull())
198  m_DataInteractor->SetDataNode(newNode);
199 
200  ObserveNewNode(newNode);
201  dynamic_cast<QmitkPointListModel *>(this->m_PointListView->model())->SetPointSetNode(newNode);
202 }
203 
205 {
206  if ((dynamic_cast<mitk::PointSet *>(m_PointSetNode->GetData())) == NULL)
207  return; // don't write empty point sets. If application logic requires something else then do something else.
208  if ((dynamic_cast<mitk::PointSet *>(m_PointSetNode->GetData()))->GetSize() == 0)
209  return;
210 
211  // take the previously defined name of node as proposal for filename
212  std::string nodeName = m_PointSetNode->GetName();
213  nodeName = "/" + nodeName + ".mps";
214  QString fileNameProposal = QString();
215  fileNameProposal.append(nodeName.c_str());
216 
217  QString aFilename = QFileDialog::getSaveFileName(
218  NULL, "Save point set", QDir::currentPath() + fileNameProposal, "MITK Pointset (*.mps)");
219  if (aFilename.isEmpty())
220  return;
221 
222  try
223  {
224  mitk::IOUtil::Save(m_PointSetNode->GetData(), aFilename.toStdString());
225  }
226  catch (...)
227  {
228  QMessageBox::warning(this,
229  "Save point set",
230  QString("File writer reported problems writing %1\n\n"
231  "PLEASE CHECK output file!")
232  .arg(aFilename));
233  }
234 }
235 
237 {
238  // get the name of the file to load
239  QString filename = QFileDialog::getOpenFileName(NULL, "Open MITK Pointset", "", "MITK Point Sets (*.mps)");
240  if (filename.isEmpty())
241  return;
242 
243  // attempt to load file
244  try
245  {
246  mitk::PointSet::Pointer pointSet = mitk::IOUtil::LoadPointSet(filename.toStdString());
247  if (pointSet.IsNull())
248  {
249  QMessageBox::warning(this, "Load point set", QString("File reader could not read %1").arg(filename));
250  return;
251  }
252 
253  // loading successful
254 
255  this->SetPointSet(pointSet);
256  }
257  catch (...)
258  {
259  QMessageBox::warning(this, "Load point set", QString("File reader collapsed while reading %1").arg(filename));
260  }
261  emit PointListChanged();
263 }
264 
266 {
267  return dynamic_cast<mitk::PointSet *>(m_PointSetNode->GetData());
268 }
269 
271 {
272  return m_PointSetNode;
273 }
274 
276 {
277  this->m_MultiWidget = multiWidget;
278  m_PointListView->SetMultiWidget(multiWidget);
279 }
280 
282 {
283  if (!m_PointSetNode)
284  return;
285  mitk::PointSet *pointSet = dynamic_cast<mitk::PointSet *>(m_PointSetNode->GetData());
286  if (!pointSet)
287  return;
288  if (pointSet->GetSize() == 0)
289  return;
290 
291  QmitkPointListModel *pointListModel = dynamic_cast<QmitkPointListModel *>(m_PointListView->model());
292  pointListModel->RemoveSelectedPoint();
293  emit PointListChanged();
294 }
295 
297 {
298  if (!m_PointSetNode)
299  return;
300  mitk::PointSet *pointSet = dynamic_cast<mitk::PointSet *>(m_PointSetNode->GetData());
301  if (!pointSet)
302  return;
303  if (pointSet->GetSize() == 0)
304  return;
305 
306  QmitkPointListModel *pointListModel = dynamic_cast<QmitkPointListModel *>(m_PointListView->model());
307  pointListModel->MoveSelectedPointDown();
308  emit PointListChanged();
309 }
310 
312 {
313  if (!m_PointSetNode)
314  return;
315  mitk::PointSet *pointSet = dynamic_cast<mitk::PointSet *>(m_PointSetNode->GetData());
316  if (!pointSet)
317  return;
318  if (pointSet->GetSize() == 0)
319  return;
320 
321  QmitkPointListModel *pointListModel = dynamic_cast<QmitkPointListModel *>(m_PointListView->model());
322  pointListModel->MoveSelectedPointUp();
323  emit PointListChanged();
324 }
325 
327 {
328  if (m_PointSetNode.IsNotNull())
329  {
330  if (checked)
331  {
332  m_DataInteractor = m_PointSetNode->GetDataInteractor();
333  // If no data Interactor is present create a new one
334  if (m_DataInteractor.IsNull())
335  {
336  // Create PointSetData Interactor
338  // Load the according state machine for regular point set interaction
339  m_DataInteractor->LoadStateMachine("PointSet.xml");
340  // Set the configuration file that defines the triggers for the transitions
341  m_DataInteractor->SetEventConfig("PointSetConfig.xml");
342  // set the DataNode (which already is added to the DataStorage
343  m_DataInteractor->SetDataNode(m_PointSetNode);
344  }
345  }
346  else
347  {
348  m_PointSetNode->SetDataInteractor(NULL);
349  m_DataInteractor = NULL;
350  }
351  emit EditPointSets(checked);
352  }
353 }
354 
356 {
357  mitk::PointSet *pointSet = this->GetPointSet();
358 
359  mitk::PointSet::PointsIterator maxIt = pointSet->GetMaxId();
360  mitk::PointSet::PointIdentifier maxId = maxIt->Index();
361 
362  QmitkEditPointDialog editPointDialog(this);
363  editPointDialog.SetPoint(pointSet, maxId + 1, m_TimeStep);
364  editPointDialog.exec();
365 }
366 
368 {
369 }
370 
372 {
373  emit this->PointSelectionChanged();
374 }
375 
377 {
378 }
379 
381 {
382  m_EditAllowed = enabled;
383  if (enabled == false)
384  m_ToggleAddPoint->setEnabled(false);
385  else
386  m_ToggleAddPoint->setEnabled(true);
387  OnBtnAddPoint(enabled);
388 }
389 
391 {
392  if (m_DataInteractor.IsNotNull())
393  m_DataInteractor->SetDataNode(node);
394 
395  // remove old observer
396  if (m_PointSetNode)
397  {
398  if (m_DataInteractor)
399  {
400  m_DataInteractor = NULL;
401  m_ToggleAddPoint->setChecked(false);
402  }
403 
404  m_PointSetNode->RemoveObserver(m_NodeObserverTag);
405  m_NodeObserverTag = 0;
406  }
407 
408  m_PointSetNode = node;
409  // add new observer if necessary
410  if (m_PointSetNode)
411  {
414  command->SetCallbackFunction(this, &QmitkPointListWidget::OnNodeDeleted);
415  m_NodeObserverTag = m_PointSetNode->AddObserver(itk::DeleteEvent(), command);
416  }
417  else
418  {
419  m_NodeObserverTag = 0;
420  }
421 
422  if (m_EditAllowed == true)
423  m_ToggleAddPoint->setEnabled(m_PointSetNode);
424  else
425  m_ToggleAddPoint->setEnabled(false);
426 
427  m_RemovePointBtn->setEnabled(m_PointSetNode);
428  m_LoadPointsBtn->setEnabled(m_PointSetNode);
429  m_SavePointsBtn->setEnabled(m_PointSetNode);
430  m_AddPoint->setEnabled(m_PointSetNode);
431 }
432 
433 void QmitkPointListWidget::OnNodeDeleted(const itk::EventObject &)
434 {
435  if (m_PointSetNode.IsNotNull() && !m_NodeObserverTag)
436  m_PointSetNode->RemoveObserver(m_NodeObserverTag);
437  m_NodeObserverTag = 0;
438  m_PointSetNode = NULL;
440  m_ToggleAddPoint->setEnabled(false);
441 
442  m_RemovePointBtn->setEnabled(false);
443  m_LoadPointsBtn->setEnabled(false);
444  m_SavePointsBtn->setEnabled(false);
445  m_AddPoint->setEnabled(false);
446 }
447 
449 {
450  if (snc == NULL)
451  {
453  }
454  else
455  {
457  }
458  m_Snc1 = snc;
459 }
460 
462 {
463  if (snc == NULL)
464  {
466  }
467  else
468  {
470  }
471  m_Snc2 = snc;
472 }
473 
475 {
476  if (snc == NULL)
477  {
479  }
480  else
481  {
483  }
484  m_Snc3 = snc;
485 }
486 
488 {
490 }
491 
493 {
495 }
496 
498 {
499  m_ToggleAddPoint->setChecked(false);
500 }
DataType::PointsContainerIterator PointsIterator
Definition: mitkPointSet.h:137
PointsIterator GetMaxId(int t=0)
Get an iterator to the max ID element if existent. Return End() otherwise.
static void Save(const mitk::BaseData *data, const std::string &path)
Save a mitk::BaseData instance.
Definition: mitkIOUtil.cpp:824
A dialog for editing points directly (coordinates) via TextEdits.
void SetMultiWidget(QmitkStdMultiWidget *multiWidget)
If Multiwidget is set, the crosshair is automatically centering to the selected point As an alternati...
void RemoveSliceNavigationController(mitk::SliceNavigationController *snc)
Remove a mitk::SliceNavigationController instance.
itk::SmartPointer< Self > Pointer
void AddSliceNavigationController(mitk::SliceNavigationController *snc)
Add a mitk::SliceNavigationController instance.
QmitkPointListWidget(QWidget *parent=0, int orientation=0)
virtual int GetSize(unsigned int t=0) const
returns the current size of the point-list
void OnBtnAddPoint(bool checked)
void PointListChanged()
signal to inform about cleared or loaded point sets
void SetPointSet(mitk::PointSet *newPs)
assign a point set (contained in a node of DataStorage) for observation
void EditPointSets(bool active)
signal to inform about the state of the EditPointSetButton, whether an interactor for setting points ...
void SetSnc3(mitk::SliceNavigationController *snc)
Sets the SliceNavigationController of the three 2D Renderwindows. If they are defined, they can be used to automatically set the crosshair to the selected point.
QmitkStdMultiWidget * m_MultiWidget
GUI widget for handling mitk::PointSet.
QPushButton * m_MovePointDownBtn
Controls the selection of the slice the associated BaseRenderer will display.
QmitkPointListView * m_PointListView
DataType::PointIdentifier PointIdentifier
Definition: mitkPointSet.h:135
void PointSelectionChanged()
signal to inform that the selection of a point in the pointset has changed
void SetPointSetNode(mitk::DataNode *newNode)
assign a point set (contained in a node of DataStorage) for observation
void SetSnc2(mitk::SliceNavigationController *snc)
Sets the SliceNavigationController of the three 2D Renderwindows. If they are defined, they can be used to automatically set the crosshair to the selected point.
mitk::DataNode::Pointer m_PointSetNode
void OnPointSelectionChanged()
pass through signal from PointListView that point selection has changed
Data structure which stores a set of points. Superclass of mitk::Mesh.
Definition: mitkPointSet.h:79
void ObserveNewNode(mitk::DataNode *node)
mitk::SliceNavigationController * m_Snc3
static RenderingManager * GetInstance()
static const std::string filename
static mitk::PointSet::Pointer LoadPointSet(const std::string &path)
LoadPointSet Convenience method to load an arbitrary mitkPointSet.
Definition: mitkIOUtil.cpp:619
void DeactivateInteractor(bool deactivate)
mitk::DataNode * GetPointSetNode()
mitk::DataInteractor::Pointer m_DataInteractor
void UnselectEditButton()
Unselects the edit button if it is selected.
void SetMultiWidget(QmitkStdMultiWidget *multiWidget)
assign a QmitkStdMultiWidget for updating render window crosshair
mitk::SliceNavigationController * m_Snc2
void AddSliceNavigationController(mitk::SliceNavigationController *snc)
Add a mitk::SliceNavigationController instance.
void SetSnc1(mitk::SliceNavigationController *snc)
Sets the SliceNavigationController of the three 2D Renderwindows. If they are defined, they can be used to automatically set the crosshair to the selected point.
void EnableEditButton(bool enabled)
mitk::PointSet * GetPointSet()
void OnNodeDeleted(const itk::EventObject &e)
itk observer for node "delete" events
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:66
mitk::SliceNavigationController * m_Snc1
void RemoveSliceNavigationController(mitk::SliceNavigationController *snc)
Remove a mitk::SliceNavigationController instance.
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.
void SetPoint(mitk::PointSet *_PointSet, mitk::PointSet::PointIdentifier _PointId, int timestep=0)