Logo Search packages:      
Sourcecode: massxpert version File versions

calculatorWnd.cpp

/* massXpert - the true massist's program.
   --------------------------------------
   Copyright(C) 2006,2007 Filippo Rusconi

   http://www.massxpert.org/massXpert

   This file is part of the massXpert project.

   The massxpert project is the successor to the "GNU polyxmass"
   project that is an official GNU project package(see
   www.gnu.org). The massXpert project is not endorsed by the GNU
   project, although it is released ---in its entirety--- under the
   GNU General Public License. A huge part of the code in massXpert
   is actually a C++ rewrite of code in GNU polyxmass. As such
   massXpert was started at the Centre National de la Recherche
   Scientifique(FRANCE), that granted me the formal authorization to
   publish it under this Free Software License.

   This software is free software; you can redistribute it and/or
   modify it under the terms of the GNU  General Public
   License version 3, as published by the Free Software Foundation.
   

   This software 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 this software; if not, write to the

   Free Software Foundation, Inc.,

   51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/


/////////////////////// Qt includes
#include <QtGui>
#include <QtXml>
#include <QtGlobal>


/////////////////////// Local includes
#include "calculatorWnd.hpp"
#include "application.hpp"
#include "calculatorRecorderDlg.hpp"
#include "polChemDefEntity.hpp"
#include "sequence.hpp"
#include "mzCalculationDlg.hpp"
#include "isotopicPatternCalculationDlg.hpp"


namespace massXpert
{

  CalculatorWnd::CalculatorWnd(QString &filePath)
  {
    m_forciblyClose = false;
    m_noDelistWnd = false;

    if (filePath.isEmpty())
      {
      QMessageBox::warning(0, 
                        tr("massXpert - Calculator"),
                        tr("Polymer chemistry definition filepath empty."),
                        QMessageBox::Ok);
      
      return;
      }
  
    m_polChemDef.setFilePath(filePath);
  
    if (!initialize())
      {
      QMessageBox::warning(0, 
                        tr("massXpert - Calculator"),
                        tr("Failed to initialize the calculator window."),
                        QMessageBox::Ok);
      }

    QSettings settings 
      (static_cast<Application *>(qApp)->configSettingsFilePath(), 
       QSettings::IniFormat);
    
    settings.beginGroup("calculator_wnd");
    
    restoreGeometry(settings.value("geometry").toByteArray());
    
    m_ui.hSplitter->
      restoreState(settings.value("hSplitterSize").toByteArray());
    
    settings.endGroup();
    
    show();
  }
  
  
  CalculatorWnd::~CalculatorWnd()
  {
    
  }
  
  
  void
  CalculatorWnd::closeEvent(QCloseEvent *event)
  {
    QSettings settings 
      (static_cast<Application *>(qApp)->configSettingsFilePath(), 
       QSettings::IniFormat);
    
    settings.beginGroup("calculator_wnd");
    
    settings.setValue("geometry", saveGeometry());
    
    settings.setValue("hSplitterSize", m_ui.hSplitter->saveState());
    
    settings.endGroup();
    

    // We are asked not to remove this window from the list of all the
    // calculator windows. This occurs when all the windows are closed
    // in the application object.
    
    if (m_noDelistWnd)
      {
      m_noDelistWnd = false;
      
      event->accept();
      
      return;
      }
      
    // We must remove this window from the application's list of such
    // windows:
  
    Application *application = static_cast<Application *>(qApp);

    int index = application->calculatorWndList()->indexOf(this);
  
    application->calculatorWndList()->takeAt(index);
    
    event->accept();
  }
  

  bool
  CalculatorWnd::initialize()
  {
    m_ui.setupUi(this);

    QPixmap pixmap(":/images/massxpert-icon-32.png");
    QIcon icon(pixmap);
    setWindowIcon(icon);

    setAttribute(Qt::WA_DeleteOnClose);
    statusBar()->setSizeGripEnabled(true);

    ////// Connection of the SIGNALS and SLOTS //////

    connect(m_ui.addToResultPushButton,
           SIGNAL(clicked()),
           this,
           SLOT(addToResult()));
  
    connect(m_ui.sendToResultPushButton,
           SIGNAL(clicked()),
           this,
           SLOT(sendToResult()));
  
    connect(m_ui.removeFromResultPushButton,
           SIGNAL(clicked()),
           this,
           SLOT(removeFromResult()));
  
    connect(m_ui.clearSeedPushButton,
           SIGNAL(clicked()),
           this,
           SLOT(clearSeed()));
  
    connect(m_ui.addToSeedPushButton,
           SIGNAL(clicked()),
           this,
           SLOT(addToSeed()));
  
    connect(m_ui.sendToSeedPushButton,
           SIGNAL(clicked()),
           this,
           SLOT(sendToSeed()));
  
    connect(m_ui.removeFromSeedPushButton,
           SIGNAL(clicked()),
           this,
           SLOT(removeFromSeed()));
  
    connect(m_ui.clearResultPushButton,
           SIGNAL(clicked()),
           this,
           SLOT(clearResult()));
  
    connect(m_ui.showRecorderCheckBox,
           SIGNAL(stateChanged(int)),
           this,
           SLOT(showRecorder(int)));
  
    connect(m_ui.showChemPadCheckBox,
           SIGNAL(stateChanged(int)),
           this,
           SLOT(showChemPad(int)));
  
    connect(m_ui.applyPushButton,
           SIGNAL(clicked()),
           this,
           SLOT(apply()));

    connect(m_ui.mzCalculationPushButton,
           SIGNAL(clicked()),
           this,
           SLOT(mzCalculation()));

    connect(m_ui.isotopicPatternCalculationPushButton,
           SIGNAL(clicked()),
           this,
           SLOT(isotopicPatternCalculation()));


    m_ui.formulaSpinBox->setRange(-1000000000, 1000000000);
    m_ui.monomerSpinBox->setRange(-1000000000, 1000000000);
    m_ui.modifSpinBox->setRange(-1000000000, 1000000000);
    m_ui.sequenceSpinBox->setRange(-1000000000, 1000000000);
  
    m_recorderDlg.setParent(this, Qt::Dialog);
    m_chemPadDlg.setParent(this, Qt::Dialog);

    if (!m_polChemDef.renderXmlPolChemDefFile())
      return false;

    if (!populatePolChemDefComboBoxes())
      {
      QMessageBox::warning(0, 
                        tr("massXpert - Calculator"),
                        tr("Failed to populate the polymer"
                          " chemistry data comboboxes.\n"
                          "The calculator will not work properly."),
                        QMessageBox::Ok);

      return false;
      }
    
    if (!setupChemicalPad())
      return false;
    
    updateWindowTitle();

    return true;
  }


  const PolChemDef &
  CalculatorWnd::polChemDef()
  {
    return m_polChemDef;
  }



  void
  CalculatorWnd::updateWindowTitle()
  {
    setWindowTitle(tr("%1 %2[*]")
                .arg(tr("massXpert - Calculator:"))
                .arg(m_polChemDef.name()));
  }


  bool
  CalculatorWnd::populatePolChemDefComboBoxes()
  {
    int iter = 0;
    QStringList stringList;
  
    for (iter = 0; iter < m_polChemDef.monomerList().size(); ++iter)
      {
      Monomer *monomer = m_polChemDef.monomerList().at(iter);
      
      stringList << monomer->name();
      }
  
    m_ui.monomerComboBox->addItems(stringList);
    stringList.clear();
  
    for (iter = 0; iter < m_polChemDef.modifList().size(); ++iter)
      {
      Modif *modif = m_polChemDef.modifList().at(iter);
      
      stringList << modif->name();
      }

    m_ui.modifComboBox->addItems(stringList);
    stringList.clear();

    // Set the polymer chemistry definition type to its lineEdit.
    m_ui.polChemDefTypeLineEdit->setText(m_polChemDef.name());
  
    updateWindowTitle();
  
    return true;
  }
  

  bool
  CalculatorWnd::setupChemicalPad()
  {
    QString filePath;
    Application *application = static_cast<Application *>(qApp);

    // Each polymer chemistry definition might have a chemical pad
    // configuration file associated to it(simply by being stored in
    // the directory of the polymer chemistry definition files). 
    //
    // If a polymer chemistry definition file is loaded in the
    // calculator, try to get its corresponding chem_pad.conf file(which
    // might not exist, as it is not compulsory to have one).
    //
    // Otherwise, look in the user's config dir.

    if (m_polChemDef.name().isEmpty())
      {
      // See if the user has one chem_pad.conf file in her
      // configuration directory.

      filePath = application->configSettings()->userDataDir() + 
        "/chem_pad.conf";
      }
    else
      {
      // Get the directory path of the polymer chemistry definition
      // and construct a full pathname to the potentially existing
      // config file.
      
      filePath = m_polChemDef.dirPath() 
        + QDir::separator() + "chem_pad.conf";
      }
  
    QFile file(filePath);

    // Note that failing to setup the chemical pad is nothing so serious
    // that we return false.
    if (! file.open(QFile::ReadOnly)) 
      {
      QMessageBox::information(0, 
                          tr("massXpert - Calculator"),
                          tr("Chemical pad config file not found.\n"
                              "The chemical pad will not work properly."),
                          QMessageBox::Ok);
      return true;
      }
  
    bool ret = m_chemPadDlg.setup(filePath);
  
    return ret;
  }


  void 
  CalculatorWnd::recordResult()
  {
    Application *application = static_cast<Application *>(qApp);
    QLocale locale = application->locale();

    QString recorder = tr("Done: mono: %2 -- avg: %3\n")
      .arg(m_tempPonderable.mono(locale))
      .arg(m_tempPonderable.avg(locale));
  
    m_recorderDlg.record(recorder);
  }


  void
  CalculatorWnd::updateSeedResultLineEdits()
  {
    Application *application = static_cast<Application *>(qApp);
    QLocale locale = application->locale();

    m_ui.seedMonoMassLineEdit->setText(m_seedPonderable.mono(locale));
    m_ui.seedAvgMassLineEdit->setText(m_seedPonderable.avg(locale));
  
    // The m_resultPonderable must always be consistent with the data in
    // the corresponding lineEdits.
  
    m_resultPonderable.setMono(m_tempPonderable.mono());
    m_resultPonderable.setAvg(m_tempPonderable.avg());
  
    m_ui.resultMonoMassLineEdit->setText(m_resultPonderable.mono(locale));
    m_ui.resultAvgMassLineEdit->setText(m_resultPonderable.avg(locale));
  }


  void 
  CalculatorWnd::recorderDlgClosed()
  {
    m_ui.showRecorderCheckBox->setCheckState(Qt::Unchecked);
  }



  void 
  CalculatorWnd::chemPadDlgClosed()
  {
    m_ui.showChemPadCheckBox->setCheckState(Qt::Unchecked);
  }



  ////////////////////////////// SLOTS ///////////////////////////////
  void 
  CalculatorWnd::addToResult()
  {
    Application *application = static_cast<Application *>(qApp);
    QLocale locale = application->locale();
    QString mass;
    bool ok = true;

    // The data in the seed masses lineEdit widgets must be added to the
    // result masses.
  
    // Get the masses from the seed lineEdits and put these in their
    // respective ponderable.

    // mono
    mass = m_ui.seedMonoMassLineEdit->text();
    m_seedPonderable.setMono(locale.toDouble(mass, &ok));
  
    if (m_seedPonderable.mono() == 0 && !ok)
      {
      QMessageBox::warning(0, 
                        tr("massXpert - Calculator"),
                        tr("Error with seed mono mass"),
                        QMessageBox::Ok);
      return;
      }
  
    mass = m_ui.seedAvgMassLineEdit->text();
    m_seedPonderable.setAvg(locale.toDouble(mass, &ok));
  
    if (m_seedPonderable.avg() == 0 && !ok)
      {
      QMessageBox::warning(0, 
                        tr("massXpert - Calculator"),
                        tr("Error with seed avg mass"),
                        QMessageBox::Ok);
      return;
      }


    // Prepare the recorder string.
  
    QString recorder = tr("Added seed(mono: %1 ; avg: %2) \n"
                     "to result(was mono:%3 ; avg: %4) \n")
      .arg(m_seedPonderable.mono(locale))
      .arg(m_seedPonderable.avg(locale))
      .arg(m_resultPonderable.mono(locale))
      .arg(m_resultPonderable.avg(locale));
  
    // Make the calculations.
    m_resultPonderable.incrementMono(m_seedPonderable.mono());
    m_resultPonderable.incrementAvg(m_seedPonderable.avg());

    // Update the lineEdits.

    m_ui.resultMonoMassLineEdit->setText(m_resultPonderable.mono(locale));
    m_ui.resultAvgMassLineEdit->setText(m_resultPonderable.avg(locale));
  
    // And now append the new recorder string to the recorder textEdit.
    m_recorderDlg.record(recorder);
  }

  void 
  CalculatorWnd::sendToResult()
  {
    Application *application = static_cast<Application *>(qApp);
    QLocale locale = application->locale();
    QString mass;
    bool ok = true;
  
    // The seed masses must be sent(no computation here) to the results
    // masses.
  
    // Get the masses from the seed lineEdits and put these in their
    // respective ponderable.

    // mono
    mass = m_ui.seedMonoMassLineEdit->text();
    m_seedPonderable.setMono(locale.toDouble(mass, &ok));

    if (m_seedPonderable.mono() == 0 && !ok)
      {
      QMessageBox::warning(0, 
                        tr("massXpert - Calculator"),
                        tr("Error with seed mono mass"),
                        QMessageBox::Ok);
      return;
      }
  
    // avg
    mass = m_ui.seedAvgMassLineEdit->text();
    m_seedPonderable.setAvg(locale.toDouble(mass, &ok));
  
    if (m_seedPonderable.avg() == 0 && !ok)
      {
      QMessageBox::warning(0, 
                        tr("massXpert - Calculator"),
                        tr("Error with seed avg mass"),
                        QMessageBox::Ok);
      return;
      }
  
  
    // Prepare the recorder string.
  
    QString recorder = tr("Sent seed(mono: %1 ; avg: %2) \n"
                     "to result(was mono:%3 ; avg: %4) \n")
      .arg(m_seedPonderable.mono(locale))
      .arg(m_seedPonderable.avg(locale))
      .arg(m_resultPonderable.mono(locale))
      .arg(m_resultPonderable.avg(locale));
    
    m_resultPonderable.setMono(m_seedPonderable.mono());
    m_resultPonderable.setAvg(m_seedPonderable.avg());
  
    // Update the lineEdits.

    m_ui.resultMonoMassLineEdit->setText(m_resultPonderable.mono(locale));
    m_ui.resultAvgMassLineEdit->setText(m_resultPonderable.avg(locale));
  }

  void 
  CalculatorWnd::removeFromResult()
  {
    Application *application = static_cast<Application *>(qApp);
    QLocale locale = application->locale();
    QString mass;
    bool ok = true;
  
    // The data in the seed masses lineEdit widgets must be removed from
    // the result masses.
  
    // Get the masses from the seed lineEdits and put these in their
    // respective ponderable.

    // mono
    mass = m_ui.seedMonoMassLineEdit->text();
    m_seedPonderable.setMono(locale.toDouble(mass, &ok));

    if (m_seedPonderable.mono() == 0 && !ok)
      {
      QMessageBox::warning(0, 
                        tr("massXpert - Calculator"),
                        tr("Error with seed mono mass"),
                        QMessageBox::Ok);
      return;
      }
  
    // avg
    mass = m_ui.seedAvgMassLineEdit->text();
    m_seedPonderable.setAvg(locale.toDouble(mass, &ok));
  
    if (m_seedPonderable.avg() == 0 && !ok)
      {
      QMessageBox::warning(0, 
                        tr("massXpert - Calculator"),
                        tr("Error with seed avg mass"),
                        QMessageBox::Ok);
      return;
      }
  
  
    // Prepare the recorder string.
  
    QString recorder = tr("Removed seed(mono: %1 ; avg: %2) \n"
                     "from result(was mono:%3 ; avg: %4) \n")
      .arg(m_seedPonderable.mono(locale))
      .arg(m_seedPonderable.avg(locale))
      .arg(m_resultPonderable.mono(locale))
      .arg(m_resultPonderable.avg(locale));
  
    // Make the calculations.
    m_resultPonderable.decrementMono(m_seedPonderable.mono());
    m_resultPonderable.decrementAvg(m_seedPonderable.avg());

    // Update the lineEdits.

    m_ui.resultMonoMassLineEdit->setText(m_resultPonderable.mono(locale));
    m_ui.resultAvgMassLineEdit->setText(m_resultPonderable.avg(locale));
  
    // And now append the new recorder string to the recorder textEdit.
    m_recorderDlg.record(recorder);
  }

  void 
  CalculatorWnd::clearSeed()
  {
    m_seedPonderable.clearMasses();
  
    m_ui.seedMonoMassLineEdit->setText("");
    m_ui.seedAvgMassLineEdit->setText("");
  }

  void 
  CalculatorWnd::addToSeed()
  {
    Application *application = static_cast<Application *>(qApp);
    QLocale locale = application->locale();
    QString mass;
    bool ok = true;
  
    // The data in the result masses lineEdit widgets must be added to
    // the seed masses.

    // Get the masses from the seed lineEdits and put these in their
    // respective ponderable.

    // mono
    mass = m_ui.seedMonoMassLineEdit->text();
    m_seedPonderable.setMono(locale.toDouble(mass, &ok));

    if (m_seedPonderable.mono() == 0 && !ok)
      {
      QMessageBox::warning(0, 
                        tr("massXpert - Calculator"),
                        tr("Error with seed mono mass"),
                        QMessageBox::Ok);
      return;
      }
  
    // avg
    mass = m_ui.seedAvgMassLineEdit->text();
    m_seedPonderable.setAvg(locale.toDouble(mass, &ok));
  
    if (m_seedPonderable.avg() == 0 && !ok)
      {
      QMessageBox::warning(0, 
                        tr("massXpert - Calculator"),
                        tr("Error with seed avg mass"),
                        QMessageBox::Ok);
      return;
      }
  

    // Prepare the recorder string.
  
    QString recorder = tr("Added result(mono: %1 ; avg: %2) \n"
                     "to seed(was mono:%3 ; avg: %4) \n")
      .arg(m_resultPonderable.mono(locale))
      .arg(m_resultPonderable.avg(locale))
      .arg(m_seedPonderable.mono(locale))
      .arg(m_seedPonderable.avg(locale));
  
    // Make the calculations.
    m_seedPonderable.incrementMono(m_resultPonderable.mono());
    m_seedPonderable.incrementAvg(m_resultPonderable.avg());

    // Update the lineEdits.

    m_ui.seedMonoMassLineEdit->setText(m_seedPonderable.mono(locale));
    m_ui.seedAvgMassLineEdit->setText(m_seedPonderable.avg(locale));
  
    // And now append the new recorder string to the recorder textEdit.
    m_recorderDlg.record(recorder);
  }

  void 
  CalculatorWnd::sendToSeed()
  {
    Application *application = static_cast<Application *>(qApp);
    QLocale locale = application->locale();
  
    // The result masses must be sent(no computation here) to the seed
    // masses.
  
    // Prepare the recorder string.
  
    QString recorder = tr("Sent result(mono: %1 ; avg: %2) \n"
                     "to seed(was mono:%3 ; avg: %4) \n")
      .arg(m_resultPonderable.mono(locale))
      .arg(m_resultPonderable.avg(locale))
      .arg(m_seedPonderable.mono(locale))
      .arg(m_seedPonderable.avg(locale));
  
    m_seedPonderable.setMono(m_resultPonderable.mono());
    m_seedPonderable.setAvg(m_resultPonderable.avg());
  
    // Update the lineEdits.

    m_ui.seedMonoMassLineEdit->setText(m_seedPonderable.mono(locale));
    m_ui.seedAvgMassLineEdit->setText(m_seedPonderable.avg(locale));
  }

  void 
  CalculatorWnd::removeFromSeed()
  {
    Application *application = static_cast<Application *>(qApp);
    QLocale locale = application->locale();
    QString mass;
    bool ok = true;
  
    // The data in the result masses lineEdit widgets must be removed
    // from the seed masses.

    // Get the masses from the seed lineEdits and put these in their
    // respective ponderable.

    // mono
    mass = m_ui.seedMonoMassLineEdit->text();
    m_seedPonderable.setMono(locale.toDouble(mass, &ok));

    if (m_seedPonderable.mono() == 0 && !ok)
      {
      QMessageBox::warning(0, 
                        tr("massXpert - Calculator"),
                        tr("Error with seed mono mass"),
                        QMessageBox::Ok);
      return;
      }
  
    // avg
    mass = m_ui.seedAvgMassLineEdit->text();
    m_seedPonderable.setAvg(locale.toDouble(mass, &ok));
  
    if (m_seedPonderable.avg() == 0 && !ok)
      {
      QMessageBox::warning(0, 
                        tr("massXpert - Calculator"),
                        tr("Error with seed avg mass"),
                        QMessageBox::Ok);
      return;
      }
  

    // Prepare the recorder string.
  
    QString recorder = tr("Removed result(mono: %1 ; avg: %2) \n"
                     "from seed(was mono:%3 ; avg: %4) \n")
      .arg(m_resultPonderable.mono(locale))
      .arg(m_resultPonderable.avg(locale))
      .arg(m_seedPonderable.mono(locale))
      .arg(m_seedPonderable.avg(locale));
  
    // Make the calculations.
    m_seedPonderable.decrementMono(m_resultPonderable.mono());
    m_seedPonderable.decrementAvg(m_resultPonderable.avg());

    // Update the lineEdits.

    m_ui.seedMonoMassLineEdit->setText(m_seedPonderable.mono(locale));
    m_ui.seedAvgMassLineEdit->setText(m_seedPonderable.avg(locale));
  
    // And now append the new recorder string to the recorder textEdit.
    m_recorderDlg.record(recorder);
  }

  void 
  CalculatorWnd::clearResult()
  {
    m_resultPonderable.clearMasses();
  
    m_ui.resultMonoMassLineEdit->setText("");
    m_ui.resultAvgMassLineEdit->setText("");
  }




  void 
  CalculatorWnd::apply()
  {
    Application *application = static_cast<Application *>(qApp);
    QLocale locale = application->locale();
    QString mass;
    bool ok = true;
    bool calculationPerformed = false;
  
    if (m_polChemDef.atomList().size() == 0)
      {
      QMessageBox::warning(0, 
                        tr("massXpert - Calculator"),
                        tr("No atom list is available"),
                        QMessageBox::Ok);
      return;
      }
  
    // We have to iterate into all the relevant widgets and account
    // for the corresponding chemical entities.

    // The starting masses are either the seed masses or the result
    // masses. If the results masses lineEdits are empty, then we use
    // the seed masses. If not, then we prefer using the results masses
    // because this way the calculations are incremental, exactly as
    // when a desktop calculator is used.

    if (!m_ui.resultMonoMassLineEdit->text().isEmpty()
      || !m_ui.resultAvgMassLineEdit->text().isEmpty())
      {
      // The result masses lineEdits contain something, so we use
      // these to perform the calculations.

      // We use the m_tempPonderable as a repository for the masses
      // actually used for the computation, be them seed or result:

      m_tempPonderable.setMono(m_resultPonderable.mono());
      m_tempPonderable.setAvg(m_resultPonderable.avg());
      
      // Store the result masses in the seed masses object, because
      // we'll need these values to put them in the seed lineEdits to
      // provide one level of undo.

      m_seedPonderable.setMono(m_resultPonderable.mono());
      m_seedPonderable.setAvg(m_resultPonderable.avg());
      }
    else
      {
      // The result masses are empty, so consider using the seed
      // masses instead.
      
      // We use the m_tempPonderable as a repository for the masses
      // actually used for the computation, be them seed or result:

      if(m_ui.seedMonoMassLineEdit->text().isEmpty()
          || m_ui.seedAvgMassLineEdit->text().isEmpty())
        {
          // The seed masses are empty and the result masses
          // also. Thus we postulate the user just wants to start
          // fresh, that is seed masses are all 0.

          m_tempPonderable.setMono(0);
          m_tempPonderable.setAvg(0);
        }
      else
        {
          mass = m_ui.seedMonoMassLineEdit->text();
          m_tempPonderable.setMono(locale.toDouble(mass, &ok));
        
          if (m_tempPonderable.avg() == 0 && !ok)
            {
            QMessageBox::warning(0, 
                              tr("massXpert - Calculator"),
                              tr("Error with seed avg mass"),
                              QMessageBox::Ok);
            return;
            }
      
          mass = m_ui.seedAvgMassLineEdit->text();
          m_tempPonderable.setAvg(locale.toDouble(mass, &ok));
      
          if (m_tempPonderable.avg() == 0 && !ok)
            {
            QMessageBox::warning(0, 
                              tr("massXpert - Calculator"),
                              tr("Error with seed avg mass"),
                              QMessageBox::Ok);
            return;
            }
        }
      
      // Store these same seed masses in the seed masses object,
      // because we'll need these values to put them in the seed
      // lineEdits to provide one level of undo.

      m_seedPonderable.setMono(m_tempPonderable.mono());
      m_seedPonderable.setAvg(m_tempPonderable.avg());
      }
  
    // Prepare the recorder string.  
    QString recorder = 
      tr("===================================================================\n"
        "Seed masses: %1 -- %2\n")
      .arg(m_seedPonderable.mono())
      .arg(m_seedPonderable.avg());
  
    // And now append the new recorder string to the recorder textEdit.
    m_recorderDlg.record(recorder);
    
    // Finally we can start doing work with the chemical entities...

    // Atoms/Formulae
    int res = accountFormula();
  
    if (res == -1)
      QMessageBox::warning(0, 
                      tr("massXpert - Calculator"),
                      tr("Error accounting formula"),
                      QMessageBox::Ok);
    else if (res == 1)
      {
      recordResult();
      
      calculationPerformed = true;
      }
  

    if (!m_polChemDef.name().isEmpty())
      {
      // A polymer chemistry definition was loaded, account for its
      // potential chemical entities.

      res = accountMonomer();
      
      if(res == -1)
        QMessageBox::warning(0, 
                        tr("massXpert - Calculator"),
                        tr("Error accounting monomer"),
                        QMessageBox::Ok);
      else if (res == 1)
        {
          recordResult();
        
          calculationPerformed = true;
        }
      
      
      res = accountModif();
      
      if(res == -1)
        QMessageBox::warning(0, 
                        tr("massXpert - Calculator"),
                        tr("Error accounting modif"),
                        QMessageBox::Ok);
      else if (res == 1)
        {
          recordResult();

          calculationPerformed = true;
        }
      

      res = accountSequence();
      
      if(res == -1)
        QMessageBox::warning(0, 
                        tr("massXpert - Calculator"),
                        tr("Error accounting sequence"),
                        QMessageBox::Ok);
      else if (res == 1)
        {
          recordResult();

          calculationPerformed = true;
        }
      }
    // End of
    // if (!m_polChemDef.type().isEmpty())
  
    // Update the lineEdits only if at last one calculation was
    // performed.
  
    if (!calculationPerformed)
      return;
  
    updateSeedResultLineEdits();
  }


  void
  CalculatorWnd::mzCalculation()
  {
    MzCalculationDlg *dlg = 
      new MzCalculationDlg(this,
                      &m_polChemDef,
                      &m_polChemDef.ionizeRule());
  
    dlg->show();
  }


  void 
  CalculatorWnd::isotopicPatternCalculation()
  {
    IsotopicPatternCalculationDlg *dlg = 
      new IsotopicPatternCalculationDlg(this, m_polChemDef.atomList());
  
    dlg->show();
  }


  int
  CalculatorWnd::accountFormula(const QString &formula, int times) 
  {
    Application *application = static_cast<Application *>(qApp);
    QLocale locale = application->locale();
    QString text;
    int count;
  
  
    // This function might be called via the chemical pad, and thus has
    // to test existence of atom definitions. The 'apply()' function
    // does that test for when the calculation is triggered by clicking
    // on the apply button.

    if (m_polChemDef.atomList().size() == 0)
      {
      QMessageBox::warning(0, 
                        tr("massXpert - Calculator"),
                        tr("No atom list is available"),
                        QMessageBox::Ok);
      return false;
      }
  
    if (formula.isEmpty())
      {
      // No string passed as parameter, get the formula from its
      // corresponding lineEdit.
      text = m_ui.formulaLineEdit->text();
      
      if(text.isEmpty())
        return 0;
    
      // How many times should the formula be accounted for?
      count = m_ui.formulaSpinBox->value();
      
      if(count == 0)
        return 0;
      }
    else
      {
      text = formula;

      // The times param tells us how many times should the formula be
      // accounted for.
      count = times;
      }
  
    Modif fake(&m_polChemDef, "NOT_SET", text);
    if (!fake.calculateMasses())
      return -1;
  
    // Prepare the recorder string.  
    QString recorder = tr("Accounting formula: %1(%2 times)... ")
      .arg(text)
      .arg(count);
  
    // And now append the new recorder string to the recorder textEdit.
    m_recorderDlg.record(recorder);
  
    if (!fake.accountMasses(&m_tempPonderable.rmono(),
                       &m_tempPonderable.ravg(),
                       count))
      return -1;
  
    return 1;
  }


  int
  CalculatorWnd::accountMonomer()
  {
    Application *application = static_cast<Application *>(qApp);
    QLocale locale = application->locale();
    QString text;
  
    // Get to see if there is a necessity to account for the displayed
    // monomer.
  
    int count = m_ui.monomerSpinBox->value();
  
    if (count == 0)
      return 0;

    text = m_ui.monomerComboBox->currentText();
  
    // Locate and make a copy of the reference monomer, that we may not
    // use itself, as the formula parsing operation do modify the
    // object..
    Monomer monomer(&m_polChemDef, "NOT_SET");
  
    int index = -1;
    index = Monomer::isNameInList(text, 
                           m_polChemDef.monomerList(),
                           &monomer);
  
    // It cannot be that the text in the combobox does not correspond to
    // a known monomer.
    Q_ASSERT(index != -1);
  
    // Prepare the recorder string.
  
    QString recorder = tr("Accounting monomer: %1(%2 times)... ")
      .arg(monomer.name())
      .arg(count);
  
    // And now append the new recorder string to the recorder textEdit.
    m_recorderDlg.record(recorder);
  
    if (!monomer.accountMasses(&m_tempPonderable.rmono(),
                        &m_tempPonderable.ravg(),
                        count))
      return -1;
  
    return 1;
  }


  int
  CalculatorWnd::accountModif()
  {
    Application *application = static_cast<Application *>(qApp);
    QLocale locale = application->locale();
    QString text;

    // Get to see if there is a necessity to account for the displayed
    // modif.
  
    int count = m_ui.modifSpinBox->value();
  
    if (count == 0)
      return 0;

    text = m_ui.modifComboBox->currentText();
  
    // Locate the reference modif and make a copy of it, as we may not
    // use itself, as the parsing operation do modify the object.
    Modif modif(&m_polChemDef, "NOT_SET");
    int index = -1;

    index = Modif::isNameInList(text, 
                         m_polChemDef.modifList(),
                         &modif);
  
    // It cannot be that the text in the combobox does not correspond to
    // a known modif.
    Q_ASSERT(index != -1);
  
    // Prepare the recorder string.
  
    QString recorder = tr("Accounting modif: %1(%2 times)... ")
      .arg(modif.name())
      .arg(count);
  
    // And now append the new recorder string to the recorder textEdit.
    m_recorderDlg.record(recorder);
  
    if (!modif.accountMasses(&m_tempPonderable.rmono(),
                        &m_tempPonderable.ravg(),
                        count))
      return -1;
  
    return 1;
  }


  int
  CalculatorWnd::accountSequence()
  {
    Application *application = static_cast<Application *>(qApp);
    QLocale locale = application->locale();
    QString text;

    // Get to see if there is a necessity to account for the displayed
    // sequence.

    int count = m_ui.sequenceSpinBox->value();

    if (count == 0)
      return 0;

    text = m_ui.sequenceLineEdit->text();

    if (text.isEmpty())
      return  0;
  

    Sequence sequence(text);
  
    if (sequence.makeMonomerList(&m_polChemDef, false, 0) == - 1)
      return -1;
  
    // Prepare the recorder string.
  
    QString recorder = tr("Accounting sequence: %1(%2 times)... ")
      .arg(text)
      .arg(count);
  
    // And now append the new recorder string to the recorder textEdit.
    m_recorderDlg.record(recorder);
  
    for (int iter = 0; iter < sequence.size(); ++iter)
      {
      const Monomer *monomer = sequence.at(iter);
      Q_ASSERT(monomer);
      
      if(!monomer->accountMasses(&m_tempPonderable.rmono(),
                             &m_tempPonderable.ravg(),
                             count))
        return -1;
      }
  
    return 1;
  }


  void 
  CalculatorWnd::showRecorder(int state)
  {
    if (state == Qt::Checked)
      {
      QSettings settings 
     (static_cast<Application *>(qApp)->configSettingsFilePath(), 
       QSettings::IniFormat);
      m_recorderDlg.restoreGeometry 
       (settings.value("calculator_recorder_dlg/geometry").toByteArray());

      m_recorderDlg.show();
      }
    else
      {
      QSettings settings 
     (static_cast<Application *>(qApp)->configSettingsFilePath(), 
       QSettings::IniFormat);
      settings.setValue("calculator_recorder_dlg/geometry", 
                    m_recorderDlg.saveGeometry());
      
      m_recorderDlg.hide();
      }
  }

  void 
  CalculatorWnd::showChemPad(int state)
  {
    if (state == Qt::Checked)
      {
      QSettings settings 
     (static_cast<Application *>(qApp)->configSettingsFilePath(), 
       QSettings::IniFormat);
      m_chemPadDlg.restoreGeometry 
       (settings.value("calculator_chem_pad_dlg/geometry").toByteArray());

      m_chemPadDlg.show();
      }
    else
      {
      QSettings settings 
     (static_cast<Application *>(qApp)->configSettingsFilePath(), 
       QSettings::IniFormat);
      settings.setValue("calculator_chem_pad_dlg/geometry", 
                    m_chemPadDlg.saveGeometry());
      
      m_chemPadDlg.hide();
      }
  }

} // namespace massXpert

Generated by  Doxygen 1.6.0   Back to index