diff --git a/Modules/QtWidgets/QmitkDataStorageTreeModel.cpp b/Modules/QtWidgets/QmitkDataStorageTreeModel.cpp index b267a98f49..08ad1f8f9a 100644 --- a/Modules/QtWidgets/QmitkDataStorageTreeModel.cpp +++ b/Modules/QtWidgets/QmitkDataStorageTreeModel.cpp @@ -1,925 +1,828 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include #include #include #include #include #include #include #include "QmitkDataStorageTreeModel.h" #include "QmitkNodeDescriptorManager.h" #include #include #include #include #include #include QmitkDataStorageTreeModel::QmitkDataStorageTreeModel( mitk::DataStorage* _DataStorage , bool _PlaceNewNodesOnTop - , bool _ShowHelperObjects - , bool _ShowNodesContainingNoData , QObject* parent ) : QAbstractItemModel(parent) , m_DataStorage(0) , m_PlaceNewNodesOnTop(_PlaceNewNodesOnTop) -, m_ShowHelperObjects(_ShowHelperObjects) -, m_ShowNodesContainingNoData(_ShowNodesContainingNoData) , m_Root(0) { - this->UpdateNodeVisibility(); this->SetDataStorage(_DataStorage); } QmitkDataStorageTreeModel::~QmitkDataStorageTreeModel() { // set data storage to 0 = remove all listeners this->SetDataStorage(0); m_Root->Delete(); m_Root = 0; - - //Removing all observers - for ( NodeTagMapType::iterator dataIter = m_HelperObjectObserverTags.begin(); dataIter != m_HelperObjectObserverTags.end(); ++dataIter ) - { - (*dataIter).first->GetProperty("helper object")->RemoveObserver( (*dataIter).second ); - } - m_HelperObjectObserverTags.clear(); } mitk::DataNode::Pointer QmitkDataStorageTreeModel::GetNode( const QModelIndex &index ) const { return this->TreeItemFromIndex(index)->GetDataNode(); } const mitk::DataStorage::Pointer QmitkDataStorageTreeModel::GetDataStorage() const { return m_DataStorage.GetPointer(); } QModelIndex QmitkDataStorageTreeModel::index( int row, int column, const QModelIndex & parent ) const { TreeItem* parentItem; if (!parent.isValid()) parentItem = m_Root; else parentItem = static_cast(parent.internalPointer()); TreeItem *childItem = parentItem->GetChild(row); if (childItem) return createIndex(row, column, childItem); else return QModelIndex(); } int QmitkDataStorageTreeModel::rowCount(const QModelIndex &parent) const { TreeItem *parentTreeItem = this->TreeItemFromIndex(parent); return parentTreeItem->GetChildCount(); } Qt::ItemFlags QmitkDataStorageTreeModel::flags( const QModelIndex& index ) const { mitk::DataNode* dataNode = this->TreeItemFromIndex(index)->GetDataNode(); if (index.isValid()) { if(DicomPropertiesExists(*dataNode)) { return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; } return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; }else{ return Qt::ItemIsDropEnabled; } } int QmitkDataStorageTreeModel::columnCount( const QModelIndex& /* parent = QModelIndex() */ ) const { return 1; } QModelIndex QmitkDataStorageTreeModel::parent(const QModelIndex &index) const { if (!index.isValid()) return QModelIndex(); TreeItem *childItem = this->TreeItemFromIndex(index); TreeItem *parentItem = childItem->GetParent(); if (parentItem == m_Root) return QModelIndex(); return this->createIndex(parentItem->GetIndex(), 0, parentItem); } QmitkDataStorageTreeModel::TreeItem* QmitkDataStorageTreeModel::TreeItemFromIndex( const QModelIndex &index ) const { if (index.isValid()) return static_cast(index.internalPointer()); else return m_Root; } Qt::DropActions QmitkDataStorageTreeModel::supportedDropActions() const { return Qt::CopyAction | Qt::MoveAction; } Qt::DropActions QmitkDataStorageTreeModel::supportedDragActions() const { return Qt::CopyAction | Qt::MoveAction; } bool QmitkDataStorageTreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int /*row*/, int /*column*/, const QModelIndex &parent) { // Early exit, returning true, but not actually doing anything (ignoring data). if (action == Qt::IgnoreAction) { return true; } // Note, we are returning true if we handled it, and false otherwise bool returnValue = false; if(data->hasFormat("application/x-qabstractitemmodeldatalist")) { returnValue = true; // First we extract a Qlist of TreeItem* pointers. QString arg = QString(data->data("application/x-qabstractitemmodeldatalist").data()); QStringList listOfTreeItemAddressPointers = arg.split(","); QStringList::iterator slIter; QList listOfItemsToDrop; for(slIter = listOfTreeItemAddressPointers.begin(); slIter != listOfTreeItemAddressPointers.end(); slIter++) { long val = (*slIter).toLong(); listOfItemsToDrop << static_cast((void*)val); } // Retrieve the TreeItem* where we are dropping stuff, and its parent. TreeItem* dropItem = this->TreeItemFromIndex(parent); TreeItem* parentItem = dropItem->GetParent(); // If item was dropped onto empty space, we select the root node if(dropItem == m_Root) { parentItem = m_Root; } // Dragging and Dropping is only allowed within the same parent, so use the first item in list to validate. // (otherwise, you could have a derived image such as a segmentation, and assign it to another image). // NOTE: We are assuming the input list is valid... i.e. when it was dragged, all the items had the same parent. if(listOfItemsToDrop[0] != dropItem && listOfItemsToDrop[0]->GetParent() == parentItem) { // Retrieve the index of where we are dropping stuff. QModelIndex dropItemModelIndex = this->IndexFromTreeItem(dropItem); QModelIndex parentModelIndex = this->IndexFromTreeItem(parentItem); // Iterate through the list of TreeItem (which may be at non-consecutive indexes). QList::iterator diIter; for (diIter = listOfItemsToDrop.begin(); diIter != listOfItemsToDrop.end(); diIter++) { // Here we assume that as you remove items, one at a time, that GetIndex() will be valid. this->beginRemoveRows(parentModelIndex, (*diIter)->GetIndex(), (*diIter)->GetIndex()); parentItem->RemoveChild(*diIter); this->endRemoveRows(); } // Select the target index position, or put it at the end of the list. int dropIndex = dropItemModelIndex.row(); if (dropIndex == -1) { dropIndex = parentItem->GetChildCount(); } // Now insert items again at the drop item position this->beginInsertRows(parentModelIndex, dropIndex, dropIndex + listOfItemsToDrop.size() - 1); for (diIter = listOfItemsToDrop.begin(); diIter != listOfItemsToDrop.end(); diIter++) { parentItem->InsertChild( (*diIter), dropIndex ); dropIndex++; } this->endInsertRows(); // Change Layers to match. this->AdjustLayerProperty(); } } else if(data->hasFormat("application/x-mitk-datanodes")) { returnValue = true; QString arg = QString(data->data("application/x-mitk-datanodes").data()); QStringList listOfDataNodeAddressPointers = arg.split(","); int numberOfNodesDropped = 0; QStringList::iterator slIter; for (slIter = listOfDataNodeAddressPointers.begin(); slIter != listOfDataNodeAddressPointers.end(); slIter++) { long val = (*slIter).toLong(); mitk::DataNode* node = static_cast((void*)val); if(node && m_DataStorage.IsNotNull() && !m_DataStorage->Exists(node)) { m_DataStorage->Add( node ); mitk::BaseData::Pointer basedata = node->GetData(); if (basedata.IsNotNull()) { mitk::RenderingManager::GetInstance()->InitializeViews( basedata->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); numberOfNodesDropped++; } } } // Only do a rendering update, if we actually dropped anything. if (numberOfNodesDropped > 0) { mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } return returnValue; } QStringList QmitkDataStorageTreeModel::mimeTypes() const { QStringList types = QAbstractItemModel::mimeTypes(); types << "application/x-qabstractitemmodeldatalist"; types << "application/x-mitk-datanodes"; return types; } QMimeData * QmitkDataStorageTreeModel::mimeData(const QModelIndexList & indexes) const{ QMimeData * ret = new QMimeData; QString treeItemAddresses(""); QString dataNodeAddresses(""); for (int i = 0; i < indexes.size(); i++) { TreeItem* treeItem = static_cast(indexes.at(i).internalPointer()); long treeItemAddress = reinterpret_cast(treeItem); long dataNodeAddress = reinterpret_cast(treeItem->GetDataNode().GetPointer()); QTextStream(&treeItemAddresses) << treeItemAddress; QTextStream(&dataNodeAddresses) << dataNodeAddress; if (i != indexes.size() - 1) { QTextStream(&treeItemAddresses) << ","; QTextStream(&dataNodeAddresses) << ","; } } ret->setData("application/x-qabstractitemmodeldatalist", QByteArray(treeItemAddresses.toAscii())); ret->setData("application/x-mitk-datanodes", QByteArray(dataNodeAddresses.toAscii())); return ret; } QVariant QmitkDataStorageTreeModel::data( const QModelIndex & index, int role ) const { mitk::DataNode* dataNode = this->TreeItemFromIndex(index)->GetDataNode(); // get name of treeItem (may also be edited) QString nodeName; if(DicomPropertiesExists(*dataNode)) { mitk::BaseProperty* seriesDescription = (dataNode->GetProperty("dicom.series.SeriesDescription")); mitk::BaseProperty* studyDescription = (dataNode->GetProperty("dicom.study.StudyDescription")); mitk::BaseProperty* patientsName = (dataNode->GetProperty("dicom.patient.PatientsName")); nodeName.append(patientsName->GetValueAsString().c_str()).append("\n"); nodeName.append(studyDescription->GetValueAsString().c_str()).append("\n"); nodeName.append(seriesDescription->GetValueAsString().c_str()); }else{ nodeName = QString::fromStdString(dataNode->GetName()); } if(nodeName.isEmpty()) { nodeName = "unnamed"; } if (role == Qt::DisplayRole) return nodeName; else if(role == Qt::ToolTipRole) return nodeName; else if(role == Qt::DecorationRole) { QmitkNodeDescriptor* nodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(dataNode); return nodeDescriptor->GetIcon(); } else if(role == Qt::CheckStateRole) { return dataNode->IsVisible(0); } else if(role == QmitkDataNodeRole) { return QVariant::fromValue(mitk::DataNode::Pointer(dataNode)); } else if(role == QmitkDataNodeRawPointerRole) { return QVariant::fromValue(dataNode); } return QVariant(); } bool QmitkDataStorageTreeModel::DicomPropertiesExists(const mitk::DataNode& node) const { bool propertiesExists = false; mitk::BaseProperty* seriesDescription = (node.GetProperty("dicom.series.SeriesDescription")); mitk::BaseProperty* studyDescription = (node.GetProperty("dicom.study.StudyDescription")); mitk::BaseProperty* patientsName = (node.GetProperty("dicom.patient.PatientsName")); if(patientsName!=NULL && studyDescription!=NULL && seriesDescription!=NULL) { if((!patientsName->GetValueAsString().empty())&& (!studyDescription->GetValueAsString().empty())&& (!seriesDescription->GetValueAsString().empty())) { propertiesExists = true; } } return propertiesExists; } QVariant QmitkDataStorageTreeModel::headerData(int /*section*/, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal && role == Qt::DisplayRole && m_Root) return QString::fromStdString(m_Root->GetDataNode()->GetName()); return QVariant(); } void QmitkDataStorageTreeModel::SetDataStorage( mitk::DataStorage* _DataStorage ) { if(m_DataStorage != _DataStorage) // dont take the same again { if(m_DataStorage.IsNotNull()) { // remove Listener for the data storage itself m_DataStorage.ObjectDelete.RemoveListener( mitk::MessageDelegate1( this, &QmitkDataStorageTreeModel::SetDataStorageDeleted ) ); // remove listeners for the nodes m_DataStorage->AddNodeEvent.RemoveListener( mitk::MessageDelegate1( this, &QmitkDataStorageTreeModel::AddNode ) ); m_DataStorage->ChangedNodeEvent.RemoveListener( mitk::MessageDelegate1( this, &QmitkDataStorageTreeModel::SetNodeModified ) ); m_DataStorage->RemoveNodeEvent.RemoveListener( mitk::MessageDelegate1( this, &QmitkDataStorageTreeModel::RemoveNode ) ); } // take over the new data storage m_DataStorage = _DataStorage; // delete the old root (if necessary, create new) if(m_Root) m_Root->Delete(); mitk::DataNode::Pointer rootDataNode = mitk::DataNode::New(); rootDataNode->SetName("Data Manager"); m_Root = new TreeItem(rootDataNode, 0); this->reset(); if(m_DataStorage.IsNotNull()) { // add Listener for the data storage itself m_DataStorage.ObjectDelete.AddListener( mitk::MessageDelegate1( this, &QmitkDataStorageTreeModel::SetDataStorageDeleted ) ); // add listeners for the nodes m_DataStorage->AddNodeEvent.AddListener( mitk::MessageDelegate1( this, &QmitkDataStorageTreeModel::AddNode ) ); m_DataStorage->ChangedNodeEvent.AddListener( mitk::MessageDelegate1( this, &QmitkDataStorageTreeModel::SetNodeModified ) ); m_DataStorage->RemoveNodeEvent.AddListener( mitk::MessageDelegate1( this, &QmitkDataStorageTreeModel::RemoveNode ) ); mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet = m_DataStorage->GetSubset(m_Predicate); // finally add all nodes to the model this->Update(); } } } void QmitkDataStorageTreeModel::SetDataStorageDeleted( const itk::Object* /*_DataStorage*/ ) { this->SetDataStorage(0); } void QmitkDataStorageTreeModel::AddNodeInternal(const mitk::DataNode *node) { if(node == 0 || m_DataStorage.IsNull() || !m_DataStorage->Exists(node) - || !m_Predicate->CheckNode(node) || m_Root->Find(node) != 0) return; // find out if we have a root node TreeItem* parentTreeItem = m_Root; QModelIndex index; mitk::DataNode* parentDataNode = this->GetParentNode(node); if(parentDataNode) // no top level data node { parentTreeItem = m_Root->Find(parentDataNode); // find the corresponding tree item if(!parentTreeItem) { this->AddNode(parentDataNode); parentTreeItem = m_Root->Find(parentDataNode); if(!parentTreeItem) return; } // get the index of this parent with the help of the grand parent index = this->createIndex(parentTreeItem->GetIndex(), 0, parentTreeItem); } // add node if(m_PlaceNewNodesOnTop) { // emit beginInsertRows event beginInsertRows(index, 0, 0); parentTreeItem->InsertChild(new TreeItem( const_cast(node)), 0); } else { beginInsertRows(index, parentTreeItem->GetChildCount() , parentTreeItem->GetChildCount()); new TreeItem(const_cast(node), parentTreeItem); } // emit endInsertRows event endInsertRows(); this->AdjustLayerProperty(); } void QmitkDataStorageTreeModel::AddNode( const mitk::DataNode* node ) { if(node == 0 || m_DataStorage.IsNull() || !m_DataStorage->Exists(node) || m_Root->Find(node) != 0) return; - bool isHelperObject (false); - NodeTagMapType::iterator searchIter = m_HelperObjectObserverTags.find( const_cast(node) ); - if (node->GetBoolProperty("helper object", isHelperObject) && searchIter == m_HelperObjectObserverTags.end()) { - itk::SimpleMemberCommand::Pointer command = itk::SimpleMemberCommand::New(); - command->SetCallbackFunction(this, &QmitkDataStorageTreeModel::UpdateNodeVisibility); - m_HelperObjectObserverTags.insert( std::pair( const_cast(node), node->GetProperty("helper object")->AddObserver( itk::ModifiedEvent(), command ) ) ); - } - - if (m_Predicate->CheckNode(node)) this->AddNodeInternal(node); } void QmitkDataStorageTreeModel::SetPlaceNewNodesOnTop(bool _PlaceNewNodesOnTop) { m_PlaceNewNodesOnTop = _PlaceNewNodesOnTop; } void QmitkDataStorageTreeModel::RemoveNodeInternal( const mitk::DataNode* node ) { if(!m_Root) return; TreeItem* treeItem = m_Root->Find(node); if(!treeItem) return; // return because there is no treeitem containing this node TreeItem* parentTreeItem = treeItem->GetParent(); QModelIndex parentIndex = this->IndexFromTreeItem(parentTreeItem); // emit beginRemoveRows event (QModelIndex is empty because we dont have a tree model) this->beginRemoveRows(parentIndex, treeItem->GetIndex(), treeItem->GetIndex()); // remove node std::vector children = treeItem->GetChildren(); delete treeItem; // emit endRemoveRows event endRemoveRows(); // move all children of deleted node into its parent for ( std::vector::iterator it = children.begin() ; it != children.end(); it++) { // emit beginInsertRows event beginInsertRows(parentIndex, parentTreeItem->GetChildCount(), parentTreeItem->GetChildCount()); // add nodes again parentTreeItem->AddChild(*it); // emit endInsertRows event endInsertRows(); } this->AdjustLayerProperty(); } void QmitkDataStorageTreeModel::RemoveNode( const mitk::DataNode* node ) { if (node == 0) return; - //Removing Observer - bool isHelperObject (false); - NodeTagMapType::iterator searchIter = m_HelperObjectObserverTags.find( const_cast(node) ); - if (node->GetBoolProperty("helper object", isHelperObject) && searchIter != m_HelperObjectObserverTags.end()) { - (*searchIter).first->GetProperty("helper object")->RemoveObserver( (*searchIter).second ); - m_HelperObjectObserverTags.erase(const_cast(node)); - } - this->RemoveNodeInternal(node); } void QmitkDataStorageTreeModel::SetNodeModified( const mitk::DataNode* node ) { TreeItem* treeItem = m_Root->Find(node); - if(!treeItem) - { - // check if the node still fits the predicates - if( m_Predicate->CheckNode( node ) ) - { - this->UpdateNodeVisibility(); - } - } - else - { + if(treeItem) { TreeItem* parentTreeItem = treeItem->GetParent(); // as the root node should not be removed one should always have a parent item if(!parentTreeItem) return; QModelIndex index = this->createIndex(treeItem->GetIndex(), 0, treeItem); // now emit the dataChanged signal emit dataChanged(index, index); } } mitk::DataNode* QmitkDataStorageTreeModel::GetParentNode( const mitk::DataNode* node ) const { mitk::DataNode* dataNode = 0; mitk::DataStorage::SetOfObjects::ConstPointer _Sources = m_DataStorage->GetSources(node); if(_Sources->Size() > 0) dataNode = _Sources->front(); return dataNode; } bool QmitkDataStorageTreeModel::setData( const QModelIndex &index, const QVariant &value, int role ) { mitk::DataNode* dataNode = this->TreeItemFromIndex(index)->GetDataNode(); if(!dataNode) return false; if(role == Qt::EditRole && !value.toString().isEmpty()) { dataNode->SetStringProperty("name", value.toString().toStdString().c_str()); mitk::PlanarFigure* planarFigure = dynamic_cast(dataNode->GetData()); if (planarFigure != NULL) mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } else if(role == Qt::CheckStateRole) { // Please note: value.toInt() returns 2, independentely from the actual checkstate of the index element. // Therefore the checkstate is being estimated again here. QVariant qcheckstate = index.data(Qt::CheckStateRole); int checkstate = qcheckstate.toInt(); bool isVisible = bool(checkstate); dataNode->SetVisibility(!isVisible); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } // inform listeners about changes emit dataChanged(index, index); return true; } bool QmitkDataStorageTreeModel::setHeaderData( int /*section*/, Qt::Orientation /*orientation*/, const QVariant& /* value */, int /*role = Qt::EditRole*/ ) { return false; } void QmitkDataStorageTreeModel::AdjustLayerProperty() { /// transform the tree into an array and set the layer property descending std::vector vec; this->TreeToVector(m_Root, vec); int i = vec.size()-1; for(std::vector::const_iterator it = vec.begin(); it != vec.end(); ++it) { mitk::DataNode::Pointer dataNode = (*it)->GetDataNode(); bool fixedLayer = false; if (!(dataNode->GetBoolProperty("fixedLayer", fixedLayer) && fixedLayer)) dataNode->SetIntProperty("layer", i); --i; } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataStorageTreeModel::TreeToVector(TreeItem* parent, std::vector& vec) const { TreeItem* current; for(int i = 0; iGetChildCount(); ++i) { current = parent->GetChild(i); this->TreeToVector(current, vec); vec.push_back(current); } } QModelIndex QmitkDataStorageTreeModel::IndexFromTreeItem( TreeItem* item ) const { if(item == m_Root) return QModelIndex(); else return this->createIndex(item->GetIndex(), 0, item); } QList QmitkDataStorageTreeModel::GetNodeSet() const { QList res; if(m_Root) this->TreeToNodeSet(m_Root, res); return res; } void QmitkDataStorageTreeModel::TreeToNodeSet( TreeItem* parent, QList& vec ) const { TreeItem* current; for(int i = 0; iGetChildCount(); ++i) { current = parent->GetChild(i); vec.push_back(current->GetDataNode()); this->TreeToNodeSet(current, vec); } } QModelIndex QmitkDataStorageTreeModel::GetIndex( const mitk::DataNode* node ) const { if(m_Root) { TreeItem* item = m_Root->Find(node); if(item) return this->IndexFromTreeItem(item); } return QModelIndex(); } QmitkDataStorageTreeModel::TreeItem::TreeItem( mitk::DataNode* _DataNode, TreeItem* _Parent ) : m_Parent(_Parent) , m_DataNode(_DataNode) { if(m_Parent) m_Parent->AddChild(this); } QmitkDataStorageTreeModel::TreeItem::~TreeItem() { if(m_Parent) m_Parent->RemoveChild(this); } void QmitkDataStorageTreeModel::TreeItem::Delete() { while(m_Children.size() > 0) delete m_Children.back(); delete this; } QmitkDataStorageTreeModel::TreeItem* QmitkDataStorageTreeModel::TreeItem::Find( const mitk::DataNode* _DataNode ) const { QmitkDataStorageTreeModel::TreeItem* item = 0; if(_DataNode) { if(m_DataNode == _DataNode) item = const_cast(this); else { for(std::vector::const_iterator it = m_Children.begin(); it != m_Children.end(); ++it) { if(item) break; item = (*it)->Find(_DataNode); } } } return item; } int QmitkDataStorageTreeModel::TreeItem::IndexOfChild( const TreeItem* item ) const { std::vector::const_iterator it = std::find(m_Children.begin(), m_Children.end(), item); return it != m_Children.end() ? std::distance(m_Children.begin(), it): -1; } QmitkDataStorageTreeModel::TreeItem* QmitkDataStorageTreeModel::TreeItem::GetChild( int index ) const { return (m_Children.size() > 0 && index >= 0 && index < (int)m_Children.size())? m_Children.at(index): 0; } void QmitkDataStorageTreeModel::TreeItem::AddChild( TreeItem* item ) { this->InsertChild(item); } void QmitkDataStorageTreeModel::TreeItem::RemoveChild( TreeItem* item ) { std::vector::iterator it = std::find(m_Children.begin(), m_Children.end(), item); if(it != m_Children.end()) { m_Children.erase(it); item->SetParent(0); } } int QmitkDataStorageTreeModel::TreeItem::GetChildCount() const { return m_Children.size(); } int QmitkDataStorageTreeModel::TreeItem::GetIndex() const { if (m_Parent) return m_Parent->IndexOfChild(this); return 0; } QmitkDataStorageTreeModel::TreeItem* QmitkDataStorageTreeModel::TreeItem::GetParent() const { return m_Parent; } mitk::DataNode::Pointer QmitkDataStorageTreeModel::TreeItem::GetDataNode() const { return m_DataNode; } void QmitkDataStorageTreeModel::TreeItem::InsertChild( TreeItem* item, int index ) { std::vector::iterator it = std::find(m_Children.begin(), m_Children.end(), item); if(it == m_Children.end()) { if(m_Children.size() > 0 && index >= 0 && index < (int)m_Children.size()) { it = m_Children.begin(); std::advance(it, index); m_Children.insert(it, item); } else m_Children.push_back(item); // add parent if necessary if(item->GetParent() != this) item->SetParent(this); } } std::vector QmitkDataStorageTreeModel::TreeItem::GetChildren() const { return m_Children; } void QmitkDataStorageTreeModel::TreeItem::SetParent( TreeItem* _Parent ) { m_Parent = _Parent; if(m_Parent) m_Parent->AddChild(this); } -void QmitkDataStorageTreeModel::SetShowHelperObjects(bool _ShowHelperObjects) -{ - m_ShowHelperObjects = _ShowHelperObjects; - this->UpdateNodeVisibility(); -} - -void QmitkDataStorageTreeModel::SetShowNodesContainingNoData(bool _ShowNodesContainingNoData) -{ - m_ShowNodesContainingNoData = _ShowNodesContainingNoData; - this->UpdateNodeVisibility(); -} - -void QmitkDataStorageTreeModel::UpdateNodeVisibility() -{ - mitk::NodePredicateData::Pointer dataIsNull = mitk::NodePredicateData::New(0); - mitk::NodePredicateNot::Pointer dataIsNotNull = mitk::NodePredicateNot::New(dataIsNull);// Show only nodes that really contain dat - - if (m_ShowHelperObjects) - { - if (m_ShowNodesContainingNoData) - { - // Show every node - m_Predicate = mitk::NodePredicateOr::New(dataIsNull, dataIsNotNull); - } - else - { - // Show helper objects but not nodes containing no data - m_Predicate = dataIsNotNull; - } - } - else - { - mitk::NodePredicateProperty::Pointer isHelperObject = mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true)); - mitk::NodePredicateNot::Pointer isNotHelperObject = mitk::NodePredicateNot::New(isHelperObject);// Show only nodes that are not helper objects - if (m_ShowNodesContainingNoData) - { - // Don't show helper objects but nodes containing no data - m_Predicate = isNotHelperObject; - } - else - { - // Don't show helper objects and nodes containing no data - m_Predicate = mitk::NodePredicateAnd::New(isNotHelperObject, dataIsNotNull); - } - } - this->Update(); -} - void QmitkDataStorageTreeModel::Update() { - if (m_DataStorage.IsNotNull()) - { - this->reset(); - - mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet = m_DataStorage->GetSubset(m_Predicate); - - for(mitk::DataStorage::SetOfObjects::const_iterator it=_NodeSet->begin(); it!=_NodeSet->end(); it++) + if (m_DataStorage.IsNotNull()) { - // save node - this->AddNodeInternal(*it); - } + this->reset(); - mitk::DataStorage::SetOfObjects::ConstPointer _NotNodeSet = m_DataStorage->GetSubset(mitk::NodePredicateNot::New(m_Predicate)); + mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet = m_DataStorage->GetAll(); - for(mitk::DataStorage::SetOfObjects::const_iterator it=_NotNodeSet->begin(); it!=_NotNodeSet->end(); it++) - { - // remove node - this->RemoveNodeInternal(*it); + for (mitk::DataStorage::SetOfObjects::const_iterator it = _NodeSet->begin(); it != _NodeSet->end(); it++) + { + // save node + this->AddNodeInternal(*it); + } } - - } } - diff --git a/Modules/QtWidgets/QmitkDataStorageTreeModel.h b/Modules/QtWidgets/QmitkDataStorageTreeModel.h index 4badf8601c..0d2473a754 100644 --- a/Modules/QtWidgets/QmitkDataStorageTreeModel.h +++ b/Modules/QtWidgets/QmitkDataStorageTreeModel.h @@ -1,293 +1,255 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QMITKDATASTORAGETREEMODEL_H_ #define QMITKDATASTORAGETREEMODEL_H_ #include #include #include #include #include #include "QmitkEnums.h" #include "QmitkCustomVariants.h" #include #include #include /// \ingroup QmitkModule class QMITK_EXPORT QmitkDataStorageTreeModel : public QAbstractItemModel { //# CONSTANTS,TYPEDEFS public: static const std::string COLUMN_NAME; static const std::string COLUMN_TYPE; static const std::string COLUMN_VISIBILITY; //# CTORS,DTOR public: QmitkDataStorageTreeModel(mitk::DataStorage* _DataStorage , bool _PlaceNewNodesOnTop=false - , bool _ShowHelperObjects=false - , bool _ShowNodesContainingNoData=false , QObject* parent = 0); ~QmitkDataStorageTreeModel(); //# GETTER public: - typedef std::map NodeTagMapType; /// /// Get node at a specific model index. /// This function is used to get a node from a QModelIndex /// mitk::DataNode::Pointer GetNode(const QModelIndex &index) const; /// /// Returns a copy of the node-vector that is shown by this model /// virtual QList GetNodeSet() const; /// /// Get the DataStorage. /// const mitk::DataStorage::Pointer GetDataStorage() const; /// /// Get the top placement flag /// bool GetPlaceNewNodesOnTopFlag() { return m_PlaceNewNodesOnTop; } - /// - /// Get the helper object visibility flag - /// - bool GetShowHelperObjectsFlag() - { - return m_ShowHelperObjects; - } - - /// - /// Get the visibility flag for showing nodes that contain no data - /// - bool GetShowNodesContainingNoDataFlag() - { - return m_ShowNodesContainingNoData; - } - /// /// Set the top placement flag /// void SetPlaceNewNodesOnTop(bool _PlaceNewNodesOnTop); //# (Re-)implemented from QAbstractItemModel //# Read model Qt::ItemFlags flags(const QModelIndex& index) const; QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; int rowCount ( const QModelIndex & parent = QModelIndex() ) const; int columnCount ( const QModelIndex & parent = QModelIndex() ) const; //# hierarchical model /// /// called whenever the model or the view needs to create a QModelIndex for a particular /// child item (or a top-level item if parent is an invalid QModelIndex) /// QModelIndex index ( int row, int column, const QModelIndex & parent = QModelIndex() ) const; QModelIndex parent ( const QModelIndex & index ) const; //# editable model bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole); bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); Qt::DropActions supportedDropActions() const; Qt::DropActions supportedDragActions() const; QStringList mimeTypes() const; QMimeData * mimeData(const QModelIndexList & indexes) const; //# End of QAbstractItemModel //# SETTER public: /// /// Sets the DataStorage. The whole model will be resetted. /// void SetDataStorage(mitk::DataStorage* _DataStorage); /// /// Notify that the DataStorage was deleted. The whole model will be resetted. /// void SetDataStorageDeleted(const itk::Object* _DataStorage); /// /// Adds a node to this model. /// If a predicate is set (not null) the node will be checked against it.The node has to have a data object (no one wants to see empty nodes). /// virtual void AddNode(const mitk::DataNode* node); /// /// Removes a node from this model. Also removes any event listener from the node. /// virtual void RemoveNode(const mitk::DataNode* node); /// /// Sets a node to modfified. Called by the DataStorage /// virtual void SetNodeModified(const mitk::DataNode* node); /// /// \return an index for the given datatreenode in the tree. If the node is not found /// QModelIndex GetIndex(const mitk::DataNode*) const; - /// - /// Show or hide helper objects - /// - void SetShowHelperObjects(bool _ShowHelperObjects); - - /// - /// Show or hide objects that contain no data - /// - void SetShowNodesContainingNoData(bool _ShowNodesContainingNoData); - - /// - /// Update the visibility of data nodes according to the preference settings - /// - void UpdateNodeVisibility(); - //# MISC protected: /// /// Helper class to represent a tree structure of DataNodes /// class TreeItem { public: /// /// Constructs a new TreeItem with the given DataNode (must not be 0) /// TreeItem(mitk::DataNode* _DataNode, TreeItem* _Parent=0); /// /// Removes itself as child from its parent-> Does not delete its children /// \sa Delete() /// virtual ~TreeItem(); /// /// Find the index of an item /// int IndexOfChild(const TreeItem* item) const; /// /// \return The child at pos index or 0 if it not exists /// TreeItem* GetChild(int index) const; /// /// Find the TreeItem containing a special tree node (recursive tree function) /// TreeItem* Find( const mitk::DataNode* _DataNode) const; /// /// Get the amount of children /// int GetChildCount() const; /// /// \return the index of this node in its parent list /// int GetIndex() const; /// /// \return the parent of this tree item /// TreeItem* GetParent() const; /// /// Return the DataNode associated with this node /// mitk::DataNode::Pointer GetDataNode() const; /// /// Get all children as vector /// std::vector GetChildren() const; /// /// add another item as a child of this (only if not already in that list) /// void AddChild( TreeItem* item); /// /// remove another item as child from this /// void RemoveChild( TreeItem* item); /// /// inserts a child at the given position. if pos is not in range /// the element is added at the end /// void InsertChild( TreeItem* item, int index=-1 ); /// Sets the parent on the treeitem void SetParent(TreeItem* _Parent); /// /// Deletes the whole tree branch /// void Delete(); protected: TreeItem* m_Parent; std::vector m_Children; mitk::DataNode::Pointer m_DataNode; }; /// /// Adjusts the LayerProperty according to the nodes position /// void AdjustLayerProperty(); /// /// invoked after m_DataStorage or m_Predicate changed /// TreeItem* TreeItemFromIndex(const QModelIndex &index) const; /// /// Gives a ModelIndex for the Tree Item /// QModelIndex IndexFromTreeItem(TreeItem*) const; /// /// Returns the first element in the nodes sources list (if available) or 0 /// mitk::DataNode* GetParentNode(const mitk::DataNode* node) const; /// /// Adds all Childs in parent to vec. Before a child is added the function is called recursively /// void TreeToVector(TreeItem* parent, std::vector& vec) const; /// /// Adds all Childs in parent to vec. Before a child is added the function is called recursively /// void TreeToNodeSet(TreeItem* parent, QList &vec) const; /// - /// Update Tree Model according to predicates + /// Update Tree Model /// void Update(); //# ATTRIBUTES protected: mitk::WeakPointer m_DataStorage; mitk::NodePredicateBase::Pointer m_Predicate; bool m_PlaceNewNodesOnTop; - bool m_ShowHelperObjects; - bool m_ShowNodesContainingNoData; TreeItem* m_Root; - NodeTagMapType m_HelperObjectObserverTags; - private: void AddNodeInternal(const mitk::DataNode*); void RemoveNodeInternal(const mitk::DataNode*); /// /// Checks if dicom properties patient name, study names and series name exists /// bool DicomPropertiesExists(const mitk::DataNode&) const; }; #endif /* QMITKDATASTORAGETREEMODEL_H_ */ diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp index c36edc20f6..fbac6fa1e7 100644 --- a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp +++ b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp @@ -1,1077 +1,1081 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkDataManagerView.h" #include //# Own Includes //## mitk #include "mitkDataStorageEditorInput.h" #include "mitkIDataStorageReference.h" #include "mitkNodePredicateDataType.h" #include "mitkCoreObjectFactory.h" #include "mitkDataNodeFactory.h" #include "mitkColorProperty.h" #include "mitkCommon.h" #include "mitkNodePredicateData.h" #include "mitkNodePredicateNot.h" #include "mitkNodePredicateProperty.h" #include "mitkEnumerationProperty.h" #include "mitkLookupTableProperty.h" #include "mitkProperties.h" #include #include #include #include #include //## Qmitk #include #include #include #include #include #include #include "src/internal/QmitkNodeTableViewKeyFilter.h" #include "src/internal/QmitkInfoDialog.h" #include "src/internal/QmitkDataManagerItemDelegate.h" //## Berry #include #include #include #include #include #include //# Toolkit Includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mitkDataNodeObject.h" #include "mitkIContextMenuAction.h" #include "berryIExtensionPointService.h" #include "mitkRenderingModeProperty.h" const std::string QmitkDataManagerView::VIEW_ID = "org.mitk.views.datamanager"; QmitkDataManagerView::QmitkDataManagerView() : m_GlobalReinitOnNodeDelete(true), m_ItemDelegate(NULL) { } QmitkDataManagerView::~QmitkDataManagerView() { //Remove all registered actions from each descriptor for (std::vector< std::pair< QmitkNodeDescriptor*, QAction* > >::iterator it = m_DescriptorActionList.begin();it != m_DescriptorActionList.end(); it++) { // first== the NodeDescriptor; second== the registered QAction (it->first)->RemoveAction(it->second); } } void QmitkDataManagerView::CreateQtPartControl(QWidget* parent) { m_CurrentRowCount = 0; m_Parent = parent; //# Preferences berry::IPreferencesService::Pointer prefService = berry::Platform::GetServiceRegistry() .GetServiceById(berry::IPreferencesService::ID); berry::IBerryPreferences::Pointer prefs = (prefService->GetSystemPreferences()->Node(VIEW_ID)) .Cast(); assert( prefs ); prefs->OnChanged.AddListener( berry::MessageDelegate1( this , &QmitkDataManagerView::OnPreferencesChanged ) ); //# GUI m_NodeTreeModel = new QmitkDataStorageTreeModel(this->GetDataStorage()); m_NodeTreeModel->setParent( parent ); m_NodeTreeModel->SetPlaceNewNodesOnTop( prefs->GetBool("Place new nodes on top", true) ); + /* m_NodeTreeModel->SetShowHelperObjects( prefs->GetBool("Show helper objects", false) ); m_NodeTreeModel->SetShowNodesContainingNoData( prefs->GetBool("Show nodes containing no data", false) ); + */ m_SurfaceDecimation = prefs->GetBool("Use surface decimation", false); //# Tree View (experimental) m_NodeTreeView = new QTreeView; m_NodeTreeView->setHeaderHidden(true); m_NodeTreeView->setSelectionMode( QAbstractItemView::ExtendedSelection ); m_NodeTreeView->setSelectionBehavior( QAbstractItemView::SelectRows ); m_NodeTreeView->setAlternatingRowColors(true); m_NodeTreeView->setDragEnabled(true); m_NodeTreeView->setDropIndicatorShown(true); m_NodeTreeView->setAcceptDrops(true); m_NodeTreeView->setContextMenuPolicy(Qt::CustomContextMenu); m_NodeTreeView->setModel(m_NodeTreeModel); m_NodeTreeView->setTextElideMode(Qt::ElideMiddle); m_NodeTreeView->installEventFilter(new QmitkNodeTableViewKeyFilter(this)); m_ItemDelegate = new QmitkDataManagerItemDelegate(m_NodeTreeView); m_NodeTreeView->setItemDelegate(m_ItemDelegate); QObject::connect( m_NodeTreeView, SIGNAL(customContextMenuRequested(const QPoint&)) , this, SLOT(NodeTableViewContextMenuRequested(const QPoint&)) ); QObject::connect( m_NodeTreeModel, SIGNAL(rowsInserted (const QModelIndex&, int, int)) , this, SLOT(NodeTreeViewRowsInserted ( const QModelIndex&, int, int )) ); QObject::connect( m_NodeTreeModel, SIGNAL(rowsRemoved (const QModelIndex&, int, int)) , this, SLOT(NodeTreeViewRowsRemoved( const QModelIndex&, int, int )) ); QObject::connect( m_NodeTreeView->selectionModel() , SIGNAL( selectionChanged ( const QItemSelection &, const QItemSelection & ) ) , this , SLOT( NodeSelectionChanged ( const QItemSelection &, const QItemSelection & ) ) ); //# m_NodeMenu m_NodeMenu = new QMenu(m_NodeTreeView); // # Actions berry::IEditorRegistry* editorRegistry = berry::PlatformUI::GetWorkbench()->GetEditorRegistry(); std::list editors = editorRegistry->GetEditors("*.mitk"); if (editors.size() > 1) { m_ShowInMapper = new QSignalMapper(this); foreach(berry::IEditorDescriptor::Pointer descriptor, editors) { QAction* action = new QAction(QString::fromStdString(descriptor->GetLabel()), this); m_ShowInActions << action; m_ShowInMapper->connect(action, SIGNAL(triggered()), m_ShowInMapper, SLOT(map())); m_ShowInMapper->setMapping(action, QString::fromStdString(descriptor->GetId())); } connect(m_ShowInMapper, SIGNAL(mapped(QString)), this, SLOT(ShowIn(QString))); } QmitkNodeDescriptor* unknownDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetUnknownDataNodeDescriptor(); QmitkNodeDescriptor* imageDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("Image"); QmitkNodeDescriptor* surfaceDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("Surface"); QAction* globalReinitAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Refresh_48.png"), "Global Reinit", this); QObject::connect( globalReinitAction, SIGNAL( triggered(bool) ) , this, SLOT( GlobalReinit(bool) ) ); unknownDataNodeDescriptor->AddAction(globalReinitAction); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor, globalReinitAction)); QAction* saveAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Save_48.png"), "Save...", this); QObject::connect( saveAction, SIGNAL( triggered(bool) ) , this, SLOT( SaveSelectedNodes(bool) ) ); unknownDataNodeDescriptor->AddAction(saveAction); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,saveAction)); QAction* removeAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Remove_48.png"), "Remove", this); QObject::connect( removeAction, SIGNAL( triggered(bool) ) , this, SLOT( RemoveSelectedNodes(bool) ) ); unknownDataNodeDescriptor->AddAction(removeAction); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,removeAction)); QAction* reinitAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Refresh_48.png"), "Reinit", this); QObject::connect( reinitAction, SIGNAL( triggered(bool) ) , this, SLOT( ReinitSelectedNodes(bool) ) ); unknownDataNodeDescriptor->AddAction(reinitAction); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,reinitAction)); // find contextMenuAction extension points and add them to the node descriptor berry::IExtensionPointService::Pointer extensionPointService = berry::Platform::GetExtensionPointService(); berry::IConfigurationElement::vector cmActions( extensionPointService->GetConfigurationElementsFor("org.mitk.gui.qt.datamanager.contextMenuActions") ); berry::IConfigurationElement::vector::iterator cmActionsIt; std::string cmNodeDescriptorName; std::string cmLabel; std::string cmIcon; std::string cmClass; QmitkNodeDescriptor* tmpDescriptor; QAction* contextMenuAction; QVariant cmActionDataIt; m_ConfElements.clear(); int i=1; for (cmActionsIt = cmActions.begin() ; cmActionsIt != cmActions.end() ; ++cmActionsIt) { cmIcon.erase(); if((*cmActionsIt)->GetAttribute("nodeDescriptorName", cmNodeDescriptorName) && (*cmActionsIt)->GetAttribute("label", cmLabel) && (*cmActionsIt)->GetAttribute("class", cmClass)) { (*cmActionsIt)->GetAttribute("icon", cmIcon); // create context menu entry here tmpDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(QString::fromStdString(cmNodeDescriptorName)); if(!tmpDescriptor) { MITK_WARN << "cannot add action \"" << cmLabel << "\" because descriptor " << cmNodeDescriptorName << " does not exist"; continue; } contextMenuAction = new QAction( QString::fromStdString(cmLabel), parent); tmpDescriptor->AddAction(contextMenuAction); m_DescriptorActionList.push_back(std::pair(tmpDescriptor,contextMenuAction)); m_ConfElements[contextMenuAction] = *cmActionsIt; cmActionDataIt.setValue(i); contextMenuAction->setData( cmActionDataIt ); connect( contextMenuAction, SIGNAL( triggered(bool) ) , this, SLOT( ContextMenuActionTriggered(bool) ) ); ++i; } } m_OpacitySlider = new QSlider; m_OpacitySlider->setMinimum(0); m_OpacitySlider->setMaximum(100); m_OpacitySlider->setOrientation(Qt::Horizontal); QObject::connect( m_OpacitySlider, SIGNAL( valueChanged(int) ) , this, SLOT( OpacityChanged(int) ) ); QLabel* _OpacityLabel = new QLabel("Opacity: "); QHBoxLayout* _OpacityWidgetLayout = new QHBoxLayout; _OpacityWidgetLayout->setContentsMargins(4,4,4,4); _OpacityWidgetLayout->addWidget(_OpacityLabel); _OpacityWidgetLayout->addWidget(m_OpacitySlider); QWidget* _OpacityWidget = new QWidget; _OpacityWidget->setLayout(_OpacityWidgetLayout); QWidgetAction* opacityAction = new QWidgetAction(this); opacityAction ->setDefaultWidget(_OpacityWidget); QObject::connect( opacityAction , SIGNAL( changed() ) , this, SLOT( OpacityActionChanged() ) ); unknownDataNodeDescriptor->AddAction(opacityAction , false); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,opacityAction)); m_ColorButton = new QPushButton; m_ColorButton->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Minimum); //m_ColorButton->setText("Change color"); QObject::connect( m_ColorButton, SIGNAL( clicked() ) , this, SLOT( ColorChanged() ) ); QLabel* _ColorLabel = new QLabel("Color: "); _ColorLabel->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); QHBoxLayout* _ColorWidgetLayout = new QHBoxLayout; _ColorWidgetLayout->setContentsMargins(4,4,4,4); _ColorWidgetLayout->addWidget(_ColorLabel); _ColorWidgetLayout->addWidget(m_ColorButton); QWidget* _ColorWidget = new QWidget; _ColorWidget->setLayout(_ColorWidgetLayout); QWidgetAction* colorAction = new QWidgetAction(this); colorAction->setDefaultWidget(_ColorWidget); QObject::connect( colorAction, SIGNAL( changed() ) , this, SLOT( ColorActionChanged() ) ); unknownDataNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,colorAction)); m_ComponentSlider = new QmitkNumberPropertySlider; m_ComponentSlider->setOrientation(Qt::Horizontal); //QObject::connect( m_OpacitySlider, SIGNAL( valueChanged(int) ) // , this, SLOT( OpacityChanged(int) ) ); QLabel* _ComponentLabel = new QLabel("Component: "); QHBoxLayout* _ComponentWidgetLayout = new QHBoxLayout; _ComponentWidgetLayout->setContentsMargins(4,4,4,4); _ComponentWidgetLayout->addWidget(_ComponentLabel); _ComponentWidgetLayout->addWidget(m_ComponentSlider); QLabel* _ComponentValueLabel = new QLabel(); _ComponentWidgetLayout->addWidget(_ComponentValueLabel); connect(m_ComponentSlider, SIGNAL(valueChanged(int)), _ComponentValueLabel, SLOT(setNum(int))); QWidget* _ComponentWidget = new QWidget; _ComponentWidget->setLayout(_ComponentWidgetLayout); QWidgetAction* componentAction = new QWidgetAction(this); componentAction->setDefaultWidget(_ComponentWidget); QObject::connect( componentAction , SIGNAL( changed() ) , this, SLOT( ComponentActionChanged() ) ); imageDataNodeDescriptor->AddAction(componentAction, false); m_DescriptorActionList.push_back(std::pair(imageDataNodeDescriptor,componentAction)); m_TextureInterpolation = new QAction("Texture Interpolation", this); m_TextureInterpolation->setCheckable ( true ); QObject::connect( m_TextureInterpolation, SIGNAL( changed() ) , this, SLOT( TextureInterpolationChanged() ) ); QObject::connect( m_TextureInterpolation, SIGNAL( toggled(bool) ) , this, SLOT( TextureInterpolationToggled(bool) ) ); imageDataNodeDescriptor->AddAction(m_TextureInterpolation, false); m_DescriptorActionList.push_back(std::pair(imageDataNodeDescriptor,m_TextureInterpolation)); m_ColormapAction = new QAction("Colormap", this); m_ColormapAction->setMenu(new QMenu); QObject::connect( m_ColormapAction->menu(), SIGNAL( aboutToShow() ) , this, SLOT( ColormapMenuAboutToShow() ) ); imageDataNodeDescriptor->AddAction(m_ColormapAction, false); m_DescriptorActionList.push_back(std::pair(imageDataNodeDescriptor, m_ColormapAction)); m_SurfaceRepresentation = new QAction("Surface Representation", this); m_SurfaceRepresentation->setMenu(new QMenu); QObject::connect( m_SurfaceRepresentation->menu(), SIGNAL( aboutToShow() ) , this, SLOT( SurfaceRepresentationMenuAboutToShow() ) ); surfaceDataNodeDescriptor->AddAction(m_SurfaceRepresentation, false); m_DescriptorActionList.push_back(std::pair(surfaceDataNodeDescriptor, m_SurfaceRepresentation)); QAction* showOnlySelectedNodes = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/ShowSelectedNode_48.png") , "Show only selected nodes", this); QObject::connect( showOnlySelectedNodes, SIGNAL( triggered(bool) ) , this, SLOT( ShowOnlySelectedNodes(bool) ) ); unknownDataNodeDescriptor->AddAction(showOnlySelectedNodes); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor, showOnlySelectedNodes)); QAction* toggleSelectedVisibility = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/InvertShowSelectedNode_48.png") , "Toggle visibility", this); QObject::connect( toggleSelectedVisibility, SIGNAL( triggered(bool) ) , this, SLOT( ToggleVisibilityOfSelectedNodes(bool) ) ); unknownDataNodeDescriptor->AddAction(toggleSelectedVisibility); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,toggleSelectedVisibility)); QAction* actionShowInfoDialog = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/ShowDataInfo_48.png") , "Details...", this); QObject::connect( actionShowInfoDialog, SIGNAL( triggered(bool) ) , this, SLOT( ShowInfoDialogForSelectedNodes(bool) ) ); unknownDataNodeDescriptor->AddAction(actionShowInfoDialog); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,actionShowInfoDialog)); //obsolete... //QAction* otsuFilterAction = new QAction("Apply Otsu Filter", this); //QObject::connect( otsuFilterAction, SIGNAL( triggered(bool) ) // , this, SLOT( OtsuFilter(bool) ) ); // //Otsu filter does not work properly, remove it temporarily // imageDataNodeDescriptor->AddAction(otsuFilterAction); // m_DescriptorActionList.push_back(std::pair(imageDataNodeDescriptor,otsuFilterAction)); QGridLayout* _DndFrameWidgetLayout = new QGridLayout; _DndFrameWidgetLayout->addWidget(m_NodeTreeView, 0, 0); _DndFrameWidgetLayout->setContentsMargins(0,0,0,0); m_DndFrameWidget = new QmitkDnDFrameWidget(m_Parent); m_DndFrameWidget->setLayout(_DndFrameWidgetLayout); QVBoxLayout* layout = new QVBoxLayout(parent); layout->addWidget(m_DndFrameWidget); layout->setContentsMargins(0,0,0,0); m_Parent->setLayout(layout); } void QmitkDataManagerView::SetFocus() { } void QmitkDataManagerView::ContextMenuActionTriggered( bool ) { QAction* action = qobject_cast ( sender() ); std::map::iterator it = m_ConfElements.find( action ); if( it == m_ConfElements.end() ) { MITK_WARN << "associated conf element for action " << action->text().toStdString() << " not found"; return; } berry::IConfigurationElement::Pointer confElem = it->second; mitk::IContextMenuAction* contextMenuAction = confElem->CreateExecutableExtension("class"); std::string className; std::string smoothed; confElem->GetAttribute("class", className); confElem->GetAttribute("smoothed", smoothed); if(className == "QmitkCreatePolygonModelAction") { contextMenuAction->SetDataStorage(this->GetDataStorage()); if(smoothed == "false") { contextMenuAction->SetSmoothed(false); } else { contextMenuAction->SetSmoothed(true); } contextMenuAction->SetDecimated(m_SurfaceDecimation); } else if(className == "QmitkStatisticsAction") { contextMenuAction->SetFunctionality(this); } else if(className == "QmitkCreateSimulationAction") { contextMenuAction->SetDataStorage(this->GetDataStorage()); } contextMenuAction->Run( this->GetCurrentSelection() ); // run the action } void QmitkDataManagerView::OnPreferencesChanged(const berry::IBerryPreferences* prefs) { if( m_NodeTreeModel->GetPlaceNewNodesOnTopFlag() != prefs->GetBool("Place new nodes on top", true) ) m_NodeTreeModel->SetPlaceNewNodesOnTop( !m_NodeTreeModel->GetPlaceNewNodesOnTopFlag() ); + /* if( m_NodeTreeModel->GetShowHelperObjectsFlag()!= prefs->GetBool("Show helper objects", false) ) m_NodeTreeModel->SetShowHelperObjects( !m_NodeTreeModel->GetShowHelperObjectsFlag() ); if( m_NodeTreeModel->GetShowNodesContainingNoDataFlag()!= prefs->GetBool("Show nodes containing no data", false) ) m_NodeTreeModel->SetShowNodesContainingNoData( !m_NodeTreeModel->GetShowNodesContainingNoDataFlag() ); + */ m_GlobalReinitOnNodeDelete = prefs->GetBool("Call global reinit if node is deleted", true); m_NodeTreeView->expandAll(); m_SurfaceDecimation = prefs->GetBool("Use surface decimation", false); this->GlobalReinit(); } void QmitkDataManagerView::NodeTableViewContextMenuRequested( const QPoint & pos ) { QModelIndex selected = m_NodeTreeView->indexAt ( pos ); mitk::DataNode::Pointer node = m_NodeTreeModel->GetNode(selected); QList selectedNodes = this->GetCurrentSelection(); if(!selectedNodes.isEmpty()) { m_NodeMenu->clear(); QList actions; if(selectedNodes.size() == 1 ) { actions = QmitkNodeDescriptorManager::GetInstance()->GetActions(node); for(QList::iterator it = actions.begin(); it != actions.end(); ++it) { (*it)->setData(QVariant::fromValue(node.GetPointer())); } } else actions = QmitkNodeDescriptorManager::GetInstance()->GetActions(selectedNodes); if (!m_ShowInActions.isEmpty()) { QMenu* showInMenu = m_NodeMenu->addMenu("Show In"); showInMenu->addActions(m_ShowInActions); } m_NodeMenu->addActions(actions); m_NodeMenu->popup(QCursor::pos()); } } void QmitkDataManagerView::OpacityChanged(int value) { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex()); if(node) { float opacity = static_cast(value)/100.0f; node->SetFloatProperty("opacity", opacity); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkDataManagerView::OpacityActionChanged() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex()); if(node) { float opacity = 0.0; if(node->GetFloatProperty("opacity", opacity)) { m_OpacitySlider->setValue(static_cast(opacity*100)); } } } void QmitkDataManagerView::ComponentActionChanged() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex()); mitk::IntProperty* componentProperty = NULL; int numComponents = 0; if(node) { componentProperty = dynamic_cast(node->GetProperty("Image.Displayed Component")); mitk::Image* img = dynamic_cast(node->GetData()); if (img != NULL) { numComponents = img->GetPixelType().GetNumberOfComponents(); } } if (componentProperty && numComponents > 1) { m_ComponentSlider->SetProperty(componentProperty); m_ComponentSlider->setMinValue(0); m_ComponentSlider->setMaxValue(numComponents-1); } else { m_ComponentSlider->SetProperty(static_cast(NULL)); } } void QmitkDataManagerView::ColorChanged() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex()); if(node) { mitk::Color color; mitk::ColorProperty::Pointer colorProp; node->GetProperty(colorProp,"color"); if(colorProp.IsNull()) return; color = colorProp->GetValue(); QColor initial(color.GetRed()*255,color.GetGreen()*255,color.GetBlue()*255); QColor qcolor = QColorDialog::getColor(initial,0,QString("Change color")); if (!qcolor.isValid()) return; m_ColorButton->setAutoFillBackground(true); node->SetProperty("color",mitk::ColorProperty::New(qcolor.red()/255.0,qcolor.green()/255.0,qcolor.blue()/255.0)); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkDataManagerView::ColorActionChanged() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex()); if(node) { mitk::Color color; mitk::ColorProperty::Pointer colorProp; node->GetProperty(colorProp,"color"); if(colorProp.IsNull()) return; color = colorProp->GetValue(); QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(color[0]*255)); styleSheet.append(","); styleSheet.append(QString::number(color[1]*255)); styleSheet.append(","); styleSheet.append(QString::number(color[2]*255)); styleSheet.append(")"); m_ColorButton->setStyleSheet(styleSheet); } } void QmitkDataManagerView::TextureInterpolationChanged() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex()); if(node) { bool textureInterpolation = false; node->GetBoolProperty("texture interpolation", textureInterpolation); m_TextureInterpolation->setChecked(textureInterpolation); } } void QmitkDataManagerView::TextureInterpolationToggled( bool checked ) { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex()); if(node) { node->SetBoolProperty("texture interpolation", checked); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkDataManagerView::ColormapActionToggled( bool /*checked*/ ) { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex()); if(!node) return; mitk::LookupTableProperty::Pointer lookupTableProperty = dynamic_cast(node->GetProperty("LookupTable")); if (!lookupTableProperty) return; QAction* senderAction = qobject_cast(QObject::sender()); if(!senderAction) return; std::string activatedItem = senderAction->text().toStdString(); mitk::LookupTable::Pointer lookupTable = lookupTableProperty->GetValue(); if (!lookupTable) return; lookupTable->SetType(activatedItem); lookupTableProperty->SetValue(lookupTable); mitk::RenderingModeProperty::Pointer renderingMode = dynamic_cast(node->GetProperty("Image Rendering.Mode")); renderingMode->SetValue(mitk::RenderingModeProperty::LOOKUPTABLE_LEVELWINDOW_COLOR); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataManagerView::ColormapMenuAboutToShow() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex()); if(!node) return; mitk::LookupTableProperty::Pointer lookupTableProperty = dynamic_cast(node->GetProperty("LookupTable")); if (!lookupTableProperty) { mitk::LookupTable::Pointer mitkLut = mitk::LookupTable::New(); lookupTableProperty = mitk::LookupTableProperty::New(); lookupTableProperty->SetLookupTable(mitkLut); node->SetProperty("LookupTable", lookupTableProperty); } mitk::LookupTable::Pointer lookupTable = lookupTableProperty->GetValue(); if (!lookupTable) return; m_ColormapAction->menu()->clear(); QAction* tmp; int i = 0; std::string lutType = lookupTable->typenameList[i]; while (lutType != "END_OF_ARRAY") { tmp = m_ColormapAction->menu()->addAction(QString::fromStdString(lutType)); tmp->setCheckable(true); if (lutType == lookupTable->GetActiveTypeAsString()) { tmp->setChecked(true); } QObject::connect(tmp, SIGNAL(triggered(bool)), this, SLOT(ColormapActionToggled(bool))); lutType = lookupTable->typenameList[++i]; } } void QmitkDataManagerView::SurfaceRepresentationMenuAboutToShow() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex()); if(!node) return; mitk::EnumerationProperty* representationProp = dynamic_cast (node->GetProperty("material.representation")); if(!representationProp) return; // clear menu m_SurfaceRepresentation->menu()->clear(); QAction* tmp; // create menu entries for(mitk::EnumerationProperty::EnumConstIterator it=representationProp->Begin(); it!=representationProp->End() ; it++) { tmp = m_SurfaceRepresentation->menu()->addAction(QString::fromStdString(it->second)); tmp->setCheckable(true); if(it->second == representationProp->GetValueAsString()) { tmp->setChecked(true); } QObject::connect( tmp, SIGNAL( triggered(bool) ) , this, SLOT( SurfaceRepresentationActionToggled(bool) ) ); } } void QmitkDataManagerView::SurfaceRepresentationActionToggled( bool /*checked*/ ) { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_NodeTreeView->selectionModel()->currentIndex()); if(!node) return; mitk::EnumerationProperty* representationProp = dynamic_cast (node->GetProperty("material.representation")); if(!representationProp) return; QAction* senderAction = qobject_cast ( QObject::sender() ); if(!senderAction) return; std::string activatedItem = senderAction->text().toStdString(); if ( activatedItem != representationProp->GetValueAsString() ) { if ( representationProp->IsValidEnumerationValue( activatedItem ) ) { representationProp->SetValue( activatedItem ); representationProp->InvokeEvent( itk::ModifiedEvent() ); representationProp->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } } void QmitkDataManagerView::SaveSelectedNodes( bool ) { QModelIndexList indexesOfSelectedRows = m_NodeTreeView->selectionModel()->selectedRows(); mitk::DataNode* node = 0; unsigned int indexesOfSelectedRowsSize = indexesOfSelectedRows.size(); for (unsigned int i = 0; iGetNode(indexesOfSelectedRows.at(i)); // if node is not defined or if the node contains geometry data do not remove it if ( node != 0 ) { mitk::BaseData::Pointer data = node->GetData(); if (data.IsNotNull()) { QString error; try { QmitkIOUtil::SaveBaseDataWithDialog( data.GetPointer(), node->GetName().c_str(), m_Parent ); } catch(std::exception& e) { error = e.what(); } catch(...) { error = "Unknown error occured"; } if( !error.isEmpty() ) QMessageBox::critical( m_Parent, "Error saving...", error ); } } } } void QmitkDataManagerView::ReinitSelectedNodes( bool ) { mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart(); if (renderWindow == NULL) renderWindow = this->OpenRenderWindowPart(false); QList selectedNodes = this->GetCurrentSelection(); foreach(mitk::DataNode::Pointer node, selectedNodes) { mitk::BaseData::Pointer basedata = node->GetData(); if ( basedata.IsNotNull() && basedata->GetTimeGeometry()->IsValid() ) { renderWindow->GetRenderingManager()->InitializeViews( basedata->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); renderWindow->GetRenderingManager()->RequestUpdateAll(); } } } void QmitkDataManagerView::RemoveSelectedNodes( bool ) { QModelIndexList indexesOfSelectedRows = m_NodeTreeView->selectionModel()->selectedRows(); if(indexesOfSelectedRows.size() < 1) { return; } std::vector selectedNodes; mitk::DataNode* node = 0; QString question = tr("Do you really want to remove "); for (QModelIndexList::iterator it = indexesOfSelectedRows.begin() ; it != indexesOfSelectedRows.end(); it++) { node = m_NodeTreeModel->GetNode(*it); // if node is not defined or if the node contains geometry data do not remove it if ( node != 0 /*& strcmp(node->GetData()->GetNameOfClass(), "PlaneGeometryData") != 0*/ ) { selectedNodes.push_back(node); question.append(QString::fromStdString(node->GetName())); question.append(", "); } } // remove the last two characters = ", " question = question.remove(question.size()-2, 2); question.append(" from data storage?"); QMessageBox::StandardButton answerButton = QMessageBox::question( m_Parent , tr("DataManager") , question , QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); if(answerButton == QMessageBox::Yes) { for (std::vector::iterator it = selectedNodes.begin() ; it != selectedNodes.end(); it++) { node = *it; this->GetDataStorage()->Remove(node); if (m_GlobalReinitOnNodeDelete) this->GlobalReinit(false); } } } void QmitkDataManagerView::MakeAllNodesInvisible( bool ) { QList nodes = m_NodeTreeModel->GetNodeSet(); foreach(mitk::DataNode::Pointer node, nodes) { node->SetVisibility(false); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataManagerView::ShowOnlySelectedNodes( bool ) { QList selectedNodes = this->GetCurrentSelection(); QList allNodes = m_NodeTreeModel->GetNodeSet(); foreach(mitk::DataNode::Pointer node, allNodes) { node->SetVisibility(selectedNodes.contains(node)); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataManagerView::ToggleVisibilityOfSelectedNodes( bool ) { QList selectedNodes = this->GetCurrentSelection(); bool isVisible = false; foreach(mitk::DataNode::Pointer node, selectedNodes) { isVisible = false; node->GetBoolProperty("visible", isVisible); node->SetVisibility(!isVisible); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataManagerView::ShowInfoDialogForSelectedNodes( bool ) { QList selectedNodes = this->GetCurrentSelection(); QmitkInfoDialog _QmitkInfoDialog(selectedNodes, this->m_Parent); _QmitkInfoDialog.exec(); } void QmitkDataManagerView::Load( bool ) { QStringList fileNames = QFileDialog::getOpenFileNames(NULL, "Load data", "", mitk::CoreObjectFactory::GetInstance()->GetFileExtensions()); for ( QStringList::Iterator it = fileNames.begin(); it != fileNames.end(); ++it ) { FileOpen((*it).toAscii(), 0); } } void QmitkDataManagerView::FileOpen( const char * fileName, mitk::DataNode* parentNode ) { mitk::DataNodeFactory::Pointer factory = mitk::DataNodeFactory::New(); try { factory->SetFileName( fileName ); QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) ); factory->Update(); for ( unsigned int i = 0 ; i < factory->GetNumberOfOutputs( ); ++i ) { mitk::DataNode::Pointer node = factory->GetOutput( i ); if ( ( node.IsNotNull() ) && ( node->GetData() != NULL ) ) { this->GetDataStorage()->Add(node, parentNode); mitk::BaseData::Pointer basedata = node->GetData(); mitk::RenderingManager::GetInstance()->InitializeViews( basedata->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); //mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } } catch ( itk::ExceptionObject & ex ) { itkGenericOutputMacro( << "Exception during file open: " << ex ); } QApplication::restoreOverrideCursor(); } QItemSelectionModel *QmitkDataManagerView::GetDataNodeSelectionModel() const { return m_NodeTreeView->selectionModel(); } void QmitkDataManagerView::GlobalReinit( bool ) { mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart(); if (renderWindow == NULL) renderWindow = this->OpenRenderWindowPart(false); // no render window available if (renderWindow == NULL) return; mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(this->GetDataStorage()); } void QmitkDataManagerView::OtsuFilter( bool ) { QList selectedNodes = this->GetCurrentSelection(); mitk::Image::Pointer mitkImage = 0; foreach(mitk::DataNode::Pointer node, selectedNodes) { mitkImage = dynamic_cast( node->GetData() ); if(mitkImage.IsNull()) continue; try { // get selected mitk image const unsigned short dim = 3; typedef short InputPixelType; typedef unsigned char OutputPixelType; typedef itk::Image< InputPixelType, dim > InputImageType; typedef itk::Image< OutputPixelType, dim > OutputImageType; typedef itk::OtsuThresholdImageFilter< InputImageType, OutputImageType > FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetOutsideValue( 1 ); filter->SetInsideValue( 0 ); InputImageType::Pointer itkImage; mitk::CastToItkImage(mitkImage, itkImage); filter->SetInput( itkImage ); filter->Update(); mitk::DataNode::Pointer resultNode = mitk::DataNode::New(); std::string nameOfResultImage = node->GetName(); nameOfResultImage.append("Otsu"); resultNode->SetProperty("name", mitk::StringProperty::New(nameOfResultImage) ); resultNode->SetProperty("binary", mitk::BoolProperty::New(true) ); resultNode->SetData( mitk::ImportItkImage(filter->GetOutput())->Clone()); this->GetDataStorage()->Add(resultNode, node); } catch( std::exception& err ) { MITK_ERROR(this->GetClassName()) << err.what(); } } } void QmitkDataManagerView::NodeTreeViewRowsRemoved ( const QModelIndex & /*parent*/, int /*start*/, int /*end*/ ) { m_CurrentRowCount = m_NodeTreeModel->rowCount(); } void QmitkDataManagerView::NodeTreeViewRowsInserted( const QModelIndex & parent, int, int ) { m_NodeTreeView->setExpanded(parent, true); // a new row was inserted if( m_CurrentRowCount == 0 && m_NodeTreeModel->rowCount() == 1 ) { this->OpenRenderWindowPart(); m_CurrentRowCount = m_NodeTreeModel->rowCount(); /* std::vector nodes = m_NodeTreeModel->GetNodeSet(); if(nodes.size() == 1) { QModelIndex treeIndex = m_NodeTreeModel->GetIndex(nodes.front()); m_NodeTreeView->selectionModel()->setCurrentIndex( treeIndex, QItemSelectionModel::ClearAndSelect ); } */ } } void QmitkDataManagerView::NodeSelectionChanged( const QItemSelection & /*selected*/, const QItemSelection & /*deselected*/ ) { QList nodes = m_NodeTreeModel->GetNodeSet(); foreach(mitk::DataNode::Pointer node, nodes) { if ( node.IsNotNull() ) node->SetBoolProperty("selected", false); } nodes.clear(); nodes = this->GetCurrentSelection(); foreach(mitk::DataNode::Pointer node, nodes) { if ( node.IsNotNull() ) node->SetBoolProperty("selected", true); } //changing the selection does NOT require any rendering processes! //mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataManagerView::ShowIn(const QString &editorId) { berry::IWorkbenchPage::Pointer page = this->GetSite()->GetPage(); berry::IEditorInput::Pointer input(new mitk::DataStorageEditorInput(this->GetDataStorageReference())); page->OpenEditor(input, editorId.toStdString(), false, berry::IWorkbenchPage::MATCH_ID); } mitk::IRenderWindowPart* QmitkDataManagerView::OpenRenderWindowPart(bool activatedEditor) { if (activatedEditor) { return this->GetRenderWindowPart(QmitkAbstractView::ACTIVATE | QmitkAbstractView::OPEN); } else { return this->GetRenderWindowPart(QmitkAbstractView::BRING_TO_FRONT | QmitkAbstractView::OPEN); } }