Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
QmitkDataStorageTreeModel.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 #include <mitkNodePredicateAnd.h>
13 #include <mitkNodePredicateData.h>
15 #include <mitkNodePredicateNot.h>
16 #include <mitkNodePredicateOr.h>
18 #include <mitkPlanarFigure.h>
19 #include <mitkProperties.h>
20 #include <mitkRenderingManager.h>
21 #include <mitkStringProperty.h>
22 
23 #include <mitkPropertyNameHelper.h>
24 
28 #include <QmitkCustomVariants.h>
29 #include <QmitkEnums.h>
30 #include <QmitkMimeTypes.h>
31 
32 #include <QFile>
33 #include <QIcon>
34 #include <QMimeData>
35 #include <QTextStream>
36 
37 #include <map>
38 
39 #include <mitkCoreServices.h>
40 
42  bool _PlaceNewNodesOnTop,
43  QObject *parent)
44  : QAbstractItemModel(parent),
45  m_DataStorage(nullptr),
46  m_PlaceNewNodesOnTop(_PlaceNewNodesOnTop),
47  m_Root(nullptr),
48  m_BlockDataStorageEvents(false),
49  m_AllowHierarchyChange(false)
50 {
51  this->SetDataStorage(_DataStorage);
52 }
53 
55 {
56  // set data storage to 0 = remove all listeners
57  this->SetDataStorage(nullptr);
58  m_Root->Delete();
59  m_Root = nullptr;
60 }
61 
63 {
64  return this->TreeItemFromIndex(index)->GetDataNode();
65 }
66 
68 {
69  return m_DataStorage.Lock();
70 }
71 
72 QModelIndex QmitkDataStorageTreeModel::index(int row, int column, const QModelIndex &parent) const
73 {
74  TreeItem *parentItem;
75 
76  if (!parent.isValid())
77  parentItem = m_Root;
78  else
79  parentItem = static_cast<TreeItem *>(parent.internalPointer());
80 
81  TreeItem *childItem = parentItem->GetChild(row);
82  if (childItem)
83  return createIndex(row, column, childItem);
84  else
85  return QModelIndex();
86 }
87 
88 int QmitkDataStorageTreeModel::rowCount(const QModelIndex &parent) const
89 {
90  TreeItem *parentTreeItem = this->TreeItemFromIndex(parent);
91  return parentTreeItem->GetChildCount();
92 }
93 
94 Qt::ItemFlags QmitkDataStorageTreeModel::flags(const QModelIndex &index) const
95 {
96  if (index.isValid())
97  {
98  return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable |
99  Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
100  }
101  else
102  {
103  return Qt::ItemIsDropEnabled;
104  }
105 }
106 
107 int QmitkDataStorageTreeModel::columnCount(const QModelIndex & /* parent = QModelIndex() */) const
108 {
109  return 1;
110 }
111 
112 QModelIndex QmitkDataStorageTreeModel::parent(const QModelIndex &index) const
113 {
114  if (!index.isValid())
115  return QModelIndex();
116 
117  TreeItem *childItem = this->TreeItemFromIndex(index);
118  TreeItem *parentItem = childItem->GetParent();
119 
120  if (parentItem == m_Root)
121  return QModelIndex();
122 
123  return this->createIndex(parentItem->GetIndex(), 0, parentItem);
124 }
125 
127 {
128  if (index.isValid())
129  return static_cast<TreeItem *>(index.internalPointer());
130  else
131  return m_Root;
132 }
134 {
135  return Qt::CopyAction | Qt::MoveAction;
136 }
137 
139 {
140  return Qt::CopyAction | Qt::MoveAction;
141 }
142 
144  const QMimeData *data, Qt::DropAction action, int row, int /*column*/, const QModelIndex &parent)
145 {
146  // Early exit, returning true, but not actually doing anything (ignoring data).
147  if (action == Qt::IgnoreAction)
148  {
149  return true;
150  }
151 
152  // Note, we are returning true if we handled it, and false otherwise
153  bool returnValue = false;
154 
155  if (data->hasFormat("application/x-qabstractitemmodeldatalist"))
156  {
157  returnValue = true;
158 
159  // First we extract a Qlist of TreeItem* pointers.
160  QList<TreeItem *> listOfItemsToDrop = ToTreeItemPtrList(data);
161  if (listOfItemsToDrop.empty())
162  {
163  return false;
164  }
165 
166  // Retrieve the TreeItem* where we are dropping stuff, and its parent.
167  TreeItem *dropItem = this->TreeItemFromIndex(parent);
168  TreeItem *parentItem = dropItem->GetParent();
169 
170  // If item was dropped onto empty space, we select the root node
171  if (dropItem == m_Root)
172  {
173  parentItem = m_Root;
174  }
175 
176  // Dragging and Dropping is only allowed within the same parent, so use the first item in list to validate.
177  // (otherwise, you could have a derived image such as a segmentation, and assign it to another image).
178  // NOTE: We are assuming the input list is valid... i.e. when it was dragged, all the items had the same parent.
179 
180  // Determine whether or not the drag and drop operation is a valid one.
181  // Examples of invalid operations include:
182  // - dragging nodes with different parents
183  // - dragging nodes from one parent to another parent, if m_AllowHierarchyChange is false
184  // - dragging a node on one of its child nodes (only relevant if m_AllowHierarchyChange is true)
185 
186  bool isValidDragAndDropOperation(true);
187 
188  // different parents
189  {
190  TreeItem *firstParent = listOfItemsToDrop[0]->GetParent();
191  QList<TreeItem *>::iterator diIter;
192  for (diIter = listOfItemsToDrop.begin() + 1; diIter != listOfItemsToDrop.end(); diIter++)
193  {
194  if (firstParent != (*diIter)->GetParent())
195  {
196  isValidDragAndDropOperation = false;
197  break;
198  }
199  }
200  }
201 
202  // dragging from one parent to another
203  if ((!m_AllowHierarchyChange) && isValidDragAndDropOperation)
204  {
205  if (row == -1) // drag onto a node
206  {
207  isValidDragAndDropOperation = listOfItemsToDrop[0]->GetParent() == parentItem;
208  }
209  else // drag between nodes
210  {
211  isValidDragAndDropOperation = listOfItemsToDrop[0]->GetParent() == dropItem;
212  }
213  }
214 
215  // dragging on a child node of one the dragged nodes
216  {
217  QList<TreeItem *>::iterator diIter;
218  for (diIter = listOfItemsToDrop.begin(); diIter != listOfItemsToDrop.end(); diIter++)
219  {
220  TreeItem *tempItem = dropItem;
221 
222  while (tempItem != m_Root)
223  {
224  tempItem = tempItem->GetParent();
225  if (tempItem == *diIter)
226  {
227  isValidDragAndDropOperation = false;
228  }
229  }
230  }
231  }
232 
233  if (!isValidDragAndDropOperation)
234  return isValidDragAndDropOperation;
235 
236  if (listOfItemsToDrop[0] != dropItem && isValidDragAndDropOperation)
237  {
238  // Retrieve the index of where we are dropping stuff.
239  QModelIndex parentModelIndex = this->IndexFromTreeItem(parentItem);
240 
241  int dragIndex = 0;
242 
243  // Iterate through the list of TreeItem (which may be at non-consecutive indexes).
244  QList<TreeItem *>::iterator diIter;
245  for (diIter = listOfItemsToDrop.begin(); diIter != listOfItemsToDrop.end(); diIter++)
246  {
247  TreeItem *itemToDrop = *diIter;
248 
249  // if the item is dragged down we have to compensate its final position for the
250  // fact it is deleted lateron, this only applies if it is dragged within the same level
251  if ((itemToDrop->GetIndex() < row) && (itemToDrop->GetParent() == dropItem))
252  {
253  dragIndex = 1;
254  }
255 
256  // Here we assume that as you remove items, one at a time, that GetIndex() will be valid.
257  this->beginRemoveRows(
258  this->IndexFromTreeItem(itemToDrop->GetParent()), itemToDrop->GetIndex(), itemToDrop->GetIndex());
259  itemToDrop->GetParent()->RemoveChild(itemToDrop);
260  this->endRemoveRows();
261  }
262 
263  // row = -1 dropped on an item, row != -1 dropped in between two items
264  // Select the target index position, or put it at the end of the list.
265  int dropIndex = 0;
266  if (row != -1)
267  {
268  if (dragIndex == 0)
269  dropIndex = std::min(row, parentItem->GetChildCount() - 1);
270  else
271  dropIndex = std::min(row - 1, parentItem->GetChildCount() - 1);
272  }
273  else
274  {
275  dropIndex = dropItem->GetIndex();
276  }
277 
278  QModelIndex dropItemModelIndex = this->IndexFromTreeItem(dropItem);
279  if ((row == -1 && dropItemModelIndex.row() == -1) || dropItemModelIndex.row() > parentItem->GetChildCount())
280  dropIndex = parentItem->GetChildCount() - 1;
281 
282  // Now insert items again at the drop item position
283 
285  {
286  this->beginInsertRows(dropItemModelIndex, dropIndex, dropIndex + listOfItemsToDrop.size() - 1);
287  }
288  else
289  {
290  this->beginInsertRows(parentModelIndex, dropIndex, dropIndex + listOfItemsToDrop.size() - 1);
291  }
292 
293  for (diIter = listOfItemsToDrop.begin(); diIter != listOfItemsToDrop.end(); diIter++)
294  {
295  // dropped on node, behaviour depends on preference setting
297  {
298  auto dataStorage = m_DataStorage.Lock();
299 
301  mitk::DataNode *droppedNode = (*diIter)->GetDataNode();
302  mitk::DataNode *dropOntoNode = dropItem->GetDataNode();
303  dataStorage->Remove(droppedNode);
304  dataStorage->Add(droppedNode, dropOntoNode);
305  m_BlockDataStorageEvents = false;
306 
307  dropItem->InsertChild((*diIter), dropIndex);
308  }
309  else
310  {
311  if (row == -1) // drag onto a node
312  {
313  parentItem->InsertChild((*diIter), dropIndex);
314  }
315  else // drag between nodes
316  {
317  dropItem->InsertChild((*diIter), dropIndex);
318  }
319  }
320 
321  dropIndex++;
322  }
323  this->endInsertRows();
324 
325  // Change Layers to match.
326  this->AdjustLayerProperty();
327  }
328  }
329  else if (data->hasFormat("application/x-mitk-datanodes"))
330  {
331  returnValue = true;
332 
333  int numberOfNodesDropped = 0;
334 
335  QList<mitk::DataNode *> dataNodeList = QmitkMimeTypes::ToDataNodePtrList(data);
336  mitk::DataNode *node = nullptr;
337  foreach (node, dataNodeList)
338  {
339  if (node && !m_DataStorage.IsExpired() && !m_DataStorage.Lock()->Exists(node))
340  {
341  m_DataStorage.Lock()->Add(node);
342  mitk::BaseData::Pointer basedata = node->GetData();
343 
344  if (basedata.IsNotNull())
345  {
347  basedata->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true);
348 
349  numberOfNodesDropped++;
350  }
351  }
352  }
353  // Only do a rendering update, if we actually dropped anything.
354  if (numberOfNodesDropped > 0)
355  {
357  }
358  }
359 
360  return returnValue;
361 }
362 
364 {
365  QStringList types = QAbstractItemModel::mimeTypes();
366  types << "application/x-qabstractitemmodeldatalist";
367  types << "application/x-mitk-datanodes";
368  return types;
369 }
370 
371 QMimeData *QmitkDataStorageTreeModel::mimeData(const QModelIndexList &indexes) const
372 {
373  return mimeDataFromModelIndexList(indexes);
374 }
375 
376 QMimeData *QmitkDataStorageTreeModel::mimeDataFromModelIndexList(const QModelIndexList &indexes)
377 {
378  QMimeData *ret = new QMimeData;
379 
380  QString treeItemAddresses("");
381  QString dataNodeAddresses("");
382 
383  QByteArray baTreeItemPtrs;
384  QByteArray baDataNodePtrs;
385 
386  QDataStream dsTreeItemPtrs(&baTreeItemPtrs, QIODevice::WriteOnly);
387  QDataStream dsDataNodePtrs(&baDataNodePtrs, QIODevice::WriteOnly);
388 
389  for (int i = 0; i < indexes.size(); i++)
390  {
391  TreeItem *treeItem = static_cast<TreeItem *>(indexes.at(i).internalPointer());
392 
393  dsTreeItemPtrs << reinterpret_cast<quintptr>(treeItem);
394  dsDataNodePtrs << reinterpret_cast<quintptr>(treeItem->GetDataNode().GetPointer());
395 
396  // --------------- deprecated -----------------
397  unsigned long long treeItemAddress = reinterpret_cast<unsigned long long>(treeItem);
398  unsigned long long dataNodeAddress = reinterpret_cast<unsigned long long>(treeItem->GetDataNode().GetPointer());
399  QTextStream(&treeItemAddresses) << treeItemAddress;
400  QTextStream(&dataNodeAddresses) << dataNodeAddress;
401 
402  if (i != indexes.size() - 1)
403  {
404  QTextStream(&treeItemAddresses) << ",";
405  QTextStream(&dataNodeAddresses) << ",";
406  }
407  // -------------- end deprecated -------------
408  }
409 
410  // ------------------ deprecated -----------------
411  ret->setData("application/x-qabstractitemmodeldatalist", QByteArray(treeItemAddresses.toLatin1()));
412  ret->setData("application/x-mitk-datanodes", QByteArray(dataNodeAddresses.toLatin1()));
413  // --------------- end deprecated -----------------
414 
415  ret->setData(QmitkMimeTypes::DataStorageTreeItemPtrs, baTreeItemPtrs);
416  ret->setData(QmitkMimeTypes::DataNodePtrs, baDataNodePtrs);
417 
418  return ret;
419 }
420 
421 QVariant QmitkDataStorageTreeModel::data(const QModelIndex &index, int role) const
422 {
423  mitk::DataNode *dataNode = this->TreeItemFromIndex(index)->GetDataNode();
424 
425  // get name of treeItem (may also be edited)
426  QString nodeName = QString::fromStdString(dataNode->GetName());
427  if (nodeName.isEmpty())
428  {
429  nodeName = "unnamed";
430  }
431 
432  if (role == Qt::DisplayRole)
433  return nodeName;
434  else if (role == Qt::ToolTipRole)
435  return nodeName;
436  else if (role == Qt::DecorationRole)
437  {
439  return nodeDescriptor->GetIcon(dataNode);
440  }
441  else if (role == Qt::CheckStateRole)
442  {
443  return dataNode->IsVisible(nullptr);
444  }
445  else if (role == QmitkDataNodeRole)
446  {
447  return QVariant::fromValue<mitk::DataNode::Pointer>(mitk::DataNode::Pointer(dataNode));
448  }
449  else if (role == QmitkDataNodeRawPointerRole)
450  {
451  return QVariant::fromValue<mitk::DataNode *>(dataNode);
452  }
453 
454  return QVariant();
455 }
456 
457 bool QmitkDataStorageTreeModel::DicomPropertiesExists(const mitk::DataNode &node) const
458 {
459  bool propertiesExists = false;
460 
461  mitk::BaseProperty *seriesDescription_deprecated = (node.GetProperty("dicom.series.SeriesDescription"));
462  mitk::BaseProperty *studyDescription_deprecated = (node.GetProperty("dicom.study.StudyDescription"));
463  mitk::BaseProperty *patientsName_deprecated = (node.GetProperty("dicom.patient.PatientsName"));
464  mitk::BaseProperty *seriesDescription =
465  (node.GetProperty(mitk::GeneratePropertyNameForDICOMTag(0x0008, 0x103e).c_str()));
466  mitk::BaseProperty *studyDescription =
467  (node.GetProperty(mitk::GeneratePropertyNameForDICOMTag(0x0008, 0x1030).c_str()));
468  mitk::BaseProperty *patientsName = (node.GetProperty(mitk::GeneratePropertyNameForDICOMTag(0x0010, 0x0010).c_str()));
469 
470  if (patientsName != nullptr && studyDescription != nullptr && seriesDescription != nullptr)
471  {
472  if ((!patientsName->GetValueAsString().empty()) && (!studyDescription->GetValueAsString().empty()) &&
473  (!seriesDescription->GetValueAsString().empty()))
474  {
475  propertiesExists = true;
476  }
477  }
478 
480  if (patientsName_deprecated != nullptr && studyDescription_deprecated != nullptr && seriesDescription_deprecated != nullptr)
481  {
482  if ((!patientsName_deprecated->GetValueAsString().empty()) &&
483  (!studyDescription_deprecated->GetValueAsString().empty()) &&
484  (!seriesDescription_deprecated->GetValueAsString().empty()))
485  {
486  propertiesExists = true;
487  }
488  }
489 
490  return propertiesExists;
491 }
492 
493 QVariant QmitkDataStorageTreeModel::headerData(int /*section*/, Qt::Orientation orientation, int role) const
494 {
495  if (orientation == Qt::Horizontal && role == Qt::DisplayRole && m_Root)
496  return QString::fromStdString(m_Root->GetDataNode()->GetName());
497 
498  return QVariant();
499 }
500 
502 {
503  if (m_DataStorage != _DataStorage) // dont take the same again
504  {
505  if (!m_DataStorage.IsExpired())
506  {
507  auto dataStorage = m_DataStorage.Lock();
508 
509  // remove Listener for the data storage itself
510  dataStorage->RemoveObserver(m_DataStorageDeletedTag);
511 
512  // remove listeners for the nodes
513  dataStorage->AddNodeEvent.RemoveListener(
516 
517  dataStorage->ChangedNodeEvent.RemoveListener(
520 
521  dataStorage->RemoveNodeEvent.RemoveListener(
524  }
525 
526  // take over the new data storage
527  m_DataStorage = _DataStorage;
528 
529  // delete the old root (if necessary, create new)
530  if (m_Root)
531  m_Root->Delete();
533  rootDataNode->SetName("Data Manager");
534  m_Root = new TreeItem(rootDataNode, nullptr);
535  this->beginResetModel();
536  this->endResetModel();
537 
538  if (!m_DataStorage.IsExpired())
539  {
540  auto dataStorage = m_DataStorage.Lock();
541 
542  // add Listener for the data storage itself
543  auto command = itk::SimpleMemberCommand<QmitkDataStorageTreeModel>::New();
544  command->SetCallbackFunction(this, &QmitkDataStorageTreeModel::SetDataStorageDeleted);
545  m_DataStorageDeletedTag = dataStorage->AddObserver(itk::DeleteEvent(), command);
546 
547  // add listeners for the nodes
550 
551  dataStorage->ChangedNodeEvent.AddListener(
554 
555  dataStorage->RemoveNodeEvent.AddListener(
558 
559  mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet = dataStorage->GetSubset(m_Predicate);
560 
561  // finally add all nodes to the model
562  this->Update();
563  }
564  }
565 }
566 
568 {
569  this->SetDataStorage(nullptr);
570 }
571 
572 void QmitkDataStorageTreeModel::AddNodeInternal(const mitk::DataNode *node)
573 {
574  if (node == nullptr || m_DataStorage.IsExpired() || !m_DataStorage.Lock()->Exists(node) || m_Root->Find(node) != nullptr)
575  return;
576 
577  // find out if we have a root node
578  TreeItem *parentTreeItem = m_Root;
579  QModelIndex index;
580  mitk::DataNode *parentDataNode = this->GetParentNode(node);
581 
582  if (parentDataNode) // no top level data node
583  {
584  parentTreeItem = m_Root->Find(parentDataNode); // find the corresponding tree item
585  if (!parentTreeItem)
586  {
587  this->AddNode(parentDataNode);
588  parentTreeItem = m_Root->Find(parentDataNode);
589  if (!parentTreeItem)
590  return;
591  }
592 
593  // get the index of this parent with the help of the grand parent
594  index = this->createIndex(parentTreeItem->GetIndex(), 0, parentTreeItem);
595  }
596 
597  // add node
599  {
600  // emit beginInsertRows event
601  beginInsertRows(index, 0, 0);
602  parentTreeItem->InsertChild(new TreeItem(const_cast<mitk::DataNode *>(node)), 0);
603  }
604  else
605  {
606  int firstRowWithASiblingBelow = 0;
607  int nodeLayer = -1;
608  node->GetIntProperty("layer", nodeLayer);
609  for (TreeItem* siblingTreeItem: parentTreeItem->GetChildren())
610  {
611  int siblingLayer = -1;
612  if (mitk::DataNode* siblingNode = siblingTreeItem->GetDataNode())
613  {
614  siblingNode->GetIntProperty("layer", siblingLayer);
615  }
616  if (nodeLayer > siblingLayer)
617  {
618  break;
619  }
620  ++firstRowWithASiblingBelow;
621  }
622  beginInsertRows(index, firstRowWithASiblingBelow, firstRowWithASiblingBelow);
623  parentTreeItem->InsertChild(new TreeItem(const_cast<mitk::DataNode*>(node)), firstRowWithASiblingBelow);
624  }
625 
626  // emit endInsertRows event
627  endInsertRows();
628 
630  {
631  this->AdjustLayerProperty();
632  }
633 }
634 
636 {
637  if (node == nullptr || m_BlockDataStorageEvents || m_DataStorage.IsExpired() || !m_DataStorage.Lock()->Exists(node) ||
638  m_Root->Find(node) != nullptr)
639  return;
640 
641  this->AddNodeInternal(node);
642 }
643 
645 {
646  m_PlaceNewNodesOnTop = _PlaceNewNodesOnTop;
647 }
648 
649 void QmitkDataStorageTreeModel::RemoveNodeInternal(const mitk::DataNode *node)
650 {
651  if (!m_Root)
652  return;
653 
654  TreeItem *treeItem = m_Root->Find(node);
655  if (!treeItem)
656  return; // return because there is no treeitem containing this node
657 
658  TreeItem *parentTreeItem = treeItem->GetParent();
659  QModelIndex parentIndex = this->IndexFromTreeItem(parentTreeItem);
660 
661  // emit beginRemoveRows event (QModelIndex is empty because we dont have a tree model)
662  this->beginRemoveRows(parentIndex, treeItem->GetIndex(), treeItem->GetIndex());
663 
664  // remove node
665  std::vector<TreeItem *> children = treeItem->GetChildren();
666  delete treeItem;
667 
668  // emit endRemoveRows event
669  endRemoveRows();
670 
671  // move all children of deleted node into its parent
672  for (std::vector<TreeItem *>::iterator it = children.begin(); it != children.end(); it++)
673  {
674  // emit beginInsertRows event
675  beginInsertRows(parentIndex, parentTreeItem->GetChildCount(), parentTreeItem->GetChildCount());
676 
677  // add nodes again
678  parentTreeItem->AddChild(*it);
679 
680  // emit endInsertRows event
681  endInsertRows();
682  }
683 
684  this->AdjustLayerProperty();
685 }
686 
688 {
689  if (node == nullptr || m_BlockDataStorageEvents)
690  return;
691 
692  this->RemoveNodeInternal(node);
693 }
694 
696 {
697  TreeItem *treeItem = m_Root->Find(node);
698  if (treeItem)
699  {
700  TreeItem *parentTreeItem = treeItem->GetParent();
701  // as the root node should not be removed one should always have a parent item
702  if (!parentTreeItem)
703  return;
704  QModelIndex index = this->createIndex(treeItem->GetIndex(), 0, treeItem);
705 
706  // now emit the dataChanged signal
707  emit dataChanged(index, index);
708  }
709 }
710 
712 {
713  mitk::DataNode *dataNode = nullptr;
714 
715  mitk::DataStorage::SetOfObjects::ConstPointer _Sources = m_DataStorage.Lock()->GetSources(node);
716 
717  if (_Sources->Size() > 0)
718  dataNode = _Sources->front();
719 
720  return dataNode;
721 }
722 
723 bool QmitkDataStorageTreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
724 {
725  mitk::DataNode *dataNode = this->TreeItemFromIndex(index)->GetDataNode();
726  if (!dataNode)
727  return false;
728 
729  if (role == Qt::EditRole && !value.toString().isEmpty())
730  {
731  dataNode->SetStringProperty("name", value.toString().toStdString().c_str());
732 
733  mitk::PlanarFigure *planarFigure = dynamic_cast<mitk::PlanarFigure *>(dataNode->GetData());
734 
735  if (planarFigure != nullptr)
737  }
738  else if (role == Qt::CheckStateRole)
739  {
740  // Please note: value.toInt() returns 2, independentely from the actual checkstate of the index element.
741  // Therefore the checkstate is being estimated again here.
742 
743  QVariant qcheckstate = index.data(Qt::CheckStateRole);
744  int checkstate = qcheckstate.toInt();
745  bool isVisible = bool(checkstate);
746  dataNode->SetVisibility(!isVisible);
747  emit nodeVisibilityChanged();
748  }
749  // inform listeners about changes
750  emit dataChanged(index, index);
751  return true;
752 }
753 
755  Qt::Orientation /*orientation*/,
756  const QVariant & /* value */,
757  int /*role = Qt::EditRole*/)
758 {
759  return false;
760 }
761 
763 {
765  std::vector<TreeItem *> vec;
766  this->TreeToVector(m_Root, vec);
767 
768  int i = vec.size() - 1;
769  for (std::vector<TreeItem *>::const_iterator it = vec.begin(); it != vec.end(); ++it)
770  {
771  mitk::DataNode::Pointer dataNode = (*it)->GetDataNode();
772  bool fixedLayer = false;
773 
774  if (!(dataNode->GetBoolProperty("fixedLayer", fixedLayer) && fixedLayer))
775  dataNode->SetIntProperty("layer", i);
776 
777  --i;
778  }
780 }
781 
782 void QmitkDataStorageTreeModel::TreeToVector(TreeItem *parent, std::vector<TreeItem *> &vec) const
783 {
784  TreeItem *current;
785  for (int i = 0; i < parent->GetChildCount(); ++i)
786  {
787  current = parent->GetChild(i);
788  this->TreeToVector(current, vec);
789  vec.push_back(current);
790  }
791 }
792 
794 {
795  if (item == m_Root)
796  return QModelIndex();
797  else
798  return this->createIndex(item->GetIndex(), 0, item);
799 }
800 
801 QList<mitk::DataNode::Pointer> QmitkDataStorageTreeModel::GetNodeSet() const
802 {
803  QList<mitk::DataNode::Pointer> res;
804  if (m_Root)
805  this->TreeToNodeSet(m_Root, res);
806 
807  return res;
808 }
809 
810 void QmitkDataStorageTreeModel::TreeToNodeSet(TreeItem *parent, QList<mitk::DataNode::Pointer> &vec) const
811 {
812  TreeItem *current;
813  for (int i = 0; i < parent->GetChildCount(); ++i)
814  {
815  current = parent->GetChild(i);
816  vec.push_back(current->GetDataNode());
817  this->TreeToNodeSet(current, vec);
818  }
819 }
820 
822 {
823  if (m_Root)
824  {
825  TreeItem *item = m_Root->Find(node);
826  if (item)
827  return this->IndexFromTreeItem(item);
828  }
829  return QModelIndex();
830 }
831 
832 QList<QmitkDataStorageTreeModel::TreeItem *> QmitkDataStorageTreeModel::ToTreeItemPtrList(const QMimeData *mimeData)
833 {
834  if (mimeData == nullptr || !mimeData->hasFormat(QmitkMimeTypes::DataStorageTreeItemPtrs))
835  {
836  return QList<TreeItem *>();
837  }
839 }
840 
841 QList<QmitkDataStorageTreeModel::TreeItem *> QmitkDataStorageTreeModel::ToTreeItemPtrList(const QByteArray &ba)
842 {
843  QList<TreeItem *> result;
844  QDataStream ds(ba);
845  while (!ds.atEnd())
846  {
847  quintptr treeItemPtr;
848  ds >> treeItemPtr;
849  result.push_back(reinterpret_cast<TreeItem *>(treeItemPtr));
850  }
851  return result;
852 }
853 
855 {
856  if (!m_DataStorage.IsExpired())
857  {
858  mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet = m_DataStorage.Lock()->GetAll();
859 
862  bool newNodesWereToBePlacedOnTop = m_PlaceNewNodesOnTop;
863  m_PlaceNewNodesOnTop = false;
864 
865  for (const auto& node: *_NodeSet)
866  {
867  this->AddNodeInternal(node);
868  }
869 
870  m_PlaceNewNodesOnTop = newNodesWereToBePlacedOnTop;
871 
873  this->AdjustLayerProperty();
874  }
875 }
876 
878 {
879  m_AllowHierarchyChange = allowHierarchyChange;
880 }
static QMimeData * mimeDataFromModelIndexList(const QModelIndexList &indexes)
mitk::BaseProperty * GetProperty(const char *propertyKey, const mitk::BaseRenderer *renderer=nullptr, bool fallBackOnDataProperties=true) const
Get the property (instance of BaseProperty) with key propertyKey from the PropertyList of the rendere...
virtual bool InitializeViews(const BaseGeometry *geometry, RequestType type=REQUEST_UPDATE_ALL, bool preserveRoughOrientationInWorldSpace=false)
void SetDataStorage(mitk::DataStorage *_DataStorage)
virtual void SetNodeModified(const mitk::DataNode *node)
Data management class that handles &#39;was created by&#39; relations.
itk::SmartPointer< T > Lock() const
Decorator class for mitk::DataNode.
void SetVisibility(bool visible, const mitk::BaseRenderer *renderer=nullptr, const char *propertyKey="visible")
Convenience method for setting visibility properties (instances of BoolProperty)
void TreeToNodeSet(TreeItem *parent, QList< mitk::DataNode::Pointer > &vec) const
void AddChild(QmitkDataStorageTreeModelInternalItem *item)
QmitkDataStorageTreeModel(mitk::DataStorage *_DataStorage, bool _PlaceNewNodesOnTop=false, QObject *parent=nullptr)
QModelIndex parent(const QModelIndex &index) const override
int columnCount(const QModelIndex &parent=QModelIndex()) const override
void SetAllowHierarchyChange(bool allowHierarchyChange)
Set whether to allow hierarchy changes by dragging and dropping.
QModelIndex GetIndex(const mitk::DataNode *) const
QModelIndex IndexFromTreeItem(TreeItem *) const
std::string MITKCORE_EXPORT GeneratePropertyNameForDICOMTag(unsigned int group, unsigned int element)
virtual QList< mitk::DataNode::Pointer > GetNodeSet() const
Qt::DropActions supportedDropActions() const override
static QList< mitk::DataNode * > ToDataNodePtrList(const QByteArray &ba)
const mitk::DataStorage::Pointer GetDataStorage() const
bool m_BlockDataStorageEvents
Flag to block the data storage events if nodes are added/removed by this class.
Qt::ItemFlags flags(const QModelIndex &index) const override
static const QString DataNodePtrs
mitk::DataNode::Pointer GetNode(const QModelIndex &index) const
bool GetIntProperty(const char *propertyKey, int &intValue, const mitk::BaseRenderer *renderer=nullptr) const
Convenience access method for int properties (instances of IntProperty)
virtual void AddNode(const mitk::DataNode *node)
void SetPlaceNewNodesOnTop(bool _PlaceNewNodesOnTop)
itk::SmartPointer< Self > Pointer
Definition: mitkDataNode.h:71
QmitkNodeDescriptor * GetDescriptor(const mitk::DataNode *node) const
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
virtual std::string GetValueAsString() const
Abstract base class for properties.
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role=Qt::EditRole) override
bool IsVisible(const mitk::BaseRenderer *renderer, const char *propertyKey="visible", bool defaultIsOn=true) const
Convenience access method for visibility properties (instances of BoolProperty). Return value is the ...
Definition: mitkDataNode.h:462
mitk::DataStorage::Pointer m_DataStorage
QmitkDataStorageTreeModelInternalItem * GetChild(int index) const
static Pointer New()
static RenderingManager * GetInstance()
mitk::WeakPointer< mitk::DataStorage > m_DataStorage
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
bool IsExpired() const noexcept
int rowCount(const QModelIndex &parent=QModelIndex()) const override
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
QmitkDataStorageTreeModelInternalItem * GetParent() const
TreeItem * TreeItemFromIndex(const QModelIndex &index) const
static T min(T x, T y)
Definition: svm.cpp:53
Base-class for geometric planar (2D) figures, such as lines, circles, rectangles, polygons...
QmitkDataStorageTreeModelInternalItem * Find(const mitk::DataNode *_DataNode) const
mitk::NodePredicateBase::Pointer m_Predicate
void SetStringProperty(const char *propertyKey, const char *string, const mitk::BaseRenderer *renderer=nullptr)
Convenience method for setting string properties (instances of StringProperty)
virtual void RemoveNode(const mitk::DataNode *node)
Qt::DropActions supportedDragActions() const override
QList< TreeItem * > ToTreeItemPtrList(const QMimeData *mimeData)
QStringList mimeTypes() const override
QmitkDataStorageTreeModelInternalItem TreeItem
std::vector< QmitkDataStorageTreeModelInternalItem * > GetChildren() const
virtual QIcon GetIcon(const mitk::DataNode *node) const
mitk::DataNode * GetParentNode(const mitk::DataNode *node) const
QMimeData * mimeData(const QModelIndexList &indexes) const override
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
void TreeToVector(TreeItem *parent, std::vector< TreeItem *> &vec) const
void RequestUpdateAll(RequestType type=REQUEST_UPDATE_ALL)
static QmitkNodeDescriptorManager * GetInstance()
Class for nodes of the DataTree.
Definition: mitkDataNode.h:57
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
bool GetName(std::string &nodeName, const mitk::BaseRenderer *renderer=nullptr, const char *propertyKey="name") const
Convenience access method for accessing the name of an object (instance of StringProperty with proper...
Definition: mitkDataNode.h:369
static const QString DataStorageTreeItemPtrs
void InsertChild(QmitkDataStorageTreeModelInternalItem *item, int index=-1)
void RemoveChild(QmitkDataStorageTreeModelInternalItem *item)