From 3316c943c29eadfe0fab70a612b84305ef95b79f Mon Sep 17 00:00:00 2001
From: Olivier Langella <olivier.langella@u-psud.fr>
Date: Thu, 15 Mar 2018 22:47:04 +0100
Subject: [PATCH] move apply filter button at bottom

---
 src/CMakeLists.txt                            | 10 +-
 .../exportspreadsheetdialog.cpp               | 10 +-
 .../load_results_dialog/loadresultsdialog.cpp |  2 -
 src/gui/project_view/project_view.ui          | 67 ++++++++++++-
 src/gui/project_view/projectwindow.cpp        | 58 +++++++-----
 src/gui/project_view/projectwindow.h          |  2 +
 .../automatic_filter_widget.ui                | 93 +++++++------------
 .../automaticfilterwidget.cpp                 | 20 ++--
 .../automaticfilterwidget.h                   | 11 ++-
 .../contaminant_widget/contaminant_widget.ui  | 33 +++++++
 .../contaminant_widget/contaminantwidget.cpp  | 16 +++-
 .../contaminant_widget/contaminantwidget.h    | 11 ++-
 12 files changed, 221 insertions(+), 112 deletions(-)

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 7f9ef4e2d..e5538e8d1 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -17,17 +17,17 @@ FIND_PACKAGE( Qt5 COMPONENTS Core Gui Svg Xml PrintSupport REQUIRED )
 QT5_ADD_RESOURCES(xtpcpp_RCC_SRCS ${xtpcpp_RCCS})
 
 FIND_PACKAGE( QCustomPlot REQUIRED )
-FIND_PACKAGE( Odsstream REQUIRED ) #ODSSTREAM_INCLUDE_DIR AND ODSSTREAM_LIBRARY
-#SET (ODSSTREAM_DIR  "/home/olivier/eclipse/git/cpp_libodsstream")
-#SET (ODSSTREAM_INCLUDE_DIR "${ODSSTREAM_DIR}/src")
-#SET (ODSSTREAM_QT5_LIBRARY "${ODSSTREAM_DIR}/build/src/libodsstream-qt5.so")
+#FIND_PACKAGE( Odsstream REQUIRED ) #ODSSTREAM_INCLUDE_DIR AND ODSSTREAM_LIBRARY
+SET (ODSSTREAM_DIR  "/home/olivier/eclipse/git/libodsstream")
+SET (ODSSTREAM_INCLUDE_DIR "${ODSSTREAM_DIR}/src")
+SET (ODSSTREAM_QT5_LIBRARY "${ODSSTREAM_DIR}/build/src/libodsstream-qt5.so")
 
 SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Xml_EXECUTABLE_COMPILE_FLAGS} ${Qt5Gui_EXECUTABLE_COMPILE_FLAGS} ${Qt5Svg_EXECUTABLE_COMPILE_FLAGS}")
 
 
 
 #sudo apt-get install libpappsomspp-dev
-FIND_PACKAGE( Pappsomspp REQUIRED )
+#FIND_PACKAGE( Pappsomspp REQUIRED )
 # SET (PAPPSOMSPP_DIR  "/home/olivier/eclipse/git/pappsomspp")
 # SET (PAPPSOMSPP_DIR  "/home/langella/developpement/git/pappsomspp")
 # SET (PAPPSOMSPP_INCLUDE_DIR "${PAPPSOMSPP_DIR}/src")
diff --git a/src/gui/export_spreadsheet_dialog/exportspreadsheetdialog.cpp b/src/gui/export_spreadsheet_dialog/exportspreadsheetdialog.cpp
index 27bd67253..7a28da0d2 100644
--- a/src/gui/export_spreadsheet_dialog/exportspreadsheetdialog.cpp
+++ b/src/gui/export_spreadsheet_dialog/exportspreadsheetdialog.cpp
@@ -42,11 +42,11 @@ ExportSpreadsheetDialog::ExportSpreadsheetDialog(QWidget * parent):
     if (settings.value("export_ods/groups", "true").toBool()) {
         ui->groups_checkbox->setCheckState(Qt::Checked);
     }
