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 &amp;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