00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <mitkStringProperty.h>
00018 #include <mitkNodePredicateFirstLevel.h>
00019 #include <mitkNodePredicateAnd.h>
00020 #include <mitkNodePredicateData.h>
00021 #include <mitkNodePredicateNot.h>
00022 #include <mitkNodePredicateProperty.h>
00023 #include <mitkProperties.h>
00024 #include <mitkRenderingManager.h>
00025
00026 #include "QmitkDataStorageTreeModel.h"
00027 #include "QmitkNodeDescriptorManager.h"
00028 #include <QmitkEnums.h>
00029 #include <QmitkCustomVariants.h>
00030
00031 #include <QIcon>
00032 #include <QMimeData>
00033 #include <QTextStream>
00034
00035 QmitkDataStorageTreeModel::QmitkDataStorageTreeModel( mitk::DataStorage* _DataStorage
00036 , bool _PlaceNewNodesOnTop
00037 , QObject* parent )
00038 : QAbstractItemModel(parent)
00039 , m_DataStorage(0)
00040 , m_PlaceNewNodesOnTop(_PlaceNewNodesOnTop)
00041 , m_Root(0)
00042 {
00043 mitk::NodePredicateData::Pointer dataIsNull = mitk::NodePredicateData::New(0);
00044 mitk::NodePredicateNot::Pointer dataIsNotNull
00045 = mitk::NodePredicateNot::New(dataIsNull);
00046
00047 mitk::NodePredicateProperty::Pointer isHelperObject = mitk::NodePredicateProperty::New("helper object"
00048 , mitk::BoolProperty::New(true));
00049
00050 mitk::NodePredicateNot::Pointer isNotHelperObject
00051 = mitk::NodePredicateNot::New(isHelperObject);
00052
00053 mitk::NodePredicateAnd::Pointer dataIsNotNullAndIsNotHelperObject = mitk::NodePredicateAnd::New(dataIsNotNull,
00054 isNotHelperObject);
00055
00056 m_Predicate = dataIsNotNullAndIsNotHelperObject;
00057
00058 this->SetDataStorage(_DataStorage);
00059 }
00060
00061 QmitkDataStorageTreeModel::~QmitkDataStorageTreeModel()
00062 {
00063
00064 this->SetDataStorage(0);
00065 m_Root->Delete(); m_Root = 0;
00066 }
00067
00068 mitk::DataNode::Pointer QmitkDataStorageTreeModel::GetNode( const QModelIndex &index ) const
00069 {
00070 return this->TreeItemFromIndex(index)->GetDataNode();
00071 }
00072
00073 const mitk::DataStorage::Pointer QmitkDataStorageTreeModel::GetDataStorage() const
00074 {
00075 return m_DataStorage.GetPointer();
00076 }
00077
00078 QModelIndex QmitkDataStorageTreeModel::index( int row, int column, const QModelIndex & parent ) const
00079 {
00080 TreeItem* parentItem;
00081
00082 if (!parent.isValid())
00083 parentItem = m_Root;
00084 else
00085 parentItem = static_cast<TreeItem*>(parent.internalPointer());
00086
00087 TreeItem *childItem = parentItem->GetChild(row);
00088 if (childItem)
00089 return createIndex(row, column, childItem);
00090 else
00091 return QModelIndex();
00092
00093
00094 }
00095
00096 int QmitkDataStorageTreeModel::rowCount(const QModelIndex &parent) const
00097 {
00098 TreeItem *parentTreeItem = this->TreeItemFromIndex(parent);
00099 return parentTreeItem->GetChildCount();
00100 }
00101
00102
00103 Qt::ItemFlags QmitkDataStorageTreeModel::flags( const QModelIndex& index ) const
00104 {
00105 if (index.isValid())
00106 return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable
00107 | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
00108 else
00109 return Qt::ItemIsDropEnabled;
00110 }
00111
00112 int QmitkDataStorageTreeModel::columnCount( const QModelIndex& ) const
00113 {
00114 return 1;
00115 }
00116
00117 QModelIndex QmitkDataStorageTreeModel::parent(const QModelIndex &index) const
00118 {
00119 if (!index.isValid())
00120 return QModelIndex();
00121
00122 TreeItem *childItem = this->TreeItemFromIndex(index);
00123 TreeItem *parentItem = childItem->GetParent();
00124
00125 if (parentItem == m_Root)
00126 return QModelIndex();
00127
00128 return this->createIndex(parentItem->GetIndex(), 0, parentItem);
00129 }
00130
00131 QmitkDataStorageTreeModel::TreeItem* QmitkDataStorageTreeModel::TreeItemFromIndex( const QModelIndex &index ) const
00132 {
00133 if (index.isValid())
00134 return static_cast<TreeItem *>(index.internalPointer());
00135 else
00136 return m_Root;
00137 }
00138 Qt::DropActions QmitkDataStorageTreeModel::supportedDropActions() const
00139 {
00140 return Qt::CopyAction | Qt::MoveAction;
00141 }
00142
00143 bool QmitkDataStorageTreeModel::dropMimeData(const QMimeData *data,
00144 Qt::DropAction action, int , int , const QModelIndex &parent)
00145 {
00146 if (action == Qt::IgnoreAction)
00147 return true;
00148
00149 if(data->hasFormat("application/x-qabstractitemmodeldatalist"))
00150 {
00151 QString arg = QString(data->data("application/x-qabstractitemmodeldatalist").data());
00152 long val = arg.toLong();
00153 TreeItem* draggedItem = static_cast<TreeItem *>((void*)val);
00154 TreeItem* dropItem = this->TreeItemFromIndex(parent);
00155 TreeItem* parentItem = dropItem->GetParent();
00156 if(dropItem == m_Root)
00157 parentItem = m_Root;
00158
00159 if(draggedItem != dropItem && draggedItem->GetParent() == parentItem)
00160 {
00161 QModelIndex parentModelIndex = this->IndexFromTreeItem(parentItem);
00162
00163
00164 this->beginRemoveRows(parentModelIndex, draggedItem->GetIndex(), draggedItem->GetIndex());
00165
00166 parentItem->RemoveChild(draggedItem);
00167
00168 endRemoveRows();
00169
00170
00171 int index = parentItem->IndexOfChild(dropItem);
00172 if(dropItem == m_Root)
00173 index = parentItem->GetChildCount();
00174
00175 beginInsertRows(parentModelIndex, index, index);
00176
00177
00178 parentItem->InsertChild( draggedItem, index );
00179
00180
00181 endInsertRows();
00182
00183 this->AdjustLayerProperty();
00184 }
00185 }
00186 return false;
00187 }
00188
00189
00190 QMimeData * QmitkDataStorageTreeModel::mimeData(const QModelIndexList & indexes) const{
00191 QMimeData * ret = new QMimeData;
00192 long a = reinterpret_cast<long>(indexes.at(0).internalPointer());
00193
00194 QString result;
00195 QTextStream(&result) << a;
00196 ret->setData("application/x-qabstractitemmodeldatalist", QByteArray(result.toAscii()));
00197 return ret;
00198 }
00199
00200 QVariant QmitkDataStorageTreeModel::data( const QModelIndex & index, int role ) const
00201 {
00202 mitk::DataNode* dataNode = this->TreeItemFromIndex(index)->GetDataNode();
00203
00204
00205 QString nodeName = QString::fromStdString(dataNode->GetName());
00206 if(nodeName.isEmpty())
00207 nodeName = "unnamed";
00208
00209 if (role == Qt::DisplayRole)
00210 return nodeName;
00211 else if(role == Qt::ToolTipRole)
00212 return nodeName;
00213 else if(role == Qt::DecorationRole)
00214 {
00215 QmitkNodeDescriptor* nodeDescriptor
00216 = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(dataNode);
00217 return nodeDescriptor->GetIcon();
00218 }
00219 else if(role == Qt::CheckStateRole)
00220 {
00221 return dataNode->IsVisible(0);
00222 }
00223 else if(role == QmitkDataNodeRole)
00224 {
00225 return QVariant::fromValue<mitk::DataNode::Pointer>(mitk::DataNode::Pointer(dataNode));
00226 }
00227
00228 return QVariant();
00229 }
00230
00231 QVariant QmitkDataStorageTreeModel::headerData(int ,
00232 Qt::Orientation orientation,
00233 int role) const
00234 {
00235 if (orientation == Qt::Horizontal && role == Qt::DisplayRole && m_Root)
00236 return QString::fromStdString(m_Root->GetDataNode()->GetName());
00237
00238 return QVariant();
00239 }
00240
00241 void QmitkDataStorageTreeModel::SetDataStorage( mitk::DataStorage* _DataStorage )
00242 {
00243 if(m_DataStorage != _DataStorage)
00244 {
00245 if(m_DataStorage.IsNotNull())
00246 {
00247
00248 m_DataStorage.ObjectDelete.RemoveListener( mitk::MessageDelegate1<QmitkDataStorageTreeModel
00249 , const itk::Object*>( this, &QmitkDataStorageTreeModel::SetDataStorageDeleted ) );
00250
00251
00252 m_DataStorage->AddNodeEvent.RemoveListener( mitk::MessageDelegate1<QmitkDataStorageTreeModel
00253 , const mitk::DataNode*>( this, &QmitkDataStorageTreeModel::AddNode ) );
00254
00255 m_DataStorage->ChangedNodeEvent.RemoveListener( mitk::MessageDelegate1<QmitkDataStorageTreeModel
00256 , const mitk::DataNode*>( this, &QmitkDataStorageTreeModel::SetNodeModified ) );
00257
00258 m_DataStorage->RemoveNodeEvent.RemoveListener( mitk::MessageDelegate1<QmitkDataStorageTreeModel
00259 , const mitk::DataNode*>( this, &QmitkDataStorageTreeModel::RemoveNode ) );
00260
00261 }
00262
00263
00264 m_DataStorage = _DataStorage;
00265
00266
00267 if(m_Root)
00268 m_Root->Delete();
00269 mitk::DataNode::Pointer rootDataNode = mitk::DataNode::New();
00270 rootDataNode->SetName("Data Manager");
00271 m_Root = new TreeItem(rootDataNode, 0);
00272 this->reset();
00273
00274 if(m_DataStorage.IsNotNull())
00275 {
00276
00277 m_DataStorage.ObjectDelete.AddListener( mitk::MessageDelegate1<QmitkDataStorageTreeModel
00278 , const itk::Object*>( this, &QmitkDataStorageTreeModel::SetDataStorageDeleted ) );
00279
00280
00281 m_DataStorage->AddNodeEvent.AddListener( mitk::MessageDelegate1<QmitkDataStorageTreeModel
00282 , const mitk::DataNode*>( this, &QmitkDataStorageTreeModel::AddNode ) );
00283
00284 m_DataStorage->ChangedNodeEvent.AddListener( mitk::MessageDelegate1<QmitkDataStorageTreeModel
00285 , const mitk::DataNode*>( this, &QmitkDataStorageTreeModel::SetNodeModified ) );
00286
00287 m_DataStorage->RemoveNodeEvent.AddListener( mitk::MessageDelegate1<QmitkDataStorageTreeModel
00288 , const mitk::DataNode*>( this, &QmitkDataStorageTreeModel::RemoveNode ) );
00289
00290 mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet = m_DataStorage->GetSubset(m_Predicate);
00291
00292
00293 for(mitk::DataStorage::SetOfObjects::const_iterator it=_NodeSet->begin(); it!=_NodeSet->end()
00294 ; it++)
00295 {
00296
00297 this->AddNode(*it);
00298 }
00299 }
00300 }
00301 }
00302
00303 void QmitkDataStorageTreeModel::SetDataStorageDeleted( const itk::Object* )
00304 {
00305 this->SetDataStorage(0);
00306 }
00307
00308 void QmitkDataStorageTreeModel::AddNode( const mitk::DataNode* node )
00309 {
00310 if(node == 0
00311 || m_DataStorage.IsNull()
00312 || !m_DataStorage->Exists(node)
00313 || !m_Predicate->CheckNode(node)
00314 || m_Root->Find(node) != 0)
00315 return;
00316
00317
00318 TreeItem* parentTreeItem = m_Root;
00319 QModelIndex index;
00320 mitk::DataNode* parentDataNode = this->GetParentNode(node);
00321
00322 if(parentDataNode)
00323 {
00324 parentTreeItem = m_Root->Find(parentDataNode);
00325 if(!parentTreeItem)
00326 {
00327 this->AddNode(parentDataNode);
00328 parentTreeItem = m_Root->Find(parentDataNode);
00329 if(!parentTreeItem)
00330 return;
00331 }
00332
00333
00334 index = this->createIndex(parentTreeItem->GetIndex(), 0, parentTreeItem);
00335 }
00336
00337
00338 if(m_PlaceNewNodesOnTop)
00339 {
00340
00341 beginInsertRows(index, 0, 0);
00342 parentTreeItem->InsertChild(new TreeItem(
00343 const_cast<mitk::DataNode*>(node)), 0);
00344 }
00345 else
00346 {
00347 beginInsertRows(index, parentTreeItem->GetChildCount()
00348 , parentTreeItem->GetChildCount());
00349 new TreeItem(const_cast<mitk::DataNode*>(node), parentTreeItem);
00350 }
00351
00352
00353 endInsertRows();
00354
00355 this->AdjustLayerProperty();
00356 }
00357
00358
00359 void QmitkDataStorageTreeModel::SetPlaceNewNodesOnTop(bool _PlaceNewNodesOnTop)
00360 {
00361 m_PlaceNewNodesOnTop = _PlaceNewNodesOnTop;
00362 }
00363
00364 void QmitkDataStorageTreeModel::RemoveNode( const mitk::DataNode* node )
00365 {
00366 if(!m_Root) return;
00367
00368 TreeItem* treeItem = m_Root->Find(node);
00369 if(!treeItem)
00370 return;
00371
00372 TreeItem* parentTreeItem = treeItem->GetParent();
00373 QModelIndex parentIndex = this->IndexFromTreeItem(parentTreeItem);
00374
00375
00376 this->beginRemoveRows(parentIndex, treeItem->GetIndex(), treeItem->GetIndex());
00377
00378
00379 std::vector<TreeItem*> children = treeItem->GetChildren();
00380 delete treeItem;
00381
00382
00383 endRemoveRows();
00384
00385
00386 for ( std::vector<TreeItem*>::iterator it = children.begin()
00387 ; it != children.end(); it++)
00388 {
00389
00390 beginInsertRows(parentIndex, parentTreeItem->GetChildCount(), parentTreeItem->GetChildCount());
00391
00392
00393 parentTreeItem->AddChild(*it);
00394
00395
00396 endInsertRows();
00397 }
00398
00399 this->AdjustLayerProperty();
00400 }
00401
00402 void QmitkDataStorageTreeModel::SetNodeModified( const mitk::DataNode* node )
00403 {
00404 TreeItem* treeItem = m_Root->Find(node);
00405 if(!treeItem)
00406 return;
00407
00408 TreeItem* parentTreeItem = treeItem->GetParent();
00409
00410 if(!parentTreeItem)
00411 return;
00412 QModelIndex index = this->createIndex(treeItem->GetIndex(), 0, treeItem);
00413
00414
00415 emit dataChanged(index, index);
00416 }
00417
00418 mitk::DataNode* QmitkDataStorageTreeModel::GetParentNode( const mitk::DataNode* node ) const
00419 {
00420 mitk::DataNode* dataNode = 0;
00421
00422 mitk::DataStorage::SetOfObjects::ConstPointer _Sources = m_DataStorage->GetSources(node);
00423
00424 if(_Sources->Size() > 0)
00425 dataNode = _Sources->front();
00426
00427 return dataNode;
00428 }
00429
00430 bool QmitkDataStorageTreeModel::setData( const QModelIndex &index, const QVariant &value, int role )
00431 {
00432 mitk::DataNode* dataNode = this->TreeItemFromIndex(index)->GetDataNode();
00433 if(!dataNode)
00434 return false;
00435
00436 if(role == Qt::EditRole && !value.toString().isEmpty())
00437 {
00438 dataNode->SetStringProperty("name", value.toString().toStdString().c_str());
00439 }
00440 else if(role == Qt::CheckStateRole)
00441 {
00442
00443
00444
00445 QVariant qcheckstate = index.data(Qt::CheckStateRole);
00446 int checkstate = qcheckstate.toInt();
00447 bool isVisible = bool(checkstate);
00448 dataNode->SetVisibility(!isVisible);
00449 mitk::RenderingManager::GetInstance()->RequestUpdateAll();
00450 }
00451
00452 emit dataChanged(index, index);
00453 return true;
00454 }
00455
00456 bool QmitkDataStorageTreeModel::setHeaderData( int , Qt::Orientation , const QVariant& , int )
00457 {
00458 return false;
00459 }
00460
00461 void QmitkDataStorageTreeModel::AdjustLayerProperty()
00462 {
00464 std::vector<TreeItem*> vec;
00465 this->TreeToVector(m_Root, vec);
00466
00467 int i = vec.size()-1;
00468 for(std::vector<TreeItem*>::const_iterator it = vec.begin(); it != vec.end(); ++it)
00469 {
00470 (*it)->GetDataNode()->SetIntProperty("layer", i);
00471 --i;
00472 }
00473 mitk::RenderingManager::GetInstance()->RequestUpdateAll();
00474 }
00475
00476 void QmitkDataStorageTreeModel::TreeToVector(TreeItem* parent, std::vector<TreeItem*>& vec) const
00477 {
00478 TreeItem* current;
00479 for(int i = 0; i<parent->GetChildCount(); ++i)
00480 {
00481 current = parent->GetChild(i);
00482 this->TreeToVector(current, vec);
00483 vec.push_back(current);
00484 }
00485 }
00486
00487 QModelIndex QmitkDataStorageTreeModel::IndexFromTreeItem( TreeItem* item ) const
00488 {
00489 if(item == m_Root)
00490 return QModelIndex();
00491 else
00492 return this->createIndex(item->GetIndex(), 0, item);
00493 }
00494
00495 std::vector<mitk::DataNode*> QmitkDataStorageTreeModel::GetNodeSet() const
00496 {
00497 std::vector<mitk::DataNode*> vec;
00498 if(m_Root)
00499 this->TreeToNodeSet(m_Root, vec);
00500
00501 return vec;
00502 }
00503
00504 void QmitkDataStorageTreeModel::TreeToNodeSet( TreeItem* parent, std::vector<mitk::DataNode*>& vec ) const
00505 {
00506 TreeItem* current;
00507 for(int i = 0; i<parent->GetChildCount(); ++i)
00508 {
00509 current = parent->GetChild(i);
00510 vec.push_back(current->GetDataNode());
00511 this->TreeToNodeSet(current, vec);
00512 }
00513 }
00514
00515 QModelIndex QmitkDataStorageTreeModel::GetIndex( const mitk::DataNode* node ) const
00516 {
00517 if(m_Root)
00518 {
00519 TreeItem* item = m_Root->Find(node);
00520 if(item)
00521 return this->IndexFromTreeItem(item);
00522 }
00523 return QModelIndex();
00524 }
00525
00526 QmitkDataStorageTreeModel::TreeItem::TreeItem( mitk::DataNode* _DataNode, TreeItem* _Parent )
00527 : m_Parent(_Parent)
00528 , m_DataNode(_DataNode)
00529 {
00530 if(m_Parent)
00531 m_Parent->AddChild(this);
00532 }
00533
00534 QmitkDataStorageTreeModel::TreeItem::~TreeItem()
00535 {
00536 if(m_Parent)
00537 m_Parent->RemoveChild(this);
00538 }
00539
00540 void QmitkDataStorageTreeModel::TreeItem::Delete()
00541 {
00542 while(m_Children.size() > 0)
00543 delete m_Children.back();
00544
00545 delete this;
00546 }
00547
00548 QmitkDataStorageTreeModel::TreeItem* QmitkDataStorageTreeModel::TreeItem::Find( const mitk::DataNode* _DataNode ) const
00549 {
00550 QmitkDataStorageTreeModel::TreeItem* item = 0;
00551 if(_DataNode)
00552 {
00553 if(m_DataNode == _DataNode)
00554 item = const_cast<TreeItem*>(this);
00555 else
00556 {
00557 for(std::vector<TreeItem*>::const_iterator it = m_Children.begin(); it != m_Children.end(); ++it)
00558 {
00559 if(item)
00560 break;
00561 item = (*it)->Find(_DataNode);
00562 }
00563 }
00564 }
00565 return item;
00566 }
00567
00568 int QmitkDataStorageTreeModel::TreeItem::IndexOfChild( const TreeItem* item ) const
00569 {
00570 std::vector<TreeItem*>::const_iterator it = std::find(m_Children.begin(), m_Children.end(), item);
00571 return it != m_Children.end() ? std::distance(m_Children.begin(), it): -1;
00572 }
00573
00574 QmitkDataStorageTreeModel::TreeItem* QmitkDataStorageTreeModel::TreeItem::GetChild( int index ) const
00575 {
00576 return (m_Children.size() > 0 && index >= 0 && index < (int)m_Children.size())? m_Children.at(index): 0;
00577 }
00578
00579 void QmitkDataStorageTreeModel::TreeItem::AddChild( TreeItem* item )
00580 {
00581 this->InsertChild(item);
00582 }
00583
00584 void QmitkDataStorageTreeModel::TreeItem::RemoveChild( TreeItem* item )
00585 {
00586 std::vector<TreeItem*>::iterator it = std::find(m_Children.begin(), m_Children.end(), item);
00587 if(it != m_Children.end())
00588 {
00589 m_Children.erase(it);
00590 item->SetParent(0);
00591 }
00592 }
00593
00594 int QmitkDataStorageTreeModel::TreeItem::GetChildCount() const
00595 {
00596 return m_Children.size();
00597 }
00598
00599 int QmitkDataStorageTreeModel::TreeItem::GetIndex() const
00600 {
00601 if (m_Parent)
00602 return m_Parent->IndexOfChild(this);
00603
00604 return 0;
00605 }
00606
00607 QmitkDataStorageTreeModel::TreeItem* QmitkDataStorageTreeModel::TreeItem::GetParent() const
00608 {
00609 return m_Parent;
00610 }
00611
00612 mitk::DataNode::Pointer QmitkDataStorageTreeModel::TreeItem::GetDataNode() const
00613 {
00614 return m_DataNode;
00615 }
00616
00617 void QmitkDataStorageTreeModel::TreeItem::InsertChild( TreeItem* item, int index )
00618 {
00619 std::vector<TreeItem*>::iterator it = std::find(m_Children.begin(), m_Children.end(), item);
00620 if(it == m_Children.end())
00621 {
00622 if(m_Children.size() > 0 && index >= 0 && index < (int)m_Children.size())
00623 {
00624 it = m_Children.begin();
00625 std::advance(it, index);
00626 m_Children.insert(it, item);
00627 }
00628 else
00629 m_Children.push_back(item);
00630
00631
00632 if(item->GetParent() != this)
00633 item->SetParent(this);
00634 }
00635 }
00636
00637 std::vector<QmitkDataStorageTreeModel::TreeItem*> QmitkDataStorageTreeModel::TreeItem::GetChildren() const
00638 {
00639 return m_Children;
00640 }
00641
00642 void QmitkDataStorageTreeModel::TreeItem::SetParent( TreeItem* _Parent )
00643 {
00644 m_Parent = _Parent;
00645 if(m_Parent)
00646 m_Parent->AddChild(this);
00647 }