-    ui->simple_checkbox->setVisible(false);
-    ui->simple_checkbox->setCheckState(Qt::Unchecked);
-    if (settings.value("export_ods/simple", "false").toBool()) {
-        ui->simple_checkbox->setCheckState(Qt::Checked);
-    }
+    //ui->simple_checkbox->setVisible(false);
+    //ui->simple_checkbox->setCheckState(Qt::Unchecked);
+    //if (settings.value("export_ods/simple", "false").toBool()) {
+    //    ui->simple_checkbox->setCheckState(Qt::Checked);
+    //}
     ui->protein_checkbox->setCheckState(Qt::Unchecked);
     if (settings.value("export_ods/proteins", "true").toBool()) {
         ui->protein_checkbox->setCheckState(Qt::Checked);
diff --git a/src/gui/load_results_dialog/loadresultsdialog.cpp b/src/gui/load_results_dialog/loadresultsdialog.cpp
index ac33fa32f..c8fcc5f17 100644
--- a/src/gui/load_results_dialog/loadresultsdialog.cpp
+++ b/src/gui/load_results_dialog/loadresultsdialog.cpp
@@ -39,8 +39,6 @@ LoadResultsDialog::LoadResultsDialog(QWidget * parent):
     this->setModal(true);
     _p_file_list = new QStringListModel();
 
-    ui->automatic_filter_widget->hideButton();
-
     QSettings settings;
     AutomaticFilterParameters param = ui->automatic_filter_widget->getAutomaticFilterParameters();
     param.setFilterCrossSamplePeptideNumber(settings.value("automatic_filter/cross_sample", "true").toBool());
diff --git a/src/gui/project_view/project_view.ui b/src/gui/project_view/project_view.ui
index 755536b84..773a39e2f 100644
--- a/src/gui/project_view/project_view.ui
+++ b/src/gui/project_view/project_view.ui
@@ -76,6 +76,30 @@
             </property>
            </widget>
           </item>
+          <item>
+           <layout class="QHBoxLayout" name="horizontalLayout">
+            <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="apply_filter_button">
+              <property name="text">
+               <string>apply</string>
+              </property>
+             </widget>
+            </item>
+           </layout>
+          </item>
          </layout>
         </item>
         <item row="1" column="0">
@@ -384,6 +408,9 @@
    <extends>QWidget</extends>
    <header>gui/widgets/contaminant_widget/contaminantwidget.h</header>
    <container>1</container>
+   <slots>
+    <signal>changed()</signal>
+   </slots>
   </customwidget>
  </customwidgets>
  <resources/>
@@ -427,8 +454,8 @@
    <slot>doIdentificationsComboboxChanged(int)</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>217</x>
-     <y>95</y>
+     <x>101</x>
+     <y>77</y>
     </hint>
     <hint type="destinationlabel">
      <x>742</x>
@@ -443,7 +470,7 @@
    <slot>doSelectDecoySource()</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>119</x>
+     <x>68</x>
      <y>104</y>
     </hint>
     <hint type="destinationlabel">
@@ -468,6 +495,38 @@
     </hint>
    </hints>
   </connection>
+  <connection>
+   <sender>contaminant_widget</sender>
+   <signal>changed()</signal>
+   <receiver>ProjectView</receiver>
+   <slot>doFilterChanged()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>368</x>
+     <y>99</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>815</x>
+     <y>196</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>apply_filter_button</sender>
+   <signal>clicked()</signal>
+   <receiver>ProjectView</receiver>
+   <slot>doApplyFilter()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>412</x>
+     <y>120</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>689</x>
+     <y>147</y>
+    </hint>
+   </hints>
+  </connection>
  </connections>
  <slots>
   <slot>doFdrChanged()</slot>
@@ -475,6 +534,8 @@
   <slot>doIdentificationsComboboxChanged(int)</slot>
   <slot>doSelectDecoySource()</slot>
   <slot>doSelectContaminantSource()</slot>
+  <slot>doFilterChanged()</slot>
+  <slot>doApplyFilter()</slot>
  </slots>
  <buttongroups>
   <buttongroup name="decoy_source_buttongroup"/>
diff --git a/src/gui/project_view/projectwindow.cpp b/src/gui/project_view/projectwindow.cpp
index f52b45355..fe7250a0a 100644
--- a/src/gui/project_view/projectwindow.cpp
+++ b/src/gui/project_view/projectwindow.cpp
@@ -84,6 +84,8 @@ ProjectWindow::ProjectWindow(MainWindow *parent):
     QVBoxLayout * p_layout = new QVBoxLayout();
     ui->identifications_widget->setLayout(p_layout);
 
+    ui->apply_filter_button->setEnabled(false);
+
 #if QT_VERSION >= 0x050000
     // Qt5 code
     connect (ui->filter_parameter_widget, &AutomaticFilterWidget::automaticFilterParametersChanged, this,&ProjectWindow::doAutomaticFilterParametersChanged);
@@ -380,28 +382,7 @@ void ProjectWindow::refresh() {
 }
 void ProjectWindow::doAutomaticFilterParametersChanged(AutomaticFilterParameters parameters) {
     qDebug() << "ProjectWindow::doAutomaticFilterParametersChanged begin ";
-    try {
-        showWaitingMessage(tr("Updating filters"));
-
-        doDisplayLoadingMessage(tr("tagging contaminant proteins"));
-        
-        ui->contaminant_widget->setProjectContaminants(_project_sp.get());
-        doDisplayLoadingMessage(tr("updating filters"));
-        _project_sp.get()->updateAutomaticFilters(parameters);
-
-        qDebug() << "ProjectWindow::doAutomaticFilterParametersChanged emit operateGrouping(_project_sp) ";
-        emit operateGrouping(_project_sp);
-    }
-    catch (pappso::PappsoException exception_pappso) {
-        hideWaitingMessage();
-        QMessageBox::warning(this,
-                             tr("Error filtering results :"), exception_pappso.qwhat());
-    }
-    catch (std::exception exception_std) {
-        hideWaitingMessage();
-        QMessageBox::warning(this,
-                             tr("Error filtering results :"), exception_std.what());
-    }
+    ui->apply_filter_button->setEnabled(true);
     qDebug() << "ProjectWindow::doAutomaticFilterParametersChanged end ";
 }
 
@@ -786,3 +767,36 @@ void ProjectWindow::doSelectDecoySource() {
     }
     qDebug() << "ProjectWindow::doSelectDecoySource end";
 }
+
+void ProjectWindow::doFilterChanged() {
+    ui->apply_filter_button->setEnabled(true);
+}
+
+void ProjectWindow::doApplyFilter() {
+    ui->apply_filter_button->setEnabled(false);
+    AutomaticFilterParameters automatic_filter = ui->filter_parameter_widget->getAutomaticFilterParameters();
+    //doAutomaticFilterParametersChanged(automatic_filter);
+    try {
+        showWaitingMessage(tr("Updating filters"));
+
+        doDisplayLoadingMessage(tr("tagging contaminant proteins"));
+
+        ui->contaminant_widget->setProjectContaminants(_project_sp.get());
+        doDisplayLoadingMessage(tr("updating filters"));
+        _project_sp.get()->updateAutomaticFilters(automatic_filter);
+
+        qDebug() << "ProjectWindow::doAutomaticFilterParametersChanged emit operateGrouping(_project_sp) ";
+        emit operateGrouping(_project_sp);
+    }
+    catch (pappso::PappsoException exception_pappso) {
+        hideWaitingMessage();
+        QMessageBox::warning(this,
+                             tr("Error filtering results :"), exception_pappso.qwhat());
+    }
+    catch (std::exception exception_std) {
+        hideWaitingMessage();
+        QMessageBox::warning(this,
+                             tr("Error filtering results :"), exception_std.what());
+    }
+
+}
diff --git a/src/gui/project_view/projectwindow.h b/src/gui/project_view/projectwindow.h
index 8ea083902..84961609d 100644
--- a/src/gui/project_view/projectwindow.h
+++ b/src/gui/project_view/projectwindow.h
@@ -81,6 +81,8 @@ public slots:
     void refreshPtmGroup(IdentificationGroup * p_ident_group);
     void doAcceptedLabelingMethod();
     void doViewPeptideDetail(PeptideEvidence * peptide_evidence);
+    void doFilterChanged();
+    void doApplyFilter();
     // void setColor(const QColor &color);
     // void setShape(Shape shape);
 signals:
diff --git a/src/gui/widgets/automatic_filter_widget/automatic_filter_widget.ui b/src/gui/widgets/automatic_filter_widget/automatic_filter_widget.ui
index 78d8e46ca..4611c3aa1 100644
--- a/src/gui/widgets/automatic_filter_widget/automatic_filter_widget.ui
+++ b/src/gui/widgets/automatic_filter_widget/automatic_filter_widget.ui
@@ -26,27 +26,6 @@
        </property>
       </widget>
      </item>
-     <item row="1" column="0">
-      <widget class="QLabel" name="group_number_label">
-       <property name="text">
-        <string>number of peptides per protein</string>
-       </property>
-      </widget>
-     </item>
-     <item row="3" column="0">
-      <widget class="QLabel" name="subgroup_number_label">
-       <property name="text">
-        <string>protein Evalue</string>
-       </property>
-      </widget>
-     </item>
-     <item row="4" column="0">
-      <widget class="QLabel" name="label_2">
-       <property name="text">
-        <string>protein Evalue (log10)</string>
-       </property>
-      </widget>
-     </item>
      <item row="0" column="1">
       <widget class="QDoubleSpinBox" name="peptide_evalue_spinbox">
        <property name="decimals">
@@ -63,6 +42,13 @@
        </property>
       </widget>
      </item>
+     <item row="1" column="0">
+      <widget class="QLabel" name="group_number_label">
+       <property name="text">
+        <string>number of peptides per protein</string>
+       </property>
+      </widget>
+     </item>
      <item row="1" column="1">
       <widget class="QSpinBox" name="peptide_number_spinbox">
        <property name="minimum">
@@ -73,6 +59,27 @@
        </property>
       </widget>
      </item>
+     <item row="2" column="0">
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>overall samples</string>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="1">
+      <widget class="QCheckBox" name="cross_sample_checkbox">
+       <property name="text">
+        <string/>
+       </property>
+      </widget>
+     </item>
+     <item row="3" column="0">
+      <widget class="QLabel" name="subgroup_number_label">
+       <property name="text">
+        <string>protein Evalue</string>
+       </property>
+      </widget>
+     </item>
      <item row="3" column="1">
       <widget class="QDoubleSpinBox" name="protein_evalue_spinbox">
        <property name="decimals">
@@ -89,6 +96,13 @@
        </property>
       </widget>
      </item>
+     <item row="4" column="0">
+      <widget class="QLabel" name="label_2">
+       <property name="text">
+        <string>protein Evalue (log10)</string>
+       </property>
+      </widget>
+     </item>
      <item row="4" column="1">
       <widget class="QDoubleSpinBox" name="protein_evalue_log_spinbox">
        <property name="minimum">
@@ -102,27 +116,6 @@
        </property>
       </widget>
      </item>
-     <item row="5" column="1">
-      <widget class="QPushButton" name="set_param_button">
-       <property name="text">
-        <string>set parameters</string>
-       </property>
-      </widget>
-     </item>
-     <item row="2" column="0">
-      <widget class="QLabel" name="label">
-       <property name="text">
-        <string>overall samples</string>
-       </property>
-      </widget>
-     </item>
-     <item row="2" column="1">
-      <widget class="QCheckBox" name="cross_sample_checkbox">
-       <property name="text">
-        <string/>
-       </property>
-      </widget>
-     </item>
     </layout>
    </item>
   </layout>
@@ -193,22 +186,6 @@
     </hint>
    </hints>
   </connection>
-  <connection>
-   <sender>set_param_button</sender>
-   <signal>clicked()</signal>
-   <receiver>AutomaticFilterWidget</receiver>
-   <slot>doSetParameters()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>522</x>
-     <y>194</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>534</x>
-     <y>253</y>
-    </hint>
-   </hints>
-  </connection>
   <connection>
    <sender>cross_sample_checkbox</sender>
    <signal>toggled(bool)</signal>
diff --git a/src/gui/widgets/automatic_filter_widget/automaticfilterwidget.cpp b/src/gui/widgets/automatic_filter_widget/automaticfilterwidget.cpp
index ef5c5e29e..3b8b1be26 100644
--- a/src/gui/widgets/automatic_filter_widget/automaticfilterwidget.cpp
+++ b/src/gui/widgets/automatic_filter_widget/automaticfilterwidget.cpp
@@ -51,35 +51,37 @@ AutomaticFilterParameters AutomaticFilterWidget::getAutomaticFilterParameters()
     return _parameters;
 }
 
