Commit a80dfa4a authored by finetjul's avatar finetjul
Browse files

ENH: Cleanup qSlicerMouseModeToolBar

Allows to programatically set the default action without activating
the place mode:
 - vtkMRMLSelectionNode::SetActiveAnnotationID
Don't listen to unnecessary events like ActiveAnnotationIDChangedEvent,
AnnotationIDListModifiedEvent, InteractionModePersistenceChangedEvent.
Listening to ModifiedEvent is enough.
Todo: remove the unnecessary events.

git-svn-id: http://svn.slicer.org/Slicer4/trunk@21555 3bd1e089-480b-0410-8dfb-8563597acbee
parent 332bd65b
......@@ -52,6 +52,7 @@ qSlicerMouseModeToolBarPrivate::qSlicerMouseModeToolBarPrivate(qSlicerMouseModeT
this->PersistenceAction = 0;
this->ActionGroup = 0;
this->DefaultAnnotation = "vtkMRMLAnnotationFiducialNode";
}
//---------------------------------------------------------------------------
......@@ -71,12 +72,6 @@ void qSlicerMouseModeToolBarPrivate::init()
this->PersistenceAction->setToolTip(QObject::tr("Switch between single place and persistent place modes."));
this->PersistenceAction->setCheckable(true);
this->PersistenceAction->setChecked(false);
vtkMRMLInteractionNode * interactionNode =
this->MRMLAppLogic ? this->MRMLAppLogic->GetInteractionNode() : 0;
if (interactionNode && interactionNode->GetPlaceModePersistence())
{
this->PersistenceAction->setChecked(true);
}
connect(this->PersistenceAction, SIGNAL(triggered(bool)),
q, SLOT(setPersistence(bool)));
......@@ -106,6 +101,7 @@ void qSlicerMouseModeToolBarPrivate::init()
this->CreateAndPlaceToolButton,
SLOT(setToolButtonStyle(Qt::ToolButtonStyle)));
this->updateWidgetFromMRML();
}
//---------------------------------------------------------------------------
......@@ -118,102 +114,62 @@ void qSlicerMouseModeToolBarPrivate::setMRMLScene(vtkMRMLScene* newScene)
return;
}
this->qvtkReconnect(this->MRMLScene, newScene, vtkMRMLScene::StartCloseEvent,
this, SLOT(OnMRMLSceneStartClose()));
this->qvtkReconnect(this->MRMLScene, newScene, vtkMRMLScene::EndImportEvent,
this, SLOT(OnMRMLSceneEndImport()));
this->qvtkReconnect(this->MRMLScene, newScene, vtkMRMLScene::StartBatchProcessEvent,
this, SLOT(onMRMLSceneStartBatchProcess()));
this->qvtkReconnect(this->MRMLScene, newScene, vtkMRMLScene::EndCloseEvent,
this, SLOT(OnMRMLSceneEndClose()));
this->qvtkReconnect(this->MRMLScene, newScene, vtkMRMLScene::EndBatchProcessEvent,
this, SLOT(onMRMLSceneEndBatchProcess()));
this->MRMLScene = newScene;
// watch for changes to the interaction, selection nodes so can update the widget
if (this->MRMLScene && this->MRMLAppLogic)
{
vtkMRMLInteractionNode * interactionNode = this->MRMLAppLogic->GetInteractionNode();
if (interactionNode)
{
this->qvtkReconnect(interactionNode, vtkMRMLInteractionNode::InteractionModeChangedEvent,
this, SLOT(onInteractionNodeModeChangedEvent()));
this->qvtkReconnect(interactionNode, vtkMRMLInteractionNode::InteractionModePersistenceChangedEvent,
this, SLOT(onInteractionNodeModePersistenceChanged()));
}
vtkMRMLSelectionNode *selectionNode = this->MRMLAppLogic->GetSelectionNode();
if (selectionNode)
{
this->qvtkReconnect(selectionNode, vtkMRMLSelectionNode::ActiveAnnotationIDChangedEvent,
this, SLOT(onActiveAnnotationIDChangedEvent()));
this->qvtkReconnect(selectionNode, vtkMRMLSelectionNode::AnnotationIDListModifiedEvent,
this, SLOT(onAnnotationIDListModifiedEvent()));
}
}
vtkMRMLInteractionNode* interactionNode =
(this->MRMLAppLogic && this->MRMLScene) ?
this->MRMLAppLogic->GetInteractionNode() : 0;
this->qvtkReconnect(interactionNode, vtkCommand::ModifiedEvent,
this, SLOT(updateWidgetFromInteractionNode()));
//this->qvtkReconnect(interactionNode, vtkMRMLInteractionNode::InteractionModeChangedEvent,
// this, SLOT(updateWidgetFromInteractionNode()));
//this->qvtkReconnect(interactionNode, vtkMRMLInteractionNode::InteractionModePersistenceChangedEvent,
// this, SLOT(updateWidgetFromInteractionNode()));
vtkMRMLSelectionNode* selectionNode =
(this->MRMLAppLogic && this->MRMLScene) ?
this->MRMLAppLogic->GetSelectionNode() : 0;
this->qvtkReconnect(selectionNode, vtkMRMLSelectionNode::ActiveAnnotationIDChangedEvent,
this, SLOT(updateWidgetFromSelectionNode()));
//this->qvtkReconnect(selectionNode, vtkMRMLSelectionNode::ActiveAnnotationIDChangedEvent,
// this, SLOT(onActiveAnnotationIDChangedEvent()));
//this->qvtkReconnect(selectionNode, vtkMRMLSelectionNode::AnnotationIDListModifiedEvent,
// this, SLOT(onAnnotationIDListModifiedEvent()));
// Update UI
q->setEnabled(this->MRMLScene != 0);
if (this->MRMLScene)
{
this->updateWidgetFromMRML();
this->updateWidgetFromSelectionNode();
}
this->updateWidgetFromMRML();
}
//---------------------------------------------------------------------------
void qSlicerMouseModeToolBarPrivate::updateWidgetFromMRML()
{
if (!this->MRMLAppLogic)
{
qWarning() << "Mouse Mode Tool Bar isn't set up with application logic";
return;
}
this->onInteractionNodeModePersistenceChanged();
vtkMRMLInteractionNode * interactionNode = this->MRMLAppLogic->GetInteractionNode();
int currentMouseMode = interactionNode->GetCurrentInteractionMode();
switch (currentMouseMode)
{
case vtkMRMLInteractionNode::Place:
{
// find the active annotation id and set it's corresponding action to be checked
vtkMRMLSelectionNode *selectionNode = this->MRMLAppLogic->GetSelectionNode();
if ( selectionNode )
{
const char *activeAnnotationID = selectionNode->GetActiveAnnotationID();
this->updateWidgetToAnnotation(activeAnnotationID);
}
}
break;
case vtkMRMLInteractionNode::ViewTransform:
// reset the widget to view transform, not supporting pick manipulate
this->updateWidgetToAnnotation(0);
break;
default:
qWarning() << "qSlicerMouseModeToolBarPrivate::updateWidgetFromMRML - "
"unhandled MouseMode:" << currentMouseMode;
break;
}
this->updateWidgetFromSelectionNode();
this->updateWidgetFromInteractionNode();
}
//---------------------------------------------------------------------------
void qSlicerMouseModeToolBarPrivate::updateWidgetFromSelectionNode()
{
Q_Q(qSlicerMouseModeToolBar);
if (!this->MRMLAppLogic)
{
qWarning() << "Mouse Mode Tool Bar not set up with application logic";
return;
}
// get the currently active annotation
vtkMRMLSelectionNode *selectionNode = this->MRMLAppLogic->GetSelectionNode();
vtkMRMLSelectionNode *selectionNode =
this->MRMLAppLogic ? this->MRMLAppLogic->GetSelectionNode() : 0;
if (!selectionNode)
{
qWarning() << "Mouse Mode ToolBar: no selection node";
return;
}
// make sure that all the elements in the selection node have actions in the
// create and place menu
int numIDs = selectionNode->GetNumberOfAnnotationIDsInList();
const int numIDs = selectionNode->GetNumberOfAnnotationIDsInList();
// if some were removed, clear out those actions first
QList<QAction*> actionList = this->CreateAndPlaceMenu->actions();
......@@ -231,11 +187,8 @@ void qSlicerMouseModeToolBarPrivate::updateWidgetFromSelectionNode()
actionText.compare(QObject::tr("Persistent")) != 0 &&
!actionText.isEmpty())
{
actionText = actionText.prepend(QString("vtkMRMLAnnotation"));
actionText = actionText.append(QString("Node"));
QByteArray thisAnnotID_bytes = actionText.toLatin1();
const char *thisAnnotID = thisAnnotID_bytes.data();
if (selectionNode->AnnotationIDInList(thisAnnotID) == -1)
if (selectionNode->AnnotationIDInList(
action->data().toString().toStdString()) == -1)
{
this->ActionGroup->removeAction(action);
this->CreateAndPlaceMenu->removeAction(action);
......@@ -246,17 +199,38 @@ void qSlicerMouseModeToolBarPrivate::updateWidgetFromSelectionNode()
actionList = this->CreateAndPlaceMenu->actions();
}
// qDebug() << "\tnumIDs = " << numIDs;
for (int i = 0; i < numIDs; i++)
// select the active one
QString activeAnnotation(selectionNode->GetActiveAnnotationID());
if (activeAnnotation.isEmpty())
{
activeAnnotation = this->DefaultAnnotation;
}
for (int i = 0; i < numIDs; ++i)
{
QString annotationID = QString(selectionNode->GetAnnotationIDByIndex(i).c_str());
QString annotationResource = QString(selectionNode->GetAnnotationResourceByIndex(i).c_str());
QString annotationName = annotationID;
annotationName = annotationName.remove(QString("vtkMRMLAnnotation"));
if (this->MRMLScene)
{
vtkSmartPointer<vtkMRMLNode> annotationNode;
annotationNode.TakeReference(
this->MRMLScene->CreateNodeByClass(annotationID.toLatin1()));
if (annotationNode.GetPointer())
{
annotationName = annotationNode->GetNodeTagName();
}
}
annotationName = annotationName.remove(QString("vtk"));
annotationName = annotationName.remove(QString("MRML"));
annotationName = annotationName.remove(QString("Annotation"));
annotationName = annotationName.remove(QString("Node"));
// qDebug() << "\t" << i << ", id = " << annotationID << ", resource = " << annotationResource;
bool inMenu = q->isActionTextInMenu(annotationName, this->CreateAndPlaceMenu);
if (!inMenu)
QAction* action = q->actionFromText(annotationName, this->CreateAndPlaceMenu);
if (!action)
{
// add it
QAction * newAction = new QAction(this->CreateAndPlaceMenu);
......@@ -279,19 +253,57 @@ void qSlicerMouseModeToolBarPrivate::updateWidgetFromSelectionNode()
q, SLOT(switchPlaceMode()));
this->CreateAndPlaceToolButton->menu()->addAction(newAction);
this->ActionGroup->addAction(newAction);
// if this new one is the fiducial
if (annotationName.compare("Fiducial") == 0)
action = newAction;
}
// if this new one is the default
if (annotationID == activeAnnotation)
{
// make it the default
this->CreateAndPlaceToolButton->setDefaultAction(action);
}
}
}
//---------------------------------------------------------------------------
void qSlicerMouseModeToolBarPrivate::updateWidgetFromInteractionNode()
{
vtkMRMLInteractionNode* interactionNode =
this->MRMLAppLogic ? this->MRMLAppLogic->GetInteractionNode() : 0;
if (!interactionNode)
{
qWarning() << "Mouse Mode ToolBar: no interaction node";
return;
}
int persistence = interactionNode->GetPlaceModePersistence();
this->PersistenceAction->setChecked(persistence != 0);
int currentMouseMode = interactionNode->GetCurrentInteractionMode();
switch (currentMouseMode)
{
case vtkMRMLInteractionNode::Place:
{
// find the active annotation id and set it's corresponding action to be checked
vtkMRMLSelectionNode *selectionNode = this->MRMLAppLogic->GetSelectionNode();
if ( selectionNode )
{
// make it the default
this->CreateAndPlaceToolButton->setDefaultAction(newAction);
const char *activeAnnotationID = selectionNode->GetActiveAnnotationID();
this->updateWidgetToAnnotation(activeAnnotationID);
}
}
break;
case vtkMRMLInteractionNode::ViewTransform:
// reset the widget to view transform, not supporting pick manipulate
this->updateWidgetToAnnotation(0);
break;
default:
qWarning() << "qSlicerMouseModeToolBarPrivate::updateWidgetFromMRML - "
"unhandled MouseMode:" << currentMouseMode;
break;
}
// select the active one
const char *activeAnnotationID = selectionNode->GetActiveAnnotationID();
this->updateWidgetToAnnotation(activeAnnotationID);
}
//---------------------------------------------------------------------------
void qSlicerMouseModeToolBarPrivate::updateWidgetToAnnotation(const char *annotationID)
{
......@@ -351,28 +363,17 @@ void qSlicerMouseModeToolBarPrivate::updateWidgetToAnnotation(const char *annota
}
}
}
if (checkedAction)
{
// make the checked one the default action
//qDebug() << "qSlicerMouseModeToolBarPrivate::updateWidgetToAnnotation - setting default action to " << qPrintable(checkedAction->text());
this->CreateAndPlaceToolButton->setDefaultAction(checkedAction);
}
else
{
// switching to view transform mode, actions are unchecked by the time we
// get here
}
}
//---------------------------------------------------------------------------
void qSlicerMouseModeToolBarPrivate::OnMRMLSceneStartClose()
void qSlicerMouseModeToolBarPrivate::onMRMLSceneStartBatchProcess()
{
Q_Q(qSlicerMouseModeToolBar);
q->setEnabled(false);
}
//---------------------------------------------------------------------------
void qSlicerMouseModeToolBarPrivate::OnMRMLSceneEndImport()
void qSlicerMouseModeToolBarPrivate::onMRMLSceneEndBatchProcess()
{
Q_Q(qSlicerMouseModeToolBar);
......@@ -383,54 +384,6 @@ void qSlicerMouseModeToolBarPrivate::OnMRMLSceneEndImport()
this->updateWidgetFromMRML();
}
//---------------------------------------------------------------------------
void qSlicerMouseModeToolBarPrivate::OnMRMLSceneEndClose()
{
Q_Q(qSlicerMouseModeToolBar);
if (!this->MRMLScene || this->MRMLScene->IsBatchProcessing())
{
return;
}
// reenable it and update
q->setEnabled(true);
this->updateWidgetFromMRML();
}
//---------------------------------------------------------------------------
void qSlicerMouseModeToolBarPrivate::onInteractionNodeModeChangedEvent()
{
this->updateWidgetFromMRML();
}
//---------------------------------------------------------------------------
void qSlicerMouseModeToolBarPrivate::onInteractionNodeModePersistenceChanged()
{
// get the place persistence mode from the interaction node
if (!this->MRMLAppLogic)
{
qWarning() << "Mouse Mode Tool Bar not set up with application logic";
return;
}
vtkMRMLInteractionNode * interactionNode = this->MRMLAppLogic->GetInteractionNode();
Q_ASSERT(interactionNode);
int persistence = interactionNode->GetPlaceModePersistence();
if (persistence)
{
if (!this->PersistenceAction->isChecked())
{
this->PersistenceAction->setChecked(true);
}
}
else
{
if (this->PersistenceAction->isChecked())
{
this->PersistenceAction->setChecked(false);
}
}
}
//---------------------------------------------------------------------------
void qSlicerMouseModeToolBarPrivate::onActiveAnnotationIDChangedEvent()
{
......@@ -642,21 +595,16 @@ void qSlicerMouseModeToolBar::switchPlaceMode()
}
//---------------------------------------------------------------------------
bool qSlicerMouseModeToolBar::isActionTextInMenu(QString actionText, QMenu *menu)
QAction* qSlicerMouseModeToolBar::actionFromText(QString actionText, QMenu *menu)
{
// get a list of all the actions currently in the menu
QList<QAction*> actionList = menu->actions();
int numActions = actionList.size();
for (int i = 0; i < numActions; i++)
foreach(QAction* action, menu->actions())
{
// qDebug() << "qSlicerMouseModeToolBar::isActionTextInMenu, testing action " << i
// << " with text " << actionList[i] << " against text " << actionText;
if (actionList[i]->text() == actionText)
if (action->text() == actionText)
{
return true;
return action;
}
}
return false;
return 0;
}
//---------------------------------------------------------------------------
......@@ -692,3 +640,17 @@ QString qSlicerMouseModeToolBar::activeActionText()
return activeActionText;
}
//---------------------------------------------------------------------------
QString qSlicerMouseModeToolBar::defaultAnnotation()const
{
Q_D(const qSlicerMouseModeToolBar);
return d->DefaultAnnotation;
}
//---------------------------------------------------------------------------
void qSlicerMouseModeToolBar::setDefaultAnnotation(const QString& annotation)
{
Q_D(qSlicerMouseModeToolBar);
d->DefaultAnnotation = annotation;
}
......@@ -33,12 +33,16 @@ class vtkMRMLScene;
class vtkSlicerApplicationLogic;
///
/// qSlicerMouseModeToolBar is a toolbar that can be used to switch between
/// qSlicerMouseModeToolBar is a toolbar that can be used to switch between
/// mouse modes: PickMode, PickModePersistent, PlaceMode, PlaceModePersistent, TransformMode
/// \note The toolbar expects qSlicerCoreApplication::mrmlApplicationLogic() to return a valid object
/// qSlicerMouseModeToolBar observes the singletons selection node and
/// interaction node to control its state.
class Q_SLICER_BASE_QTGUI_EXPORT qSlicerMouseModeToolBar: public QToolBar
{
Q_OBJECT
/// "vtkMRMLAnnotationFiducialNode" by default.
Q_PROPERTY(QString defaultAnnotation READ defaultAnnotation WRITE setDefaultAnnotation)
public:
typedef QToolBar Superclass;
......@@ -51,10 +55,16 @@ public:
/// For testing, return the active action text
QString activeActionText();
QString defaultAnnotation()const;
void setDefaultAnnotation(const QString& annotation);
public slots:
/// Set the application logic. It is used to retrieve the selection and
/// interaction nodes.
void setApplicationLogic(vtkSlicerApplicationLogic* logic);
/// Observe the mrml scene to prevent updates in batch processing modes.
void setMRMLScene(vtkMRMLScene* newScene);
void switchToViewTransformMode();
......@@ -70,7 +80,7 @@ public slots:
protected:
QScopedPointer<qSlicerMouseModeToolBarPrivate> d_ptr;
bool isActionTextInMenu(QString actionText, QMenu *menu);
QAction* actionFromText(QString actionText, QMenu *menu);
private:
Q_DECLARE_PRIVATE(qSlicerMouseModeToolBar);
Q_DISABLE_COPY(qSlicerMouseModeToolBar);
......
......@@ -63,22 +63,20 @@ public:
void init();
void setMRMLScene(vtkMRMLScene* newScene);
void updateWidgetFromMRML();
void updateWidgetFromSelectionNode();
/// given an annotation id, find the action associated with it and set it
/// checked, update the cursor, update the icon on the button
void updateWidgetToAnnotation(const char *annotationID);
public slots:
void OnMRMLSceneStartClose();
void OnMRMLSceneEndImport();
void OnMRMLSceneEndClose();
void onMRMLSceneStartBatchProcess();
void onMRMLSceneEndBatchProcess();
void updateWidgetFromSelectionNode();
void updateWidgetFromInteractionNode();
void onInteractionNodeModeChangedEvent();
void onInteractionNodeModePersistenceChanged();
void onActiveAnnotationIDChangedEvent();
void onAnnotationIDListModifiedEvent();
public:
vtkSmartPointer<vtkMRMLScene> MRMLScene;
......@@ -94,6 +92,7 @@ public:
/// Group the place actions together so that they're exclusive
QActionGroup* ActionGroup;
QString DefaultAnnotation;
};
#endif
......@@ -75,6 +75,7 @@ void vtkMRMLInteractionNode::SetPlaceModePersistence ( int val )
{
this->PlaceModePersistence = val;
this->InvokeEvent(this->InteractionModePersistenceChangedEvent, NULL);
this->Modified();
}
}
......@@ -85,6 +86,7 @@ void vtkMRMLInteractionNode::SetTransformModePersistence ( int val )
{
this->TransformModePersistence = val;
this->InvokeEvent(this->InteractionModePersistenceChangedEvent, NULL);
this->Modified();
}
}
......@@ -125,6 +127,7 @@ void vtkMRMLInteractionNode::SetCurrentInteractionMode ( int mode )
default:
break;
}
this->Modified();
}
//----------------------------------------------------------------------------
......
......@@ -356,6 +356,7 @@ void vtkMRMLSelectionNode::AddNewAnnotationIDToList(const char *newID, const cha
this->InvokeEvent(vtkMRMLSelectionNode::AnnotationIDListModifiedEvent);
}
}
this->Modified();
}
//----------------------------------------------------------------------------
......@@ -387,7 +388,9 @@ void vtkMRMLSelectionNode::RemoveAnnotationIDFromList(const char *id)
this->SetActiveAnnotationID(NULL);
}
this->InvokeEvent(vtkMRMLSelectionNode::AnnotationIDListModifiedEvent);
}
this->Modified();
}
//----------------------------------------------------------------------------
std::string vtkMRMLSelectionNode::GetAnnotationIDByIndex(int n)
{
......@@ -443,3 +446,10 @@ std::string vtkMRMLSelectionNode::GetAnnotationResourceByID(std::string id)
}
return resource;
}
//----------------------------------------------------------------------------
void vtkMRMLSelectionNode::SetReferenceActiveAnnotationID (const char *id)
{
this->SetActiveAnnotationID(id);
this->InvokeEvent(vtkMRMLSelectionNode::ActiveAnnotationIDChangedEvent);
}
......@@ -89,11 +89,15 @@ class VTK_MRML_EXPORT vtkMRMLSelectionNode : public vtkMRMLNode
void SetActiveFiducialListID(const char* id);
void SetReferenceActiveFiducialListID (const char *id) { this->SetActiveFiducialListID(id); };
///
/// the ID of a MRMLAnnotationNode
/// Set/Get the classname of the active annotation type.
/// The active annotation is used to control what annotation is being
/// dropped by the user.
vtkGetStringMacro (ActiveAnnotationID);
void SetActiveAnnotationID(const char* id);
void SetReferenceActiveAnnotationID (const char *id) { this->SetActiveAnnotationID(id); this->InvokeEvent(vtkMRMLSelectionNode::ActiveAnnotationIDChangedEvent); };
/// Set the active annotation id and fire the event
/// ActiveAnnotationIDChangedEvent.
void SetReferenceActiveAnnotationID (const char *id);
/// the ID of a MRMLROIList
vtkGetStringMacro (ActiveROIListID);
......
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