CustusX  18.04
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 
273  mFullScreenAction = new QAction(tr("Fullscreen"), this);
274  mFullScreenAction->setShortcut(tr("F11"));
275  mFullScreenAction->setStatusTip(tr("Toggle full screen"));
276  mFullScreenAction->setCheckable(true);
277  mFullScreenAction->setChecked(this->windowState() & Qt::WindowFullScreen);
278  connect(mFullScreenAction, &QAction::triggered, this, &MainWindow::toggleFullScreenSlot);
279 
280  mQuitAction = new QAction(tr("&Quit"), this);
281  mQuitAction->setShortcut(tr("Ctrl+Q"));
282  mQuitAction->setStatusTip(tr("Exit the application"));
283 
284  connect(mAboutAction, &QAction::triggered, this, &MainWindow::aboutSlot);
285  connect(mPreferencesAction, &QAction::triggered, this, &MainWindow::preferencesSlot);
286  connect(mQuitAction, &QAction::triggered, qApp, &QApplication::quit);
287 
288  mSaveDesktopAction = new QAction(QIcon(":/icons/workflow_state_save.png"), tr("Save desktop"), this);
289  mSaveDesktopAction->setToolTip("Save desktop for workflow step");
290  connect(mSaveDesktopAction, &QAction::triggered, this, &MainWindow::saveDesktopSlot);
291  mResetDesktopAction = new QAction(QIcon(":/icons/workflow_state_revert.png"), tr("Reset desktop"), this);
292  mResetDesktopAction->setToolTip("Reset desktop for workflow step");
293  connect(mResetDesktopAction, &QAction::triggered, this, &MainWindow::resetDesktopSlot);
294 
295  mInteractorStyleActionGroup = mServices->view()->getInteractorStyleActionGroup();
296 
297  // cross-connect save patient to save session
298  connect(mServices->session().get(), &SessionStorageService::isSaving, this, &MainWindow::saveDesktopSlot);
299 }
300 
301 
303 {
304  this->updateWindowTitle();
305 }
306 
307 void MainWindow::updateWindowTitle()
308 {
309  QString profileName = mServices->state()->getApplicationStateName();
310  QString versionName = mServices->state()->getVersionName();
311 
312  QString activePatientFolder = mServices->patient()->getActivePatientFolder();
313  if (activePatientFolder.endsWith('/'))
314  activePatientFolder.chop(1);
315  QString patientName;
316 
317  if (!activePatientFolder.isEmpty())
318  {
319  QFileInfo info(activePatientFolder);
320  patientName = info.completeBaseName();
321  }
322 
323  QString format("%1 %2 - %3 - %4 (not approved for medical use)");
324  QString title = format
325  .arg(qApp->applicationDisplayName())
326  .arg(versionName)
327  .arg(profileName)
328  .arg(patientName);
329  this->setWindowTitle(title);
330 }
331 
333 {
334  Desktop desktop = mServices->state()->getActiveDesktop();
335 
336  mDockWidgets->restoreFrom(desktop);
337  mServices->view()->setActiveLayout(desktop.mLayoutUid, 0);
338  mServices->view()->setActiveLayout(desktop.mSecondaryLayoutUid, 1);
339  mServices->patient()->autoSave();
340 
341  // moved to help plugin:
342 // // set initial focus to mainwindow in order to view it in the documentation
343 // // this is most important when starting up.
344 // QTimer::singleShot(0, this, SLOT(setFocus())); // avoid loops etc by send async event.
345 
346 //#ifdef CX_APPLE
347 // // HACK
348 // // Toolbars are not correctly refreshed on mac 10.8,
349 // // Cause is related to QVTKWidget (removing it removes the problem)
350 // // The following "force refresh by resize" solves repaint, but
351 // // inactive toolbars are still partly clickable.
352 // QSize size = this->size();
353 // this->resize(size.width()-1, size.height());
354 // this->resize(size);
355 //#endif
356 }
357 
359 {
360  Desktop desktop;
361  desktop.mMainWindowState = this->saveState();
362  desktop.mLayoutUid = mServices->view()->getActiveLayout(0);
363  desktop.mSecondaryLayoutUid = mServices->view()->getActiveLayout(1);
364  mServices->state()->saveDesktop(desktop);
365 
366  // save to settings file in addition
367  settings()->setValue("mainWindow/geometry", saveGeometry());
368  settings()->setValue("mainWindow/windowState", saveState());
369  settings()->sync();
370 }
371 
373 {
374  mServices->state()->resetDesktop();
376 }
377 
379 {
380  mDockWidgets->showWidget("Help");
381 }
382 
384 {
385  this->setWindowState(this->windowState() ^ Qt::WindowFullScreen);
386 
387  settings()->setValue("gui/fullscreen", (this->windowState() & Qt::WindowFullScreen)!=0);
388 }
389 
390 void MainWindow::createActionForWidgetInSeparateWindow(QWidget* widget)
391 {
392  QString uid = widget->objectName();
393  if(mSecondaryMainWindows.find(uid) == mSecondaryMainWindows.end())
394  {
395  SecondaryMainWindow* secondaryMainWindow = new SecondaryMainWindow(this, widget);
396  QAction* action = new QAction(widget->windowTitle(), this);
397 
398  mSecondaryMainWindows[uid] = secondaryMainWindow;
399  mSecondaryMainWindowsActions[uid] = action;
400 
401  connect(action, &QAction::triggered, secondaryMainWindow, &QWidget::show);
402 
403  mFileMenu->addAction(action);
404  }
405 }
406 
408 {
409  if (!mControlPanel)
410  {
411  TrackPadWidget* trackPadWidget = new TrackPadWidget(mServices->view(), this);
412  mControlPanel = new SecondaryMainWindow(this, trackPadWidget);
413  }
414  mControlPanel->show();
415 }
416 
418 {
419  if (!mSecondaryViewLayoutWindow)
420  mSecondaryViewLayoutWindow = new SecondaryViewLayoutWindow(this);
421  mSecondaryViewLayoutWindow->tryShowOnSecondaryScreen();
422 }
423 
425 {
426  this->updateWindowTitle();
427 }
428 
429 void MainWindow::createMenus()
430 {
431 #ifdef CX_LINUX
432  // shortcuts defined on actions in the global menubar is not reachable on Qt5+Ubuntu14.04,
433  // solve by reverting to old style.
434  // This will create a double menubar: remove by autohiding menubar or using
435  // sudo apt-get autoremove appmenu-gtk appmenu-gtk3 appmenu-qt
436  // and reboot
437  this->menuBar()->setNativeMenuBar(false);
438 #endif
439  mFileMenu = new QMenu(tr("File"), this);
440  mWorkflowMenu = new QMenu(tr("Workflow"), this);
441  mToolMenu = new QMenu(tr("Tracking"), this);
442  mLayoutMenu = new QMenu(tr("Layouts"), this);
443  mNavigationMenu = new QMenu(tr("Navigation"), this);
444  mHelpMenu = new QMenu(tr("Help"), this);
445 
446  // File
447  mFileMenu->addAction(mPreferencesAction);
448  this->menuBar()->addMenu(mFileMenu);
449  mFileMenu->addAction(mActions->getAction("NewPatient"));
450  mFileMenu->addAction(mActions->getAction("SaveFile"));
451  mFileMenu->addAction(mActions->getAction("LoadFile"));
452  mFileMenu->addAction(mActions->getAction("LoadFileCopy"));
453  mFileMenu->addAction(mActions->getAction("ClearPatient"));
454  mFileMenu->addSeparator();
455  mFileMenu->addAction(mActions->getAction("ExportPatient"));
456  mFileMenu->addAction(mActions->getAction("ImportData"));
457  mFileMenu->addSeparator();
458  mFileMenu->addAction(mFullScreenAction);
459  mFileMenu->addAction(mActions->getAction("StartLogConsole"));
460  mFileMenu->addAction(mActions->getAction("ShootScreen"));
461  mFileMenu->addAction(mActions->getAction("ShootWindow"));
462  mFileMenu->addAction(mActions->getAction("RecordFullscreen"));
463  mFileMenu->addSeparator();
464  mFileMenu->addAction(mShowControlPanelAction);
465  mFileMenu->addAction(mSecondaryViewLayoutWindowAction);
466 
467  mFileMenu->addAction(mQuitAction);
468 
469  //workflow
470  this->menuBar()->addMenu(mWorkflowMenu);
471  QList<QAction*> actions = mServices->state()->getWorkflowActions()->actions();
472  for (int i=0; i<actions.size(); ++i)
473  {
474  mWorkflowMenu->addAction(actions[i]);
475  }
476 
477  mWorkflowMenu->addSeparator();
478  mWorkflowMenu->addAction(mSaveDesktopAction);
479  mWorkflowMenu->addAction(mResetDesktopAction);
480 
481  //tool
482  this->menuBar()->addMenu(mToolMenu);
483  mToolMenu->addAction(mActions->getAction("ConfigureTools"));
484  mToolMenu->addAction(mActions->getAction("InitializeTools"));
485  mToolMenu->addAction(mActions->getAction("TrackingTools"));
486  mToolMenu->addSeparator();
487  mToolMenu->addAction(mActions->getAction("StartStreaming"));
488  mToolMenu->addSeparator();
489 
490  //layout
491  this->menuBar()->addMenu(mLayoutMenu);
492  mLayoutInteractor->connectToMenu(mLayoutMenu);
493 
494  this->menuBar()->addMenu(mNavigationMenu);
495  mNavigationMenu->addAction(mActions->getAction("CenterToImageCenter"));
496  mNavigationMenu->addAction(mActions->getAction("CenterToTooltip"));
497  mNavigationMenu->addAction(mActions->getAction("ShowPointPicker"));
498  mNavigationMenu->addSeparator();
499  mNavigationMenu->addActions(mInteractorStyleActionGroup->actions());
500 
501  mHelpMenuAction = this->menuBar()->addMenu(mHelpMenu);
502  mHelpMenu->addAction(mAboutAction);
503  mHelpMenu->addAction(mActions->getAction("GotoDocumentation"));
504  mHelpMenu->addAction(mShowContextSensitiveHelpAction);
505 }
506 
507 void MainWindow::createToolBars()
508 {
509  mWorkflowToolBar = this->registerToolBar("Workflow");
510  QList<QAction*> actions = mServices->state()->getWorkflowActions()->actions();
511  for (int i=0; i<actions.size(); ++i)
512  mWorkflowToolBar->addAction(actions[i]);
513 
514  mDataToolBar = this->registerToolBar("Data");
515  mDataToolBar->addAction(mActions->getAction("NewPatient"));
516  mDataToolBar->addAction(mActions->getAction("LoadFile"));
517  mDataToolBar->addAction(mActions->getAction("SaveFile"));
518  mDataToolBar->addAction(mActions->getAction("ImportData"));
519 
520  mToolToolBar = this->registerToolBar("Tools");
521  mToolToolBar->addAction(mActions->getAction("TrackingTools"));
522  mToolToolBar->addAction(mActions->getAction("StartStreaming"));
523 
524  mNavigationToolBar = this->registerToolBar("Navigation");
525  mNavigationToolBar->addAction(mActions->getAction("CenterToImageCenter"));
526  mNavigationToolBar->addAction(mActions->getAction("CenterToTooltip"));
527  mNavigationToolBar->addAction(mActions->getAction("ShowPointPicker"));
528 
529  mInteractorStyleToolBar = this->registerToolBar("InteractorStyle");
530  mInteractorStyleToolBar->addActions(mInteractorStyleActionGroup->actions());
531 
532  mDesktopToolBar = this->registerToolBar("Desktop");
533  mDesktopToolBar->addAction(mSaveDesktopAction);
534  mDesktopToolBar->addAction(mResetDesktopAction);
535 
536  mScreenshotToolBar = this->registerToolBar("Screenshot");
537  mScreenshotToolBar->addAction(mActions->getAction("ShootScreen"));
538  mScreenshotToolBar->addAction(mActions->getAction("RecordFullscreen"));
539 
540  QToolBar* camera3DViewToolBar = this->registerToolBar("Camera 3D Views");
541  camera3DViewToolBar->addActions(mStandard3DViewActions->actions());
542 
543  QToolBar* samplerWidgetToolBar = this->registerToolBar("Sampler");
544  samplerWidgetToolBar->addWidget(new SamplerWidget(mServices->tracking(), mServices->patient(), mServices->spaceProvider(), this));
545 
546  QToolBar* toolOffsetToolBar = this->registerToolBar("Tool Offset");
548  SpinBoxAndSliderGroupWidget* offsetWidget = new SpinBoxAndSliderGroupWidget(this, offset);
549  offsetWidget->showLabel(false);
550  toolOffsetToolBar->addWidget(offsetWidget);
551 
552  QToolBar* helpToolBar = this->registerToolBar("Help");
553  helpToolBar->addAction(mShowContextSensitiveHelpAction);
554 }
555 
556 QToolBar* MainWindow::registerToolBar(QString name, QString groupname)
557 {
558  QToolBar* toolbar = new QToolBar(name);
559  toolbar->setObjectName(QString(name).remove(" ")+"ToolBar");
560  mDockWidgets->registerToolBar(toolbar, groupname);
561  return toolbar;
562 }
563 
565 {
566  QString doc_path = DataLocations::getDocPath();
567  QString appName = qApp->applicationDisplayName();
568  QString url_website = DataLocations::getWebsiteURL();
569  QString url_license = QString("file://%1/License.txt").arg(doc_path);
570  QString url_config = QString("file://%1/cxConfigDescription.txt").arg(doc_path);
571 
572  QString text(""
573  "<h2>%1</h2>"
574  "<h4>%2</h4>"
575  "<p>A Research Platform for Image-Guided Therapy<p>"
576  "<p>%1 is NOT approved for medical use.<p>"
577  ""
578  "<p><a href=%3> website </a><p>"
579  "<p><a href=%4> license </a><p>"
580  "<p><a href=%5> configuration </a><p>");
581 
582  QMessageBox::about(this, tr("About %1").arg(appName), text
583  .arg(appName)
584  .arg(CustusX_VERSION_STRING)
585  .arg(url_website)
586  .arg(url_license)
587  .arg(url_config)
588  );
589 }
590 
592 {
593  PreferencesDialog prefDialog(mServices->view(), mServices->patient(), mServices->state(), mServices->tracking(), this);
594  prefDialog.exec();
595 }
596 
597 void MainWindow::closeEvent(QCloseEvent *event)
598 {
599  QMainWindow::closeEvent(event);
600  qApp->quit();
601 }
602 
603 QDockWidget* MainWindow::addAsDockWidget(QWidget* widget, QString groupname)
604 {
605  QDockWidget* dw = mDockWidgets->addAsDockWidget(widget, groupname);
606  return dw;
607 
608 }
609 
610 }//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:38
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 workflowStateAboutToChange()
void onGUIExtenderServiceAdded(GUIExtenderService *service)
void toggleFullScreenSlot()
void onGUIExtenderServiceRemoved(GUIExtenderService *service)
void preferencesSlot()
void saveDesktopSlot()
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
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
void isSaving(QDomElement &root)
xml storage is available
Widget for erasing parts of images/meshes.
Namespace for all CustusX production code.