/******************************************************************************* * Copyright (c) 2015 Olivier Langella <Olivier.Langella@moulon.inra.fr>. * * This file is part of XTPcpp. * * XTPcpp is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * XTPcpp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with XTPcpp. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * Olivier Langella <Olivier.Langella@moulon.inra.fr> - initial API and *implementation ******************************************************************************/ #include <QSettings> #include <QFileDialog> #include <QMessageBox> #include <QDebug> #include <QCommandLineParser> #include "../config.h" #include "mainwindow.h" #include "ui_main.h" #include <pappsomspp/pappsoexception.h> #include "../utils/utils.h" #include "workerthread.h" #include "output/xpip.h" #include "export/export_masschroq_dialog/masschroqfileparameters.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::Main) { // http://pappso.inra.fr/demande/ws/pappso_software/xtpcpp _p_app = QCoreApplication::instance(); ui->setupUi(this); setWindowTitle(QString("%1 %2").arg(SOFTWARE_NAME).arg(XTPCPP_VERSION)); setWindowIcon(QIcon(":/xtpcpp_icon/resources/xtandempipeline_icon.svg")); WorkerThread *worker = new WorkerThread(this); worker->moveToThread(&_worker_thread); _worker_thread.start(); _p_load_results_dialog = new LoadResultsDialog(this); _p_export_spreadsheet_dialog = new ExportSpreadsheetDialog(this); _p_waiting_message_dialog = new WaitingMessageDialog(this); _p_tandem_run_dialog = new TandemRunDialog(this); _project_window = new ProjectWindow(this); ui->menu_export_files->setDisabled(true); ui->centralwidget->layout()->addWidget(_project_window); _project_window->hide(); ui->action_save_project->setDisabled(true); ui->default_display_widget->show(); //_protein_list_window = new ProteinListWindow(this); // QDockWidget *dock = new QDockWidget(tr("Protein List"), this); // dock->setWidget(_protein_list_window); // addDockWidget(Qt::RightDockWidgetArea, dock); qRegisterMetaType<ProjectSp>("ProjectSp"); qRegisterMetaType<AutomaticFilterParameters>("AutomaticFilterParameters"); qRegisterMetaType<GroupingType>("GroupingType"); #if QT_VERSION >= 0x050000 // Qt5 code connect(_p_tandem_run_dialog, &TandemRunDialog::accepted, this, &MainWindow::doAcceptedTandemRunDialog); connect(_p_load_results_dialog, &LoadResultsDialog::accepted, this, &MainWindow::doAcceptedLoadResultDialog); connect(_p_export_spreadsheet_dialog, &ExportSpreadsheetDialog::accepted, this, &MainWindow::doAcceptedExportSpreadsheetDialog); connect(&m_onlineVersion, &HttpVersion::httpVersionReady, this, &MainWindow::doCheckNewVersion); #else // Qt4 code connect(_p_tandem_run_dialog, SIGNAL(accepted()), this, SLOT(doAcceptedTandemRunDialog())); connect(_p_load_results_dialog, SIGNAL(accepted()), this, SLOT(doAcceptedLoadResultDialog())); connect(_p_export_spreadsheet_dialog, SIGNAL(accepted()), this, SLOT(doAcceptedExportSpreadsheetDialog())); #endif } MainWindow::~MainWindow() { qDebug() << "MainWindow::~MainWindow"; _worker_thread.quit(); _worker_thread.wait(); // if (_p_ms_data_file != nullptr) delete _p_ms_data_file; delete ui; // delete _project_window; delete _p_load_results_dialog; delete _p_export_spreadsheet_dialog; delete _p_waiting_message_dialog; if(_p_export_masschroq_dialog != nullptr) { delete _p_export_masschroq_dialog; } qDebug() << "MainWindow::~MainWindow end"; } bool MainWindow::stopWorkerThread() { return _p_waiting_message_dialog->stopWorkerThread(); } void MainWindow::closeEvent(QCloseEvent *event) { if(true) { event->accept(); } else { event->ignore(); } } void MainWindow::viewError(QString error) { hideWaitingMessage(); QMessageBox::warning( this, tr("Oops! an error occurred in XTPCPP. Dont Panic :"), error); } void MainWindow::doDisplayJobFinished(QString message) { qDebug() << "MainWindow::doDisplayJobFinished " << message; hideWaitingMessage(); QMessageBox::information(this, tr("job finished"), message); } void MainWindow::doDisplayLoadingMessage(QString message) { qDebug() << "MainWindow::doDisplayLoadingMessage " << message; _p_waiting_message_dialog->message(message); ui->statusbar->showMessage(message); } void MainWindow::doDisplayLoadingMessagePercent(QString message, int value) { qDebug() << "MainWindow::doDisplayLoadingMessagePercent " << message << " " << value; _p_waiting_message_dialog->message(message, value); ui->statusbar->showMessage(message); } void MainWindow::doWorkerSetText(QString text) { _p_waiting_message_dialog->setText(text); } void MainWindow::doWorkerAppendText(char *text) { _p_waiting_message_dialog->appendText(text); } void MainWindow::doActionQuit() { qDebug() << "MainWindow::doActionQuit begin"; this->close(); } void MainWindow::doAcceptedExportSpreadsheetDialog() { qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; try { QString format = this->_p_export_spreadsheet_dialog->getExportFormat(); QSettings settings; QString default_location = settings.value("path/export_ods", "").toString(); QString filename; if(format == "ods") { filename = QFileDialog::getSaveFileName( this, tr("Save ODS file"), QString("%1/untitled.ods").arg(default_location), tr("Open Document Spreadsheet (*.ods)")); settings.setValue("path/export_ods", QFileInfo(filename).absolutePath()); } else { filename = QFileDialog::getExistingDirectory( this, tr("Save TSV files"), QString("%1").arg(default_location)); QDir parent(filename); parent.cdUp(); settings.setValue("path/export_ods", parent.canonicalPath()); qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " " << parent.absolutePath(); } if(filename.isEmpty()) { return; } showWaitingMessage( tr("writing %1 ODS file").arg(QFileInfo(filename).fileName())); emit operateWritingOdsFile(filename, format, _project_sp); // emit operateXpipFile(filename); } catch(pappso::PappsoException &error) { viewError(tr("Error while writing ODS file :\n%1").arg(error.qwhat())); } qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; } void MainWindow::doAcceptedTandemRunDialog() { qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; showWaitingMessage(tr("Running X!Tandem")); emit operateRunningXtandem(_p_tandem_run_dialog->getTandemRunBatch()); qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; } void MainWindow::doAcceptedLoadResultDialog() { qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; AutomaticFilterParameters param = _p_load_results_dialog->getAutomaticFilterParameters(); QSettings settings; settings.setValue( "automatic_filter/cross_sample", QString("%1").arg(param.getFilterCrossSamplePeptideNumber())); settings.setValue("automatic_filter/peptide_number", QString("%1").arg(param.getFilterMinimumPeptidePerMatch())); settings.setValue("automatic_filter/peptide_evalue", QString("%1").arg(param.getFilterPeptideEvalue())); settings.setValue("automatic_filter/protein_evalue", QString("%1").arg(param.getFilterProteinEvalue())); QStringList file_list = _p_load_results_dialog->getFileList(); bool is_individual = _p_load_results_dialog->isIndividual(); showWaitingMessage(tr("Loading files")); emit operateLoadingResults(is_individual, param, file_list); qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; } void MainWindow::doOperationFailed(QString error) { hideWaitingMessage(); viewError(error); } void MainWindow::doOperationFinished() { hideWaitingMessage(); } void MainWindow::doGroupingFinished() { hideWaitingMessage(); _project_window->setProjectSp(_project_sp); } void MainWindow::doLoadingResultsReady(ProjectSp project_sp) { qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; if(_p_load_results_dialog != nullptr) { _p_load_results_dialog->setProjectContaminants(project_sp.get()); } doProjectReady(project_sp); qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; } void MainWindow::doProjectReady(ProjectSp project_sp) { qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " " << project_sp.get()->getFastaFileStore().getFastaFileList().size(); _project_sp = project_sp; qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " " << _project_sp.get()->getFastaFileStore().getFastaFileList().size(); showWaitingMessage(tr("grouping proteins")); emit operateGrouping(project_sp); ui->menu_export_files->setDisabled(false); ui->menu_edit->setDisabled(false); _project_window->show(); ui->default_display_widget->hide(); ui->action_save_project->setDisabled(false); qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; } void MainWindow::doActionLabelingMethods() { _project_window->editLabelingMethods(); } void MainWindow::doActionModifications() { _project_window->editModifications(); } void MainWindow::doProjectNotReady(QString error) { viewError(error); } void MainWindow::doActionTandemRun() { _p_tandem_run_dialog->show(); _p_tandem_run_dialog->raise(); _p_tandem_run_dialog->activateWindow(); } void MainWindow::loadResults() { _p_load_results_dialog->show(); _p_load_results_dialog->raise(); _p_load_results_dialog->activateWindow(); } void MainWindow::hideWaitingMessage() { _p_waiting_message_dialog->hide(); ui->statusbar->showMessage(""); } void MainWindow::showWaitingMessage(const QString title) { _p_waiting_message_dialog->setWindowTitle(title); _p_waiting_message_dialog->show(); _p_waiting_message_dialog->raise(); _p_waiting_message_dialog->activateWindow(); } void MainWindow::selectXpipFile() { try { QSettings settings; QString default_location = settings.value("path/xpipfile", "").toString(); QString filename = QFileDialog::getOpenFileName( this, tr("Open XPIP File"), default_location, tr("xpip files (*.xpip);;all files (*)")); if(filename.isEmpty()) { return; } settings.setValue("path/xpipfile", QFileInfo(filename).absolutePath()); showWaitingMessage( tr("Loading %1 XPIP file").arg(QFileInfo(filename).fileName())); emit operateXpipFile(filename); } catch(pappso::PappsoException &error) { viewError(tr("Error while reading XPIP file :\n%1").arg(error.qwhat())); } } void MainWindow::doActionSaveProject() { try { // QMessageBox::warning(this, // tr("Experimental feature"), "WARNING : project // files export is not ready"); QSettings settings; QString default_location = settings.value("path/xpipfile", "").toString(); QString filename = QFileDialog::getSaveFileName( this, tr("Save XPIP file"), QString("%1/untitled.xpip").arg(default_location), tr("XPIP (*.xpip)")); if(filename.isEmpty()) { return; } settings.setValue("path/xpipfile", QFileInfo(filename).absolutePath()); showWaitingMessage( tr("Writing %1 XPIP file").arg(QFileInfo(filename).fileName())); emit operateWritingXpipFile(filename, _project_sp); } catch(pappso::PappsoException &error) { viewError(tr("Error while writing XPIP file :\n%1").arg(error.qwhat())); } } void MainWindow::doActionSpreadsheet() { qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; try { if(_project_sp.get() != nullptr) { _p_export_spreadsheet_dialog->setProject(_project_sp.get()); } _p_export_spreadsheet_dialog->show(); _p_export_spreadsheet_dialog->raise(); _p_export_spreadsheet_dialog->activateWindow(); } catch(pappso::PappsoException &error) { viewError(tr("Error doActionSpreadsheet :\n%1").arg(error.qwhat())); } qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; } void MainWindow::doActionSpectralCountingMcq() { qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; QSettings settings; QString default_location = settings.value("path/scmcqfile", "").toString(); QString filename = QFileDialog::getSaveFileName( this, tr("Save spectral count TSV file"), QString("%1/untitled.tsv").arg(default_location), tr("TSV (*.tsv)")); if(filename.isEmpty()) { return; } settings.setValue("path/scmcqfile", QFileInfo(filename).absolutePath()); showWaitingMessage(tr("Writing %1 spectral count file for MassChroqR") .arg(QFileInfo(filename).fileName())); emit operateWritingMcqrSpectralCountFile(filename, _project_sp); qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; } void MainWindow::doActionFasta() { QSettings settings; QString default_location = settings.value("path/fastafile", "").toString(); QString filename = QFileDialog::getSaveFileName( this, tr("Save FASTA file"), QString("%1/untitled.fasta").arg(default_location), tr("FASTA (*.fasta)")); if(filename.isEmpty()) { return; } settings.setValue("path/fastafile", QFileInfo(filename).absolutePath()); showWaitingMessage( tr("Writing %1 FASTA file").arg(QFileInfo(filename).fileName())); emit operateWritingFastaFile(filename, _project_sp, ExportFastaType::all); } void MainWindow::doActionFastaOneBySubgroup() { QSettings settings; QString default_location = settings.value("path/fastafile", "").toString(); QString filename = QFileDialog::getSaveFileName( this, tr("Save FASTA file"), QString("%1/untitled.fasta").arg(default_location), tr("FASTA (*.fasta)")); if(filename.isEmpty()) { return; } settings.setValue("path/fastafile", QFileInfo(filename).absolutePath()); showWaitingMessage( tr("Writing %1 FASTA file").arg(QFileInfo(filename).fileName())); emit operateWritingFastaFile(filename, _project_sp, ExportFastaType::oneBySubgroup); } void MainWindow::doActionFastaOneByGroup() { QSettings settings; QString default_location = settings.value("path/fastafile", "").toString(); QString filename = QFileDialog::getSaveFileName( this, tr("Save FASTA file"), QString("%1/untitled.fasta").arg(default_location), tr("FASTA (*.fasta)")); if(filename.isEmpty()) { return; } settings.setValue("path/fastafile", QFileInfo(filename).absolutePath()); showWaitingMessage( tr("Writing %1 FASTA file").arg(QFileInfo(filename).fileName())); emit operateWritingFastaFile(filename, _project_sp, ExportFastaType::oneByGroup); } void MainWindow::doActionMassChroQ() { qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; try { _project_sp.get()->checkPsimodCompliance(); if(_p_export_masschroq_dialog == nullptr) { _p_export_masschroq_dialog = new ExportMasschroqDialog(this); connect(_p_export_masschroq_dialog, &ExportMasschroqDialog::accepted, this, &MainWindow::doAcceptedExportMasschroqDialog); } MasschroqFileParameters params; params.load(); if(_project_sp.get() != nullptr) { _p_export_masschroq_dialog->setMasschroqFileParameters(params); _p_export_masschroq_dialog->setProject(this->_project_sp.get()); } _p_export_masschroq_dialog->show(); _p_export_masschroq_dialog->raise(); _p_export_masschroq_dialog->activateWindow(); } catch(pappso::PappsoException &error) { viewError(tr("Error doActionMassChroQ :\n%1").arg(error.qwhat())); } qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; } void MainWindow::doAcceptedExportMasschroqDialog() { qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; try { MasschroqFileParameters params = _p_export_masschroq_dialog->getMasschroqFileParameters(); params.save(); QSettings settings; QString default_location = settings.value("path/mcqfile", "").toString(); QString filename = QFileDialog::getSaveFileName( this, tr("Save MassChroqML file"), QString("%1/untitled.masschroqml").arg(default_location), tr("MassChroqML (*.masschroqml)")); if(filename.isEmpty()) { return; } settings.setValue("path/mcqfile", QFileInfo(filename).absolutePath()); showWaitingMessage( tr("Writing %1 MassChroqML file").arg(QFileInfo(filename).fileName())); emit operateWritingMassChroqFile(filename, _project_sp, params); } catch(pappso::PappsoException &error) { viewError( tr("Error while writing MassChroqML file :\n%1").arg(error.qwhat())); } qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; } void MainWindow::doActionMassChroqPRM() { qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; try { _project_sp.get()->checkPsimodCompliance(); QSettings settings; QString default_location = settings.value("path/mcqprmfile", "").toString(); QString filename = QFileDialog::getSaveFileName( this, tr("Save MassChroqPRM file"), QString("%1/untitled.masschroqprm").arg(default_location), tr("MassChroqPRM (*.masschroqprm)")); if(filename.isEmpty()) { return; } settings.setValue("path/mcqprmfile", QFileInfo(filename).absolutePath()); showWaitingMessage( tr("Writing %1 MassChroqPRM file").arg(QFileInfo(filename).fileName())); emit operateWritingMassChroqPrmFile(filename, _project_sp); // emit operateXpipFile(filename); } catch(pappso::PappsoException &error) { viewError( tr("Error while writing MassChroqML file :\n%1").arg(error.qwhat())); } qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; } void MainWindow::doActionProticDb() { qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; try { _project_sp.get()->checkPsimodCompliance(); QSettings settings; QString default_location = settings.value("path/proticfile", "").toString(); QString filename = QFileDialog::getSaveFileName( this, tr("Save PROTICdbML file"), QString("%1/untitled.proticdbml").arg(default_location), tr("PROTICdbML (*.proticdbml)")); if(filename.isEmpty()) { return; } settings.setValue("path/proticfile", QFileInfo(filename).absolutePath()); showWaitingMessage( tr("Writing %1 PROTICdbML file").arg(QFileInfo(filename).fileName())); emit operateWritingProticFile(filename, _project_sp); // emit operateXpipFile(filename); } catch(pappso::PappsoException &error) { viewError( tr("Error while writing PROTICdbML file :\n%1").arg(error.qwhat())); } qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; } void MainWindow::doActionAbout() { qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; if(_p_about_dialog == nullptr) { _p_about_dialog = new AboutDialog(this); } _p_about_dialog->show(); _p_about_dialog->raise(); _p_about_dialog->activateWindow(); qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; } void MainWindow::doCheckNewVersion() { qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; if(m_onlineVersion.isNewVersion()) { hideWaitingMessage(); int ret = QMessageBox::warning( this, tr("new version available"), tr("A new %1 version is available %2\nCheck our web site \n" "http://pappso.inra.fr/bioinfo/xtandempipeline\n to download it") .arg(SOFTWARE_NAME) .arg(m_onlineVersion.getVersion())); if(ret == QMessageBox::Ok) { QDesktopServices::openUrl( QUrl("http://pappso.inra.fr/bioinfo/xtandempipeline")); } } qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; } // 10ms after the application starts this method will run // all QT messaging is running at this point so threads, signals and slots // will all work as expected. void MainWindow::run() { QTextStream errorStream(stderr, QIODevice::WriteOnly); try { qDebug() << "MainWindow::run() begin"; QCommandLineParser parser; // throw pappso::PappsoException("test"); parser.setApplicationDescription( QString(SOFTWARE_NAME).append(" ").append(XTPCPP_VERSION)); parser.addHelpOption(); parser.addVersionOption(); parser.addPositionalArgument( "XPIP project file", QCoreApplication::translate("main", "Project file to open.")); qDebug() << "MainWindow::run() 1"; // Process the actual command line arguments given by the user parser.process(*_p_app); QStringList xpip_list = parser.positionalArguments(); if(xpip_list.size() > 0) { showWaitingMessage(tr("Loading %1 XPIP file").arg(xpip_list.at(0))); emit operateXpipFile(xpip_list.at(0)); } } catch(pappso::PappsoException &error) { viewError( tr("Oops! an error occurred in X!TandemPipeline. Dont Panic :\n%1") .arg(error.qwhat())); } catch(std::exception &error) { viewError( tr("Oops! an error occurred in X!TandemPipeline. Dont Panic :\n%1") .arg(error.what())); } }