BALL
1.4.1
|
00001 // -*- Mode: C++; tab-width: 2; -*- 00002 // vi: set ts=2: 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 //#define BALL_VIEW_DEBUG 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 // setup main window 00067 // --------------------- 00068 setWindowTitle(tr("BALLView")); 00069 setWindowIcon(QPixmap(bucky_64x64_xpm)); 00070 // make sure submenus are the first 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 // Logstream setup ----- 00086 // --------------------- 00087 // Log.remove(std::cout); 00088 // Log.remove(std::cerr); 00089 setLoggingFilename("BALLView.log"); 00090 00091 // Display Menu 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 // NOTE: raytraceable grids have been deferred until 1.4/2.0 00119 // dc->registerController(new RaytraceableGridController()); 00120 00121 DatasetControl::getInstance(0)->hide(); 00122 00123 new DemoTutorialDialog(this, ((String)tr("BALLViewDemo")).c_str()); 00124 00125 Path path; 00126 00127 // NOTE: disable the link to the BALL documentation until we can use webkit to correctly 00128 // display full HTML including remote links 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 // setup the VIEW server 00161 #ifdef BALL_HAS_ASIO 00162 ServerWidget* server = new ServerWidget(this); 00163 // registering object generator 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 // Menus --------------- 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 // Help-Menu ------------------------------------------------------------------- 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 // TODO: why is this done here and not, e.g., in mainControl()??? 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 // check all menu entries if Alt or CTRL is pressed to enable shortcuts 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 // prevent multiple inserting of menu entries, by calls of showFullScreen(), ... 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 // we have changed the child widgets stored in the maincontrol (e.g. toolbars), so we have 00355 // to restore the window state again! 00356 restoreWindows(); 00357 } 00358 00359 void Mainframe::about() 00360 { 00361 // Display about dialog 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 // find the BALLView log 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 }