CustusX  22.04-rc3
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, Qt::DirectConnection);
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  CX_LOG_DEBUG() << "saveDesktopSlot";
361  Desktop desktop;
362  desktop.mMainWindowState = this->saveState();
363  desktop.mLayoutUid = mServices->view()->getActiveLayout(0);
364  desktop.mSecondaryLayoutUid = mServices->view()->getActiveLayout(1);
365  mServices->state()->saveDesktop(desktop);
366 
367  // save to settings file in addition
368  settings()->setValue("mainWindow/geometry", saveGeometry());
369  settings()->setValue("mainWindow/windowState", saveState());
370  settings()->sync();
371 }
372 
374 {
375  mServices->state()->resetDesktop();
377 }
378 
380 {
381  mDockWidgets->showWidget("Help");
382 }
383 
385 {
386  this->setWindowState(this->windowState() ^ Qt::WindowFullScreen);
387 
388  settings()->setValue("gui/fullscreen", (this->windowState() & Qt::WindowFullScreen)!=0);
389 }
390 
391 void MainWindow::createActionForWidgetInSeparateWindow(QWidget* widget)
392 {
393  QString uid = widget->objectName();
394  if(mSecondaryMainWindows.find(uid) == mSecondaryMainWindows.end())
395  {
396  SecondaryMainWindow* secondaryMainWindow = new SecondaryMainWindow(this, widget);
397  QAction* action = new QAction(widget->windowTitle(), this);
398 
399  mSecondaryMainWindows[uid] = secondaryMainWindow;
400  mSecondaryMainWindowsActions[uid] = action;
401 
402  connect(action, &QAction::triggered, secondaryMainWindow, &QWidget::show);
403 
404  mFileMenu->addAction(action);
405  }
406 }
407 
409 {
410  if (!mControlPanel)
411  {
412  TrackPadWidget* trackPadWidget = new TrackPadWidget(mServices->view(), this);
413  mControlPanel = new SecondaryMainWindow(this, trackPadWidget);
414  }
415  mControlPanel->show();
416 }
417 
419 {
420  if (!mSecondaryViewLayoutWindow)
421  mSecondaryViewLayoutWindow = new SecondaryViewLayoutWindow(this);
422  mSecondaryViewLayoutWindow->tryShowOnSecondaryScreen();
423 }
424 
426 {
427  this->updateWindowTitle();
428 }
429 
430 void MainWindow::createMenus()
431 {
432 #ifdef CX_LINUX
433  // shortcuts defined on actions in the global menubar is not reachable on Qt5+Ubuntu14.04,
434  // solve by reverting to old style.
435  // This will create a double menubar: remove by autohiding menubar or using
436  // sudo apt-get autoremove appmenu-gtk appmenu-gtk3 appmenu-qt
437  // and reboot
438  this->menuBar()->setNativeMenuBar(false);
439 #endif
440  mFileMenu = new QMenu(tr("File"), this);
441  mWorkflowMenu = new QMenu(tr("Workflow"), this);
442  mToolMenu = new QMenu(tr("Tracking"), this);
443  mLayoutMenu = new QMenu(tr("Layouts"), this);
444  mNavigationMenu = new QMenu(tr("Navigation"), this);
445  mHelpMenu = new QMenu(tr("Help"), this);
446 
447  // File
448  mFileMenu->addAction(mPreferencesAction);
449  this->menuBar()->addMenu(mFileMenu);
450  mFileMenu->addAction(mActions->getAction("NewPatient"));
451  mFileMenu->addAction(mActions->getAction("SaveFile"));
452  mFileMenu->addAction(mActions->getAction("LoadFile"));
453  mFileMenu->addAction(mActions->getAction("LoadFileCopy"));
454  mFileMenu->addAction(mActions->getAction("ClearPatient"));
455  mFileMenu->addSeparator();
456  mFileMenu->addAction(mActions->getAction("ExportPatient"));
457  mFileMenu->addAction(mActions->getAction("AddFilesForImport"));
458  mFileMenu->addSeparator();
459  mFileMenu->addAction(mFullScreenAction);
460  mFileMenu->addAction(mActions->getAction("StartLogConsole"));
461  mFileMenu->addAction(mActions->getAction("ShootScreen"));
462  mFileMenu->addAction(mActions->getAction("ShootWindow"));
463  mFileMenu->addAction(mActions->getAction("RecordFullscreen"));
464  mFileMenu->addSeparator();
465  mFileMenu->addAction(mShowControlPanelAction);
466  mFileMenu->addAction(mSecondaryViewLayoutWindowAction);
467 
468  mFileMenu->addAction(mQuitAction);
469 
470  //workflow
471  this->menuBar()->addMenu(mWorkflowMenu);
472  QList<QAction*> actions = mServices->state()->getWorkflowActions()->actions();
473  for (int i=0; i<actions.size(); ++i)
474  {
475  mWorkflowMenu->addAction(actions[i]);
476  }
477 
478  mWorkflowMenu->addSeparator();
479  mWorkflowMenu->addAction(mSaveDesktopAction);
480  mWorkflowMenu->addAction(mResetDesktopAction);
481 
482  //tool
483  this->menuBar()->addMenu(mToolMenu);
484  mToolMenu->addAction(mActions->getAction("ConfigureTools"));
485  mToolMenu->addAction(mActions->getAction("InitializeTools"));
486  mToolMenu->addAction(mActions->getAction("TrackingTools"));
487  mToolMenu->addSeparator();
488  mToolMenu->addAction(mActions->getAction("StartStreaming"));
489  mToolMenu->addSeparator();
490 
491  //layout
492  this->menuBar()->addMenu(mLayoutMenu);
493  mLayoutInteractor->connectToMenu(mLayoutMenu);
494 
495  this->menuBar()->addMenu(mNavigationMenu);
496  mNavigationMenu->addAction(mActions->getAction("CenterToImageCenter"));
497  mNavigationMenu->addAction(mActions->getAction("CenterToTooltip"));
498  mNavigationMenu->addAction(mActions->getAction("ShowPointPicker"));
499  mNavigationMenu->addSeparator();
500  mNavigationMenu->addActions(mInteractorStyleActionGroup->actions());
501 
502  mHelpMenuAction = this->menuBar()->addMenu(mHelpMenu);
503  mHelpMenu->addAction(mAboutAction);
504  mHelpMenu->addAction(mActions->getAction("GotoDocumentation"));
505  mHelpMenu->addAction(mShowContextSensitiveHelpAction);
506 }
507 
508 void MainWindow::createToolBars()
509 {
510  mWorkflowToolBar = this->registerToolBar("Workflow");
511  QList<QAction*> actions = mServices->state()->getWorkflowActions()->actions();
512  for (int i=0; i<actions.size(); ++i)
513  mWorkflowToolBar->addAction(actions[i]);
514 
515  mDataToolBar = this->registerToolBar("Data");
516  mDataToolBar->addAction(mActions->getAction("NewPatient"));
517  mDataToolBar->addAction(mActions->getAction("LoadFile"));
518  mDataToolBar->addAction(mActions->getAction("SaveFile"));
519  mDataToolBar->addAction(mActions->getAction("AddFilesForImport"));
520 
521  mToolToolBar = this->registerToolBar("Tools");
522  mToolToolBar->addAction(mActions->getAction("TrackingTools"));
523  mToolToolBar->addAction(mActions->getAction("StartStreaming"));
524 
525  mNavigationToolBar = this->registerToolBar("Navigation");
526  mNavigationToolBar->addAction(mActions->getAction("CenterToImageCenter"));
527  mNavigationToolBar->addAction(mActions->getAction("CenterToTooltip"));
528  mNavigationToolBar->addAction(mActions->getAction("ShowPointPicker"));
529 
530  mInteractorStyleToolBar = this->registerToolBar("InteractorStyle");
531  mInteractorStyleToolBar->addActions(mInteractorStyleActionGroup->actions());
532 
533  mDesktopToolBar = this->registerToolBar("Desktop");
534  mDesktopToolBar->addAction(mSaveDesktopAction);
535  mDesktopToolBar->addAction(mResetDesktopAction);
536 
537  mScreenshotToolBar = this->registerToolBar("Screenshot");
538  mScreenshotToolBar->addAction(mActions->getAction("ShootScreen"));
539  mScreenshotToolBar->addAction(mActions->getAction("RecordFullscreen"));
540 
541  QToolBar* camera3DViewToolBar = this->registerToolBar("Camera 3D Views");
542  camera3DViewToolBar->addActions(mStandard3DViewActions->actions());
543 
544  QToolBar* samplerWidgetToolBar = this->registerToolBar("Sampler");
545  samplerWidgetToolBar->addWidget(new SamplerWidget(mServices->tracking(), mServices->patient(), mServices->spaceProvider(), this));
546 
547  QToolBar* toolOffsetToolBar = this->registerToolBar("Tool Offset");
549  SpinBoxAndSliderGroupWidget* offsetWidget = new SpinBoxAndSliderGroupWidget(this, offset);
550  offsetWidget->showLabel(false);
551  toolOffsetToolBar->addWidget(offsetWidget);
552 
553  QToolBar* helpToolBar = this->registerToolBar("Help");
554  helpToolBar->addAction(mShowContextSensitiveHelpAction);
555 }
556 
557 QToolBar* MainWindow::registerToolBar(QString name, QString groupname)
558 {
559  QToolBar* toolbar = new QToolBar(name);
560  toolbar->setObjectName(QString(name).remove(" ")+"ToolBar");
561  mDockWidgets->registerToolBar(toolbar, groupname);
562  return toolbar;
563 }
564 
566 {
567  QString doc_path = DataLocations::getDocPath();
568  QString appName = qApp->applicationDisplayName();
569  QString url_website = DataLocations::getWebsiteURL();
570  QString url_license = QString("file://%1/License.txt").arg(doc_path);
571  QString url_config = QString("file://%1/cxConfigDescription.txt").arg(doc_path);
572 
573  QString text(""
574  "<h2>%1</h2>"
575  "<h4>%2</h4>"
576  "<p>A Research Platform for Image-Guided Therapy<p>"
577  "<p>%1 is NOT approved for medical use.<p>"
578  ""
579  "<p><a href=%3> website </a><p>"
580  "<p><a href=%4> license </a><p>"
581  "<p><a href=%5> configuration </a><p>");
582 
583  QMessageBox::about(this, tr("About %1").arg(appName), text
584  .arg(appName)
585  .arg(CustusX_VERSION_STRING)
586  .arg(url_website)
587  .arg(url_license)
588  .arg(url_config)
589  );
590 }
591 
593 {
594  PreferencesDialog prefDialog(mServices->view(), mServices->patient(), mServices->state(), mServices->tracking(), this);
595  prefDialog.exec();
596 }
597 
598 void MainWindow::closeEvent(QCloseEvent *event)
599 {
600  QMainWindow::closeEvent(event);
601  qApp->quit();
602 }
603 
604 QDockWidget* MainWindow::addAsDockWidget(QWidget* widget, QString groupname)
605 {
606  QDockWidget* dw = mDockWidgets->addAsDockWidget(widget, groupname);
607  return dw;
608 
609 }
610 
611 }//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 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
#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.