/[svn]/qsampler/trunk/src/qsamplerMainForm.cpp
ViewVC logotype

Diff of /qsampler/trunk/src/qsamplerMainForm.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3357 by capela, Tue Oct 17 21:44:20 2017 UTC revision 3759 by capela, Sat Mar 28 00:28:13 2020 UTC
# Line 1  Line 1 
1  // qsamplerMainForm.cpp  // qsamplerMainForm.cpp
2  //  //
3  /****************************************************************************  /****************************************************************************
4     Copyright (C) 2004-2017, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2020, rncbc aka Rui Nuno Capela. All rights reserved.
5     Copyright (C) 2007,2008,2015 Christian Schoenebeck     Copyright (C) 2007-2019 Christian Schoenebeck
6    
7     This program is free software; you can redistribute it and/or     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License     modify it under the terms of the GNU General Public License
# Line 58  Line 58 
58  #include <QTimer>  #include <QTimer>
59  #include <QDateTime>  #include <QDateTime>
60    
61  #if QT_VERSION >= 0x050000  #include <QElapsedTimer>
62    
63    #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
64  #include <QMimeData>  #include <QMimeData>
65  #endif  #endif
66    
67  #if QT_VERSION < 0x040500  #if QT_VERSION < QT_VERSION_CHECK(4, 5, 0)
68  namespace Qt {  namespace Qt {
69  const WindowFlags WindowCloseButtonHint = WindowFlags(0x08000000);  const WindowFlags WindowCloseButtonHint = WindowFlags(0x08000000);
70  }  }
71  #endif  #endif
72    
73  #ifdef HAVE_SIGNAL_H  // Deprecated QTextStreamFunctions/Qt namespaces workaround.
74  #include <signal.h>  #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
75    #define endl    Qt::endl
76  #endif  #endif
77    
78    
79  #ifdef CONFIG_LIBGIG  #ifdef CONFIG_LIBGIG
80  #include <gig.h>  #include <gig.h>
81  #endif  #endif
# Line 91  static inline long lroundf ( float x ) Line 95  static inline long lroundf ( float x )
95    
96    
97  // All winsock apps needs this.  // All winsock apps needs this.
98  #if defined(_WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
99  static WSADATA _wsaData;  static WSADATA _wsaData;
100    #undef HAVE_SIGNAL_H
101  #endif  #endif
102    
103    
# Line 103  static WSADATA _wsaData; Line 108  static WSADATA _wsaData;
108    
109  #include <QSocketNotifier>  #include <QSocketNotifier>
110    
111    #include <unistd.h>
112  #include <sys/types.h>  #include <sys/types.h>
113  #include <sys/socket.h>  #include <sys/socket.h>
   
114  #include <signal.h>  #include <signal.h>
115    
116  // File descriptor for SIGUSR1 notifier.  // File descriptor for SIGUSR1 notifier.
117  static int g_fdUsr1[2];  static int g_fdSigusr1[2] = { -1, -1 };
118    
119  // Unix SIGUSR1 signal handler.  // Unix SIGUSR1 signal handler.
120  static void qsampler_sigusr1_handler ( int /* signo */ )  static void qsampler_sigusr1_handler ( int /* signo */ )
121  {  {
122          char c = 1;          char c = 1;
123    
124          (::write(g_fdUsr1[0], &c, sizeof(c)) > 0);          (::write(g_fdSigusr1[0], &c, sizeof(c)) > 0);
125    }
126    
127    // File descriptor for SIGTERM notifier.
128    static int g_fdSigterm[2] = { -1, -1 };
129    
130    // Unix SIGTERM signal handler.
131    static void qsampler_sigterm_handler ( int /* signo */ )
132    {
133            char c = 1;
134    
135            (::write(g_fdSigterm[0], &c, sizeof(c)) > 0);
136  }  }
137    
138  #endif  // HAVE_SIGNAL_H  #endif  // HAVE_SIGNAL_H
# Line 194  protected: Line 210  protected:
210  // QSampler::MainForm -- Main window form implementation.  // QSampler::MainForm -- Main window form implementation.
211    
212  // Kind of singleton reference.  // Kind of singleton reference.
213  MainForm *MainForm::g_pMainForm = NULL;  MainForm *MainForm::g_pMainForm = nullptr;
214    
215  MainForm::MainForm ( QWidget *pParent )  MainForm::MainForm ( QWidget *pParent )
216          : QMainWindow(pParent)          : QMainWindow(pParent)
# Line 205  MainForm::MainForm ( QWidget *pParent ) Line 221  MainForm::MainForm ( QWidget *pParent )
221          g_pMainForm = this;          g_pMainForm = this;
222    
223          // Initialize some pointer references.          // Initialize some pointer references.
224          m_pOptions = NULL;          m_pOptions = nullptr;
225    
226          // All child forms are to be created later, not earlier than setup.          // All child forms are to be created later, not earlier than setup.
227          m_pMessages = NULL;          m_pMessages = nullptr;
228          m_pInstrumentListForm = NULL;          m_pInstrumentListForm = nullptr;
229          m_pDeviceForm = NULL;          m_pDeviceForm = nullptr;
230    
231          // We'll start clean.          // We'll start clean.
232          m_iUntitled   = 0;          m_iUntitled   = 0;
233          m_iDirtySetup = 0;          m_iDirtySetup = 0;
234          m_iDirtyCount = 0;          m_iDirtyCount = 0;
235    
236          m_pServer = NULL;          m_pServer = nullptr;
237          m_pClient = NULL;          m_pClient = nullptr;
238    
239          m_iStartDelay = 0;          m_iStartDelay = 0;
240          m_iTimerDelay = 0;          m_iTimerDelay = 0;
# Line 233  MainForm::MainForm ( QWidget *pParent ) Line 249  MainForm::MainForm ( QWidget *pParent )
249          // LADISH Level 1 suport.          // LADISH Level 1 suport.
250    
251          // Initialize file descriptors for SIGUSR1 socket notifier.          // Initialize file descriptors for SIGUSR1 socket notifier.
252          ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdUsr1);          ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigusr1);
253          m_pUsr1Notifier          m_pSigusr1Notifier
254                  = new QSocketNotifier(g_fdUsr1[1], QSocketNotifier::Read, this);                  = new QSocketNotifier(g_fdSigusr1[1], QSocketNotifier::Read, this);
255    
256          QObject::connect(m_pUsr1Notifier,          QObject::connect(m_pSigusr1Notifier,
257                  SIGNAL(activated(int)),                  SIGNAL(activated(int)),
258                  SLOT(handle_sigusr1()));                  SLOT(handle_sigusr1()));
259    
260          // Install SIGUSR1 signal handler.          // Install SIGUSR1 signal handler.
261      struct sigaction usr1;          struct sigaction sigusr1;
262      usr1.sa_handler = qsampler_sigusr1_handler;          sigusr1.sa_handler = qsampler_sigusr1_handler;
263      sigemptyset(&usr1.sa_mask);          sigemptyset(&sigusr1.sa_mask);
264      usr1.sa_flags = 0;          sigusr1.sa_flags = 0;
265      usr1.sa_flags |= SA_RESTART;          sigusr1.sa_flags |= SA_RESTART;
266      ::sigaction(SIGUSR1, &usr1, NULL);          ::sigaction(SIGUSR1, &sigusr1, nullptr);
267    
268            // Initialize file descriptors for SIGTERM socket notifier.
269            ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigterm);
270            m_pSigtermNotifier
271                    = new QSocketNotifier(g_fdSigterm[1], QSocketNotifier::Read, this);
272    
273            QObject::connect(m_pSigtermNotifier,
274                    SIGNAL(activated(int)),
275                    SLOT(handle_sigterm()));
276    
277            // Install SIGTERM signal handler.
278            struct sigaction sigterm;
279            sigterm.sa_handler = qsampler_sigterm_handler;
280            sigemptyset(&sigterm.sa_mask);
281            sigterm.sa_flags = 0;
282            sigterm.sa_flags |= SA_RESTART;
283            ::sigaction(SIGTERM, &sigterm, nullptr);
284            ::sigaction(SIGQUIT, &sigterm, nullptr);
285    
286            // Ignore SIGHUP/SIGINT signals.
287            ::signal(SIGHUP, SIG_IGN);
288            ::signal(SIGINT, SIG_IGN);
289    
290  #else   // HAVE_SIGNAL_H  #else   // HAVE_SIGNAL_H
291    
292          m_pUsr1Notifier = NULL;          m_pSigusr1Notifier = nullptr;
293            m_pSigtermNotifier = nullptr;
294                    
295  #endif  // !HAVE_SIGNAL_H  #endif  // !HAVE_SIGNAL_H
296    
# Line 324  MainForm::MainForm ( QWidget *pParent ) Line 363  MainForm::MainForm ( QWidget *pParent )
363          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
364          statusBar()->addWidget(pLabel);          statusBar()->addWidget(pLabel);
365    
366  #if defined(_WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
367          WSAStartup(MAKEWORD(1, 1), &_wsaData);          WSAStartup(MAKEWORD(1, 1), &_wsaData);
368  #endif  #endif
369    
# Line 425  MainForm::~MainForm() Line 464  MainForm::~MainForm()
464          // Do final processing anyway.          // Do final processing anyway.
465          processServerExit();          processServerExit();
466    
467  #if defined(_WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
468          WSACleanup();          WSACleanup();
469  #endif  #endif
470    
471  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
472          if (m_pUsr1Notifier)          if (m_pSigusr1Notifier)
473                  delete m_pUsr1Notifier;                  delete m_pSigusr1Notifier;
474            if (m_pSigtermNotifier)
475                    delete m_pSigtermNotifier;
476  #endif  #endif
477    
478          // Finally drop any widgets around...          // Finally drop any widgets around...
# Line 460  MainForm::~MainForm() Line 501  MainForm::~MainForm()
501  #endif  #endif
502    
503          // Pseudo-singleton reference shut-down.          // Pseudo-singleton reference shut-down.
504          g_pMainForm = NULL;          g_pMainForm = nullptr;
505  }  }
506    
507    
# Line 597  void MainForm::closeEvent ( QCloseEvent Line 638  void MainForm::closeEvent ( QCloseEvent
638  void MainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )  void MainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
639  {  {
640          // Accept external drags only...          // Accept external drags only...
641          if (pDragEnterEvent->source() == NULL          if (pDragEnterEvent->source() == nullptr
642                  && pDragEnterEvent->mimeData()->hasUrls()) {                  && pDragEnterEvent->mimeData()->hasUrls()) {
643                  pDragEnterEvent->accept();                  pDragEnterEvent->accept();
644          } else {          } else {
# Line 621  void MainForm::dropEvent ( QDropEvent *p Line 662  void MainForm::dropEvent ( QDropEvent *p
662                          if (QFileInfo(sPath).exists()) {                          if (QFileInfo(sPath).exists()) {
663                                  // Try to create a new channel from instrument file...                                  // Try to create a new channel from instrument file...
664                                  Channel *pChannel = new Channel();                                  Channel *pChannel = new Channel();
665                                  if (pChannel == NULL)                                  if (pChannel == nullptr)
666                                          return;                                          return;
667                                  // Start setting the instrument filename...                                  // Start setting the instrument filename...
668                                  pChannel->setInstrument(sPath, 0);                                  pChannel->setInstrument(sPath, 0);
# Line 721  void MainForm::handle_sigusr1 (void) Line 762  void MainForm::handle_sigusr1 (void)
762    
763          char c;          char c;
764    
765          if (::read(g_fdUsr1[1], &c, sizeof(c)) > 0)          if (::read(g_fdSigusr1[1], &c, sizeof(c)) > 0)
766                  saveSession(false);                  saveSession(false);
767    
768  #endif  #endif
769  }  }
770    
771    
772    void MainForm::handle_sigterm (void)
773    {
774    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
775    
776            char c;
777    
778            if (::read(g_fdSigterm[1], &c, sizeof(c)) > 0)
779                    close();
780    
781    #endif
782    }
783    
784    
785  void MainForm::updateViewMidiDeviceStatusMenu (void)  void MainForm::updateViewMidiDeviceStatusMenu (void)
786  {  {
787          m_ui.viewMidiDeviceStatusMenu->clear();          m_ui.viewMidiDeviceStatusMenu->clear();
# Line 806  bool MainForm::newSession (void) Line 860  bool MainForm::newSession (void)
860          m_iUntitled++;          m_iUntitled++;
861    
862          // Stabilize form.          // Stabilize form.
863          m_sFilename = QString::null;          m_sFilename = QString();
864          m_iDirtyCount = 0;          m_iDirtyCount = 0;
865          appendMessages(tr("New session: \"%1\".").arg(sessionName(m_sFilename)));          appendMessages(tr("New session: \"%1\".").arg(sessionName(m_sFilename)));
866          stabilizeForm();          stabilizeForm();
# Line 818  bool MainForm::newSession (void) Line 872  bool MainForm::newSession (void)
872  // Open an existing sampler session.  // Open an existing sampler session.
873  bool MainForm::openSession (void)  bool MainForm::openSession (void)
874  {  {
875          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
876                  return false;                  return false;
877    
878          // Ask for the filename to open...          // Ask for the filename to open...
879          QString sFilename = QFileDialog::getOpenFileName(this,          QString sFilename = QFileDialog::getOpenFileName(this,
880                  QSAMPLER_TITLE ": " + tr("Open Session"), // Caption.                  tr("Open Session"),                       // Caption.
881                  m_pOptions->sSessionDir,                  // Start here.                  m_pOptions->sSessionDir,                  // Start here.
882                  tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)                  tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)
883          );          );
# Line 844  bool MainForm::openSession (void) Line 898  bool MainForm::openSession (void)
898  // Save current sampler session with another name.  // Save current sampler session with another name.
899  bool MainForm::saveSession ( bool bPrompt )  bool MainForm::saveSession ( bool bPrompt )
900  {  {
901          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
902                  return false;                  return false;
903    
904          QString sFilename = m_sFilename;          QString sFilename = m_sFilename;
# Line 856  bool MainForm::saveSession ( bool bPromp Line 910  bool MainForm::saveSession ( bool bPromp
910                          sFilename = m_pOptions->sSessionDir;                          sFilename = m_pOptions->sSessionDir;
911                  // Prompt the guy...                  // Prompt the guy...
912                  sFilename = QFileDialog::getSaveFileName(this,                  sFilename = QFileDialog::getSaveFileName(this,
913                          QSAMPLER_TITLE ": " + tr("Save Session"), // Caption.                          tr("Save Session"),                       // Caption.
914                          sFilename,                                // Start here.                          sFilename,                                // Start here.
915                          tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)                          tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)
916                  );                  );
# Line 866  bool MainForm::saveSession ( bool bPromp Line 920  bool MainForm::saveSession ( bool bPromp
920                  // Enforce .lscp extension...                  // Enforce .lscp extension...
921                  if (QFileInfo(sFilename).suffix().isEmpty())                  if (QFileInfo(sFilename).suffix().isEmpty())
922                          sFilename += ".lscp";                          sFilename += ".lscp";
923            #if 0
924                  // Check if already exists...                  // Check if already exists...
925                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
926                          if (QMessageBox::warning(this,                          if (QMessageBox::warning(this,
927                                  QSAMPLER_TITLE ": " + tr("Warning"),                                  tr("Warning"),
928                                  tr("The file already exists:\n\n"                                  tr("The file already exists:\n\n"
929                                  "\"%1\"\n\n"                                  "\"%1\"\n\n"
930                                  "Do you want to replace it?")                                  "Do you want to replace it?")
# Line 878  bool MainForm::saveSession ( bool bPromp Line 933  bool MainForm::saveSession ( bool bPromp
933                                  == QMessageBox::No)                                  == QMessageBox::No)
934                                  return false;                                  return false;
935                  }                  }
936            #endif
937          }          }
938    
939          // Save it right away.          // Save it right away.
# Line 893  bool MainForm::closeSession ( bool bForc Line 949  bool MainForm::closeSession ( bool bForc
949          // Are we dirty enough to prompt it?          // Are we dirty enough to prompt it?
950          if (m_iDirtyCount > 0) {          if (m_iDirtyCount > 0) {
951                  switch (QMessageBox::warning(this,                  switch (QMessageBox::warning(this,
952                          QSAMPLER_TITLE ": " + tr("Warning"),                          tr("Warning"),
953                          tr("The current session has been changed:\n\n"                          tr("The current session has been changed:\n\n"
954                          "\"%1\"\n\n"                          "\"%1\"\n\n"
955                          "Do you want to save the changes?")                          "Do you want to save the changes?")
# Line 918  bool MainForm::closeSession ( bool bForc Line 974  bool MainForm::closeSession ( bool bForc
974                  m_pWorkspace->setUpdatesEnabled(false);                  m_pWorkspace->setUpdatesEnabled(false);
975                  const QList<QMdiSubWindow *>& wlist                  const QList<QMdiSubWindow *>& wlist
976                          = m_pWorkspace->subWindowList();                          = m_pWorkspace->subWindowList();
977                  const int iStripCount = wlist.count();                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
978                  for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                          ChannelStrip *pChannelStrip
979                          ChannelStrip *pChannelStrip = NULL;                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                         QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                         if (pMdiSubWindow)  
                                 pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
980                          if (pChannelStrip) {                          if (pChannelStrip) {
981                                  Channel *pChannel = pChannelStrip->channel();                                  Channel *pChannel = pChannelStrip->channel();
982                                  if (bForce && pChannel)                                  if (bForce && pChannel)
983                                          pChannel->removeChannel();                                          pChannel->removeChannel();
984                                  delete pChannelStrip;                                  delete pChannelStrip;
985                          }                          }
986                          if (pMdiSubWindow)                          delete pMdiSubWindow;
                                 delete pMdiSubWindow;  
987                  }                  }
988                  m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
989                  // We're now clean, for sure.                  // We're now clean, for sure.
# Line 945  bool MainForm::closeSession ( bool bForc Line 997  bool MainForm::closeSession ( bool bForc
997  // Load a session from specific file path.  // Load a session from specific file path.
998  bool MainForm::loadSessionFile ( const QString& sFilename )  bool MainForm::loadSessionFile ( const QString& sFilename )
999  {  {
1000          if (m_pClient == NULL)          if (m_pClient == nullptr)
1001                  return false;                  return false;
1002    
1003          // Open and read from real file.          // Open and read from real file.
# Line 1021  bool MainForm::loadSessionFile ( const Q Line 1073  bool MainForm::loadSessionFile ( const Q
1073  // Save current session to specific file path.  // Save current session to specific file path.
1074  bool MainForm::saveSessionFile ( const QString& sFilename )  bool MainForm::saveSessionFile ( const QString& sFilename )
1075  {  {
1076          if (m_pClient == NULL)          if (m_pClient == nullptr)
1077                  return false;                  return false;
1078    
1079          // Check whether server is apparently OK...          // Check whether server is apparently OK...
# Line 1060  bool MainForm::saveSessionFile ( const Q Line 1112  bool MainForm::saveSessionFile ( const Q
1112          // It is assumed that this new kind of device+session file          // It is assumed that this new kind of device+session file
1113          // will be loaded from a complete initialized server...          // will be loaded from a complete initialized server...
1114          int *piDeviceIDs;          int *piDeviceIDs;
1115          int  iDevice;          int  i, iDevice;
1116          ts << "RESET" << endl;          ts << "RESET" << endl;
1117    
1118          // Audio device mapping.          // Audio device mapping.
1119          QMap<int, int> audioDeviceMap;          QMap<int, int> audioDeviceMap; iDevice = 0;
1120          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);
1121          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1122                  ts << endl;                  Device device(Device::Audio, piDeviceIDs[i]);
1123                  Device device(Device::Audio, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1124                    if (device.driverName().toUpper() == "PLUGIN")
1125                            continue;
1126                  // Audio device specification...                  // Audio device specification...
1127                    ts << endl;
1128                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1129                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1130                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
# Line 1100  bool MainForm::saveSessionFile ( const Q Line 1155  bool MainForm::saveSessionFile ( const Q
1155                          iPort++;                          iPort++;
1156                  }                  }
1157                  // Audio device index/id mapping.                  // Audio device index/id mapping.
1158                  audioDeviceMap[device.deviceID()] = iDevice;                  audioDeviceMap.insert(device.deviceID(), iDevice++);
1159                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1160                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1161          }          }
1162    
1163          // MIDI device mapping.          // MIDI device mapping.
1164          QMap<int, int> midiDeviceMap;          QMap<int, int> midiDeviceMap; iDevice = 0;
1165          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);
1166          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1167                  ts << endl;                  Device device(Device::Midi, piDeviceIDs[i]);
1168                  Device device(Device::Midi, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1169                    if (device.driverName().toUpper() == "PLUGIN")
1170                            continue;
1171                  // MIDI device specification...                  // MIDI device specification...
1172                    ts << endl;
1173                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1174                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1175                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
# Line 1142  bool MainForm::saveSessionFile ( const Q Line 1200  bool MainForm::saveSessionFile ( const Q
1200                          iPort++;                          iPort++;
1201                  }                  }
1202                  // MIDI device index/id mapping.                  // MIDI device index/id mapping.
1203                  midiDeviceMap[device.deviceID()] = iDevice;                  midiDeviceMap.insert(device.deviceID(), iDevice++);
1204                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1205                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1206          }          }
# Line 1205  bool MainForm::saveSessionFile ( const Q Line 1263  bool MainForm::saveSessionFile ( const Q
1263                  }                  }
1264                  ts << endl;                  ts << endl;
1265                  // Check for errors...                  // Check for errors...
1266                  if (pInstrs == NULL && ::lscp_client_get_errno(m_pClient)) {                  if (pInstrs == nullptr && ::lscp_client_get_errno(m_pClient)) {
1267                          appendMessagesClient("lscp_list_midi_instruments");                          appendMessagesClient("lscp_list_midi_instruments");
1268                          iErrors++;                          iErrors++;
1269                  }                  }
1270                  // MIDI strument index/id mapping.                  // MIDI strument index/id mapping.
1271                  midiInstrumentMap[iMidiMap] = iMap;                  midiInstrumentMap.insert(iMidiMap, iMap);
1272          }          }
1273          // Check for errors...          // Check for errors...
1274          if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {          if (piMaps == nullptr && ::lscp_client_get_errno(m_pClient)) {
1275                  appendMessagesClient("lscp_list_midi_instrument_maps");                  appendMessagesClient("lscp_list_midi_instrument_maps");
1276                  iErrors++;                  iErrors++;
1277          }          }
1278  #endif  // CONFIG_MIDI_INSTRUMENT  #endif  // CONFIG_MIDI_INSTRUMENT
1279    
1280          // Sampler channel mapping.          // Sampler channel mapping...
1281            int iChannelID = 0;
1282          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
1283                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
1284          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
1285          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
1286                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
1287                  if (pChannelStrip) {                  if (pChannelStrip) {
1288                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1289                          if (pChannel) {                          if (pChannel) {
1290                                  const int iChannelID = pChannel->channelID();                                  // Avoid "artifial" plug-in devices...
1291                                    const int iAudioDevice = pChannel->audioDevice();
1292                                    if (!audioDeviceMap.contains(iAudioDevice))
1293                                            continue;
1294                                    const int iMidiDevice = pChannel->midiDevice();
1295                                    if (!midiDeviceMap.contains(iMidiDevice))
1296                                            continue;
1297                                    // Go for regular, canonical devices...
1298                                  ts << "# " << tr("Channel") << " " << iChannelID << endl;                                  ts << "# " << tr("Channel") << " " << iChannelID << endl;
1299                                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
1300                                  if (audioDeviceMap.isEmpty()) {                                  if (audioDeviceMap.isEmpty()) {
# Line 1239  bool MainForm::saveSessionFile ( const Q Line 1302  bool MainForm::saveSessionFile ( const Q
1302                                                  << " " << pChannel->audioDriver() << endl;                                                  << " " << pChannel->audioDriver() << endl;
1303                                  } else {                                  } else {
1304                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannelID                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannelID
1305                                                  << " " << audioDeviceMap[pChannel->audioDevice()] << endl;                                                  << " " << audioDeviceMap.value(iAudioDevice) << endl;
1306                                  }                                  }
1307                                  if (midiDeviceMap.isEmpty()) {                                  if (midiDeviceMap.isEmpty()) {
1308                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID
1309                                                  << " " << pChannel->midiDriver() << endl;                                                  << " " << pChannel->midiDriver() << endl;
1310                                  } else {                                  } else {
1311                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannelID                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannelID
1312                                                  << " " << midiDeviceMap[pChannel->midiDevice()] << endl;                                                  << " " << midiDeviceMap.value(iMidiDevice) << endl;
1313                                  }                                  }
1314                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID
1315                                          << " " << pChannel->midiPort() << endl;                                          << " " << pChannel->midiPort() << endl;
# Line 1277  bool MainForm::saveSessionFile ( const Q Line 1340  bool MainForm::saveSessionFile ( const Q
1340                                  if (pChannel->channelSolo())                                  if (pChannel->channelSolo())
1341                                          ts << "SET CHANNEL SOLO " << iChannelID << " 1" << endl;                                          ts << "SET CHANNEL SOLO " << iChannelID << " 1" << endl;
1342                          #ifdef CONFIG_MIDI_INSTRUMENT                          #ifdef CONFIG_MIDI_INSTRUMENT
1343                                  if (pChannel->midiMap() >= 0) {                                  const int iMidiMap = pChannel->midiMap();
1344                                    if (midiInstrumentMap.contains(iMidiMap)) {
1345                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannelID                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannelID
1346                                                  << " " << midiInstrumentMap[pChannel->midiMap()] << endl;                                                  << " " << midiInstrumentMap.value(iMidiMap) << endl;
1347                                  }                                  }
1348                          #endif                          #endif
1349                          #ifdef CONFIG_FXSEND                          #ifdef CONFIG_FXSEND
# Line 1318  bool MainForm::saveSessionFile ( const Q Line 1382  bool MainForm::saveSessionFile ( const Q
1382                                  }                                  }
1383                          #endif                          #endif
1384                                  ts << endl;                                  ts << endl;
1385                                    // Go for next channel...
1386                                    ++iChannelID;
1387                          }                          }
1388                  }                  }
1389                  // Try to keep it snappy :)                  // Try to keep it snappy :)
# Line 1423  void MainForm::fileSaveAs (void) Line 1489  void MainForm::fileSaveAs (void)
1489  // Reset the sampler instance.  // Reset the sampler instance.
1490  void MainForm::fileReset (void)  void MainForm::fileReset (void)
1491  {  {
1492          if (m_pClient == NULL)          if (m_pClient == nullptr)
1493                  return;                  return;
1494    
1495          // Ask user whether he/she want's an internal sampler reset...          // Ask user whether he/she want's an internal sampler reset...
1496          if (m_pOptions && m_pOptions->bConfirmReset) {          if (m_pOptions && m_pOptions->bConfirmReset) {
1497                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");                  const QString& sTitle = tr("Warning");
1498                  const QString& sText = tr(                  const QString& sText = tr(
1499                          "Resetting the sampler instance will close\n"                          "Resetting the sampler instance will close\n"
1500                          "all device and channel configurations.\n\n"                          "all device and channel configurations.\n\n"
# Line 1479  void MainForm::fileReset (void) Line 1545  void MainForm::fileReset (void)
1545  // Restart the client/server instance.  // Restart the client/server instance.
1546  void MainForm::fileRestart (void)  void MainForm::fileRestart (void)
1547  {  {
1548          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1549                  return;                  return;
1550    
1551          bool bRestart = true;          bool bRestart = true;
# Line 1487  void MainForm::fileRestart (void) Line 1553  void MainForm::fileRestart (void)
1553          // Ask user whether he/she want's a complete restart...          // Ask user whether he/she want's a complete restart...
1554          // (if we're currently up and running)          // (if we're currently up and running)
1555          if (m_pOptions && m_pOptions->bConfirmRestart) {          if (m_pOptions && m_pOptions->bConfirmRestart) {
1556                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");                  const QString& sTitle = tr("Warning");
1557                  const QString& sText = tr(                  const QString& sText = tr(
1558                          "New settings will be effective after\n"                          "New settings will be effective after\n"
1559                          "restarting the client/server connection.\n\n"                          "restarting the client/server connection.\n\n"
# Line 1547  void MainForm::editAddChannel (void) Line 1613  void MainForm::editAddChannel (void)
1613    
1614  void MainForm::addChannelStrip (void)  void MainForm::addChannelStrip (void)
1615  {  {
1616          if (m_pClient == NULL)          if (m_pClient == nullptr)
1617                  return;                  return;
1618    
1619          // Just create the channel instance...          // Just create the channel instance...
1620          Channel *pChannel = new Channel();          Channel *pChannel = new Channel();
1621          if (pChannel == NULL)          if (pChannel == nullptr)
1622                  return;                  return;
1623    
1624          // Before we show it up, may be we'll          // Before we show it up, may be we'll
# Line 1588  void MainForm::editRemoveChannel (void) Line 1654  void MainForm::editRemoveChannel (void)
1654    
1655  void MainForm::removeChannelStrip (void)  void MainForm::removeChannelStrip (void)
1656  {  {
1657          if (m_pClient == NULL)          if (m_pClient == nullptr)
1658                  return;                  return;
1659    
1660          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1661          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1662                  return;                  return;
1663    
1664          Channel *pChannel = pChannelStrip->channel();          Channel *pChannel = pChannelStrip->channel();
1665          if (pChannel == NULL)          if (pChannel == nullptr)
1666                  return;                  return;
1667    
1668          // Prompt user if he/she's sure about this...          // Prompt user if he/she's sure about this...
1669          if (m_pOptions && m_pOptions->bConfirmRemove) {          if (m_pOptions && m_pOptions->bConfirmRemove) {
1670                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");                  const QString& sTitle = tr("Warning");
1671                  const QString& sText = tr(                  const QString& sText = tr(
1672                          "About to remove channel:\n\n"                          "About to remove channel:\n\n"
1673                          "%1\n\n"                          "%1\n\n"
# Line 1644  void MainForm::removeChannelStrip (void) Line 1710  void MainForm::removeChannelStrip (void)
1710  // Setup current sampler channel.  // Setup current sampler channel.
1711  void MainForm::editSetupChannel (void)  void MainForm::editSetupChannel (void)
1712  {  {
1713          if (m_pClient == NULL)          if (m_pClient == nullptr)
1714                  return;                  return;
1715    
1716          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1717          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1718                  return;                  return;
1719    
1720          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1659  void MainForm::editSetupChannel (void) Line 1725  void MainForm::editSetupChannel (void)
1725  // Edit current sampler channel.  // Edit current sampler channel.
1726  void MainForm::editEditChannel (void)  void MainForm::editEditChannel (void)
1727  {  {
1728          if (m_pClient == NULL)          if (m_pClient == nullptr)
1729                  return;                  return;
1730    
1731          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1732          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1733                  return;                  return;
1734    
1735          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1674  void MainForm::editEditChannel (void) Line 1740  void MainForm::editEditChannel (void)
1740  // Reset current sampler channel.  // Reset current sampler channel.
1741  void MainForm::editResetChannel (void)  void MainForm::editResetChannel (void)
1742  {  {
1743          if (m_pClient == NULL)          if (m_pClient == nullptr)
1744                  return;                  return;
1745    
1746          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1747          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1748                  return;                  return;
1749    
1750          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1689  void MainForm::editResetChannel (void) Line 1755  void MainForm::editResetChannel (void)
1755  // Reset all sampler channels.  // Reset all sampler channels.
1756  void MainForm::editResetAllChannels (void)  void MainForm::editResetAllChannels (void)
1757  {  {
1758          if (m_pClient == NULL)          if (m_pClient == nullptr)
1759                  return;                  return;
1760    
1761          // Invoque the channel strip procedure,          // Invoque the channel strip procedure,
# Line 1697  void MainForm::editResetAllChannels (voi Line 1763  void MainForm::editResetAllChannels (voi
1763          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1764          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
1765                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
1766          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
1767          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
1768                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
1769                  if (pChannelStrip)                  if (pChannelStrip)
1770                          pChannelStrip->channelReset();                          pChannelStrip->channelReset();
1771          }          }
# Line 1761  void MainForm::viewMessages ( bool bOn ) Line 1824  void MainForm::viewMessages ( bool bOn )
1824  // Show/hide the MIDI instrument list-view form.  // Show/hide the MIDI instrument list-view form.
1825  void MainForm::viewInstruments (void)  void MainForm::viewInstruments (void)
1826  {  {
1827          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1828                  return;                  return;
1829    
1830          if (m_pInstrumentListForm) {          if (m_pInstrumentListForm) {
# Line 1780  void MainForm::viewInstruments (void) Line 1843  void MainForm::viewInstruments (void)
1843  // Show/hide the device configurator form.  // Show/hide the device configurator form.
1844  void MainForm::viewDevices (void)  void MainForm::viewDevices (void)
1845  {  {
1846          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1847                  return;                  return;
1848    
1849          if (m_pDeviceForm) {          if (m_pDeviceForm) {
# Line 1799  void MainForm::viewDevices (void) Line 1862  void MainForm::viewDevices (void)
1862  // Show options dialog.  // Show options dialog.
1863  void MainForm::viewOptions (void)  void MainForm::viewOptions (void)
1864  {  {
1865          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1866                  return;                  return;
1867    
1868          OptionsForm* pOptionsForm = new OptionsForm(this);          OptionsForm* pOptionsForm = new OptionsForm(this);
# Line 1841  void MainForm::viewOptions (void) Line 1904  void MainForm::viewOptions (void)
1904                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)     ||                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)     ||
1905                                  (iOldBaseFontSize   !=  m_pOptions->iBaseFontSize)) {                                  (iOldBaseFontSize   !=  m_pOptions->iBaseFontSize)) {
1906                                  QMessageBox::information(this,                                  QMessageBox::information(this,
1907                                          QSAMPLER_TITLE ": " + tr("Information"),                                          tr("Information"),
1908                                          tr("Some settings may be only effective\n"                                          tr("Some settings may be only effective\n"
1909                                          "next time you start this program."));                                          "next time you start this program."));
1910                                  updateMessagesCapture();                                  updateMessagesCapture();
# Line 1905  void MainForm::channelsArrange (void) Line 1968  void MainForm::channelsArrange (void)
1968    
1969          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1970          int y = 0;          int y = 0;
1971          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
1972          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  pMdiSubWindow->adjustSize();
1973                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);                  const QRect& frameRect
1974                  if (pMdiSubWindow) {                          = pMdiSubWindow->frameGeometry();
1975                          pMdiSubWindow->adjustSize();                  int w = m_pWorkspace->width();
1976                          int iWidth = m_pWorkspace->width();                  if (w < frameRect.width())
1977                          if (iWidth < pMdiSubWindow->width())                          w = frameRect.width();
1978                                  iWidth = pMdiSubWindow->width();                  const int h = frameRect.height();
1979                          const int iHeight = pMdiSubWindow->frameGeometry().height();                  pMdiSubWindow->setGeometry(0, y, w, h);
1980                          pMdiSubWindow->setGeometry(0, y, iWidth, iHeight);                  y += h;
                         y += iHeight;  
                 }  
1981          }          }
1982          m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
1983    
# Line 1927  void MainForm::channelsArrange (void) Line 1988  void MainForm::channelsArrange (void)
1988  // Auto-arrange channel strips.  // Auto-arrange channel strips.
1989  void MainForm::channelsAutoArrange ( bool bOn )  void MainForm::channelsAutoArrange ( bool bOn )
1990  {  {
1991          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1992                  return;                  return;
1993    
1994          // Toggle the auto-arrange flag.          // Toggle the auto-arrange flag.
# Line 2031  void MainForm::helpAbout (void) Line 2092  void MainForm::helpAbout (void)
2092          sText += "</small>";          sText += "</small>";
2093          sText += "</p>\n";          sText += "</p>\n";
2094    
2095          QMessageBox::about(this, tr("About") + " " QSAMPLER_TITLE, sText);          QMessageBox::about(this, tr("About"), sText);
2096  }  }
2097    
2098    
# Line 2044  void MainForm::stabilizeForm (void) Line 2105  void MainForm::stabilizeForm (void)
2105          QString sSessionName = sessionName(m_sFilename);          QString sSessionName = sessionName(m_sFilename);
2106          if (m_iDirtyCount > 0)          if (m_iDirtyCount > 0)
2107                  sSessionName += " *";                  sSessionName += " *";
2108          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));          setWindowTitle(sSessionName);
2109    
2110          // Update the main menu state...          // Update the main menu state...
2111          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
2112          const QList<QMdiSubWindow *>& wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist = m_pWorkspace->subWindowList();
2113          const bool bHasClient = (m_pOptions != NULL && m_pClient != NULL);          const bool bHasClient = (m_pOptions != nullptr && m_pClient != nullptr);
2114          const bool bHasChannel = (bHasClient && pChannelStrip != NULL);          const bool bHasChannel = (bHasClient && pChannelStrip != nullptr);
2115          const bool bHasChannels = (bHasClient && wlist.count() > 0);          const bool bHasChannels = (bHasClient && wlist.count() > 0);
2116          m_ui.fileNewAction->setEnabled(bHasClient);          m_ui.fileNewAction->setEnabled(bHasClient);
2117          m_ui.fileOpenAction->setEnabled(bHasClient);          m_ui.fileOpenAction->setEnabled(bHasClient);
2118          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
2119          m_ui.fileSaveAsAction->setEnabled(bHasClient);          m_ui.fileSaveAsAction->setEnabled(bHasClient);
2120          m_ui.fileResetAction->setEnabled(bHasClient);          m_ui.fileResetAction->setEnabled(bHasClient);
2121          m_ui.fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);          m_ui.fileRestartAction->setEnabled(bHasClient || m_pServer == nullptr);
2122          m_ui.editAddChannelAction->setEnabled(bHasClient);          m_ui.editAddChannelAction->setEnabled(bHasClient);
2123          m_ui.editRemoveChannelAction->setEnabled(bHasChannel);          m_ui.editRemoveChannelAction->setEnabled(bHasChannel);
2124          m_ui.editSetupChannelAction->setEnabled(bHasChannel);          m_ui.editSetupChannelAction->setEnabled(bHasChannel);
# Line 2206  void MainForm::updateAllChannelStrips ( Line 2267  void MainForm::updateAllChannelStrips (
2267    
2268          // Retrieve the current channel list.          // Retrieve the current channel list.
2269          int *piChannelIDs = ::lscp_list_channels(m_pClient);          int *piChannelIDs = ::lscp_list_channels(m_pClient);
2270          if (piChannelIDs == NULL) {          if (piChannelIDs == nullptr) {
2271                  if (::lscp_client_get_errno(m_pClient)) {                  if (::lscp_client_get_errno(m_pClient)) {
2272                          appendMessagesClient("lscp_list_channels");                          appendMessagesClient("lscp_list_channels");
2273                          appendMessagesError(                          appendMessagesError(
# Line 2226  void MainForm::updateAllChannelStrips ( Line 2287  void MainForm::updateAllChannelStrips (
2287                  if (bRemoveDeadStrips) {                  if (bRemoveDeadStrips) {
2288                          const QList<QMdiSubWindow *>& wlist                          const QList<QMdiSubWindow *>& wlist
2289                                  = m_pWorkspace->subWindowList();                                  = m_pWorkspace->subWindowList();
2290                          const int iStripCount = wlist.count();                          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2291                          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                                  ChannelStrip *pChannelStrip
2292                                  ChannelStrip *pChannelStrip = NULL;                                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                                 if (pMdiSubWindow)  
                                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2293                                  if (pChannelStrip) {                                  if (pChannelStrip) {
2294                                          bool bExists = false;                                          bool bExists = false;
2295                                          for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {                                          for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {
2296                                                  Channel *pChannel = pChannelStrip->channel();                                                  Channel *pChannel = pChannelStrip->channel();
2297                                                  if (pChannel == NULL)                                                  if (pChannel == nullptr)
2298                                                          break;                                                          break;
2299                                                  if (piChannelIDs[iChannel] == pChannel->channelID()) {                                                  if (piChannelIDs[iChannel] == pChannel->channelID()) {
2300                                                          // strip exists, don't touch it                                                          // strip exists, don't touch it
# Line 2259  void MainForm::updateAllChannelStrips ( Line 2317  void MainForm::updateAllChannelStrips (
2317  // Update the recent files list and menu.  // Update the recent files list and menu.
2318  void MainForm::updateRecentFiles ( const QString& sFilename )  void MainForm::updateRecentFiles ( const QString& sFilename )
2319  {  {
2320          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2321                  return;                  return;
2322    
2323          // Remove from list if already there (avoid duplicates)          // Remove from list if already there (avoid duplicates)
# Line 2274  void MainForm::updateRecentFiles ( const Line 2332  void MainForm::updateRecentFiles ( const
2332  // Update the recent files list and menu.  // Update the recent files list and menu.
2333  void MainForm::updateRecentFilesMenu (void)  void MainForm::updateRecentFilesMenu (void)
2334  {  {
2335          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2336                  return;                  return;
2337    
2338          // Time to keep the list under limits.          // Time to keep the list under limits.
# Line 2308  void MainForm::updateInstrumentNames (vo Line 2366  void MainForm::updateInstrumentNames (vo
2366                  return;                  return;
2367    
2368          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2369          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2370          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2371                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2372                  if (pChannelStrip)                  if (pChannelStrip)
2373                          pChannelStrip->updateInstrumentName(true);                          pChannelStrip->updateInstrumentName(true);
2374          }          }
# Line 2324  void MainForm::updateInstrumentNames (vo Line 2379  void MainForm::updateInstrumentNames (vo
2379  // Force update of the channels display font.  // Force update of the channels display font.
2380  void MainForm::updateDisplayFont (void)  void MainForm::updateDisplayFont (void)
2381  {  {
2382          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2383                  return;                  return;
2384    
2385          // Check if display font is legal.          // Check if display font is legal.
# Line 2343  void MainForm::updateDisplayFont (void) Line 2398  void MainForm::updateDisplayFont (void)
2398                  return;                  return;
2399    
2400          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2401          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2402          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2403                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2404                  if (pChannelStrip)                  if (pChannelStrip)
2405                          pChannelStrip->setDisplayFont(font);                          pChannelStrip->setDisplayFont(font);
2406          }          }
# Line 2366  void MainForm::updateDisplayEffect (void Line 2418  void MainForm::updateDisplayEffect (void
2418                  return;                  return;
2419    
2420          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2421          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2422          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2423                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2424                  if (pChannelStrip)                  if (pChannelStrip)
2425                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2426          }          }
# Line 2382  void MainForm::updateDisplayEffect (void Line 2431  void MainForm::updateDisplayEffect (void
2431  // Force update of the channels maximum volume setting.  // Force update of the channels maximum volume setting.
2432  void MainForm::updateMaxVolume (void)  void MainForm::updateMaxVolume (void)
2433  {  {
2434          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2435                  return;                  return;
2436    
2437  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
# Line 2399  void MainForm::updateMaxVolume (void) Line 2448  void MainForm::updateMaxVolume (void)
2448                  return;                  return;
2449    
2450          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2451          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2452          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2453                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2454                  if (pChannelStrip)                  if (pChannelStrip)
2455                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2456          }          }
# Line 2449  void MainForm::appendMessagesError( cons Line 2495  void MainForm::appendMessagesError( cons
2495          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2496    
2497          if (m_pOptions && m_pOptions->bConfirmError) {          if (m_pOptions && m_pOptions->bConfirmError) {
2498                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Error");                  const QString& sTitle = tr("Error");
2499          #if 0          #if 0
2500                  QMessageBox::critical(this, sTitle, sText, QMessageBox::Cancel);                  QMessageBox::critical(this, sTitle, sText, QMessageBox::Cancel);
2501          #else          #else
# Line 2472  void MainForm::appendMessagesError( cons Line 2518  void MainForm::appendMessagesError( cons
2518  // This is a special message format, just for client results.  // This is a special message format, just for client results.
2519  void MainForm::appendMessagesClient( const QString& s )  void MainForm::appendMessagesClient( const QString& s )
2520  {  {
2521          if (m_pClient == NULL)          if (m_pClient == nullptr)
2522                  return;                  return;
2523    
2524          appendMessagesColor(s + QString(": %1 (errno=%2)")          appendMessagesColor(s + QString(": %1 (errno=%2)")
# Line 2487  void MainForm::appendMessagesClient( con Line 2533  void MainForm::appendMessagesClient( con
2533  // Force update of the messages font.  // Force update of the messages font.
2534  void MainForm::updateMessagesFont (void)  void MainForm::updateMessagesFont (void)
2535  {  {
2536          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2537                  return;                  return;
2538    
2539          if (m_pMessages && !m_pOptions->sMessagesFont.isEmpty()) {          if (m_pMessages && !m_pOptions->sMessagesFont.isEmpty()) {
# Line 2501  void MainForm::updateMessagesFont (void) Line 2547  void MainForm::updateMessagesFont (void)
2547  // Update messages window line limit.  // Update messages window line limit.
2548  void MainForm::updateMessagesLimit (void)  void MainForm::updateMessagesLimit (void)
2549  {  {
2550          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2551                  return;                  return;
2552    
2553          if (m_pMessages) {          if (m_pMessages) {
# Line 2516  void MainForm::updateMessagesLimit (void Line 2562  void MainForm::updateMessagesLimit (void
2562  // Enablement of the messages capture feature.  // Enablement of the messages capture feature.
2563  void MainForm::updateMessagesCapture (void)  void MainForm::updateMessagesCapture (void)
2564  {  {
2565          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2566                  return;                  return;
2567    
2568          if (m_pMessages)          if (m_pMessages)
# Line 2530  void MainForm::updateMessagesCapture (vo Line 2576  void MainForm::updateMessagesCapture (vo
2576  // The channel strip creation executive.  // The channel strip creation executive.
2577  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )
2578  {  {
2579          if (m_pClient == NULL || pChannel == NULL)          if (m_pClient == nullptr || pChannel == nullptr)
2580                  return NULL;                  return nullptr;
2581    
2582          // Add a new channel itema...          // Add a new channel itema...
2583          ChannelStrip *pChannelStrip = new ChannelStrip();          ChannelStrip *pChannelStrip = new ChannelStrip();
2584          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
2585                  return NULL;                  return nullptr;
2586    
2587          // Set some initial channel strip options...          // Set some initial channel strip options...
2588          if (m_pOptions) {          if (m_pOptions) {
# Line 2552  ChannelStrip *MainForm::createChannelStr Line 2598  ChannelStrip *MainForm::createChannelStr
2598          }          }
2599    
2600          // Add it to workspace...          // Add it to workspace...
2601          m_pWorkspace->addSubWindow(pChannelStrip,          QMdiSubWindow *pMdiSubWindow
2602                  Qt::SubWindow | Qt::FramelessWindowHint);                  = m_pWorkspace->addSubWindow(pChannelStrip,
2603                            Qt::SubWindow | Qt::FramelessWindowHint);
2604            pMdiSubWindow->setAttribute(Qt::WA_DeleteOnClose);
2605    
2606          // Actual channel strip setup...          // Actual channel strip setup...
2607          pChannelStrip->setup(pChannel);          pChannelStrip->setup(pChannel);
# Line 2577  void MainForm::destroyChannelStrip ( Cha Line 2625  void MainForm::destroyChannelStrip ( Cha
2625  {  {
2626          QMdiSubWindow *pMdiSubWindow          QMdiSubWindow *pMdiSubWindow
2627                  = static_cast<QMdiSubWindow *> (pChannelStrip->parentWidget());                  = static_cast<QMdiSubWindow *> (pChannelStrip->parentWidget());
2628          if (pMdiSubWindow == NULL)          if (pMdiSubWindow == nullptr)
2629                  return;                  return;
2630    
2631          // Just delete the channel strip.          // Just delete the channel strip.
# Line 2596  ChannelStrip *MainForm::activeChannelStr Line 2644  ChannelStrip *MainForm::activeChannelStr
2644          if (pMdiSubWindow)          if (pMdiSubWindow)
2645                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2646          else          else
2647                  return NULL;                  return nullptr;
2648  }  }
2649    
2650    
2651  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2652  ChannelStrip *MainForm::channelStripAt ( int iStrip )  ChannelStrip *MainForm::channelStripAt ( int iStrip )
2653  {  {
2654          if (!m_pWorkspace) return NULL;          if (!m_pWorkspace) return nullptr;
2655    
2656          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
2657                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
2658          if (wlist.isEmpty())          if (wlist.isEmpty())
2659                  return NULL;                  return nullptr;
2660    
2661          if (iStrip < 0 || iStrip >= wlist.count())          if (iStrip < 0 || iStrip >= wlist.count())
2662                  return NULL;                  return nullptr;
2663    
2664          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2665          if (pMdiSubWindow)          if (pMdiSubWindow)
2666                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2667          else          else
2668                  return NULL;                  return nullptr;
2669  }  }
2670    
2671    
# Line 2627  ChannelStrip *MainForm::channelStrip ( i Line 2675  ChannelStrip *MainForm::channelStrip ( i
2675          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
2676                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
2677          if (wlist.isEmpty())          if (wlist.isEmpty())
2678                  return NULL;                  return nullptr;
2679    
2680          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2681          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2682                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2683                  if (pChannelStrip) {                  if (pChannelStrip) {
2684                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
2685                          if (pChannel && pChannel->channelID() == iChannelID)                          if (pChannel && pChannel->channelID() == iChannelID)
# Line 2643  ChannelStrip *MainForm::channelStrip ( i Line 2688  ChannelStrip *MainForm::channelStrip ( i
2688          }          }
2689    
2690          // Not found.          // Not found.
2691          return NULL;          return nullptr;
2692  }  }
2693    
2694    
# Line 2658  void MainForm::channelsMenuAboutToShow ( Line 2703  void MainForm::channelsMenuAboutToShow (
2703                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
2704          if (!wlist.isEmpty()) {          if (!wlist.isEmpty()) {
2705                  m_ui.channelsMenu->addSeparator();                  m_ui.channelsMenu->addSeparator();
2706                  const int iStripCount = wlist.count();                  int iStrip = 0;
2707                  for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2708                          ChannelStrip *pChannelStrip = NULL;                          ChannelStrip *pChannelStrip
2709                          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                         if (pMdiSubWindow)  
                                 pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2710                          if (pChannelStrip) {                          if (pChannelStrip) {
2711                                  QAction *pAction = m_ui.channelsMenu->addAction(                                  QAction *pAction = m_ui.channelsMenu->addAction(
2712                                          pChannelStrip->windowTitle(),                                          pChannelStrip->windowTitle(),
# Line 2672  void MainForm::channelsMenuAboutToShow ( Line 2715  void MainForm::channelsMenuAboutToShow (
2715                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);
2716                                  pAction->setData(iStrip);                                  pAction->setData(iStrip);
2717                          }                          }
2718                            ++iStrip;
2719                  }                  }
2720          }          }
2721  }  }
# Line 2682  void MainForm::channelsMenuActivated (vo Line 2726  void MainForm::channelsMenuActivated (vo
2726  {  {
2727          // Retrive channel index from action data...          // Retrive channel index from action data...
2728          QAction *pAction = qobject_cast<QAction *> (sender());          QAction *pAction = qobject_cast<QAction *> (sender());
2729          if (pAction == NULL)          if (pAction == nullptr)
2730                  return;                  return;
2731    
2732          ChannelStrip *pChannelStrip = channelStripAt(pAction->data().toInt());          ChannelStrip *pChannelStrip = channelStripAt(pAction->data().toInt());
# Line 2713  void MainForm::stopSchedule (void) Line 2757  void MainForm::stopSchedule (void)
2757  // Timer slot funtion.  // Timer slot funtion.
2758  void MainForm::timerSlot (void)  void MainForm::timerSlot (void)
2759  {  {
2760          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2761                  return;                  return;
2762    
2763          // Is it the first shot on server start after a few delay?          // Is it the first shot on server start after a few delay?
# Line 2748  void MainForm::timerSlot (void) Line 2792  void MainForm::timerSlot (void)
2792                                  // Update the channel stream usage for each strip...                                  // Update the channel stream usage for each strip...
2793                                  const QList<QMdiSubWindow *>& wlist                                  const QList<QMdiSubWindow *>& wlist
2794                                          = m_pWorkspace->subWindowList();                                          = m_pWorkspace->subWindowList();
2795                                  const int iStripCount = wlist.count();                                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2796                                  for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                                          ChannelStrip *pChannelStrip
2797                                          ChannelStrip *pChannelStrip = NULL;                                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                                         QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                                         if (pMdiSubWindow)  
                                                 pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2798                                          if (pChannelStrip && pChannelStrip->isVisible())                                          if (pChannelStrip && pChannelStrip->isVisible())
2799                                                  pChannelStrip->updateChannelUsage();                                                  pChannelStrip->updateChannelUsage();
2800                                  }                                  }
2801                          }                          }
2802                  }                  }
2803    
2804            #if CONFIG_LSCP_CLIENT_CONNECTION_LOST
2805                    // If we lost connection to server: Try to automatically reconnect if we
2806                    // did not start the server.
2807                    //
2808                    // TODO: If we started the server, then we might inform the user that
2809                    // the server probably crashed and asking user ONCE whether we should
2810                    // restart the server.
2811                    if (lscp_client_connection_lost(m_pClient) && !m_pServer)
2812                            startAutoReconnectClient();
2813            #endif // CONFIG_LSCP_CLIENT_CONNECTION_LOST
2814          }          }
2815    
2816          // Register the next timer slot.          // Register the next timer slot.
# Line 2772  void MainForm::timerSlot (void) Line 2824  void MainForm::timerSlot (void)
2824  // Start linuxsampler server...  // Start linuxsampler server...
2825  void MainForm::startServer (void)  void MainForm::startServer (void)
2826  {  {
2827          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2828                  return;                  return;
2829    
2830          // Aren't already a client, are we?          // Aren't already a client, are we?
# Line 2782  void MainForm::startServer (void) Line 2834  void MainForm::startServer (void)
2834          // Is the server process instance still here?          // Is the server process instance still here?
2835          if (m_pServer) {          if (m_pServer) {
2836                  if (QMessageBox::warning(this,                  if (QMessageBox::warning(this,
2837                          QSAMPLER_TITLE ": " + tr("Warning"),                          tr("Warning"),
2838                          tr("Could not start the LinuxSampler server.\n\n"                          tr("Could not start the LinuxSampler server.\n\n"
2839                          "Maybe it is already started."),                          "Maybe it is already started."),
2840                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
# Line 2852  void MainForm::stopServer ( bool bIntera Line 2904  void MainForm::stopServer ( bool bIntera
2904    
2905          if (m_pServer && bInteractive) {          if (m_pServer && bInteractive) {
2906                  if (QMessageBox::question(this,                  if (QMessageBox::question(this,
2907                          QSAMPLER_TITLE ": " + tr("The backend's fate ..."),                          tr("The backend's fate ..."),
2908                          tr("You have the option to keep the sampler backend (LinuxSampler)\n"                          tr("You have the option to keep the sampler backend (LinuxSampler)\n"
2909                          "running in the background. The sampler would continue to work\n"                          "running in the background. The sampler would continue to work\n"
2910                          "according to your current sampler session and you could alter the\n"                          "according to your current sampler session and you could alter the\n"
# Line 2864  void MainForm::stopServer ( bool bIntera Line 2916  void MainForm::stopServer ( bool bIntera
2916                  }                  }
2917          }          }
2918    
2919            bool bGraceWait = true;
2920    
2921          // And try to stop server.          // And try to stop server.
2922          if (m_pServer && m_bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2923                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2924                  if (m_pServer->state() == QProcess::Running) {                  if (m_pServer->state() == QProcess::Running) {
2925                  #if defined(_WIN32)                  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
2926                          // Try harder...                          // Try harder...
2927                          m_pServer->kill();                          m_pServer->kill();
2928                  #else                  #else
2929                          // Try softly...                          // Try softly...
2930                          m_pServer->terminate();                          m_pServer->terminate();
2931                            bool bFinished = m_pServer->waitForFinished(QSAMPLER_TIMER_MSECS * 1000);
2932                            if (bFinished) bGraceWait = false;
2933                  #endif                  #endif
2934                  }                  }
2935          }       // Do final processing anyway.          }       // Do final processing anyway.
2936          else processServerExit();          else processServerExit();
2937    
2938          // Give it some time to terminate gracefully and stabilize...          // Give it some time to terminate gracefully and stabilize...
2939          QTime t;          if (bGraceWait) {
2940          t.start();                  QElapsedTimer timer;
2941          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                  timer.start();
2942                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  while (timer.elapsed() < QSAMPLER_TIMER_MSECS)
2943                            QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2944            }
2945  }  }
2946    
2947    
# Line 2911  void MainForm::processServerExit (void) Line 2969  void MainForm::processServerExit (void)
2969                          // Force final server shutdown...                          // Force final server shutdown...
2970                          m_pServer->kill();                          m_pServer->kill();
2971                          // Give it some time to terminate gracefully and stabilize...                          // Give it some time to terminate gracefully and stabilize...
2972                          QTime t;                          QElapsedTimer timer;
2973                          t.start();                          timer.start();
2974                          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                          while (timer.elapsed() < QSAMPLER_TIMER_MSECS)
2975                                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2976                  }                  }
2977                  // Force final server shutdown...                  // Force final server shutdown...
# Line 2921  void MainForm::processServerExit (void) Line 2979  void MainForm::processServerExit (void)
2979                          tr("Server was stopped with exit status %1.")                          tr("Server was stopped with exit status %1.")
2980                          .arg(m_pServer->exitStatus()));                          .arg(m_pServer->exitStatus()));
2981                  delete m_pServer;                  delete m_pServer;
2982                  m_pServer = NULL;                  m_pServer = nullptr;
2983          }          }
2984    
2985          // Again, make status visible stable.          // Again, make status visible stable.
# Line 2937  lscp_status_t qsampler_client_callback ( Line 2995  lscp_status_t qsampler_client_callback (
2995          lscp_event_t event, const char *pchData, int cchData, void *pvData )          lscp_event_t event, const char *pchData, int cchData, void *pvData )
2996  {  {
2997          MainForm* pMainForm = (MainForm *) pvData;          MainForm* pMainForm = (MainForm *) pvData;
2998          if (pMainForm == NULL)          if (pMainForm == nullptr)
2999                  return LSCP_FAILED;                  return LSCP_FAILED;
3000    
3001          // ATTN: DO NOT EVER call any GUI code here,          // ATTN: DO NOT EVER call any GUI code here,
# Line 2951  lscp_status_t qsampler_client_callback ( Line 3009  lscp_status_t qsampler_client_callback (
3009    
3010    
3011  // Start our almighty client...  // Start our almighty client...
3012  bool MainForm::startClient (void)  bool MainForm::startClient (bool bReconnectOnly)
3013  {  {
3014          // Have it a setup?          // Have it a setup?
3015          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
3016                  return false;                  return false;
3017    
3018          // Aren't we already started, are we?          // Aren't we already started, are we?
# Line 2968  bool MainForm::startClient (void) Line 3026  bool MainForm::startClient (void)
3026          m_pClient = ::lscp_client_create(          m_pClient = ::lscp_client_create(
3027                  m_pOptions->sServerHost.toUtf8().constData(),                  m_pOptions->sServerHost.toUtf8().constData(),
3028                  m_pOptions->iServerPort, qsampler_client_callback, this);                  m_pOptions->iServerPort, qsampler_client_callback, this);
3029          if (m_pClient == NULL) {          if (m_pClient == nullptr) {
3030                  // Is this the first try?                  // Is this the first try?
3031                  // maybe we need to start a local server...                  // maybe we need to start a local server...
3032                  if ((m_pServer && m_pServer->state() == QProcess::Running)                  if ((m_pServer && m_pServer->state() == QProcess::Running)
3033                          || !m_pOptions->bServerStart) {                          || !m_pOptions->bServerStart || bReconnectOnly)
3034                          appendMessagesError(                  {
3035                                  tr("Could not connect to server as client.\n\nSorry."));                          // if this method is called from autoReconnectClient()
3036                            // then don't bother user with an error message...
3037                            if (!bReconnectOnly) {
3038                                    appendMessagesError(
3039                                            tr("Could not connect to server as client.\n\nSorry.")
3040                                    );
3041                            }
3042                  } else {                  } else {
3043                          startServer();                          startServer();
3044                  }                  }
# Line 3038  bool MainForm::startClient (void) Line 3102  bool MainForm::startClient (void)
3102          if (!m_pOptions->sSessionFile.isEmpty()) {          if (!m_pOptions->sSessionFile.isEmpty()) {
3103                  // Just load the prabably startup session...                  // Just load the prabably startup session...
3104                  if (loadSessionFile(m_pOptions->sSessionFile)) {                  if (loadSessionFile(m_pOptions->sSessionFile)) {
3105                          m_pOptions->sSessionFile = QString::null;                          m_pOptions->sSessionFile = QString();
3106                          return true;                          return true;
3107                  }                  }
3108          }          }
# Line 3054  bool MainForm::startClient (void) Line 3118  bool MainForm::startClient (void)
3118  // Stop client...  // Stop client...
3119  void MainForm::stopClient (void)  void MainForm::stopClient (void)
3120  {  {
3121          if (m_pClient == NULL)          if (m_pClient == nullptr)
3122                  return;                  return;
3123    
3124          // Log prepare here.          // Log prepare here.
# Line 3086  void MainForm::stopClient (void) Line 3150  void MainForm::stopClient (void)
3150          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
3151          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);
3152          ::lscp_client_destroy(m_pClient);          ::lscp_client_destroy(m_pClient);
3153          m_pClient = NULL;          m_pClient = nullptr;
3154    
3155          // Hard-notify instrumnet and device configuration forms,          // Hard-notify instrumnet and device configuration forms,
3156          // if visible, that we're running out...          // if visible, that we're running out...
# Line 3103  void MainForm::stopClient (void) Line 3167  void MainForm::stopClient (void)
3167  }  }
3168    
3169    
3170    void MainForm::startAutoReconnectClient (void)
3171    {
3172            stopClient();
3173            appendMessages(tr("Trying to reconnect..."));
3174            QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(autoReconnectClient()));
3175    }
3176    
3177    
3178    void MainForm::autoReconnectClient (void)
3179    {
3180            const bool bSuccess = startClient(true);
3181            if (!bSuccess)
3182                    QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(autoReconnectClient()));
3183    }
3184    
3185    
3186  // Channel strip activation/selection.  // Channel strip activation/selection.
3187  void MainForm::activateStrip ( QMdiSubWindow *pMdiSubWindow )  void MainForm::activateStrip ( QMdiSubWindow *pMdiSubWindow )
3188  {  {
3189          ChannelStrip *pChannelStrip = NULL;          ChannelStrip *pChannelStrip = nullptr;
3190          if (pMdiSubWindow)          if (pMdiSubWindow)
3191                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
3192          if (pChannelStrip)          if (pChannelStrip)

Legend:
Removed from v.3357  
changed lines
  Added in v.3759

  ViewVC Help
Powered by ViewVC