BALL
1.4.1
|
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