00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00019
00027
00028
00029
00031
00032
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
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
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
00074 options->ToolButtonUpdate->setIconSet(IconSets::getIconSet(IconSets::Start));
00075 options->ToolButtonCancel->setIconSet(IconSets::getIconSet(IconSets::Stop));
00076
00077
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
00084 for(unsigned int i = 1; i <= AtomSet::maxElements; i++)
00085 options->ComboBoxAtom->insertItem(AtomSet::numToAtom(i));
00086
00087
00088 options->ColorButtonPositive->setColor(QColor(0, 0, 255));
00089 options->ColorButtonNegative->setColor(QColor(255, 0, 0));
00090
00091
00092 options->LineEditProbability->setValidator(new QDoubleValidator(this));
00093
00094
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
00111
00112
00113
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
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
00170 updateColors();
00171
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
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
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();
00311
00312 view->setMaximumRadius(calcThread->boundingSphereRadius());
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