CustusX  2023.01.05-dev+develop.0da12
An IGT application
cxMainWindow.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
11 
12 #include "cxMainWindow.h"
13 
14 #include <QtWidgets>
15 #include "boost/bind.hpp"
16 
17 #include "cxConfig.h"
18 #include "cxDataLocations.h"
19 #include "cxLogicManager.h"
20 #include "cxSettings.h"
21 #include "cxPatientModelService.h"
22 #include "cxViewService.h"
24 #include "cxAudioImpl.h"
25 #include "cxLayoutInteractor.h"
26 #include "cxCameraControl.h"
27 
29 #include "cxStatusBar.h"
30 #include "cxSecondaryMainWindow.h"
32 #include "cxSamplerWidget.h"
33 #include "cxHelperWidgets.h"
34 #include "cxMainWindowActions.h"
35 
38 #include "cxToolManagerWidget.h"
39 #include "cxFrameTreeWidget.h"
40 #include "cxNavigationWidget.h"
42 #include "cxToolPropertiesWidget.h"
43 #include "cxPreferencesDialog.h"
45 #include "cxMeshInfoWidget.h"
46 #include "cxTrackPadWidget.h"
47 #include "cxConsoleWidget.h"
48 #include "cxMetricWidget.h"
49 #include "cxPlaybackWidget.h"
50 #include "cxEraserWidget.h"
51 #include "cxFiltersWidget.h"
53 #include "cxManageClippersWidget.h"
54 #include "cxBrowserWidget.h"
55 #include "cxActiveToolProxy.h"
56 
57 namespace cx
58 {
59 
61  mFullScreenAction(NULL),
62  mStandard3DViewActions(new QActionGroup(this)),
63  mControlPanel(NULL),
64  mDockWidgets(new DynamicMainWindowWidgets(this)),
65  mActions(NULL)
66 {
67  this->setObjectName("main_window");
68 
69  mServices = VisServices::create(logicManager()->getPluginContext());
70  mLayoutInteractor.reset(new LayoutInteractor(mServices->view()));
71 
72  this->setCentralWidget(mServices->view()->createLayoutWidget(this, 0));
73 
74  mActions = new MainWindowActions(mServices, this);
75 
76  this->createActions();
77  this->createMenus();
78  this->createToolBars();
79  this->setStatusBar(new StatusBar(mServices->tracking(), mServices->view(), mServices->video()));
80 
81  reporter()->setAudioSource(AudioPtr(new AudioImpl()));
82 
83  connect(mServices->state().get(), &StateService::applicationStateChanged, this, &MainWindow::onApplicationStateChangedSlot);
84  connect(mServices->state().get(), &StateService::workflowStateChanged, this, &MainWindow::onWorkflowStateChangedSlot);
85  //connect(mServices->state().get(), &StateService::workflowStateAboutToChange, this, &MainWindow::saveDesktopSlot);
86 
87  this->updateWindowTitle();
88 
89  this->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
90 
91  this->addAsDockWidget(new PlaybackWidget(mServices->tracking(), mServices->video(), mServices->patient(), this), "Browsing");
92  this->addAsDockWidget(new VideoConnectionWidget(mServices, this), "Utility");
93  this->addAsDockWidget(new EraserWidget(mServices->patient(), mServices->view(), this), "Properties");
94  this->addAsDockWidget(new MetricWidget(mServices, this), "Utility");
95  this->addAsDockWidget(new SlicePropertiesWidget(mServices->patient(), mServices->view(), this), "Properties");
96  this->addAsDockWidget(new VolumePropertiesWidget(mServices, this), "Properties");
97  this->addAsDockWidget(new ActiveMeshPropertiesWidget(mServices, this), "Properties");
98  this->addAsDockWidget(new StreamPropertiesWidget(mServices->patient(), mServices->view(), this), "Properties");
99  this->addAsDockWidget(new TrackPadWidget(mServices->view(), this), "Utility");
100  this->addAsDockWidget(new ActiveToolPropertiesWidget(mServices->tracking(), mServices->spaceProvider(), this), "Properties");
101  this->addAsDockWidget(new NavigationWidget(mServices->view(), mServices->tracking(), this), "Properties");
102  this->addAsDockWidget(new ConsoleWidget(this, "console_widget", "Console"), "Utility");
103  this->addAsDockWidget(new ConsoleWidget(this, "console_widget_2", "Extra Console"), "Utility");
104 // this->addAsDockWidget(new ConsoleWidgetCollection(this, "ConsoleWidgets", "Consoles"), "Utility");
105  this->addAsDockWidget(new FrameTreeWidget(mServices->patient(), this), "Browsing");
106  this->addAsDockWidget(new ToolManagerWidget(mServices->tracking(), this), "Debugging");
107  this->addAsDockWidget(new PluginFrameworkWidget(this), "Browsing");
108  this->addAsDockWidget(new FiltersWidget(VisServices::create(logicManager()->getPluginContext()), this), "Algorithms");
109  this->addAsDockWidget(new ClippingPropertiesWidget(mServices, this), "Properties");
110 
111  this->addAsDockWidget(new BrowserWidget(this, mServices), "Browsing");
112 
113  connect(mServices->patient().get(), &PatientModelService::patientChanged, this, &MainWindow::patientChangedSlot);
114  connect(qApp, &QApplication::focusChanged, this, &MainWindow::focusChanged);
115 
116  this->setupGUIExtenders();
117 
118  // window menu must be created after all dock widgets are created
119  QMenu* popupMenu = this->createPopupMenu();
120  popupMenu->setTitle("Window");
121  this->menuBar()->insertMenu(mHelpMenuAction, popupMenu);
122  this->menuBar()->setVisible(settings()->value("Gui/showMenuBar").toBool());
123 
124  // show after window has been initialized
125  QTimer::singleShot(0, this, SLOT(delayedShow()));
126 }
127 
129 {
130  // Restore saved window states
131  // Must be done after all DockWidgets are created
132  if (restoreGeometry(settings()->value("mainWindow/geometry").toByteArray()))
133  {
134  this->show();
135  }
136  else
137  {
138  this->showMaximized();
139  }
140 
141  if (settings()->value("gui/fullscreen").toBool())
142  {
143  this->setWindowState(this->windowState() | Qt::WindowFullScreen);
144  }
145 }
146 
147 void MainWindow::changeEvent(QEvent * event)
148 {
149  QMainWindow::changeEvent(event);
150 
151  if (event->type() == QEvent::WindowStateChange)
152  {
153  if (mFullScreenAction)
154  mFullScreenAction->setChecked(this->windowState() & Qt::WindowFullScreen);
155  }
156 }
157 
158 void MainWindow::setupGUIExtenders()
159 {
160  mServiceListener.reset(new ServiceTrackerListener<GUIExtenderService>(
161  LogicManager::getInstance()->getPluginContext(),
162  boost::bind(&MainWindow::onGUIExtenderServiceAdded, this, _1),
163  boost::bind(&MainWindow::onGUIExtenderServiceModified, this, _1),
164  boost::bind(&MainWindow::onGUIExtenderServiceRemoved, this, _1)
165  ));
166  mServiceListener->open();
167 }
168 
170 {
171  std::vector<GUIExtenderService::CategorizedWidget> widgets = service->createWidgets();
172  for (unsigned j = 0; j < widgets.size(); ++j)
173  {
174  if(!widgets[j].mPlaceInSeparateWindow)
175  mDockWidgets->addAsDockWidget(widgets[j].mWidget, widgets[j].mCategory, service);
176  else
177  this->createActionForWidgetInSeparateWindow(widgets[j].mWidget);
178  }
179 
180  std::vector<QToolBar*> toolBars = service->createToolBars();
181  for(unsigned j = 0; j < toolBars.size(); ++j)
182  {
183  mDockWidgets->registerToolBar(toolBars[j]);
184  }
185 }
186 
188 {
189 }
190 
192 {
193  mDockWidgets->owningServiceRemoved(service);
194 }
195 
197 {
198  if (val)
199  this->focusInsideDockWidget(sender());
200 }
201 
202 void MainWindow::focusChanged(QWidget * old, QWidget * now)
203 {
204  this->focusInsideDockWidget(now);
205 }
206 
207 void MainWindow::focusInsideDockWidget(QObject *dockWidget)
208 {
209  if (!dockWidget)
210  return;
211 
212 // CX_LOG_CHANNEL_DEBUG("HELP_DB") << QString(" try mw::focus [%1](%2)")
213 // .arg(dockWidget->objectName())
214 // .arg(dockWidget->metaObject()->className());
215 
216  // focusing to docked widgets is required by the help system
217 
218  // Assume structure: QDockWidget->QScrollArea->QWidget,
219  // as defined in MainWindow::addAsDockWidget()
220  QDockWidget* dw = dynamic_cast<QDockWidget*>(dockWidget);
221  if (!dw)
222  return;
223  if (dw->parent()!=this) // avoid events from other mainwindows
224  return;
225  QScrollArea* sa = dynamic_cast<QScrollArea*>(dw->widget());
226  if (!sa)
227  return;
228 
229  if (!sa->widget())
230  return;
231 
232 // CX_LOG_CHANNEL_DEBUG("HELP_DB") << QString(" do mw::focus [%1](%2)")
233 // .arg(sa->widget()->objectName())
234 // .arg(sa->widget()->metaObject()->className());
235 
236  QTimer::singleShot(0, sa->widget(), SLOT(setFocus())); // avoid loops etc by send async event.
237 }
238 
240 {
241  mServices->view()->deactivateLayout();
242  reporter()->setAudioSource(AudioPtr()); // important! QSound::play fires a thread, causes segfault during shutdown
243  mServiceListener.reset();
244 }
245 
247 {
248  return mDockWidgets->createPopupMenu();
249 }
250 
251 void MainWindow::createActions()
252 {
253  CameraControlPtr cameraControl = mServices->view()->getCameraControl();
254  if (cameraControl)
255  mStandard3DViewActions = cameraControl->createStandard3DViewActions();
256 
257  mShowContextSensitiveHelpAction = new QAction(QIcon(":/icons/open_icon_library/help-contents-5.png"),
258  "Context-sensitive help", this);
259  connect(mShowContextSensitiveHelpAction, &QAction::triggered, this, &MainWindow::onShowContextSentitiveHelp);
260 
261  mShowControlPanelAction = new QAction("Show Control Panel", this);
262  connect(mShowControlPanelAction, &QAction::triggered, this, &MainWindow::showControlPanelActionSlot);
263  mSecondaryViewLayoutWindowAction = new QAction("Show Secondary View Layout Window", this);
264  connect(mSecondaryViewLayoutWindowAction, &QAction::triggered, this, &MainWindow::showSecondaryViewLayoutWindowActionSlot);
265 
266  // Application
267  mAboutAction = new QAction(tr("About"), this);
268  mAboutAction->setStatusTip(tr("Show the application's About box"));
269  mPreferencesAction = new QAction(tr("Preferences"), this);
270  mPreferencesAction->setShortcut(tr("Ctrl+,"));
271  mPreferencesAction->setStatusTip(tr("Show the preferences dialog"));
272  mPreferencesToolConfigAction = new QAction(tr("Tool Config"), this);
273 
274  mFullScreenAction = new QAction(tr("Fullscreen"), this);
275  mFullScreenAction->setShortcut(tr("F11"));
276  mFullScreenAction->setStatusTip(tr("Toggle full screen"));
277  mFullScreenAction->setCheckable(true);
278  mFullScreenAction->setChecked(this->windowState() & Qt::WindowFullScreen);
279  connect(mFullScreenAction, &QAction::triggered, this, &MainWindow::toggleFullScreenSlot);
280 
281  mQuitAction = new QAction(tr("&Quit"), this);
282  mQuitAction->setShortcut(tr("Ctrl+Q"));
283  mQuitAction->setStatusTip(tr("Exit the application"));
284 
285  connect(mAboutAction, &QAction::triggered, this, &MainWindow::aboutSlot);
286  connect(mPreferencesAction, &QAction::triggered, this, &MainWindow::preferencesSlot);
287  connect(mPreferencesToolConfigAction, &QAction::triggered, this, [this]{ preferencesSlot(5); });
288  connect(mQuitAction, &QAction::triggered, qApp, &QApplication::quit);
289 
290  mSaveDesktopAction = new QAction(QIcon(":/icons/workflow_state_save.png"), tr("Save desktop"), this);
291  mSaveDesktopAction->setToolTip("Save desktop for workflow step");
292  connect(mSaveDesktopAction, &QAction::triggered, this, &MainWindow::saveDesktopSlot);
293  mResetDesktopAction = new QAction(QIcon(":/icons/workflow_state_revert.png"), tr("Reset desktop"), this);
294  mResetDesktopAction->setToolTip("Reset desktop for workflow step");
295  connect(mResetDesktopAction, &QAction::triggered, this, &MainWindow::resetDesktopSlot);
296 
297  mInteractorStyleActionGroup = mServices->view()->getInteractorStyleActionGroup();
298 
299  // cross-connect save patient to save session
300  //connect(mServices->session().get(), &SessionStorageService::isSaving, this, &MainWindow::saveDesktopSlot, Qt::DirectConnection);
301 }
302 
303 
305 {
306  this->updateWindowTitle();
307 }
308 
309 void MainWindow::updateWindowTitle()
310 {
311  QString profileName = mServices->state()->getApplicationStateName();
312  QString versionName = mServices->state()->getVersionName();
313 
314  QString activePatientFolder = mServices->patient()->getActivePatientFolder();
315  if (activePatientFolder.endsWith('/'))
316  activePatientFolder.chop(1);
317  QString patientName;
318 
319  if (!activePatientFolder.isEmpty())
320  {
321  QFileInfo info(activePatientFolder);
322  patientName = info.completeBaseName();
323  }
324 
325  QString format("%1 %2 - %3 - %4 (not approved for medical use)");
326  QString title = format
327  .arg(qApp->applicationDisplayName())
328  .arg(versionName)
329  .arg(profileName)
330  .arg(patientName);
331  this->setWindowTitle(title);
332 }
333 
335 {
336  Desktop desktop = mServices->state()->getActiveDesktop();
337 
338  mDockWidgets->restoreFrom(desktop);
339  mServices->view()->setActiveLayout(desktop.mLayoutUid, 0);
340  mServices->view()->setActiveLayout(desktop.mSecondaryLayoutUid, 1);
341  mServices->patient()->autoSave();
342 
343  // moved to help plugin:
344 // // set initial focus to mainwindow in order to view it in the documentation
345 // // this is most important when starting up.
346 // QTimer::singleShot(0, this, SLOT(setFocus())); // avoid loops etc by send async event.
347 
348 //#ifdef CX_APPLE
349 // // HACK
350 // // Toolbars are not correctly refreshed on mac 10.8,
351 // // Cause is related to QVTKWidget (removing it removes the problem)
352 // // The following "force refresh by resize" solves repaint, but
353 // // inactive toolbars are still partly clickable.
354 // QSize size = this->size();
355 // this->resize(size.width()-1, size.height());
356 // this->resize(size);
357 //#endif
358 }
359 
361 {
362  CX_LOG_DEBUG() << "saveDesktopSlot";
363  Desktop desktop;
364  desktop.mMainWindowState = this->saveState();
365  desktop.mLayoutUid = mServices->view()->getActiveLayout(0);
366  desktop.mSecondaryLayoutUid = mServices->view()->getActiveLayout(1);
367  mServices->state()->saveDesktop(desktop);
368 
369  // save to settings file in addition
370  settings()->setValue("mainWindow/geometry", saveGeometry());
371  settings()->setValue("mainWindow/windowState", saveState());
372  settings()->sync();
373 }
374 
376 {
377  mServices->state()->resetDesktop();
379 }
380 
382 {
383  mDockWidgets->showWidget("Help");
384 }
385 
387 {
388  this->setWindowState(this->windowState() ^ Qt::WindowFullScreen);
389 
390  settings()->setValue("gui/fullscreen", (this->windowState() & Qt::WindowFullScreen)!=0);
391 }
392 
393 void MainWindow::createActionForWidgetInSeparateWindow(QWidget* widget)
394 {
395  QString uid = widget->objectName();
396  if(mSecondaryMainWindows.find(uid) == mSecondaryMainWindows.end())
397  {
398  SecondaryMainWindow* secondaryMainWindow = new SecondaryMainWindow(this, widget);
399  QAction* action = new QAction(widget->windowTitle(), this);
400 
401  mSecondaryMainWindows[uid] = secondaryMainWindow;
402  mSecondaryMainWindowsActions[uid] = action;
403 
404  connect(action, &QAction::triggered, secondaryMainWindow, &QWidget::show);
405 
406  mFileMenu->addAction(action);
407  }
408 }
409 
411 {
412  if (!mControlPanel)
413  {
414  TrackPadWidget* trackPadWidget = new TrackPadWidget(mServices->view(), this);
415  mControlPanel = new SecondaryMainWindow(this, trackPadWidget);
416  }
417  mControlPanel->show();
418 }
419 
421 {
422  if (!mSecondaryViewLayoutWindow)
423  mSecondaryViewLayoutWindow = new SecondaryViewLayoutWindow(this);
424  mSecondaryViewLayoutWindow->tryShowOnSecondaryScreen();
425 }
426 
428 {
429  this->updateWindowTitle();
430 }
431 
432 void MainWindow::createMenus()
433 {
434 #ifdef CX_LINUX
435  // shortcuts defined on actions in the global menubar is not reachable on Qt5+Ubuntu14.04,
436  // solve by reverting to old style.
437  // This will create a double menubar: remove by autohiding menubar or using
438  // sudo apt-get autoremove appmenu-gtk appmenu-gtk3 appmenu-qt
439  // and reboot
440  this->menuBar()->setNativeMenuBar(false);
441 #endif
442  mFileMenu = new QMenu(tr("File"), this);
443  mWorkflowMenu = new QMenu(tr("Workflow"), this);
444  mToolMenu = new QMenu(tr("Tracking"), this);
445  mLayoutMenu = new QMenu(tr("Layouts"), this);
446  mNavigationMenu = new QMenu(tr("Navigation"), this);
447  mHelpMenu = new QMenu(tr("Help"), this);
448 
449  // File
450  mFileMenu->addAction(mPreferencesAction);
451  this->menuBar()->addMenu(mFileMenu);
452  mFileMenu->addAction(mActions->getAction("NewPatient"));
453  mFileMenu->addAction(mActions->getAction("SaveFile"));
454  mFileMenu->addAction(mActions->getAction("LoadFile"));
455  mFileMenu->addAction(mActions->getAction("LoadFileCopy"));
456  mFileMenu->addAction(mActions->getAction("ClearPatient"));
457  mFileMenu->addSeparator();
458  mFileMenu->addAction(mActions->getAction("ExportPatient"));
459  mFileMenu->addAction(mActions->getAction("AddFilesForImport"));
460  mFileMenu->addSeparator();
461  mFileMenu->addAction(mFullScreenAction);
462  mFileMenu->addAction(mActions->getAction("StartLogConsole"));
463  mFileMenu->addAction(mActions->getAction("ShootScreen"));
464  mFileMenu->addAction(mActions->getAction("ShootWindow"));
465  mFileMenu->addAction(mActions->getAction("RecordFullscreen"));
466  mFileMenu->addSeparator();
467  mFileMenu->addAction(mShowControlPanelAction);
468  mFileMenu->addAction(mSecondaryViewLayoutWindowAction);
469 
470  mFileMenu->addAction(mQuitAction);
471 
472  //workflow
473  this->menuBar()->addMenu(mWorkflowMenu);
474  QList<QAction*> actions = mServices->state()->getWorkflowActions()->actions();
475  for (int i=0; i<actions.size(); ++i)
476  {
477  mWorkflowMenu->addAction(actions[i]);
478  }
479 
480  mWorkflowMenu->addSeparator();
481  mWorkflowMenu->addAction(mSaveDesktopAction);
482  mWorkflowMenu->addAction(mResetDesktopAction);
483 
484  //tool
485  this->menuBar()->addMenu(mToolMenu);
486  mToolMenu->addAction(mPreferencesToolConfigAction);
487  mToolMenu->addAction(mActions->getAction("TrackingTools"));
488  mToolMenu->addSeparator();
489  mToolMenu->addAction(mActions->getAction("StartStreaming"));
490  mToolMenu->addSeparator();
491 
492  //layout
493  this->menuBar()->addMenu(mLayoutMenu);
494  mLayoutInteractor->connectToMenu(mLayoutMenu);
495 
496  this->menuBar()->addMenu(mNavigationMenu);
497  mNavigationMenu->addAction(mActions->getAction("CenterToImageCenter"));
498  mNavigationMenu->addAction(mActions->getAction("CenterToTooltip"));
499  mNavigationMenu->addAction(mActions->getAction("ShowPointPicker"));
500  mNavigationMenu->addSeparator();
501  mNavigationMenu->addActions(mInteractorStyleActionGroup->actions());
502 
503  mHelpMenuAction = this->menuBar()->addMenu(mHelpMenu);
504  mHelpMenu->addAction(mAboutAction);
505  mHelpMenu->addAction(mActions->getAction("GotoDocumentation"));
506  mHelpMenu->addAction(mShowContextSensitiveHelpAction);
507 }
508 
509 void MainWindow::createToolBars()
510 {
511  mWorkflowToolBar = this->registerToolBar("Workflow");
512  QList<QAction*> actions = mServices->state()->getWorkflowActions()->actions();
513  for (int i=0; i<actions.size(); ++i)
514  mWorkflowToolBar->addAction(actions[i]);
515 
516  mDataToolBar = this->registerToolBar("Data");
517  mDataToolBar->addAction(mActions->getAction("NewPatient"));
518  mDataToolBar->addAction(mActions->getAction("LoadFile"));
519  mDataToolBar->addAction(mActions->getAction("SaveFile"));
520  mDataToolBar->addAction(mActions->getAction("AddFilesForImport"));
521 
522  mToolToolBar = this->registerToolBar("Tools");
523  mToolToolBar->addAction(mActions->getAction("TrackingTools"));
524  mToolToolBar->addAction(mActions->getAction("StartStreaming"));
525 
526  mNavigationToolBar = this->registerToolBar("Navigation");
527  mNavigationToolBar->addAction(mActions->getAction("CenterToImageCenter"));
528  mNavigationToolBar->addAction(mActions->getAction("CenterToTooltip"));
529  mNavigationToolBar->addAction(mActions->getAction("ShowPointPicker"));
530 
531  mInteractorStyleToolBar = this->registerToolBar("InteractorStyle");
532  mInteractorStyleToolBar->addActions(mInteractorStyleActionGroup->actions());
533 
534  mDesktopToolBar = this->registerToolBar("Desktop");
535  mDesktopToolBar->addAction(mSaveDesktopAction);
536  mDesktopToolBar->addAction(mResetDesktopAction);
537 
538  mScreenshotToolBar = this->registerToolBar("Screenshot");
539  mScreenshotToolBar->addAction(mActions->getAction("ShootScreen"));
540  mScreenshotToolBar->addAction(mActions->getAction("RecordFullscreen"));
541 
542  QToolBar* camera3DViewToolBar = this->registerToolBar("Camera 3D Views");
543  camera3DViewToolBar->addActions(mStandard3DViewActions->actions());
544 
545  QToolBar* samplerWidgetToolBar = this->registerToolBar("Sampler");
546  samplerWidgetToolBar->addWidget(new SamplerWidget(mServices->tracking(), mServices->patient(), mServices->spaceProvider(), this));
547 
548  QToolBar* toolOffsetToolBar = this->registerToolBar("Tool Offset");
550  SpinBoxAndSliderGroupWidget* offsetWidget = new SpinBoxAndSliderGroupWidget(this, offset);
551  offsetWidget->showLabel(false);
552  toolOffsetToolBar->addWidget(offsetWidget);
553 
554  QToolBar* helpToolBar = this->registerToolBar("Help");
555  helpToolBar->addAction(mShowContextSensitiveHelpAction);
556 }
557 
558 QToolBar* MainWindow::registerToolBar(QString name, QString groupname)
559 {
560  QToolBar* toolbar = new QToolBar(name);
561  toolbar->setObjectName(QString(name).remove(" ")+"ToolBar");
562  mDockWidgets->registerToolBar(toolbar, groupname);
563  return toolbar;
564 }
565 
567 {
568  QString doc_path = DataLocations::getDocPath();
569  QString appName = qApp->applicationDisplayName();
570  QString url_website = DataLocations::getWebsiteURL();
571  QString url_license = QString("file://%1/License.txt").arg(doc_path);
572  QString url_config = QString("file://%1/cxConfigDescription.txt").arg(doc_path);
573 
574  QString text(""
575  "<h2>%1</h2>"
576  "<h4>%2</h4>"
577  "<p>A Research Platform for Image-Guided Therapy<p>"
578  "<p>%1 is NOT approved for medical use.<p>"
579  ""
580  "<p><a href=%3> website </a><p>"
581  "<p><a href=%4> license </a><p>"
582  "<p><a href=%5> configuration </a><p>");
583 
584  QMessageBox::about(this, tr("About %1").arg(appName), text
585  .arg(appName)
586  .arg(CustusX_VERSION_STRING)
587  .arg(url_website)
588  .arg(url_license)
589  .arg(url_config)
590  );
591 }
592 
593 void MainWindow::preferencesSlot(int currentTabIndex)
594 {
595  PreferencesDialog prefDialog(mServices->view(), mServices->patient(), mServices->state(), mServices->tracking(), currentTabIndex, this);
596  prefDialog.exec();
597 }
598 
599 void MainWindow::closeEvent(QCloseEvent *event)
600 {
601  QMainWindow::closeEvent(event);
602  qApp->quit();
603 }
604 
605 QDockWidget* MainWindow::addAsDockWidget(QWidget* widget, QString groupname)
606 {
607  QDockWidget* dw = mDockWidgets->addAsDockWidget(widget, groupname);
608  return dw;
609 
610 }
611 
612 }//namespace cx
Widget for controlling camera follow style.
void registerToolBar(QToolBar *toolbar, QString groupname="Toolbars")
void dockWidgetVisibilityChanged(bool val)
Widget for displaying and changing clipper properties.
virtual QMenu * createPopupMenu()
ReporterPtr reporter()
Definition: cxReporter.cpp:36
void changeEvent(QEvent *event)
boost::shared_ptr< class CameraControl > CameraControlPtr
Statusbar with extended functionality.
Definition: cxStatusBar.h:70
void applicationStateChanged()
void showSecondaryViewLayoutWindowActionSlot()
Shows a treestructure containing the loaded images, meshes and tools.
void focusChanged(QWidget *old, QWidget *now)
void restoreFrom(const Desktop &desktop)
void patientChangedSlot()
static VisServicesPtr create(ctkPluginContext *context)
Experimental class for IPad usage.This detached main window can be moved onto a secondary screen...
Widget for displaying status messages.
Widget for displaying and manipulating various 3D Volume properties.
void onApplicationStateChangedSlot()
void resetDesktopSlot()
static ActiveToolProxyPtr New(TrackingServicePtr trackingService)
void setValue(const QString &key, const QVariant &value)
Definition: cxSettings.cpp:58
GUI for setting up a connection to a video stream.
Widget for controlling the camera in the 3D view.This widget is designed for use on a touchpad device...
Composite widget for scalar data manipulation.
Experimental class for IPad usage.
void onGUIExtenderServiceAdded(GUIExtenderService *service)
void toggleFullScreenSlot()
void onGUIExtenderServiceRemoved(GUIExtenderService *service)
void saveDesktopSlot()
void preferencesSlot(int currentTabIndex=0)
static QString getWebsiteURL()
QByteArray mMainWindowState
static LogicManager * getInstance()
Widget interface to PlaybackTime.
void onGUIExtenderServiceModified(GUIExtenderService *service)
boost::shared_ptr< class DoublePropertyBase > DoublePropertyBasePtr
void onShowContextSentitiveHelp()
Settings * settings()
Shortcut for accessing the settings instance.
Definition: cxSettings.cpp:21
Widget for displaying the FrameForest object.
Widget for displaying and manipulating TrackedStream properties.
Helper class for listening to services being added, modified and removed.
LogicManager * logicManager()
void workflowStateChanged()
Data class for CustusX desktop.
void showControlPanelActionSlot()
QAction * getAction(QString uid)
QString mLayoutUid
#define CX_LOG_DEBUG
Definition: cxLogger.h:95
virtual ~MainWindow()
virtual std::vector< QToolBar * > createToolBars() const
QString mSecondaryLayoutUid
Designed as a debugging widget for the cxToolManager.
static boost::shared_ptr< DoublePropertyActiveToolOffset > create(ActiveToolProxyPtr activeTool)
virtual std::vector< CategorizedWidget > createWidgets() const =0
QDockWidget * addAsDockWidget(QWidget *widget, QString groupname, QObject *owningPlugin=NULL)
void onWorkflowStateChangedSlot()
static QString getDocPath()
return path to folder containing documentation files
Set application preferences.
boost::shared_ptr< Audio > AudioPtr
Definition: cxAudio.h:47
Widget for erasing parts of images/meshes.
Namespace for all CustusX production code.