newatombase.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                         newatombase.cpp  -  description
00003                              -------------------
00004     begin                : Sun Jul 31 2005
00005     copyright            : (C) 2005-2006 by Ben Swerts
00006     email                : bswerts@users.sourceforge.net
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00019 
00026 
00027 
00028 
00030 
00031 // C++ header files
00032 #include <cassert>
00033 
00034 // Qt header files
00035 #include <qbuttongroup.h>
00036 #include <qlabel.h>
00037 #include <qlineedit.h>
00038 #include <qpushbutton.h>
00039 #include <qradiobutton.h>
00040 #include <qspinbox.h>
00041 #include <qwidgetstack.h>
00042 
00043 // Xbrabo header files
00044 #include "atomset.h"
00045 #include "newatombase.h"
00046 #include "point3d.h"
00047 
00051 
00053 NewAtomBase::NewAtomBase(AtomSet* atomset, QWidget* parent, const char* name, bool modal, WFlags fl) : NewAtomWidget(parent, name, modal, fl),
00055   atoms(atomset)
00056 {
00057   assert(atomset != 0);
00058 
00059   connect(PushButtonAdd, SIGNAL(clicked()), this, SLOT(addAtom()));
00060   connect(PushButtonClose, SIGNAL(clicked()), this, SLOT(hide()));
00061   connect(ButtonGroupType, SIGNAL(clicked(int)), this, SLOT(updateSelectedAtom(int)));
00062   connect(ButtonGroupCoordinates, SIGNAL(clicked(int)), WidgetStackCoordinates, SLOT(raiseWidget(int)));
00063   connect(ButtonGroupCoordinates, SIGNAL(clicked(int)), this, SLOT(checkAdd()));
00064   connect(ButtonGroupType, SIGNAL(clicked(int)), this, SLOT(updateICAtoms()));
00065   connect(SpinBoxReference1, SIGNAL(valueChanged(int)), this, SLOT(updateICAtoms()));
00066   connect(SpinBoxReference2, SIGNAL(valueChanged(int)), this, SLOT(updateICAtoms()));
00067   connect(SpinBoxReference3, SIGNAL(valueChanged(int)), this, SLOT(updateICAtoms()));
00068 
00069   updateAtomLimits();
00070 }
00071 
00073 NewAtomBase::~NewAtomBase()
00075 {
00076 }
00077 
00081 
00083 void NewAtomBase::updateAtomLimits()
00086 {
00087   const unsigned int numAtoms = atoms->count();
00088   if(numAtoms == 0)
00089   {
00090     // no atoms present, so none can be used as a reference
00091     RadioButtonInternal->setEnabled(false);
00092     RadioButtonCartesian->setChecked(true);
00093     WidgetStackCoordinates->raiseWidget(0);
00094     RadioButtonRelative->setEnabled(false);
00095     RadioButtonAbsolute->setChecked(true);
00096     SpinBoxRelative->setEnabled(false);
00097   }
00098   else
00099   {
00100     // at least one atom is present
00101     RadioButtonInternal->setEnabled(true);
00102     RadioButtonRelative->setEnabled(true);
00103     SpinBoxRelative->setEnabled(true);
00104     SpinBoxRelative->setMaxValue(numAtoms);
00105     SpinBoxReference1->setMaxValue(numAtoms);
00106     SpinBoxReference2->setMaxValue(numAtoms);
00107     SpinBoxReference3->setMaxValue(numAtoms);
00108     if(!SpinBoxReference2->isEnabled() && numAtoms > 1)
00109       SpinBoxReference2->setValue(numAtoms);
00110     SpinBoxReference2->setEnabled(numAtoms > 1);
00111     if(!SpinBoxReference3->isEnabled() && numAtoms > 2)
00112       SpinBoxReference3->setValue(numAtoms);
00113     SpinBoxReference3->setEnabled(numAtoms > 2);
00114     LineEditAngle->setEnabled(numAtoms > 1);
00115     TextLabelAngle1->setEnabled(numAtoms > 1);
00116     TextLabelAngle2->setEnabled(numAtoms > 1);
00117     TextLabelAngle3->setEnabled(numAtoms > 1);
00118     TextLabelAngleA->setEnabled(numAtoms > 1);
00119     TextLabelAngleB->setEnabled(numAtoms > 1);
00120     TextLabelAngleC->setEnabled(numAtoms > 1);
00121     TextLabelAngleD->setEnabled(numAtoms > 1);
00122     TextLabelAngleE->setEnabled(numAtoms > 1);
00123     LineEditTorsion->setEnabled(numAtoms > 2);
00124     TextLabelTorsion1->setEnabled(numAtoms > 2);
00125     TextLabelTorsion2->setEnabled(numAtoms > 2);
00126     TextLabelTorsion3->setEnabled(numAtoms > 2);
00127     TextLabelTorsion4->setEnabled(numAtoms > 2);
00128     TextLabelTorsionA->setEnabled(numAtoms > 2);
00129     TextLabelTorsionB->setEnabled(numAtoms > 2);
00130     TextLabelTorsionC->setEnabled(numAtoms > 2);
00131     TextLabelTorsionD->setEnabled(numAtoms > 2);
00132     TextLabelTorsionE->setEnabled(numAtoms > 2);
00133     TextLabelTorsionF->setEnabled(numAtoms > 2);
00134     updateICAtoms();
00135   }
00136 }
00137 
00141 
00143 void NewAtomBase::showEvent(QShowEvent* e)
00145 {
00146   updateAtomLimits();
00147   NewAtomWidget::showEvent(e);
00148 }
00149 
00153 
00155 void NewAtomBase::addAtom()
00157 {
00158   unsigned int selectedAtomType = ButtonGroupType->selectedId();
00159   if(RadioButtonCartesian->isOn())
00160   {
00162     if(RadioButtonAbsolute->isOn())
00163       // absolute
00164       atoms->addAtom(LineEditX->text().toDouble(), LineEditY->text().toDouble(), LineEditZ->text().toDouble(), selectedAtomType);
00165     else
00166       // relative      
00167       atoms->addAtom(LineEditX->text().toDouble() + atoms->x(SpinBoxRelative->value() - 1), LineEditY->text().toDouble() + atoms->y(SpinBoxRelative->value() - 1), LineEditZ->text().toDouble() + atoms->z(SpinBoxRelative->value() - 1), selectedAtomType);
00168   }
00169   else
00170   {
00172     // get some indices
00173     const unsigned int newIndex = atoms->count();
00174     const unsigned int refIndex1 = SpinBoxReference1->value() - 1;
00175     const unsigned int refIndex2 = SpinBoxReference2->value() - 1;
00176     const unsigned int refIndex3 = SpinBoxReference3->value() - 1;
00177     // add the atom with the correct bond distance from the first reference atom (along the X-axis)
00178     atoms->addAtom(atoms->x(refIndex1) + LineEditBond->text().toDouble(), atoms->y(refIndex1), atoms->z(refIndex1), selectedAtomType);
00179     if(newIndex > 1)
00180     {
00181       // only set the angle when more than one atom is present 
00182       // get the current angle
00183       double angle = atoms->angle(newIndex, refIndex1, refIndex2);
00184       if(fabs(angle) < Point3D<double>::TOLERANCE || fabs(angle - 180) < Point3D<double>::TOLERANCE || fabs(angle + 180) < Point3D<double>::TOLERANCE)
00185       {
00186         qDebug("current angle is %f when using X-axis, so changing to Y-axis", angle); 
00187         // bad initial axis chosen, try the Y-axis
00188         atoms->setX(newIndex, atoms->x(refIndex1));
00189         atoms->setY(newIndex, atoms->y(refIndex1) + LineEditBond->text().toDouble());
00190         angle = atoms->angle(newIndex, refIndex1, refIndex2);
00191         /*if(abs(angle) < Point3D<double>::TOLERANCE)
00192         {
00193           // again bad initial axis chosen, try the Z-axis, last chance
00194           atoms->setY(newIndex, atoms->y(refIndex1));
00195           atoms->setZ(newIndex, atoms->z(refIndex1) + LineEditBond->text().toDouble());
00196           angle = atoms->angle(newIndex, refIndex1, refIndex2);
00197         }*/
00198       }
00199       // change it to the desired value
00200       atoms->changeAngle(LineEditAngle->text().toDouble() - angle, newIndex, refIndex1, refIndex2, false);
00201       if(newIndex > 2)
00202       {
00203         // only set the torsion when more than 2 atoms were present
00204         // get the current torsion
00205         const double torsion = atoms->torsion(newIndex, refIndex1, refIndex2, refIndex3);
00206         // change it to the desired value
00207         atoms->changeTorsion(torsion - LineEditTorsion->text().toDouble(), newIndex, refIndex1, refIndex2, refIndex3, false);
00208       }
00209     }
00210   }
00211   emit atomAdded();
00212   /*
00213   qDebug("finished, coordinates of all atoms:");
00214   for(unsigned int i = 0; i < atoms->count(); i++)
00215     qDebug("atom i: %f %f %f",atoms->x(i), atoms->y(i), atoms->z(i));
00216   */
00217   updateAtomLimits();
00218 }
00219 
00221 void NewAtomBase::updateICAtoms()
00225 {
00226   QString newAtomSymbol = TextLabelSymbol->text().stripWhiteSpace() + QString::number(atoms->count() + 1);
00227   QString refAtom1 = AtomSet::numToAtom(atoms->atomicNumber(SpinBoxReference1->value() - 1)).stripWhiteSpace() + QString::number(SpinBoxReference1->value());
00228   QString refAtom2 = AtomSet::numToAtom(atoms->atomicNumber(SpinBoxReference2->value() - 1)).stripWhiteSpace() + QString::number(SpinBoxReference2->value());
00229   QString refAtom3 = AtomSet::numToAtom(atoms->atomicNumber(SpinBoxReference3->value() - 1)).stripWhiteSpace() + QString::number(SpinBoxReference3->value());
00230 
00232   TextLabelBond1->setText(newAtomSymbol);
00233   TextLabelBond2->setText(refAtom1);
00235   TextLabelAngle1->setText(newAtomSymbol);
00236   TextLabelAngle2->setText(refAtom1);
00237   TextLabelAngle3->setText(refAtom2);
00239   TextLabelTorsion1->setText(newAtomSymbol);
00240   TextLabelTorsion2->setText(refAtom1);
00241   TextLabelTorsion3->setText(refAtom2);
00242   TextLabelTorsion4->setText(refAtom3);
00243 
00244   checkAdd();
00245 }
00246 
00248 void NewAtomBase::updateSelectedAtom(int number)
00251 {
00252   TextLabelSymbol->setText(AtomSet::numToAtom(number));
00253   TextLabelNumber->setText(QString::number(number));
00254 }
00255 
00257 void NewAtomBase::checkAdd()
00260 {
00261   if(RadioButtonCartesian->isOn())
00262     // always possible to add an atom
00263     PushButtonAdd->setEnabled(true);
00264   else
00265   {
00266     // for Internal Coordinates, adding is only possible under specific circumstances
00267     const unsigned int refAtom1 = SpinBoxReference1->value();
00268     const unsigned int refAtom2 = SpinBoxReference2->value();
00269     const unsigned int refAtom3 = SpinBoxReference3->value();
00270     if(   (SpinBoxReference2->isEnabled() && (refAtom1 == refAtom2)) // ref1 cannot be equal to ref2
00271        || (SpinBoxReference3->isEnabled() && (refAtom1 == refAtom3)) // ref1 cannot be equal to ref3
00272        || (SpinBoxReference3->isEnabled() && (refAtom2 == refAtom3)) // ref2 cannot be equal to ref3
00273        || (fabs(LineEditBond->text().toDouble()) < 0.1)) // bond distance should be at least 0.1
00274       PushButtonAdd->setEnabled(false);
00275     else
00276       PushButtonAdd->setEnabled(true);
00277   }
00278 }
00279 

Generated on Fri May 19 14:31:55 2006 for Brabosphere by  doxygen 1.4.6-NO