diff --git a/Modules/QtWidgets/src/QmitkDataStorageTreeModel.cpp b/Modules/QtWidgets/src/QmitkDataStorageTreeModel.cpp index adbd312693..9a727083db 100644 --- a/Modules/QtWidgets/src/QmitkDataStorageTreeModel.cpp +++ b/Modules/QtWidgets/src/QmitkDataStorageTreeModel.cpp @@ -1,1010 +1,1035 @@ /*=================================================================== 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 #include "QmitkDataStorageTreeModel.h" #include "QmitkNodeDescriptorManager.h" #include #include #include #include #include #include #include #include #include QmitkDataStorageTreeModel::QmitkDataStorageTreeModel(mitk::DataStorage *_DataStorage, bool _PlaceNewNodesOnTop, QObject *parent) : QAbstractItemModel(parent), m_DataStorage(0), m_PlaceNewNodesOnTop(_PlaceNewNodesOnTop), m_Root(0), m_BlockDataStorageEvents(false), m_AllowHierarchyChange(false) { this->SetDataStorage(_DataStorage); } QmitkDataStorageTreeModel::~QmitkDataStorageTreeModel() { // set data storage to 0 = remove all listeners this->SetDataStorage(0); m_Root->Delete(); m_Root = 0; } 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. QList listOfItemsToDrop = ToTreeItemPtrList(data); if (listOfItemsToDrop.empty()) { return false; } // 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. // Determine whether or not the drag and drop operation is a valid one. // Examples of invalid operations include: // - dragging nodes with different parents // - dragging nodes from one parent to another parent, if m_AllowHierarchyChange is false // - dragging a node on one of its child nodes (only relevant if m_AllowHierarchyChange is true) bool isValidDragAndDropOperation(true); // different parents { TreeItem *firstParent = listOfItemsToDrop[0]->GetParent(); QList::iterator diIter; for (diIter = listOfItemsToDrop.begin() + 1; diIter != listOfItemsToDrop.end(); diIter++) { if (firstParent != (*diIter)->GetParent()) { isValidDragAndDropOperation = false; break; } } } // dragging from one parent to another if ((!m_AllowHierarchyChange) && isValidDragAndDropOperation) { if (row == -1) // drag onto a node { isValidDragAndDropOperation = listOfItemsToDrop[0]->GetParent() == parentItem; } else // drag between nodes { isValidDragAndDropOperation = listOfItemsToDrop[0]->GetParent() == dropItem; } } // dragging on a child node of one the dragged nodes { QList::iterator diIter; for (diIter = listOfItemsToDrop.begin(); diIter != listOfItemsToDrop.end(); diIter++) { TreeItem *tempItem = dropItem; while (tempItem != m_Root) { tempItem = tempItem->GetParent(); if (tempItem == *diIter) { isValidDragAndDropOperation = false; } } } } if (!isValidDragAndDropOperation) return isValidDragAndDropOperation; if (listOfItemsToDrop[0] != dropItem && isValidDragAndDropOperation) { // Retrieve the index of where we are dropping stuff. QModelIndex parentModelIndex = this->IndexFromTreeItem(parentItem); int dragIndex = 0; // Iterate through the list of TreeItem (which may be at non-consecutive indexes). QList::iterator diIter; for (diIter = listOfItemsToDrop.begin(); diIter != listOfItemsToDrop.end(); diIter++) { TreeItem *itemToDrop = *diIter; // if the item is dragged down we have to compensate its final position for the // fact it is deleted lateron, this only applies if it is dragged within the same level if ((itemToDrop->GetIndex() < row) && (itemToDrop->GetParent() == dropItem)) { dragIndex = 1; } // Here we assume that as you remove items, one at a time, that GetIndex() will be valid. this->beginRemoveRows( this->IndexFromTreeItem(itemToDrop->GetParent()), itemToDrop->GetIndex(), itemToDrop->GetIndex()); itemToDrop->GetParent()->RemoveChild(itemToDrop); this->endRemoveRows(); } // row = -1 dropped on an item, row != -1 dropped in between two items // Select the target index position, or put it at the end of the list. int dropIndex = 0; if (row != -1) { if (dragIndex == 0) dropIndex = std::min(row, parentItem->GetChildCount() - 1); else dropIndex = std::min(row - 1, parentItem->GetChildCount() - 1); } else { dropIndex = dropItem->GetIndex(); } QModelIndex dropItemModelIndex = this->IndexFromTreeItem(dropItem); if ((row == -1 && dropItemModelIndex.row() == -1) || dropItemModelIndex.row() > parentItem->GetChildCount()) dropIndex = parentItem->GetChildCount() - 1; // Now insert items again at the drop item position if (m_AllowHierarchyChange) { this->beginInsertRows(dropItemModelIndex, dropIndex, dropIndex + listOfItemsToDrop.size() - 1); } else { this->beginInsertRows(parentModelIndex, dropIndex, dropIndex + listOfItemsToDrop.size() - 1); } for (diIter = listOfItemsToDrop.begin(); diIter != listOfItemsToDrop.end(); diIter++) { // dropped on node, behaviour depends on preference setting if (m_AllowHierarchyChange) { m_BlockDataStorageEvents = true; mitk::DataNode *droppedNode = (*diIter)->GetDataNode(); mitk::DataNode *dropOntoNode = dropItem->GetDataNode(); m_DataStorage->Remove(droppedNode); m_DataStorage->Add(droppedNode, dropOntoNode); m_BlockDataStorageEvents = false; dropItem->InsertChild((*diIter), dropIndex); } else { if (row == -1) // drag onto a node { parentItem->InsertChild((*diIter), dropIndex); } else // drag between nodes { dropItem->InsertChild((*diIter), dropIndex); } } dropIndex++; } this->endInsertRows(); // Change Layers to match. this->AdjustLayerProperty(); } } else if (data->hasFormat("application/x-mitk-datanodes")) { returnValue = true; int numberOfNodesDropped = 0; QList dataNodeList = QmitkMimeTypes::ToDataNodePtrList(data); mitk::DataNode *node = NULL; foreach (node, dataNodeList) { 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 { return mimeDataFromModelIndexList(indexes); } QMimeData *QmitkDataStorageTreeModel::mimeDataFromModelIndexList(const QModelIndexList &indexes) { QMimeData *ret = new QMimeData; QString treeItemAddresses(""); QString dataNodeAddresses(""); QByteArray baTreeItemPtrs; QByteArray baDataNodePtrs; QDataStream dsTreeItemPtrs(&baTreeItemPtrs, QIODevice::WriteOnly); QDataStream dsDataNodePtrs(&baDataNodePtrs, QIODevice::WriteOnly); for (int i = 0; i < indexes.size(); i++) { TreeItem *treeItem = static_cast(indexes.at(i).internalPointer()); dsTreeItemPtrs << reinterpret_cast(treeItem); dsDataNodePtrs << reinterpret_cast(treeItem->GetDataNode().GetPointer()); // --------------- deprecated ----------------- unsigned long long treeItemAddress = reinterpret_cast(treeItem); unsigned long long dataNodeAddress = reinterpret_cast(treeItem->GetDataNode().GetPointer()); QTextStream(&treeItemAddresses) << treeItemAddress; QTextStream(&dataNodeAddresses) << dataNodeAddress; if (i != indexes.size() - 1) { QTextStream(&treeItemAddresses) << ","; QTextStream(&dataNodeAddresses) << ","; } // -------------- end deprecated ------------- } // ------------------ deprecated ----------------- ret->setData("application/x-qabstractitemmodeldatalist", QByteArray(treeItemAddresses.toLatin1())); ret->setData("application/x-mitk-datanodes", QByteArray(dataNodeAddresses.toLatin1())); // --------------- end deprecated ----------------- ret->setData(QmitkMimeTypes::DataStorageTreeItemPtrs, baTreeItemPtrs); ret->setData(QmitkMimeTypes::DataNodePtrs, baDataNodePtrs); 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(mitk::GeneratePropertyNameForDICOMTag(0x0008, 0x103e).c_str())); mitk::BaseProperty *studyDescription = (dataNode->GetProperty(mitk::GeneratePropertyNameForDICOMTag(0x0008, 0x1030).c_str())); mitk::BaseProperty *patientsName = (dataNode->GetProperty(mitk::GeneratePropertyNameForDICOMTag(0x0010, 0x0010).c_str())); mitk::BaseProperty *seriesDescription_deprecated = (dataNode->GetProperty("dicom.series.SeriesDescription")); mitk::BaseProperty *studyDescription_deprecated = (dataNode->GetProperty("dicom.study.StudyDescription")); mitk::BaseProperty *patientsName_deprecated = (dataNode->GetProperty("dicom.patient.PatientsName")); if (patientsName) { nodeName += QFile::encodeName(patientsName->GetValueAsString().c_str()) + "\n"; nodeName += QFile::encodeName(studyDescription->GetValueAsString().c_str()) + "\n"; nodeName += QFile::encodeName(seriesDescription->GetValueAsString().c_str()); } else { /** Code coveres the deprecated property naming for backwards compatibility */ nodeName += QFile::encodeName(patientsName_deprecated->GetValueAsString().c_str()) + "\n"; nodeName += QFile::encodeName(studyDescription_deprecated->GetValueAsString().c_str()) + "\n"; nodeName += QFile::encodeName(seriesDescription_deprecated->GetValueAsString().c_str()); } } else { nodeName = QFile::encodeName(dataNode->GetName().c_str()); } 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_deprecated = (node.GetProperty("dicom.series.SeriesDescription")); mitk::BaseProperty *studyDescription_deprecated = (node.GetProperty("dicom.study.StudyDescription")); mitk::BaseProperty *patientsName_deprecated = (node.GetProperty("dicom.patient.PatientsName")); mitk::BaseProperty *seriesDescription = (node.GetProperty(mitk::GeneratePropertyNameForDICOMTag(0x0008, 0x103e).c_str())); mitk::BaseProperty *studyDescription = (node.GetProperty(mitk::GeneratePropertyNameForDICOMTag(0x0008, 0x1030).c_str())); mitk::BaseProperty *patientsName = (node.GetProperty(mitk::GeneratePropertyNameForDICOMTag(0x0010, 0x0010).c_str())); if (patientsName != NULL && studyDescription != NULL && seriesDescription != NULL) { if ((!patientsName->GetValueAsString().empty()) && (!studyDescription->GetValueAsString().empty()) && (!seriesDescription->GetValueAsString().empty())) { propertiesExists = true; } } /** Code coveres the deprecated property naming for backwards compatibility */ if (patientsName_deprecated != NULL && studyDescription_deprecated != NULL && seriesDescription_deprecated != NULL) { if ((!patientsName_deprecated->GetValueAsString().empty()) && (!studyDescription_deprecated->GetValueAsString().empty()) && (!seriesDescription_deprecated->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->beginResetModel(); this->endResetModel(); 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_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); + int firstRowWithASiblingBelow = 0; + int nodeLayer = -1; + node->GetIntProperty("layer", nodeLayer); + for (TreeItem* siblingTreeItem: parentTreeItem->GetChildren()) + { + int siblingLayer = -1; + if (mitk::DataNode* siblingNode = siblingTreeItem->GetDataNode()) + { + siblingNode->GetIntProperty("layer", siblingLayer); + } + if (nodeLayer > siblingLayer) + { + break; + } + ++firstRowWithASiblingBelow; + } + beginInsertRows(index, firstRowWithASiblingBelow, firstRowWithASiblingBelow); + parentTreeItem->InsertChild(new TreeItem(const_cast(node)), firstRowWithASiblingBelow); } // emit endInsertRows event endInsertRows(); - this->AdjustLayerProperty(); + if(m_PlaceNewNodesOnTop) + { + this->AdjustLayerProperty(); + } } void QmitkDataStorageTreeModel::AddNode(const mitk::DataNode *node) { if (node == 0 || m_BlockDataStorageEvents || m_DataStorage.IsNull() || !m_DataStorage->Exists(node) || m_Root->Find(node) != 0) return; 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 || m_BlockDataStorageEvents) return; this->RemoveNodeInternal(node); } void QmitkDataStorageTreeModel::SetNodeModified(const mitk::DataNode *node) { TreeItem *treeItem = m_Root->Find(node); 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; i < parent->GetChildCount(); ++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; i < parent->GetChildCount(); ++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(); } QList QmitkDataStorageTreeModel::ToTreeItemPtrList(const QMimeData *mimeData) { if (mimeData == NULL || !mimeData->hasFormat(QmitkMimeTypes::DataStorageTreeItemPtrs)) { return QList(); } return ToTreeItemPtrList(mimeData->data(QmitkMimeTypes::DataStorageTreeItemPtrs)); } QList QmitkDataStorageTreeModel::ToTreeItemPtrList(const QByteArray &ba) { QList result; QDataStream ds(ba); while (!ds.atEnd()) { quintptr treeItemPtr; ds >> treeItemPtr; result.push_back(reinterpret_cast(treeItemPtr)); } return result; } 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::Update() { if (m_DataStorage.IsNotNull()) { - this->beginResetModel(); - this->endResetModel(); - mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet = m_DataStorage->GetAll(); - for (mitk::DataStorage::SetOfObjects::const_iterator it = _NodeSet->begin(); it != _NodeSet->end(); it++) + /// Regardless the value of this preference, the new nodes must not be inserted + /// at the top now, but at the position according to their layer. + bool newNodesWereToBePlacedOnTop = m_PlaceNewNodesOnTop; + m_PlaceNewNodesOnTop = false; + + for (const auto& node: *_NodeSet) { - // save node - this->AddNodeInternal(*it); + this->AddNodeInternal(node); } + + m_PlaceNewNodesOnTop = newNodesWereToBePlacedOnTop; + + /// Adjust the layers to ensure that derived nodes are above their sources. + this->AdjustLayerProperty(); } } void QmitkDataStorageTreeModel::SetAllowHierarchyChange(bool allowHierarchyChange) { m_AllowHierarchyChange = allowHierarchyChange; } diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp index 7c2e977513..d0796a2e3f 100644 --- a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp +++ b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp @@ -1,1135 +1,1133 @@ /*=================================================================== 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" //# Own Includes //## mitk #include "mitkDataStorageEditorInput.h" #include "mitkIDataStorageReference.h" #include "mitkNodePredicateDataType.h" #include "mitkCoreObjectFactory.h" #include "mitkColorProperty.h" #include "mitkCommon.h" #include "mitkNodePredicateData.h" #include "mitkNodePredicateNot.h" #include "mitkNodePredicateOr.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 #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 "berryIExtensionRegistry.h" #include "mitkRenderingModeProperty.h" const QString 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* prefService = berry::Platform::GetPreferencesService(); 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 = new QmitkDataStorageTreeModel(this->GetDataStorage(), prefs->GetBool("Place new nodes on top", true)); m_NodeTreeModel->setParent( parent ); - m_NodeTreeModel->SetPlaceNewNodesOnTop( - prefs->GetBool("Place new nodes on top", true) ); m_NodeTreeModel->SetAllowHierarchyChange( prefs->GetBool("Allow changing of parent node", false)); m_SurfaceDecimation = prefs->GetBool("Use surface decimation", false); // Prepare filters m_HelperObjectFilterPredicate = mitk::NodePredicateOr::New( mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true)), mitk::NodePredicateProperty::New("hidden object", mitk::BoolProperty::New(true))); m_NodeWithNoDataFilterPredicate = mitk::NodePredicateData::New(0); m_FilterModel = new QmitkDataStorageFilterProxyModel(); m_FilterModel->setSourceModel(m_NodeTreeModel); m_FilterModel->AddFilterPredicate(m_HelperObjectFilterPredicate); m_FilterModel->AddFilterPredicate(m_NodeWithNoDataFilterPredicate); //# 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_FilterModel); 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(); QList editors = editorRegistry->GetEditors("*.mitk"); if (editors.size() > 1) { m_ShowInMapper = new QSignalMapper(this); foreach(berry::IEditorDescriptor::Pointer descriptor, editors) { QAction* action = new QAction(descriptor->GetLabel(), this); m_ShowInActions << action; m_ShowInMapper->connect(action, SIGNAL(triggered()), m_ShowInMapper, SLOT(map())); m_ShowInMapper->setMapping(action, descriptor->GetId()); } connect(m_ShowInMapper, SIGNAL(mapped(QString)), this, SLOT(ShowIn(QString))); } auto unknownDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetUnknownDataNodeDescriptor(); auto imageDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("Image"); auto multiComponentImageDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("MultiComponentImage"); auto diffusionImageDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("DiffusionImage"); auto surfaceDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("Surface"); auto labelSetImageDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("LabelSetImage"); auto pointSetNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PointSet"); auto planarLineNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarLine"); auto planarCircleNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarCircle"); auto planarEllipseNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarEllipse"); auto planarAngleNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarAngle"); auto planarFourPointAngleNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarFourPointAngle"); auto planarRectangleNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarRectangle"); auto planarPolygonNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarPolygon"); auto planarPathNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarPath"); auto planarDoubleEllipseNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarDoubleEllipse"); auto planarBezierCurveNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarBezierCurve"); auto planarSubdivisionPolygonNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarSubdivisionPolygon"); QAction* globalReinitAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Refresh_48.png"), tr("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 QmitkFileSaveAction(QIcon(":/org.mitk.gui.qt.datamanager/Save_48.png"), this->GetSite()->GetWorkbenchWindow()); unknownDataNodeDescriptor->AddAction(saveAction); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,saveAction)); QAction* removeAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Remove_48.png"), tr("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"), tr("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::IExtensionRegistry* extensionPointService = berry::Platform::GetExtensionRegistry(); QList cmActions( extensionPointService->GetConfigurationElementsFor("org.mitk.gui.qt.datamanager.contextMenuActions") ); QList::iterator cmActionsIt; QmitkNodeDescriptor* tmpDescriptor; QAction* contextMenuAction; QVariant cmActionDataIt; m_ConfElements.clear(); int i=1; for (cmActionsIt = cmActions.begin() ; cmActionsIt != cmActions.end() ; ++cmActionsIt) { QString cmNodeDescriptorName = (*cmActionsIt)->GetAttribute("nodeDescriptorName"); QString cmLabel = (*cmActionsIt)->GetAttribute("label"); QString cmClass = (*cmActionsIt)->GetAttribute("class"); if(!cmNodeDescriptorName.isEmpty() && !cmLabel.isEmpty() && !cmClass.isEmpty()) { QString cmIcon = (*cmActionsIt)->GetAttribute("icon"); // create context menu entry here tmpDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(cmNodeDescriptorName); if(!tmpDescriptor) { MITK_WARN << "cannot add action \"" << cmLabel << "\" because descriptor " << cmNodeDescriptorName << " does not exist"; continue; } // check if the user specified an icon attribute if ( !cmIcon.isEmpty() ) { contextMenuAction = new QAction( QIcon(cmIcon), cmLabel, parent); } else { contextMenuAction = new QAction( 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(tr("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(tr("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() ) ); { // only give the color context menu option where appropriate if (imageDataNodeDescriptor != NULL) { imageDataNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(imageDataNodeDescriptor, colorAction)); } if (multiComponentImageDataNodeDescriptor != NULL) { multiComponentImageDataNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(multiComponentImageDataNodeDescriptor, colorAction)); } if (diffusionImageDataNodeDescriptor != NULL) { diffusionImageDataNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(diffusionImageDataNodeDescriptor, colorAction)); } if (surfaceDataNodeDescriptor != NULL) { surfaceDataNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(surfaceDataNodeDescriptor, colorAction)); } if (pointSetNodeDescriptor != NULL) { pointSetNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(pointSetNodeDescriptor, colorAction)); } if (planarLineNodeDescriptor != NULL) { planarLineNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(planarLineNodeDescriptor, colorAction)); } if (planarCircleNodeDescriptor != NULL) { planarCircleNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(planarCircleNodeDescriptor, colorAction)); } if (planarEllipseNodeDescriptor != NULL) { planarEllipseNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(planarEllipseNodeDescriptor, colorAction)); } if (planarAngleNodeDescriptor != NULL) { planarAngleNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(planarAngleNodeDescriptor, colorAction)); } if (planarFourPointAngleNodeDescriptor != NULL) { planarFourPointAngleNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(planarFourPointAngleNodeDescriptor, colorAction)); } if (planarRectangleNodeDescriptor != NULL) { planarRectangleNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(planarRectangleNodeDescriptor, colorAction)); } if (planarPolygonNodeDescriptor != NULL) { planarPolygonNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(planarPolygonNodeDescriptor, colorAction)); } if (planarPathNodeDescriptor != NULL) { planarPathNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(planarPathNodeDescriptor, colorAction)); } if (planarDoubleEllipseNodeDescriptor != NULL) { planarDoubleEllipseNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(planarDoubleEllipseNodeDescriptor, colorAction)); } if (planarBezierCurveNodeDescriptor != NULL) { planarBezierCurveNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(planarBezierCurveNodeDescriptor, colorAction)); } if (planarSubdivisionPolygonNodeDescriptor != NULL) { planarSubdivisionPolygonNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back( std::pair(planarSubdivisionPolygonNodeDescriptor, 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(tr("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() ) ); multiComponentImageDataNodeDescriptor->AddAction(componentAction, false); m_DescriptorActionList.push_back(std::pair(multiComponentImageDataNodeDescriptor,componentAction)); if (diffusionImageDataNodeDescriptor!=NULL) { diffusionImageDataNodeDescriptor->AddAction(componentAction, false); m_DescriptorActionList.push_back(std::pair(diffusionImageDataNodeDescriptor,componentAction)); } m_TextureInterpolation = new QAction(tr("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)); if (diffusionImageDataNodeDescriptor!=NULL) { diffusionImageDataNodeDescriptor->AddAction(m_TextureInterpolation, false); m_DescriptorActionList.push_back(std::pair(diffusionImageDataNodeDescriptor,m_TextureInterpolation)); } m_ColormapAction = new QAction(tr("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)); if (diffusionImageDataNodeDescriptor!=NULL) { diffusionImageDataNodeDescriptor->AddAction(m_ColormapAction, false); m_DescriptorActionList.push_back(std::pair(diffusionImageDataNodeDescriptor, m_ColormapAction)); } m_SurfaceRepresentation = new QAction(tr("Surface Representation"), this); m_SurfaceRepresentation->setMenu(new QMenu(m_NodeTreeView)); 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") , tr("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") , tr("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") , tr("Details..."), this); QObject::connect( actionShowInfoDialog, SIGNAL( triggered(bool) ) , this, SLOT( ShowInfoDialogForSelectedNodes(bool) ) ); unknownDataNodeDescriptor->AddAction(actionShowInfoDialog); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,actionShowInfoDialog)); 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"); QString className = confElem->GetAttribute("class"); QString smoothed = confElem->GetAttribute("smoothed"); contextMenuAction->SetDataStorage(this->GetDataStorage()); if(className == "QmitkCreatePolygonModelAction") { if(smoothed == "false") { contextMenuAction->SetSmoothed(false); } else { contextMenuAction->SetSmoothed(true); } contextMenuAction->SetDecimated(m_SurfaceDecimation); } else if(className == "QmitkStatisticsAction") { contextMenuAction->SetFunctionality(this); } 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() ); bool hideHelperObjects = !prefs->GetBool("Show helper objects", false); if (m_FilterModel->HasFilterPredicate(m_HelperObjectFilterPredicate) != hideHelperObjects) { if (hideHelperObjects) { m_FilterModel->AddFilterPredicate(m_HelperObjectFilterPredicate); } else { m_FilterModel->RemoveFilterPredicate(m_HelperObjectFilterPredicate); } } bool hideNodesWithNoData = !prefs->GetBool("Show nodes containing no data", false); if (m_FilterModel->HasFilterPredicate(m_NodeWithNoDataFilterPredicate) != hideNodesWithNoData) { if (hideNodesWithNoData) { m_FilterModel->AddFilterPredicate(m_NodeWithNoDataFilterPredicate); } else { m_FilterModel->RemoveFilterPredicate(m_NodeWithNoDataFilterPredicate); } } m_GlobalReinitOnNodeDelete = prefs->GetBool("Call global reinit if node is deleted", true); m_NodeTreeView->expandAll(); m_SurfaceDecimation = prefs->GetBool("Use surface decimation", false); m_NodeTreeModel->SetAllowHierarchyChange( prefs->GetBool("Allow changing of parent node", false)); this->GlobalReinit(); } void QmitkDataManagerView::NodeTableViewContextMenuRequested( const QPoint & pos ) { QModelIndex selectedProxy = m_NodeTreeView->indexAt ( pos ); QModelIndex selected = m_FilterModel->mapToSource(selectedProxy); 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(tr("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_FilterModel->mapToSource(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_FilterModel->mapToSource(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_FilterModel->mapToSource(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_FilterModel->mapToSource(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(tr("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)); if (node->GetProperty("binaryimage.selectedcolor")) { node->SetProperty("binaryimage.selectedcolor",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_FilterModel->mapToSource(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_FilterModel->mapToSource(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_FilterModel->mapToSource(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_FilterModel->mapToSource(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_FilterModel->mapToSource(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_FilterModel->mapToSource(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_FilterModel->mapToSource(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::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 ); } } } void QmitkDataManagerView::RemoveSelectedNodes( bool ) { QModelIndexList indexesOfSelectedRowsFiltered = m_NodeTreeView->selectionModel()->selectedRows(); QModelIndexList indexesOfSelectedRows; for (int i = 0; i < indexesOfSelectedRowsFiltered.size(); ++i) { indexesOfSelectedRows.push_back(m_FilterModel->mapToSource(indexesOfSelectedRowsFiltered[i])); } if(indexesOfSelectedRows.size() < 1) { return; } std::vector selectedNodes; mitk::DataNode::Pointer 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.IsNotNull() /*& 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(tr(" 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::NodeChanged(const mitk::DataNode* /*node*/) { // m_FilterModel->invalidate(); // fix as proposed by R. Khlebnikov in the mitk-users mail from 02.09.2014 QMetaObject::invokeMethod( m_FilterModel, "invalidate", Qt::QueuedConnection ); } 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::NodeTreeViewRowsRemoved ( const QModelIndex & /*parent*/, int /*start*/, int /*end*/ ) { m_CurrentRowCount = m_NodeTreeModel->rowCount(); } void QmitkDataManagerView::NodeTreeViewRowsInserted( const QModelIndex & parent, int, int ) { QModelIndex viewIndex = m_FilterModel->mapFromSource(parent); m_NodeTreeView->setExpanded(viewIndex, true); // a new row was inserted if( m_CurrentRowCount == 0 && m_NodeTreeModel->rowCount() == 1 ) { this->OpenRenderWindowPart(); m_CurrentRowCount = m_NodeTreeModel->rowCount(); } } 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, 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); } }