diff --git a/Sources/MainWindow.cpp b/Sources/MainWindow.cpp index be4825ac0aab4950c6edb4594a489ad6ebd7bcbc..ff6bb640665bb1fe0691beb6ca1afa1d6e515fb0 100644 --- a/Sources/MainWindow.cpp +++ b/Sources/MainWindow.cpp @@ -20,7 +20,7 @@ #include <QMessageBox> #include <QDoubleValidator> #include <QIntValidator> -#include <QSignalMapper> +#include <QRegExpValidator> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), @@ -44,6 +44,7 @@ MainWindow::MainWindow(QWidget *parent) : // quit worker thread and clear plot data immediately when any settings are changed connect(ui->openProject, &QPushButton::clicked, this, &MainWindow::handleOpenProj); connect(ui->openFileButton, &QPushButton::clicked, this, &MainWindow::onOpenFileClicked); + ui->runIDInput->setValidator(new QRegExpValidator( QRegExp("[A-Za-z0-9_]+"), ui->runIDInput)); connect(ui->runIDInput, &QLineEdit::editingFinished, this, &MainWindow::onRunIDInput); ui->maxEventNumInput->setValidator(new QIntValidator(1, 10000000,ui->maxEventNumInput)); connect(ui->maxEventNumInput, &QLineEdit::editingFinished, this, &MainWindow::onMaxEventNumInput); @@ -137,9 +138,12 @@ MainWindow::MainWindow(QWidget *parent) : // connect(ui->applySettingsButton, &QPushButton::clicked, this, &MainWindow::onConfigApplied); setWindowTitle(tr("Back projection")); - while(!handleOpenProj()) + qDebug() << "Attempting to open a project"; + if(!handleOpenProj()) { - qDebug() << "Attempting to open a project"; + qDebug() << "Cannot open project. Exit application."; +// QCoreApplication::exit(1); + exit(EXIT_FAILURE); } ui->statusBar->showMessage("Ready."); } @@ -216,7 +220,8 @@ bool MainWindow::handleOpenProj() if (config) { // save current settings - config->writeSetup(config->outputDir.currentPath() + "settings.ini"); + config->writeSetup("settings.ini"); + // stop current run onConfigChanged(); } // select project dir @@ -224,37 +229,126 @@ bool MainWindow::handleOpenProj() dialog.setWindowTitle("Open a new or existing project"); dialog.setFileMode(QFileDialog::DirectoryOnly); dialog.setOption(QFileDialog::ShowDirsOnly, false); - if(dialog.exec()) + if(!dialog.exec()) + return false; + + QFileInfo proj_dir(dialog.directory().absolutePath()); + if (!proj_dir.isDir()) + { + QMessageBox::critical(this, "Failed to open direcory", QString("%1 is not a directory.").arg(proj_dir.absolutePath())); + return false; + } + if (!proj_dir.isWritable()) { - QDir::setCurrent(dialog.directory().path()); + QMessageBox::critical(this, "Permission denied", QString("%1 is not writable.").arg(proj_dir.absolutePath())); + return false; + } // qDebug() << QDir::current(); - // if settings.ini does not exist, copy the template settings.ini file to current dir - if (!QDir::current().exists("settings.ini")) - { - QFile::copy(":/Data/Data/settings.ini", "settings.ini"); - } - // read .ini file in current dir - if (!config) // start up - config = new Setup("settings.ini"); - else { - config->readSetup("settings.ini"); + // if settings.ini does not exist, copy the template settings.ini file to current dir + QString settingsPath = dialog.directory().absolutePath() + "/settings.ini"; + if (!dialog.directory().exists("settings.ini")) + { + if(!QFile::copy(":/Data/Data/settings.ini", settingsPath)){ + QMessageBox::critical(this, "Cannot create file", QString("Cannot create settings.ini in %1").arg(proj_dir.absolutePath())); + return false; } - showConfig(); - return true; } - return false; + // check read permission + if(!QFileInfo(settingsPath).isReadable() && !QFile::setPermissions(settingsPath, QFileDevice::ReadOwner)) + { + QMessageBox::critical(this, "Permission denied", QString("Cannot read settings.ini in %1").arg(proj_dir.absolutePath())); + return false; + } + // check write permission + if(!QFileInfo(settingsPath).isWritable() && !QFile::setPermissions(settingsPath, QFileDevice::WriteOwner)) + { + QMessageBox::critical(this, "Permission denied", QString("Cannot write to settings.ini in %1").arg(proj_dir.absolutePath())); + return false; + } + + // set current path to this dir + QDir::setCurrent(dialog.directory().absolutePath()); + // read .ini file in current dir + if (!config) // start up + config = new Setup("settings.ini"); + else { + config->readSetup("settings.ini"); + } + showConfig(); + return true; } bool MainWindow::handleSave() { qDebug() << "Save clicked"; - return true; + if (config){ + config->writeSetup("settings.ini"); + ui->statusBar->showMessage("Project settings saved."); + return true; + } + return false; } bool MainWindow::handleSaveAs() { qDebug() << "Save as clicked"; + if (!config) + return false; + + // save current settings + config->writeSetup("settings.ini"); + // stop current run + onConfigChanged(); + // select new dir + QFileDialog dialog; + dialog.setWindowTitle("Save as"); + dialog.setFileMode(QFileDialog::DirectoryOnly); + dialog.setOption(QFileDialog::ShowDirsOnly, false); + if(!dialog.exec()) + return false; + + QFileInfo proj_dir(dialog.directory().absolutePath()); + if (!proj_dir.isDir()) + { + QMessageBox::critical(this, "Failed to open direcory", QString("%1 is not a directory.").arg(proj_dir.absolutePath())); + return false; + } + if (!proj_dir.isWritable()) + { + QMessageBox::critical(this, "Permission denied", QString("%1 is not writable.").arg(proj_dir.absolutePath())); + return false; + } + // qDebug() << QDir::current(); + + // if settings.ini does not exist, copy the template settings.ini file to current dir + QString settingsPath = dialog.directory().absolutePath() + "/settings.ini"; + if (!dialog.directory().exists("settings.ini")) + { + if(!QFile::copy("settings.ini", settingsPath)){ + QMessageBox::critical(this, "Cannot create file", QString("Cannot create settings.ini in %1").arg(proj_dir.absolutePath())); + return false; + } + } + // check read permission + if(!QFileInfo(settingsPath).isReadable() && !QFile::setPermissions(settingsPath, QFileDevice::ReadOwner)) + { + QMessageBox::critical(this, "Permission denied", QString("Cannot read settings.ini in %1").arg(proj_dir.absolutePath())); + return false; + } + // check write permission + if(!QFileInfo(settingsPath).isWritable() && !QFile::setPermissions(settingsPath, QFileDevice::WriteOwner)) + { + QMessageBox::critical(this, "Permission denied", QString("Cannot write to settings.ini in %1").arg(proj_dir.absolutePath())); + return false; + } + + // set current path to this dir + QDir::setCurrent(dialog.directory().absolutePath()); + // read .ini file in current dir + config->readSetup("settings.ini"); + showConfig(); + ui->statusBar->showMessage(QString("Project saved to %1").arg(QDir::currentPath())); return true; } @@ -273,6 +367,7 @@ void MainWindow::handleAbout() void MainWindow::notifyThreadFinished() { + ui->statusBar->showMessage("Stopped"); // pop up a message box indicating processing is finished. // if (!aborted) // { @@ -293,11 +388,11 @@ void MainWindow::handleStart() if (!workerThread.isNull()) { emit workerStarted(); + ui->statusBar->showMessage("Running"); } else{ onConfigApplied(); } - ui->statusBar->showMessage("Running"); } void MainWindow::handlePause() @@ -364,8 +459,19 @@ void MainWindow::showConfig() bool MainWindow::checkConfig() { + // check if file exists + if (!QFile(config->filePath).exists()){ + QMessageBox::critical(this, "File not exist", QString("Cannot open file %1").arg(config->filePath)); + return false; + } + // check if runID already exists if (config->outputDir.exists()) { - // check if runID already exists + // check if it's writable + if (!QFileInfo(config->outputDir.absolutePath()).isWritable()) + { + QMessageBox::critical(this, "Permission denied", QString("Cannot write to directory %1").arg(config->outputDir.absolutePath())); + return false; + } QMessageBox::StandardButton resBtn = QMessageBox::question(this, "Overwrite", QString("Run-%1 already exists. Are you sure you want to overwrite?\n").arg(config->runID), QMessageBox::Cancel | QMessageBox::No | QMessageBox::Yes, @@ -375,8 +481,24 @@ bool MainWindow::checkConfig() } } else { - // create a new dir - config->outputDir.mkpath("."); + // create a new dir for current ID + if(!config->outputDir.mkpath(".")){ + QMessageBox::critical(this, "Permission denied", "Cannot create output directory for run "+config->runID); + return false; + } + // check read permission + QString outdirpath = config->outputDir.absolutePath(); + if(!QFileInfo(outdirpath).isReadable() && !QFile::setPermissions(outdirpath, QFileDevice::ReadOwner)) + { + QMessageBox::critical(this, "Permission denied", QString("Cannot read settings.ini in %1").arg(outdirpath)); + return false; + } + // check write permission + if(!QFileInfo(outdirpath).isWritable() && !QFile::setPermissions(outdirpath, QFileDevice::WriteOwner)) + { + QMessageBox::critical(this, "Permission denied", QString("Cannot write to settings.ini in %1").arg(outdirpath)); + return false; + } } if (config->phiMax <= config->phiMin) @@ -405,7 +527,8 @@ bool MainWindow::checkConfig() for (int i=0; i<config->channelSettings.size(); i++) { for (int j=i+1; j<config->channelSettings.size(); j++) { if (config->channelSettings[j].chNum == config->channelSettings[i].chNum){ - QMessageBox::warning(this, "Duplicated channel number.", QString("Channel-%1 and channel-%2 have same channel number.").arg(QString::number(i+1), QString::number(j+1))); + QMessageBox::warning(this, "Duplicated channel number.", + QString("Channel-%1 and channel-%2 have same channel number.").arg(QString::number(i+1), QString::number(j+1))); return false; } } diff --git a/Sources/setup.cpp b/Sources/setup.cpp index b2c4fab93dbb073982f9dfd09b58914983cf0735..51184b9814d152c613a2ecedceb6d36f165dbd50 100644 --- a/Sources/setup.cpp +++ b/Sources/setup.cpp @@ -14,7 +14,7 @@ void Setup::readSetup(const QString path) // filePath = ":/Data/Data/pulses.txt"; // filePath = "/media/ming/DATA/projects/Postprocessing/simulation_2/pulses_with_pos_sort_by_time.txt"; // filePath = "/media/ming/DATA/projects/Postprocessing/simulation_3/pulses_with_pos_sort_by_time.txt"; - filePath = "/home/mingf2/Downloads/pulses_with_pos_sort_by_time.txt"; +// filePath = "/home/mingf2/Downloads/pulses_with_pos_sort_by_time.txt"; runID = settings.value("RunID").toString(); outputDir = QDir(runID); maxN = settings.value("MaxEventNum").toInt(); diff --git a/imagerQt.pro b/imagerQt.pro index f334b74a6290821555bd4f4ebc48118d65438c89..c85d236e134b82459a1d536d2c8e3c72eea0dad3 100644 --- a/imagerQt.pro +++ b/imagerQt.pro @@ -57,14 +57,14 @@ QMAKE_CXXFLAGS += -fopenmp #QMAKE_LFLAGS += -fsanitize=address LIBS += -fopenmp -# ROOTSYS=/home/ming/root + ROOTSYS=/home/ming/root INCLUDEPATH += \ - $$(ROOTSYS)/include \ + $$ROOTSYS/include \ $$PWD/Headers LIBS += \ - -L$$(ROOTSYS)/lib -lCore -lImt -lRIO -lNet -lHist -lGraf \ + -L$$ROOTSYS/lib -lCore -lImt -lRIO -lNet -lHist -lGraf \ -lGraf3d -lGpad -lTree -lTreePlayer -lRint -lPostscript -lMatrix \ -lPhysics -lMathCore -lThread -lMultiProc -pthread -lm -ldl -rdynamic