Commit 094b0145 authored by finetjul's avatar finetjul
Browse files

ENH: Add support for parentable annotations

Sometimes we want the annotations to be parent of other annotations.

git-svn-id: http://svn.slicer.org/Slicer4/trunk@21544 3bd1e089-480b-0410-8dfb-8563597acbee
parent 591d4aa8
......@@ -177,6 +177,14 @@ int qMRMLSceneHierarchyModel::nodeIndex(vtkMRMLNode* node)const
if (hnode)
{
vtkMRMLHierarchyNode* parentHierarchy = vtkMRMLHierarchyNode::SafeDownCast(parent);
if (parentHierarchy == 0)
{
// sometimes the parent is not a hierarchy node but the associated node
// of a hierarchy node (if the hierarchy node is filtered out from the view).
// We need to find that hierarchy node.
parentHierarchy = vtkMRMLHierarchyNode::GetAssociatedHierarchyNode(
d->MRMLScene, parent->GetID());
}
const int childrenCount = parentHierarchy->GetNumberOfChildrenNodes();
for ( int i = 0; i < childrenCount ; ++i)
{
......
......@@ -175,8 +175,12 @@ public:
virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action,
int row, int column, const QModelIndex &parent);
/// Must be reimplemented in derived classes
/// Returns 0 (scene is not a node) in qMRMLSceneModel
/// Returns the parent node of the scene, 0 otherwise (the parent is the
/// scene).
/// Must be reimplemented in derived classes. If reimplemented, you might
/// have to reimplement nodeIndex() as well.
/// Returns 0 by default.
/// \sa nodeIndex(), canBeAChild(), canBeAParent()
virtual vtkMRMLNode* parentNode(vtkMRMLNode* node)const;
/// Must be reimplemented in derived classes
virtual int nodeIndex(vtkMRMLNode* node)const;
......
......@@ -3049,14 +3049,14 @@ vtkMRMLAnnotationHierarchyNode *vtkSlicerAnnotationModuleLogic::GetActiveHierarc
}
if (this->GetMRMLScene()->GetNodeByID(this->GetActiveHierarchyNodeID()) == NULL)
{
// if the node with the active id can't be found in the scene, reset it to
// null
this->SetActiveHierarchyNodeID(NULL);
// try finding the top level hierarchy
char* toplevelNodeID = this->GetTopLevelHierarchyNodeID();
if (!toplevelNodeID)
{
vtkErrorMacro("GetActiveHierarchyNode: the active hierarchy node id was invalid and can't find or make a top level hierarchy node");
// if the node with the active id can't be found in the scene, reset it to
// null
this->SetActiveHierarchyNodeID(NULL);
return NULL;
}
else
......@@ -3064,7 +3064,8 @@ vtkMRMLAnnotationHierarchyNode *vtkSlicerAnnotationModuleLogic::GetActiveHierarc
this->SetActiveHierarchyNodeID(toplevelNodeID);
}
}
return vtkMRMLAnnotationHierarchyNode::SafeDownCast(this->GetMRMLScene()->GetNodeByID(this->GetActiveHierarchyNodeID()));
return vtkMRMLAnnotationHierarchyNode::SafeDownCast(
this->GetMRMLScene()->GetNodeByID(this->GetActiveHierarchyNodeID()));
}
//---------------------------------------------------------------------------
......
......@@ -139,6 +139,23 @@ void qMRMLAnnotationTreeView::onSelectionChanged(const QItemSelection& index,con
}
}
//------------------------------------------------------------------------------
void qMRMLAnnotationTreeView::onCurrentRowChanged(const QModelIndex& index)
{
Q_D(qMRMLAnnotationTreeView);
// if the user clicked on a hierarchy, set this as the active one
// this means, new annotations or new user-created hierarchies will be created
// as childs of this one
vtkMRMLNode *mrmlNode = d->SortFilterModel->mrmlNodeFromIndex(index);
vtkMRMLNode* activeNode =
this->annotationModel()->activeHierarchyNode(mrmlNode);
this->m_Logic->SetActiveHierarchyNodeID(
activeNode ? activeNode->GetID() : 0);
this->Superclass::onCurrentRowChanged(index);
}
//------------------------------------------------------------------------------
void qMRMLAnnotationTreeView::onClicked(const QModelIndex& index)
{
......@@ -150,29 +167,6 @@ void qMRMLAnnotationTreeView::onClicked(const QModelIndex& index)
{
return;
}
// if the user clicked on a hierarchy, set this as the active one
// this means, new annotations or new user-created hierarchies will be created
// as childs of this one
if(mrmlNode->IsA("vtkMRMLAnnotationHierarchyNode"))
{
this->m_Logic->SetActiveHierarchyNodeID(mrmlNode->GetID());
}
else
{
// if the user clicked on a row that isn't a hierarchy node, reset the
// active hierarchy to the parent hierarchy of this node (going via the
// hierarchy node associated with this node)
if(mrmlNode &&
!mrmlNode->IsA("vtkMRMLAnnotationHierarchyNode"))
{
vtkMRMLHierarchyNode *hnode = vtkMRMLAnnotationHierarchyNode::GetAssociatedHierarchyNode(this->mrmlScene(), mrmlNode->GetID());
if (hnode && hnode->GetParentNode())
{
this->m_Logic->SetActiveHierarchyNodeID(hnode->GetParentNode()->GetID());
}
}
}
// check if user clicked on icon, this can happen even after we marked a
// hierarchy as active
......
......@@ -89,6 +89,10 @@ protected:
virtual void toggleVisibility(const QModelIndex& index);
/// Set the active hierarchy node when the current index changes.
/// \sa vtkSlicerAnnotationModuleLogic::SetActiveHierarchyNodeID()
virtual void onCurrentRowChanged(const QModelIndex& index);
private:
Q_DECLARE_PRIVATE(qMRMLAnnotationTreeView);
Q_DISABLE_COPY(qMRMLAnnotationTreeView);
......
......@@ -36,6 +36,7 @@ qMRMLSceneAnnotationModelPrivate
::qMRMLSceneAnnotationModelPrivate(qMRMLSceneAnnotationModel& object)
: qMRMLSceneDisplayableModelPrivate(object)
{
this->AnnotationsAreParent = false;
this->LockColumn = -1;
this->EditColumn = -1;
this->ValueColumn = -1;
......@@ -81,6 +82,20 @@ qMRMLSceneAnnotationModel::~qMRMLSceneAnnotationModel()
{
}
//------------------------------------------------------------------------------
bool qMRMLSceneAnnotationModel::areAnnotationsParent()const
{
Q_D(const qMRMLSceneAnnotationModel);
return d->AnnotationsAreParent;
}
//------------------------------------------------------------------------------
void qMRMLSceneAnnotationModel::setAnnotationsAreParent(bool parentable)
{
Q_D(qMRMLSceneAnnotationModel);
d->AnnotationsAreParent = parentable;
}
//------------------------------------------------------------------------------
void qMRMLSceneAnnotationModel::updateNodeFromItemData(vtkMRMLNode* node, QStandardItem* item)
{
......@@ -251,7 +266,7 @@ QFlags<Qt::ItemFlag> qMRMLSceneAnnotationModel::nodeFlags(vtkMRMLNode* node, int
bool qMRMLSceneAnnotationModel::canBeAParent(vtkMRMLNode* node)const
{
bool res = this->Superclass::canBeAParent(node) ||
(node && node->IsA("vtkMRMLAnnotationNode"));
(node && node->IsA("vtkMRMLAnnotationNode") && this->areAnnotationsParent());
return res;
}
......@@ -263,47 +278,69 @@ vtkMRMLNode* qMRMLSceneAnnotationModel::parentNode(vtkMRMLNode* node)const
return 0;
}
// MRML Displayable nodes (inherits from transformable)
vtkMRMLDisplayableNode *displayableNode = vtkMRMLDisplayableNode::SafeDownCast(node);
vtkMRMLDisplayableHierarchyNode * displayableHierarchyNode = NULL;
if (displayableNode &&
displayableNode->GetScene() &&
displayableNode->GetID())
vtkMRMLDisplayableHierarchyNode* displayableHierarchyNode =
vtkMRMLDisplayableHierarchyNode::SafeDownCast(node);
if (displayableHierarchyNode == 0)
{
// get the displayable hierarchy node associated with this displayable node
displayableHierarchyNode = vtkMRMLDisplayableHierarchyNode::GetDisplayableHierarchyNode(
displayableNode->GetScene(), displayableNode->GetID());
if (displayableHierarchyNode)
vtkMRMLDisplayableNode *displayableNode = vtkMRMLDisplayableNode::SafeDownCast(node);
if (displayableNode != 0)
{
if (displayableHierarchyNode->GetHideFromEditors())
// get the displayable hierarchy node associated with this displayable node
displayableHierarchyNode =
vtkMRMLDisplayableHierarchyNode::GetDisplayableHierarchyNode(
displayableNode->GetScene(), displayableNode->GetID());
if (displayableHierarchyNode &&
!displayableHierarchyNode->GetHideFromEditors())
{
// this is a hidden hierarchy node, so we do not want to display it
// instead, we will return the parent of the hidden hierarchy node
// to be used as the parent for the displayableNode
vtkMRMLDisplayableHierarchyNode* parent =
vtkMRMLDisplayableHierarchyNode::SafeDownCast(
displayableHierarchyNode->GetParentNode());
if (parent && parent->GetHideFromEditors() &&
parent->GetDisplayableNode())
{
return parent->GetDisplayableNode();
}
return parent;
return displayableHierarchyNode;
}
return displayableHierarchyNode;
}
}
if (displayableHierarchyNode == NULL)
if (displayableHierarchyNode != 0)
{
// the passed in node might have been a hierarchy node instead, try to
// cast it
displayableHierarchyNode = vtkMRMLDisplayableHierarchyNode::SafeDownCast(node);
// this is a hidden hierarchy node, so we do not want to display it
// instead, we will return the parent of the hidden hierarchy node
// to be used as the parent for the displayableNode
vtkMRMLDisplayableHierarchyNode* parent =
vtkMRMLDisplayableHierarchyNode::SafeDownCast(
displayableHierarchyNode->GetParentNode());
// return it's parent
if (this->areAnnotationsParent() &&
parent && parent->GetHideFromEditors() &&
parent->GetDisplayableNode())
{
return parent->GetDisplayableNode();
}
return parent;
}
if (displayableHierarchyNode)
return 0;
}
//------------------------------------------------------------------------------
vtkMRMLNode* qMRMLSceneAnnotationModel
::activeHierarchyNode(vtkMRMLNode* mrmlNode)const
{
Q_D(const qMRMLSceneAnnotationModel);
if(mrmlNode->IsA("vtkMRMLAnnotationHierarchyNode"))
{
// return it's parent
return displayableHierarchyNode->GetParentNode();
return mrmlNode;
}
// If the node isn't a hierarchy node, reset the
// active hierarchy to the parent hierarchy of this node (going via the
// hierarchy node associated with this node)
vtkMRMLHierarchyNode *hnode =
vtkMRMLAnnotationHierarchyNode::GetAssociatedHierarchyNode(
this->mrmlScene(), mrmlNode->GetID());
if (hnode)
{
if (this->areAnnotationsParent())
{
return hnode;
}
else
{
return hnode->GetParentNode();
}
}
return 0;
}
......
......@@ -40,6 +40,13 @@ class Q_SLICER_MODULE_ANNOTATIONS_WIDGETS_EXPORT qMRMLSceneAnnotationModel
: public qMRMLSceneDisplayableModel
{
Q_OBJECT
/// This property controls whether annotations can have children or not.
/// This is used when setting the active hierarchy node.
/// False by default.
/// \sa indexHierarchyNode(),
/// vtkSlicerAnnotationModuleLogic::SetActiveHierarchyNodeID()
Q_PROPERTY(bool annotationsAreParent READ areAnnotationsParent WRITE setAnnotationsAreParent)
/// This property holds the column index where the annotation lock property is
/// controlled.
/// 2 by default.
......@@ -74,6 +81,13 @@ public:
// Register the logic
void setLogic(vtkSlicerAnnotationModuleLogic* logic);
/// Return true if the annotations can have children, false otherwise.
/// \sa annotationsAreParent, setAnnotationsAreParent()
bool areAnnotationsParent()const;
/// Set whether annotations can have children or not.
/// \sa annotationsAreParent, areAnnotationsParent()
void setAnnotationsAreParent(bool parentable);
/// Return the lock column.
/// \sa lockColumn, setLockColumn
int lockColumn()const;
......@@ -102,6 +116,12 @@ public:
/// \sa textColumn, textColumn()
void setTextColumn(int column);
/// Return the best active hierarchy node for a given node.
/// If the node is an annotation node and annotationsAreParent is true,
/// then it returns the associated hierarchy node instead of the parent
/// hierarchy node.
/// \sa annotationsAreParent
virtual vtkMRMLNode* activeHierarchyNode(vtkMRMLNode* mrmlNode)const;
virtual vtkMRMLNode* parentNode(vtkMRMLNode* node)const;
virtual bool canBeAParent(vtkMRMLNode* node)const;
......
......@@ -40,6 +40,8 @@ public:
qMRMLSceneAnnotationModelPrivate(qMRMLSceneAnnotationModel& object);
virtual void init();
bool AnnotationsAreParent;
int LockColumn;
int EditColumn;
int ValueColumn;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment