Commit 5f56a12d authored by benjamin.long's avatar benjamin.long

ENH: Add Qt Testing support

Expose signals/slots on some widget APIs for qttesting recording/replay

git-svn-id: http://svn.slicer.org/Slicer4/trunk@19959 3bd1e089-480b-0410-8dfb-8563597acbee
parent 88850670
......@@ -74,6 +74,21 @@
namespace
{
#ifdef Slicer_USE_QtTesting
//-----------------------------------------------------------------------------
void setEnableQtTesting(int argc, char* argv[])
{
for (int i = 0; i < argc; ++i)
{
if (qstrcmp(argv[i], "--qt-testing") == 0)
{
QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuBar);
break;
}
}
}
#endif
#ifdef Slicer_USE_PYTHONQT
//----------------------------------------------------------------------------
......@@ -209,6 +224,10 @@ int SlicerAppMain(int argc, char* argv[])
QApplication::setDesktopSettingsAware(false);
QApplication::setStyle(new qSlicerStyle);
#ifdef Slicer_USE_QtTesting
setEnableQtTesting(argc, argv);
#endif
qSlicerApplication app(argc, argv);
if (app.returnCode() != -1)
{
......
......@@ -59,6 +59,9 @@
<string>&amp;Edit</string>
</property>
<addaction name="actionEditApplicationSettings"/>
<addaction name="separator"/>
<addaction name="actionEditRecordMacro"/>
<addaction name="actionEditPlayMacro"/>
</widget>
<widget class="QMenu" name="menuView">
<property name="title">
......@@ -1085,6 +1088,22 @@
<string>4x4 viewers</string>
</property>
</action>
<action name="actionEditRecordMacro">
<property name="text">
<string>Record Macro</string>
</property>
<property name="visible">
<bool>false</bool>
</property>
</action>
<action name="actionEditPlayMacro">
<property name="text">
<string>Play Macro</string>
</property>
<property name="visible">
<bool>false</bool>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
......
......@@ -61,6 +61,17 @@ slicer_add_python_test(SCRIPT SlicerTestingExitSuccessTest.py)
slicer_add_python_test(SCRIPT SlicerTestingExitFailureTest.py)
set_tests_properties(py_SlicerTestingExitFailureTest PROPERTIES WILL_FAIL TRUE)
#
# Check if Tutorial work as expected
#
#if(Slicer_USE_QtTesting)
# slicer_add_python_test(
# SCRIPT SlicerQtTestingDTITutorial.py
# SLICER_ARGS --launcher-no-splash --qt-testing)
#endif()
#
# Check if 'slicer.testing.runUnitTest()' works as expected
#
......
......@@ -29,6 +29,7 @@
#include <QMenu>
#include "qSlicerApplication.h" // Indirectly includes vtkSlicerConfigure.h
#include "vtkSlicerConfigure.h" // For Slicer_USE_PYTHONQT and Slicer_USE_QtTesting
// CTK includes
#include <ctkErrorLogWidget.h>
......@@ -36,6 +37,9 @@
#ifdef Slicer_USE_PYTHONQT
# include <ctkPythonConsole.h>
#endif
#ifdef Slicer_USE_QtTesting
#include <ctkQtTestingUtility.h>
#endif
#include <ctkSettingsDialog.h>
#include <ctkVTKSliceView.h>
......@@ -43,6 +47,10 @@
#include "qSlicerAppMainWindow.h"
#include "ui_qSlicerAppMainWindow.h"
#include "qSlicerAbstractModule.h"
#if defined Slicer_USE_QtTesting && defined Slicer_BUILD_CLI_SUPPORT
#include "qSlicerCLIModuleWidgetEventPlayer.h"
#endif
#include "qSlicerCommandOptions.h"
#include "qSlicerCoreCommandOptions.h"
#ifdef Slicer_BUILD_EXTENSIONMANAGER_SUPPORT
# include "qSlicerExtensionsManagerDialog.h"
......@@ -247,6 +255,11 @@ void qSlicerAppMainWindowPrivate::setupUi(QMainWindow * mainWindow)
this->LayoutManager->setScriptedDisplayableManagerDirectory(
qSlicerApplication::application()->slicerHome() + "/bin/Python/mrmlDisplayableManager");
qSlicerApplication::application()->setLayoutManager(this->LayoutManager);
#ifdef Slicer_USE_QtTesting
// we store this layout manager to the Object state property for QtTesting
qSlicerApplication::application()->testingUtility()->addObjectStateProperty(
qSlicerApplication::application()->layoutManager(), QString("layout"));
#endif
// Layout manager should also listen the MRML scene
this->LayoutManager->setMRMLScene(qSlicerApplication::application()->mrmlScene());
QObject::connect(qSlicerApplication::application(),
......@@ -263,6 +276,7 @@ void qSlicerAppMainWindowPrivate::setupUi(QMainWindow * mainWindow)
// Add menus for configuring compare view
QMenu *compareMenu = new QMenu(q->tr("Select number of viewers..."));
compareMenu->setObjectName("CompareMenuView");
compareMenu->addAction(this->actionViewLayoutCompare_2_viewers);
compareMenu->addAction(this->actionViewLayoutCompare_3_viewers);
compareMenu->addAction(this->actionViewLayoutCompare_4_viewers);
......@@ -276,6 +290,7 @@ void qSlicerAppMainWindowPrivate::setupUi(QMainWindow * mainWindow)
// ... and for widescreen version of compare view as well
compareMenu = new QMenu(q->tr("Select number of viewers..."));
compareMenu->setObjectName("CompareMenuWideScreen");
compareMenu->addAction(this->actionViewLayoutCompareWidescreen_2_viewers);
compareMenu->addAction(this->actionViewLayoutCompareWidescreen_3_viewers);
compareMenu->addAction(this->actionViewLayoutCompareWidescreen_4_viewers);
......@@ -289,6 +304,7 @@ void qSlicerAppMainWindowPrivate::setupUi(QMainWindow * mainWindow)
// ... and for the grid version of the compare views
compareMenu = new QMenu(q->tr("Select number of viewers..."));
compareMenu->setObjectName("CompareMenuGrid");
compareMenu->addAction(this->actionViewLayoutCompareGrid_2x2_viewers);
compareMenu->addAction(this->actionViewLayoutCompareGrid_3x3_viewers);
compareMenu->addAction(this->actionViewLayoutCompareGrid_4x4_viewers);
......@@ -370,6 +386,21 @@ void qSlicerAppMainWindowPrivate::setupUi(QMainWindow * mainWindow)
#ifdef Slicer_BUILD_EXTENSIONMANAGER_SUPPORT
this->ExtensionsManagerDialog = new qSlicerExtensionsManagerDialog(q);
#endif
//----------------------------------------------------------------------------
// Update UI considering build options
//----------------------------------------------------------------------------
#if defined Slicer_USE_QtTesting && defined Slicer_BUILD_CLI_SUPPORT
if (qSlicerApplication::application()->commandOptions()->enableQtTesting())
{
this->actionEditPlayMacro->setVisible(true);
this->actionEditRecordMacro->setVisible(true);
qSlicerApplication::application()->testingUtility()->addPlayer(
new qSlicerCLIModuleWidgetEventPlayer());
}
#endif
}
//-----------------------------------------------------------------------------
......@@ -556,6 +587,8 @@ void qSlicerAppMainWindow::setupMenuActions()
this->connect(d->actionFileExit, SIGNAL(triggered()),
this, SLOT(close()));
qSlicerAppMainWindowCore_connect(EditRecordMacro);
qSlicerAppMainWindowCore_connect(EditPlayMacro);
qSlicerAppMainWindowCore_connect(EditUndo);
qSlicerAppMainWindowCore_connect(EditRedo);
......@@ -731,6 +764,7 @@ void qSlicerAppMainWindow::onModuleLoaded(const QString& moduleName)
}
}
d->ModuleToolBar->insertAction(beforeAction, action);
action->setParent(d->ModuleToolBar);
}
}
......
......@@ -30,7 +30,10 @@
#include <ctkErrorLogWidget.h>
#include <ctkMessageBox.h>
#ifdef Slicer_USE_PYTHONQT
#include <ctkPythonConsole.h>
# include <ctkPythonConsole.h>
#endif
#ifdef Slicer_USE_QtTesting
# include <ctkQtTestingUtility.h>
#endif
......@@ -248,6 +251,33 @@ void qSlicerAppMainWindowCore::onFileCloseSceneActionTriggered()
qSlicerCoreApplication::application()->mrmlScene()->Clear(false);
}
//---------------------------------------------------------------------------
void qSlicerAppMainWindowCore::onEditRecordMacroActionTriggered()
{
#ifdef Slicer_USE_QtTesting
QString filename = QFileDialog::getSaveFileName(this->widget(), "Macro File Name",
QString(), "XML Files (*.xml)");
if (!filename.isEmpty())
{
qSlicerApplication::application()->testingUtility()->recordTests(filename);
}
#endif
}
//---------------------------------------------------------------------------
void qSlicerAppMainWindowCore::onEditPlayMacroActionTriggered()
{
#ifdef Slicer_USE_QtTesting
qSlicerApplication::application()->testingUtility()->openPlayerDialog();
// QString filename = QFileDialog::getOpenFileName(this->widget(), "Test File Name",
// QString(), "XML Files (*.xml)");
// if (!filename.isEmpty())
// {
// d->TestUtility.playTests(filename);
// }
#endif
}
//---------------------------------------------------------------------------
void qSlicerAppMainWindowCore::onEditUndoActionTriggered()
{
......
......@@ -63,6 +63,8 @@ public slots:
void onSDBZipDirectoryActionTriggered();
void onSDBZipToDCMActionTriggered();
void onFileCloseSceneActionTriggered();
void onEditRecordMacroActionTriggered();
void onEditPlayMacroActionTriggered();
void onEditUndoActionTriggered();
void onEditRedoActionTriggered();
void setLayout(int);
......
import slicer
import slicer.testing
import slicer.util
filepath = os.environ['SLICER_HOME'] + '/../../Slicer4/Applications/SlicerQT/Testing/QtTesting/UnitTest_DTI_DWI.xml'
testUtility = slicer.app.testingUtility()
success = testUtility.playTests(filepath)
if success :
slicer.util.exit(EXIT_SUCCESS)
else:
slicer.util.exit(EXIT_FAILURE)
This diff is collapsed.
......@@ -76,6 +76,16 @@ set(KIT_target_libraries
MRMLCLI
)
if(Slicer_USE_QtTesting)
list(APPEND KIT_SRCS
qSlicerCLIModuleWidgetEventPlayer.cxx
qSlicerCLIModuleWidgetEventPlayer.h
)
list(APPEND KIT_MOC_SRCS
qSlicerCLIModuleWidgetEventPlayer.h
)
endif()
SlicerMacroBuildBaseQtLibrary(
NAME ${PROJECT_NAME}
EXPORT_DIRECTIVE ${KIT_export_directive}
......
......@@ -352,13 +352,13 @@ void qSlicerCLIModuleWidget::setCurrentCommandLineModuleNode(
}
//-----------------------------------------------------------------------------
void qSlicerCLIModuleWidget::apply()
void qSlicerCLIModuleWidget::apply(bool wait)
{
Q_D(qSlicerCLIModuleWidget);
vtkMRMLCommandLineModuleNode* node = d->commandLineModuleNode();
Q_ASSERT(node);
d->CLIModuleUIHelper->updateMRMLCommandLineModuleNode(node);
this->run(node, /* waitForCompletion= */ false);
this->run(node, /* waitForCompletion= */ wait);
}
//-----------------------------------------------------------------------------
......
......@@ -55,7 +55,7 @@ public slots:
/// Set the current \a commandLineModuleNode
void setCurrentCommandLineModuleNode(vtkMRMLNode* commandLineModuleNode);
void apply();
void apply(bool wait = false);
void cancel();
void reset();
......
/*==============================================================================
Program: 3D Slicer
Copyright (c) Kitware Inc.
See COPYRIGHT.txt
or http://www.slicer.org/copyright/copyright.txt for details.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file was originally developed by Benjamin LONG, Kitware Inc.
and was partially funded by NIH grant 3P41RR013218-12S1
==============================================================================*/
// QT includes
#include <QDebug>
#include "qSlicerCLIModuleWidget.h"
#include "qSlicerCLIModuleWidgetEventPlayer.h"
// ----------------------------------------------------------------------------
qSlicerCLIModuleWidgetEventPlayer::qSlicerCLIModuleWidgetEventPlayer(QObject *parent)
: pqWidgetEventPlayer(parent)
{
}
// ----------------------------------------------------------------------------
bool qSlicerCLIModuleWidgetEventPlayer::playEvent(QObject *Object,
const QString &Command,
const QString &/*Arguments*/,
bool &Error)
{
// But in the CLI module under Slicer4 when we activate the button apply,
// we want to do apply and wait instead of apply !
if (Command != "activate")
{
return false;
}
qSlicerCLIModuleWidget* parent = NULL;
for(QObject* test = Object; parent == NULL && test != NULL; test = test->parent())
{
parent = qobject_cast<qSlicerCLIModuleWidget*>(test);
}
// This Command is mainly use for the QPushButton.
if (!parent || Object->objectName() != "ApplyPushButton")
{
return false;
}
if (parent)
{
if (Command == "activate")
{
qDebug() << "***************************** " << Object->objectName();
parent->apply(true);
return true;
}
}
qCritical() << "calling activate on unhandled type " << Object;
Error = true;
return true;
}
/*==============================================================================
Program: 3D Slicer
Copyright (c) Kitware Inc.
See COPYRIGHT.txt
or http://www.slicer.org/copyright/copyright.txt for details.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file was originally developed by Benjamin LONG, Kitware Inc.
and was partially funded by NIH grant 3P41RR013218-12S1
==============================================================================*/
#ifndef __qSlicerCLIModuleWidgetEventPlayer_h
#define __qSlicerCLIModuleWidgetEventPlayer_h
// QtTesting includes
#include <pqWidgetEventPlayer.h>
// QtCLI includes
#include "qSlicerBaseQTCLIExport.h"
class Q_SLICER_BASE_QTCLI_EXPORT qSlicerCLIModuleWidgetEventPlayer : public pqWidgetEventPlayer
{
Q_OBJECT
public:
qSlicerCLIModuleWidgetEventPlayer(QObject* parent = 0);
bool playEvent(QObject *Object, const QString &Command, const QString &Arguments, bool &Error);
private:
qSlicerCLIModuleWidgetEventPlayer(const qSlicerCLIModuleWidgetEventPlayer&); // NOT implemented
qSlicerCLIModuleWidgetEventPlayer& operator=(const qSlicerCLIModuleWidgetEventPlayer&); // NOT implemented
};
#endif // __qSlicerCLIModuleWidgetEventPlayer_h
......@@ -16,6 +16,9 @@
// PythonQt includes
#include <PythonQt.h>
// CTK includes
#include <ctkErrorLogModel.h>
// SlicerQt includes
#include "qSlicerCoreApplication.h"
#include "qSlicerAbstractCoreModule.h"
......@@ -38,6 +41,7 @@ public:
{
PythonQt::self()->registerClass(&qSlicerCoreApplication::staticMetaObject);
PythonQt::self()->registerClass(&qSlicerAbstractCoreModule::staticMetaObject);
PythonQt::self()->registerClass(&ctkErrorLogModel::staticMetaObject);
// Note: Use registerCPPClassForPythonQt to register pure Cpp classes
}
......
......@@ -78,6 +78,7 @@ QAction* qSlicerAbstractModule::action()
if (d->Action == 0)
{
d->Action = new QAction(this->icon(), this->title(), this);
d->Action->setObjectName(QString("action%1").arg(this->name()));
d->Action->setData(this->name());
d->Action->setIconVisibleInMenu(true);
d->Action->setProperty("index", this->index());
......
......@@ -23,11 +23,18 @@
#include <QDebug>
#include <QMainWindow>
#include "vtkSlicerConfigure.h" // For Slicer_USE_QtTesting
// CTK includes
#include <ctkColorDialog.h>
#include <ctkErrorLogModel.h>
#include <ctkMessageBox.h>
#include <ctkSettings.h>
#ifdef Slicer_USE_QtTesting
#include <ctkQtTestingUtility.h>
#include <ctkXMLEventObserver.h>
#include <ctkXMLEventSource.h>
#endif
#include <ctkToolTipTrapper.h>
// QTGUI includes
......@@ -51,6 +58,15 @@
// qMRMLWidget includes
#include "qMRMLEventBrokerConnection.h"
// qMRML includes
#ifdef Slicer_USE_QtTesting
#include <qMRMLCheckableNodeComboBoxEventPlayer.h>
#include <qMRMLNodeComboBoxEventPlayer.h>
#include <qMRMLNodeComboBoxEventTranslator.h>
#include <qMRMLTreeViewEventPlayer.h>
#include <qMRMLTreeViewEventTranslator.h>
#endif
// Logic includes
#include <vtkSlicerApplicationLogic.h>
......@@ -81,6 +97,9 @@ public:
qSlicerLayoutManager* LayoutManager;
ctkToolTipTrapper* ToolTipTrapper;
ctkSettingsDialog* SettingsDialog;
#ifdef Slicer_USE_QtTesting
ctkQtTestingUtility* TestingUtility;
#endif
};
......@@ -95,6 +114,9 @@ qSlicerApplicationPrivate::qSlicerApplicationPrivate(
this->LayoutManager = 0;
this->ToolTipTrapper = 0;
this->SettingsDialog = 0;
#ifdef Slicer_USE_QtTesting
this->TestingUtility = 0;
#endif
}
//-----------------------------------------------------------------------------
......@@ -102,6 +124,10 @@ qSlicerApplicationPrivate::~qSlicerApplicationPrivate()
{
delete this->SettingsDialog;
this->SettingsDialog = 0;
#ifdef Slicer_USE_QtTesing
delete this->TestingUtility;
this->TestingUtility = 0;
#endif
}
//-----------------------------------------------------------------------------
......@@ -150,6 +176,33 @@ void qSlicerApplicationPrivate::init()
QObject::connect(this->SettingsDialog, SIGNAL(accepted()),
q, SLOT(onSettingDialogAccepted()));
//----------------------------------------------------------------------------
// Test Utility
//----------------------------------------------------------------------------
#ifdef Slicer_USE_QtTesting
this->TestingUtility = new ctkQtTestingUtility(0);
this->TestingUtility->addEventObserver(
"xml", new ctkXMLEventObserver(this->TestingUtility));
ctkXMLEventSource* eventSource = new ctkXMLEventSource(this->TestingUtility);
eventSource->setRestoreSettingsAuto(
qSlicerApplication::testAttribute(qSlicerCoreApplication::AA_EnableTesting));
this->TestingUtility->addEventSource("xml", eventSource);
// Translator and Player for MRML widget
this->TestingUtility->addPlayer(
new qMRMLCheckableNodeComboBoxEventPlayer());
this->TestingUtility->addPlayer(
new qMRMLNodeComboBoxEventPlayer());
this->TestingUtility->addTranslator(
new qMRMLNodeComboBoxEventTranslator());
this->TestingUtility->addPlayer(
new qMRMLTreeViewEventPlayer());
this->TestingUtility->addTranslator(
new qMRMLTreeViewEventTranslator());
// Player for the CLI Module || cannot be added for the moment ...
#endif
}
/*
#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
......@@ -224,6 +277,15 @@ qSlicerPythonManager* qSlicerApplication::pythonManager()
}
#endif
#ifdef Slicer_USE_QtTesting
//-----------------------------------------------------------------------------
ctkQtTestingUtility* qSlicerApplication::testingUtility()
{
Q_D(const qSlicerApplication);
return d->TestingUtility;
}
#endif
//-----------------------------------------------------------------------------
void qSlicerApplication::setLayoutManager(qSlicerLayoutManager* layoutManager)
{
......
......@@ -44,6 +44,10 @@ class qSlicerPythonManager;
class qSlicerLayoutManager;
class qSlicerWidget;
#ifdef Slicer_USE_QtTesting
class ctkQtTestingUtility;
#endif
// MRML includes
class vtkMRMLNode;
......@@ -70,6 +74,11 @@ public:
Q_INVOKABLE qSlicerPythonManager * pythonManager();
#endif
#ifdef Slicer_USE_QtTesting
/// Get test utility
Q_INVOKABLE ctkQtTestingUtility* testingUtility();
#endif
/// Set/Get layout manager
Q_INVOKABLE qSlicerLayoutManager* layoutManager()const;
void setLayoutManager(qSlicerLayoutManager* layoutManager);
......
......@@ -16,6 +16,9 @@
// PythonQt includes
#include <PythonQt.h>
// CTK QtTesting includes
#include <ctkQtTestingUtility.h>
// SlicerQt includes
#include "qSlicerAbstractModuleRepresentation.h"
#include "qSlicerAbstractModuleWidget.h"
......@@ -44,6 +47,7 @@ public:
PythonQt::self()->registerClass(&qSlicerAbstractModuleWidget::staticMetaObject);
PythonQt::self()->registerClass(&qSlicerPythonManager::staticMetaObject);
PythonQt::self()->registerClass(&qSlicerCommandOptions::staticMetaObject);
PythonQt::self()->registerClass(&ctkQtTestingUtility::staticMetaObject);
// Note: Use registerCPPClassForPythonQt to register pure Cpp classes
}
......
......@@ -55,6 +55,12 @@ bool qSlicerCommandOptions::showPythonInteractor() const
return this->parsedArgs().value("show-python-interactor").toBool();
}
//-----------------------------------------------------------------------------
bool qSlicerCommandOptions::enableQtTesting()const
{
return this->parsedArgs().value("qt-testing").toBool();
}
//-----------------------------------------------------------------------------
void qSlicerCommandOptions::addArguments()
{
......@@ -76,4 +82,9 @@ void qSlicerCommandOptions::addArguments()
"Show Python interactor at startup.");
}
#endif
#ifdef Slicer_USE_QtTesting
this->addArgument("qt-testing", "", QVariant::Bool,
"Enable QtTesting in the user interface and disable the native Menu bar");
#endif
}
......@@ -35,6 +35,7 @@ class Q_SLICER_BASE_QTGUI_EXPORT qSlicerCommandOptions : public qSlicerCoreComma
Q_PROPERTY(bool disableToolTips READ disableToolTips)
Q_PROPERTY(bool noMainWindow READ noMainWindow)
Q_PROPERTY(bool showPythonInteractor READ showPythonInteractor)
Q_PROPERTY(bool enableQtTesting READ enableQtTesting)
public:
typedef qSlicerCoreCommandOptions Superclass;
qSlicerCommandOptions();
......@@ -48,6 +49,8 @@ public:
bool showPythonInteractor()const;
bool enableQtTesting()const;
protected:
virtual void addArguments();
......
......@@ -242,6 +242,7 @@ bool qSlicerStandardFileDialog::exec(const qSlicerIO::IOProperties& ioProperties
delete options;
options = 0;
}
delete fileDialog;
return res;
}
......
......@@ -30,8 +30,6 @@
#include "qMRMLSliceWidget.h"
#include "qSlicerMouseModeToolBar_p.h"
// CTK includes
// SlicerLogic includes
#include <vtkSlicerApplicationLogic.h>
......@@ -68,6 +66,7 @@ void qSlicerMouseModeToolBarPrivate::init()
// RotateMode action
this->ViewTransformModeAction = new QAction(q);
this->ViewTransformModeAction->setObjectName("MouseRotateMode");
this->ViewTransformModeAction->setIcon(QIcon(":/Icons/MouseRotateMode.png"));
this->ViewTransformModeAction->setText("&Rotate");
this->ViewTransformModeAction->setToolTip("Set the 3DViewer mouse mode to transform view (use drop down menu to place Annotations)");
......@@ -103,6 +102,7 @@ void qSlicerMouseModeToolBarPrivate::init()
// popuplate the create and place menu, with persistence first
this->CreateAndPlaceMenu = new QMenu(QObject::tr("Create and Place"), q);
this->CreateAndPlaceMenu->setObjectName("CreateAndPlaceMenu");
this->CreateAndPlaceMenu->addAction(this->PersistenceAction);
this->CreateAndPlaceMenu->addSeparator();
this->CreateAndPlaceMenu->addActions(this->ActionGroup->actions());
......@@ -110,6 +110,7 @@ void qSlicerMouseModeToolBarPrivate::init()
this->CreateAndPlaceToolButton = new QToolButton();
this->CreateAndPlaceToolButton->setObjectName("CreateAndPlaceToolButton");
this->CreateAndPlaceToolButton->setToolButtonStyle(Qt::ToolButtonIconOnly);
this->CreateAndPlaceToolButton->setToolTip(QObject::tr("Create and Place"));
this->CreateAndPlaceToolButton->setText(QObject::tr("Place"));
......@@ -278,6 +279,7 @@ void qSlicerMouseModeToolBarPrivate::updateWidgetFromSelectionNode()
{
// add it
QAction * newAction = new QAction(this->CreateAndPlaceMenu);
newAction->setObjectName(annotationID);
newAction->setIcon(QIcon(annotationResource));