00001
00002
00003
00004
00005 #include "mainframe.h"
00006 #include "icons.h"
00007 #include "demoTutorialDialog.h"
00008
00009 #include <BALL/VIEW/KERNEL/iconLoader.h>
00010 #include <BALL/VIEW/RENDERING/POVRenderer.h>
00011 #include <BALL/VIEW/RENDERING/VRMLRenderer.h>
00012 #include <BALL/VIEW/WIDGETS/molecularStructure.h>
00013 #include <BALL/VIEW/WIDGETS/molecularControl.h>
00014 #include <BALL/VIEW/WIDGETS/geometricControl.h>
00015 #include <BALL/VIEW/WIDGETS/logView.h>
00016 #include <BALL/VIEW/WIDGETS/helpViewer.h>
00017 #include <BALL/VIEW/WIDGETS/datasetControl.h>
00018 #include <BALL/VIEW/WIDGETS/editableScene.h>
00019 #include <BALL/VIEW/WIDGETS/fileObserver.h>
00020 #include <BALL/VIEW/DIALOGS/pubchemDialog.h>
00021 #include <BALL/VIEW/DIALOGS/undoManagerDialog.h>
00022 #include <BALL/VIEW/DIALOGS/downloadPDBFile.h>
00023 #include <BALL/VIEW/DIALOGS/downloadElectronDensity.h>
00024 #include <BALL/VIEW/DIALOGS/labelDialog.h>
00025 #include <BALL/VIEW/DIALOGS/displayProperties.h>
00026 #include <BALL/VIEW/DIALOGS/molecularFileDialog.h>
00027 #include <BALL/VIEW/DATATYPE/standardDatasets.h>
00028 #ifdef BALL_PYTHON_SUPPORT
00029 # include <BALL/VIEW/WIDGETS/pyWidget.h>
00030 # include <BALL/VIEW/WIDGETS/testFramework.h>
00031 #endif
00032
00033 #include <BALL/SYSTEM/path.h>
00034 #include <BALL/KERNEL/forEach.h>
00035 #include <BALL/COMMON/version.h>
00036
00037 #include <QtGui/QKeyEvent>
00038 #include <QtGui/QTreeWidget>
00039
00040 #include <BALL/CONCEPT/moleculeObjectCreator.h>
00041 #ifdef BALL_HAS_ASIO
00042 #include <BALL/VIEW/KERNEL/serverWidget.h>
00043 #endif
00044
00045 #include "ui_aboutDialog.h"
00046
00047 #include <BALL/VIEW/DIALOGS/pluginDialog.h>
00048
00049 using namespace std;
00050
00051
00052 namespace BALL
00053 {
00054 using namespace std;
00055 using namespace BALL::VIEW;
00056
00057 Mainframe::Mainframe(QWidget* parent, const char* name)
00058 : MainControl(parent, name, ".BALLView"),
00059 scene_(0)
00060 {
00061 #ifdef BALL_VIEW_DEBUG
00062 Log.error() << "new Mainframe " << this << std::endl;
00063 #endif
00064
00065
00066
00067
00068 setWindowTitle(tr("BALLView"));
00069 setWindowIcon(QPixmap(bucky_64x64_xpm));
00070
00071 initPopupMenu(FILE_OPEN);
00072 initPopupMenu(EDIT);
00073 initPopupMenu(BUILD);
00074 initPopupMenu(DISPLAY);
00075 initPopupMenu(MOLECULARMECHANICS);
00076 initPopupMenu(TOOLS);
00077 #ifdef BALL_PYTHON_SUPPORT
00078 initPopupMenu(TOOLS_PYTHON);
00079 initPopupMenu(MainControl::USER);
00080 #endif
00081 initPopupMenu(WINDOWS);
00082 initPopupMenu(MACRO);
00083
00084
00085
00086
00087
00088
00089 setLoggingFilename("BALLView.log");
00090
00091
00092 String description = "Shortcut|Display|Toggle_Fullscreen";
00093 fullscreen_action_ = insertMenuEntry(MainControl::DISPLAY, (String)tr("Toggle Fullscreen"), this,
00094 SLOT(toggleFullScreen()), description,
00095 QKeySequence("Alt+X"));
00096
00097 fullscreen_action_->setIcon(IconLoader::instance().getIcon("actions/view-fullscreen"));
00098
00099 insertPopupMenuSeparator(DISPLAY);
00100 initPopupMenu(DISPLAY_VIEWPOINT);
00101
00102 new MolecularFileDialog(this, ((String)tr("MolecularFileDialog")).c_str());
00103 new DownloadPDBFile( this, ((String)tr("DownloadPDBFile")).c_str(), false);
00104 new DownloadElectronDensity(this, ((String)tr("DownloadElectronDensity")).c_str(), false);
00105 new PubChemDialog( this, ((String)tr("PubChemDialog")).c_str());
00106 new PluginDialog( this, ((String)tr("PluginDialog")).c_str());
00107 new UndoManagerDialog( this, ((String)tr("UndoManagerDialog")).c_str());
00108
00109 addDockWidget(Qt::LeftDockWidgetArea, new MolecularControl(this, ((String)tr("Structures")).c_str()));
00110 addDockWidget(Qt::LeftDockWidgetArea, new GeometricControl(this, ((String)tr("Representations")).c_str()));
00111 addDockWidget(Qt::TopDockWidgetArea, new DatasetControl(this, ((String)tr("Datasets")).c_str()));
00112 DatasetControl* dc = DatasetControl::getInstance(0);
00113 dc->registerController(new RegularData3DController());
00114 dc->registerController(new TrajectoryController());
00115 dc->registerController(new VectorGridController());
00116 dc->registerController(new DockResultController());
00117
00118
00119
00120
00121 DatasetControl::getInstance(0)->hide();
00122
00123 new DemoTutorialDialog(this, ((String)tr("BALLViewDemo")).c_str());
00124
00125 Path path;
00126
00127
00128
00129 String dirp = path.find("../doc/BALL/");
00130
00131 if (dirp != "")
00132 {
00133 HelpViewer* BALL_docu = new HelpViewer(this, ((String)tr("BALL Docu")).c_str());
00134 addDockWidget(Qt::BottomDockWidgetArea, BALL_docu);
00135
00136 BALL_docu->setBaseDirectory(dirp);
00137 BALL_docu->setWhatsThisEnabled(false);
00138 BALL_docu->setProject("BALL");
00139 BALL_docu->setDefaultPage("index.html");
00140
00141 }
00142 else
00143 {
00144 Log.error() << "Please build the BALL documentation!" << std::endl;
00145 }
00146
00147 addDockWidget(Qt::BottomDockWidgetArea, new HelpViewer(this, "BALLView Docu"));
00148 new LabelDialog( this, ((String)tr("LabelDialog")).c_str());
00149 new MolecularStructure( this, ((String)tr("MolecularStructure")).c_str());
00150 addDockWidget(Qt::BottomDockWidgetArea, new LogView( this, ((String)tr("Logs")).c_str()));
00151 addDockWidget(Qt::BottomDockWidgetArea, new FileObserver( this, ((String)tr("FileObserver")).c_str()));
00152
00153 Scene::stereoBufferSupportTest();
00154 scene_ = new EditableScene(this, ((String)tr("3D View")).c_str());
00155 setCentralWidget(scene_);
00156 setAcceptDrops(true);
00157
00158 new DisplayProperties(this, ((String)tr("DisplayProperties")).c_str());
00159
00160
00161 #ifdef BALL_HAS_ASIO
00162 ServerWidget* server = new ServerWidget(this);
00163
00164 MoleculeObjectCreator* object_creator = new MoleculeObjectCreator;
00165 server->registerObjectCreator(*object_creator);
00166 #endif
00167
00168 #ifdef BALL_PYTHON_SUPPORT
00169 new TestFramework(this, ((String)"Test Framework").c_str());
00170 addDockWidget(Qt::BottomDockWidgetArea, new PyWidget(this, ((String)tr("Python Interpreter")).c_str()));
00171 #endif
00172
00173
00174
00175
00176
00177 description = "Shortcut|File|Open|Project";
00178 insertMenuEntry(MainControl::FILE_OPEN, ((String)tr("Project")).c_str(), this,
00179 SLOT(loadBALLViewProjectFile()), description);
00180
00181 description = "Shortcut|File|Save_Project";
00182 save_project_action_ = insertMenuEntry(MainControl::FILE, ((String)tr("Save Project")).c_str(), this,
00183 SLOT(saveBALLViewProjectFile()), description);
00184
00185
00186 QAction* action = 0;
00187
00188 description = "Shortcut|Help|About";
00189 action = insertMenuEntry(MainControl::HELP, (String)tr("About"), this, SLOT(about()), description);
00190 setMenuHint(action, (String)tr("Show informations on this version of BALLView"));
00191
00192 description = "Shortcut|Help|How_to_cite";
00193 action = insertMenuEntry(MainControl::HELP, (String)tr("How to cite"), this, SLOT(howToCite()), description);
00194 setMenuHint(action, (String)tr("Show infos on how to cite BALL and BALLView"));
00195
00196
00197 description = "Shortcut|MolecularMechanics|Abort_Calculation";
00198 stop_simulation_action_ = insertMenuEntry(MainControl::MOLECULARMECHANICS, (String)tr("Abort Calculation"), this,
00199 SLOT(stopSimulation()), description,
00200 QKeySequence("Alt+C"));
00201
00202 stop_simulation_action_->setEnabled(false);
00203 insertPopupMenuSeparator(MainControl::MOLECULARMECHANICS);
00204 setMenuHint(stop_simulation_action_, (String)tr("Abort a running simulation"));
00205
00206 stop_simulation_action_->setIcon(IconLoader::instance().getIcon("actions/process-stop"));
00207
00208 description = "Shortcut|Edit|Invert_Selection";
00209 complement_selection_action_ = insertMenuEntry(MainControl::EDIT, (String)tr("Invert Selection"), this,
00210 SLOT(complementSelection()), description);
00211
00212 description = "Shortcut|Edit|Clear_Selection";
00213 clear_selection_action_ = insertMenuEntry(MainControl::EDIT, (String)tr("Clear Selection"), this,
00214 SLOT(clearSelection()), description);
00215
00216
00217 qApp->installEventFilter(this);
00218
00219 setStatusbarText((String)tr("Ready."));
00220 }
00221
00222 Mainframe::~Mainframe()
00223 {
00224 }
00225
00226
00227 bool Mainframe::eventFilter(QObject* sender, QEvent* event)
00228 {
00229 if (event->type() != QEvent::KeyPress) return false;
00230
00231 QKeyEvent* e = dynamic_cast<QKeyEvent*>(event);
00232
00233 if (e->key() == Qt::Key_Escape &&
00234 HelpViewer::getInstance("BALLView Docu")->isWhatsThisEnabled())
00235 {
00236 HelpViewer::getInstance("BALLView Docu")->exitWhatsThisMode();
00237 }
00238
00239 QPoint point = QCursor::pos();
00240 QWidget* widget = qApp->widgetAt(point);
00241 if (widget == scene_ &&
00242 qApp->focusWidget() != scene_)
00243 {
00244 scene_->keyPressEvent(e);
00245 return true;
00246 }
00247
00248 if (e->key() == Qt::Key_Delete &&
00249 RTTI::isKindOf<QTreeWidget>(*sender))
00250 {
00251 deleteClicked();
00252 return true;
00253 }
00254
00255 if (e->key() == Qt::Key_Enter)
00256 {
00257 if (composite_manager_.getNumberOfComposites() == 0) return false;
00258
00259 if (getMolecularControlSelection().size() == 0)
00260 {
00261 control_selection_.push_back(*composite_manager_.begin());
00262 }
00263
00264 MolecularStructure::getInstance(0)->centerCamera();
00265 return true;
00266 }
00267
00268
00269 if (e->key() == Qt::Key_Alt ||
00270 e->key() == Qt::Key_Control)
00271 {
00272 checkMenus();
00273 return false;
00274 }
00275
00276 #ifdef BALL_PYTHON_SUPPORT
00277 PyWidget::getInstance(0)->reactTo(*e);
00278 e->accept();
00279 #endif
00280
00281 return false;
00282 }
00283
00284
00285 void Mainframe::reset()
00286 {
00287 if (composites_locked_ || getRepresentationManager().updateRunning()) return;
00288
00289 clearData();
00290
00291 DisplayProperties* dp = DisplayProperties::getInstance(0);
00292 dp->setDrawingPrecision(DRAWING_PRECISION_HIGH);
00293 dp->selectModel(MODEL_STICK);
00294 dp->selectColoringMethod(COLORING_ELEMENT);
00295 dp->selectMode(DRAWING_MODE_SOLID);
00296 dp->setTransparency(0);
00297 dp->setSurfaceDrawingPrecision(6.5);
00298 }
00299
00300
00301 void Mainframe::howToCite()
00302 {
00303 HelpViewer::getInstance("BALLView Docu")->showHelp("tips.html", (String)tr("cite"));
00304 }
00305
00306 void Mainframe::show()
00307 {
00308
00309 if (preferences_action_ != 0)
00310 {
00311 MainControl::show();
00312 return;
00313 }
00314
00315
00316 QToolBar* tb = new QToolBar("Main Toolbar", this);
00317 tb->setObjectName("Main Toolbar");
00318 tb->setIconSize(QSize(22,22));
00319 addToolBar(Qt::TopToolBarArea, tb);
00320
00321 MainControl::show();
00322
00323 initPopupMenu(MainControl::WINDOWS)->addSeparator();
00324 initPopupMenu(MainControl::WINDOWS)->addAction(tb->toggleViewAction());
00325 MolecularFileDialog::getInstance(0)->addToolBarEntries(tb);
00326 DownloadPDBFile::getInstance(0)->addToolBarEntries(tb);
00327 DownloadElectronDensity::getInstance(0)->addToolBarEntries(tb);
00328 PubChemDialog::getInstance(0)->addToolBarEntries(tb);
00329 UndoManagerDialog::getInstance(0)->addToolBarEntries(tb);
00330 tb->addAction(fullscreen_action_);
00331 Path path;
00332
00333 IconLoader& loader = IconLoader::instance();
00334 qload_action_ = new QAction(loader.getIcon("actions/quickopen-file"), tr("quickload"), this);
00335 qload_action_->setObjectName("quickload");
00336 connect(qload_action_, SIGNAL(triggered()), this, SLOT(quickLoadConfirm()));
00337 HelpViewer::getInstance("BALLView Docu")->registerForHelpSystem(qload_action_, "tips.html#quickload");
00338 tb->addAction(qload_action_);
00339
00340 qsave_action_ = new QAction(loader.getIcon("actions/quicksave"), tr("quicksave"), this);
00341 qsave_action_->setObjectName("quicksave");
00342 connect(qsave_action_, SIGNAL(triggered()), this, SLOT(quickSave()));
00343 HelpViewer::getInstance("BALLView Docu")->registerForHelpSystem(qsave_action_, "tips.html#quickload");
00344 tb->addAction(qsave_action_);
00345
00346 tb->addSeparator();
00347 DisplayProperties::getInstance(0)->addToolBarEntries(tb);
00348 MolecularStructure::getInstance(0)->addToolBarEntries(tb);
00349 scene_->addToolBarEntries(tb);
00350 tb->addAction(stop_simulation_action_);
00351 tb->addAction(preferences_action_);
00352 HelpViewer::getInstance("BALLView Docu")->addToolBarEntries(tb);
00353
00354
00355
00356 restoreWindows();
00357 }
00358
00359 void Mainframe::about()
00360 {
00361
00362 QDialog w;
00363 Ui_AboutDialog about;
00364 about.setupUi(&w);
00365 QString version = QString(tr("QT ")) + qVersion();
00366 #ifdef BALL_QT_HAS_THREADS
00367 version += "(mt)";
00368 #endif
00369 about.qt_version_label->setText(version);
00370 QFont font = about.BALLView_version_label->font();
00371 about.BALLView_version_label->setText(QString("BALLView ") + BALL_RELEASE_STRING);
00372 font.setPixelSize(18);
00373 about.BALLView_version_label->setFont(font);
00374 about.BALL_version_label->setText(__DATE__);
00375
00376
00377 Path p;
00378 String logo_path = p.find("graphics/logo.png");
00379
00380 if (logo_path != "")
00381 about.BALLView_logo_label->setPixmap(QPixmap(logo_path.c_str()));
00382
00383 w.exec();
00384 }
00385
00386 void Mainframe::changeEvent(QEvent* evt)
00387 {
00388 if(evt->type() == QEvent::WindowStateChange) {
00389 if (isFullScreen())
00390 {
00391 fullscreen_action_->setIcon(IconLoader::instance().getIcon("actions/view-restore"));
00392 } else {
00393 fullscreen_action_->setIcon(IconLoader::instance().getIcon("actions/view-fullscreen"));
00394 }
00395 }
00396 }
00397
00398 }