00001
00002
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
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
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
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
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)
00318 {
00319 hide();
00320 return;
00321 }
00322
00323 MolecularStructure* ms = MolecularStructure::getInstance(0);
00324
00325 next_button->setEnabled(current_step_ >= 15);
00326
00327
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
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)
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)
00421 {
00422
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
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:
00479 {
00480 if (cmsg == 0 || cmsg->getType() != CompositeMessage::NEW_MOLECULE) return;
00481 break;
00482 }
00483
00484 case TUTORIAL_ROTATE:
00485 {
00486 if (!RTTI::isKindOf<SceneMessage>(*message)) return;
00487 break;
00488 }
00489
00490 case TUTORIAL_HIERARCHY:
00491 {
00492 break;
00493 }
00494
00495 case TUTORIAL_MDS:
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:
00515 {
00516 if (cmsg != 0 && cmsg->getType() == CompositeMessage::CHANGED_COMPOSITE)
00517 {
00518 enableNextStep_();
00519 }
00520 break;
00521 }
00522
00523 case TUTORIAL_ES:
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:
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:
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:
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 } }