Skip to content
Snippets Groups Projects
mainwindow.cpp 18.37 KiB

/*******************************************************************************
* 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 <pappsomspp/fasta/fastaoutputstream.h>
#include <odsstream/tsvoutputstream.h>
#include "../utils/utils.h"
#include "workerthread.h"
#include "output/ods/comparspectrasheet.h"
#include "output/xpip.h"

class TsvNoSheetOutput: public TsvOutputStream {
public :
    TsvNoSheetOutput(QTextStream & otxtstream):TsvOutputStream(otxtstream) {
    }
    ~TsvNoSheetOutput() {
    }

    virtual void writeSheet(const QString & sheetName) override {
    }
};

MainWindow::MainWindow(QWidget *parent):
    QMainWindow(parent),
    ui(new Ui::Main)
{
    _p_app = QCoreApplication::instance();
    ui->setupUi(this);
    setWindowTitle(QString("%1 %2").arg(SOFTWARE_NAME).arg(XTPCPP_VERSION));

    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);
#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;
    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() << "MainWindow::doAcceptedExportSpreadsheetDialog begin";
    try {
        QSettings settings;
        QString default_location = settings.value("path/export_ods", "").toString();

        QString filename = QFileDialog::getSaveFileName(this, tr("Save ODS file"),
                           QString("%1/untitled.ods").arg(default_location),
                           tr("Open Document Spreadsheet (*.ods)"));

        if (filename.isEmpty()) {
            return;
        }

        settings.setValue("path/export_ods", QFileInfo(filename).absolutePath());

        showWaitingMessage(tr("writing %1 ODS file").arg(QFileInfo(filename).fileName()));
        emit operateWritingOdsFile(filename, _project_sp);
        //emit operateXpipFile(filename);
    }
    catch (pappso::PappsoException & error) {
        viewError(tr("Error while writing ODS file :\n%1").arg(error.qwhat()));
    }
    qDebug() << "MainWindow::doAcceptedExportSpreadsheetDialog end";
}

void MainWindow::doAcceptedTandemRunDialog()
{
    qDebug() << "MainWindow::doAcceptedTandemRunDialog begin";
    showWaitingMessage(tr("Running X!Tandem"));
    emit operateRunningXtandem(_p_tandem_run_dialog->getTandemRunBatch());
    qDebug() << "MainWindow::doAcceptedTandemRunDialog end";
}

void MainWindow::doAcceptedLoadResultDialog() {
    qDebug() << "MainWindow::doAcceptedLoadResultDialog begin";
    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() << "MainWindow::doAcceptedLoadResultDialog end";
}

void MainWindow::doOperationFailed(QString error) {
    hideWaitingMessage();
    viewError(error);
}
void MainWindow::doOperationFinished() {
    hideWaitingMessage();
}
void MainWindow::doGroupingFinished() {
    hideWaitingMessage();
    _project_window->setProjectSp(_project_sp);

}
void MainWindow::doProjectReady(ProjectSp project_sp) {

    qDebug() << "MainWindow::doProjectReady begin";
    qDebug() << "MainWindow::doProjectReady begin a " << project_sp.get()->getFastaFileStore().getFastaFileList().size() ;
    _project_sp = project_sp;

    qDebug() << "MainWindow::doProjectReady begin b " << _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() << "MainWindow::doProjectReady end";
}

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());

        Xpip xpip_file(filename);
        xpip_file.write(_project_sp);
        xpip_file.close();

    }
    catch (pappso::PappsoException & error) {
        viewError(tr("Error while writing XPIP file :\n%1").arg(error.qwhat()));
    }

}

void MainWindow::doActionSpreadsheet() {
    qDebug() << "MainWindow::doActionSpreadsheet begin";
    try {

        _p_export_spreadsheet_dialog->disablePtm();
        if (_project_sp.get() != nullptr) {
            if (_project_sp.get()->hasPtmExperiment()) {
                _p_export_spreadsheet_dialog->enablePtm();
            }
        }
        _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() << "MainWindow::doActionSpreadsheet end";
}

void MainWindow::doActionSpectralCountingMcq()
{
    qDebug() << "MainWindow::doActionSpectralCountingMcq begin";

    QSettings settings;
    QString default_location = settings.value("path/scmcqfile", "").toString();

    QString filename = QFileDialog::getSaveFileName(this, tr("Save spectral count TSV text file"),
                       QString("%1/untitled.tsv").arg(default_location),
                       tr("TSV (*.tsv)"));

    if (filename.isEmpty()) {
        return;
    }

    settings.setValue("path/scmcqfile", QFileInfo(filename).absolutePath());



    QFile outFile;
    outFile.setFileName(filename);
    outFile.open(QIODevice::WriteOnly);
    QTextStream * p_outputStream = new QTextStream(&outFile);
    TsvNoSheetOutput* p_writer = new TsvNoSheetOutput(*p_outputStream);
    ComparSpectraSheet spectra_sheet(nullptr, p_writer, _project_sp.get());
    spectra_sheet.writeSheet();

    p_writer->close();
    delete p_writer;
    delete p_outputStream;
    outFile.close();
    qDebug() << "MainWindow::doActionSpectralCountingMcq end";
}

void MainWindow::doActionFasta() {
    try {

        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());



        QFile outFile;
        outFile.setFileName(filename);
        outFile.open(QIODevice::WriteOnly);
        QTextStream * p_outputStream = new QTextStream(&outFile);

        pappso::FastaOutputStream fasta_output(*p_outputStream);

        for (IdentificationGroup * identification:_project_sp.get()->getIdentificationGroupList()) {
            for (ProteinMatch * protein_match : identification->getProteinMatchList()) {
                if (protein_match->getValidationState() >= ValidationState::grouped) {
                    pappso::Protein protein(QString("%1 %2").arg(protein_match->getProteinXtpSp().get()->getAccession()).arg(protein_match->getProteinXtpSp().get()->getDescription()),protein_match->getProteinXtpSp().get()->getSequence());
                    fasta_output.writeProtein(protein);
                }
            }
        }

        p_outputStream->flush();
        delete p_outputStream;
        outFile.close();
        //emit operateXpipFile(filename);
    }
    catch (pappso::PappsoException & error) {
        viewError(tr("Error while writing MassChroqML file :\n%1").arg(error.qwhat()));
    }
}
void MainWindow::doActionMassChroQ() {
    qDebug() << "MainWindow::doActionMassChroQ begin";
    try {
        _project_sp.get()->checkPsimodCompliance();

        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 XPIP file").arg(QFileInfo(filename).fileName()));
        emit operateWritingMassChroqFile(filename, _project_sp);
        //emit operateXpipFile(filename);
    }
    catch (pappso::PappsoException & error) {
        viewError(tr("Error while writing MassChroqML file :\n%1").arg(error.qwhat()));
    }
    qDebug() << "MainWindow::doActionMassChroQ end";
}

void MainWindow::doActionProticDb() {
    qDebug() << "MainWindow::doActionProticDb begin";
    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() << "MainWindow::doActionProticDb end";
}

void MainWindow::doActionAbout() {
    qDebug() << "MainWindow::doActionAbout begin";
    if (_p_about_dialog == nullptr) {
        _p_about_dialog = new AboutDialog(this);
    }
    _p_about_dialog->show();
    _p_about_dialog->raise();
    _p_about_dialog->activateWindow();

    qDebug() << "MainWindow::doActionAbout end";
}




// 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()));
    }


}