diff --git a/src/recorder/jamrecorder.cpp b/src/recorder/jamrecorder.cpp index 0fe05134..d8dc9833 100755 --- a/src/recorder/jamrecorder.cpp +++ b/src/recorder/jamrecorder.cpp @@ -302,7 +302,7 @@ QMap> CJamSession::TracksFromSessionDir(const QString * @brief CJamRecorder::Init Create recording directory, if necessary, and connect signal handlers * @param server Server object emiting signals */ -void CJamRecorder::Init( const CServer* server, +bool CJamRecorder::Init( const CServer* server, const int _iServerFrameSizeSamples ) { QFileInfo fi(recordBaseDir.absolutePath()); @@ -310,21 +310,28 @@ void CJamRecorder::Init( const CServer* server, if (!fi.exists() && !QDir().mkpath(recordBaseDir.absolutePath())) { - throw std::runtime_error( (recordBaseDir.absolutePath() + " does not exist but could not be created").toStdString() ); + qCritical() << recordBaseDir.absolutePath() << "does not exist but could not be created"; + return false; } if (!fi.isDir()) { - throw std::runtime_error( (recordBaseDir.absolutePath() + " exists but is not a directory").toStdString() ); + qCritical() << recordBaseDir.absolutePath() << "exists but is not a directory"; + return false; } if (!fi.isWritable()) { - throw std::runtime_error( (recordBaseDir.absolutePath() + " is a directory but cannot be written to").toStdString() ); + qCritical() << recordBaseDir.absolutePath() << "is a directory but cannot be written to"; + return false; } QObject::connect( (const QObject *)server, SIGNAL ( RestartRecorder() ), this, SLOT( OnTriggerSession() ), Qt::ConnectionType::QueuedConnection ); + QObject::connect( (const QObject *)server, SIGNAL ( StopRecorder() ), + this, SLOT( OnEnd() ), + Qt::ConnectionType::QueuedConnection ); + QObject::connect( (const QObject *)server, SIGNAL ( Stopped() ), this, SLOT( OnEnd() ), Qt::ConnectionType::QueuedConnection ); @@ -346,6 +353,8 @@ void CJamRecorder::Init( const CServer* server, thisThread = new QThread(); moveToThread ( thisThread ); thisThread->start(); + + return true; } /** @@ -363,15 +372,10 @@ void CJamRecorder::Start() { /** - * @brief CJamRecorder::OnEnd Finalise the recording and emit the Reaper RPP file - * - * Emits RecordingSessionEnded with the Reaper project file name, - * or null if was not recording or a problem occurs + * @brief CJamRecorder::OnEnd Finalise the recording and write the Reaper RPP file */ void CJamRecorder::OnEnd() { - QString reaperProjectFileName = QString::Null(); - if ( isRecording ) { isRecording = false; diff --git a/src/recorder/jamrecorder.h b/src/recorder/jamrecorder.h index 3713162a..0dec305f 100755 --- a/src/recorder/jamrecorder.h +++ b/src/recorder/jamrecorder.h @@ -148,7 +148,7 @@ public: * @brief Create recording directory, if necessary, and connect signal handlers * @param server Server object emiting signals */ - void Init( const CServer* server, const int _iServerFrameSizeSamples ); + bool Init( const CServer* server, const int _iServerFrameSizeSamples ); /** * @brief SessionDirToReaper Method that allows an RPP file to be recreated diff --git a/src/server.cpp b/src/server.cpp index 11ad954f..dbd423cf 100755 --- a/src/server.cpp +++ b/src/server.cpp @@ -239,7 +239,6 @@ CServer::CServer ( const int iNewMaxNumChan, Socket ( this, iPortNumber ), Logging ( iMaxDaysHistory ), JamRecorder ( strRecordingDirName ), - bEnableRecording ( !strRecordingDirName.isEmpty() ), bWriteStatusHTMLFile ( false ), HighPrecisionTimer ( bNUseDoubleSystemFrameSize ), ServerListManager ( iPortNumber, @@ -402,9 +401,10 @@ CServer::CServer ( const int iNewMaxNumChan, } // Enable jam recording (if requested) - kicks off the thread - if ( bEnableRecording ) + if ( !strRecordingDirName.isEmpty() ) { - JamRecorder.Init ( this, iServerFrameSizeSamples ); + bRecorderInitialised = JamRecorder.Init ( this, iServerFrameSizeSamples ); + bEnableRecording = bRecorderInitialised; } // enable all channels (for the server all channel must be enabled the @@ -691,6 +691,10 @@ void CServer::OnHandledSignal ( int sigNum ) RequestNewRecording(); break; + case SIGUSR2: + SetEnableRecording ( !bEnableRecording ); + break; + case SIGINT: case SIGTERM: // This should trigger OnAboutToQuit @@ -705,12 +709,28 @@ void CServer::OnHandledSignal ( int sigNum ) void CServer::RequestNewRecording() { - if ( bEnableRecording ) + if ( bRecorderInitialised && bEnableRecording ) { emit RestartRecorder(); } } +void CServer::SetEnableRecording ( bool bNewEnableRecording ) +{ + if ( bRecorderInitialised ) { + bEnableRecording = bNewEnableRecording; + if ( !bEnableRecording ) + { + emit StopRecorder(); + } + else if ( !IsRunning() ) + { + // This dirty hack is for the GUI. It doesn't care. + emit StopRecorder(); + } + } +} + void CServer::Start() { // only start if not already running diff --git a/src/server.h b/src/server.h index 8c401304..f41fd04d 100755 --- a/src/server.h +++ b/src/server.h @@ -197,7 +197,10 @@ public: CVector& veciJitBufNumFrames, CVector& veciNetwFrameSizeFact ); + bool GetRecorderInitialised() { return bRecorderInitialised; } bool GetRecordingEnabled() { return bEnableRecording; } + void RequestNewRecording(); + void SetEnableRecording ( bool bNewEnableRecording ); // Server list management -------------------------------------------------- void UpdateServerList() { ServerListManager.Update(); } @@ -300,8 +303,6 @@ protected: const CVector > vecvecsData, CVector& vecLevelsOut ); - void RequestNewRecording(); - // do not use the vector class since CChannel does not have appropriate // copy constructor/operator CChannel vecChannels[MAX_NUM_CHANNELS]; @@ -350,6 +351,7 @@ protected: // recording thread recorder::CJamRecorder JamRecorder; + bool bRecorderInitialised; bool bEnableRecording; // HTML file server status @@ -383,6 +385,7 @@ signals: const int iNumAudChan, const CVector vecsData ); void RestartRecorder(); + void StopRecorder(); void RecordingSessionStarted ( QString sessionDir ); public slots: diff --git a/src/serverdlg.cpp b/src/serverdlg.cpp index ca875306..a01739c9 100755 --- a/src/serverdlg.cpp +++ b/src/serverdlg.cpp @@ -121,6 +121,28 @@ CServerDlg::CServerDlg ( CServer* pNServP, cbxLocationCountry->setAccessibleName ( tr ( "Country where the server is located combo box" ) ); + // enable recorder + chbEnableRecorder->setAccessibleName( tr ( "Checkbox to turn on or off server recording" ) ); + chbEnableRecorder->setWhatsThis( "" + tr ( "Enable Recorder" ) + ":" + + tr ( "Checked when the recorder is enabled, otherwise unchecked. " + "The recorder will run when a session is in progress, if (set up correctly and) enabled.") ); + + // current session directory + edtCurrentSessionDir->setAccessibleName( tr ( "Current session directory text box (read-only)" ) ); + edtCurrentSessionDir->setWhatsThis( "" + tr ( "Current Session Directory" ) + ":" + + tr ( "Enabled during recording and holds the current recording session directory. " + "Disabled after recording or when the recorder is not enabled.") ); + + // recorder status + lblRecorderStatus->setAccessibleName ( tr ( "Recorder status label" ) ); + lblRecorderStatus->setWhatsThis ( "" + tr ( "Recorder Status" ) + ":" + + tr ( "Displays the current status of the recorder." ) ); + + // new recording + pbtNewRecording->setAccessibleName ( tr ( "Request new recording button" ) ); + pbtNewRecording->setWhatsThis ( "" + tr ( "New Recording" ) + ":" + + tr ( "During a recording session, the button can be used to start a new recording." ) ); + // check if system tray icon can be used bSystemTrayIconAvaialbe = SystemTrayIcon.isSystemTrayAvailable(); @@ -268,21 +290,25 @@ lvwClients->setMinimumHeight ( 140 ); #endif // Recorder controls - pbtNewRecording->setAutoDefault ( false ); - - if ( !pServer->GetRecordingEnabled() ) + if ( !pServer->GetRecorderInitialised() ) { - // The recorder was not enabled from the command line - // TODO: Once enabling from the GUI is implemented, remove + // The recorder was not initialised successfully from the command line + // TODO: Once initialising from the GUI is implemented, remove + chbEnableRecorder->setVisible ( false ); + edtCurrentSessionDir->setVisible ( false ); lblRecorderStatus->setVisible ( false ); pbtNewRecording->setVisible ( false ); } + edtCurrentSessionDir->setText ( "" ); + pbtNewRecording->setAutoDefault ( false ); + // TODO: Not yet implemented, so hide them! - chbEnableRecorder->setVisible ( false ); pbtRecordingDir->setVisible ( false ); edtRecordingsDir->setVisible ( false ); + UpdateRecorderStatus ( QString::null ); + // update GUI dependencies UpdateGUIDependencies(); @@ -318,6 +344,9 @@ lvwClients->setMinimumHeight ( 140 ); QObject::connect ( chbUseCCLicence, SIGNAL ( stateChanged ( int ) ), this, SLOT ( OnUseCCLicenceStateChanged ( int ) ) ); + QObject::connect ( chbEnableRecorder, SIGNAL ( stateChanged ( int ) ), + this, SLOT ( OnEnableRecorderStateChanged ( int ) ) ); + // line edits QObject::connect ( edtCentralServerAddress, SIGNAL ( editingFinished() ), this, SLOT ( OnCentralServerAddressEditingFinished() ) ); @@ -355,6 +384,9 @@ lvwClients->setMinimumHeight ( 140 ); QObject::connect ( pServer, SIGNAL ( RecordingSessionStarted ( QString ) ), this, SLOT ( OnRecordingSessionStarted ( QString ) ) ); + QObject::connect ( pServer, SIGNAL ( StopRecorder() ), + this, SLOT ( OnStopRecorder() ) ); + QObject::connect ( QCoreApplication::instance(), SIGNAL ( aboutToQuit() ), this, SLOT ( OnAboutToQuit() ) ); @@ -474,12 +506,23 @@ void CServerDlg::OnCentServAddrTypeActivated ( int iTypeIdx ) UpdateGUIDependencies(); } +void CServerDlg::OnServerStarted() +{ + UpdateSystemTrayIcon ( true ); + UpdateRecorderStatus ( QString::null ); +} + void CServerDlg::OnServerStopped() { UpdateSystemTrayIcon ( false ); UpdateRecorderStatus ( QString::null ); } +void CServerDlg::OnStopRecorder() +{ + UpdateRecorderStatus ( QString::null ); +} + void CServerDlg::OnSysTrayActivated ( QSystemTrayIcon::ActivationReason ActReason ) { // on double click on the icon, show window in fore ground @@ -589,9 +632,6 @@ void CServerDlg::UpdateGUIDependencies() } lblRegSvrStatus->setText ( strStatus ); - - edtCurrentSessionDir->setText ( "" ); - UpdateRecorderStatus ( QString::null ); } void CServerDlg::UpdateSystemTrayIcon ( const bool bIsActive ) @@ -652,12 +692,20 @@ void CServerDlg::ModifyAutoStartEntry ( const bool bDoAutoStart ) void CServerDlg::UpdateRecorderStatus ( QString sessionDir ) { + if ( !pServer->GetRecorderInitialised() ) + { + // everything should be hidden. + return; + } + + Qt::CheckState csIsEnabled; QString currentSessionDir = edtCurrentSessionDir->text(); bool bIsRecording = false; QString strRecorderStatus; if ( pServer->GetRecordingEnabled() ) { + csIsEnabled = Qt::CheckState::Checked; if ( pServer->IsRunning() ) { currentSessionDir = sessionDir != QString::null ? sessionDir : ""; @@ -671,10 +719,12 @@ void CServerDlg::UpdateRecorderStatus ( QString sessionDir ) } else { + csIsEnabled = Qt::CheckState::Unchecked; strRecorderStatus = tr ( "Not enabled" ); } - edtCurrentSessionDir->setVisible ( pServer->GetRecordingEnabled() ); + chbEnableRecorder->setCheckState ( csIsEnabled ); + edtCurrentSessionDir->setEnabled ( bIsRecording ); edtCurrentSessionDir->setText ( currentSessionDir ); diff --git a/src/serverdlg.h b/src/serverdlg.h index 8227032a..a2e7bb3b 100755 --- a/src/serverdlg.h +++ b/src/serverdlg.h @@ -86,15 +86,19 @@ public slots: void OnRegisterServerStateChanged ( int value ); void OnStartOnOSStartStateChanged ( int value ); void OnUseCCLicenceStateChanged ( int value ); + void OnEnableRecorderStateChanged ( int value ) + { pServer->SetEnableRecording ( Qt::CheckState::Checked == value ); } + void OnCentralServerAddressEditingFinished(); void OnServerNameTextChanged ( const QString& strNewName ); void OnLocationCityTextChanged ( const QString& strNewCity ); void OnLocationCountryActivated ( int iCntryListItem ); void OnCentServAddrTypeActivated ( int iTypeIdx ); void OnTimer(); - void OnServerStarted() { UpdateSystemTrayIcon ( true ); } + void OnServerStarted(); void OnServerStopped(); void OnSvrRegStatusChanged() { UpdateGUIDependencies(); } + void OnStopRecorder(); void OnSysTrayMenuOpen() { ShowWindowInForeground(); } void OnSysTrayMenuHide() { hide(); } void OnSysTrayMenuExit() { close(); } @@ -103,7 +107,7 @@ public slots: void keyPressEvent ( QKeyEvent *e ) // block escape key { if ( e->key() != Qt::Key_Escape ) QDialog::keyPressEvent ( e ); } - void OnNewRecordingClicked() { pServer->RestartRecorder(); } + void OnNewRecordingClicked() { pServer->RequestNewRecording(); } void OnRecordingSessionStarted ( QString sessionDir ) { UpdateRecorderStatus ( sessionDir ); } }; diff --git a/src/serverdlgbase.ui b/src/serverdlgbase.ui index 6e55a0ed..e00bb4db 100755 --- a/src/serverdlgbase.ui +++ b/src/serverdlgbase.ui @@ -167,22 +167,6 @@ - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 20 - 20 - - - - diff --git a/src/signalhandler.cpp b/src/signalhandler.cpp index d0205c9e..58587c60 100755 --- a/src/signalhandler.cpp +++ b/src/signalhandler.cpp @@ -146,6 +146,7 @@ CSignalUnix::CSignalUnix ( CSignalHandler* nPSignalHandler ) : socketNotifier->setEnabled ( true ); setSignalHandled ( SIGUSR1, true ); + setSignalHandled ( SIGUSR2, true ); setSignalHandled ( SIGINT, true ); setSignalHandled ( SIGTERM, true ); } @@ -153,6 +154,7 @@ CSignalUnix::CSignalUnix ( CSignalHandler* nPSignalHandler ) : CSignalUnix::~CSignalUnix() { setSignalHandled ( SIGUSR1, false ); + setSignalHandled ( SIGUSR2, false ); setSignalHandled ( SIGINT, false ); setSignalHandled ( SIGTERM, false ); }