MITK-IGT
IGT Extension of MITK
Loading...
Searching...
No Matches
QmitkUSZonesDataModel.cpp
Go to the documentation of this file.
1/*============================================================================
2
3The Medical Imaging Interaction Toolkit (MITK)
4
5Copyright (c) German Cancer Research Center (DKFZ)
6All rights reserved.
7
8Use of this source code is governed by a 3-clause BSD license that can be
9found in the LICENSE file.
10
11============================================================================*/
12
14
15#include <QBrush>
16
17#include "mitkMessage.h"
18#include "mitkProperties.h"
19#include "mitkRenderingManager.h"
21
23 QAbstractTableModel(parent),
24 m_ListenerAddNode(this, &QmitkUSZonesDataModel::AddNode),
25 m_ListenerChangeNode(this, &QmitkUSZonesDataModel::ChangeNode),
26 m_ListenerRemoveNode(this, &QmitkUSZonesDataModel::RemoveNode)
27{
28}
29
31{
32 if ( m_DataStorage.IsNotNull() )
33 {
34 m_DataStorage->AddNodeEvent.RemoveListener(m_ListenerAddNode);
35 m_DataStorage->ChangedNodeEvent.RemoveListener(m_ListenerChangeNode);
36 m_DataStorage->InteractorChangedNodeEvent.RemoveListener(m_ListenerChangeNode);
37 m_DataStorage->RemoveNodeEvent.RemoveListener(m_ListenerRemoveNode);
38 }
39}
40
41void QmitkUSZonesDataModel::SetDataStorage(mitk::DataStorage::Pointer dataStorage, mitk::DataNode::Pointer baseNode)
42{
43 m_DataStorage = dataStorage;
44 m_BaseNode = baseNode;
45
46 if ( m_DataStorage.IsNotNull() )
47 {
48 m_DataStorage->AddNodeEvent.AddListener(m_ListenerAddNode);
49 m_DataStorage->RemoveNodeEvent.AddListener(m_ListenerRemoveNode);
50 m_DataStorage->ChangedNodeEvent.AddListener(m_ListenerChangeNode);
51 m_DataStorage->InteractorChangedNodeEvent.AddListener(m_ListenerChangeNode);
52 }
53}
54
55void QmitkUSZonesDataModel::AddNode(const mitk::DataNode* node)
56{
57 if ( m_DataStorage.IsNull() )
58 {
59 MITK_ERROR << "DataStorage has to be set before adding the first zone node.";
60 mitkThrow() << "DataStorage has to be set before adding the first zone node.";
61 }
62
63 // do not add nodes, which aren't fully created yet
64 bool boolValue;
65 if ( ! (node->GetBoolProperty(mitk::USZonesInteractor::DATANODE_PROPERTY_CREATED, boolValue) && boolValue) )
66 {
67 return;
68 }
69
70 // get source node of given node and test if m_BaseNode is a source node
71 mitk::DataStorage::SetOfObjects::ConstPointer sourceNodes = m_DataStorage->GetSources(node);
72 mitk::DataStorage::SetOfObjects::ConstIterator baseNodeIt = sourceNodes->Begin();
73 while ( baseNodeIt != sourceNodes->End() && baseNodeIt->Value() != m_BaseNode ) { ++baseNodeIt; }
74
75 // only nodes below m_BaseNode should be added to the model
76 if ( baseNodeIt == sourceNodes->End() ) { return; }
77
78 int newRowIndex = this->rowCount();
79 this->insertRow(newRowIndex);
80 m_ZoneNodes.at(newRowIndex) = const_cast<mitk::DataNode*>(node);
81
82 // get row of the changed node and emit signal that the data of this row changed
83 emit dataChanged(this->index(newRowIndex, 0), this->index(newRowIndex, this->columnCount()));
84}
85
86void QmitkUSZonesDataModel::RemoveNode(const mitk::DataNode* node)
87{
88 // find index of the given node in the nodes vector
89 unsigned int index = 0;
90 DataNodeVector::iterator current = m_ZoneNodes.begin();
91 while (current != m_ZoneNodes.end())
92 {
93 if ( *current == node ) { break; }
94 ++index;
95 ++current;
96 }
97
98 // remove node from model if it was found
99 if ( current != m_ZoneNodes.end() )
100 {
101 // remove node from the model and make sure that there will be no
102 // recursive removing calls (as removing node from data storage inside
103 // removeRows function will lead into another call of RemoveNode).
104 this->removeRows(index, 1, QModelIndex(), false);
105 }
106}
107
108void QmitkUSZonesDataModel::ChangeNode(const mitk::DataNode* node)
109{
110 if ( static_cast<itk::SmartPointer<const mitk::DataNode> >(node).IsNull() ) { return; }
111
112 DataNodeVector::iterator oldNodeIt = find (m_ZoneNodes.begin(), m_ZoneNodes.end(), node);
113 if (oldNodeIt == m_ZoneNodes.end())
114 {
115 // if node was not added yet, but it's creation is finished -> add it now
116 bool boolValue;
117 if ( node->GetBoolProperty(mitk::USZonesInteractor::DATANODE_PROPERTY_CREATED, boolValue) && boolValue )
118 {
119 this->AddNode(node);
120 }
121
122 return;
123 }
124
125 // get row of the changed node and emit signal that the data of this row changed
126 unsigned int row = oldNodeIt - m_ZoneNodes.begin();
127 emit dataChanged(this->index(row, 0), this->index(row, this->columnCount()));
128}
129
130int QmitkUSZonesDataModel::rowCount ( const QModelIndex& /*parent*/ ) const
131{
132 return m_ZoneNodes.size();
133}
134
135int QmitkUSZonesDataModel::columnCount ( const QModelIndex& /*parent*/ ) const
136{
137 return 3;
138}
139
140QVariant QmitkUSZonesDataModel::headerData ( int section, Qt::Orientation orientation, int role ) const
141{
142 if ( role != Qt::DisplayRole ) { return QVariant(QVariant::Invalid); }
143
144 if ( orientation == Qt::Horizontal )
145 {
146 switch ( section )
147 {
148 case 0: return QVariant("Name");
149 case 1: return QVariant("Size");
150 case 2: return QVariant("Color");
151 }
152 }
153 else
154 {
155 return QVariant(section+1);
156 }
157
158 return QVariant(QVariant::Invalid);
159}
160
161Qt::ItemFlags QmitkUSZonesDataModel::flags ( const QModelIndex& index ) const
162{
163 if (index.column() == 1 || index.column() == 2) { return Qt::ItemIsSelectable | Qt::ItemIsEnabled; }
164
165 return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
166}
167
168QVariant QmitkUSZonesDataModel::data ( const QModelIndex& index, int role ) const
169{
170 // make sure that row and column index fit data borders
171 if (static_cast<unsigned int>(index.row()) >= m_ZoneNodes.size()
172 || index.column() >= this->columnCount())
173 {
174 return QVariant(QVariant::Invalid);
175 }
176
177 mitk::DataNode::Pointer curNode = m_ZoneNodes.at(index.row());
178
179 switch (role)
180 {
181 case Qt::BackgroundRole:
182 {
183 float color[3];
184 if ( curNode->GetColor(color) )
185 {
186 QColor qColor(color[0] * 255, color[1] * 255, color[2] * 255);
187 if (qColor.isValid()) { return QVariant(QBrush(qColor)); }
188 }
189
190 break;
191 }
192
193 case Qt::EditRole:
194 case Qt::DisplayRole:
195 {
196 switch ( index.column() )
197 {
198 case 0:
199 {
200 return QString::fromStdString(curNode->GetName());
201 }
202 case 1:
203 {
204 float floatValue;
205 if ( curNode->GetFloatProperty(mitk::USZonesInteractor::DATANODE_PROPERTY_SIZE, floatValue) )
206 {
207 return static_cast<int>(floatValue);
208 }
209 else
210 {
211 return QVariant(QVariant::Invalid);
212 }
213 }
214 case 2:
215 {
216 float color[3];
217 if ( curNode->GetColor(color) )
218 {
219 QColor qColor(color[0] * 255, color[1] * 255, color[2] * 255);
220
221 if (qColor == Qt::darkGreen) { return QVariant("Green"); }
222 else if (qColor == Qt::red) { return QVariant("Red"); }
223 else if (qColor == Qt::blue) { return QVariant("Blue"); }
224 else if (qColor == Qt::yellow) { return QVariant("Yellow"); }
225 else { return QVariant(qColor.name()); }
226 }
227 else { return QVariant(QVariant::Invalid); }
228 }
229 }
230 break;
231 }
232 }
233
234 return QVariant(QVariant::Invalid);
235}
236
237bool QmitkUSZonesDataModel::setData ( const QModelIndex & index, const QVariant & value, int role )
238{
239 if (role == Qt::EditRole)
240 {
241 if (static_cast<unsigned int>(index.row()) >= m_ZoneNodes.size()
242 || index.column() >= this->columnCount())
243 {
244 return false;
245 }
246
247 mitk::DataNode::Pointer curNode = m_ZoneNodes.at(index.row());
248
249 switch ( index.column() )
250 {
251 case 0:
252 {
253 curNode->SetName(value.toString().toStdString());
254 break;
255 }
256 case 1:
257 {
258 curNode->SetFloatProperty(mitk::USZonesInteractor::DATANODE_PROPERTY_SIZE, value.toFloat());
259
260 if (curNode->GetData() != nullptr)
261 {
262 curNode->SetFloatProperty(mitk::USZonesInteractor::DATANODE_PROPERTY_SIZE, value.toFloat());
264 }
265
266 break;
267 }
268 case 2:
269 {
270 QColor color(value.toString());
271 curNode->SetColor(color.redF(), color.greenF(), color.blueF());
272 break;
273 }
274 default:
275 return false;
276 }
277
278 emit dataChanged(index, index);
279 }
280
281 // update the RenderWindow to show new points
282 mitk::RenderingManager::GetInstance()->RequestUpdateAll();
283
284 return true;
285}
286
287bool QmitkUSZonesDataModel::insertRows ( int row, int count, const QModelIndex & parent )
288{
289 this->beginInsertRows(parent, row, row+count-1);
290
291 for ( int n = 0; n < count; ++n )
292 {
293 m_ZoneNodes.insert(m_ZoneNodes.begin()+row, mitk::DataNode::New());
294 }
295
296 this->endInsertRows();
297
298 return true;
299}
300
301bool QmitkUSZonesDataModel::removeRows ( int row, int count, const QModelIndex & parent )
302{
303 return this->removeRows(row, count, parent, true);
304}
305
306bool QmitkUSZonesDataModel::removeRows ( int row, int count, const QModelIndex & parent, bool removeFromDataStorage )
307{
308 if ( static_cast<unsigned int>(row+count) > m_ZoneNodes.size() ) { return false; }
309
310 this->beginRemoveRows(parent, row, row+count-1);
311
312 for ( int n = count-1; n >= 0; --n )
313 {
314 DataNodeVector::iterator it = m_ZoneNodes.begin()+row+n;
315 mitk::DataNode::Pointer curNode = *it;
316 m_ZoneNodes.erase(it);
317
318 if ( removeFromDataStorage && m_DataStorage.IsNotNull() )
319 {
320 m_DataStorage->Remove(curNode);
321 }
322 }
323
324 this->endRemoveRows();
325
326 return true;
327}
Implementation of the QAbstractTableModel for ultrasound risk zones. This class manages the data mode...
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
Return names for the columns, numbers for the rows and invalid for DisplayRole.
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
Return model data of the selected cell.
int columnCount(const QModelIndex &parent=QModelIndex()) const override
Return number of columns (3) of the model.
mitk::DataStorage::Pointer m_DataStorage
void SetDataStorage(mitk::DataStorage::Pointer dataStorage, mitk::DataNode::Pointer baseNode)
Set data storage and base node for the zone nodes of this model. The node event listeners will only r...
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
Remove given rows from the model.
QmitkUSZonesDataModel(QObject *parent=nullptr)
void RemoveNode(const mitk::DataNode *)
Qt::ItemFlags flags(const QModelIndex &index) const override
Return selectable and enabled for column 1 (size); selectable, enabled and editable for every other c...
void AddNode(const mitk::DataNode *)
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
Set model data for the selected cell.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Return number of rows of the model.
bool insertRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
Insert empty rows into the model (creates zone nodes).
mitk::DataNode::Pointer m_BaseNode
void ChangeNode(const mitk::DataNode *)
static void UpdateSurface(itk::SmartPointer< mitk::DataNode >)
Creates Vtk Sphere according to current radius. The radius is gotten from the float property "zone....
static const char * DATANODE_PROPERTY_SIZE
static const char * DATANODE_PROPERTY_CREATED