BALL  1.4.1
demoTutorialDialog.C
Go to the documentation of this file.
00001 // -*- Mode: C++; tab-width: 2; -*-
00002 // vi: set ts=2:
00003 //
00004 
00005 #include "demoTutorialDialog.h"
00006 #include "mainframe.h"
00007 
00008 #include <BALL/VIEW/KERNEL/common.h>
00009 #include <BALL/VIEW/PRIMITIVES/mesh.h>
00010 #include <BALL/VIEW/KERNEL/message.h>
00011 
00012 #include <BALL/VIEW/DIALOGS/displayProperties.h>
00013 #include <BALL/VIEW/DIALOGS/FDPBDialog.h>
00014 #include <BALL/VIEW/DIALOGS/modifyRepresentationDialog.h>
00015 #include <BALL/VIEW/DIALOGS/molecularFileDialog.h>
00016 
00017 #include <BALL/VIEW/DATATYPE/standardDatasets.h>
00018 
00019 #include <BALL/VIEW/WIDGETS/molecularStructure.h>
00020 #include <BALL/VIEW/WIDGETS/scene.h>
00021 #include <BALL/VIEW/WIDGETS/logView.h>
00022 #include <BALL/VIEW/WIDGETS/pyWidget.h>
00023 #include <BALL/VIEW/WIDGETS/datasetControl.h>
00024 #include <BALL/VIEW/WIDGETS/molecularControl.h>
00025 #include <BALL/VIEW/WIDGETS/geometricControl.h>
00026 #include <BALL/VIEW/WIDGETS/helpViewer.h>
00027 
00028 #include <BALL/DATATYPE/contourSurface.h>
00029 #include <BALL/SYSTEM/path.h>
00030 
00031 #include <QtGui/QPushButton>
00032 #include <QtGui/QMessageBox>
00033 #include <QtGui/QTextBrowser>
00034 
00035 namespace BALL
00036 {
00037   namespace VIEW
00038   {
00039 
00040 enum TutorialSteps
00041 {
00042   TUTORIAL_PEPTIDE = 1,
00043   TUTORIAL_ROTATE,
00044   TUTORIAL_HIERARCHY,
00045   TUTORIAL_MDS,
00046   TUTORIAL_TRAJECTORY,
00047   TUTORIAL_ES,
00048   TUTORIAL_SES,
00049   TUTORIAL_SES_COLORING,
00050   TUTORIAL_CS
00051 };
00052 
00053 
00054 DemoTutorialDialog::DemoTutorialDialog(QWidget* parent, const char* name)
00055   : QDialog(parent),
00056     Ui_DemoTutorialDialogData(),
00057     ModularWidget(name),
00058     surface_(0)
00059 {
00060 #ifdef BALL_VIEW_DEBUG
00061   Log.error() << "new DemoTutorialDialog " << this << std::endl;
00062 #endif
00063 
00064   setupUi(this);
00065   setObjectName(name);
00066 
00067   // register the widget with the MainControl
00068   ModularWidget::registerWidget(this);
00069   hide();
00070   connect(next_button, SIGNAL(clicked()), this, SLOT(nextStepClicked()));
00071   connect(cancel_button, SIGNAL(clicked()), this, SLOT(hide()));
00072 }
00073 
00074 DemoTutorialDialog::~DemoTutorialDialog()
00075 {
00076 #ifdef BALL_VIEW_DEBUG
00077   Log.error() << "deleting DemoTutorialDialog " << this << std::endl;
00078 #endif
00079 
00080   delete surface_;
00081 }
00082 
00083 void DemoTutorialDialog::initDemo_()
00084 {
00085   setWindowTitle(tr("BALLView Demo"));
00086 
00087   prefix_ = getBaseDir_() + "demo";
00088 
00089   next_button->setEnabled(true);
00090   QDialog::show();
00091   raise();
00092   move(20,20);
00093 
00094   // hide some dockwidgets
00095   if (LogView::getInstance(0) != 0)        LogView::getInstance(0)->hide();
00096   if (DatasetControl::getInstance(0) != 0) DatasetControl::getInstance(0)->hide();
00097 #ifdef BALL_PYTHON_SUPPORT
00098   if (PyWidget::getInstance(0) != 0)       PyWidget::getInstance(0)->hide();
00099 #endif
00100 }
00101 
00102 String DemoTutorialDialog::getBaseDir_()
00103 {
00104   Path p;
00105   String dir = p.find(   String("..")
00106                        + FileSystem::PATH_SEPARATOR
00107                        + "doc"
00108                        + FileSystem::PATH_SEPARATOR
00109                        + "internal" 
00110                        + FileSystem::PATH_SEPARATOR );
00111 
00112   return dir;
00113 }
00114 
00115 void DemoTutorialDialog::initTutorial_()
00116 {
00117   setWindowTitle(tr("BALLView Tutorial"));
00118   
00119   prefix_ = getBaseDir_() + "tutorial";
00120 
00121   next_button->setEnabled(false);
00122 
00123   ((Mainframe*)getMainControl())->reset();
00124 
00125   Scene::getInstance(0)->show();
00126   MolecularControl::getInstance(0)->show();
00127   MolecularControl::getInstance(0)->setFloating(false);
00128   MolecularControl::getInstance(0)->applyPreferences();
00129   DatasetControl::getInstance(0)->show();
00130   DatasetControl::getInstance(0)->applyPreferences();
00131   DatasetControl::getInstance(0)->setFloating(false);
00132   GeometricControl::getInstance(0)->show();
00133   GeometricControl::getInstance(0)->applyPreferences();
00134   GeometricControl::getInstance(0)->setFloating(false);
00135 
00136   LogView::getInstance(0)->hide();
00137 }
00138 
00139 void DemoTutorialDialog::show()
00140 {
00141   current_step_ = 1;
00142 
00143   if (demo_mode_)
00144   {
00145     initDemo_();
00146   }
00147   else
00148   {
00149     int result = QMessageBox::question(this, tr("Warning"),
00150         tr("To start the tutorial, all loaded structures and molecules will be deleted."),
00151         QMessageBox::Ok| QMessageBox::Cancel, QMessageBox::Ok);
00152     if (result != QMessageBox::Ok) return;
00153 
00154     initTutorial_();
00155   }
00156 
00157   QUrl qurl = QUrl::fromLocalFile((prefix_ + "01.html").c_str());
00158   text_browser->setSource(qurl);
00159 
00160   QDialog::show();
00161   resize(350, 650);
00162   raise();
00163 }
00164 
00165 void DemoTutorialDialog::onNotify(Message* message)
00166 {
00167   if (!isVisible()) return;
00168 
00169   if (demo_mode_)
00170   {
00171     onNotifyDemo_(message);
00172   }
00173   else
00174   {
00175     onNotifyTutorial_(message);
00176   }
00177 }
00178 
00179 void DemoTutorialDialog::onNotifyDemo_(Message *message)
00180 {
00181   RepresentationMessage* rmsg = RTTI::castTo<RepresentationMessage>(*message);
00182 
00183   if (current_step_ == 13 ||
00184       current_step_ == 14)
00185   {
00186     if (!RTTI::isKindOf<FinishedSimulationMessage>(*message)) return;
00187   }
00188   else if (current_step_ == 15)
00189   {
00190     DatasetMessage* msg = RTTI::castTo<DatasetMessage>(*message);
00191     if (msg == 0) return;
00192 
00193     if (msg->getDataset() == 0)
00194     {
00195       BALLVIEW_DEBUG
00196       return;
00197     }
00198 
00199     RegularData3DDataset* set = dynamic_cast<RegularData3DDataset*>(msg->getDataset());
00200     if (set->getType() != RegularData3DController::type) return;
00201 
00202     grid_ = (RegularData3D*) set->getData();
00203   }
00204   else if (current_step_ == 16)
00205   {
00206     SceneMessage* msg = RTTI::castTo<SceneMessage>(*message);
00207     if (msg == 0 || msg->getType() != SceneMessage::REBUILD_DISPLAY_LISTS)
00208     {
00209       return;
00210     }
00211   }
00212   else if (rmsg == 0 ||
00213            rmsg->getType() != RepresentationMessage::UPDATE)
00214   {
00215     return;
00216   }
00217 
00218   enableNextStep_();
00219 }
00220 
00221 
00222 void DemoTutorialDialog::enableNextStep_()
00223 {
00224   next_button->setEnabled(true);
00225 }
00226 
00227 
00228 void DemoTutorialDialog::nextStepClicked()
00229 {
00230   String id = String(current_step_ + 1);
00231   if (id.size() == 1) id = "0" + id;
00232 
00233   id = prefix_ + id + ".html";
00234 
00235   QUrl qurl = QUrl::fromLocalFile(id.c_str());
00236   text_browser->setSource(qurl);
00237   next_button->setEnabled(false);
00238 
00239   current_step_ ++;
00240 
00241   if (demo_mode_) 
00242   {
00243     if (current_step_ == 18)
00244     {
00245       showTutorial();
00246       return;
00247     }
00248 
00249     nextStepDemo_();
00250   }
00251   else
00252   {
00253     if (current_step_ == 9)
00254     {
00255       next_button->setEnabled(true);
00256     }
00257     if (current_step_ == 10)
00258     {
00259       hide();
00260       HelpViewer* hv = HelpViewer::getInstance(1);
00261       if (hv == 0) return;
00262       hv->showHelp();
00263       hv->setFloating(true);
00264       hv->showMaximized();
00265     }
00266   }
00267 }
00268 
00269 
00270 void DemoTutorialDialog::nextStepDemo_()
00271 {
00272   // initialisation for first real step
00273   if (current_step_ == 2)
00274   {
00275     DisplayProperties* dp = DisplayProperties::getInstance(0);
00276     dp->setDrawingPrecision(DRAWING_PRECISION_HIGH);
00277 
00278     ((Mainframe*)getMainControl())->reset();
00279 
00280     // open bpti 
00281     try
00282     {
00283       Path path;
00284       String file_name = path.find("structures/bpti.pdb");
00285 
00286       MolecularFileDialog* dialog = MolecularFileDialog::getInstance(0);
00287       if (dialog == 0) return;
00288 
00289       dp->enableCreationForNewMolecules(false);
00290       system_ = dialog->openMolecularFile(file_name);
00291       dp->enableCreationForNewMolecules(true);
00292 
00293       if (system_ == 0)
00294       {
00295         String msg((String)tr("Could not open bpti.pdb. Maybe the file was deleted?")+"\n");
00296         msg += (String)tr("It should be found in") + " " + file_name;
00297 
00298         QMessageBox::critical(0, tr("Error while starting BALLView Demo"), msg.c_str(),
00299             QMessageBox::Ok, Qt::NoButton, Qt::NoButton);
00300         return;
00301       }
00302       
00303       system_->apply(getFragmentDB().add_hydrogens);
00304       system_->apply(getFragmentDB().build_bonds);
00305       getMainControl()->update(*system_, true);
00306     }
00307     catch(Exception::FileNotFound e)
00308     {
00309       Log.error() << (String)tr("Could not open") << " " << e.getFilename() << std::endl;
00310       return;
00311     }
00312 
00313     composites_.clear();
00314     composites_.push_back(system_);
00315   }
00316 
00317   if (current_step_ == 18) // last page
00318   {
00319     hide();
00320     return;
00321   }
00322 
00323   MolecularStructure* ms = MolecularStructure::getInstance(0);
00324 
00325   next_button->setEnabled(current_step_ >= 15);
00326 
00327   // remove representations
00328   RepresentationManager& pm = getMainControl()->getRepresentationManager();
00329   Size nr = pm.getNumberOfRepresentations();
00330   std::list<Representation*> reps = pm.getRepresentations();
00331 
00332   if (surface_ == 0 && nr == 1 && current_step_ == 7)
00333   {
00334     GeometricObject* go = *(**reps.begin()).getGeometricObjects().begin();
00335     Mesh* mesh = dynamic_cast<Mesh*>(go);
00336     if (mesh != 0)
00337     {
00338       surface_ = new Mesh(*mesh);
00339     }
00340     else
00341     {
00342       // should not happen
00343       BALLVIEW_DEBUG
00344       surface_ = new Mesh();
00345     }
00346   }
00347 
00348   for (Position p = 0; p < nr; p++)
00349   {
00350     getMainControl()->remove(**reps.begin());
00351     reps.pop_front();
00352   }
00353 
00354   if (current_step_ < 9)
00355   {
00356     ModelType type = (ModelType) (current_step_ - 2);
00357     if (type >= MODEL_SA_SURFACE)
00358     {
00359       type = (ModelType)((Index)type + 1);
00360     }
00361     notify_(new CreateRepresentationMessage(composites_, type, COLORING_ELEMENT));
00362   }
00363   else if (current_step_ == 9)
00364   {
00365     getMainControl()->getMolecularControlSelection().clear();
00366     getMainControl()->getMolecularControlSelection().push_back(system_);
00367     ms->calculateHBonds();
00368     notify_(new CreateRepresentationMessage(composites_, MODEL_STICK, COLORING_ELEMENT));
00369     notify_(new CreateRepresentationMessage(composites_, MODEL_HBONDS, COLORING_ELEMENT));
00370 
00371   }
00372   else if (current_step_ == 10)
00373   {
00374     notify_(new CreateRepresentationMessage(composites_, MODEL_VDW, COLORING_TEMPERATURE_FACTOR));
00375   }
00376   else if (current_step_ == 11)
00377   {
00378     notify_(new CreateRepresentationMessage(composites_, MODEL_CARTOON, COLORING_SECONDARY_STRUCTURE));
00379   }
00380   else if (current_step_ == 12)
00381   {
00382     notify_(new CreateRepresentationMessage(composites_, MODEL_CARTOON, COLORING_RESIDUE_INDEX));
00383   }
00384   else if (current_step_ == 13 ||
00385            current_step_ == 14)
00386   {
00387     getMainControl()->setMultithreading(0);
00388     notify_(new CreateRepresentationMessage(composites_, MODEL_STICK, COLORING_ELEMENT));
00389     getMainControl()->setMultithreading(1);
00390 
00391     list<Composite*> composites;
00392     composites.push_back(*getMainControl()->getCompositeManager().getComposites().begin());
00393     MolecularControl::getInstance(0)->highlight(composites);
00394 
00395     if (current_step_ == 13)
00396     {
00397       ms->getAmberConfigurationDialog().resetOptions();
00398       ms->chooseAmberFF();
00399       ms->getMinimizationDialog().setMaxGradient(1.);
00400       ms->getMinimizationDialog().setMaxIterations(20);
00401       ms->getMinimizationDialog().setRefresh(5);
00402       ms->runMinimization(false);
00403     }
00404     else
00405     {
00406       ms->getMDSimulationDialog().setTimeStep(0.002);
00407       ms->getMDSimulationDialog().setNumberOfSteps(30);
00408       ms->MDSimulation(false);
00409     }
00410   }
00411   else if (current_step_ == 15) //FDPB
00412   {
00413     getMainControl()->setMultithreading(0);
00414     if (!ms->calculateFDPB(false))
00415     {
00416       BALLVIEW_DEBUG;
00417     }
00418     getMainControl()->setMultithreading(1);
00419   }
00420   else if (current_step_ == 16) // SES colored 
00421   {
00422     // Create a new representation containing the contour surface.
00423     Representation* rep = getMainControl()->getRepresentationManager().createRepresentation();
00424     rep->setModelType(MODEL_SE_SURFACE); 
00425     rep->insert(*new Mesh(*surface_));
00426     getMainControl()->insert(*rep);
00427 
00428     ModifyRepresentationDialog* cdialog = ModifyRepresentationDialog::getInstance(0);
00429     cdialog->setMode(0);
00430     cdialog->setRepresentation(rep);
00431     cdialog->setGrid(grid_);
00432     cdialog->setMinValue(-0.7);
00433     cdialog->setMaxValue(0.7);
00434     cdialog->accept();
00435 
00436     getMainControl()->update(*rep);
00437   }
00438   else if (current_step_ == 17)
00439   {
00440     getMainControl()->setMultithreading(0);
00441     notify_(new CreateRepresentationMessage(composites_, MODEL_STICK, COLORING_ELEMENT));
00442     getMainControl()->setMultithreading(1);
00443 
00444     notify_(new CreateRepresentationMessage(composites_, MODEL_STICK, COLORING_ELEMENT));
00445 
00446     DatasetController* dc = DatasetControl::getInstance(0)->getController(RegularData3DController::type);
00447     RegularData3DController& rcon = *(RegularData3DController*) dc;
00448     vector<Dataset*> grids = rcon.getDatasets();
00449     if (grids.size() == 0) return;
00450     rcon.computeIsoContourSurface(*grids[0], ColorRGBA(255,0,0), -0.1);
00451     rcon.computeIsoContourSurface(*grids[0], ColorRGBA(0,0,255), 0.1);
00452 
00453     // last entry: we are done
00454   }
00455 }
00456 
00457 void DemoTutorialDialog::showTutorial()
00458 {
00459   demo_mode_ = false;
00460   show();
00461 }
00462 
00463 void DemoTutorialDialog::showDemo()
00464 {
00465   demo_mode_ = true;
00466   show();
00467 }
00468 
00469 void DemoTutorialDialog::onNotifyTutorial_(Message *message)
00470 {
00471   CompositeMessage* cmsg = RTTI::castTo<CompositeMessage>(*message);
00472   RepresentationMessage* rmsg = RTTI::castTo<RepresentationMessage>(*message);
00473 
00474   if (rmsg != 0 && rmsg->getRepresentation() == 0) return;
00475 
00476   switch (current_step_)
00477   {
00478     case TUTORIAL_PEPTIDE: // "Building a peptide from a given sequence"
00479     {
00480       if (cmsg == 0 || cmsg->getType() != CompositeMessage::NEW_MOLECULE) return;
00481       break;
00482     }
00483 
00484     case TUTORIAL_ROTATE: // "Rotating"
00485     {
00486       if (!RTTI::isKindOf<SceneMessage>(*message)) return;
00487       break;
00488     }
00489 
00490     case TUTORIAL_HIERARCHY: // "Hierarchy of molecules"
00491     {
00492       break;
00493     }
00494 
00495     case TUTORIAL_MDS: // "Molecular Dynamics Simulation")
00496     {
00497       if (!RTTI::isKindOf<DatasetMessage>(*message)) return;
00498       DatasetMessage* msg = dynamic_cast<DatasetMessage*>(message);
00499       if (msg->getDataset() == 0)
00500       {
00501         BALLVIEW_DEBUG
00502         return;
00503       }
00504 
00505       if (msg->getDataset()->getType() != TrajectoryController::type ||
00506           msg->getType() != DatasetMessage::ADD)
00507       {
00508         return;
00509       }
00510 
00511       break;
00512     }
00513 
00514     case TUTORIAL_TRAJECTORY: // "Visualisation of trajectories")
00515     {
00516       if (cmsg != 0 && cmsg->getType() == CompositeMessage::CHANGED_COMPOSITE)
00517       {
00518         enableNextStep_();
00519       }
00520       break;
00521     }
00522 
00523     case TUTORIAL_ES:  // "Calculation of electrostatics"
00524     {
00525       if (!RTTI::isKindOf<DatasetMessage>(*message)) return;
00526       DatasetMessage* msg = dynamic_cast<DatasetMessage*>(message);
00527       if (msg->getDataset() == 0)
00528       {
00529         BALLVIEW_DEBUG
00530         return;
00531       }
00532 
00533       if (msg->getDataset()->getType() != RegularData3DController::type ||
00534           msg->getType() != DatasetMessage::ADD)
00535       {
00536         return;
00537       }
00538 
00539       break;
00540     }
00541 
00542     case TUTORIAL_SES: // "Creating a Solvent Excluded Surface"
00543     {
00544       if (rmsg == 0 ||
00545           rmsg->getType() != RepresentationMessage::ADD_TO_GEOMETRIC_CONTROL ||
00546           rmsg->getRepresentation()->getModelType() != MODEL_SE_SURFACE)
00547       {
00548         return;
00549       }
00550       break;
00551     }
00552 
00553     case TUTORIAL_SES_COLORING: // "Coloring a SES by electrostatics"
00554     {
00555       if (rmsg == 0 || 
00556           (rmsg->getType() != RepresentationMessage::UPDATE &&
00557           rmsg->getRepresentation()->getModelType() != MODEL_SE_SURFACE))
00558       {
00559         return;
00560       }
00561       break;
00562     }
00563 
00564     case TUTORIAL_CS: // "Creating a isocontour surface"
00565     {
00566       if (rmsg == 0 ||
00567           rmsg->getRepresentation()->getModelType() != MODEL_CONTOUR_SURFACE)
00568       {
00569         return;
00570       }
00571       break;
00572     }   
00573 
00574     default:
00575       BALLVIEW_DEBUG;
00576       Log.error() << (String)tr("Current step") << ": " << current_step_ << std::endl;
00577       return;
00578   }
00579 
00580   enableNextStep_();
00581 }
00582 
00583 void DemoTutorialDialog::initializeWidget(MainControl&)
00584 {
00585   getMainControl()->insertPopupMenuSeparator(MainControl::HELP);
00586   
00587   String description = "Shortcut|Help|Demo";
00588   demo_action_ = insertMenuEntry(MainControl::HELP, (String)tr("Demo"), this, SLOT(showDemo()), description);
00589   setMenuHint((String)tr("Show a demonstration of BALLView's features"));
00590 
00591   description = "Shortcut|Help|Tutorial";
00592   tutorial_action_ = insertMenuEntry(MainControl::HELP, (String)tr("Tutorial"), this, SLOT(showTutorial()), description);
00593   setMenuHint((String)tr("Perform a step-by-step tutorial"));
00594   getMainControl()->insertPopupMenuSeparator(MainControl::HELP);
00595 }
00596 
00597 void DemoTutorialDialog::checkMenu(MainControl& main_control)
00598 {
00599   bool busy = main_control.isBusy();
00600   demo_action_->setEnabled(!busy);
00601   tutorial_action_->setEnabled(!busy);
00602 }
00603             
00604 } } // namespaces
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines