From 57061e97f603663fa92056d293f2454111e57a4a Mon Sep 17 00:00:00 2001 From: Olivier Langella <olivier.langella@u-psud.fr> Date: Mon, 15 Oct 2018 08:05:12 +0200 Subject: [PATCH] new decoy selection widget --- src/CMakeLists.txt | 2 + src/gui/widgets/decoy_widget/decoy_widget.ui | 228 +++++++++++++++++ src/gui/widgets/decoy_widget/decoywidget.cpp | 243 +++++++++++++++++++ src/gui/widgets/decoy_widget/decoywidget.h | 78 ++++++ 4 files changed, 551 insertions(+) create mode 100644 src/gui/widgets/decoy_widget/decoy_widget.ui create mode 100644 src/gui/widgets/decoy_widget/decoywidget.cpp create mode 100644 src/gui/widgets/decoy_widget/decoywidget.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 97ef748f..26fec38f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -194,6 +194,7 @@ SET(XTPCPP_SRCS ./gui/waiting_message_dialog/waitingmessagedialog.cpp ./gui/widgets/automatic_filter_widget/automaticfilterwidget.cpp ./gui/widgets/contaminant_widget/contaminantwidget.cpp + ./gui/widgets/decoy_widget/decoywidget.cpp ./gui/widgets/massitemdelegate.cpp ./gui/xic_view/xic_box/xicbox.cpp ./gui/xic_view/xic_widgets/zivydialog.cpp @@ -225,6 +226,7 @@ SET (GUI_UIS ./gui/waiting_message_dialog/waiting_message_dialog.ui ./gui/widgets/automatic_filter_widget/automatic_filter_widget.ui ./gui/widgets/contaminant_widget/contaminant_widget.ui + ./gui/widgets/decoy_widget/decoy_widget.ui ./gui/xic_view/xic_box/xic_box.ui ./gui/xic_view/xic_widgets/zivy_widget.ui ./gui/xic_view/xic_window.ui diff --git a/src/gui/widgets/decoy_widget/decoy_widget.ui b/src/gui/widgets/decoy_widget/decoy_widget.ui new file mode 100644 index 00000000..2530fec8 --- /dev/null +++ b/src/gui/widgets/decoy_widget/decoy_widget.ui @@ -0,0 +1,228 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>DecoyWidget</class> + <widget class="QWidget" name="DecoyWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>405</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QGroupBox" name="decoy_groupbox"> + <property name="title"> + <string>Contaminants</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_6"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <item> + <widget class="QRadioButton" name="decoy_file_radiobutton"> + <property name="toolTip"> + <string>select decoys from fasta files</string> + </property> + <property name="text"> + <string>decoy file</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + <attribute name="buttonGroup"> + <string notr="true">decoy_source_buttongroup</string> + </attribute> + </widget> + </item> + <item> + <widget class="QRadioButton" name="decoy_regexp_radiobutton"> + <property name="toolTip"> + <string>select decoys using a regular expression</string> + </property> + <property name="text"> + <string>decoy &regular expression</string> + </property> + <attribute name="buttonGroup"> + <string notr="true">decoy_source_buttongroup</string> + </attribute> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QListView" name="decoy_database_listview"/> + </item> + <item> + <widget class="QWidget" name="control_list_widget" native="true"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="pushButton"> + <property name="text"> + <string>clear list</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton_2"> + <property name="text"> + <string>add files</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_8"> + <item> + <widget class="QLineEdit" name="decoy_protein_regexp_line_edit"> + <property name="placeholderText"> + <string>reversed$</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>decoy_file_radiobutton</sender> + <signal>clicked()</signal> + <receiver>DecoyWidget</receiver> + <slot>doSelectDecoySource()</slot> + <hints> + <hint type="sourcelabel"> + <x>113</x> + <y>58</y> + </hint> + <hint type="destinationlabel"> + <x>735</x> + <y>64</y> + </hint> + </hints> + </connection> + <connection> + <sender>contaminant_regexp_radiobutton</sender> + <signal>clicked()</signal> + <receiver>ContaminantWidget</receiver> + <slot>doSelectContaminantSource()</slot> + <hints> + <hint type="sourcelabel"> + <x>226</x> + <y>52</y> + </hint> + <hint type="destinationlabel"> + <x>670</x> + <y>79</y> + </hint> + </hints> + </connection> + <connection> + <sender>pushButton_2</sender> + <signal>clicked()</signal> + <receiver>ContaminantWidget</receiver> + <slot>doSelectFastaFile()</slot> + <hints> + <hint type="sourcelabel"> + <x>333</x> + <y>229</y> + </hint> + <hint type="destinationlabel"> + <x>690</x> + <y>146</y> + </hint> + </hints> + </connection> + <connection> + <sender>pushButton</sender> + <signal>clicked()</signal> + <receiver>ContaminantWidget</receiver> + <slot>doClearList()</slot> + <hints> + <hint type="sourcelabel"> + <x>269</x> + <y>220</y> + </hint> + <hint type="destinationlabel"> + <x>508</x> + <y>201</y> + </hint> + </hints> + </connection> + <connection> + <sender>contaminant_database_listview</sender> + <signal>clicked(QModelIndex)</signal> + <receiver>ContaminantWidget</receiver> + <slot>doChanged()</slot> + <hints> + <hint type="sourcelabel"> + <x>317</x> + <y>102</y> + </hint> + <hint type="destinationlabel"> + <x>714</x> + <y>107</y> + </hint> + </hints> + </connection> + <connection> + <sender>decoy_protein_regexp_line_edit</sender> + <signal>textChanged(QString)</signal> + <receiver>DecoyWidget</receiver> + <slot>doChanged()</slot> + <hints> + <hint type="sourcelabel"> + <x>167</x> + <y>267</y> + </hint> + <hint type="destinationlabel"> + <x>657</x> + <y>303</y> + </hint> + </hints> + </connection> + </connections> + <slots> + <slot>doSelectDecoySource()</slot> + <slot>doSelectFastaFile()</slot> + <slot>doClearList()</slot> + <slot>doChanged()</slot> + </slots> + <buttongroups> + <buttongroup name="decoy_source_buttongroup"/> + </buttongroups> +</ui> diff --git a/src/gui/widgets/decoy_widget/decoywidget.cpp b/src/gui/widgets/decoy_widget/decoywidget.cpp new file mode 100644 index 00000000..9c8101f8 --- /dev/null +++ b/src/gui/widgets/decoy_widget/decoywidget.cpp @@ -0,0 +1,243 @@ +/** + * \file gui/widgets/decoy_widget/decoywidget.cpp + * \date 20/2/2018 + * \author Olivier Langella + * \brief graphic widget to choose decoy files or regular expression + */ + + +/******************************************************************************* + * Copyright (c) 2018 Olivier Langella <olivier.langella@u-psud.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/>. + * + ******************************************************************************/ + + +#include "decoywidget.h" + +#include "ui_decoy_widget.h" +#include <QDebug> +#include <pappsomspp/pappsoexception.h> +#include <QSettings> +#include <QFileDialog> + +DecoyWidget::DecoyWidget(QWidget *parent) + : QWidget(parent), ui(new Ui::DecoyWidget) +{ + qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; + ui->setupUi(this); + _emit_changed = false; + _p_fasta_str_li = new QStandardItemModel(); + ui->decoy_database_listview->setModel(_p_fasta_str_li); + QItemSelectionModel *selection_model = + ui->decoy_database_listview->selectionModel(); + ui->decoy_database_listview->setSelectionMode( + QAbstractItemView::MultiSelection); + + doSelectDecoySource(); + _emit_changed = true; + qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; +} + +DecoyWidget::~DecoyWidget() +{ + qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; + delete ui; + delete _p_fasta_str_li; + qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; +} + + +void +DecoyWidget::setRegexpDecoyPattern(const QString &pattern) +{ + _emit_changed = false; + ui->decoy_protein_regexp_line_edit->setText(pattern); + _emit_changed = true; +} + + +void +DecoyWidget::setFastaFileList(std::vector<FastaFileSp> fasta_file_list) +{ + + _p_fasta_str_li->removeRows(0, _p_fasta_str_li->rowCount()); + for(FastaFileSp fasta_file : fasta_file_list) + { + + QStandardItem *item; + item = + new QStandardItem(QString("%1").arg(fasta_file.get()->getFilename())); + item->setEditable(false); + item->setData(QVariant::fromValue(fasta_file), Qt::UserRole); + _p_fasta_str_li->appendRow(item); + // item->setData(QVariant(QString("%1").arg(fasta_file.get()->getAbsoluteFilePath())),Qt::UserRole); + } +} + +void +DecoyWidget::getProjectDecoys(const Project *p_project) +{ + _emit_changed = false; + ui->decoy_regexp_radiobutton->setChecked(true); + ui->decoy_protein_regexp_line_edit->setVisible(true); + ui->decoy_database_listview->setVisible(false); + if(p_project->getProteinStore().getContaminantFastaFileList().size() > 0) + { + ui->decoy_file_radiobutton->setChecked(true); + ui->decoy_protein_regexp_line_edit->setVisible(false); + ui->decoy_database_listview->setVisible(true); + } + + ui->decoy_protein_regexp_line_edit->setText( + p_project->getProteinStore().getRegexpContaminant().pattern()); + + this->setFastaFileList(p_project->getFastaFileStore().getFastaFileList()); + + ui->control_list_widget->setVisible(false); + _no_project = false; + _emit_changed = true; +} + +void +DecoyWidget::setProjectDecoys(Project *p_project) +{ + qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; + + _emit_changed = false; + if(ui->decoy_file_radiobutton->isChecked()) + { + QModelIndexList index_list = + ui->decoy_database_listview->selectionModel()->selectedIndexes(); + p_project->getProteinStore().clearContaminants(); + if(index_list.size() > 0) + { + for(QModelIndex index : index_list) + { + if(index.data(Qt::UserRole).canConvert<FastaFileSp>()) + { + FastaFileSp p_fasta_file = + index.data(Qt::UserRole).value<FastaFileSp>(); + p_fasta_file.get()->setContaminants( + p_project->getProteinStore()); + } + else + { + throw pappso::PappsoException( + QObject::tr("can not convert to FastaFile " + "index.data().canConvert<FastaFile *>()")); + } + } + } + + if(_no_project) + { + ui->control_list_widget->setVisible(true); + } + } + else + { + p_project->getProteinStore().setRegexpContaminantPattern( + ui->decoy_protein_regexp_line_edit->text()); + ui->control_list_widget->setVisible(false); + } + _emit_changed = true; + qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; +} + + +void +DecoyWidget::doChanged() +{ + qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; + if(_emit_changed) + emit changed(); + qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; +} + +void +DecoyWidget::doSelectDecoySource() +{ + qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; + ui->decoy_database_listview->setVisible(false); + ui->decoy_protein_regexp_line_edit->setVisible(false); + if(ui->decoy_file_radiobutton->isChecked()) + { + ui->decoy_database_listview->setVisible(true); + } + else + { + ui->decoy_protein_regexp_line_edit->setVisible(true); + } + if(_emit_changed) + emit changed(); + qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__; +} + + +void +DecoyWidget::doSelectFastaFile() +{ + try + { + QSettings settings; + QString default_fasta_location = + settings.value("path/fastafiles_directory", "").toString(); + + QStringList filenames = QFileDialog::getOpenFileNames( + this, + tr("FASTA files"), + default_fasta_location, + tr("FASTA files (*.fasta);;all files (*)")); + + if(filenames.size() > 0) + { + settings.setValue("path/fastafiles_directory", + QFileInfo(filenames[0]).absolutePath()); + } + + std::vector<FastaFileSp> fasta_file_list; + for(QString filename : filenames) + { + fasta_file_list.push_back(std::make_shared<FastaFile>(filename)); + } + + + for(FastaFileSp fasta_file : fasta_file_list) + { + + QStandardItem *item; + item = new QStandardItem( + QString("%1").arg(fasta_file.get()->getFilename())); + item->setEditable(false); + item->setData(QVariant::fromValue(fasta_file), Qt::UserRole); + _p_fasta_str_li->appendRow(item); + // item->setData(QVariant(QString("%1").arg(fasta_file.get()->getAbsoluteFilePath())),Qt::UserRole); + } + } + catch(pappso::PappsoException &error) + { + // QMessageBox::warning(this, + // tr("Error choosing identification result files : + // %1").arg(error.qwhat()), error); + } +} +void +DecoyWidget::doClearList() +{ + _p_fasta_str_li->removeRows(0, _p_fasta_str_li->rowCount()); +} diff --git a/src/gui/widgets/decoy_widget/decoywidget.h b/src/gui/widgets/decoy_widget/decoywidget.h new file mode 100644 index 00000000..9cd64c78 --- /dev/null +++ b/src/gui/widgets/decoy_widget/decoywidget.h @@ -0,0 +1,78 @@ +/** + * \file gui/widgets/decoy_widget/decoywidget.h + * \date 20/2/2018 + * \author Olivier Langella + * \brief graphic widget to choose decoy files or regular expression + */ + +/******************************************************************************* + * Copyright (c) 2018 Olivier Langella <olivier.langella@u-psud.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/>. + * + ******************************************************************************/ + + +#pragma once + +#include <QWidget> +#include <QStandardItemModel> +#include "../../../files/fastafile.h" +#include "../../../core/project.h" + + +namespace Ui +{ +class DecoyWidget; +} + +class DecoyWidget : public QWidget +{ + Q_OBJECT + + public: + explicit DecoyWidget(QWidget *parent); + ~DecoyWidget(); + + + void setRegexpDecoyPattern(const QString &pattern); + + void setFastaFileList(std::vector<FastaFileSp> fasta_file_list); + + void setProjectDecoys(Project *p_project); + void getProjectDecoys(const Project *p_project); + + public slots: + + signals: + void changed(); + + private slots: + void doSelectDecoySource(); + void doSelectFastaFile(); + void doClearList(); + void doChanged(); + + + private: + Ui::DecoyWidget *ui; + + bool _no_project = true; + + QStandardItemModel *_p_fasta_str_li; + + bool _emit_changed = true; +}; -- GitLab