diff --git a/.gitignore b/.gitignore index 22de5eeaf1..b56af9cd0d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,18 +2,27 @@ Jamulus Jamulus.ini Makefile -*.pro.user* **.cppe **.he .cproject .project .settings .idea +.xcode .vscode +.vs .cache +.DS_Store *.user *.user.* +*.pro.user* *.o +*.sln +*.vcxproj +*.vcxproj.filters +*.xcodeproj +*.log +Jamulus*.ps1 moc_*.cpp ui_*.h moc_predefs.h @@ -30,20 +39,14 @@ build/ deploy/ build-gui/ build-nox/ -jamulus.sln -jamulus.vcxproj -jamulus.vcxproj.filters Jamulus.app/ -.DS_Store distributions/opus* distributions/jack2 distributions/claudio_piano.sf2 distributions/fluidsynth* distributions/jamulus.desktop distributions/jamulus-server.desktop -.xcode Debug-iphoneos/ -Jamulus.xcodeproj jamulus_plugin_import.cpp autoLatestChangelog.md debian/ diff --git a/src/channel.cpp b/src/channel.cpp index a35576a34d..9cd4f57a1e 100644 --- a/src/channel.cpp +++ b/src/channel.cpp @@ -37,6 +37,7 @@ CChannel::CChannel ( const bool bNIsServer ) : bIsEnabled ( false ), bIsServer ( bNIsServer ), bIsIdentified ( false ), + bDisconnectAndDisable ( false ), iAudioFrameSizeSamples ( DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES ), SignalLevelMeter ( false, 0.5 ) // server mode with mono out and faster smoothing { @@ -125,7 +126,8 @@ void CChannel::SetEnable ( const bool bNEnStat ) QMutexLocker locker ( &Mutex ); // set internal parameter - bIsEnabled = bNEnStat; + bIsEnabled = bNEnStat; + bDisconnectAndDisable = false; // The support for the packet sequence number must be reset if the client // disconnects from a server since we do not yet know if the next server we @@ -506,11 +508,20 @@ void CChannel::Disconnect() // we only have to disconnect the channel if it is actually connected if ( IsConnected() ) { + // for a Client we will block further audio data and disable the channel as soon as disconnected; + bDisconnectAndDisable = !bIsServer; + // set time out counter to a small value > 0 so that the next time a // received audio block is queried, the disconnection is performed // (assuming that no audio packet is received in the meantime) iConTimeOut = 1; // a small number > 0 } + else if ( !bIsServer ) + { + bDisconnectAndDisable = false; + bIsEnabled = false; + iConTimeOut = 0; + } } void CChannel::PutProtocolData ( const int iRecCounter, const int iRecID, const CVector& vecbyMesBodyData, const CHostAddress& RecHostAddr ) @@ -534,7 +545,7 @@ EPutDataStat CChannel::PutAudioData ( const CVector& vecbyData, const i // Only process audio data if: // - for client only: the packet comes from the server we want to talk to // - the channel is enabled - if ( ( bIsServer || ( GetAddress() == RecHostAddr ) ) && IsEnabled() ) + if ( ( bIsServer || ( GetAddress() == RecHostAddr ) ) && IsEnabled() && !bDisconnectAndDisable ) { MutexSocketBuf.lock(); { @@ -622,6 +633,12 @@ EGetDataStat CChannel::GetData ( CVector& vecbyData, const int iNumByte eGetStatus = GS_CHAN_NOW_DISCONNECTED; iConTimeOut = 0; // make sure we do not have negative values + if ( bDisconnectAndDisable ) + { + bDisconnectAndDisable = false; + bIsEnabled = false; + } + // reset network transport properties ResetNetworkTransportProperties(); } @@ -643,6 +660,13 @@ EGetDataStat CChannel::GetData ( CVector& vecbyData, const int iNumByte { // channel is disconnected eGetStatus = GS_CHAN_NOT_CONNECTED; + + if ( bDisconnectAndDisable ) + { + bDisconnectAndDisable = false; + bIsEnabled = false; + iConTimeOut = 0; + } } } MutexSocketBuf.unlock(); @@ -652,7 +676,6 @@ EGetDataStat CChannel::GetData ( CVector& vecbyData, const int iNumByte { // reset the protocol Protocol.Reset(); - // emit message emit Disconnected(); } diff --git a/src/channel.h b/src/channel.h index 86791494b3..32463bfe1d 100644 --- a/src/channel.h +++ b/src/channel.h @@ -76,7 +76,7 @@ class CChannel : public QObject void PrepAndSendPacket ( CHighPrioSocket* pSocket, const CVector& vecbyNPacket, const int iNPacketLen ); - void ResetTimeOutCounter() { iConTimeOut = iConTimeOutStartVal; } + void ResetTimeOutCounter() { iConTimeOut = bDisconnectAndDisable ? 1 : iConTimeOutStartVal; } bool IsConnected() const { return iConTimeOut > 0; } void Disconnect(); @@ -216,6 +216,7 @@ void CreateReqChannelLevelListMes() { Protocol.CreateReqChannelLevelListMes(); } bool bIsEnabled; bool bIsServer; bool bIsIdentified; + bool bDisconnectAndDisable; int iNetwFrameSizeFact; int iNetwFrameSize; diff --git a/src/chatdlg.cpp b/src/chatdlg.cpp index 9e275633ea..8d8c7c3efa 100644 --- a/src/chatdlg.cpp +++ b/src/chatdlg.cpp @@ -140,8 +140,8 @@ void CChatDlg::OnAnchorClicked ( const QUrl& Url ) // only allow http(s) URLs to be opened in an external browser if ( Url.scheme() == QLatin1String ( "https" ) || Url.scheme() == QLatin1String ( "http" ) ) { - if ( QMessageBox::question ( this, - APP_NAME, + if ( QMessageBox::question ( CMsgBoxes::MainForm(), + CMsgBoxes::MainFormName(), tr ( "Do you want to open the link '%1' in your browser?" ).arg ( "" + Url.toString() + "" ), QMessageBox::Yes | QMessageBox::No ) == QMessageBox::Yes ) { diff --git a/src/client.cpp b/src/client.cpp index a1b34a8eeb..37a6000d73 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -27,7 +27,6 @@ /* Implementation *************************************************************/ CClient::CClient ( const quint16 iPortNumber, const quint16 iQosNumber, - const QString& strConnOnStartupAddress, const QString& strMIDISetup, const bool bNoAutoJackConnect, const QString& strNClientName, @@ -181,13 +180,6 @@ CClient::CClient ( const quint16 iPortNumber, // start the socket (it is important to start the socket after all // initializations and connections) Socket.Start(); - - // do an immediate start if a server address is given - if ( !strConnOnStartupAddress.isEmpty() ) - { - SetServerAddr ( strConnOnStartupAddress ); - Start(); - } } CClient::~CClient() @@ -298,7 +290,7 @@ void CClient::CreateServerJitterBufferMessage() void CClient::OnCLPingReceived ( CHostAddress InetAddr, int iMs ) { // make sure we are running and the server address is correct - if ( IsRunning() && ( InetAddr == Channel.GetAddress() ) ) + if ( Channel.IsEnabled() && ( InetAddr == Channel.GetAddress() ) ) { // take care of wrap arounds (if wrapping, do not use result) const int iCurDiff = EvaluatePingMessage ( iMs ); @@ -435,22 +427,6 @@ void CClient::StartDelayTimer() } } -bool CClient::SetServerAddr ( QString strNAddr ) -{ - CHostAddress HostAddress; - if ( NetworkUtil().ParseNetworkAddress ( strNAddr, HostAddress, bEnableIPv6 ) ) - { - // apply address to the channel - Channel.SetAddress ( HostAddress ); - - return true; - } - else - { - return false; // invalid address - } -} - bool CClient::GetAndResetbJitterBufferOKFlag() { // get the socket buffer put status flag and reset it @@ -586,9 +562,12 @@ QString CClient::SetSndCrdDev ( const QString strNewDev ) // in case of an error inform the GUI about it if ( !strError.isEmpty() ) { - emit SoundDeviceChanged ( strError ); + QMessageBox::critical ( 0, APP_NAME, strError ); + Disconnect(); } + emit SoundDeviceChanged(); + return strError; } @@ -715,8 +694,13 @@ void CClient::OnSndCrdReinitRequest ( int iSndCrdResetType ) } MutexDriverReinit.unlock(); + if ( !strError.isEmpty() ) + { + QMessageBox::critical ( 0, APP_NAME, strError ); + } + // inform GUI about the sound card device change - emit SoundDeviceChanged ( strError ); + emit SoundDeviceChanged(); } void CClient::OnHandledSignal ( int sigNum ) @@ -731,10 +715,7 @@ void CClient::OnHandledSignal ( int sigNum ) case SIGINT: case SIGTERM: // if connected, terminate connection (needed for headless mode) - if ( IsRunning() ) - { - Stop(); - } + Disconnect(); // this should trigger OnAboutToQuit QCoreApplication::instance()->exit(); @@ -819,50 +800,89 @@ void CClient::OnClientIDReceived ( int iChanID ) emit ClientIDReceived ( iChanID ); } -void CClient::Start() +bool CClient::Connect ( QString strServerAddress, QString strServerName ) { - // init object - Init(); + if ( !Channel.IsEnabled() ) + { + CHostAddress HostAddress; + + if ( NetworkUtil().ParseNetworkAddress ( strServerAddress, HostAddress, bEnableIPv6 ) ) + { + // init object + Init(); + + // apply address to the channel + Channel.SetAddress ( HostAddress ); - // enable channel - Channel.SetEnable ( true ); + // enable channel + Channel.SetEnable ( true ); - // start audio interface - Sound.Start(); + // start audio interface + Sound.Start(); + + // Notify ClientDlg + emit Connecting ( strServerName ); + + return true; + } + } + + return false; } -void CClient::Stop() +bool CClient::Disconnect() { - // stop audio interface - Sound.Stop(); - - // disable channel - Channel.SetEnable ( false ); - - // wait for approx. 100 ms to make sure no audio packet is still in the - // network queue causing the channel to be reconnected right after having - // received the disconnect message (seems not to gain much, disconnect is - // still not working reliably) - QTime DieTime = QTime::currentTime().addMSecs ( 100 ); - while ( QTime::currentTime() < DieTime ) + if ( Channel.IsEnabled() ) { - // exclude user input events because if we use AllEvents, it happens - // that if the user initiates a connection and disconnection quickly - // (e.g. quickly pressing enter five times), the software can get into - // an unknown state - QCoreApplication::processEvents ( QEventLoop::ExcludeUserInputEvents, 100 ); + // start disconnection + Channel.Disconnect(); + + // Channel.Disconnect() should now automatically disable Channel as soon as disconnected. + // Note that this only works if Sound is Active ! + + QTime DieTime = QTime::currentTime().addMSecs ( 500 ); + while ( ( QTime::currentTime() < DieTime ) && Channel.IsEnabled() ) + { + // exclude user input events because if we use AllEvents, it happens + // that if the user initiates a connection and disconnection quickly + // (e.g. quickly pressing enter five times), the software can get into + // an unknown state + QCoreApplication::processEvents ( QEventLoop::ExcludeUserInputEvents, 100 ); + } + + // Now stop the audio interface + Sound.Stop(); + + // in case we timed out, log warning and make sure Channel is disabled + if ( Channel.IsEnabled() ) + { + Channel.SetEnable ( false ); + } + + // Send disconnect message to server (Since we disable our protocol + // receive mechanism with the next command, we do not evaluate any + // respond from the server, therefore we just hope that the message + // gets its way to the server, if not, the old behaviour time-out + // disconnects the connection anyway). + ConnLessProtocol.CreateCLDisconnection ( Channel.GetAddress() ); + + // reset current signal level and LEDs + bJitterBufferOK = true; + SignalLevelMeter.Reset(); + + emit Disconnected(); + + return true; } + else + { + // make sure sound is stopped too + Sound.Stop(); - // Send disconnect message to server (Since we disable our protocol - // receive mechanism with the next command, we do not evaluate any - // respond from the server, therefore we just hope that the message - // gets its way to the server, if not, the old behaviour time-out - // disconnects the connection anyway). - ConnLessProtocol.CreateCLDisconnection ( Channel.GetAddress() ); + emit Disconnected(); - // reset current signal level and LEDs - bJitterBufferOK = true; - SignalLevelMeter.Reset(); + return false; + } } void CClient::Init() diff --git a/src/client.h b/src/client.h index cdb21f6e6e..d2b750c0e6 100644 --- a/src/client.h +++ b/src/client.h @@ -110,7 +110,6 @@ class CClient : public QObject public: CClient ( const quint16 iPortNumber, const quint16 iQosNumber, - const QString& strConnOnStartupAddress, const QString& strMIDISetup, const bool bNoAutoJackConnect, const QString& strNClientName, @@ -119,19 +118,17 @@ class CClient : public QObject virtual ~CClient(); - void Start(); - void Stop(); - bool IsRunning() { return Sound.IsRunning(); } - bool IsCallbackEntered() const { return Sound.IsCallbackEntered(); } - bool SetServerAddr ( QString strNAddr ); + bool Connect ( QString strServerAddress, QString strServerName ); + bool Disconnect(); + + bool SoundIsRunning() const { return Sound.IsCallbackEntered(); } // For OnTimerCheckAudioDeviceOk only ! + bool IsConnected() { return Channel.IsConnected(); } double GetLevelForMeterdBLeft() { return SignalLevelMeter.GetLevelForMeterdBLeftOrMono(); } double GetLevelForMeterdBRight() { return SignalLevelMeter.GetLevelForMeterdBRight(); } bool GetAndResetbJitterBufferOKFlag(); - bool IsConnected() { return Channel.IsConnected(); } - EGUIDesign GetGUIDesign() const { return eGUIDesign; } void SetGUIDesign ( const EGUIDesign eNGD ) { eGUIDesign = eNGD; } @@ -425,8 +422,9 @@ protected slots: void CLChannelLevelListReceived ( CHostAddress InetAddr, CVector vecLevelList ); + void Connecting ( QString strServerName ); void Disconnected(); - void SoundDeviceChanged ( QString strError ); + void SoundDeviceChanged(); void ControllerInFaderLevel ( int iChannelIdx, int iValue ); void ControllerInPanValue ( int iChannelIdx, int iValue ); void ControllerInFaderIsSolo ( int iChannelIdx, bool bIsSolo ); diff --git a/src/clientdlg.cpp b/src/clientdlg.cpp index c94c03b707..fee662654c 100644 --- a/src/clientdlg.cpp +++ b/src/clientdlg.cpp @@ -27,7 +27,6 @@ /* Implementation *************************************************************/ CClientDlg::CClientDlg ( CClient* pNCliP, CClientSettings* pNSetP, - const QString& strConnOnStartupAddress, const QString& strMIDISetup, const bool bNewShowComplRegConnList, const bool bShowAnalyzerConsole, @@ -272,14 +271,6 @@ CClientDlg::CClientDlg ( CClient* pNCliP, TimerCheckAudioDeviceOk.setSingleShot ( true ); // only check once after connection TimerDetectFeedback.setSingleShot ( true ); - // Connect on startup ------------------------------------------------------ - if ( !strConnOnStartupAddress.isEmpty() ) - { - // initiate connection (always show the address in the mixer board - // (no alias)) - Connect ( strConnOnStartupAddress, strConnOnStartupAddress ); - } - // File menu -------------------------------------------------------------- QMenu* pFileMenu = new QMenu ( tr ( "&File" ), this ); @@ -473,7 +464,9 @@ CClientDlg::CClientDlg ( CClient* pNCliP, // other QObject::connect ( pClient, &CClient::ConClientListMesReceived, this, &CClientDlg::OnConClientListMesReceived ); - QObject::connect ( pClient, &CClient::Disconnected, this, &CClientDlg::OnDisconnected ); + QObject::connect ( pClient, &CClient::Connecting, this, &CClientDlg::OnConnect ); + + QObject::connect ( pClient, &CClient::Disconnected, this, &CClientDlg::OnDisconnect ); QObject::connect ( pClient, &CClient::ChatTextReceived, this, &CClientDlg::OnChatTextReceived ); @@ -609,10 +602,7 @@ void CClientDlg::closeEvent ( QCloseEvent* Event ) AnalyzerConsole.close(); // if connected, terminate connection - if ( pClient->IsRunning() ) - { - pClient->Stop(); - } + pClient->Disconnect(); // make sure all current fader settings are applied to the settings struct MainMixerBoard->StoreAllFaderSettings(); @@ -730,16 +720,12 @@ void CClientDlg::OnConnectDlgAccepted() } } - // first check if we are already connected, if this is the case we have to - // disconnect the old server first - if ( pClient->IsRunning() ) + // initiate connection + if ( pClient->Connect ( strSelectedAddress, strMixerBoardLabel ) ) { - Disconnect(); + OnConnect ( strMixerBoardLabel ); } - // initiate connection - Connect ( strSelectedAddress, strMixerBoardLabel ); - // reset flag bConnectDlgWasShown = false; } @@ -748,10 +734,9 @@ void CClientDlg::OnConnectDlgAccepted() void CClientDlg::OnConnectDisconBut() { // the connect/disconnect button implements a toggle functionality - if ( pClient->IsRunning() ) + if ( pClient->Disconnect() ) { - Disconnect(); - SetMixerBoardDeco ( RS_UNDEFINED, pClient->GetGUIDesign() ); + // Client was Connected, now disconnected } else { @@ -835,7 +820,7 @@ void CClientDlg::OnChatTextReceived ( QString strChatText ) // always when a new message arrives since this is annoying. ShowChatWindow ( ( strChatText.indexOf ( WELCOME_MESSAGE_PREFIX ) == 0 ) ); - UpdateDisplay(); + UpdateSettingsAndChatButtons(); } void CClientDlg::OnLicenceRequired ( ELicenceType eLicenceType ) @@ -853,7 +838,7 @@ void CClientDlg::OnLicenceRequired ( ELicenceType eLicenceType ) // disconnect from that server. if ( !LicenceDlg.exec() ) { - Disconnect(); + pClient->Disconnect(); } // unmute the client output stream if local mute button is not pressed @@ -991,7 +976,7 @@ void CClientDlg::ShowChatWindow ( const bool bForceRaise ) ChatDlg.activateWindow(); } - UpdateDisplay(); + UpdateSettingsAndChatButtons(); } void CClientDlg::ShowAnalyzerConsole() @@ -1059,7 +1044,8 @@ void CClientDlg::OnTimerSigMet() // show message box about feedback issue QCheckBox* chb = new QCheckBox ( tr ( "Enable feedback detection" ) ); chb->setCheckState ( pSettings->bEnableFeedbackDetection ? Qt::Checked : Qt::Unchecked ); - QMessageBox msgbox; + QMessageBox msgbox ( CMsgBoxes::MainForm() ); + msgbox.setWindowTitle ( CMsgBoxes::MainFormName() + ": " + tr ( "Warning" ) ); msgbox.setText ( tr ( "Audio feedback or loud signal detected.\n\n" "We muted your channel and activated 'Mute Myself'. Please solve " "the feedback issue first and unmute yourself afterwards." ) ); @@ -1141,31 +1127,17 @@ void CClientDlg::OnTimerCheckAudioDeviceOk() // timeout to check if a valid device is selected and if we do not have // fundamental settings errors (in which case the GUI would only show that // it is trying to connect the server which does not help to solve the problem (#129)) - if ( !pClient->IsCallbackEntered() ) + if ( !pClient->SoundIsRunning() ) // ---> pgScorpio Was pClient->IsCallbackEntered() { - QMessageBox::warning ( this, - APP_NAME, - tr ( "Your sound card is not working correctly. " - "Please open the settings dialog and check the device selection and the driver settings." ) ); + CMsgBoxes::ShowWarning ( tr ( "Your sound card is not working correctly. " + "Please open the settings dialog and check the device selection and the driver settings." ) ); } } void CClientDlg::OnTimerDetectFeedback() { bDetectFeedback = false; } -void CClientDlg::OnSoundDeviceChanged ( QString strError ) +void CClientDlg::OnSoundDeviceChanged() { - if ( !strError.isEmpty() ) - { - // the sound device setup has a problem, disconnect any active connection - if ( pClient->IsRunning() ) - { - Disconnect(); - } - - // show the error message of the device setup - QMessageBox::critical ( this, APP_NAME, strError, tr ( "Ok" ), nullptr ); - } - // if the check audio device timer is running, it must be restarted on a device change if ( TimerCheckAudioDeviceOk.isActive() ) { @@ -1188,65 +1160,36 @@ void CClientDlg::OnCLPingTimeWithNumClientsReceived ( CHostAddress InetAddr, int ConnectDlg.SetPingTimeAndNumClientsResult ( InetAddr, iPingTime, iNumClients ); } -void CClientDlg::Connect ( const QString& strSelectedAddress, const QString& strMixerBoardLabel ) +void CClientDlg::OnConnect ( QString strServerName ) { - // set address and check if address is valid - if ( pClient->SetServerAddr ( strSelectedAddress ) ) - { - // try to start client, if error occurred, do not go in - // running state but show error message - try - { - if ( !pClient->IsRunning() ) - { - pClient->Start(); - } - } - catch ( const CGenErr& generr ) - { - // show error message and return the function - QMessageBox::critical ( this, APP_NAME, generr.GetErrorText(), "Close", nullptr ); - return; - } + // hide label connect to server + lblConnectToServer->hide(); + lbrInputLevelL->setEnabled ( true ); + lbrInputLevelR->setEnabled ( true ); - // hide label connect to server - lblConnectToServer->hide(); - lbrInputLevelL->setEnabled ( true ); - lbrInputLevelR->setEnabled ( true ); + // change connect button text to "disconnect" + butConnect->setText ( tr ( "&Disconnect" ) ); - // change connect button text to "disconnect" - butConnect->setText ( tr ( "&Disconnect" ) ); + // set server name in audio mixer group box title + MainMixerBoard->SetServerName ( strServerName ); - // set server name in audio mixer group box title - MainMixerBoard->SetServerName ( strMixerBoardLabel ); + // start timer for level meter bar and ping time measurement + TimerSigMet.start ( LEVELMETER_UPDATE_TIME_MS ); + TimerBuffersLED.start ( BUFFER_LED_UPDATE_TIME_MS ); + TimerPing.start ( PING_UPDATE_TIME_MS ); + TimerCheckAudioDeviceOk.start ( CHECK_AUDIO_DEV_OK_TIME_MS ); // is single shot timer - // start timer for level meter bar and ping time measurement - TimerSigMet.start ( LEVELMETER_UPDATE_TIME_MS ); - TimerBuffersLED.start ( BUFFER_LED_UPDATE_TIME_MS ); - TimerPing.start ( PING_UPDATE_TIME_MS ); - TimerCheckAudioDeviceOk.start ( CHECK_AUDIO_DEV_OK_TIME_MS ); // is single shot timer - - // audio feedback detection - if ( pSettings->bEnableFeedbackDetection ) - { - TimerDetectFeedback.start ( DETECT_FEEDBACK_TIME_MS ); // single shot timer - bDetectFeedback = true; - } + // audio feedback detection + if ( pSettings->bEnableFeedbackDetection ) + { + TimerDetectFeedback.start ( DETECT_FEEDBACK_TIME_MS ); // single shot timer + bDetectFeedback = true; } } -void CClientDlg::Disconnect() +void CClientDlg::OnDisconnect() { - // only stop client if currently running, in case we received - // the stopped message, the client is already stopped but the - // connect/disconnect button and other GUI controls must be - // updated - if ( pClient->IsRunning() ) - { - pClient->Stop(); - } - // change connect button text to "connect" butConnect->setText ( tr ( "C&onnect" ) ); @@ -1270,11 +1213,7 @@ void CClientDlg::Disconnect() TimerDetectFeedback.stop(); bDetectFeedback = false; - // clang-format off -// TODO is this still required??? -// immediately update status bar -OnTimerStatus(); - // clang-format on + UpdateSettingsAndChatButtons(); // reset LEDs ledBuffers->Reset(); @@ -1288,9 +1227,11 @@ OnTimerStatus(); // clear mixer board (remove all faders) MainMixerBoard->HideAll(); + + SetMixerBoardDeco ( RS_UNDEFINED, pClient->GetGUIDesign() ); } -void CClientDlg::UpdateDisplay() +void CClientDlg::UpdateSettingsAndChatButtons() { // update settings/chat buttons (do not fire signals since it is an update) if ( chbSettings->isChecked() && !ClientSettingsDlg.isVisible() ) diff --git a/src/clientdlg.h b/src/clientdlg.h index bbcc604766..79d8190dea 100644 --- a/src/clientdlg.h +++ b/src/clientdlg.h @@ -76,7 +76,6 @@ class CClientDlg : public CBaseDlg, private Ui_CClientDlgBase public: CClientDlg ( CClient* pNCliP, CClientSettings* pNSetP, - const QString& strConnOnStartupAddress, const QString& strMIDISetup, const bool bNewShowComplRegConnList, const bool bShowAnalyzerConsole, @@ -94,8 +93,6 @@ class CClientDlg : public CBaseDlg, private Ui_CClientDlgBase void ShowAnalyzerConsole(); void UpdateAudioFaderSlider(); void UpdateRevSelection(); - void Connect ( const QString& strSelectedAddress, const QString& strMixerBoardLabel ); - void Disconnect(); void ManageDragNDrop ( QDropEvent* Event, const bool bCheckAccept ); void SetPingTime ( const int iPingTime, const int iOverallDelayMs, const CMultiColorLED::ELightColor eOverallDelayLEDColor ); @@ -119,7 +116,7 @@ class CClientDlg : public CBaseDlg, private Ui_CClientDlgBase virtual void closeEvent ( QCloseEvent* Event ); virtual void dragEnterEvent ( QDragEnterEvent* Event ) { ManageDragNDrop ( Event, true ); } virtual void dropEvent ( QDropEvent* Event ) { ManageDragNDrop ( Event, false ); } - void UpdateDisplay(); + void UpdateSettingsAndChatButtons(); CClientSettingsDlg ClientSettingsDlg; CChatDlg ChatDlg; @@ -127,13 +124,16 @@ class CClientDlg : public CBaseDlg, private Ui_CClientDlgBase CAnalyzerConsole AnalyzerConsole; public slots: + void OnConnect ( QString strServerName ); + void OnDisconnect(); + void OnConnectDisconBut(); void OnTimerSigMet(); void OnTimerBuffersLED(); void OnTimerCheckAudioDeviceOk(); void OnTimerDetectFeedback(); - void OnTimerStatus() { UpdateDisplay(); } + void OnTimerStatus() { UpdateSettingsAndChatButtons(); } void OnTimerPing(); void OnPingTimeResult ( int iPingTime ); @@ -191,7 +191,7 @@ public slots: void OnConClientListMesReceived ( CVector vecChanInfo ); void OnChatTextReceived ( QString strChatText ); void OnLicenceRequired ( ELicenceType eLicenceType ); - void OnSoundDeviceChanged ( QString strError ); + void OnSoundDeviceChanged(); void OnChangeChanGain ( int iId, float fGain, bool bIsMyOwnFader ) { pClient->SetRemoteChanGain ( iId, fGain, bIsMyOwnFader ); } @@ -232,7 +232,6 @@ public slots: } void OnConnectDlgAccepted(); - void OnDisconnected() { Disconnect(); } void OnGUIDesignChanged(); void OnMeterStyleChanged(); void OnRecorderStateReceived ( ERecorderState eRecorderState ); diff --git a/src/clientsettingsdlg.cpp b/src/clientsettingsdlg.cpp index 78f2353b50..77e19ab82b 100644 --- a/src/clientsettingsdlg.cpp +++ b/src/clientsettingsdlg.cpp @@ -1039,8 +1039,16 @@ void CClientSettingsDlg::OnSndCrdBufferDelayButtonGroupClicked ( QAbstractButton void CClientSettingsDlg::UpdateUploadRate() { // update upstream rate information label - lblUpstreamValue->setText ( QString().setNum ( pClient->GetUploadRateKbps() ) ); - lblUpstreamUnit->setText ( "kbps" ); + if ( pClient->IsConnected() ) + { + lblUpstreamValue->setText ( QString().setNum ( pClient->GetUploadRateKbps() ) ); + lblUpstreamUnit->setText ( "kbps" ); + } + else + { + lblUpstreamValue->setText ( "---" ); + lblUpstreamUnit->setText ( "" ); + } } void CClientSettingsDlg::UpdateDisplay() @@ -1048,13 +1056,8 @@ void CClientSettingsDlg::UpdateDisplay() // update slider controls (settings might have been changed) UpdateJitterBufferFrame(); UpdateSoundCardFrame(); - - if ( !pClient->IsRunning() ) - { - // clear text labels with client parameters - lblUpstreamValue->setText ( "---" ); - lblUpstreamUnit->setText ( "" ); - } + // update upstream rate information label + UpdateUploadRate(); } void CClientSettingsDlg::UpdateDirectoryServerComboBox() diff --git a/src/global.h b/src/global.h index 22ae0c52bf..cda4bf107e 100644 --- a/src/global.h +++ b/src/global.h @@ -359,18 +359,220 @@ class CCustomEvent : public QEvent }; /* Prototypes for global functions ********************************************/ -// command line parsing, TODO do not declare functions globally but in a class -QString UsageArguments ( char** argv ); +extern QString UsageArguments ( char** argv ); + +//============================================================================ +// CMsgBoxes class: +// Use this static class to show basic Error, Warning and Info messageboxes +// For own created message boxes you should still use +// CMsgBoxes::MainForm() and CMsgBoxes::MainFormName() +//============================================================================ +#ifndef HEADLESS +# include +# define tMainform QDialog +#else +# define tMainform void +#endif + +// html text macro's (for use in gui texts) +#define htmlBold( T ) "" + T + "" +#define htmlNewLine() "
" + +class CMsgBoxes +{ +protected: + static tMainform* pMainForm; + static QString strMainFormName; + +public: + static void init ( tMainform* theMainForm, QString theMainFormName ) + { + pMainForm = theMainForm; + strMainFormName = theMainFormName; + } + + static tMainform* MainForm() { return pMainForm; } + static const QString& MainFormName() { return strMainFormName; } + + // Message boxes: + static void ShowError ( QString strError ); + static void ShowWarning ( QString strWarning ); + static void ShowInfo ( QString strInfo ); +}; + +//============================================================================ +// CCommandlineOptions class: +// Note that passing commandline arguments to classes is no longer required, +// since via this class we can get commandline options anywhere. +//============================================================================ + +class CCommandlineOptions +{ +public: + CCommandlineOptions() { reset(); } -bool GetFlagArgument ( char** argv, int& i, QString strShortOpt, QString strLongOpt ); +private: + friend int main ( int argc, char** argv ); -bool GetStringArgument ( int argc, char** argv, int& i, QString strShortOpt, QString strLongOpt, QString& strArg ); + // Statics assigned from main () + static int appArgc; + static char** appArgv; + +public: + static QString GetProgramPath() { return QString ( *appArgv ); } + +public: + // sequencial parse functions using the argument index: + + static bool GetFlagArgument ( int& i, const QString& strShortOpt, const QString& strLongOpt ); + + static bool GetStringArgument ( int& i, const QString& strShortOpt, const QString& strLongOpt, QString& strArg ); + + static bool GetNumericArgument ( int& i, + const QString& strShortOpt, + const QString& strLongOpt, + double rRangeStart, + double rRangeStop, + double& rValue ); + +public: + // find and get a specific argument: + + static bool GetFlagArgument ( const QString& strShortOpt, const QString& strLongOpt ) + { + int i = 1; + while ( i < appArgc ) + { + if ( GetFlagArgument ( i, strShortOpt, strLongOpt ) ) + { + return true; + } + + i++; + } + + return false; + } + + static bool GetStringArgument ( const QString& strShortOpt, const QString& strLongOpt, QString& strArg ) + { + int i = 1; + while ( i < appArgc ) + { + if ( GetStringArgument ( i, strShortOpt, strLongOpt, strArg ) ) + { + return true; + } + + i++; + } + + return false; + } + + static bool GetNumericArgument ( const QString& strShortOpt, const QString& strLongOpt, double rRangeStart, double rRangeStop, double& rValue ) + { + int i = 1; + while ( i < appArgc ) + { + if ( GetNumericArgument ( i, strShortOpt, strLongOpt, rRangeStart, rRangeStop, rValue ) ) + { + return true; + } + + i++; + } + + return false; + } + + //================================================= + // Non statics to parse bare arguments + // (These need an instance of CCommandlineOptions) + //================================================= + +protected: + int currentIndex; + char** currentArgv; + + void reset() + { + currentArgv = appArgv; + currentIndex = 0; + } + +public: + QString GetFirstArgument() + { + reset(); + // Skipping program path + return GetNextArgument(); + } + + QString GetNextArgument() + { + if ( currentIndex < appArgc ) + { + currentArgv++; + currentIndex++; + + if ( currentIndex < appArgc ) + { + return QString ( *currentArgv ); + } + } + + return QString(); + } +}; -bool GetNumericArgument ( int argc, - char** argv, - int& i, - QString strShortOpt, - QString strLongOpt, - double rRangeStart, - double rRangeStop, - double& rValue ); +// defines for commandline options in the style "shortopt", "longopt" +// Name is standard CMDLN_LONGOPTNAME +// These defines can be used for strShortOpt, strLongOpt parameters +// of the CCommandlineOptions functions. +// +// clang-format off +#define CMDLN_SERVER "-s", "--server" +#define CMDLN_INIFILE "-i", "--inifile" +#define CMDLN_NOGUI "-n", "--nogui" +#define CMDLN_PORT "-p", "--port" +#define CMDLN_JSONRPCPORT "--jsonrpcport", "--jsonrpcport" +#define CMDLN_JSONRPCSECRETFILE "--jsonrpcsecretfile", "--jsonrpcsecretfile" +#define CMDLN_QOS "-Q", "--qos" +#define CMDLN_NOTRANSLATION "-t", "--notranslation" +#define CMDLN_ENABLEIPV6 "-6", "--enableipv6" +#define CMDLN_DISCONONQUIT "-d", "--discononquit" +#define CMDLN_DIRECTORYSERVER "-e", "--directoryserver" +#define CMDLN_DIRECTORYFILE "--directoryfile", "--directoryfile" +#define CMDLN_LISTFILTER "-f", "--listfilter" +#define CMDLN_FASTUPDATE "-F", "--fastupdate" +#define CMDLN_LOG "-l", "--log" +#define CMDLN_LICENCE "-L", "--licence" +#define CMDLN_HTMLSTATUS "-m", "--htmlstatus" +#define CMDLN_SERVERINFO "-o", "--serverinfo" +#define CMDLN_SERVERPUBLICIP "--serverpublicip", "--serverpublicip" +#define CMDLN_DELAYPAN "-P", "--delaypan" +#define CMDLN_RECORDING "-R", "--recording" +#define CMDLN_NORECORD "--norecord", "--norecord" +#define CMDLN_SERVERBINDIP "--serverbindip", "--serverbindip" +#define CMDLN_MULTITHREADING "-T", "--multithreading" +#define CMDLN_NUMCHANNELS "-u", "--numchannels" +#define CMDLN_WELCOMEMESSAGE "-w", "--welcomemessage" +#define CMDLN_STARTMINIMIZED "-z", "--startminimized" +#define CMDLN_CONNECT "-c", "--connect" +#define CMDLN_NOJACKCONNECT "-j", "--nojackconnect" +#define CMDLN_MUTESTREAM "-M", "--mutestream" +#define CMDLN_MUTEMYOWN "--mutemyown", "--mutemyown" +#define CMDLN_CLIENTNAME "--clientname", "--clientname" +#define CMDLN_CTRLMIDICH "--ctrlmidich", "--ctrlmidich" +// Backwards compatibilyty: +#define CMDLN_CENTRALSERVER "--centralserver", "--centralserver" +// Debug options: (not in help) +#define CMDLN_SHOWALLSERVERS "--showallservers", "--showallservers" +#define CMDLN_SHOWANALYZERCONSOLE "--showanalyzerconsole", "--showanalyzerconsole" +// CMDLN_SPECIAL: Used for debugging, should NOT be in help, nor documented elsewhere! +// any option after --special is accepted +#define CMDLN_SPECIAL "--special", "--special" +// Special options for sound-redesign testing +#define CMDLN_JACKINPUTS "--jackinputs", "--jackinputs" +// clang-format on diff --git a/src/main.cpp b/src/main.cpp index 0bc792376b..e9bb72014d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -55,8 +55,88 @@ extern void qt_set_sequence_auto_mnemonic ( bool bEnable ); // Implementation ************************************************************** +int CCommandlineOptions::appArgc = 0; +char** CCommandlineOptions::appArgv = NULL; + +tMainform* CMsgBoxes::pMainForm = NULL; +QString CMsgBoxes::strMainFormName = APP_NAME; + +QString UsageArguments ( char** argv ) +{ + // clang-format off + return QString ( + "\n" + "Usage: %1 [option] [option argument] ...\n" + "\n" + " -h, -?, --help display this help text and exit\n" + " -v, --version display version information and exit\n" + "\n" + "Common options:\n" + " -i, --inifile initialization file name\n" + " (not supported for headless Server mode)\n" + " -n, --nogui disable GUI (\"headless\")\n" + " -p, --port set the local port number\n" + " --jsonrpcport enable JSON-RPC server, set TCP port number\n" + " (EXPERIMENTAL, APIs might still change;\n" + " only accessible from localhost)\n" + " --jsonrpcsecretfile\n" + " path to a single-line file which contains a freely\n" + " chosen secret to authenticate JSON-RPC users.\n" + " -Q, --qos set the QoS value. Default is 128. Disable with 0\n" + " (see the Jamulus website to enable QoS on Windows)\n" + " -t, --notranslation disable translation (use English language)\n" + " -6, --enableipv6 enable IPv6 addressing (IPv4 is always enabled)\n" + "\n" + "Server only:\n" + " -d, --discononquit disconnect all Clients on quit\n" + " -e, --directoryserver address of the directory Server with which to register\n" + " (or 'localhost' to host a server list on this Server)\n" + " --directoryfile Remember registered Servers even if the Directory is restarted. Directory Servers only.\n" + " -f, --listfilter Server list whitelist filter. Format:\n" + " [IP address 1];[IP address 2];[IP address 3]; ...\n" + " -F, --fastupdate use 64 samples frame size mode\n" + " -l, --log enable logging, set file name\n" + " -L, --licence show an agreement window before users can connect\n" + " -m, --htmlstatus enable HTML status file, set file name\n" + " -o, --serverinfo registration info for this Server. Format:\n" + " [name];[city];[country as QLocale ID]\n" + " --serverpublicip public IP address for this Server. Needed when\n" + " registering with a server list hosted\n" + " behind the same NAT\n" + " -P, --delaypan start with delay panning enabled\n" + " -R, --recording sets directory to contain recorded jams\n" + " --norecord disables recording (when enabled by default by -R)\n" + " -s, --server start Server\n" + " --serverbindip IP address the Server will bind to (rather than all)\n" + " -T, --multithreading use multithreading to make better use of\n" + " multi-core CPUs and support more Clients\n" + " -u, --numchannels maximum number of channels\n" + " -w, --welcomemessage welcome message to display on connect\n" + " (string or filename, HTML supported)\n" + " -z, --startminimized start minimizied\n" + "\n" + "Client only:\n" + " -c, --connect connect to given Server address on startup\n" + " -j, --nojackconnect disable auto JACK connections\n" + " -M, --mutestream starts the application in muted state\n" + " --mutemyown mute me in my personal mix (headless only)\n" + " --clientname Client name (window title and JACK client name)\n" + " --ctrlmidich MIDI controller channel to listen\n" + "\n" + "Example: %1 -s --inifile myinifile.ini\n" + "\n" + "For more information and localized help see:\n" + "https://jamulus.io/wiki/Command-Line-Options\n" + ).arg( argv[0] ); + // clang-format on +} + int main ( int argc, char** argv ) { + CCommandlineOptions::appArgc = argc; + CCommandlineOptions::appArgv = argv; + + CCommandlineOptions cmdLine; // We don't really need an instance here, but using one improves the readability of the code. #if defined( Q_OS_MACX ) // Mnemonic keys are default disabled in Qt for MacOS. The following function enables them. @@ -79,6 +159,7 @@ int main ( int argc, char** argv ) #else bool bIsClient = true; #endif + bool bSpecialOptions = false; // Any options after this option will be accepted ! (mostly used for debugging purpouses) bool bUseGUI = true; bool bStartMinimized = false; bool bShowComplRegConnList = false; @@ -128,14 +209,13 @@ int main ( int argc, char** argv ) // QT docu: argv()[0] is the program name, argv()[1] is the first // argument and argv()[argc()-1] is the last argument. // Start with first argument, therefore "i = 1" + for ( int i = 1; i < argc; i++ ) { - // Help (usage) flag --------------------------------------------------- if ( ( !strcmp ( argv[i], "--help" ) ) || ( !strcmp ( argv[i], "-h" ) ) || ( !strcmp ( argv[i], "-?" ) ) ) { - const QString strHelp = UsageArguments ( argv ); - std::cout << qUtf8Printable ( strHelp ); + std::cout << qUtf8Printable ( UsageArguments ( argv ) ); exit ( 0 ); } @@ -149,7 +229,7 @@ int main ( int argc, char** argv ) // Common options: // Initialization file ------------------------------------------------- - if ( GetStringArgument ( argc, argv, i, "-i", "--inifile", strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_INIFILE, strArgument ) ) { strIniFileName = strArgument; qInfo() << qUtf8Printable ( QString ( "- initialization file name: %1" ).arg ( strIniFileName ) ); @@ -158,7 +238,7 @@ int main ( int argc, char** argv ) } // Disable GUI flag ---------------------------------------------------- - if ( GetFlagArgument ( argv, i, "-n", "--nogui" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_NOGUI ) ) { bUseGUI = false; qInfo() << "- no GUI mode chosen"; @@ -167,7 +247,7 @@ int main ( int argc, char** argv ) } // Port number --------------------------------------------------------- - if ( GetNumericArgument ( argc, argv, i, "-p", "--port", 0, 65535, rDbleArgument ) ) + if ( cmdLine.GetNumericArgument ( i, CMDLN_PORT, 0, 65535, rDbleArgument ) ) { iPortNumber = static_cast ( rDbleArgument ); bCustomPortNumberGiven = true; @@ -177,7 +257,7 @@ int main ( int argc, char** argv ) } // JSON-RPC port number ------------------------------------------------ - if ( GetNumericArgument ( argc, argv, i, "--jsonrpcport", "--jsonrpcport", 0, 65535, rDbleArgument ) ) + if ( cmdLine.GetNumericArgument ( i, CMDLN_JSONRPCPORT, 0, 65535, rDbleArgument ) ) { iJsonRpcPortNumber = static_cast ( rDbleArgument ); qInfo() << qUtf8Printable ( QString ( "- JSON-RPC port number: %1" ).arg ( iJsonRpcPortNumber ) ); @@ -186,7 +266,7 @@ int main ( int argc, char** argv ) } // JSON-RPC secret file name ------------------------------------------- - if ( GetStringArgument ( argc, argv, i, "--jsonrpcsecretfile", "--jsonrpcsecretfile", strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_JSONRPCSECRETFILE, strArgument ) ) { strJsonRpcSecretFileName = strArgument; qInfo() << qUtf8Printable ( QString ( "- JSON-RPC secret file: %1" ).arg ( strJsonRpcSecretFileName ) ); @@ -195,7 +275,7 @@ int main ( int argc, char** argv ) } // Quality of Service -------------------------------------------------- - if ( GetNumericArgument ( argc, argv, i, "-Q", "--qos", 0, 255, rDbleArgument ) ) + if ( cmdLine.GetNumericArgument ( i, CMDLN_QOS, 0, 255, rDbleArgument ) ) { iQosNumber = static_cast ( rDbleArgument ); qInfo() << qUtf8Printable ( QString ( "- selected QoS value: %1" ).arg ( iQosNumber ) ); @@ -204,7 +284,7 @@ int main ( int argc, char** argv ) } // Disable translations ------------------------------------------------ - if ( GetFlagArgument ( argv, i, "-t", "--notranslation" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_NOTRANSLATION ) ) { bUseTranslation = false; qInfo() << "- translations disabled"; @@ -213,7 +293,7 @@ int main ( int argc, char** argv ) } // Enable IPv6 --------------------------------------------------------- - if ( GetFlagArgument ( argv, i, "-6", "--enableipv6" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_ENABLEIPV6 ) ) { bEnableIPv6 = true; qInfo() << "- IPv6 enabled"; @@ -224,7 +304,7 @@ int main ( int argc, char** argv ) // Server only: // Disconnect all clients on quit -------------------------------------- - if ( GetFlagArgument ( argv, i, "-d", "--discononquit" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_DISCONONQUIT ) ) { bDisconnectAllClientsOnQuit = true; qInfo() << "- disconnect all clients on quit"; @@ -234,22 +314,9 @@ int main ( int argc, char** argv ) } // Directory server ---------------------------------------------------- - if ( GetStringArgument ( argc, argv, i, "-e", "--directoryserver", strArgument ) ) - { - strDirectoryServer = strArgument; - qInfo() << qUtf8Printable ( QString ( "- directory server: %1" ).arg ( strDirectoryServer ) ); - CommandLineOptions << "--directoryserver"; - ServerOnlyOptions << "--directoryserver"; - continue; - } - - // Central server ** D E P R E C A T E D ** ---------------------------- - if ( GetStringArgument ( argc, - argv, - i, - "--centralserver", // no short form - "--centralserver", - strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_DIRECTORYSERVER, strArgument ) || + cmdLine.GetStringArgument ( i, CMDLN_CENTRALSERVER, strArgument ) // ** D E P R E C A T E D ** + ) { strDirectoryServer = strArgument; qInfo() << qUtf8Printable ( QString ( "- directory server: %1" ).arg ( strDirectoryServer ) ); @@ -259,12 +326,7 @@ int main ( int argc, char** argv ) } // Directory file ------------------------------------------------------ - if ( GetStringArgument ( argc, - argv, - i, - "--directoryfile", // no short form - "--directoryfile", - strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_DIRECTORYFILE, strArgument ) ) { strServerListFileName = strArgument; qInfo() << qUtf8Printable ( QString ( "- directory server persistence file: %1" ).arg ( strServerListFileName ) ); @@ -274,7 +336,7 @@ int main ( int argc, char** argv ) } // Server list filter -------------------------------------------------- - if ( GetStringArgument ( argc, argv, i, "-f", "--listfilter", strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_LISTFILTER, strArgument ) ) { strServerListFilter = strArgument; qInfo() << qUtf8Printable ( QString ( "- server list filter: %1" ).arg ( strServerListFilter ) ); @@ -284,7 +346,7 @@ int main ( int argc, char** argv ) } // Use 64 samples frame size mode -------------------------------------- - if ( GetFlagArgument ( argv, i, "-F", "--fastupdate" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_FASTUPDATE ) ) { bUseDoubleSystemFrameSize = false; // 64 samples frame size qInfo() << qUtf8Printable ( QString ( "- using %1 samples frame size mode" ).arg ( SYSTEM_FRAME_SIZE_SAMPLES ) ); @@ -294,7 +356,7 @@ int main ( int argc, char** argv ) } // Use logging --------------------------------------------------------- - if ( GetStringArgument ( argc, argv, i, "-l", "--log", strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_LOG, strArgument ) ) { strLoggingFileName = strArgument; qInfo() << qUtf8Printable ( QString ( "- logging file name: %1" ).arg ( strLoggingFileName ) ); @@ -304,7 +366,7 @@ int main ( int argc, char** argv ) } // Use licence flag ---------------------------------------------------- - if ( GetFlagArgument ( argv, i, "-L", "--licence" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_LICENCE ) ) { // LT_CREATIVECOMMONS is now used just to enable the pop up eLicenceType = LT_CREATIVECOMMONS; @@ -315,7 +377,7 @@ int main ( int argc, char** argv ) } // HTML status file ---------------------------------------------------- - if ( GetStringArgument ( argc, argv, i, "-m", "--htmlstatus", strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_HTMLSTATUS, strArgument ) ) { strHTMLStatusFileName = strArgument; qInfo() << qUtf8Printable ( QString ( "- HTML status file name: %1" ).arg ( strHTMLStatusFileName ) ); @@ -325,7 +387,7 @@ int main ( int argc, char** argv ) } // Server info --------------------------------------------------------- - if ( GetStringArgument ( argc, argv, i, "-o", "--serverinfo", strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_SERVERINFO, strArgument ) ) { strServerInfo = strArgument; qInfo() << qUtf8Printable ( QString ( "- server info: %1" ).arg ( strServerInfo ) ); @@ -335,12 +397,7 @@ int main ( int argc, char** argv ) } // Server Public IP ---------------------------------------------------- - if ( GetStringArgument ( argc, - argv, - i, - "--serverpublicip", // no short form - "--serverpublicip", - strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_SERVERPUBLICIP, strArgument ) ) { strServerPublicIP = strArgument; qInfo() << qUtf8Printable ( QString ( "- server public IP: %1" ).arg ( strServerPublicIP ) ); @@ -350,7 +407,7 @@ int main ( int argc, char** argv ) } // Enable delay panning on startup ------------------------------------- - if ( GetFlagArgument ( argv, i, "-P", "--delaypan" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_DELAYPAN ) ) { bDelayPan = true; qInfo() << "- starting with delay panning"; @@ -360,7 +417,7 @@ int main ( int argc, char** argv ) } // Recording directory ------------------------------------------------- - if ( GetStringArgument ( argc, argv, i, "-R", "--recording", strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_RECORDING, strArgument ) ) { strRecordingDirName = strArgument; qInfo() << qUtf8Printable ( QString ( "- recording directory name: %1" ).arg ( strRecordingDirName ) ); @@ -370,10 +427,7 @@ int main ( int argc, char** argv ) } // Disable recording on startup ---------------------------------------- - if ( GetFlagArgument ( argv, - i, - "--norecord", // no short form - "--norecord" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_NORECORD ) ) { bDisableRecording = true; qInfo() << "- recording will not take place until enabled"; @@ -383,7 +437,7 @@ int main ( int argc, char** argv ) } // Server mode flag ---------------------------------------------------- - if ( GetFlagArgument ( argv, i, "-s", "--server" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_SERVER ) ) { bIsClient = false; qInfo() << "- server mode chosen"; @@ -393,12 +447,7 @@ int main ( int argc, char** argv ) } // Server Bind IP -------------------------------------------------- - if ( GetStringArgument ( argc, - argv, - i, - "--serverbindip", // no short form - "--serverbindip", - strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_SERVERBINDIP, strArgument ) ) { strServerBindIP = strArgument; qInfo() << qUtf8Printable ( QString ( "- server bind IP: %1" ).arg ( strServerBindIP ) ); @@ -408,7 +457,7 @@ int main ( int argc, char** argv ) } // Use multithreading -------------------------------------------------- - if ( GetFlagArgument ( argv, i, "-T", "--multithreading" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_MULTITHREADING ) ) { bUseMultithreading = true; qInfo() << "- using multithreading"; @@ -418,7 +467,7 @@ int main ( int argc, char** argv ) } // Maximum number of channels ------------------------------------------ - if ( GetNumericArgument ( argc, argv, i, "-u", "--numchannels", 1, MAX_NUM_CHANNELS, rDbleArgument ) ) + if ( cmdLine.GetNumericArgument ( i, CMDLN_NUMCHANNELS, 1, MAX_NUM_CHANNELS, rDbleArgument ) ) { iNumServerChannels = static_cast ( rDbleArgument ); @@ -430,7 +479,7 @@ int main ( int argc, char** argv ) } // Server welcome message ---------------------------------------------- - if ( GetStringArgument ( argc, argv, i, "-w", "--welcomemessage", strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_WELCOMEMESSAGE, strArgument ) ) { strWelcomeMessage = strArgument; qInfo() << qUtf8Printable ( QString ( "- welcome message: %1" ).arg ( strWelcomeMessage ) ); @@ -440,7 +489,7 @@ int main ( int argc, char** argv ) } // Start minimized ----------------------------------------------------- - if ( GetFlagArgument ( argv, i, "-z", "--startminimized" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_STARTMINIMIZED ) ) { bStartMinimized = true; qInfo() << "- start minimized enabled"; @@ -452,7 +501,7 @@ int main ( int argc, char** argv ) // Client only: // Connect on startup -------------------------------------------------- - if ( GetStringArgument ( argc, argv, i, "-c", "--connect", strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_CONNECT, strArgument ) ) { strConnOnStartupAddress = NetworkUtil::FixAddress ( strArgument ); qInfo() << qUtf8Printable ( QString ( "- connect on startup to address: %1" ).arg ( strConnOnStartupAddress ) ); @@ -462,7 +511,7 @@ int main ( int argc, char** argv ) } // Disabling auto Jack connections ------------------------------------- - if ( GetFlagArgument ( argv, i, "-j", "--nojackconnect" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_NOJACKCONNECT ) ) { bNoAutoJackConnect = true; qInfo() << "- disable auto Jack connections"; @@ -472,7 +521,7 @@ int main ( int argc, char** argv ) } // Mute stream on startup ---------------------------------------------- - if ( GetFlagArgument ( argv, i, "-M", "--mutestream" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_MUTESTREAM ) ) { bMuteStream = true; qInfo() << "- mute stream activated"; @@ -482,10 +531,7 @@ int main ( int argc, char** argv ) } // For headless client mute my own signal in personal mix -------------- - if ( GetFlagArgument ( argv, - i, - "--mutemyown", // no short form - "--mutemyown" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_MUTEMYOWN ) ) { bMuteMeInPersonalMix = true; qInfo() << "- mute me in my personal mix"; @@ -495,12 +541,7 @@ int main ( int argc, char** argv ) } // Client Name --------------------------------------------------------- - if ( GetStringArgument ( argc, - argv, - i, - "--clientname", // no short form - "--clientname", - strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_CLIENTNAME, strArgument ) ) { strClientName = strArgument; qInfo() << qUtf8Printable ( QString ( "- client name: %1" ).arg ( strClientName ) ); @@ -510,12 +551,7 @@ int main ( int argc, char** argv ) } // Controller MIDI channel --------------------------------------------- - if ( GetStringArgument ( argc, - argv, - i, - "--ctrlmidich", // no short form - "--ctrlmidich", - strArgument ) ) + if ( cmdLine.GetStringArgument ( i, CMDLN_CTRLMIDICH, strArgument ) ) { strMIDISetup = strArgument; qInfo() << qUtf8Printable ( QString ( "- MIDI controller settings: %1" ).arg ( strMIDISetup ) ); @@ -530,10 +566,7 @@ int main ( int argc, char** argv ) // Undocumented debugging command line argument: Show all registered // servers in the server list regardless if a ping to the server is // possible or not. - if ( GetFlagArgument ( argv, - i, - "--showallservers", // no short form - "--showallservers" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_SHOWALLSERVERS ) ) { bShowComplRegConnList = true; qInfo() << "- show all registered servers in server list"; @@ -545,10 +578,7 @@ int main ( int argc, char** argv ) // Show analyzer console ----------------------------------------------- // Undocumented debugging command line argument: Show the analyzer // console to debug network buffer properties. - if ( GetFlagArgument ( argv, - i, - "--showanalyzerconsole", // no short form - "--showanalyzerconsole" ) ) + if ( cmdLine.GetFlagArgument ( i, CMDLN_SHOWANALYZERCONSOLE ) ) { bShowAnalyzerConsole = true; qInfo() << "- show analyzer console"; @@ -557,13 +587,27 @@ int main ( int argc, char** argv ) continue; } + // Enable Special Options ---------------------------------------------- + if ( cmdLine.GetFlagArgument ( i, CMDLN_SPECIAL ) ) + { + bSpecialOptions = true; + qInfo() << "- Special options enabled !"; + continue; + } + // Unknown option ------------------------------------------------------ qCritical() << qUtf8Printable ( QString ( "%1: Unknown option '%2' -- use '--help' for help" ).arg ( argv[0] ).arg ( argv[i] ) ); -// clicking on the Mac application bundle, the actual application -// is called with weird command line args -> do not exit on these #if !( defined( Q_OS_MACX ) ) - exit ( 1 ); + // clicking on the Mac application bundle, the actual application + // is called with weird command line args -> do not exit on these + + // pgScorpio: No exit for options after the "--special" option. + // Used for debugging and testing new options... + if ( !bSpecialOptions ) + { + exit ( 1 ); + } #endif } @@ -596,8 +640,7 @@ int main ( int argc, char** argv ) if ( ServerOnlyOptions.size() != 0 ) { qCritical() << qUtf8Printable ( QString ( "%1: Server only option(s) '%2' used. Did you omit '--server'?" ) - .arg ( argv[0] ) - .arg ( ServerOnlyOptions.join ( ", " ) ) ); + .arg ( CCommandlineOptions::GetProgramPath(), ServerOnlyOptions.join ( ", " ) ) ); exit ( 1 ); } @@ -812,7 +855,7 @@ int main ( int argc, char** argv ) Q_INIT_RESOURCE ( resources ); #ifndef SERVER_ONLY - // clang-format off +// clang-format off // TEST -> activate the following line to activate the test bench, //CTestbench Testbench ( "127.0.0.1", DEFAULT_PORT_NUMBER ); // clang-format on @@ -862,14 +905,7 @@ int main ( int argc, char** argv ) { // Client: // actual client object - CClient Client ( iPortNumber, - iQosNumber, - strConnOnStartupAddress, - strMIDISetup, - bNoAutoJackConnect, - strClientName, - bEnableIPv6, - bMuteMeInPersonalMix ); + CClient Client ( iPortNumber, iQosNumber, strMIDISetup, bNoAutoJackConnect, strClientName, bEnableIPv6, bMuteMeInPersonalMix ); // load settings from init-file (command line options override) CClientSettings Settings ( &Client, strIniFileName ); @@ -891,18 +927,18 @@ int main ( int argc, char** argv ) if ( bUseGUI ) { // GUI object - CClientDlg ClientDlg ( &Client, - &Settings, - strConnOnStartupAddress, - strMIDISetup, - bShowComplRegConnList, - bShowAnalyzerConsole, - bMuteStream, - bEnableIPv6, - nullptr ); + CClientDlg + ClientDlg ( &Client, &Settings, strMIDISetup, bShowComplRegConnList, bShowAnalyzerConsole, bMuteStream, bEnableIPv6, nullptr ); // show dialog ClientDlg.show(); + + // Connect on startup ------------------------------------------------------ + if ( !strConnOnStartupAddress.isEmpty() ) + { + Client.Connect ( strConnOnStartupAddress, strConnOnStartupAddress ); + } + pApp->exec(); } else @@ -911,6 +947,15 @@ int main ( int argc, char** argv ) // only start application without using the GUI qInfo() << qUtf8Printable ( GetVersionAndNameStr ( false ) ); + // initialise message boxes + CMsgBoxes::init ( NULL, strClientName.isEmpty() ? QString ( APP_NAME ) : QString ( APP_NAME ) + " " + strClientName ); + + // Connect on startup ------------------------------------------------------ + if ( !strConnOnStartupAddress.isEmpty() ) + { + Client.Connect ( strConnOnStartupAddress, strConnOnStartupAddress ); + } + pApp->exec(); } } @@ -961,6 +1006,9 @@ int main ( int argc, char** argv ) // GUI object for the server CServerDlg ServerDlg ( &Server, &Settings, bStartMinimized, nullptr ); + // initialise message boxes + CMsgBoxes::init ( &ServerDlg, strClientName.isEmpty() ? QString ( APP_NAME ) : QString ( APP_NAME ) + " " + strClientName ); + // show dialog (if not the minimized flag is set) if ( !bStartMinimized ) { @@ -982,6 +1030,9 @@ int main ( int argc, char** argv ) Server.SetDirectoryType ( AT_CUSTOM ); } + // initialise message boxes + CMsgBoxes::init ( NULL, strClientName.isEmpty() ? QString ( APP_NAME ) : QString ( APP_NAME ) + " " + strClientName ); + pApp->exec(); } } @@ -993,7 +1044,7 @@ int main ( int argc, char** argv ) #ifndef HEADLESS if ( bUseGUI ) { - QMessageBox::critical ( nullptr, APP_NAME, generr.GetErrorText(), "Quit", nullptr ); + CMsgBoxes::ShowError ( generr.GetErrorText() ); } else #endif @@ -1011,81 +1062,41 @@ int main ( int argc, char** argv ) } /******************************************************************************\ -* Command Line Argument Parsing * +* Message Boxes * \******************************************************************************/ -QString UsageArguments ( char** argv ) +void CMsgBoxes::ShowError ( QString strError ) { - // clang-format off - return QString ( - "\n" - "Usage: %1 [option] [option argument] ...\n" - "\n" - " -h, -?, --help display this help text and exit\n" - " -v, --version display version information and exit\n" - "\n" - "Common options:\n" - " -i, --inifile initialization file name\n" - " (not supported for headless Server mode)\n" - " -n, --nogui disable GUI (\"headless\")\n" - " -p, --port set the local port number\n" - " --jsonrpcport enable JSON-RPC server, set TCP port number\n" - " (EXPERIMENTAL, APIs might still change;\n" - " only accessible from localhost)\n" - " --jsonrpcsecretfile\n" - " path to a single-line file which contains a freely\n" - " chosen secret to authenticate JSON-RPC users.\n" - " -Q, --qos set the QoS value. Default is 128. Disable with 0\n" - " (see the Jamulus website to enable QoS on Windows)\n" - " -t, --notranslation disable translation (use English language)\n" - " -6, --enableipv6 enable IPv6 addressing (IPv4 is always enabled)\n" - "\n" - "Server only:\n" - " -d, --discononquit disconnect all Clients on quit\n" - " -e, --directoryserver address of the directory Server with which to register\n" - " (or 'localhost' to host a server list on this Server)\n" - " --directoryfile Remember registered Servers even if the Directory is restarted. Directory Servers only.\n" - " -f, --listfilter Server list whitelist filter. Format:\n" - " [IP address 1];[IP address 2];[IP address 3]; ...\n" - " -F, --fastupdate use 64 samples frame size mode\n" - " -l, --log enable logging, set file name\n" - " -L, --licence show an agreement window before users can connect\n" - " -m, --htmlstatus enable HTML status file, set file name\n" - " -o, --serverinfo registration info for this Server. Format:\n" - " [name];[city];[country as QLocale ID]\n" - " --serverpublicip public IP address for this Server. Needed when\n" - " registering with a server list hosted\n" - " behind the same NAT\n" - " -P, --delaypan start with delay panning enabled\n" - " -R, --recording sets directory to contain recorded jams\n" - " --norecord disables recording (when enabled by default by -R)\n" - " -s, --server start Server\n" - " --serverbindip IP address the Server will bind to (rather than all)\n" - " -T, --multithreading use multithreading to make better use of\n" - " multi-core CPUs and support more Clients\n" - " -u, --numchannels maximum number of channels\n" - " -w, --welcomemessage welcome message to display on connect\n" - " (string or filename, HTML supported)\n" - " -z, --startminimized start minimizied\n" - "\n" - "Client only:\n" - " -c, --connect connect to given Server address on startup\n" - " -j, --nojackconnect disable auto JACK connections\n" - " -M, --mutestream starts the application in muted state\n" - " --mutemyown mute me in my personal mix (headless only)\n" - " --clientname Client name (window title and JACK client name)\n" - " --ctrlmidich MIDI controller channel to listen\n" - "\n" - "Example: %1 -s --inifile myinifile.ini\n" - "\n" - "For more information and localized help see:\n" - "https://jamulus.io/wiki/Command-Line-Options\n" - ).arg( argv[0] ); - // clang-format on +#ifndef HEADLESS + QMessageBox::critical ( pMainForm, strMainFormName + ": " + QObject::tr ( "Error" ), strError, QObject::tr ( "Ok" ), nullptr ); +#else + qCritical() << "Error: " << strError.toLocal8Bit().data(); +#endif } -bool GetFlagArgument ( char** argv, int& i, QString strShortOpt, QString strLongOpt ) +void CMsgBoxes::ShowWarning ( QString strWarning ) +{ +#ifndef HEADLESS + QMessageBox::warning ( pMainForm, strMainFormName + ": " + QObject::tr ( "Warning" ), strWarning, QObject::tr ( "Ok" ), nullptr ); +#else + qWarning() << "Warning: " << strWarning.toLocal8Bit().data(); +#endif +} + +void CMsgBoxes::ShowInfo ( QString strInfo ) +{ +#ifndef HEADLESS + QMessageBox::information ( pMainForm, strMainFormName + ": " + QObject::tr ( "Information" ), strInfo, QObject::tr ( "Ok" ), nullptr ); +#else + qInfo() << "Info: " << strInfo.toLocal8Bit().data(); +#endif +} + +/******************************************************************************\ +* Command Line Argument Parsing * +\******************************************************************************/ +bool CCommandlineOptions::GetFlagArgument ( int& i, const QString& strShortOpt, const QString& strLongOpt ) { - if ( ( !strShortOpt.compare ( argv[i] ) ) || ( !strLongOpt.compare ( argv[i] ) ) ) + if ( ( !strShortOpt.compare ( appArgv[i] ) ) || ( !strLongOpt.compare ( appArgv[i] ) ) ) { return true; } @@ -1095,17 +1106,17 @@ bool GetFlagArgument ( char** argv, int& i, QString strShortOpt, QString strLong } } -bool GetStringArgument ( int argc, char** argv, int& i, QString strShortOpt, QString strLongOpt, QString& strArg ) +bool CCommandlineOptions::GetStringArgument ( int& i, const QString& strShortOpt, const QString& strLongOpt, QString& strArg ) { - if ( ( !strShortOpt.compare ( argv[i] ) ) || ( !strLongOpt.compare ( argv[i] ) ) ) + if ( ( !strShortOpt.compare ( appArgv[i] ) ) || ( !strLongOpt.compare ( appArgv[i] ) ) ) { - if ( ++i >= argc ) + if ( ++i >= appArgc ) { - qCritical() << qUtf8Printable ( QString ( "%1: '%2' needs a string argument." ).arg ( argv[0] ).arg ( argv[i - 1] ) ); + qCritical() << qUtf8Printable ( QString ( "%1: '%2' needs a string argument." ).arg ( appArgv[0] ).arg ( appArgv[i - 1] ) ); exit ( 1 ); } - strArg = argv[i]; + strArg = appArgv[i]; return true; } @@ -1115,29 +1126,27 @@ bool GetStringArgument ( int argc, char** argv, int& i, QString strShortOpt, QSt } } -bool GetNumericArgument ( int argc, - char** argv, - int& i, - QString strShortOpt, - QString strLongOpt, - double rRangeStart, - double rRangeStop, - double& rValue ) +bool CCommandlineOptions::GetNumericArgument ( int& i, + const QString& strShortOpt, + const QString& strLongOpt, + double rRangeStart, + double rRangeStop, + double& rValue ) { - if ( ( !strShortOpt.compare ( argv[i] ) ) || ( !strLongOpt.compare ( argv[i] ) ) ) + if ( ( !strShortOpt.compare ( appArgv[i] ) ) || ( !strLongOpt.compare ( appArgv[i] ) ) ) { QString errmsg = "%1: '%2' needs a numeric argument from '%3' to '%4'."; - if ( ++i >= argc ) + if ( ++i >= appArgc ) { - qCritical() << qUtf8Printable ( errmsg.arg ( argv[0] ).arg ( argv[i - 1] ).arg ( rRangeStart ).arg ( rRangeStop ) ); + qCritical() << qUtf8Printable ( errmsg.arg ( appArgv[0] ).arg ( appArgv[i - 1] ).arg ( rRangeStart ).arg ( rRangeStop ) ); exit ( 1 ); } char* p; - rValue = strtod ( argv[i], &p ); + rValue = strtod ( appArgv[i], &p ); if ( *p || ( rValue < rRangeStart ) || ( rValue > rRangeStop ) ) { - qCritical() << qUtf8Printable ( errmsg.arg ( argv[0] ).arg ( argv[i - 1] ).arg ( rRangeStart ).arg ( rRangeStop ) ); + qCritical() << qUtf8Printable ( errmsg.arg ( appArgv[0] ).arg ( appArgv[i - 1] ).arg ( rRangeStart ).arg ( rRangeStop ) ); exit ( 1 ); } diff --git a/src/serverdlg.cpp b/src/serverdlg.cpp index f467a2f22b..8b827a8681 100644 --- a/src/serverdlg.cpp +++ b/src/serverdlg.cpp @@ -571,12 +571,10 @@ void CServerDlg::OnStopRecorder() UpdateRecorderStatus ( QString() ); if ( pServer->GetRecorderErrMsg() != QString() ) { - QMessageBox::warning ( this, - APP_NAME, - tr ( "Recorder failed to start. " - "Please check available disk space and permissions and try again. " - "Error: " ) + - pServer->GetRecorderErrMsg() ); + CMsgBoxes::ShowWarning ( tr ( "Recorder failed to start. " + "Please check available disk space and permissions and try again. " + "Error: " ) + + pServer->GetRecorderErrMsg() ); } } diff --git a/src/settings.cpp b/src/settings.cpp index ab9b038dfd..7bb2282809 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -336,11 +336,9 @@ void CClientSettings::ReadSettingsFromXML ( const QDomDocument& IniXMLDocument, if ( !strError.isEmpty() ) { -# ifndef HEADLESS // special case: when settings are loaded no GUI is yet created, therefore // we have to create a warning message box here directly - QMessageBox::warning ( nullptr, APP_NAME, strError ); -# endif + CMsgBoxes::ShowWarning ( strError ); } // sound card channel mapping settings: make sure these settings are @@ -458,14 +456,14 @@ void CClientSettings::ReadSettingsFromXML ( const QDomDocument& IniXMLDocument, // custom directories // clang-format off // TODO compatibility to old version (< 3.6.1) -QString strDirectoryAddress = GetIniSetting ( IniXMLDocument, "client", "centralservaddr", "" ); // clang-format on + QString strDirectoryAddress = GetIniSetting ( IniXMLDocument, "client", "centralservaddr", "" ); for ( iIdx = 0; iIdx < MAX_NUM_SERVER_ADDR_ITEMS; iIdx++ ) { // clang-format off // TODO compatibility to old version (< 3.8.2) -strDirectoryAddress = GetIniSetting ( IniXMLDocument, "client", QString ( "centralservaddr%1" ).arg ( iIdx ), strDirectoryAddress ); // clang-format on + strDirectoryAddress = GetIniSetting ( IniXMLDocument, "client", QString ( "centralservaddr%1" ).arg ( iIdx ), strDirectoryAddress ); vstrDirectoryAddress[iIdx] = GetIniSetting ( IniXMLDocument, "client", QString ( "directoryaddress%1" ).arg ( iIdx ), strDirectoryAddress ); strDirectoryAddress = ""; } @@ -473,17 +471,19 @@ strDirectoryAddress = GetIniSetting ( IniXMLDocument, "client", QString ( "centr // directory type // clang-format off // TODO compatibility to old version (<3.4.7) -// only the case that "centralservaddr" was set in old ini must be considered -if ( !vstrDirectoryAddress[0].isEmpty() && GetFlagIniSet ( IniXMLDocument, "client", "defcentservaddr", bValue ) && !bValue ) -{ - eDirectoryType = AT_CUSTOM; -} + // clang-format on + // only the case that "centralservaddr" was set in old ini must be considered + if ( !vstrDirectoryAddress[0].isEmpty() && GetFlagIniSet ( IniXMLDocument, "client", "defcentservaddr", bValue ) && !bValue ) + { + eDirectoryType = AT_CUSTOM; + } + // clang-format off // TODO compatibility to old version (< 3.8.2) -else if ( GetNumericIniSet ( IniXMLDocument, "client", "centservaddrtype", 0, static_cast ( AT_CUSTOM ), iValue ) ) -{ - eDirectoryType = static_cast ( iValue ); -} // clang-format on + else if ( GetNumericIniSet ( IniXMLDocument, "client", "centservaddrtype", 0, static_cast ( AT_CUSTOM ), iValue ) ) + { + eDirectoryType = static_cast ( iValue ); + } else if ( GetNumericIniSet ( IniXMLDocument, "client", "directorytype", 0, static_cast ( AT_CUSTOM ), iValue ) ) { eDirectoryType = static_cast ( iValue ); @@ -822,7 +822,7 @@ void CServerSettings::ReadSettingsFromXML ( const QDomDocument& IniXMLDocument, QString directoryAddress = ""; // clang-format off // TODO compatibility to old version < 3.8.2 -directoryAddress = GetIniSetting ( IniXMLDocument, "server", "centralservaddr", directoryAddress ); +// directoryAddress = GetIniSetting ( IniXMLDocument, "server", "centralservaddr", directoryAddress ); // clang-format on directoryAddress = GetIniSetting ( IniXMLDocument, "server", "directoryaddress", directoryAddress ); @@ -843,40 +843,42 @@ directoryAddress = GetIniSetting ( IniXMLDocument, "server", "centralservaddr", { // clang-format off // TODO compatibility to old version < 3.4.7 -if ( GetFlagIniSet ( IniXMLDocument, "server", "defcentservaddr", bValue ) ) -{ - directoryType = bValue ? AT_DEFAULT : AT_CUSTOM; -} -else - // clang-format on - - // if "directorytype" itself is set, use it (note "AT_NONE", "AT_DEFAULT" and "AT_CUSTOM" are min/max directory type here) - // clang-format off + // clang-format on + if ( GetFlagIniSet ( IniXMLDocument, "server", "defcentservaddr", bValue ) ) + { + directoryType = bValue ? AT_DEFAULT : AT_CUSTOM; + } + // if "directorytype" itself is set, use it (note "AT_NONE", "AT_DEFAULT" and "AT_CUSTOM" are min/max directory type here) + // clang-format off // TODO compatibility to old version < 3.8.2 -if ( GetNumericIniSet ( IniXMLDocument, "server", "centservaddrtype", static_cast ( AT_DEFAULT ), static_cast ( AT_CUSTOM ), iValue ) ) -{ - directoryType = static_cast ( iValue ); -} -else - // clang-format on - if ( GetNumericIniSet ( IniXMLDocument, - "server", - "directorytype", - static_cast ( AT_NONE ), - static_cast ( AT_CUSTOM ), - iValue ) ) + // clang-format on + else if ( GetNumericIniSet ( IniXMLDocument, + "server", + "centservaddrtype", + static_cast ( AT_DEFAULT ), + static_cast ( AT_CUSTOM ), + iValue ) ) + { + directoryType = static_cast ( iValue ); + } + else if ( GetNumericIniSet ( IniXMLDocument, + "server", + "directorytype", + static_cast ( AT_NONE ), + static_cast ( AT_CUSTOM ), + iValue ) ) { directoryType = static_cast ( iValue ); } // clang-format off // TODO compatibility to old version < 3.9.0 -// override type to AT_NONE if servlistenabled exists and is false -if ( GetFlagIniSet ( IniXMLDocument, "server", "servlistenabled", bValue ) && !bValue ) -{ - directoryType = AT_NONE; -} // clang-format on + // override type to AT_NONE if servlistenabled exists and is false + if ( GetFlagIniSet ( IniXMLDocument, "server", "servlistenabled", bValue ) && !bValue ) + { + directoryType = AT_NONE; + } } pServer->SetDirectoryType ( directoryType ); diff --git a/src/soundbase.cpp b/src/soundbase.cpp index 3e8f2c2b21..c62895b5cf 100644 --- a/src/soundbase.cpp +++ b/src/soundbase.cpp @@ -182,7 +182,8 @@ QString CSoundBase::SetDev ( const QString strDevName ) // ASIO drivers sErrorMessage += "
" + tr ( "Do you want to open the ASIO driver setup to try changing your configuration to a working state?" ); - if ( QMessageBox::Yes == QMessageBox::information ( nullptr, APP_NAME, sErrorMessage, QMessageBox::Yes | QMessageBox::No ) ) + if ( QMessageBox::Yes == + QMessageBox::information ( CMsgBoxes::MainForm(), CMsgBoxes::MainFormName(), sErrorMessage, QMessageBox::Yes | QMessageBox::No ) ) { LoadAndInitializeFirstValidDriver ( true ); } diff --git a/src/util.cpp b/src/util.cpp index d2f7d6f78b..37faa9c537 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -495,6 +495,7 @@ CAboutDlg::CAboutDlg ( QWidget* parent ) : CBaseDlg ( parent ) "

