Commit 0abe92e9 authored by Emmanuel Promayon's avatar Emmanuel Promayon

NEW nogui example now successful + nogui test + safeguard around all...

NEW nogui example now successful + nogui test + safeguard around all Application::getViewer(Viewer*)

The nogui application is an example of an single independent program that
uses CamiTK to load an image, apply a CamiTK action and save the resulting image to file.
Safeguards around Application::getViewer(Viewer*) avoid possible crashes while
providing error messages.
Note: the nogui success is now automatically tested as well
parent 78956437
......@@ -122,7 +122,10 @@ void AnglesAndTranslationAction::update() {
// update central viewer
MedicalImageViewer::LayoutVisibility visibleViewer = static_cast<MedicalImageViewer::LayoutVisibility>(property("Visible Viewer").toInt());
dynamic_cast<MedicalImageViewer*>(Application::getViewer("Medical Image Viewer"))->setVisibleViewer(visibleViewer);
MedicalImageViewer* medicalImageViewer = dynamic_cast<MedicalImageViewer*>(Application::getViewer("Medical Image Viewer"));
if (medicalImageViewer != nullptr) {
medicalImageViewer->setVisibleViewer(visibleViewer);
}
// keep property up-to-date when the GUI will change
blockEvent = false;
......
......@@ -75,22 +75,25 @@ PixelColorChanger::PixelColorChanger(ActionExtension* extension) : Action(extens
isConnected = false;
}
QWidget* PixelColorChanger::getWidget() {
if (!isConnected) {
//-- run the action every time a picking is done in the axial/sagittal or coronal planes
QObject::connect(Application::getViewer("Axial Viewer"), SIGNAL(selectionChanged()), this, SLOT(apply()));
QObject::connect(Application::getViewer("Coronal Viewer"), SIGNAL(selectionChanged()), this, SLOT(apply()));
QObject::connect(Application::getViewer("Sagittal Viewer"), SIGNAL(selectionChanged()), this, SLOT(apply()));
isConnected = true;
}
return Action::getWidget();
}
// --------------- destructor -------------------
PixelColorChanger::~PixelColorChanger() {
// do not delete the widget has it might have been used in the ActionViewer (i.e. the ownership might have been taken by the stacked widget)
}
// --------------- destructor -------------------
QWidget* PixelColorChanger::getWidget() {
if (!isConnected) {
if (Application::getViewer("Axial Viewer") != nullptr) {
//-- run the action every time a picking is done in the axial/sagittal or coronal planes
QObject::connect(Application::getViewer("Axial Viewer"), SIGNAL(selectionChanged()), this, SLOT(apply()));
QObject::connect(Application::getViewer("Coronal Viewer"), SIGNAL(selectionChanged()), this, SLOT(apply()));
QObject::connect(Application::getViewer("Sagittal Viewer"), SIGNAL(selectionChanged()), this, SLOT(apply()));
isConnected = true;
}
}
return Action::getWidget();
}
// --------------- apply -------------------
Action::ApplyStatus PixelColorChanger::apply() {
// check if widget is still visible, otherwise disconnect action
......@@ -218,11 +221,14 @@ Action::ApplyStatus PixelColorChanger::apply() {
QApplication::restoreOverrideCursor();
}
else {
// disconnect
QObject::disconnect(Application::getViewer("Axial Viewer"), SIGNAL(selectionChanged()), this, SLOT(apply()));
QObject::disconnect(Application::getViewer("Coronal Viewer"), SIGNAL(selectionChanged()), this, SLOT(apply()));
QObject::disconnect(Application::getViewer("Sagittal Viewer"), SIGNAL(selectionChanged()), this, SLOT(apply()));
isConnected = false;
if (Application::getViewer("Axial Viewer") != nullptr) {
// disconnect
QObject::disconnect(Application::getViewer("Axial Viewer"), SIGNAL(selectionChanged()), this, SLOT(apply()));
QObject::disconnect(Application::getViewer("Coronal Viewer"), SIGNAL(selectionChanged()), this, SLOT(apply()));
QObject::disconnect(Application::getViewer("Sagittal Viewer"), SIGNAL(selectionChanged()), this, SLOT(apply()));
isConnected = false;
}
}
return SUCCESS;
}
......@@ -358,7 +358,6 @@ Action::ApplyStatus ReorientImage::process(ImageComponent* image) {
result->setFrameVisibility("3D Viewer", true);
}
Application::getViewer("3D Viewer")->refresh();
Application::refresh();
......
......@@ -4,7 +4,6 @@ camitk_extension(ACTION_EXTENSION
CEP_NAME SDK
DESCRIPTION "Use ray tracing to produce a 3D reprensation of the image"
NEEDS_VIEWER_EXTENSION interactivegeometryviewer
NEEDS_VIEWER_EXTENSION interactivegeometryviewer
ENABLE_AUTO_TEST
TEST_FILES Mesh.off brain.mha sinus.mhd
)
......
......@@ -22,8 +22,15 @@
*
* $CAMITK_LICENCE_END$
****************************************************************************/
#include "VolumeRenderingAction.h"
// -- CamiTK
#include <Application.h>
#include <MeshComponent.h>
#include <InteractiveGeometryViewer.h>
#include <Log.h>
// -- vtk stuff --
#include <vtkImageCast.h>
#include <vtkVolume.h>
......@@ -49,12 +56,6 @@
#include <vtkPoints.h>
#include <vtkPolyData.h>
// -- Application --
#include <Application.h>
#include <MeshComponent.h>
#include <RendererWidget.h>
#include <Log.h>
using namespace camitk;
......@@ -257,10 +258,12 @@ void VolumeRenderingAction::createVolumeRendering(ImageComponent* comp) {
// Add the new computed volume to the component and display it in the 3D viewer
comp->getVolumeRenderingChild()->addProp(volumeName, volume);
comp->getVolumeRenderingChild()->getProp(volumeName)->SetVisibility(true);
//Application::getViewer<InteractiveViewer>("3D Viewer")->getRendererWidget()->addProp(volume);
comp->getVolumeRenderingChild()->setVisibility("3D Viewer", true);
Application::getViewer("3D Viewer")->refresh();
InteractiveGeometryViewer* default3DViewer = dynamic_cast<InteractiveGeometryViewer*>(Application::getViewer("3D Viewer"));
if (default3DViewer != nullptr) {
default3DViewer->refresh();
}
}
......
......@@ -61,7 +61,10 @@ QWidget* Show3DViewer::getWidget() {
// --------------- apply -------------------
Action::ApplyStatus Show3DViewer::apply() {
dynamic_cast<MedicalImageViewer*>(Application::getViewer("Medical Image Viewer"))->setVisibleViewer(MedicalImageViewer::VIEWER_3D);
MedicalImageViewer* medicalImageViewer = dynamic_cast<MedicalImageViewer*>(Application::getViewer("Medical Image Viewer"));
if (medicalImageViewer != nullptr) {
medicalImageViewer->setVisibleViewer(MedicalImageViewer::VIEWER_3D);
}
Application::refresh();
return SUCCESS;
}
......@@ -60,7 +60,10 @@ QWidget* ShowAllViewers::getWidget() {
// --------------- apply -------------------
Action::ApplyStatus ShowAllViewers::apply() {
dynamic_cast<MedicalImageViewer*>(Application::getViewer("Medical Image Viewer"))->setVisibleViewer(MedicalImageViewer::VIEWER_ALL);
MedicalImageViewer* medicalImageViewer = dynamic_cast<MedicalImageViewer*>(Application::getViewer("Medical Image Viewer"));
if (medicalImageViewer != nullptr) {
medicalImageViewer->setVisibleViewer(MedicalImageViewer::VIEWER_ALL);
}
Application::refresh();
return SUCCESS;
}
......@@ -60,7 +60,10 @@ QWidget* ShowArbitraryViewer::getWidget() {
// --------------- apply -------------------
Action::ApplyStatus ShowArbitraryViewer::apply() {
dynamic_cast<MedicalImageViewer*>(Application::getViewer("Medical Image Viewer"))->setVisibleViewer(MedicalImageViewer::VIEWER_ARBITRARY);
MedicalImageViewer* medicalImageViewer = dynamic_cast<MedicalImageViewer*>(Application::getViewer("Medical Image Viewer"));
if (medicalImageViewer != nullptr) {
medicalImageViewer->setVisibleViewer(MedicalImageViewer::VIEWER_ARBITRARY);
}
Application::refresh();
return SUCCESS;
}
......@@ -60,7 +60,10 @@ QWidget* ShowAxialViewer::getWidget() {
// --------------- apply -------------------
Action::ApplyStatus ShowAxialViewer::apply() {
dynamic_cast<MedicalImageViewer*>(Application::getViewer("Medical Image Viewer"))->setVisibleViewer(MedicalImageViewer::VIEWER_AXIAL);
MedicalImageViewer* medicalImageViewer = dynamic_cast<MedicalImageViewer*>(Application::getViewer("Medical Image Viewer"));
if (medicalImageViewer != nullptr) {
medicalImageViewer->setVisibleViewer(MedicalImageViewer::VIEWER_AXIAL);
}
Application::refresh();
return SUCCESS;
}
......@@ -60,7 +60,10 @@ QWidget* ShowCoronalViewer::getWidget() {
// --------------- apply -------------------
Action::ApplyStatus ShowCoronalViewer::apply() {
dynamic_cast<MedicalImageViewer*>(Application::getViewer("Medical Image Viewer"))->setVisibleViewer(MedicalImageViewer::VIEWER_CORONAL);
MedicalImageViewer* medicalImageViewer = dynamic_cast<MedicalImageViewer*>(Application::getViewer("Medical Image Viewer"));
if (medicalImageViewer != nullptr) {
medicalImageViewer->setVisibleViewer(MedicalImageViewer::VIEWER_CORONAL);
}
Application::refresh();
return SUCCESS;
}
......@@ -60,7 +60,10 @@ QWidget* ShowSagittalViewer::getWidget() {
// --------------- apply -------------------
Action::ApplyStatus ShowSagittalViewer::apply() {
dynamic_cast<MedicalImageViewer*>(Application::getViewer("Medical Image Viewer"))->setVisibleViewer(MedicalImageViewer::VIEWER_SAGITTAL);
MedicalImageViewer* medicalImageViewer = dynamic_cast<MedicalImageViewer*>(Application::getViewer("Medical Image Viewer"));
if (medicalImageViewer != nullptr) {
medicalImageViewer->setVisibleViewer(MedicalImageViewer::VIEWER_SAGITTAL);
}
Application::refresh();
return SUCCESS;
}
......@@ -61,7 +61,11 @@ QWidget* MeshPicking::getWidget() {
informationLabel = new QLabel();
//-- run the action every time a picking is done in the axial/sagittal or coronal planes
QObject::connect(Application::getViewer("3D Viewer"), SIGNAL(selectionChanged()), this, SLOT(apply()));
InteractiveGeometryViewer* default3DViewer = dynamic_cast<InteractiveGeometryViewer*>(Application::getViewer("3D Viewer"));
if (default3DViewer != nullptr) {
QObject::connect(default3DViewer, SIGNAL(selectionChanged()), this, SLOT(apply()));
}
//-- the vertical layout, put every GUI elements in it
auto* informationFrameLayout = new QVBoxLayout();
......
......@@ -114,6 +114,7 @@ QWidget* RigidTransform::getWidget() {
//-- connect the custom pipeline to the selected Component
filterList.clear();
foreach (Component* comp, getTargets()) {
filterList.append(vtkSmartPointerTransformFilter::New());
filterList.last()->SetTransform(transformation);
......@@ -131,7 +132,12 @@ void RigidTransform::reset() {
//-- init values
double bounds[6];
dynamic_cast<InteractiveGeometryViewer*>(Application::getViewer("3D Viewer"))->getBounds(bounds);
InteractiveGeometryViewer* default3DViewer = dynamic_cast<InteractiveGeometryViewer*>(Application::getViewer("3D Viewer"));
if (default3DViewer != nullptr) {
default3DViewer->getBounds(bounds);
}
double xLength = bounds[1] - bounds[0];
double yLength = bounds[3] - bounds[2];
double zLength = bounds[5] - bounds[4];
......@@ -171,6 +177,7 @@ void RigidTransform::update(bool forceUpdate) {
double sx, sy, sz;
myUI.sY->setEnabled(!myUI.uniformScaling->isChecked());
myUI.sZ->setEnabled(!myUI.uniformScaling->isChecked());
if (myUI.uniformScaling->isChecked()) {
sx = double(myUI.sX->getValue());
sy = double(myUI.sX->getValue());
......@@ -181,10 +188,14 @@ void RigidTransform::update(bool forceUpdate) {
sy = double(myUI.sY->getValue());
sz = double(myUI.sZ->getValue());
}
transformation->Scale(sx, sy, sz);
// Refresh all the used viewers
Application::getViewer("3D Viewer")->refresh();
InteractiveGeometryViewer* default3DViewer = dynamic_cast<InteractiveGeometryViewer*>(Application::getViewer("3D Viewer"));
if (default3DViewer != nullptr) {
default3DViewer->refresh();
}
}
}
......@@ -194,9 +205,11 @@ Action::ApplyStatus RigidTransform::apply() {
// apply the transformation
unsigned int i = 0;
foreach (Component* comp, getTargets()) {
// get the result from the corresponding filter
vtkSmartPointer<vtkPointSet> result = vtkPointSet::SafeDownCast(filterList[i]->GetOutputDataObject(0));
if (result) {
comp->setPointSet(result);
comp->setModified();
......@@ -205,9 +218,11 @@ Action::ApplyStatus RigidTransform::apply() {
CAMITK_WARNING(tr("Filter output is of type: %1. Action aborted").arg(QString(filterList[i]->GetOutputDataObject(0)->GetClassName())))
return ABORTED;
}
// next filter
i++;
}
// disconnect everyone
close();
return SUCCESS;
......@@ -219,6 +234,7 @@ void RigidTransform::close() {
foreach (Component* comp, getTargets()) {
comp->setDataConnection(nullptr);
}
// hide the dialog
dialog->hide();
// Refresh all the used viewers
......@@ -238,6 +254,7 @@ void RigidTransform::load() {
if (!fn.isNull()) {
std::ifstream in(fn.toStdString().c_str());
double x, y, z, t;
for (unsigned int i = 0; i < 4; i++) {
in >> x >> y >> z >> t;
transformation->GetMatrix()->SetElement(i, 0, x);
......@@ -246,6 +263,7 @@ void RigidTransform::load() {
transformation->GetMatrix()->SetElement(i, 3, t);
}
}
myUI.tX->setValue(transformation->GetPosition()[0]);
myUI.tY->setValue(transformation->GetPosition()[1]);
myUI.tZ->setValue(transformation->GetPosition()[2]);
......@@ -262,12 +280,15 @@ void RigidTransform::load() {
void RigidTransform::save() {
// get the file name
QString fn = QFileDialog::getSaveFileName(dialog, "Save Current Transformation");
if (!fn.isNull()) {
std::ofstream out(fn.toStdString().c_str());
for (unsigned int i = 0; i < 4; i++) {
for (unsigned int j = 0; j < 4; j++) {
out << transformation->GetMatrix()->GetElement(i, j) << " ";
}
out << endl;
}
}
......
......@@ -77,47 +77,48 @@ MeshClipping::~MeshClipping() {
// --------------- getWidget -------------------
QWidget* MeshClipping::getWidget() {
//-- Customizing the action widget (specific UI, specific buttons...)
if (!widget) {
if (widget == nullptr) {
widget = new PlaneWidget(this);
customizeActionLayout();
}
//-- Creating the clipping plane widget (the first time getWidget() is called)
if (!widget->planeWidget) {
vtkRenderWindowInteractor* iren =
dynamic_cast<InteractiveGeometryViewer*>(Application::getViewer("3D Viewer"))
->getRendererWidget()->GetRenderWindow()->GetInteractor();
//-- Configure the plane widget including callbacks
widget->planeWidget =
vtkSmartPointer < vtkImplicitPlaneWidget >::New();
widget->planeWidget->SetInteractor(iren);
//-- Bounding box definition and placement
widget->planeWidget->SetPlaceFactor(1.5);
dynamic_cast<InteractiveGeometryViewer*>(Application::getViewer("3D Viewer"))->getBounds(limBounds);
widget->planeWidget->PlaceWidget(limBounds);
QVector3D origin((limBounds[1] + limBounds[0]) / 2,
(limBounds[3] + limBounds[2]) / 2,
(limBounds[5] + limBounds[4]) / 2);
QVector3D normal(0, 0, (limBounds[4] - limBounds[5]));
widget->planeWidget->SetNormal(normal.x(), normal.y(), normal.z());
widget->planeWidget->SetOrigin(origin.x(), origin.y(), origin.z());
widget->planeWidget->GetOutlineProperty()->SetColor(0, 0, 0);
widget->planeWidget->GetOutlineProperty()->SetLineWidth(1);
widget->planeWidget->GetPlaneProperty()->SetOpacity(0);
widget->planeWidget->UpdatePlacement();
//-- Widget Action Parameters
widget->planeWidget->OutlineTranslationOff();
widget->planeWidget->ScaleEnabledOff();
widget->planeWidget->AddObserver(vtkCommand::EndInteractionEvent, this->widget);
if (widget->planeWidget == nullptr) {
vtkRenderWindowInteractor* iren = nullptr;
InteractiveGeometryViewer* default3DViewer = dynamic_cast<InteractiveGeometryViewer*>(Application::getViewer("3D Viewer"));
if (default3DViewer != nullptr) {
default3DViewer->getRendererWidget()->GetRenderWindow()->GetInteractor();
//-- Configure the plane widget including callbacks
widget->planeWidget = vtkSmartPointer <vtkImplicitPlaneWidget>::New();
widget->planeWidget->SetInteractor(iren);
//-- Bounding box definition and placement
widget->planeWidget->SetPlaceFactor(1.5);
default3DViewer->getBounds(limBounds);
widget->planeWidget->PlaceWidget(limBounds);
QVector3D origin((limBounds[1] + limBounds[0]) / 2,
(limBounds[3] + limBounds[2]) / 2,
(limBounds[5] + limBounds[4]) / 2);
QVector3D normal(0, 0, (limBounds[4] - limBounds[5]));
widget->planeWidget->SetNormal(normal.x(), normal.y(), normal.z());
widget->planeWidget->SetOrigin(origin.x(), origin.y(), origin.z());
widget->planeWidget->GetOutlineProperty()->SetColor(0, 0, 0);
widget->planeWidget->GetOutlineProperty()->SetLineWidth(1);
widget->planeWidget->GetPlaneProperty()->SetOpacity(0);
widget->planeWidget->UpdatePlacement();
//-- Widget Action Parameters
widget->planeWidget->OutlineTranslationOff();
widget->planeWidget->ScaleEnabledOff();
widget->planeWidget->AddObserver(vtkCommand::EndInteractionEvent, this->widget);
}
}
else
else {
// just update the box
{
updateBox(false);
}
......@@ -146,10 +147,12 @@ Action::ApplyStatus MeshClipping::apply() {
if (list.size() != 0) {
//-- Clipping
Component* candidate;
foreach (candidate, list) {
if (candidate->isInstanceOf("MeshComponent")) {
if (allComponents || candidate->isSelected()) {
ApplyStatus clipStatus = clipMesh(dynamic_cast < MeshComponent* >(candidate), plane);
if (clipStatus == SUCCESS) {
// proceed and make sure to remove the vtk Widget of the screen if the component dies
connect(candidate, SIGNAL(destroyed()), this, SLOT(meshDeleted()));
......@@ -240,23 +243,30 @@ void MeshClipping::updateBox(bool refreshViewer) {
ComponentList list = Application::getTopLevelComponents();
(*list.begin())->getBounds(limBounds);
Component* currentComponent;
foreach (currentComponent, list) {
currentComponent->getBounds(currentBounds);
if (currentBounds[0] < limBounds[0]) {
limBounds[0] = currentBounds[0];
}
if (currentBounds[1] > limBounds[1]) {
limBounds[1] = currentBounds[1];
}
if (currentBounds[2] < limBounds[2]) {
limBounds[2] = currentBounds[2];
}
if (currentBounds[3] > limBounds[3]) {
limBounds[3] = currentBounds[3];
}
if (currentBounds[4] < limBounds[4]) {
limBounds[4] = currentBounds[4];
}
if (currentBounds[5] > limBounds[5]) {
limBounds[5] = currentBounds[5];
}
......@@ -278,12 +288,14 @@ void MeshClipping::updateBox(bool refreshViewer) {
Action::ApplyStatus MeshClipping::clipMesh(MeshComponent* mesh, vtkSmartPointer < vtkPlane > plane) {
vtkSmartPointer<vtkPointSet> meshPointSet = mesh->getPointSet();
int vtkObjectDataType = -1;
if (meshPointSet != NULL) {
vtkObjectDataType = meshPointSet->GetDataObjectType();
}
switch (vtkObjectDataType) {
case VTK_POLY_DATA:
//-- mesh is a vtkPolyData
if (smoothing) {
//-- smoothed clip
......@@ -294,6 +306,7 @@ Action::ApplyStatus MeshClipping::clipMesh(MeshComponent* mesh, vtkSmartPointer
filter->SetClipFunction(plane);
filter->Update();
mesh->setDataConnection(filter->GetOutputPort());
if (save) {
new MeshComponent(filter->GetOutput(), mesh->getName() + " clipped");
}
......@@ -307,14 +320,17 @@ Action::ApplyStatus MeshClipping::clipMesh(MeshComponent* mesh, vtkSmartPointer
filter->SetImplicitFunction(plane);
filter->Update();
mesh->setDataConnection(filter->GetOutputPort());
if (save) {
new MeshComponent(filter->GetOutput(), mesh->getName() + " clipped");
}
}
break;
case VTK_STRUCTURED_GRID:
case VTK_UNSTRUCTURED_GRID:
//-- mesh is a vtkUnstructuredGrid or vtkStructuredGrid
if (smoothing) {
//-- smoothed clip
......@@ -325,6 +341,7 @@ Action::ApplyStatus MeshClipping::clipMesh(MeshComponent* mesh, vtkSmartPointer
filter->SetClipFunction(plane);
filter->Update();
mesh->setDataConnection(filter->GetOutputPort());
if (save) {
new MeshComponent((vtkPointSet*)filter->GetOutput(), mesh->getName() + " clipped");
}
......@@ -337,11 +354,14 @@ Action::ApplyStatus MeshClipping::clipMesh(MeshComponent* mesh, vtkSmartPointer
filter->ExtractInsideOn();
filter->SetImplicitFunction(plane);
mesh->setDataConnection(filter->GetOutputPort());
if (save) {
new MeshComponent((vtkPointSet*)filter->GetOutput(), mesh->getName() + " clipped");
}
}
break;
default:
//-- Not implemented
CAMITK_WARNING(tr("Cannot clip mesh \"%1\": not a vtkPolyData, a vtkUnstructuredGrid nor a vtkStructuredGrid. Action aborted.").arg(mesh->getName()))
......@@ -356,9 +376,11 @@ Action::ApplyStatus MeshClipping::clipMesh(MeshComponent* mesh, vtkSmartPointer
// --------------- restoreMeshes -------------------
void MeshClipping::restoreMeshes() {
Component* candidate;
foreach (candidate, list) {
candidate->setDataConnection(candidate->getDataPort());
}
list.clear();
Application::refresh();
}
......@@ -369,12 +391,14 @@ void MeshClipping::changeVisibility() {
//- Updating button text
QPushButton* button = dynamic_cast< QPushButton* >(sender());
if (planeVisibility) {
button->setText("Hide clipping widget");
}
else {
button->setText("Show clipping widget");
}
Application::refresh();
}
......@@ -384,6 +408,7 @@ void MeshClipping::changeSmoothing() {
//- Updating button text
QPushButton* button = dynamic_cast< QPushButton* >(sender());
if (smoothing) {
button->setText(tr("Raw clipping"));
}
......@@ -401,16 +426,19 @@ void MeshClipping::changeAllComponents() {
//- Updating button text
QPushButton* button = dynamic_cast< QPushButton* >(sender());
if (allComponents) {
button->setText(tr("Clip Selected Components only"));
}
else {
button->setText(tr("Clip All Components"));
Component* candidate;
foreach (candidate, list) {
candidate->setDataConnection(candidate->getDataPort());
}
}
apply();
}
......
......@@ -161,12 +161,24 @@ void ActionStateMachine::autoNext() {
void ActionStateMachine::initMainWindow() {
mainWindow = new MainWindow(name);
mainWindow->setCentralViewer(Application::getViewer("Medical Image Viewer"));
MedicalImageViewer* medicalImageViewer = dynamic_cast<MedicalImageViewer*>(Application::getViewer("Medical Image Viewer"));
if (medicalImageViewer != nullptr) {
mainWindow->setCentralViewer(medicalImageViewer);
}
else {
CAMITK_ERROR("Cannot find \"Medical Image Viewer\". This viewer is mandatory for the action state machine application.")
}
mainWindow->addDockViewer(Qt::RightDockWidgetArea, Application::getViewer("Action State Viewer"));
mainWindow->addDockViewer(Qt::LeftDockWidgetArea, Application::getViewer("Explorer"));
Explorer *explorer = dynamic_cast<Explorer*>(Application::getViewer("Explorer"));
if (explorer != nullptr) {
mainWindow->addDockViewer(Qt::LeftDockWidgetArea, explorer);
}
else {
CAMITK_ERROR("Cannot find \"Explorer\" viewer. This viewer is mandatory for the action state machine application.")
}
// never show the toolbar
dynamic_cast<MedicalImageViewer*>(Application::getViewer("Medical Image Viewer"))->setToolbarAutoVisibility(false);
medicalImageViewer->setToolbarAutoVisibility(false);
mainWindow->showStatusBar(true);
this->setMainWindow(mainWindow);
......
......@@ -31,6 +31,10 @@
#include <ExtensionManager.h>
#include <SettingsDialog.h>
#include <Component.h>
#include <MedicalImageViewer.h>
#include <Explorer.h>
#include <FrameExplorer.h>
#include <PropertyExplorer.h>
#include <ActionViewer.h>
#include <Action.h>
#include <Viewer.h>
......@@ -70,23 +74,56 @@ ImpMainWindow::ImpMainWindow() : MainWindow("imp") {
updateActionStates();
// now add the different viewers
setCentralViewer(Application::getViewer("Medical Image Viewer"));
addDockViewer(Qt::LeftDockWidgetArea, Application::getViewer("Explorer"));
addDockViewer(Qt::LeftDockWidgetArea, Application::getViewer("Frame Explorer"));
addDockViewer(Qt::LeftDockWidgetArea, Application::getViewer("Property Explorer"));
addDockViewer(Qt::RightDockWidgetArea, Application::getViewer("Action Viewer"));
MedicalImageViewer* medicalImageViewer = dynamic_cast<MedicalImageViewer*>(Application::getViewer("Medical Image Viewer"));
if (medicalImageViewer != nullptr) {
setCentralViewer(medicalImageViewer);
}
else {
CAMITK_ERROR(tr("Cannot find \"Medical Image Viewer\". This viewer is mandatory for running camitk-imp."))
}
Explorer* explorer = dynamic_cast<Explorer*>(Application::getViewer("Explorer"));
if (explorer != nullptr) {
addDockViewer(Qt::LeftDockWidgetArea, explorer);
}
else {
CAMITK_ERROR(tr("Cannot find \"Explorer\" viewer. This viewer is mandatory for running camitk-imp."))
}
FrameExplorer* frameExplorer = dynamic_cast<FrameExplorer*>(Application::getViewer("Frame Explorer"));
if (frameExplorer != nullptr) {
addDockViewer(Qt::LeftDockWidgetArea, frameExplorer);
}
else {
CAMITK_ERROR(tr("Cannot find \"Frame Explorer\" viewer. This viewer is mandatory for running camitk-imp."))
}
PropertyExplorer* propertyExplorer = dynamic_cast<PropertyExplorer*>(Application::getViewer("Property Explorer"));
if (frameExplorer != nullptr) {
addDockViewer(Qt::LeftDockWidgetArea, propertyExplorer);
}
else {
CAMITK_ERROR(tr("Cannot find \"Property Explorer\" viewer. This viewer is mandatory for running camitk-imp."))
}
ActionViewer* actionViewer = dynamic_cast<ActionViewer*>(Application::getViewer("Action Viewer"));
if (actionViewer != nullptr) {
addDockViewer(Qt::RightDockWidgetArea, actionViewer);
actionViewer->setSearchPanelVisible(true);
showDockViewer(actionViewer, false);
}
else {
CAMITK_ERROR(tr("Cannot find \"Action Viewer\". This viewer is mandatory for running camitk-imp."))
}
// Merge Explorer and FrameExplorer viewers in one layout
QDockWidget* dockWidgetExplorer = dockWidgetMap.value(Application::getViewer("Explorer"), nullptr);
QDockWidget* dockWidgetFrameExplorer = dockWidgetMap.value(Application::getViewer("Frame Explorer"), nullptr);
QDockWidget* dockWidgetExplorer = dockWidgetMap.value(explorer, nullptr);
QDockWidget* dockWidgetFrameExplorer = dockWidgetMap.value(frameExplorer, nullptr);
if (dockWidgetExplorer != nullptr && dockWidgetFrameExplorer != nullptr) {
tabifyDockWidget(dockWidgetExplorer, dockWidgetFrameExplorer);
dockWidgetExplorer->raise();
}
showDockViewer(Application::getViewer("Action Viewer"), false);
dynamic_cast<ActionViewer*>(Application::getViewer("Action Viewer"))->setSearchPanelVisible(true);
showStatusBar(true);
}