Files
2026-01-07 01:46:55 +01:00

720 lines
25 KiB
C++

#include "mainw.h"
#include "ui_mainw.h"
#include "gRen.h"
#include <qsettings.h>
#include <QDebug>
#include <QApplication>
#include <vtkDICOMImageReader.h>
#include <qapplication.h>
// setupUi
void MainWindow::onSkullMaskingUpdt(QString msg, double val){
// SkullRemovalWorker already emits progress in percent [0..100]
Ui->progBar->setValue(static_cast<int>(val));
QMetaObject::invokeMethod(Ui->statusbar, "showMessage", Qt::QueuedConnection,
Q_ARG(QString, msg ),
Q_ARG(int, 0));
return;
}
void MainWindow::call_quit(){
loadPatient_thread->quit();
localize_thread->quit();
skull_thread->quit();
sleep(1);
//Sleep(100);
cout<< "Bye bye" <<endl;
QApplication::quit();
return;
}
void MainWindow::call_quit_nothreads(){
// Sleep(100);
sleep(1);
cout<< "Bye bye" <<endl;
QApplication::quit();
return;
}
void MainWindow::onVirtualIsoTested(bool IsoV){
Ui->l_isoV->clear();
(IsoV == true? Ui->l_isoV->setText("Yes") : Ui->l_isoV->setText("No") );
return;
}
void MainWindow::showEvent(QShowEvent* e)
{
QMainWindow::showEvent(e);
static bool done = false;
if (done) return;
done = true;
Visualizer->init();
}
#include <vtkGenericOpenGLRenderWindow.h>
#include <QTimer>
#include <QFileDialog>
#include <QMessageBox>
MainWindow::MainWindow(QString p_loadPath){
Ui = new Ui_MainWindow;
Ui->setupUi(this);
this->retranslateUi(Ui,this);
this->connectUi(Ui);
Ui->actionVolRen->setEnabled(false);
Ui->actionOrthoslice->setEnabled(false);
Ui->pushButton_3->setEnabled(false);
Ui->pb_manualMask->setEnabled(false);
Ui->pushButton_5->setEnabled(false);
auto rw = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
Ui->qvtk->setRenderWindow(rw);
Visualizer= new gRen(Ui->qvtk);
loadPatient = new DicomScanWorker;
loadPatient_thread = new QThread;
loadPatient->moveToThread(loadPatient_thread);
loadPatient_thread->start();
// Volume preparation worker (detaches volumes from the loader thread)
volumePrep = new VolumePrepWorker;
volumePrep_thread = new QThread;
volumePrep->moveToThread(volumePrep_thread);
volumePrep_thread->start();
qRegisterMetaType< gPatientRTGeneralInfos* >("gPatientRTGeneralInfos *");
qRegisterMetaType< std::vector<std::string> >("std::vector<std::string>");
qRegisterMetaType< std::string >("std::string");
qRegisterMetaType< vtkImageData* >("vtkImageData*");
qRegisterMetaType < QList<bool> > ("QList<bool>");
// For queued cross-thread signal/slot connections
qRegisterMetaType<Marker>("Marker");
qRegisterMetaType<MarkerList>("MarkerList");
qRegisterMetaType<LocalizationParams>("LocalizationParams");
connect(loadPatient, SIGNAL(loadEnd(vtkImageData*)), volumePrep, SLOT(run(vtkImageData* )));
connect(volumePrep, SIGNAL(finished(vtkImageData*)), Visualizer, SLOT(loadVolume (vtkImageData* )));
connect(loadPatient, SIGNAL(folderIsEmpty()),this,SLOT(onParsedEmptyFolder()));
connect(loadPatient, SIGNAL(parse_result(int , gPatientRTGeneralInfos* )),this,SLOT(onParsedOK(int , gPatientRTGeneralInfos* )));
connect(loadPatient, SIGNAL(loadedRTIso(double*)),this,SLOT(onRTIsoAvailable(double*)));
connect(loadPatient, SIGNAL(loadedVolBBox(double*, double*, int*)),this,SLOT(onCTVolumeAvailable(double*,double*,int*)));
connect(loadPatient, SIGNAL(virtualIsoTested(bool)),this,SLOT(onVirtualIsoTested(bool)));
localize_thread = new QThread;
localize_marker = new LocalizationWorker;
localize_marker->moveToThread(localize_thread);
localize_thread->start();
connect(localize_marker, SIGNAL(finished(MarkerList)), this, SLOT(onLocalizationEnd(MarkerList)));
connect(localize_marker, SIGNAL(progress(double)), this, SLOT(onLocalizationProgress(double)));
connect(localize_marker, SIGNAL(aborted()), this, SLOT(onLocalizationAborted()));
connect(localize_marker, SIGNAL(failed(QString)), this, SLOT(onLocalizationError(QString)));
skullRemoval = new SkullRemovalWorker;
skull_thread= new QThread;
skullRemoval->moveToThread(skull_thread);
skull_thread->start();
// Handle result in MainWindow and forward to the renderer from the GUI thread.
connect(skullRemoval, SIGNAL(skull_mask_end(vtkImageData *)),this,SLOT(onAutoSkullMaskEnd(vtkImageData* )));
connect(skullRemoval, SIGNAL(errMsg(QString)),this,SLOT(onAutoMaskError(QString )));
connect(skullRemoval, SIGNAL(skull_mask_upd(QString , double )), this, SLOT(onSkullMaskingUpdt(QString,double)));
treeModel = new QStandardItemModel;
connect(treeModel,SIGNAL(itemChanged(QStandardItem*)),this,SLOT(onItemChanged(QStandardItem*)));
connect(Ui->viewGroup, SIGNAL(triggered(QAction*)), this, SLOT(onVisualizationTrigger(QAction* )));
connect(Ui->pb_manualMask, SIGNAL(toggled ( bool )), this, SLOT(onManualMaskTrigger(bool)));
#if MULTIPLE_REF
connect(Ui->refGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(onRefTrigger(QAbstractButton*)));
#endif
loadDialog = new gLoadPatDialog;
connect(Visualizer, SIGNAL(PatientLoaded()),this,SLOT(onPatientlLoaded()));
QSettings *config = new QSettings ("config.ini",QSettings::IniFormat);
pathIn = config->value("Path/inDir").toString();
pathOut = config->value("Path/outDir").toString();
/*default values*/
Ui->spinBox->setValue(config->value("fiducialsLocalize/markerIntensity").toInt());
Ui->doubleSpinBox_2->setValue(config->value("fiducialsLocalize/boxDiag_down").toDouble());
Ui->doubleSpinBox_2bis->setValue(config->value("fiducialsLocalize/boxDiag_up").toDouble());
Ui->doubleSpinBox_3->setValue(config->value("fiducialsLocalize/hausdDist").toDouble());
Ui->doubleSpinBox_5->setValue(config->value("fiducialsLocalize/boxSidesDiff").toDouble());
regGrownParameters[0]=config->value("skullMask/regGrow_up").toDouble();
regGrownParameters[1]=config->value("skullMask/regGrow_down").toDouble();
delete config;
// (Legacy signal kept in old versions; replaced by LocalizationWorker::aborted())
connect(loadPatient,SIGNAL(referenceChange(double, double, double )),
Visualizer,SLOT(onReferenceChange(double, double , double)));
connect(loadPatient,SIGNAL(referenceChange(double, double, double )),
this,SLOT(updateMarkerPos(double, double , double)));
/*load passed workdir if any*/
loadPath.clear();
/*first check for argv [1]*/
if(p_loadPath.isEmpty()) {
/*then check for ini inDir*/
if(!pathIn.isEmpty())
loadPath=pathIn;
} else
loadPath=p_loadPath;
if(loadPath.isEmpty()){
cout<< "loadpath is emty" <<endl;
} else {
loadDialog->show();
cout<< "loadPath: "<<loadPath.toLatin1().constData() <<endl;
QApplication::setOverrideCursor(Qt::WaitCursor);
QMetaObject::invokeMethod(loadPatient, "load", Qt::QueuedConnection,
Q_ARG(QString, loadPath));
}
return;
}
MainWindow::~MainWindow(){
// Stop worker threads... post abort first so worker loops can exit.
if (localize_marker) {
QMetaObject::invokeMethod(localize_marker, "abort", Qt::QueuedConnection);
}
if (localize_thread) {
localize_thread->quit();
localize_thread->wait();
}
if (skull_thread) {
skull_thread->quit();
skull_thread->wait();
}
if (loadPatient_thread) {
loadPatient_thread->quit();
loadPatient_thread->wait();
}
if (localize_marker) localize_marker->deleteLater();
if (skullRemoval) skullRemoval->deleteLater();
if (loadPatient) loadPatient->deleteLater();
if (localize_thread) localize_thread->deleteLater();
if (skull_thread) skull_thread->deleteLater();
if (loadPatient_thread) loadPatient_thread->deleteLater();
delete Ui;
}
void MainWindow::onAutoSkullMaskEnd(vtkImageData* img){
// Apply the masked volume to the renderer. gRen deep-copies the input,
// so we can safely free the temporary VTK image afterwards.
if (img && Visualizer)
Visualizer->onAutoSkullMaskEnd(img);
QMetaObject::invokeMethod(Ui->statusbar, "showMessage", Qt::QueuedConnection,
Q_ARG(QString, QString("Masking Done") ),
Q_ARG(int, 3000));
Ui->progBar->reset();
QApplication::restoreOverrideCursor();
Ui->pb_manualMask->setEnabled(true);
Ui->pushButton_5->setEnabled(true);
Ui->frame_3->setEnabled(true);
Ui->frame_4->setEnabled(true);
if (img)
img->Delete();
return;
}
void MainWindow::onPatientlLoaded(){
QApplication::restoreOverrideCursor();
Ui->pushButton_5->setEnabled(true);
Ui->pb_manualMask->setEnabled(true);
Ui->actionVolRen->setEnabled(true);
Ui->actionOrthoslice->setEnabled(true);
Ui->pushButton_3->setEnabled(true);
loadDialog->close();
Ui->actionLoad->setEnabled(false);
Ui->pb_manualMask->setEnabled(true);
Ui->pushButton_5->setEnabled(true);
Ui->pushButton_4->setEnabled(false);
Ui->pushButton_3->setEnabled(true);
return;
}
void MainWindow::onParsedEmptyFolder(){
QApplication::restoreOverrideCursor();
loadDialog->close();
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Icon::Critical);
msgBox.setText("Load failed...");
msgBox.setInformativeText("Parsed directory is empty or does not contain CT.");
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
int ret = msgBox.exec();
return;
}
void MainWindow::setStatusMsg(QString msg, int timeout){
QMetaObject::invokeMethod(Ui->statusbar, "showMessage", Qt::QueuedConnection,
Q_ARG(QString, msg ),
Q_ARG(int, timeout));
return;
}
void MainWindow::retranslateUi(Ui_MainWindow* Ui, QMainWindow *MainWindow) {
MainWindow->setWindowTitle(QApplication::translate("MainWindow", "gLocalize - Fondazione CNAO - Politecnico di Milano - 2014", 0));
Ui->actionLoad->setText(QApplication::translate("MainWindow", "Load", 0));
Ui->actionLoad->setIcon(QIcon(":/icons/pb_load.png"));
#ifndef QT_NO_TOOLTIP
Ui->actionLoad->setToolTip(QApplication::translate("MainWindow", "Load patient data", 0));
#endif // QT_NO_TOOLTIP
Ui->actionQuit->setText(QApplication::translate("MainWindow", "Quit", 0));
Ui->actionQuit->setIcon(QIcon(":/icons/pb_quit.png"));
#ifndef QT_NO_TOOLTIP
Ui->actionQuit->setToolTip(QApplication::translate("MainWindow", "Quit application", 0));
#endif // QT_NO_TOOLTIP
Ui->actionVolRen->setText(QApplication::translate("MainWindow", "VolRen", 0));
#ifndef QT_NO_TOOLTIP
Ui->actionVolRen->setToolTip(QApplication::translate("MainWindow", "Volume rendering", 0));
#endif // QT_NO_TOOLTIP
Ui->actionVolRen->setIcon(QIcon(":/icons/volrenIco.png"));
Ui->actionOrthoslice->setText(QApplication::translate("MainWindow", "Orthoslice", 0));
Ui->actionOrthoslice->setIcon(QIcon(":/icons/ortoIco.png"));
Ui->label_6->setText(QApplication::translate("MainWindow", "Patient ID:", 0));
Ui->l_patientID->setText(QString());
Ui->label_8->setText(QApplication::translate("MainWindow", "Patient position:", 0));
Ui->l_patientID_2->setText(QString());
Ui->label_12->setText(QApplication::translate("MainWindow", "RT Isocenter:", 0));
Ui->l_patientID_6->setText(QString());
Ui->label_7->setText(QApplication::translate("MainWindow", "Automatic skull mask", 0));
Ui->pushButton_5->setText(QApplication::translate("MainWindow", "Execute", 0));
Ui->label->setText(QApplication::translate("MainWindow", "Marker intensity", 0));
Ui->checkBox_2->setText(QString());
Ui->label_2->setText(QApplication::translate("MainWindow", "Box diagonal", 0));
Ui->checkBox_3->setText(QString());
Ui->label_3->setText(QApplication::translate("MainWindow", "Hausdorff distance", 0));
Ui->checkBox_5->setText(QString());
Ui->label_5->setText(QApplication::translate("MainWindow", "Box sides distance", 0));
Ui->pushButton_3->setText(QApplication::translate("MainWindow", "Localize", 0));
Ui->pushButton_4->setText(QApplication::translate("MainWindow", "Cancel", 0));
Ui->pushButton->setText(QApplication::translate("MainWindow", "Select all", 0));
Ui->pushButton_2->setText(QApplication::translate("MainWindow", "Uncheck all", 0));
Ui->toolBar->setWindowTitle(QApplication::translate("MainWindow", "toolBar", 0));
return;
} // retranslateUi
void MainWindow::connectUi(Ui_MainWindow* Ui){
QObject::connect(Ui->pushButton_3, SIGNAL(released()), this, SLOT(call_localize_start()));
QObject::connect(Ui->pushButton_4, SIGNAL(released()), this, SLOT(call_localize_cancel()));
QObject::connect(Ui->pushButton, SIGNAL(released()), this, SLOT(call_visualize_all()));
QObject::connect(Ui->pushButton_2, SIGNAL(released()), this, SLOT(call_hide_all()));
QObject::connect(Ui->toolBar, SIGNAL(actionTriggered(QAction*)), this, SLOT(call_ToolbarAction(QAction*)));
QObject::connect(Ui->pushButton_5, SIGNAL(released()), this, SLOT(call_skullMask()));
QObject::connect(Ui->pb_save, SIGNAL(released()), this, SLOT(call_saveDotCtFile()));
QMetaObject::connectSlotsByName(this);
return;
}
void MainWindow::onLocalizationAborted(){
Ui->pushButton_4->setEnabled(false);
Ui->pushButton_3->setEnabled(true);
Ui->progBar->reset();
QMetaObject::invokeMethod(Ui->statusbar, "showMessage", Qt::QueuedConnection,
Q_ARG(QString, "Localization aborted..." ),
Q_ARG(int, 3000));
return;
}
void MainWindow::call_localize_start(){
LocalizationParams params;
params.marchThreshold = Ui->spinBox->text().toInt();
params.thrDown_D = Ui->doubleSpinBox_2->text().toDouble();
params.thrUp_D = Ui->doubleSpinBox_2bis->text().toDouble();
params.thr_HAUSD = Ui->doubleSpinBox_3->text().toDouble();
params.thr_S = Ui->doubleSpinBox_5->text().toDouble();
params.selectedFilters = {
Ui->checkBox_2->isChecked(),
Ui->checkBox_3->isChecked(),
Ui->checkBox_5->isChecked()
};
QMetaObject::invokeMethod(localize_marker, "run", Qt::QueuedConnection,
Q_ARG(vtkImageData*, Visualizer->getVolume()),
Q_ARG(LocalizationParams, params));
QMetaObject::invokeMethod(Ui->statusbar, "showMessage", Qt::QueuedConnection,
Q_ARG(QString, "Localizing..." ),
Q_ARG(int, 0));
Ui->pushButton_4->setEnabled(true);
Ui->pushButton_3->setEnabled(false);
return;
}
void MainWindow::call_localize_cancel(){
QMetaObject::invokeMethod(localize_marker, "abort", Qt::QueuedConnection);
Ui->pushButton_4->setEnabled(false);
return;}
void MainWindow::onItemChanged(QStandardItem* item){
QMetaObject::invokeMethod(Visualizer, "onSingleMarkerChange", Qt::QueuedConnection,
Q_ARG(int, item->text().toInt() ),
Q_ARG(bool, (item->checkState() == Qt::Checked ? true : false)));
return;
}
void MainWindow::updateMarkerPos(double dx, double dy, double dz){
treeModel->blockSignals(true);
for(int ii=0; ii< treeModel->rowCount() ; ii++){
treeModel->item(ii,0)->child(0,0)->setText(QString::number(
treeModel->item(ii,0)->child(0,0)->text().toDouble()-dx));
treeModel->item(ii,0)->child(1,0)->setText(QString::number(
treeModel->item(ii,0)->child(1,0)->text().toDouble()-dy));
treeModel->item(ii,0)->child(2,0)->setText(QString::number(
treeModel->item(ii,0)->child(2,0)->text().toDouble()-dz));
}
treeModel->blockSignals(false);
return;
}
void MainWindow::onLocalizationEnd(MarkerList marker_list){
Ui->treeView->reset();
treeModel->clear();
Ui->pb_save->setEnabled(true);
Ui->pushButton_4->setEnabled(false);
Ui->pushButton_3->setEnabled(true);
if(marker_list.empty()){
Ui->pb_save->setEnabled(false);
Visualizer->setMarkers(MarkerList{});
QMetaObject::invokeMethod(Ui->statusbar, "showMessage", Qt::QueuedConnection,
Q_ARG(QString, "Localization done. No markers found." ),
Q_ARG(int, 3000));
this->Ui->progBar->reset();
this->Ui->pushButton->setEnabled(false);
this->Ui->pushButton_2->setEnabled(false);
return;
}
QStandardItem *parentItem = treeModel->invisibleRootItem();
for (int i = 0; i < marker_list.size() ; i++) {
QStandardItem *item = new QStandardItem(QString("%0").arg(i));
item->setCheckable(true);
item->setCheckState(Qt::Checked);
item->setEditable(false);
QList <QStandardItem*> columnList;
columnList.clear();
columnList.append(new QStandardItem(QString("%0").arg(marker_list[i].centroid.x*1000)));
columnList.append(new QStandardItem(QString("%0").arg(marker_list[i].centroid.y*1000)));
columnList.append(new QStandardItem(QString("%0").arg(marker_list[i].centroid.z*1000)));
item->appendRows(columnList);
// cout<< "Scritto tree: " <<marker_list[i].centroid.x*1000<<" "<<marker_list[i].centroid.y*1000<<marker_list[i].centroid.z*1000<<endl;
//parentItem->appendRow(item);
treeModel->setItem(i, 0, item);
}
Ui->treeView->setModel (treeModel);
Visualizer->setMarkers(marker_list);
Ui->statusbar->showMessage("Localization done.",3);
QMetaObject::invokeMethod(Ui->statusbar, "showMessage", Qt::QueuedConnection,
Q_ARG(QString, "Localization done." ),
Q_ARG(int, 3000));
this->Ui->progBar->reset();
this->Ui->pushButton->setEnabled(true);
this->Ui->pushButton_2->setEnabled(true);
return;
}
void MainWindow::call_saveDotCtFile(){
/*QString filename = QFileDialog::getSaveFileName (
this,
tr("Save .tac file"),
".",
tr("Reference marker file (*.tac)") );*/
QString filename;
filename = pathOut
+ "\\"
+ Ui->l_patientID->text().split(" ").first() +
+ ".tac";
QFile file(filename);
//file.open(QIODevice::WriteOnly | QIODevice::Text);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QMessageBox::warning(this, "Save failed",
"Cannot open file for writing:\n" + file.fileName() + "\n" + file.errorString());
return;
}
QTextStream out(&file);
#if MULTIPLE_REF
if(Ui->a_OTSref->isChecked() ){
#endif
/*divide by volumeSpacing*/
for(int ii=0; ii< treeModel->rowCount() ; ii++)
if( treeModel->item(ii,0)->checkState() == Qt::Checked)
out << treeModel->item(ii,0)->child(0,0)->text().toDouble()/Visualizer->getSpacing()[0]<<" "
<< treeModel->item(ii,0)->child(1,0)->text().toDouble()/Visualizer->getSpacing()[1]<<" "
<< treeModel->item(ii,0)->child(2,0)->text().toDouble()/Visualizer->getSpacing()[2]<<Qt::endl;
#if MULTIPLE_REF
}else{
for(int ii=0; ii< treeModel->rowCount() ; ii++)
if( treeModel->item(ii,0)->checkState() == Qt::Checked)
out << treeModel->item(ii,0)->child(0,0)->text()<<" "
<< treeModel->item(ii,0)->child(1,0)->text()<<" "
<< treeModel->item(ii,0)->child(2,0)->text()<<Qt::endl;
}
#endif
if (Ui->l_isoV->text() == QString("Yes"))
out<< 1;
else if (Ui->l_isoV->text() == QString("No"))
out<< 0;
// optional, as QFile destructor will already do it:
file.close();
QMessageBox msgBox;
msgBox.setText("File saved");
msgBox.setIcon(QMessageBox::Icon::Information);
msgBox.setInformativeText(filename);
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
msgBox.setFixedSize(400,150);
int ret = msgBox.exec();
return;
}
void MainWindow::call_visualize_all(){
// //VISUALIZATION and Countour shift
for(int ii=0; ii< treeModel->rowCount() ; ii++)
treeModel->item(ii,0)->setCheckState(Qt::Checked);
return;
}
void MainWindow::call_hide_all(){
for(int ii=0; ii< treeModel->rowCount() ; ii++)
treeModel->item(ii,0)->setCheckState(Qt::Unchecked);
return;
}
void MainWindow::call_ToolbarAction(QAction* action){
if(action == Ui->actionQuit)
this->call_quit();
// QApplication::quit();
if(action == Ui->actionLoad){
QString dirName = QFileDialog::getExistingDirectory(this,tr("Chose DICOM Directory"), "wrkDir",QFileDialog::ShowDirsOnly);
if(!dirName.isEmpty()) {
QMetaObject::invokeMethod(loadPatient, "load", Qt::QueuedConnection,
Q_ARG(QString, dirName));
loadDialog->show();
QMetaObject::invokeMethod(Ui->statusbar, "showMessage", Qt::QueuedConnection,
Q_ARG(QString, "Loading patient..." ),
Q_ARG(int, 3000));
}
//patientLoader->parse(dirName);
}
return;
}
void MainWindow::call_skullMask(){
QApplication::setOverrideCursor(Qt::WaitCursor);
QMetaObject::invokeMethod(Ui->statusbar, "showMessage", Qt::QueuedConnection,
Q_ARG(QString, "Skull masking..." ),
Q_ARG(int, 3000));
QMetaObject::invokeMethod(skullRemoval, "run", Qt::QueuedConnection,
Q_ARG(vtkImageData*, Visualizer->getVolume()),
Q_ARG(double, regGrownParameters[1]),
Q_ARG(double,regGrownParameters[0]));
Ui->pb_manualMask->setEnabled(false);
Ui->pushButton_5->setEnabled(false);
Ui->frame_3->setEnabled(false);
Ui->frame_4->setEnabled(false);
return;
}
void MainWindow::onAutoMaskError(QString msg){
QApplication::restoreOverrideCursor();
QMessageBox msgBox;
msgBox.setText("The automatic masking failed...");
msgBox.setInformativeText("Manual volume clipping is the way to handle this error.");
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
int ret = msgBox.exec();
return;
}
void MainWindow:: onRTIsoAvailable(double* iso){
#if MULTIPLE_REF
Ui->a_RTref->setEnabled(true);
#endif
Ui->l_patientID_6->setText(QString("%0 %1 %2")
.arg(iso[0])
.arg(iso[1])
.arg(iso[2]));
return;
}
void MainWindow:: onCTVolumeAvailable(double* bounds, double* spacing, int* dim){
return;
}
void MainWindow:: onParsedOK(int result, gPatientRTGeneralInfos* infos){
if(result != NOERRORS)
return;
if( QString(infos->PatientID).isEmpty() )
Ui->l_patientID->setText(QString("RTPlan not available"));
else
Ui->l_patientID->setText(QString(infos->PatientID));
if( QString(infos->PatientOrientation).isEmpty() )
Ui->l_patientID_2->setText(QString("RTPlan not available"));
else
Ui->l_patientID_2->setText(QString(infos->PatientOrientation));
QMetaObject::invokeMethod(Ui->statusbar, "showMessage", Qt::QueuedConnection,
Q_ARG(QString, "Dir parser: Ok." ),
Q_ARG(int, 3000));
return;
}
void MainWindow::call_loadPatient(){
return;
}
#if MULTIPLE_REF
void MainWindow::onRefTrigger(QAbstractButton* trigger_button){
QRadioButton* clickedButton= reinterpret_cast <QRadioButton*> (trigger_button);
if(clickedButton == Ui->a_DCMref){
QMetaObject::invokeMethod(loadPatient, "changeRef", Qt::QueuedConnection,
Q_ARG(int,0));
}
if(clickedButton == Ui->a_RTref){
QMetaObject::invokeMethod(loadPatient, "changeRef", Qt::QueuedConnection,
Q_ARG(int,1));
}
if(clickedButton == Ui->a_OTSref){
QMetaObject::invokeMethod(loadPatient, "changeRef", Qt::QueuedConnection,
Q_ARG(int,2));
}
return;
}
#endif
void MainWindow::onVisualizationTrigger(QAction* trigger_action){
if(trigger_action == Ui->actionOrthoslice ){
this->Visualizer->onRequestRenderChange(1);
this->Ui->qvtk->renderWindow()->GetInteractor()->Render();
}
if(trigger_action == Ui->actionVolRen ){
this->Visualizer->onRequestRenderChange(0);
this->Ui->qvtk->renderWindow()->GetInteractor()->Render();
}
return;
}
void MainWindow::onManualMaskTrigger(bool state){
if(state){
this->Visualizer->onRequestManualMask(0);
}else{
this->Visualizer->onRequestManualMask(1);
}
return;
}
void MainWindow::onLocalizationProgress(double percent)
{
// Keep UI updates on the GUI thread
Ui->progBar->setValue(static_cast<int>(percent));
}
void MainWindow::onLocalizationError(const QString& message)
{
qWarning() << "Localization error:" << message;
// Re-enable UI bits if needed
// UI uses generic button names from the legacy .ui
Ui->pushButton_3->setEnabled(true); // "Localize" / start
Ui->pushButton_4->setEnabled(false); // abort
}