xbraboview.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                         xbraboview.cpp  -  description
00003                              -------------------
00004     begin                : Fri Jul 19 2002
00005     copyright            : (C) 2002-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 
00025 
00026 
00027 
00029 
00030 // C++ header files
00031 #include <cmath> 
00032 
00033 // Qt header files
00034 #include <qapplication.h>
00035 #include <qcheckbox.h>
00036 #include <qcombobox.h>
00037 #include <qcursor.h>
00038 #include <qdir.h>
00039 #include <qdom.h>
00040 #include <qlabel.h>
00041 #include <qlayout.h>
00042 #include <qlistview.h>
00043 #include <qmessagebox.h>
00044 #include <qpixmap.h>
00045 #include <qpopupmenu.h>
00046 #include <qprogressbar.h>
00047 #include <qnamespace.h>
00048 #include <qrect.h>
00049 #include <qsplitter.h>
00050 #include <qstringlist.h>
00051 #include <qtextedit.h>
00052 #include <qtimer.h>
00053 #include <qwhatsthis.h>
00054 
00055 // Xbrabo header files
00056 #include "atomset.h"
00057 #include "brabobase.h"
00058 #include "calculation.h"
00059 #include "crdfactory.h"
00060 #include "domutils.h"
00061 #include "glmoleculeview.h"
00062 #include "globalbase.h"
00063 #include "iconsets.h"
00064 #include "moleculepropertieswidget.h"
00065 #include "outputchooserwidget.h"
00066 #include "paths.h"
00067 #include "relaxbase.h"
00068 #include "statustext.h"
00069 #include "textviewwidget.h"
00070 #include "xbraboview.h"
00071 #include "version.h"
00072 
00073 #if defined(USE_KMDI) || defined(USE_KMDI_DLL)
00074 #define QextMdiChildView KMdiChildView
00075 #endif
00076 
00080 
00082 XbraboView::XbraboView(QWidget* mainWin, QWidget* parent, QString title, const char* name, WFlags f) : QextMdiChildView( title, parent, name, f),
00083   globalSetup(0),
00084   braboSetup(0),
00085   relaxSetup(0),
00086   mainWindow(mainWin),
00087   calcDate(QDateTime::currentDateTime(Qt::UTC).toString(Qt::ISODate)),
00088   calculation(0)
00092 {
00093   calcCounter++;
00094   calcDefaultName = tr("unnamed") + QString::number(calcCounter);
00095   calcFileName = calcDefaultName;
00096 
00098   //QGLFormat f;
00099   //f.setAlpha(true);  // needed for antialiasing
00100   //QGLFormat::setDefaultFormat(f);
00101 
00103   atoms = new AtomSet();
00104   
00106   BigLayout = new QVBoxLayout(this,10);
00107     Splitter = new QSplitter(this, 0);
00108     Splitter->setOrientation(QSplitter::Vertical);
00109     Splitter->setOpaqueResize(true);
00110       MoleculeView = new GLMoleculeView(atoms, Splitter);
00111       MoleculeView->setSizePolicy(QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding, false));
00112       QWidget* LayoutWidget = new QWidget(Splitter);
00113       StatusLayout = new QVBoxLayout(LayoutWidget,0);
00114         TextLabelStatus = new QLabel(LayoutWidget);
00115         TextLabelStatus->setText(tr("Status"));
00116         TextEditStatus = new StatusText(LayoutWidget);
00117         StatusLayout->addWidget(TextLabelStatus);
00118         StatusLayout->addWidget(TextEditStatus);
00119     BigLayout->addWidget(Splitter);
00120     ProgressLayout = new QHBoxLayout(BigLayout);
00121       TextLabelProgress = new QLabel(this);
00122       TextLabelProgress->setText(tr("Progress"));
00123       ProgressBar = new QProgressBar(this);
00124       ProgressBar->setCenterIndicator(true);
00125       ProgressLayout->addWidget(TextLabelProgress);
00126       ProgressLayout->addWidget(ProgressBar);
00127     // default size is 400x400
00128     MoleculeView->resize(MoleculeView->width(),350);
00129     MoleculeView->resetView();
00130 
00132   connect(TextEditStatus, SIGNAL(rightButtonClicked()),this, SLOT(popup()));
00133 #if defined(USE_KMDI) || defined(USE_KMDI_DLL)
00134   connect(this, SIGNAL(gotFocus(KMdiChildView*)), this, SIGNAL(changed()));
00135 #else
00136   connect(this, SIGNAL(gotFocus(QextMdiChildView*)), this, SIGNAL(changed()));
00137 #endif
00138   connect(MoleculeView, SIGNAL(modified()), this, SLOT(setModified()));
00139   connect(MoleculeView, SIGNAL(changed()), this, SIGNAL(changed()));
00140   
00142   QWhatsThis::add(MoleculeView, 
00143     tr("<p>Shows the molecular system in 3D. Pressing the right mouse button "
00144        "opens a context menu containing the most frequently used actions from the "
00145        "Molecule menu.</p>"
00146        "<p>The scene can be manipulated with the mouse and the keyboard. Here follows "
00147        "a list of possible manipulations and ways to invoke them. Directions are indicated "
00148        "either by the arrow keys or by dragging the mouse in the desired direction while "
00149        "pressing the left mouse button.</p>"
00150        "<ul>"
00151        "<li>Rotate around the X-axis: <em>Up</em> and <em>Down</em>"
00152        "<li>Rotate around the Y-axis: <em>Left</em> and <em>Right</em>"
00153        "<li>Rotate around the Z-axis: <em>Shift+Left</em> and <em>Shift+Right</em>"
00154        "<li>Zoom: <em>Shift+Up</em> and <em>Shift+Down</em> or using the scrollwheel of the mouse"
00155        "<li>Translate horizontally: <em>Ctrl+Left</em> and <em>Ctrl+Right</em>"
00156        "<li>Translate vertically: <em>Ctrl+Up</em> and <em>Ctrl+Down</em>"       
00157        "</ul>"
00158        "<p>Atoms can be selected/deselected by clicking on them with the left mouse button. When a "
00159        "selection is present, all actions shown above can be applied to the selection only. This can "
00160        "be done either by holding the <em>Alt</em> modifier or selecting the <em>Manipulate Selection</em> "
00161        "button/menu-entry. Using the scrollwheel of the mouse will still zoom the entire system.</p>"
00162        "<p>When a bond, angle or torsion angle is selected, the internal coordinate (whose value is always visible) "
00163        "can be altered by using <em>Ctrl+Shift+Left</em> and <em>Ctrl+Shift+Right</em>.</p>"
00164       ));
00165   QWhatsThis::add(TextEditStatus,
00166     tr("<p>Shows a log of informational messages mostly when a calculation is running. Results presented "
00167        "here will not be saved but are always accessible through other means. Data can, however, be "
00168        "copied using the standard <em>Copy</em> action.</p><p>The size of this box can be changed by dragging "
00169        "the bar between this box and the 3D view above (not visible in all skins).</p>"));
00170   QWhatsThis::add(ProgressBar,
00171     tr("Indicates the progress of a running calculation. It will be reset shortly after a calculation has finished."));
00172 
00174   setModified(false);
00175 }
00176 
00178 XbraboView::~XbraboView()
00180 {
00181   delete atoms;
00182 }
00183 
00185 unsigned int XbraboView::calculationType() const
00191 {  
00192   if(globalSetup == 0)
00193     return GlobalBase::SinglePointEnergy;
00194 
00195   return globalSetup->calculationType();
00196 }
00197 
00199 unsigned int XbraboView::buurType() const
00204 {  
00205   if(globalSetup == 0)
00206     return GlobalBase::NoBuur;
00207   
00208   return globalSetup->buurType();
00209 }
00210 
00212 bool XbraboView::isModified() const
00214 {  
00215   return calcModified;
00216 }
00217 
00218 /*//// isAnimating /////////////////////////////////////////////////////////////
00219 bool XbraboView::isAnimating() const
00221 {
00222   return MoleculeView->isAnimating();
00223 }*/
00224 
00226 QString XbraboView::name() const
00228 {
00229   if(globalSetup == 0)
00230     return calcDefaultName;
00231 
00232   return globalSetup->name();
00233 }
00234 
00236 QString XbraboView::fileName() const
00238 {
00239   return calcFileName;
00240 }
00241 
00243 QString XbraboView::directory() const
00245 {
00246   if(globalSetup == 0)
00247     return QDir::convertSeparators(QDir::homeDirPath()) + QDir::separator() + calcDefaultName;
00248 
00249   return globalSetup->directory();
00250 }
00251 
00253 bool XbraboView::isRunning() const
00255 {
00256   if(calculation == 0)
00257     return false;
00258   
00259   return calculation->isRunning();
00260 }
00261 
00263 bool XbraboView::isPaused() const
00265 {
00266   if(calculation == 0)
00267     return false;
00268   
00269   return calculation->isPaused();
00270 }
00271 
00272 /*//// hasSelection ////////////////////////////////////////////////////////////
00273 bool XbraboView::hasSelection() const
00275 { 
00276   return MoleculeView->selectedAtoms() > 0;
00277 }*/
00278 
00280 void XbraboView::cut()
00284 { 
00285   TextEditStatus->cut();
00286 }
00287 
00289 void XbraboView::copy()
00292 {
00293   TextEditStatus->copy();
00294 }
00295 
00297 void XbraboView::paste()
00301 {
00302   TextEditStatus->paste();
00303 }
00304 
00306 GLMoleculeView* XbraboView::moleculeView() const
00308 {
00309   return MoleculeView;
00310 }
00311 
00313 bool XbraboView::loadCML(const QDomDocument* doc)
00315 {  
00317   QDomElement root = doc->documentElement();
00318   if(root.tagName() != "cml")
00319   {
00320     QMessageBox::warning(this, Version::appName, tr("The selected file is a regular CML file"), QMessageBox::Ok, QMessageBox::NoButton);
00321     return false;
00322   }
00324   if(root.attribute("xmlns:" + DomUtils::ns) != DomUtils::uriDict10)
00325   {
00326     //qDebug("attribute list for <cml>:");
00327     //for(int i = 0; i < root.attributes().count(); i++)
00328     //  qDebug("attribute 1: "+root.attributes().item(i).nodeName()+" "+root.attributes().item(i).nodeValue());
00329     QMessageBox::warning(this, Version::appName, tr("The selected file does not contain the correct version indicator."), QMessageBox::Ok, QMessageBox::NoButton);
00330     return false;
00331   }
00333   QDomNode metaNode = root.namedItem("metadataList");
00334   if(!metaNode.isNull())
00335   {
00336     QDomNode childNode = metaNode.firstChild();
00337     while(!childNode.isNull())
00338     {
00339       if(childNode.isElement() && childNode.toElement().tagName() == "metadata" && childNode.toElement().attribute("name") == "dc:date")
00340       {
00341         calcDate = childNode.toElement().attribute("content");
00342         break;
00343       }
00344       childNode = childNode.nextSibling();
00345     }
00346   }
00347 
00348   TextEditStatus->append(tr("Loading data"));
00351   QDomElement section = root.namedItem("molecule").toElement();
00352   if(section.isNull())
00353     TextEditStatus->append("<font color=red>" + tr("  ...no coordinates found while loading") + "</font>");
00354   else
00355   {
00356     TextEditStatus->append(tr("  ...loading coordinates"));
00357     atoms->loadCML(&section);
00358   }
00360   root = root.namedItem("parameterList").toElement();
00361   if(root.attribute("dictRef") != DomUtils::ns + ":settings")
00362   {
00363     TextEditStatus->append("<font color=red>" + tr("  ...no calculation related information found while loading") + "</font>");  
00364   }
00365   else
00366   {
00367     section = root.firstChild().toElement();
00368     while(!section.isNull() && section.tagName() == "parameterList")
00369     {
00370       if(section.attribute("dictRef") == DomUtils::ns + ":geometry")
00371       {
00373         {
00374           TextEditStatus->append(tr("  ...setting geometry"));  
00375           loadCMLLocal(&section);
00376         }
00377       }
00378       else if(section.attribute("dictRef") == DomUtils::ns + ":view")
00379       {
00381         {
00382           TextEditStatus->append(tr("  ...loading view data"));  
00383           MoleculeView->loadCML(&section);
00384         }
00385       }
00386       else if(section.attribute("dictRef") == DomUtils::ns + ":global")
00387       {
00389         {
00390           TextEditStatus->append(tr("  ...loading Global data"));  
00391           initGlobalSetup();
00392           globalSetup->loadCML(&section);
00393         }
00394       }
00395       else if(section.attribute("dictRef") == DomUtils::ns + ":energy_and_forces")
00396       {
00398         {
00399           TextEditStatus->append(tr("  ...loading Energy & Forces data"));  
00400           initBraboSetup();
00401           braboSetup->loadCML(&section);
00402         }
00403       }
00404       else if(section.attribute("dictRef") == DomUtils::ns + ":geometry_optimization")
00405       {
00407         {
00408           TextEditStatus->append(tr("  ...loading Geometry Optimization data"));  
00409           initRelaxSetup();
00410           relaxSetup->loadCML(&section);
00411         }
00412       }
00413       else if(section.attribute("dictRef") == DomUtils::ns + ":calculation")
00414       {
00416         {
00417           TextEditStatus->append(tr("  ...loading Calculation data"));  
00418           bool ok = initCalculation();
00419           calculation->loadCML(&section);
00420           if(!ok)
00421             calculation->stop();
00422         }
00423       }
00424       section = section.nextSibling().toElement();
00425     }
00426     TextEditStatus->append(tr("Loading done"));  
00427   }
00428   
00429   updateBraboSetup();
00430   updateRelaxSetup();
00431   setModified(false);
00432   return true;
00433 }
00434 
00436 QDomDocument* XbraboView::saveCML()
00438 {  
00439   QDomDocument* doc = new QDomDocument();
00441   QDomProcessingInstruction instr = doc->createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\"");
00442   doc->appendChild(instr);
00444   //QDomImplementation impl;
00445   //QDomDocumentType type = impl.createDocumentType("cml",0, "cml.dtd");
00446   //doc->appendChild(type);  
00448   QDomElement root = doc->createElement("cml");
00449   root.setAttribute("xmlns", DomUtils::uriNSCML);
00450   root.setAttribute("xmlns:" + DomUtils::nsCMLM, DomUtils::uriDictCMLM);
00451   root.setAttribute("xmlns:" + DomUtils::ns, DomUtils::uriDict10);
00452   root.setAttribute("xmlns:" + DomUtils::nsXSD, DomUtils::uriDictXSD);
00453   root.setAttribute("xmlns:" + DomUtils::nsAtomic, DomUtils::uriDictAtomic);
00454   root.setAttribute("xmlns:" + DomUtils::nsSI, DomUtils::uriDictSI);
00455   root.setAttribute("xmlns:" + DomUtils::nsDC, DomUtils::uriNSDC);
00456 
00457   doc->appendChild(root);
00459   QDomElement childNode = doc->createElement("metadataList");
00460   childNode.setAttribute("title", "Generated by " + Version::appName);
00461   root.appendChild(childNode);
00462   QDomElement grandChildNode = doc->createElement("metadata");
00463   grandChildNode.setAttribute("name", DomUtils::nsDC + ":creator");
00464   grandChildNode.setAttribute("content", Version::appName + " " + Version::appVersion);
00465   childNode.appendChild(grandChildNode);
00466   grandChildNode = doc->createElement("metadata");
00467   childNode.appendChild(grandChildNode);
00468   grandChildNode.setAttribute("name", DomUtils::nsDC + ":description");
00469   grandChildNode.setAttribute("content", Version::appName + " Calculation File");
00470   grandChildNode = doc->createElement("metadata");
00471   grandChildNode.setAttribute("content", calcDate);
00472   grandChildNode.setAttribute("name", DomUtils::nsDC + ":date");
00473   childNode.appendChild(grandChildNode);
00475   childNode = doc->createElement("molecule");
00476   root.appendChild(childNode);  
00477   atoms->saveCML(&childNode);
00479   childNode = doc->createElement("parameterList");
00480   childNode.setAttribute("dictRef", DomUtils::ns + ":settings");
00481   childNode.setAttribute("title", Version::appName + " specific data");
00482   root.appendChild(childNode);
00484   grandChildNode = doc->createElement("parameterList");
00485   grandChildNode.setAttribute("dictRef", DomUtils::ns + ":geometry");
00486   childNode.appendChild(grandChildNode);
00487   saveCMLLocal(&grandChildNode);
00489   grandChildNode = doc->createElement("parameterList");
00490   grandChildNode.setAttribute("dictRef", DomUtils::ns + ":view");
00491   childNode.appendChild(grandChildNode);
00492   MoleculeView->saveCML(&grandChildNode);
00494   if(globalSetup != 0)
00495   {
00496     grandChildNode = doc->createElement("parameterList");
00497     grandChildNode.setAttribute("dictRef", DomUtils::ns + ":global");
00498     childNode.appendChild(grandChildNode);
00499     globalSetup->saveCML(&grandChildNode);
00500   }
00501   if(braboSetup != 0)
00502   {
00503     grandChildNode = doc->createElement("parameterList");
00504     grandChildNode.setAttribute("dictRef", DomUtils::ns + ":energy_and_forces");
00505     childNode.appendChild(grandChildNode);
00506     braboSetup->saveCML(&grandChildNode);
00507   }
00508   if(relaxSetup != 0)
00509   {
00510     grandChildNode = doc->createElement("parameterList");
00511     grandChildNode.setAttribute("dictRef", DomUtils::ns + ":geometry_optimization");
00512     childNode.appendChild(grandChildNode);
00513     relaxSetup->saveCML(&grandChildNode);
00514   }
00516   if(calculation != 0)
00517   {
00518     grandChildNode = doc->createElement("parameterList");
00519     grandChildNode.setAttribute("dictRef", DomUtils::ns + ":calculation");
00520     childNode.appendChild(grandChildNode);
00521     calculation->saveCML(&grandChildNode);
00522   }
00523   return doc;
00524 }
00525 
00527 void XbraboView::setFileName(const QString filename)
00529 {
00530   calcFileName = filename;
00531   updateCaptions();
00532 }
00533 
00537 
00539 void XbraboView::setModified(bool state)
00542 {
00543   calcModified = state;
00544   if(!state)
00545   {
00546     // setting the calculation is not being modified is only done after a 
00547     // save has occured
00548     MoleculeView->setModified(false);
00549     if(calculation != 0)
00550       calculation->setModified(false);
00551   }
00552   updateCaptions();
00553   emit changed();
00554 }
00555 
00557 void XbraboView::moleculeReadCoordinates()
00559 {
00560   QString filename;
00561   unsigned int result = CrdFactory::readFromFile(atoms, filename);
00562   switch(result)
00563   {
00564     case CrdFactory::OK:
00565       setModified();
00566       MoleculeView->updateAtomSet(true); // does a complete reset
00567       if(calculation != 0)
00568         calculation->setContinuable(false);
00569       TextEditStatus->append(tr("New coordinates read: ") + QString::number(atoms->count()) + tr(" atoms"));
00570       break;
00571     case CrdFactory::UnknownExtension:
00572       QMessageBox::warning(this, tr("Unknown format"), "The file " + filename + " has an unknown extension", QMessageBox::Ok, QMessageBox::NoButton);
00573       break;
00574     case CrdFactory::ErrorOpen:
00575       QMessageBox::warning(this, tr("Error opening file"), "The file " + filename + " could not be opened for reading", QMessageBox::Ok, QMessageBox::NoButton);
00576       break;
00577     case CrdFactory::ErrorRead:
00578       QMessageBox::warning(this, tr("Parse error"), "The contents of the file " + filename + " could not be parsed correctly", QMessageBox::Ok, QMessageBox::NoButton);
00579       break;
00580     case CrdFactory::UnknownFormat:
00581       QMessageBox::warning(this, tr("Unknown format"), "The format (normal/extended) of the file " + filename + " could not be detected correctly", QMessageBox::Ok, QMessageBox::NoButton);
00582       break;
00583   }    
00584 }
00585 
00587 void XbraboView::moleculeSaveCoordinates()
00589 {
00590   unsigned short int result = CrdFactory::writeToFile(atoms);
00591   switch(result)
00592   {
00593     case CrdFactory::UnknownExtension:
00594       QMessageBox::warning(this, tr("Unknown format"), tr("The file has an unknown extension"), QMessageBox::Ok, QMessageBox::NoButton);
00595       break;
00596     case CrdFactory::ErrorOpen:
00597       QMessageBox::warning(this, tr("Error opening file"), tr("The file could not be opened for writing"), QMessageBox::Ok, QMessageBox::NoButton);
00598       break;
00599     case CrdFactory::ErrorWrite:
00600       QMessageBox::warning(this, tr("Error writing file"), tr("The file could not be written"), QMessageBox::Ok, QMessageBox::NoButton);
00601       break;
00602   }
00603 }
00604 
00606 void XbraboView::moleculeFPS()
00608 {
00609   TextEditStatus->append(tr("Frames per second: ") + QString::number(MoleculeView->calculateFPS()));
00610 }
00611 
00613 void XbraboView::setupGlobal()
00615 {  
00616   initGlobalSetup();
00617   if(globalSetup->exec() == QDialog::Accepted)
00618   {
00620     setModified();
00621     updateBraboSetup();
00622     updateRelaxSetup();
00623     updateCaptions();
00624   }
00625 }
00626 
00628 void XbraboView::setupBrabo()
00630 {  
00631   initBraboSetup();
00632   if(braboSetup->exec() == QDialog::Accepted)
00633   {
00634     setModified();
00635     if(calculation != 0 && calculation->isRunning() && globalSetup->calculationType() != GlobalBase::SinglePointEnergy
00636       && globalSetup->calculationType() != GlobalBase::EnergyAndForces)
00637     {
00638       bool ok;
00639       QStringList basissetList = braboSetup->basissets(ok);
00640       if(!ok)
00641         return; // don't apply the changes if the basissets are not available for all atoms
00642       QString atdens = braboSetup->generateAtdens(ok);
00643       if(!ok)
00644         return; // same for the atomic density basisset
00645 
00647       bool prefer;
00648       unsigned int size1, size2;
00649       QString startVector = braboSetup->startVector(prefer, size1, size2); // zero sizes for size1 and size2 imply a problem with
00650                                                                            // reading the basisset files.
00651       if(size1 == 0)
00652         return;
00653       calculation->setBraboInput(braboSetup->generateInput(BraboBase::BRABO), basissetList, startVector, prefer, size1, size2);
00654       calculation->setStockInput(braboSetup->generateInput(BraboBase::STOCK), atdens);      
00655     }
00656   }
00657 }
00658 
00660 void XbraboView::setupRelax()
00662 {
00663   initRelaxSetup();
00664   if(relaxSetup->exec() == QDialog::Accepted)
00665   {
00666     setModified();
00667     if(calculation != 0 && calculation->isRunning() && globalSetup->calculationType() == GlobalBase::GeometryOptimization)
00668     {
00670       std::vector<unsigned int> steps;
00671       std::vector<double> factors;
00672       relaxSetup->scaleFactors(steps, factors);
00673       calculation->setRelaxInput(relaxSetup->generateInput(RelaxBase::AFF), relaxSetup->generateInput(RelaxBase::MAFF), 
00674                                  relaxSetup->inputGenerationFrequency(), relaxSetup->maxSteps(), steps, factors);
00675     }
00676   }
00677 }
00678 
00680 void XbraboView::setupFreq()
00682 {
00683 }
00684 
00686 void XbraboView::setupBuur()
00688 {
00689 }
00690 
00692 void XbraboView::start()
00694 {
00695   if(calculation != 0 && calculation->isRunning())
00696   {      // succesful unpausing
00697     if(calculation->isPaused())
00698         TextEditStatus->append("<font color=blue>" + tr("Calculation unpaused") + "</font>");
00699     calculation->start(); // this handles the error messages or un-pausing
00700     emit changed();
00701     return;
00702   }
00703 
00704 
00706   if(!initCalculation()) // does initial setup
00707     return;
00708 
00710   if(calculation->start())
00711     globalSetup->allowChanges(false);
00712   else
00713     return;
00714 
00716   TextEditStatus->append("<font color=blue>" + tr("Calculation started") + "</font>");
00717   QString tempItem = " * " + tr("Type") + ": ";
00718   unsigned int calcType = globalSetup->calculationType();
00719   switch(calcType)
00720   {
00721     case GlobalBase::SinglePointEnergy:    tempItem += tr("Single Point Energy");
00722                                            break;
00723     case GlobalBase::EnergyAndForces:      tempItem += tr("Energy & Forces");
00724                                            break;
00725     case GlobalBase::GeometryOptimization: tempItem += tr("Geometry Optimization");
00726                                            break;
00727   }
00728   TextEditStatus->append(tempItem);
00729   TextEditStatus->append(" * " + tr("Method") + ": " + braboSetup->method());
00730   if(calcType == GlobalBase::GeometryOptimization)
00731     TextEditStatus->append(" * " + tr("Optimization step") + " 1");
00732   TextEditStatus->append("   - " + tr("Calculating energy"));  
00733 
00734   // progressbar  
00735   ProgressBar->reset();
00736   unsigned int numSteps = braboSetup->maxIterations(); // never zero
00737   if(calcType != GlobalBase::SinglePointEnergy)
00738     numSteps *= 2;
00739   if(calcType == GlobalBase::GeometryOptimization)
00740   {
00741     unsigned int calcMaxSteps = relaxSetup->maxSteps();
00742     if(calcMaxSteps == 0)
00743       numSteps *= 3*atoms->count(); // starting value ~ minimal number of IC's
00744     else
00745       numSteps *= calcMaxSteps;
00746   }
00747   ProgressBar->setTotalSteps(numSteps);
00748   lastProgress = 0;
00749   ProgressBar->setProgress(lastProgress);
00750   emit changed();
00751 }
00752 
00754 void XbraboView::pause()
00756 {  
00757   if(calculation != 0)
00758   {
00759     if(calculation->pause())
00760     {
00761       // succesful (un)pausing
00762       if(calculation->isPaused())
00763         TextEditStatus->append("<font color=blue>" + tr("Calculation paused") + "</font>" +  tr("(effective after the current step)"));
00764       else
00765         TextEditStatus->append("<font color=blue>" + tr("Calculation unpaused") + "</font>");
00766       emit changed();
00767     }
00768   }
00769 }
00770 
00772 void XbraboView::stop()
00774 {  
00775   if(calculation != 0)
00776   {
00777     calculation->stop();
00778     emit changed();
00779   }
00780 }
00781 
00783 void XbraboView::writeInput()
00785 {
00786   if(!initCalculation())
00787     return;
00788 
00789   calculation->writeInput();
00790 
00791   /*
00793   initGlobalSetup();
00794   initBraboSetup();
00795   QFile file(globalSetup->directory() + QDir::separator() + globalSetup->name() + ".inp");
00796   qDebug("writing file "+file.name());
00797   if(!file.open(IO_WriteOnly))
00798     return;
00799   QTextStream stream(&file);
00800   QStringList input = braboSetup->generateInput(BraboBase::BRABO);
00801   for(QStringList::Iterator it = input.begin(); it != input.end(); it++)
00802     stream << *it << "\n";
00803   file.close();
00804   */
00805 }
00806 
00808 void XbraboView::cleanCalculation()
00810 {
00811   if(calculation == 0 || calculation->isRunning())
00812     return;
00813   if(QMessageBox::information(this, "Clean up calculation", "This will remove all files pertaining to the calculation from the calculation directory", "Clean", "Cancel", QString::null, 0, 1) == 0)
00814     calculation->clean();
00815 }
00816 
00818 void XbraboView::viewOutput()
00820 {  
00822   OutputChooserWidget* outputChooser = new OutputChooserWidget(this, 0, true, 0);
00823   outputChooser->ListView->setSorting(-1);
00824   QPixmap pixmapPresent = IconSets::getPixmap(IconSets::OK);
00825 
00826   if(calculation)
00827   {
00829     QListViewItem* item = new QListViewItem(outputChooser->ListView);
00830     item->setText(0, tr("last"));
00831     if(!calculation->braboOutput().isEmpty())
00832       item->setPixmap(1, pixmapPresent);
00833     if(!calculation->stockOutput().isEmpty())
00834       item->setPixmap(2, pixmapPresent);
00835     if(!calculation->relaxOutput().isEmpty())
00836       item->setPixmap(3, pixmapPresent);
00837     if(!calculation->affOutput().isEmpty())
00838       item->setPixmap(4, pixmapPresent);
00839   
00841     vector<unsigned int> cycles;
00842     vector<bool> savedBrabo, savedStock, savedRelax, savedAFF;
00843     calculation->getAvailableOutputs(cycles, savedBrabo, savedStock, savedRelax, savedAFF);
00844     for(unsigned int i = 0; i < cycles.size(); i++)
00845     {
00846       item = new QListViewItem(outputChooser->ListView, item);
00847       item->setText(0, QString::number(cycles[i]));
00848       if(savedBrabo[i])
00849         item->setPixmap(1, pixmapPresent);
00850       if(savedStock[i])
00851         item->setPixmap(2, pixmapPresent);
00852       if(savedRelax[i])
00853         item->setPixmap(3, pixmapPresent);
00854       if(savedAFF[i])
00855         item->setPixmap(4, pixmapPresent);
00856     }
00857   }
00858 
00860   connect(outputChooser->ListView, SIGNAL(clicked(QListViewItem*, const QPoint&, int)), SLOT(showOutput(QListViewItem*, const QPoint&, int)));
00861   connect(outputChooser->PushButtonClose, SIGNAL(clicked()), outputChooser, SLOT(close()));
00862   outputChooser->exec();
00863   delete outputChooser;
00864 }
00865 
00867 void XbraboView::updatePVMHosts(const QStringList& hosts)
00869 {  
00870   if(!braboSetup)
00871     hostListPVM = hosts;
00872   else
00873     braboSetup->setPVMHosts(hosts);
00874 }
00875 
00876 
00880 
00882 void XbraboView::keyPressEvent(QKeyEvent* e)
00885 {
00886   if(isTopLevel())
00887     // No parent so transfer it manually while changing the type from
00888     // QEvent::KeyPress to QEvent::QAccel. This might not be a very wise thing
00889     // to do as the docs state a QKeyEvent can only have a type of
00890     // QEvent::KeyPress or QEvent::KeyRelease.
00891     qApp->sendEvent(mainWindow, new QKeyEvent(QEvent::Accel, e->key(), e->ascii(), e->state(), e->text(), e->isAutoRepeat(), e->count()));
00892 
00893   e->ignore(); // automatic propagation to the parent widget when it's not NULL (mainwindow)
00894 }
00895 
00897 void XbraboView::mouseReleaseEvent(QMouseEvent* e)
00900 {
00901   if(e->button() == QMouseEvent::RightButton)
00902     popup();
00903   // eat all other release events
00904 }
00905 
00906 
00910 
00912 void XbraboView::popup()
00914 {
00916   QPopupMenu* popup = new QPopupMenu(0,0);
00917   popup->insertItem(IconSets::getIconSet(IconSets::MoleculeRead), tr("Read coordinates..."), this, SLOT(moleculeReadCoordinates()));
00918   popup->insertItem(tr("Add atoms..."), MoleculeView, SLOT(addAtoms()));
00919   const int ID_MOLECULE_DELETE = popup->insertItem(tr("Delete selected atoms"), MoleculeView, SLOT(deleteSelectedAtoms()));
00920   popup->insertSeparator();
00921   const int ID_ALTER_CARTESIAN = popup->insertItem(tr("Alter cartesian coordinates"), MoleculeView, SLOT(alterCartesian()));
00922   const int ID_ALTER_INTERNAL = popup->insertItem(tr("Alter internal coordinate"), MoleculeView, SLOT(alterInternal()));    
00923   popup->insertSeparator();
00924   popup->insertItem(tr("Select all"), MoleculeView, SLOT(selectAll()));
00925   popup->insertItem(tr("Select none"), MoleculeView, SLOT(unselectAll()));
00926   popup->insertSeparator();
00927   popup->insertItem(IconSets::getIconSet(IconSets::SetupGlobal), tr("Setup global"),this, SLOT(setupGlobal()));
00928   popup->insertItem(IconSets::getIconSet(IconSets::SetupBrabo), tr("Setup energy && Forces"),this, SLOT(setupBrabo()));
00929   const int ID_SETUP_RELAX = popup->insertItem(IconSets::getIconSet(IconSets::SetupRelax), tr("Setup geometry optimization"),this, SLOT(setupRelax()));
00930   popup->insertSeparator();
00931   const int ID_RUN_START = popup->insertItem(IconSets::getIconSet(IconSets::Start), tr("Start"), this, SLOT(start()));
00932   const int ID_RUN_PAUSE = popup->insertItem(IconSets::getIconSet(IconSets::Pause), tr("Pause"), this, SLOT(pause()));
00933   const int ID_RUN_STOP = popup->insertItem(IconSets::getIconSet(IconSets::Stop), tr("Stop"), this, SLOT(stop()));
00934   popup->insertItem(IconSets::getIconSet(IconSets::Outputs), tr("View output"), this, SLOT(viewOutput()));
00935 
00936   /*
00938   QPopupMenu* popupReset = new QPopupMenu(popup, 0);
00939   popupReset->insertItem(tr("Translation"), MoleculeView, SLOT(centerView()));
00940   popupReset->insertItem(tr("Orientation"), MoleculeView, SLOT(resetOrientation()));
00941   popupReset->insertItem(tr("Zoom"), MoleculeView, SLOT(zoomFit()));
00942   popupReset->insertItem(tr("View"), MoleculeView, SLOT(resetView()));
00944   QPopupMenu* popupSelect = new QPopupMenu(popup, 0);
00945   popupSelect->insertItem(tr("All"), MoleculeView, SLOT(selectAll()));
00946   popupSelect->insertItem(tr("None"), MoleculeView, SLOT(unselectAll()));
00948   QPopupMenu* popupAlter = new QPopupMenu(popup, 0);
00949   const int ID_ALTER_CARTESIAN = popupAlter->insertItem(tr("Cartesian coordinates"), MoleculeView, SLOT(alterCartesian()));
00950   const int ID_ALTER_INTERNAL = popupAlter->insertItem(tr("Internal coordinate"), MoleculeView, SLOT(alterInternal()));    
00952   QPopupMenu* popupSetup = new QPopupMenu(popup, 0);
00953   popupSetup->insertItem(IconSets::getIconSet(IconSets::SetupGlobal), tr("Global"),this, SLOT(setupGlobal()));
00954   popupSetup->insertItem(IconSets::getIconSet(IconSets::SetupBrabo), tr("Energy && Forces"),this, SLOT(setupBrabo()));
00955   const int ID_SETUP_RELAX = popupSetup->insertItem(IconSets::getIconSet(IconSets::SetupRelax), tr("Geometry Optimization"),this, SLOT(setupRelax()));
00956   const int ID_SETUP_FREQ = popupSetup->insertItem(IconSets::getIconSet(IconSets::SetupFreq), tr("Frequencies"),this, SLOT(setupFreq()));
00957   const int ID_SETUP_BUUR = popupSetup->insertItem(IconSets::getIconSet(IconSets::SetupBuur), tr("Crystal"),this, SLOT(setupBuur()));
00959   QPopupMenu* popupRun = new QPopupMenu(popup, 0);
00960   const int ID_RUN_START = popupRun->insertItem(IconSets::getIconSet(IconSets::Start), tr("Start"), this, SLOT(start()));
00961   const int ID_RUN_PAUSE = popupRun->insertItem(IconSets::getIconSet(IconSets::Pause), tr("Pause"), this, SLOT(pause()));
00962   const int ID_RUN_STOP = popupRun->insertItem(IconSets::getIconSet(IconSets::Stop), tr("Stop"), this, SLOT(stop()));
00963   popupRun->insertItem(IconSets::getIconSet(IconSets::Outputs), tr("View output"), this, SLOT(viewOutput()));
00965   popup->insertItem(IconSets::getIconSet(IconSets::MoleculeRead), tr("Read coordinates..."), this, SLOT(moleculeReadCoordinates()));
00966   popup->insertItem(tr("Change isosurfaces..."), MoleculeView, SLOT(showDensity()));
00967   popup->insertItem(tr("Change display mode..."), this, SLOT(showProperties()), 0);
00968   popup->insertItem(tr("Reset"), popupReset);
00969   popup->insertItem(tr("Select"), popupSelect);
00970   popup->insertItem(tr("Alter"), popupAlter);
00971   popup->insertItem(tr("Add atoms..."), MoleculeView, SLOT(addAtoms()));
00972   const int ID_MOLECULE_DELETE = popup->insertItem(tr("Delete selected atoms"), MoleculeView, SLOT(deleteSelectedAtoms()));
00973   // don't add the animate action as it doesn't update the mainmenu action
00974   //const int ID_MOLECULE_ANIMATION = popup->insertItem(IconSets::getIconSet(IconSets::MoleculeAnimate), tr("Toggle animation"), this, SLOT(moleculeAnimate()));
00975   popup->insertItem(tr("Calculate FPS"), this, SLOT(moleculeFPS()));
00976   popup->insertItem(IconSets::getIconSet(IconSets::Image), tr("Save image"), MoleculeView, SLOT(saveImage()));
00977   popup->insertSeparator();
00978   popup->insertItem(tr("Setup"), popupSetup);
00979   popup->insertItem(tr("Run"), popupRun);
00980   */
00981 
00983   if(MoleculeView->selectedAtoms() == 0 || isRunning())
00984   {
00985     popup->setItemEnabled(ID_ALTER_CARTESIAN, false);
00986     popup->setItemEnabled(ID_MOLECULE_DELETE, false);
00987   }
00988   if(MoleculeView->selectedAtoms() < 2 || MoleculeView->selectedAtoms() > 4)
00989     popup->setItemEnabled(ID_ALTER_INTERNAL, false);
00990     
00992   if(globalSetup == 0 || globalSetup->calculationType() != GlobalBase::GeometryOptimization)
00993     popup->setItemEnabled(ID_SETUP_RELAX, false);
00994   //if(globalSetup == 0 || globalSetup->calculationType() != GlobalBase::Frequencies)
00995   //  popup->setItemEnabled(ID_SETUP_FREQ, false);
00996   //if(globalSetup == 0 || globalSetup->buurType() == GlobalBase::NoBuur)
00997   //  popup->setItemEnabled(ID_SETUP_BUUR, false);
00998 
01000   if(isRunning())
01001     popup->setItemEnabled(ID_RUN_START, false);
01002   else
01003   {
01004     popup->setItemEnabled(ID_RUN_PAUSE, false);
01005     popup->setItemEnabled(ID_RUN_STOP, false);
01006   }
01007  
01009   popup->exec(QCursor::pos());
01010   delete popup;
01011 }
01012 
01014 void XbraboView::updateIteration(unsigned int iteration, double energy)
01016 {
01017   // only show each iteration when not optimizing
01018   if(globalSetup->calculationType() == GlobalBase::SinglePointEnergy || globalSetup->calculationType() == GlobalBase::EnergyAndForces)
01019     TextEditStatus->append("       " + tr("Iteration") + " " + QString::number(iteration) + " : " + tr("Energy") + " = " + QString::number(energy,'f',8));
01020     //ListBoxStatus->insertItem("       " + tr("Iteration") + " " + QString::number(iteration) + " : " + tr("Energy") + " = " + QString::number(energy,'f',8));
01021   // always add the final energy
01022   if(iteration == 50)
01023   {
01024     //ListBoxStatus->insertItem("   - " + tr("Total energy") + " = " + QString::number(energy,'f',8));
01025     TextEditStatus->append("   - " + tr("Total energy") + " = " + QString::number(energy,'f',8));
01026     if(globalSetup->calculationType() != GlobalBase::SinglePointEnergy)
01027       TextEditStatus->append("   - " + tr("Calculating forces"));
01028       //ListBoxStatus->insertItem("   - " + tr("Calculating forces"));
01029   }
01030 
01031   //ListBoxStatus->setCurrentItem(ListBoxStatus->count()-1);
01032   lastProgress++;
01033   ProgressBar->setProgress(lastProgress);
01034 }
01035 
01037 void XbraboView::updateCycle(unsigned int cycle)
01039 {
01040   bool ref1, ref2, ref3, ref4, ref5;
01041   calculation->getRefinementParameters(ref1, ref2, ref3, ref4, ref5);
01042   QString refResult = "   - " + tr("Refinement parameters") + ":";
01043   refResult += ref1 ? " +" : " -";
01044   refResult += ref2 ? " +" : " -";
01045   refResult += ref3 ? " +" : " -";
01046   refResult += ref4 ? " +" : " -";
01047   refResult += ref5 ? " +" : " -";
01048   TextEditStatus->append(refResult);
01049   TextEditStatus->append(" * " + tr("Optimization step") + " " + QString::number(cycle));
01050   TextEditStatus->append("   - " + tr("Calculating energy"));
01051   lastProgress += braboSetup->maxIterations(); // assume calculation of forces takes as long as energy
01052   if(lastProgress >= static_cast<unsigned int>(ProgressBar->totalSteps()))
01053     ProgressBar->setTotalSteps(lastProgress + 2* braboSetup->maxIterations());
01054   ProgressBar->setProgress(lastProgress); 
01055 }
01056 
01057 /*//// updateCharges ///////////////////////////////////////////////////////////
01058 void XbraboView::updateCharges()
01060 {
01061   if(MoleculeView->isShowingCharges(AtomSet::Stockholder))
01062   {
01063     MoleculeView->updateGL();
01064     QString text = "   - " + tr("Updated stockholder charges");
01065     QString scf = atoms->chargesSCF(AtomSet::Stockholder);
01066     QString density = atoms->chargesDensity(AtomSet::Stockholder);
01067     if(!scf.isEmpty())
01068     {
01069       text += " " + tr("calculated using") + " " + scf;
01070       if(!density.isEmpty())
01071         text += tr(" from the ") + density;
01072     }
01073     ListBoxStatus->insertItem(text);
01074   }
01075 }*/
01076 
01078 void XbraboView::cleanupCalculation(unsigned int error)
01080 {
01081   qDebug("XbraboView::cleanupCalculation() called");
01082 
01083   switch(error)
01084   {
01085     case Calculation::NoError:
01086       {
01087         if(globalSetup->calculationType() == GlobalBase::GeometryOptimization)
01088         {
01089           TextEditStatus->append("   - " + tr("Refinement parameters") + ": + + + + +");
01090           TextEditStatus->append(" * " + tr("Structure optimized"));
01091         }
01092         TextEditStatus->append("<font color=green>" + tr("Calculation finished successfully") + "</font>");
01093       }
01094       break;
01095     case Calculation::UndefinedError:
01096       TextEditStatus->append("<font color=red>" + tr("Calculation finished with errors") + "</font>");
01097       break;
01098     case Calculation::NoConvergence:
01099       TextEditStatus->append("<font color=red>" + tr("Calculation finished with errors: no convergence") + "</font>");
01100       break;
01101     case Calculation::CloseNuclei:
01102       TextEditStatus->append("<font color=red>" + tr("Calculation finished with errors: nuclei too close") + "</font>");
01103       break;
01104     case Calculation::MaxCyclesExceeded:
01105       TextEditStatus->append("<font color=red>" + tr("Calculation finished with errors: maximum number of optimization cycles reached") + "</font>");
01106       break;
01107     case Calculation::ManualStop:
01108       TextEditStatus->append("<font color=red>" + tr("Calculation stopped immediately") + "</font>");
01109       break;
01110   }
01111 
01112   if(globalSetup->calculationType() == GlobalBase::GeometryOptimization)
01113     calculation->setContinuable(true);
01114   ProgressBar->setProgress(ProgressBar->totalSteps());
01115   QTimer::singleShot(5*1000, ProgressBar, SLOT(reset())); // reset the progressbar after 5 seconds
01116 
01117   globalSetup->allowChanges(true);
01118   emit changed();
01119 }
01120 
01122 void XbraboView::showOutput(QListViewItem* item, const QPoint&, int column)
01124 { 
01126   if(item == 0 || column < 1 || column > 4 || calculation == 0)
01127     return;
01128 
01130   if(item->pixmap(column) == 0)
01131     return;
01132 
01134   unsigned int cycle;
01135   if(item->text(0) == tr("last"))
01136     cycle = 0;
01137   else
01138     cycle = item->text(0).toUInt();
01139   
01141   QStringList contents;
01142   int fileWidth = 81;
01143   switch(column)
01144   {
01145     case 1: // it's a Brabo output file
01146             contents = calculation->braboOutput(cycle);
01147             fileWidth = 111;
01148             break;
01149     case 2: // it's a Stock output file
01150             contents = calculation->stockOutput(cycle);
01151             fileWidth = 97;
01152             break;
01153     case 3: // it's a Relax output file
01154             contents = calculation->relaxOutput(cycle);
01155             fileWidth = 131;
01156             break;
01157     case 4: //it's an AFF file
01158             contents = calculation->affOutput(cycle);
01159             break;
01160   }
01161   if(contents.isEmpty())
01162     return;
01163 
01165   TextViewWidget* outputViewer = new TextViewWidget(this, 0, true, Qt::WDestructiveClose);
01166   outputViewer->TextEdit->setTextFormat(Qt::LogText); // default is PlainText
01167   QFontMetrics metrics(outputViewer->TextEdit->currentFont());
01168   int newWidth = fileWidth*metrics.width(" ") + 2*outputViewer->layout()->margin() + outputViewer->TextEdit->verticalScrollBar()->sliderRect().width();
01169   outputViewer->resize(newWidth, outputViewer->height()); 
01170 
01172   switch(column)
01173   {
01174     case 1: // it's a Brabo output file
01175             if(cycle == 0)
01176               outputViewer->setCaption(tr("Showing Brabo output from last cycle"));
01177             else
01178               outputViewer->setCaption(tr("Showing Brabo output from cycle") + " " + QString::number(cycle));
01179             outputViewer->TextEdit->setText(contents.join("\n"));      
01180             break;
01181 
01182       /*
01183       for(QStringList::iterator it = contents.begin(); it != contents.end(); it++)
01184       {
01185         QString line = *it;
01186         //line.replace("&", "&amp;");
01187         //line.replace("<", "&lt;");
01188         //line.replace(">", "&gt;");
01189 
01200         if(line.left(15) == " TOTAL ENERGY =")
01201         {
01202           line = "<font color=darkblue>" + line.mid(0, 15)  + "</font>"
01203                + "<font color=blue>"     + line.mid(15, 20) + "</font>"
01204                + "<font color=darkblue>" + line.mid(35, 8)  + "</font>";
01205           outputViewer->TextEdit->append(line);
01206           line = *(++it); // total energy in other units
01207           line = "<font color=blue>"     + line.mid(0, 25)  + "</font>"
01208                + "<font color=darkblue>" + line.mid(25, 7)  + "</font>"
01209                + "<font color=blue>"     + line.mid(32, 19) + "</font>"
01210                + "<font color=darkblue>" + line.mid(51, 3)  + "</font>"
01211                + "<font color=blue>"     + line.mid(54, 18) + "</font>"
01212                + "<font color=darkblue>" + line.mid(72, 9)  + "</font>"
01213                + "<font color=blue>"     + line.mid(81, 15) + "</font>"
01214                + "<font color=darkblue>" + line.mid(96, 7)  + "</font>";
01215           outputViewer->TextEdit->append(line);
01216           line = *(++it); // total energy in other units (2)
01217           line = "<font color=blue>"     + line.mid(0, 25)  + "</font>"
01218                + "<font color=darkblue>" + line.mid(25, 7)  + "</font>"
01219                + "<font color=blue>"     + line.mid(32, 19) + "</font>"
01220                + "<font color=darkblue>" + line.mid(51, 5)  + "</font>"
01221                + "<font color=blue>"     + line.mid(56, 19) + "</font>"
01222                + "<font color=darkblue>" + line.mid(75, 6)  + "</font>"
01223                + "<font color=blue>"     + line.mid(81, 19) + "</font>"
01224                + "<font color=darkblue>" + line.mid(100, 3) + "</font>";
01225           outputViewer->TextEdit->append(line);
01226           line = *(++it); // empty line
01227           outputViewer->TextEdit->append(line);
01228           line = *(++it); // 2e and 1e electron energy
01229           line = "<font color=darkblue>" + line.mid(0, 21)  + "</font>"
01230                + "<font color=blue>"     + line.mid(21, 16) + "</font>"
01231                + "<font color=darkblue>" + line.mid(37, 22) + "</font>"
01232                + "<font color=blue>"     + line.mid(59, 17) + "</font>";
01233           outputViewer->TextEdit->append(line);
01234           line = *(++it); // kinetic and core-attraction energy
01235           line = "<font color=darkblue>" + line.mid(0, 21)  + "</font>"
01236                + "<font color=blue>"     + line.mid(21, 16) + "</font>"
01237                + "<font color=darkblue>" + line.mid(37, 22) + "</font>"
01238                + "<font color=blue>"     + line.mid(59, 17) + "</font>";
01239           outputViewer->TextEdit->append(line);
01240           line = *(++it); // virial and nuclear energy
01241           line = "<font color=darkblue>" + line.mid(0, 21)  + "</font>"
01242                + "<font color=blue>"     + line.mid(21, 16) + "</font>"
01243                + "<font color=darkblue>" + line.mid(37, 22) + "</font>"
01244                + "<font color=blue>"     + line.mid(59, 17) + "</font>";
01245           outputViewer->TextEdit->append(line);
01246           line = *(++it); // empty line
01247           outputViewer->TextEdit->append(line);
01248           line = *(++it); // XYZ
01249           line = "<font color=darkblue>" + line + "</font>";
01250           outputViewer->TextEdit->append(line);
01251           line = *(++it); // dipole
01252           line = "<font color=darkblue>" + line.mid(0, 10)  + "</font>"
01253                + "<font color=blue>"     + line.mid(10, 45) + "</font>"
01254                + "<font color=darkblue>" + line.mid(55, 3)  + "</font>";
01255           outputViewer->TextEdit->append(line);
01256           line = *(++it); // dipole (2)
01257           line = "<font color=blue>"     + line.mid(0, 55)  + "</font>"
01258                + "<font color=darkblue>" + line.mid(55, 6)  + "</font>";
01259           outputViewer->TextEdit->append(line);
01260           line = *(++it); // dipole (3)
01261           line = "<font color=blue>"     + line.mid(0, 55)  + "</font>"
01262                + "<font color=darkblue>" + line.mid(55, 5)  + "</font>";
01263           outputViewer->TextEdit->append(line);
01264           line = *(++it); // empty line
01265           outputViewer->TextEdit->append(line);
01266           line = *(++it); // |dipole|
01267           line = "<font color=darkblue>" + line.mid(0, 11)  + "</font>"
01268                + "<font color=blue>"     + line.mid(11, 15) + "</font>"
01269                + "<font color=darkblue>" + line.mid(26, 3)  + "</font>"
01270                + "<font color=blue>"     + line.mid(29, 15) + "</font>"
01271                + "<font color=darkblue>" + line.mid(44, 6)  + "</font>"
01272                + "<font color=blue>"     + line.mid(50, 16) + "</font>"
01273                + "<font color=darkblue>" + line.mid(66, 5)  + "</font>";   
01274           outputViewer->TextEdit->append(line);                            
01275         }
01276         else if(line.left(10) == "**********")
01277         {
01278           line = "<font color=darkgray>" + line + "</font>";
01279           outputViewer->TextEdit->append(line);
01280         }
01281         else if(line.left(5) == " >>>>>")
01282         {
01283           line = "<font color=darkgray>" + line + "</font>";
01284           outputViewer->TextEdit->append(line);
01285         }
01286         else                      
01287           outputViewer->TextEdit->append(line);
01288       }
01289       break;
01290       */
01291     case 2: // it's a Stock output file
01292             if(cycle == 0)
01293               outputViewer->setCaption(tr("Showing Stock output from last cycle"));
01294             else
01295               outputViewer->setCaption(tr("Showing Stock output from cycle") + " " + QString::number(cycle));
01296             outputViewer->TextEdit->setText(contents.join("\n"));      
01297             break;
01298     case 3: // it's a Relax output file      
01299             if(cycle == 0)
01300               outputViewer->setCaption(tr("Showing Relax output from last cycle"));
01301             else
01302               outputViewer->setCaption(tr("Showing Relax output from cycle") + " " + QString::number(cycle));
01303             outputViewer->TextEdit->setText(contents.join("\n"));      
01304             break;
01305     case 4: //it's an AFF file
01306             if(cycle == 0)
01307               outputViewer->setCaption(tr("Showing AFF file from last cycle"));
01308             else
01309               outputViewer->setCaption(tr("Showing AFF file from cycle") + " " + QString::number(cycle));
01310             outputViewer->TextEdit->setText(contents.join("\n"));      
01311             break;      
01312   }
01313 
01315   //outputViewer->TextEdit->ensureVisible(1, 1); // not needed on Windows apparently
01316   //outputViewer->TextEdit->setCursorPosition(1,1);
01317   //outputViewer->TextEdit->ensureCursorVisible();
01318   outputViewer->exec(); // will delete itself when closed
01319 }
01320 
01322 void XbraboView::showProperties()
01325 {
01326   MoleculePropertiesWidget* properties = new MoleculePropertiesWidget(this, 0, true, 0);
01327   properties->ComboBoxRenderingType->setCurrentItem(MoleculeView->displayStyle(GLSimpleMoleculeView::Molecule));
01328   properties->ComboBoxForces->setCurrentItem(MoleculeView->displayStyle(GLSimpleMoleculeView::Forces));
01329   properties->CheckBoxElement->setChecked(MoleculeView->isShowingElements());
01330   properties->CheckBoxNumber->setChecked(MoleculeView->isShowingNumbers());
01331   if(MoleculeView->isShowingCharges(AtomSet::Mulliken))
01332     properties->ComboBoxCharge->setCurrentItem(AtomSet::Mulliken); 
01333   else if(MoleculeView->isShowingCharges(AtomSet::Stockholder))
01334     properties->ComboBoxCharge->setCurrentItem(AtomSet::Stockholder);
01335   else
01336     properties->ComboBoxCharge->setCurrentItem(AtomSet::None);
01337 
01338   if(properties->exec() == QDialog::Accepted)
01339   {
01340     MoleculeView->setDisplayStyle(GLSimpleMoleculeView::Molecule, properties->ComboBoxRenderingType->currentItem());
01341     MoleculeView->setDisplayStyle(GLSimpleMoleculeView::Forces, properties->ComboBoxForces->currentItem());
01342     MoleculeView->setLabels(properties->CheckBoxElement->isChecked(),
01343                             properties->CheckBoxNumber->isChecked(),
01344                             properties->ComboBoxCharge->currentItem());
01345     MoleculeView->updateGL();
01346   }
01347   delete properties;
01348 }
01349 
01353 
01355 void XbraboView::loadCMLLocal(const QDomElement* root)
01357 {  
01358   int positionX = 0, positionY = 0, sizeWidth = 400, sizeHeight = 400;
01359   QValueList<int> splitterSizes;
01360   const QString prefix = "geometry_";
01361   QDomNode childNode = root->firstChild();
01362   while(!childNode.isNull())
01363   {
01364     if(childNode.isElement() && childNode.nodeName() == "parameter")
01365     {
01366       if(DomUtils::dictEntry(childNode, prefix + "position-x"))
01367         DomUtils::readNode(&childNode, &positionX);
01368       else if(DomUtils::dictEntry(childNode, prefix + "position-y"))
01369         DomUtils::readNode(&childNode, &positionY);
01370       else if(DomUtils::dictEntry(childNode, prefix + "width"))
01371         DomUtils::readNode(&childNode, &sizeWidth);
01372       else if(DomUtils::dictEntry(childNode, prefix + "height"))
01373         DomUtils::readNode(&childNode, &sizeHeight);  
01374       else if(DomUtils::dictEntry(childNode, prefix + "splitter_sizes"))
01375         DomUtils::readNode(&childNode, &splitterSizes);
01376     }
01377     childNode = childNode.nextSibling();
01378   }
01379   QPoint position(positionX, positionY);
01380   QSize size(sizeWidth, sizeHeight);
01381   resize(size);
01382   move(position);
01383   if(splitterSizes.size() != 0)
01384     Splitter->setSizes(splitterSizes);
01385 }
01386 
01388 void XbraboView::saveCMLLocal(QDomElement* root)
01390 {  
01392   QRect geometry = internalGeometry();  
01393   const QString prefix = "geometry_";
01394   DomUtils::makeNode(root, geometry.x(), prefix + "position-x");
01395   DomUtils::makeNode(root, geometry.y(), prefix + "position-y");
01396   DomUtils::makeNode(root, geometry.width(), prefix + "width");
01397   DomUtils::makeNode(root, geometry.height(), prefix + "height");
01398   
01399   QValueList<int> list = Splitter->sizes();
01400   DomUtils::makeNode(root, list, prefix + "splitter_sizes");
01401 }
01402 
01404 void XbraboView::updateCaptions()
01406 {
01407   QFileInfo fi = QFileInfo(calcFileName);  
01408   QString tempString = fi.baseName(true);
01409   if(globalSetup != 0 && !globalSetup->description().isEmpty())
01410     tempString += QString(" - ") + globalSetup->description();
01411   if(isModified())
01412     tempString += tr(" [modified]");
01413   setCaption(tempString);
01414   setTabCaption(fi.baseName(true));
01415 }
01416 
01418 void XbraboView::updateBraboSetup()
01420 {
01421   if(braboSetup == 0)
01422     return;
01423 
01424   braboSetup->setForces(globalSetup->calculationType() != GlobalBase::SinglePointEnergy);
01425   braboSetup->setDescription(globalSetup->description());
01426   braboSetup->setName(globalSetup->name());
01427   braboSetup->setExtendedFormat(globalSetup->extendedFormat());
01428 }
01429 
01431 void XbraboView::updateRelaxSetup()
01433 {
01434   if(relaxSetup == 0)
01435     return;
01436 
01437   relaxSetup->setName(globalSetup->name());
01438   relaxSetup->setDescription(globalSetup->description());
01439   relaxSetup->setDir(globalSetup->directory());
01440   relaxSetup->setExtendedFormat(globalSetup->extendedFormat());
01441 }
01442 
01444 bool XbraboView::makeDirCurrent(const QString dir, const QString title)
01447 {
01448   QDir workDir = dir;
01449   if(!workDir.exists())
01450   {
01451     if(!workDir.mkdir(workDir.path()))
01452     {
01453       QMessageBox::warning(this, title, tr("Unable to create the directory ") + workDir.path());
01454       return false;
01455     }
01456   }
01457   if(!QDir::setCurrent(workDir.path()))
01458   {
01459     QMessageBox::warning(this, title, tr("Unable to change to the directory ") + workDir.path());
01460     return false;
01461   }
01462   return true;
01463 }
01464 
01466 void XbraboView::initGlobalSetup()
01468 {
01469   if(globalSetup != 0)
01470     return;
01471   
01472   globalSetup = new GlobalBase(this, 0, true, 0);
01473   globalSetup->setDefaultName(calcDefaultName);
01474   globalSetup->setIcon(QPixmap::fromMimeSource("SetupGlobalNormal"));
01475 }
01476 
01478 void XbraboView::initBraboSetup()
01481 {
01482   if(braboSetup != 0)
01483     return;
01484   
01485   initGlobalSetup();
01486   braboSetup = new BraboBase(atoms, this, 0, true, 0);
01487   //braboSetup->setIcon(QPixmap::fromMimeSource("SetupBraboNormal")); // doesn't work apparently 
01488   updateBraboSetup();
01489   if(!hostListPVM.isEmpty())
01490     updatePVMHosts(hostListPVM);
01491 }
01492 
01494 void XbraboView::initRelaxSetup()
01497 {
01498   if(relaxSetup != 0)
01499     return;
01500 
01501   initGlobalSetup();
01502   relaxSetup = new RelaxBase(atoms, this, 0, true, 0);
01503   relaxSetup->setIcon(QPixmap::fromMimeSource("SetupRelaxNormal"));
01504   updateRelaxSetup();
01505 }
01506 
01508 bool XbraboView::initCalculation()
01511 {
01512   if(calculation == 0)
01513   {
01514     calculation = new Calculation(atoms, this);
01515     connect(calculation, SIGNAL(newIteration(unsigned int, double)), this, SLOT(updateIteration(unsigned int, double)));
01516     connect(calculation, SIGNAL(newCycle(unsigned int)), this, SLOT(updateCycle(unsigned int)));
01517     connect(calculation, SIGNAL(updated()), MoleculeView, SLOT(updateGL()));
01518     connect(calculation, SIGNAL(finished(unsigned int)), this, SLOT(cleanupCalculation(unsigned int)));
01519     connect(calculation, SIGNAL(modified()), this, SIGNAL(changed()));
01520   }
01521   
01523   if(atoms->count() == 0)
01524   {
01525     QMessageBox::warning(this, tr("Initialize calculation"), tr("There are no atoms present"));
01526     return false;
01527   }  
01528 
01530   initBraboSetup(); // also inits globalSetup  
01531   calculation->setCalculationType(globalSetup->calculationType(), globalSetup->buurType());
01532   calculation->setParameters(globalSetup->name(), globalSetup->directory(), globalSetup->extendedFormat());
01533   calculation->setBackup(1, true, true, true, true, true); // default until interface is made (in class GlobalBase)
01534 
01536   bool ok;
01537   QStringList basissetList = braboSetup->basissets(ok);
01538   if(!ok)
01539     return false;
01540   QString atdens = braboSetup->generateAtdens(ok);
01541   if(!ok)
01542     return false;
01543   bool prefer;
01544   unsigned int size1, size2;
01545   QString startVector = braboSetup->startVector(prefer, size1, size2);
01546   if(size1 == 0)
01547     return false;
01548   calculation->setBraboInput(braboSetup->generateInput(BraboBase::BRABO), basissetList, startVector, prefer, size1, size2);
01549   calculation->setStockInput(braboSetup->generateInput(BraboBase::STOCK), atdens);
01550   
01552   if(globalSetup->calculationType() == GlobalBase::GeometryOptimization)
01553   {
01554     initRelaxSetup();
01555     std::vector<unsigned int> steps;
01556     std::vector<double> factors;
01557     relaxSetup->scaleFactors(steps, factors);
01558     qDebug("XbraboView::start:");
01559     for(unsigned int i = 0; i < steps.size(); i++)
01560       qDebug(" %d, step %d, factor %f", i, steps[i], factors[i]);
01561 
01562     calculation->setRelaxInput(relaxSetup->generateInput(RelaxBase::AFF), relaxSetup->generateInput(RelaxBase::MAFF), 
01563                                relaxSetup->inputGenerationFrequency(), relaxSetup->maxSteps(), steps, factors);
01564   }
01565   return true;
01566 }
01567 
01569 void XbraboView::updateAtomSet()
01572 {
01573   if(calculation != 0)
01574     calculation->setContinuable(false);
01575 
01576   // possibly update the SpinBox limits in RelaxBase when needed. ATM it is done 
01577   // each time the dialog is opened. 
01578 }
01579 
01583 
01584 unsigned int XbraboView::calcCounter = 0;
01585 

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