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