-void AutomaticFilterWidget::hideButton() {
-    qDebug() << "AutomaticFilterWidget::hideButton begin ";
-    ui->set_param_button->setVisible(false);
-    qDebug() << "AutomaticFilterWidget::hideButton end ";
-}
 void AutomaticFilterWidget::setAutomaticFilterParameters(const AutomaticFilterParameters & params) {
     qDebug() << "AutomaticFilterWidget::setAutomaticFilterParameters begin ";
     _parameters = params;
-
+    _emit_changed = false;
     ui->peptide_evalue_spinbox->setValue(_parameters.getFilterPeptideEvalue());
     ui->protein_evalue_spinbox->setValue(_parameters.getFilterProteinEvalue());
     ui->peptide_number_spinbox->setValue(_parameters.getFilterMinimumPeptidePerMatch());
     //ui->protein_evalue_log_spinbox->setValue(std::log(_parameters.getFilterProteinEvalue()));
     ui->cross_sample_checkbox->setCheckState(Qt::Unchecked);
     if (_parameters.getFilterCrossSamplePeptideNumber()) ui->cross_sample_checkbox->setCheckState(Qt::Checked);
+    _emit_changed = true;
     qDebug() << "AutomaticFilterWidget::setAutomaticFilterParameters end ";
 }
 
 void AutomaticFilterWidget::doCrossSample(bool is_cross_sample) {
     _parameters.setFilterCrossSamplePeptideNumber(is_cross_sample);
+
+    if (_emit_changed) emit automaticFilterParametersChanged(_parameters);
 }
 void AutomaticFilterWidget::doPeptideEvalue(double evalue) {
     _parameters.setFilterPeptideEvalue(evalue);
+
+    if (_emit_changed) emit automaticFilterParametersChanged(_parameters);
 }
 void AutomaticFilterWidget::doProteinEvalue(double evalue) {
     if (_signal) {
         _parameters.setFilterProteinEvalue(evalue);
         _signal = false;
         ui->protein_evalue_log_spinbox->setValue(std::log10(_parameters.getFilterProteinEvalue()));
+
+        if (_emit_changed) emit automaticFilterParametersChanged(_parameters);
     }
     else {
         _signal = true;
@@ -90,6 +92,8 @@ void AutomaticFilterWidget::doProteinLogEvalue(double evalue) {
         _parameters.setFilterProteinEvalue(std::pow(10, evalue));
         _signal = false;
         ui->protein_evalue_spinbox->setValue(_parameters.getFilterProteinEvalue());
+
+        if (_emit_changed) emit automaticFilterParametersChanged(_parameters);
     }
     else {
         _signal = true;
@@ -97,7 +101,5 @@ void AutomaticFilterWidget::doProteinLogEvalue(double evalue) {
 }
 void AutomaticFilterWidget::doPeptideNumber(int number) {
     _parameters.setFilterMinimumPeptidePerMatch((unsigned int) number);
-}
-void AutomaticFilterWidget::doSetParameters() {
-    emit automaticFilterParametersChanged(_parameters);
+    if (_emit_changed) emit automaticFilterParametersChanged(_parameters);
 }
diff --git a/src/gui/widgets/automatic_filter_widget/automaticfilterwidget.h b/src/gui/widgets/automatic_filter_widget/automaticfilterwidget.h
index 13109ca53..4b6e118d4 100644
--- a/src/gui/widgets/automatic_filter_widget/automaticfilterwidget.h
+++ b/src/gui/widgets/automatic_filter_widget/automaticfilterwidget.h
@@ -41,23 +41,24 @@ public:
     ~AutomaticFilterWidget();
 
     void setAutomaticFilterParameters(const AutomaticFilterParameters & params);
-    void hideButton();
     AutomaticFilterParameters getAutomaticFilterParameters() const;
 
 public slots:
+
+signals:
+    void automaticFilterParametersChanged(AutomaticFilterParameters parameters);
+    
+private slots:
     void doPeptideEvalue(double evalue);
     void doProteinEvalue(double evalue);
     void doProteinLogEvalue(double evalue);
     void doPeptideNumber(int number);
     void doCrossSample(bool is_cross_sample);
-    void doSetParameters();
-
-signals:
-    void automaticFilterParametersChanged(AutomaticFilterParameters parameters);
 
 private:
     Ui::AutomaticFilterWidget *ui;
     bool _signal = true;
+    bool _emit_changed=true;
 
     AutomaticFilterParameters _parameters;
 
diff --git a/src/gui/widgets/contaminant_widget/contaminant_widget.ui b/src/gui/widgets/contaminant_widget/contaminant_widget.ui
index f7e6a7a0e..00a9fadd5 100644
--- a/src/gui/widgets/contaminant_widget/contaminant_widget.ui
+++ b/src/gui/widgets/contaminant_widget/contaminant_widget.ui
@@ -183,11 +183,44 @@
     </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>contaminant_protein_regexp_line_edit</sender>
+   <signal>textChanged(QString)</signal>
+   <receiver>ContaminantWidget</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>doSelectContaminantSource()</slot>
   <slot>doSelectFastaFile()</slot>
   <slot>doClearList()</slot>
+  <slot>doChanged()</slot>
  </slots>
  <buttongroups>
   <buttongroup name="contaminant_source_buttongroup"/>
diff --git a/src/gui/widgets/contaminant_widget/contaminantwidget.cpp b/src/gui/widgets/contaminant_widget/contaminantwidget.cpp
index 7c4f95820..97b05057f 100644
--- a/src/gui/widgets/contaminant_widget/contaminantwidget.cpp
+++ b/src/gui/widgets/contaminant_widget/contaminantwidget.cpp
@@ -42,13 +42,14 @@ ContaminantWidget::ContaminantWidget(QWidget * parent):
 {
     qDebug() << "ContaminantWidget::ContaminantWidget begin";
     ui->setupUi(this);
-
+    _emit_changed = false;
     _p_fasta_str_li = new QStandardItemModel();
     ui->contaminant_database_listview->setModel(_p_fasta_str_li);
     QItemSelectionModel * selection_model = ui->contaminant_database_listview->selectionModel();
     ui->contaminant_database_listview->setSelectionMode(QAbstractItemView::MultiSelection);
 
     doSelectContaminantSource();
+    _emit_changed = true;
     qDebug() << "ContaminantWidget::ContaminantWidget end";
 }
 
@@ -62,7 +63,9 @@ ContaminantWidget::~ContaminantWidget()
 
 
 void ContaminantWidget::setRegexpContaminantPattern(const QString & pattern) {
+    _emit_changed = false;
     ui->contaminant_protein_regexp_line_edit->setText(pattern);
+    _emit_changed = true;
 }
 
 
@@ -82,6 +85,7 @@ void ContaminantWidget::setFastaFileList(std::vector<FastaFileSp> fasta_file_lis
 }
 
 void ContaminantWidget::getProjectContaminants(const Project * p_project) {
+    _emit_changed = false;
     ui->contaminant_regexp_radiobutton->setChecked(true);
     ui->contaminant_protein_regexp_line_edit->setVisible(true);
     ui->contaminant_database_listview->setVisible(false);
@@ -97,10 +101,12 @@ void ContaminantWidget::getProjectContaminants(const Project * p_project) {
 
     ui->control_list_widget->setVisible(false);
     _no_project = false;
+    _emit_changed = true;
 }
 
 void ContaminantWidget::setProjectContaminants(Project * p_project) {
     qDebug() << "ContaminantWidget::setProjectContaminants begin";
+    _emit_changed = false;
     if (ui->contaminant_file_radiobutton->isChecked()) {
         QModelIndexList index_list = ui->contaminant_database_listview->selectionModel()->selectedIndexes();
         p_project->getProteinStore().clearContaminants();
@@ -124,10 +130,17 @@ void ContaminantWidget::setProjectContaminants(Project * p_project) {
         p_project->getProteinStore().setRegexpContaminantPattern(ui->contaminant_protein_regexp_line_edit->text());
         ui->control_list_widget->setVisible(false);
     }
+    _emit_changed = true;
     qDebug() << "ContaminantWidget::setProjectContaminants end";
 }
 
 
+void ContaminantWidget::doChanged() {
+    qDebug() << "ContaminantWidget::doChanged begin";
+    if (_emit_changed) emit changed();
+    qDebug() << "ContaminantWidget::doChanged end";
+}
+
 void ContaminantWidget::doSelectContaminantSource() {
     qDebug() << "ContaminantWidget::doSelectContaminantSource begin";
     ui->contaminant_database_listview->setVisible(false);
@@ -138,6 +151,7 @@ void ContaminantWidget::doSelectContaminantSource() {
     else {
         ui->contaminant_protein_regexp_line_edit->setVisible(true);
     }
+    if (_emit_changed) emit changed();
     qDebug() << "ContaminantWidget::doSelectContaminantSource end";
 }
 
diff --git a/src/gui/widgets/contaminant_widget/contaminantwidget.h b/src/gui/widgets/contaminant_widget/contaminantwidget.h
index f0b0081ca..ef6c84a84 100644
--- a/src/gui/widgets/contaminant_widget/contaminantwidget.h
+++ b/src/gui/widgets/contaminant_widget/contaminantwidget.h
@@ -58,11 +58,16 @@ public:
     void getProjectContaminants(const Project * p_project);
 
 public slots:
+
+signals:
+    void changed();
+    
+private slots:
     void doSelectContaminantSource();
     void doSelectFastaFile();
     void doClearList();
-
-signals:
+    void doChanged();
+    
 
 private:
     Ui::ContaminantWidget *ui;
@@ -70,6 +75,8 @@ private:
     bool _no_project = true;
     
     QStandardItemModel * _p_fasta_str_li;
+    
+    bool _emit_changed=true;
 
 };
 
-- 
GitLab