Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
QmitkRenderWindowDataStorageListModel.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 // render window manager UI module
15 
16 // qt widgets module
17 #include "QmitkCustomVariants.h"
18 #include "QmitkEnums.h"
19 #include "QmitkMimeTypes.h"
21 
24 {
25  m_RenderWindowLayerController = std::make_unique<mitk::RenderWindowLayerController>();
26 }
27 
29 {
30  m_RenderWindowLayerController->SetDataStorage(m_DataStorage.Lock());
31  UpdateModelData();
32 }
33 
35 {
36  UpdateModelData();
37 }
38 
40 {
41  // add a node to each render window specific list (or to a global list initially)
42  AddDataNodeToAllRenderer(const_cast<mitk::DataNode*>(node));
43  UpdateModelData();
44 }
45 
47 {
48  // nothing here, since the "'NodeChanged'-event is currently sent far too often
49 }
50 
52 {
53  // update model data to create a new list without the removed data node
54  UpdateModelData();
55 }
56 
57 QModelIndex QmitkRenderWindowDataStorageListModel::index(int row, int column, const QModelIndex& parent) const
58 {
59  bool hasIndex = this->hasIndex(row, column, parent);
60  if (hasIndex)
61  {
62  return this->createIndex(row, column);
63  }
64 
65  return QModelIndex();
66 }
67 
68 QModelIndex QmitkRenderWindowDataStorageListModel::parent(const QModelIndex& /*child*/) const
69 {
70  return QModelIndex();
71 }
72 
73 int QmitkRenderWindowDataStorageListModel::rowCount(const QModelIndex& parent /*= QModelIndex()*/) const
74 {
75  if (parent.isValid())
76  {
77  return 0;
78  }
79 
80  return static_cast<int>(m_LayerStack.size());
81 }
82 
83 int QmitkRenderWindowDataStorageListModel::columnCount(const QModelIndex& parent /*= QModelIndex()*/) const
84 {
85  if (parent.isValid())
86  {
87  return 0;
88  }
89 
90  return 1;
91 }
92 
93 QVariant QmitkRenderWindowDataStorageListModel::data(const QModelIndex& index, int role) const
94 {
95  if (m_BaseRenderer.IsExpired())
96  {
97  return QVariant();
98  }
99 
100  auto baseRenderer = m_BaseRenderer.Lock();
101 
102  if (!index.isValid() || this != index.model())
103  {
104  return QVariant();
105  }
106 
107  if (index.row() < 0 || index.row() >= static_cast<int>(m_LayerStack.size()))
108  {
109  return QVariant();
110  }
111 
112  mitk::RenderWindowLayerUtilities::LayerStack::const_iterator layerStackIt = m_LayerStack.begin();
113  std::advance(layerStackIt, index.row());
114  mitk::DataNode* dataNode = layerStackIt->second;
115 
116  if (Qt::CheckStateRole == role)
117  {
118  bool visibility = false;
119  dataNode->GetVisibility(visibility, baseRenderer);
120  if (visibility)
121  {
122  return Qt::Checked;
123  }
124  else
125  {
126  return Qt::Unchecked;
127  }
128  }
129  else if (Qt::DisplayRole == role)
130  {
131  return QVariant(QString::fromStdString(dataNode->GetName()));
132  }
133  else if (Qt::ToolTipRole == role)
134  {
135  return QVariant("Name of the data node.");
136  }
137  else if (Qt::DecorationRole == role)
138  {
140  return nodeDescriptor->GetIcon(dataNode);
141  }
142  else if (Qt::UserRole == role || QmitkDataNodeRawPointerRole == role)
143  {
144  // user role always returns a reference to the data node,
145  // which can be used to modify the data node in the data storage
146  return QVariant::fromValue<mitk::DataNode*>(dataNode);
147  }
148  else if (QmitkDataNodeRole == role)
149  {
150  return QVariant::fromValue<mitk::DataNode::Pointer>(mitk::DataNode::Pointer(dataNode));
151  }
152 
153  return QVariant();
154 }
155 
156 bool QmitkRenderWindowDataStorageListModel::setData(const QModelIndex& index, const QVariant& value, int role /*= Qt::EditRole*/)
157 {
158  if (m_BaseRenderer.IsExpired())
159  {
160  return false;
161  }
162 
163  auto baseRenderer = m_BaseRenderer.Lock();
164 
165  if (!index.isValid() || this != index.model())
166  {
167  return false;
168  }
169 
170  if (index.row() < 0 || index.row() >= static_cast<int>(m_LayerStack.size()))
171  {
172  return false;
173  }
174 
175  mitk::RenderWindowLayerUtilities::LayerStack::const_iterator layerStackIt = m_LayerStack.begin();
176  std::advance(layerStackIt, index.row());
177  mitk::DataNode* dataNode = layerStackIt->second;
178  if (Qt::CheckStateRole == role)
179  {
180  Qt::CheckState newCheckState = static_cast<Qt::CheckState>(value.toInt());
181  bool isVisible = newCheckState;
182  dataNode->SetVisibility(isVisible, baseRenderer);
183 
184  emit dataChanged(index, index);
185  mitk::RenderingManager::GetInstance()->RequestUpdate(baseRenderer->GetRenderWindow());
186  return true;
187  }
188  return false;
189 }
190 
191 Qt::ItemFlags QmitkRenderWindowDataStorageListModel::flags(const QModelIndex &index) const
192 {
193  if (this != index.model())
194  {
195  return Qt::NoItemFlags;
196  }
197 
198  if (!index.isValid())
199  {
200  return Qt::ItemIsDropEnabled;
201  }
202 
203  return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
204 }
205 
207 {
208  return Qt::CopyAction | Qt::MoveAction;
209 }
210 
212 {
213  return Qt::CopyAction | Qt::MoveAction;
214 }
215 
217 {
218  QStringList types = QAbstractItemModel::mimeTypes();
220  return types;
221 }
222 
223 QMimeData* QmitkRenderWindowDataStorageListModel::mimeData(const QModelIndexList& indexes) const
224 {
225  QMimeData* mimeData = new QMimeData();
226  QByteArray encodedData;
227 
228  QDataStream stream(&encodedData, QIODevice::WriteOnly);
229 
230  for (const auto& index : indexes)
231  {
232  if (index.isValid())
233  {
234  auto dataNode = data(index, QmitkDataNodeRawPointerRole).value<mitk::DataNode*>();
235  stream << reinterpret_cast<quintptr>(dataNode);
236  }
237  }
238 
239  mimeData->setData(QmitkMimeTypes::DataNodePtrs, encodedData);
240  return mimeData;
241 }
242 
243 bool QmitkRenderWindowDataStorageListModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int /*row*/, int column, const QModelIndex& parent)
244 {
245  if (m_BaseRenderer.IsExpired())
246  {
247  return false;
248  }
249 
250  auto baseRenderer = m_BaseRenderer.Lock();
251 
252  if (action == Qt::IgnoreAction)
253  {
254  return true;
255  }
256 
257  if (!data->hasFormat(QmitkMimeTypes::DataNodePtrs))
258  {
259  return false;
260  }
261 
262  if (column > 0)
263  {
264  return false;
265  }
266 
267  if (parent.isValid())
268  {
269  int layer = -1;
270  auto dataNode = this->data(parent, QmitkDataNodeRawPointerRole).value<mitk::DataNode*>();
271  if (nullptr != dataNode)
272  {
273  dataNode->GetIntProperty("layer", layer, baseRenderer);
274  }
275 
276  auto dataNodeList = QmitkMimeTypes::ToDataNodePtrList(data);
277  for (const auto& dataNode : dataNodeList)
278  {
279  m_RenderWindowLayerController->MoveNodeToPosition(dataNode, layer, baseRenderer);
280  }
281 
282  UpdateModelData();
283  return true;
284  }
285 
286  return false;
287 }
288 
290 {
291  m_RenderWindowLayerController->SetControlledRenderer(controlledRenderer);
292 
293  if (!m_DataStorage.IsExpired())
294  {
295  auto dataStorage = m_DataStorage.Lock();
296  mitk::DataStorage::SetOfObjects::ConstPointer allDataNodes = dataStorage->GetAll();
297  for (mitk::DataStorage::SetOfObjects::ConstIterator it = allDataNodes->Begin(); it != allDataNodes->End(); ++it)
298  {
299  mitk::DataNode::Pointer dataNode = it->Value();
300  if (dataNode.IsNull())
301  {
302  continue;
303  }
304 
305  AddDataNodeToAllRenderer(dataNode);
306  }
307  }
308 }
309 
311 {
312  if (m_BaseRenderer == baseRenderer)
313  {
314  return;
315  }
316 
317  m_BaseRenderer = baseRenderer;
318  if (!m_BaseRenderer.IsExpired())
319  {
320  UpdateModelData();
321  }
322 }
323 
325 {
326  if (m_BaseRenderer.IsExpired())
327  {
328  return nullptr;
329  }
330 
331  return m_BaseRenderer.Lock().GetPointer();
332 }
333 
335 {
336  m_RenderWindowLayerController->InsertLayerNode(dataNode);
337 }
338 
339 void QmitkRenderWindowDataStorageListModel::UpdateModelData()
340 {
341  if (!m_DataStorage.IsExpired())
342  {
343  auto dataStorage = m_DataStorage.Lock();
344  if (!m_BaseRenderer.IsExpired())
345  {
346  auto baseRenderer = m_BaseRenderer.Lock();
347  // update the model, so that it will be filled with the nodes of the new data storage
348  beginResetModel();
349  // get the current layer stack of the given base renderer
350  m_LayerStack = mitk::RenderWindowLayerUtilities::GetLayerStack(dataStorage, baseRenderer, true);
351  endResetModel();
352  }
353  }
354 }
QModelIndex parent(const QModelIndex &child) const override
void NodeChanged(const mitk::DataNode *node) override
See &#39;QmitkAbstractDataStorageModel&#39;.
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 AddDataNodeToAllRenderer(mitk::DataNode *dataNode)
Use the RenderWindowLayerController to insert the given data node into all controlled render windows...
Organizes the rendering process.
static QList< mitk::DataNode * > ToDataNodePtrList(const QByteArray &ba)
static const QString DataNodePtrs
void NodeRemoved(const mitk::DataNode *node) override
See &#39;QmitkAbstractDataStorageModel&#39;.
bool GetIntProperty(const char *propertyKey, int &intValue, const mitk::BaseRenderer *renderer=nullptr) const
Convenience access method for int properties (instances of IntProperty)
Qt::ItemFlags flags(const QModelIndex &index) const override
std::vector< BaseRenderer * > RendererVector
itk::SmartPointer< Self > Pointer
Definition: mitkDataNode.h:71
QmitkNodeDescriptor * GetDescriptor(const mitk::DataNode *node) const
void SetControlledRenderer(mitk::RenderWindowLayerUtilities::RendererVector controlledRenderer)
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
static RenderingManager * GetInstance()
bool IsExpired() const noexcept
bool GetVisibility(bool &visible, const mitk::BaseRenderer *renderer, const char *propertyKey="visible") const
Convenience access method for visibility properties (instances of BoolProperty with property-key "vis...
Definition: mitkDataNode.h:422
MITKRENDERWINDOWMANAGER_EXPORT LayerStack GetLayerStack(const DataStorage *dataStorage, const BaseRenderer *renderer, bool withBaseNode)
Return the stack of layers of the given renderer as std::map<int, DataNode::Pointer>, which guarantees ordering of the layers. Stacked layers are only included if they have their "fixedLayer" property set to true and their "layer" property set.
void DataStorageChanged() override
See &#39;QmitkAbstractDataStorageModel&#39;.
int columnCount(const QModelIndex &parent=QModelIndex()) const override
void RequestUpdate(vtkRenderWindow *renderWindow)
int rowCount(const QModelIndex &parent=QModelIndex()) const override
void NodePredicateChanged() override
See &#39;QmitkAbstractDataStorageModel&#39;.
QMimeData * mimeData(const QModelIndexList &indexes) const override
void NodeAdded(const mitk::DataNode *node) override
See &#39;QmitkAbstractDataStorageModel&#39;.
void SetCurrentRenderer(mitk::BaseRenderer *baseRenderer)
virtual QIcon GetIcon(const mitk::DataNode *node) const
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override
static QmitkNodeDescriptorManager * GetInstance()
Class for nodes of the DataTree.
Definition: mitkDataNode.h:57
QVariant data(const QModelIndex &index, int role) const override
mitk::WeakPointer< mitk::DataStorage > m_DataStorage