diff --git a/.gitsubprojects b/.gitsubprojects index 3ecd0cd4d50ff989cc3dcd91fbdd51613afc878e..ed5377f133cd09801a718db2552560a8a1c4cb35 100644 --- a/.gitsubprojects +++ b/.gitsubprojects @@ -7,4 +7,4 @@ git_subproject( ReTo https://github.com/gmrvvis/ReTo.git ff4086c ) git_subproject( prefr https://github.com/gmrvvis/prefr.git 05fbf11 ) git_subproject( SimIL https://github.com/gmrvvis/SimIL.git 7a1eab6 ) git_subproject( scoop https://github.com/gmrvvis/scoop.git b3326cd ) -git_subproject( acuterecorder https://github.com/vg-lab/AcuteRecorder.git 81a1615 ) +git_subproject( acuterecorder https://github.com/vg-lab/AcuteRecorder.git 7485cd8b ) diff --git a/CMakeLists.txt b/CMakeLists.txt index 61bbf698885fee012bc005d7484348fb6dd4e791..6e64eece307c1f423317104acec862711ff6a754 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ cmake_minimum_required( VERSION 3.1 FATAL_ERROR ) # visimpl project and version -project( visimpl VERSION 1.5.3 ) +project( visimpl VERSION 1.5.4 ) set( visimpl_VERSION_ABI 6 ) SET( VISIMPL_LICENSE "GPL") diff --git a/stackviz/MainWindow.cpp b/stackviz/MainWindow.cpp index 0a77cc211db0d9b4774a123efb684d6626413e43..6d2e98e6ea288733973ce3255cf060be45b354c3 100644 --- a/stackviz/MainWindow.cpp +++ b/stackviz/MainWindow.cpp @@ -91,6 +91,13 @@ MainWindow::MainWindow( QWidget* parent_ ) { _ui->setupUi( this ); + auto recorderAction = RecorderUtils::recorderAction(); + _ui->menuTools->insertAction(_ui->menuTools->actions().first(), recorderAction); + _ui->toolBar->addAction(recorderAction); + + connect(recorderAction, SIGNAL(triggered(bool)), + this, SLOT(openRecorder())); + #ifdef VISIMPL_USE_SIMIL _ui->actionOpenBlueConfig->setEnabled( true ); #else @@ -104,9 +111,6 @@ MainWindow::MainWindow( QWidget* parent_ ) connect( _ui->actionAbout, SIGNAL( triggered( void )), this, SLOT( aboutDialog( void ))); - connect( _ui->actionRecorder , SIGNAL( triggered( void )) , this , - SLOT( openRecorder( void ))); - m_dataInspector = new DataInspector(""); m_dataInspector->hide(); } @@ -1044,15 +1048,14 @@ void stackviz::MainWindow::loadData(const simil::TDataType type, void MainWindow::openRecorder( void ) { + auto action = qobject_cast<QAction *>(sender()); // The button stops the recorder if found. if( _recorder != nullptr ) { - _ui->actionRecorder->setDisabled( true ); - _recorder->stop(); + if(action) action->setDisabled( true ); - // Recorder will be deleted after finishing. + RecorderUtils::stopAndWait(_recorder, this); _recorder = nullptr; - _ui->actionRecorder->setChecked( false ); return; } @@ -1079,16 +1082,18 @@ void MainWindow::openRecorder( void ) _recorder , SLOT( deleteLater( ))); connect( _recorder , SIGNAL( finished( )) , this , SLOT( finishRecording( ))); - _ui->actionRecorder->setChecked( true ); + if(action) action->setChecked( true ); } else { - _ui->actionRecorder->setChecked( false ); + if(action) action->setChecked( false ); } } void MainWindow::finishRecording( ) { - _ui->actionRecorder->setEnabled( true ); + auto action = _ui->menuTools->actions().first(); + action->setEnabled( true ); + action->setChecked( false ); } void stackviz::MainWindow::onLoadFinished() @@ -1215,6 +1220,29 @@ void stackviz::MainWindow::onDataUpdated() } } +void stackviz::MainWindow::closeEvent(QCloseEvent *e) +{ + if(_recorder) + { + QMessageBox msgBox(this); + msgBox.setWindowTitle(tr("Exit StackViz")); + msgBox.setWindowIcon( QIcon( ":/visimpl.png" )); + msgBox.setText(tr("A recording is being made. Do you really want to exit StackViz?")); + msgBox.setStandardButtons(QMessageBox::Cancel|QMessageBox::Yes); + + if(msgBox.exec() != QMessageBox::Yes) + { + e->ignore(); + return; + } + + RecorderUtils::stopAndWait(_recorder, this); + _recorder = nullptr; + } + + QMainWindow::closeEvent(e); +} + void stackviz::MainWindow::closeLoadingDialog() { if(m_loaderDialog) diff --git a/stackviz/MainWindow.h b/stackviz/MainWindow.h index d32333a22ff90c0aae94b53608d6d634038f17b4..56806255fbefa89c1b18cdc41d366f10c1491d8b 100644 --- a/stackviz/MainWindow.h +++ b/stackviz/MainWindow.h @@ -49,6 +49,7 @@ #include "DisplayManagerWidget.h" class Recorder; +class QCloseEvent; namespace Ui { @@ -135,6 +136,8 @@ namespace stackviz void initSummaryWidget( void ); void initPlaybackDock( void ); + virtual void closeEvent(QCloseEvent *e) override; + #ifdef VISIMPL_USE_ZEROEQ void _onSelectionEvent( lexis::data::ConstSelectedIDsPtr selected ); diff --git a/stackviz/icons/recorder.svg b/stackviz/icons/recorder.svg deleted file mode 100644 index 947269bc99779555e5d921b191df4d5d69a1b7e2..0000000000000000000000000000000000000000 --- a/stackviz/icons/recorder.svg +++ /dev/null @@ -1,76 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> - -<svg - width="123.49702mm" - height="123.49702mm" - viewBox="0 0 123.49705 123.49705" - version="1.1" - id="svg5" - inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)" - sodipodi:docname="recorder.svg" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns="http://www.w3.org/2000/svg" - xmlns:svg="http://www.w3.org/2000/svg"> - <sodipodi:namedview - id="namedview7" - pagecolor="#505050" - bordercolor="#eeeeee" - borderopacity="1" - inkscape:pageshadow="0" - inkscape:pageopacity="0" - inkscape:pagecheckerboard="0" - inkscape:document-units="mm" - showgrid="false" - fit-margin-top="15" - fit-margin-left="15" - fit-margin-right="15" - fit-margin-bottom="15" - lock-margins="false" - width="107.89702mm" - inkscape:zoom="0.74029882" - inkscape:cx="-127.65116" - inkscape:cy="226.93539" - inkscape:window-width="1920" - inkscape:window-height="1013" - inkscape:window-x="2560" - inkscape:window-y="1440" - inkscape:window-maximized="1" - inkscape:current-layer="layer1" /> - <defs - id="defs2"> - <filter - style="color-interpolation-filters:sRGB" - inkscape:label="Blur" - id="filter721" - x="-0.077007798" - y="-0.077007798" - width="1.1540156" - height="1.1540156"> - <feGaussianBlur - stdDeviation="3 3" - result="blur" - id="feGaussianBlur719" /> - </filter> - </defs> - <g - inkscape:label="Layer 1" - inkscape:groupmode="layer" - id="layer1" - transform="translate(-38.877594,-60.209427)"> - <circle - style="fill:#2b0000;fill-rule:evenodd;stroke-width:0.264583;filter:url(#filter721)" - id="circle413" - cx="106.41572" - cy="129.05154" - r="46.748512" - transform="matrix(0.80142274,0,0,0.80142274,21.131741,25.626701)" /> - <circle - style="fill:#aa0000;fill-rule:evenodd;stroke-width:0.212043" - id="path129" - cx="101.77579" - cy="123.36657" - r="37.465321" /> - </g> -</svg> diff --git a/stackviz/resources.qrc b/stackviz/resources.qrc index 6ad7fba7ad999629e3c7c442e9d595845173440b..66b2cd2e6d643fcccc1a7dd09023aa367c7632e2 100644 --- a/stackviz/resources.qrc +++ b/stackviz/resources.qrc @@ -24,6 +24,5 @@ <file>icons/generic-info.svg</file> <file>icons/fill.svg</file> <file>icons/toolconfig.svg</file> - <file>icons/recorder.svg</file> </qresource> </RCC> diff --git a/stackviz/stackviz.ui b/stackviz/stackviz.ui index 2d155724695650e00b474086685921bc47ec16ea..b16ef1c456c55b4496768de386d56c504c4e446d 100644 --- a/stackviz/stackviz.ui +++ b/stackviz/stackviz.ui @@ -56,9 +56,6 @@ <addaction name="actionFill_Plots"/> <addaction name="actionShowPanels"/> <addaction name="actionAddZeroEQhistograms"/> - <addaction name="separator"/> - <addaction name="actionRecorder"/> - <addaction name="actionAdvancedRecorderOptions"/> </widget> <widget class="QMenu" name="menuPlayback"> <property name="title"> @@ -67,9 +64,16 @@ <addaction name="actionFocusOnPlayhead"/> <addaction name="actionFollowPlayhead"/> </widget> + <widget class="QMenu" name="menuTools"> + <property name="title"> + <string>Tools</string> + </property> + <addaction name="actionAdvancedRecorderOptions"/> + </widget> <addaction name="menuFile"/> <addaction name="menuPlayback"/> <addaction name="menuOptions"/> + <addaction name="menuTools"/> <addaction name="menuHelp"/> </widget> <widget class="QStatusBar" name="statusbar"/> @@ -99,7 +103,6 @@ <addaction name="separator"/> <addaction name="actionFill_Plots"/> <addaction name="separator"/> - <addaction name="actionRecorder"/> </widget> <action name="actionQuit"> <property name="text"> @@ -299,24 +302,6 @@ <string>Shows/Hides the configuration panels.</string> </property> </action> - <action name="actionRecorder"> - <property name="checkable"> - <bool>true</bool> - </property> - <property name="icon"> - <iconset resource="resources.qrc"> - <normaloff>:/icons/recorder.svg</normaloff>:/icons/recorder.svg</iconset> - </property> - <property name="text"> - <string>Recorder</string> - </property> - <property name="toolTip"> - <string>Starts/Stops the recorder</string> - </property> - <property name="shortcut"> - <string>Ctrl+R</string> - </property> - </action> <action name="actionAdvancedRecorderOptions"> <property name="checkable"> <bool>true</bool> diff --git a/visimpl/MainWindow.cpp b/visimpl/MainWindow.cpp index e5f6232c2c03a2d729a06629eb4f15101c6b8fd5..c91646ab6f862c2196d1ba0ab86960fa93bee294 100644 --- a/visimpl/MainWindow.cpp +++ b/visimpl/MainWindow.cpp @@ -151,6 +151,13 @@ namespace visimpl { _ui->setupUi( this ); + auto recorderAction = RecorderUtils::recorderAction(); + _ui->menuTools->insertAction(_ui->menuTools->actions().first(), recorderAction); + _ui->toolBar->addAction(recorderAction); + + connect(recorderAction, SIGNAL(triggered(bool)), + this, SLOT(openRecorder())); + _ui->actionUpdateOnIdle->setChecked( updateOnIdle ); _ui->actionShowFPSOnIdleUpdate->setChecked( false ); @@ -229,9 +236,6 @@ namespace visimpl connect( _ui->actionHome , SIGNAL( triggered( void )) , _openGLWidget , SLOT( home( void )) ); - connect( _ui->actionRecorder , SIGNAL( triggered( void )) , this , - SLOT( openRecorder( void ))); - connect( _openGLWidget , SIGNAL( stepCompleted( void )) , this , SLOT( completedStep( void ))); @@ -500,15 +504,17 @@ namespace visimpl void MainWindow::openRecorder( void ) { + auto action = qobject_cast<QAction *>(sender()); + // The button stops the recorder if found. if( _recorder != nullptr ) { - _ui->actionRecorder->setDisabled( true ); - _recorder->stop(); + if(action) action->setDisabled( true ); + + RecorderUtils::stopAndWait(_recorder, this); // Recorder will be deleted after finishing. _recorder = nullptr; - _ui->actionRecorder->setChecked( false ); return; } @@ -538,10 +544,10 @@ namespace visimpl this , SLOT( finishRecording( ))); connect( _openGLWidget , SIGNAL( frameSwapped( )) , _recorder , SLOT( takeFrame( ))); - _ui->actionRecorder->setChecked( true ); + if(action) action->setChecked( true ); } else { - _ui->actionRecorder->setChecked( false ); + if(action) action->setChecked( false ); } } @@ -2668,7 +2674,32 @@ void MainWindow::clearGroups( void ) void MainWindow::finishRecording( ) { - _ui->actionRecorder->setEnabled( true ); + auto recorderAction = _ui->menuTools->actions().first(); + recorderAction->setEnabled( true ); + recorderAction->setChecked( false ); + } + + void MainWindow::closeEvent(QCloseEvent *e) + { + if(_recorder) + { + QMessageBox msgBox(this); + msgBox.setWindowTitle(tr("Exit SimPart")); + msgBox.setWindowIcon( QIcon( ":/visimpl.png" )); + msgBox.setText(tr("A recording is being made. Do you really want to exit SimPart?")); + msgBox.setStandardButtons(QMessageBox::Cancel|QMessageBox::Yes); + + if(msgBox.exec() != QMessageBox::Yes) + { + e->ignore(); + return; + } + + RecorderUtils::stopAndWait(_recorder, this); + _recorder = nullptr; + } + + QMainWindow::closeEvent(e); } void MainWindow::sendZeroEQPlaybackOperation(const unsigned int op) diff --git a/visimpl/MainWindow.h b/visimpl/MainWindow.h index c45e3a6c804560d35411397229beac26267600ff..943f092c905ee425144b0c0373f591cb4df79c85 100644 --- a/visimpl/MainWindow.h +++ b/visimpl/MainWindow.h @@ -49,6 +49,7 @@ class QRadioButton; class QGroupBox; class QPushButton; class QToolBox; +class QCloseEvent; namespace Ui { @@ -254,6 +255,8 @@ namespace visimpl */ void updateGroupColors(size_t idx, const TTransferFunction &t, const TSizeFunction &s); + virtual void closeEvent(QCloseEvent *e) override; + #ifdef VISIMPL_USE_ZEROEQ #ifdef VISIMPL_USE_GMRVLEX diff --git a/visimpl/icons/recorder.svg b/visimpl/icons/recorder.svg deleted file mode 100644 index 947269bc99779555e5d921b191df4d5d69a1b7e2..0000000000000000000000000000000000000000 --- a/visimpl/icons/recorder.svg +++ /dev/null @@ -1,76 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> - -<svg - width="123.49702mm" - height="123.49702mm" - viewBox="0 0 123.49705 123.49705" - version="1.1" - id="svg5" - inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)" - sodipodi:docname="recorder.svg" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns="http://www.w3.org/2000/svg" - xmlns:svg="http://www.w3.org/2000/svg"> - <sodipodi:namedview - id="namedview7" - pagecolor="#505050" - bordercolor="#eeeeee" - borderopacity="1" - inkscape:pageshadow="0" - inkscape:pageopacity="0" - inkscape:pagecheckerboard="0" - inkscape:document-units="mm" - showgrid="false" - fit-margin-top="15" - fit-margin-left="15" - fit-margin-right="15" - fit-margin-bottom="15" - lock-margins="false" - width="107.89702mm" - inkscape:zoom="0.74029882" - inkscape:cx="-127.65116" - inkscape:cy="226.93539" - inkscape:window-width="1920" - inkscape:window-height="1013" - inkscape:window-x="2560" - inkscape:window-y="1440" - inkscape:window-maximized="1" - inkscape:current-layer="layer1" /> - <defs - id="defs2"> - <filter - style="color-interpolation-filters:sRGB" - inkscape:label="Blur" - id="filter721" - x="-0.077007798" - y="-0.077007798" - width="1.1540156" - height="1.1540156"> - <feGaussianBlur - stdDeviation="3 3" - result="blur" - id="feGaussianBlur719" /> - </filter> - </defs> - <g - inkscape:label="Layer 1" - inkscape:groupmode="layer" - id="layer1" - transform="translate(-38.877594,-60.209427)"> - <circle - style="fill:#2b0000;fill-rule:evenodd;stroke-width:0.264583;filter:url(#filter721)" - id="circle413" - cx="106.41572" - cy="129.05154" - r="46.748512" - transform="matrix(0.80142274,0,0,0.80142274,21.131741,25.626701)" /> - <circle - style="fill:#aa0000;fill-rule:evenodd;stroke-width:0.212043" - id="path129" - cx="101.77579" - cy="123.36657" - r="37.465321" /> - </g> -</svg> diff --git a/visimpl/resources.qrc b/visimpl/resources.qrc index 950eb7a705119479dd75028f4258d9b925713415..c0abd46f34241dacf0323ffbf4d37e9fda2c343e 100644 --- a/visimpl/resources.qrc +++ b/visimpl/resources.qrc @@ -26,7 +26,6 @@ <file>icons/generic-info.svg</file> <file>icons/trash.svg</file> <file>icons/stackviz.svg</file> - <file>icons/recorder.svg</file> <file>icons/toolconfig.svg</file> <file>icons/left.svg</file> <file>icons/right.svg</file> diff --git a/visimpl/visimpl.ui b/visimpl/visimpl.ui index 7a412dd92632b6de66c91f5dbe2f82f70fb25ce9..b05131aa5e511e4109161c767a4b711f8feade13 100644 --- a/visimpl/visimpl.ui +++ b/visimpl/visimpl.ui @@ -65,10 +65,6 @@ <addaction name="separator"/> <addaction name="actionUpdateOnIdle"/> <addaction name="actionShowFPSOnIdleUpdate"/> - <addaction name="separator"/> - <addaction name="actionRecorder"/> - <addaction name="actionAdvancedRecorderOptions"/> - <addaction name="separator"/> </widget> <widget class="QMenu" name="stackVizOptions"> <property name="title"> @@ -81,9 +77,16 @@ <addaction name="actionStackVizFollowPlayHead"/> <addaction name="actionStackVizShowPanels"/> </widget> + <widget class="QMenu" name="menuTools"> + <property name="title"> + <string>Tools</string> + </property> + <addaction name="actionAdvancedRecorderOptions"/> + </widget> <addaction name="menuFile"/> <addaction name="menuOptions"/> <addaction name="stackVizOptions"/> + <addaction name="menuTools"/> <addaction name="menuHelp"/> </widget> <widget class="QStatusBar" name="statusbar"/> @@ -126,7 +129,6 @@ <addaction name="actionToggleSimConfigDock"/> <addaction name="separator"/> <addaction name="actionShowInactive"/> - <addaction name="actionRecorder"/> </widget> <action name="actionQuit"> <property name="text"> @@ -167,21 +169,6 @@ <string>Ctrl+B</string> </property> </action> - <action name="actionRecorder"> - <property name="checkable"> - <bool>true</bool> - </property> - <property name="icon"> - <iconset resource="resources.qrc"> - <normaloff>:/icons/recorder.svg</normaloff>:/icons/recorder.svg</iconset> - </property> - <property name="text"> - <string>Recorder</string> - </property> - <property name="shortcut"> - <string>Ctrl+R</string> - </property> - </action> <action name="actionOpenBlueConfig"> <property name="icon"> <iconset resource="resources.qrc">