RobyDati (RobyDati)

" "

Rob-NY (Rob-NY)

" "

Thai Pangsakulyanont (dtinth)

" + "

Peter Goderie (pgScorpio)

" "
" + tr ( "For details on the contributions check out the %1" ) .arg ( "" + tr ( "Github Contributors list" ) + "." ) ); @@ -666,7 +667,9 @@ void CLanguageComboBox::OnLanguageActivated ( int iLanguageIdx ) // only update if the language selection is different from the current selected language if ( iIdxSelectedLanguage != iLanguageIdx ) { - QMessageBox::information ( this, tr ( "Restart Required" ), tr ( "Please restart the application for the language change to take effect." ) ); + QMessageBox::information ( CMsgBoxes::MainForm(), + CMsgBoxes::MainFormName() + ": " + tr ( "Restart Required" ), + tr ( "Please restart the application for the language change to take effect." ) ); emit LanguageChanged ( itemData ( iLanguageIdx ).toString() ); } diff --git a/src/util.h b/src/util.h index 4a546781c9..72b32ff828 100644 --- a/src/util.h +++ b/src/util.h @@ -421,7 +421,7 @@ class CHelpMenu : public QMenu public slots: void OnHelpWhatsThis() { QWhatsThis::enterWhatsThisMode(); } void OnHelpAbout() { AboutDlg.exec(); } - void OnHelpAboutQt() { QMessageBox::aboutQt ( nullptr, QString ( tr ( "About Qt" ) ) ); } + void OnHelpAboutQt() { QMessageBox::aboutQt ( CMsgBoxes::MainForm(), QString ( tr ( "About Qt" ) ) ); } void OnHelpClientGetStarted() { QDesktopServices::openUrl ( QUrl ( CLIENT_GETTING_STARTED_URL ) ); } void OnHelpServerGetStarted() { QDesktopServices::openUrl ( QUrl ( SERVER_GETTING_STARTED_URL ) ); } void OnHelpSoftwareMan() { QDesktopServices::openUrl ( QUrl ( SOFTWARE_MANUAL_URL ) ); } diff --git a/windows/sound.cpp b/windows/sound.cpp index 58ad034e8a..72f9fcd139 100644 --- a/windows/sound.cpp +++ b/windows/sound.cpp @@ -101,8 +101,8 @@ QString CSound::LoadAndInitializeDriver ( QString strDriverName, bool bOpenDrive if ( bOpenDriverSetup ) { OpenDriverSetup(); - QMessageBox::question ( nullptr, - APP_NAME, + QMessageBox::question ( CMsgBoxes::MainForm(), + CMsgBoxes::MainFormName(), "Are you done with your ASIO driver settings of " + GetDeviceName ( iDriverIdx ) + "?", QMessageBox::Yes ); } @@ -314,9 +314,8 @@ int CSound::GetActualBufferSize ( const int iDesiredBufferSizeMono ) // clang-format off /* // TEST -#include -QMessageBox::information ( 0, "APP_NAME", QString("lMinSize: %1, lMaxSize: %2, lPreferredSize: %3, lGranularity: %4"). - arg(HWBufferInfo.lMinSize).arg(HWBufferInfo.lMaxSize).arg(HWBufferInfo.lPreferredSize).arg(HWBufferInfo.lGranularity) ); +CMsgBoxes::ShowInfo( QString("lMinSize: %1, lMaxSize: %2, lPreferredSize: %3, lGranularity: %4"). + arg(HWBufferInfo.lMinSize).arg(HWBufferInfo.lMaxSize).arg(HWBufferInfo.lPreferredSize).arg(HWBufferInfo.lGranularity) ); _exit(1); */ // clang-format on