orbitalviewerbase.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                      orbitalviewerbase.cpp  -  description
00003                              -------------------
00004     begin                : Thu Nov 4 2004
00005     copyright            : (C) 2004-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 
00027 
00028 
00029 
00031 
00032 // Qt header files
00033 #include <qcombobox.h>
00034 #include <qlabel.h>
00035 #include <qlayout.h>
00036 #include <qlineedit.h>
00037 #include <qprogressbar.h>
00038 #include <qslider.h>
00039 #include <qspinbox.h>
00040 #include <qtimer.h>
00041 #include <qtoolbutton.h>
00042 #include <qvalidator.h>
00043 #include <qwhatsthis.h>
00044 
00045 // Xbrabo header files
00046 #include "atomset.h"
00047 #include "colorbutton.h"
00048 #include "glorbitalview.h"
00049 #include "iconsets.h"
00050 #include "orbitaloptionswidget.h"
00051 #include "orbitalthread.h"
00052 #include "orbitalviewerbase.h"
00053 #include "version.h"
00054 
00058 
00060 OrbitalViewerBase::OrbitalViewerBase(QWidget* parent, const char* name, bool modal, WFlags fl) : QDialog(parent, name, modal, fl),
00061   calcThread(0)
00063 {
00064   // Construct the widget layout
00065   BigLayout = new QHBoxLayout(this, 10);
00066     options = new OrbitalOptionsWidget(this);
00067     BigLayout->addWidget(options);
00068     view = new GLOrbitalView(this);
00069     BigLayout->addWidget(view);
00070 
00071   timer = new QTimer(this);
00072    
00073   // set the icons for the options widget
00074   options->ToolButtonUpdate->setIconSet(IconSets::getIconSet(IconSets::Start));
00075   options->ToolButtonCancel->setIconSet(IconSets::getIconSet(IconSets::Stop));
00076 
00077   // Keep the options as small as possible
00078   options->setFixedWidth(options->width());
00079   options->setMaximumWidth(options->width());
00080   view->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
00081   resize(options->width()*3, height());
00082 
00083   // Fill the combobox for atoms
00084   for(unsigned int i = 1; i <= AtomSet::maxElements; i++)
00085     options->ComboBoxAtom->insertItem(AtomSet::numToAtom(i));
00086 
00087   // set the initial colors
00088   options->ColorButtonPositive->setColor(QColor(0, 0, 255));
00089   options->ColorButtonNegative->setColor(QColor(255, 0, 0));
00090   
00091   // set a validator
00092   options->LineEditProbability->setValidator(new QDoubleValidator(this));
00093 
00094   // do some connections
00095   connect(options->SpinBoxN, SIGNAL(valueChanged(int)), this, SLOT(adjustL(int)));
00096   connect(options->SpinBoxL, SIGNAL(valueChanged(int)), this, SLOT(adjustM(int)));
00097   connect(options->ColorButtonPositive, SIGNAL(newColor(QColor*)), this, SLOT(updateColors()));
00098   connect(options->ComboBoxType, SIGNAL(activated(int)), this, SLOT(updateTypeOptions(int)));
00099   connect(options->SliderDots, SIGNAL(valueChanged(int)), options->SpinBoxDots, SLOT(setValue(int)));
00100   connect(options->SpinBoxDots, SIGNAL(valueChanged(int)), options->SliderDots, SLOT(setValue(int)));  
00101     
00102   connect(options->ToolButtonUpdate, SIGNAL(clicked()), this, SLOT(update()));
00103   connect(options->PushButtonReset, SIGNAL(clicked()), view, SLOT(resetView()));
00104   connect(options->PushButtonSave, SIGNAL(clicked()), view, SLOT(saveImage()));
00105   connect(options->ToolButtonCancel, SIGNAL(clicked()), this, SLOT(cancelCalculation()));
00106   connect(options->PushButtonClose, SIGNAL(clicked()), this, SLOT(close()));
00107 
00108   connect(timer, SIGNAL(timeout()), view, SLOT(updateGL()));  
00109 
00110   //connect(view, SIGNAL(maximumProgress(int)), options->ProgressBar, SLOT(setTotalSteps(int)));
00111   //connect(view, SIGNAL(currentProgress(int)), options->ProgressBar, SLOT(setProgress(int)));
00112   
00113   // What's This
00114   QWhatsThis::add(view,
00115     tr("<p>Shows the hydrogen-like orbital in 3D. This view can be manipulated in exactly the "
00116        "same way as the 3D molecular scene in calculations (read its context sensitive help for "
00117        "details). This means the orbital can be translated, rotated and zoomed using the mouse "
00118        "and/or keyboard.</p>"));
00119   QWhatsThis::add(options->ToolButtonUpdate, tr("Starts calculating the orbital with the requested characteristics."));
00120   QWhatsThis::add(options->ToolButtonCancel, tr("Stops the calculation in progress."));
00121 
00122   //update the view
00123   updateTypeOptions(0);
00124   update();
00125   setCaption(Version::appName + " - " + tr("Visualizing hydrogen-like orbitals"));
00126 }
00127 
00129 OrbitalViewerBase::~OrbitalViewerBase()
00131 {
00132   if(calcThread != 0)
00133   {
00134     if(calcThread->running())
00135     {
00136       calcThread->stop();
00137       calcThread->wait();
00138     }
00139     delete calcThread;
00140   }
00141 }
00142 
00146 
00148 void OrbitalViewerBase::customEvent(QCustomEvent* e)
00150 {
00152   if(e->type() == 1001)
00153     options->ProgressBar->setProgress(*(static_cast<unsigned int*>(e->data())));
00155   else if(e->type() == 1002)
00156     finishCalculation();
00157 }
00158 
00162 
00164 void OrbitalViewerBase::update()
00166 {
00167   options->ToolButtonUpdate->setEnabled(false);
00168   options->ToolButtonCancel->setEnabled(true);
00169   // update the view
00170   updateColors();
00171   // setup the progressbar
00172   options->ProgressBar->setProgress(0);
00173   const int resolution = options->SliderResolution->value();
00174   const int numDots = options->SpinBoxDots->value();
00175   switch(options->ComboBoxType->currentItem())
00176   {
00177     case OrbitalThread::IsoProbability:
00178     case OrbitalThread::AccumulatedProbability:
00179     case OrbitalThread::AngularPart: 
00180       options->ProgressBar->setTotalSteps(resolution*resolution);
00181       break;
00182     case OrbitalThread::Density: 
00183       options->ProgressBar->setTotalSteps(numDots);
00184       break;
00185     case OrbitalThread::RadialPart: 
00186       options->ProgressBar->setTotalSteps(10*resolution);
00187       break; 
00188   }
00189 
00190   // start a computation thread
00191   calcThread = new OrbitalThread(this, view->getMutex(), view->getCoordinates(), 
00192                                  static_cast<unsigned int>(options->ComboBoxType->currentItem()),
00193                                  static_cast<unsigned int>(options->ComboBoxAtom->currentItem() + 1),
00194                                  static_cast<unsigned int>(options->SpinBoxN->value()),
00195                                  static_cast<unsigned int>(options->SpinBoxL->value()),
00196                                  static_cast<int>(options->SpinBoxM->value()),
00197                                  static_cast<float>(options->SliderResolution->value()),
00198                                  options->LineEditProbability->text().toFloat(),
00199                                  static_cast<unsigned int>(options->SpinBoxDots->value()));
00200   calcThread->start(QThread::LowPriority);
00201 
00202   // update the scene every 100 ms
00203   timer->start(100);
00204 }
00205 
00207 void OrbitalViewerBase::adjustL(int newN)
00210 {
00211   options->SpinBoxL->setMaxValue(newN - 1);
00212 }
00213 
00215 void OrbitalViewerBase::adjustM(int newL)
00218 {
00219   options->SpinBoxM->setMinValue(-newL);
00220   options->SpinBoxM->setMaxValue(newL);
00221 }
00222 
00224 void OrbitalViewerBase::updateColors()
00226 {
00227   view->updateColors(options->ColorButtonPositive->color(), options->ColorButtonNegative->color());
00228 }
00229 
00231 void OrbitalViewerBase::updateTypeOptions(int type)
00233 {
00234   switch(type)
00235   {
00236     case OrbitalThread::IsoProbability:
00237             options->LabelResolution->setEnabled(true);
00238             options->SliderResolution->setEnabled(true);
00239             options->LabelProbability->setEnabled(true);
00240             options->LineEditProbability->setEnabled(true);
00241             options->LabelDots->setEnabled(false);
00242             options->SliderDots->setEnabled(false);
00243             options->SpinBoxDots->setEnabled(false);
00244             if(options->LineEditProbability->text().toFloat() > 0.1f) 
00245               options->LineEditProbability->setText("0.0001");            
00246             break;
00247     case OrbitalThread::AccumulatedProbability:
00248             options->LabelResolution->setEnabled(true);
00249             options->SliderResolution->setEnabled(true);
00250             options->LabelProbability->setEnabled(true);
00251             options->LineEditProbability->setEnabled(true);
00252             options->LabelDots->setEnabled(false);
00253             options->SliderDots->setEnabled(false);
00254             options->SpinBoxDots->setEnabled(false);
00255             if(options->LineEditProbability->text().toFloat() < 0.1f)
00256             options->LineEditProbability->setText("0.95");
00257             break;
00258     case OrbitalThread::Density:
00259             options->LabelResolution->setEnabled(false);
00260             options->SliderResolution->setEnabled(false);
00261             options->LabelProbability->setEnabled(false);
00262             options->LineEditProbability->setEnabled(false);
00263             options->LabelDots->setEnabled(true);
00264             options->SliderDots->setEnabled(true);
00265             options->SpinBoxDots->setEnabled(true);
00266             break;
00267     case OrbitalThread::RadialPart:
00268             options->LabelResolution->setEnabled(true);
00269             options->SliderResolution->setEnabled(true);
00270             options->LabelProbability->setEnabled(false);
00271             options->LineEditProbability->setEnabled(false);
00272             options->LabelDots->setEnabled(false);
00273             options->SliderDots->setEnabled(false);
00274             options->SpinBoxDots->setEnabled(false);
00275             break;
00276     case OrbitalThread::AngularPart:
00277             options->LabelResolution->setEnabled(true);
00278             options->SliderResolution->setEnabled(true);
00279             options->LabelProbability->setEnabled(false);
00280             options->LineEditProbability->setEnabled(false);
00281             options->LabelDots->setEnabled(false);
00282             options->SliderDots->setEnabled(false);
00283             options->SpinBoxDots->setEnabled(false);
00284   }
00285 }
00286 
00288 void OrbitalViewerBase::cancelCalculation()
00290 {
00291   if(calcThread == 0)
00292     return;
00293 
00294   calcThread->stop();
00295 }
00296 
00300 
00302 void OrbitalViewerBase::finishCalculation()
00304 {
00306   if(calcThread == 0)
00307     return;
00308 
00309   if(!calcThread->finished())
00310     calcThread->wait(); // blocking wait
00311 
00312   view->setMaximumRadius(calcThread->boundingSphereRadius()); // this forces a zoomfit and a redraw
00313 
00314   delete calcThread;
00315   calcThread = 0;
00316 
00318   options->ToolButtonCancel->setEnabled(false);
00319   options->ToolButtonUpdate->setEnabled(true);     
00320   options->ProgressBar->setProgress(0);
00321 
00323   timer->stop();
00324 }
00325 

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