/[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 3685 by capela, Thu Jan 2 19:03:34 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    
 #ifdef HAVE_SIGNAL_H  
 #include <signal.h>  
 #endif  
   
73  #ifdef CONFIG_LIBGIG  #ifdef CONFIG_LIBGIG
74  #include <gig.h>  #include <gig.h>
75  #endif  #endif
# Line 91  static inline long lroundf ( float x ) Line 89  static inline long lroundf ( float x )
89    
90    
91  // All winsock apps needs this.  // All winsock apps needs this.
92  #if defined(_WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
93  static WSADATA _wsaData;  static WSADATA _wsaData;
94    #undef HAVE_SIGNAL_H
95  #endif  #endif
96    
97    
# Line 103  static WSADATA _wsaData; Line 102  static WSADATA _wsaData;
102    
103  #include <QSocketNotifier>  #include <QSocketNotifier>
104    
105    #include <unistd.h>
106  #include <sys/types.h>  #include <sys/types.h>
107  #include <sys/socket.h>  #include <sys/socket.h>
   
108  #include <signal.h>  #include <signal.h>
109    
110  // File descriptor for SIGUSR1 notifier.  // File descriptor for SIGUSR1 notifier.
111  static int g_fdUsr1[2];  static int g_fdSigusr1[2] = { -1, -1 };
112    
113  // Unix SIGUSR1 signal handler.  // Unix SIGUSR1 signal handler.
114  static void qsampler_sigusr1_handler ( int /* signo */ )  static void qsampler_sigusr1_handler ( int /* signo */ )
115  {  {
116          char c = 1;          char c = 1;
117    
118          (::write(g_fdUsr1[0], &c, sizeof(c)) > 0);          (::write(g_fdSigusr1[0], &c, sizeof(c)) > 0);
119    }
120    
121    // File descriptor for SIGTERM notifier.
122    static int g_fdSigterm[2] = { -1, -1 };
123    
124    // Unix SIGTERM signal handler.
125    static void qsampler_sigterm_handler ( int /* signo */ )
126    {
127            char c = 1;
128    
129            (::write(g_fdSigterm[0], &c, sizeof(c)) > 0);
130  }  }
131    
132  #endif  // HAVE_SIGNAL_H  #endif  // HAVE_SIGNAL_H
# Line 194  protected: Line 204  protected:
204  // QSampler::MainForm -- Main window form implementation.  // QSampler::MainForm -- Main window form implementation.
205    
206  // Kind of singleton reference.  // Kind of singleton reference.
207  MainForm *MainForm::g_pMainForm = NULL;  MainForm *MainForm::g_pMainForm = nullptr;
208    
209  MainForm::MainForm ( QWidget *pParent )  MainForm::MainForm ( QWidget *pParent )
210          : QMainWindow(pParent)          : QMainWindow(pParent)
# Line 205  MainForm::MainForm ( QWidget *pParent ) Line 215  MainForm::MainForm ( QWidget *pParent )
215          g_pMainForm = this;          g_pMainForm = this;
216    
217          // Initialize some pointer references.          // Initialize some pointer references.
218          m_pOptions = NULL;          m_pOptions = nullptr;
219    
220          // All child forms are to be created later, not earlier than setup.          // All child forms are to be created later, not earlier than setup.
221          m_pMessages = NULL;          m_pMessages = nullptr;
222          m_pInstrumentListForm = NULL;          m_pInstrumentListForm = nullptr;
223          m_pDeviceForm = NULL;          m_pDeviceForm = nullptr;
224    
225          // We'll start clean.          // We'll start clean.
226          m_iUntitled   = 0;          m_iUntitled   = 0;
227          m_iDirtySetup = 0;          m_iDirtySetup = 0;
228          m_iDirtyCount = 0;          m_iDirtyCount = 0;
229    
230          m_pServer = NULL;          m_pServer = nullptr;
231          m_pClient = NULL;          m_pClient = nullptr;
232    
233          m_iStartDelay = 0;          m_iStartDelay = 0;
234          m_iTimerDelay = 0;          m_iTimerDelay = 0;
# Line 233  MainForm::MainForm ( QWidget *pParent ) Line 243  MainForm::MainForm ( QWidget *pParent )
243          // LADISH Level 1 suport.          // LADISH Level 1 suport.
244    
245          // Initialize file descriptors for SIGUSR1 socket notifier.          // Initialize file descriptors for SIGUSR1 socket notifier.
246          ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdUsr1);          ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigusr1);
247          m_pUsr1Notifier          m_pSigusr1Notifier
248                  = new QSocketNotifier(g_fdUsr1[1], QSocketNotifier::Read, this);                  = new QSocketNotifier(g_fdSigusr1[1], QSocketNotifier::Read, this);
249    
250          QObject::connect(m_pUsr1Notifier,          QObject::connect(m_pSigusr1Notifier,
251                  SIGNAL(activated(int)),                  SIGNAL(activated(int)),
252                  SLOT(handle_sigusr1()));                  SLOT(handle_sigusr1()));
253    
254          // Install SIGUSR1 signal handler.          // Install SIGUSR1 signal handler.
255      struct sigaction usr1;          struct sigaction sigusr1;
256      usr1.sa_handler = qsampler_sigusr1_handler;          sigusr1.sa_handler = qsampler_sigusr1_handler;
257      sigemptyset(&usr1.sa_mask);          sigemptyset(&sigusr1.sa_mask);
258      usr1.sa_flags = 0;          sigusr1.sa_flags = 0;
259      usr1.sa_flags |= SA_RESTART;          sigusr1.sa_flags |= SA_RESTART;
260      ::sigaction(SIGUSR1, &usr1, NULL);          ::sigaction(SIGUSR1, &sigusr1, nullptr);
261    
262            // Initialize file descriptors for SIGTERM socket notifier.
263            ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigterm);
264            m_pSigtermNotifier
265                    = new QSocketNotifier(g_fdSigterm[1], QSocketNotifier::Read, this);
266    
267            QObject::connect(m_pSigtermNotifier,
268                    SIGNAL(activated(int)),
269                    SLOT(handle_sigterm()));
270    
271            // Install SIGTERM signal handler.
272            struct sigaction sigterm;
273            sigterm.sa_handler = qsampler_sigterm_handler;
274            sigemptyset(&sigterm.sa_mask);
275            sigterm.sa_flags = 0;
276            sigterm.sa_flags |= SA_RESTART;
277            ::sigaction(SIGTERM, &sigterm, nullptr);
278            ::sigaction(SIGQUIT, &sigterm, nullptr);
279    
280            // Ignore SIGHUP/SIGINT signals.
281            ::signal(SIGHUP, SIG_IGN);
282            ::signal(SIGINT, SIG_IGN);
283    
284  #else   // HAVE_SIGNAL_H  #else   // HAVE_SIGNAL_H
285    
286          m_pUsr1Notifier = NULL;          m_pSigusr1Notifier = nullptr;
287            m_pSigtermNotifier = nullptr;
288                    
289  #endif  // !HAVE_SIGNAL_H  #endif  // !HAVE_SIGNAL_H
290    
# Line 324  MainForm::MainForm ( QWidget *pParent ) Line 357  MainForm::MainForm ( QWidget *pParent )
357          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
358          statusBar()->addWidget(pLabel);          statusBar()->addWidget(pLabel);
359    
360  #if defined(_WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
361          WSAStartup(MAKEWORD(1, 1), &_wsaData);          WSAStartup(MAKEWORD(1, 1), &_wsaData);
362  #endif  #endif
363    
# Line 425  MainForm::~MainForm() Line 458  MainForm::~MainForm()
458          // Do final processing anyway.          // Do final processing anyway.
459          processServerExit();          processServerExit();
460    
461  #if defined(_WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
462          WSACleanup();          WSACleanup();
463  #endif  #endif
464    
465  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
466          if (m_pUsr1Notifier)          if (m_pSigusr1Notifier)
467                  delete m_pUsr1Notifier;                  delete m_pSigusr1Notifier;
468            if (m_pSigtermNotifier)
469                    delete m_pSigtermNotifier;
470  #endif  #endif
471    
472          // Finally drop any widgets around...          // Finally drop any widgets around...
# Line 460  MainForm::~MainForm() Line 495  MainForm::~MainForm()
495  #endif  #endif
496    
497          // Pseudo-singleton reference shut-down.          // Pseudo-singleton reference shut-down.
498          g_pMainForm = NULL;          g_pMainForm = nullptr;
499  }  }
500    
501    
# Line 597  void MainForm::closeEvent ( QCloseEvent Line 632  void MainForm::closeEvent ( QCloseEvent
632  void MainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )  void MainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
633  {  {
634          // Accept external drags only...          // Accept external drags only...
635          if (pDragEnterEvent->source() == NULL          if (pDragEnterEvent->source() == nullptr
636                  && pDragEnterEvent->mimeData()->hasUrls()) {                  && pDragEnterEvent->mimeData()->hasUrls()) {
637                  pDragEnterEvent->accept();                  pDragEnterEvent->accept();
638          } else {          } else {
# Line 621  void MainForm::dropEvent ( QDropEvent *p Line 656  void MainForm::dropEvent ( QDropEvent *p
656                          if (QFileInfo(sPath).exists()) {                          if (QFileInfo(sPath).exists()) {
657                                  // Try to create a new channel from instrument file...                                  // Try to create a new channel from instrument file...
658                                  Channel *pChannel = new Channel();                                  Channel *pChannel = new Channel();
659                                  if (pChannel == NULL)                                  if (pChannel == nullptr)
660                                          return;                                          return;
661                                  // Start setting the instrument filename...                                  // Start setting the instrument filename...
662                                  pChannel->setInstrument(sPath, 0);                                  pChannel->setInstrument(sPath, 0);
# Line 721  void MainForm::handle_sigusr1 (void) Line 756  void MainForm::handle_sigusr1 (void)
756    
757          char c;          char c;
758    
759          if (::read(g_fdUsr1[1], &c, sizeof(c)) > 0)          if (::read(g_fdSigusr1[1], &c, sizeof(c)) > 0)
760                  saveSession(false);                  saveSession(false);
761    
762  #endif  #endif
763  }  }
764    
765    
766    void MainForm::handle_sigterm (void)
767    {
768    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
769    
770            char c;
771    
772            if (::read(g_fdSigterm[1], &c, sizeof(c)) > 0)
773                    close();
774    
775    #endif
776    }
777    
778    
779  void MainForm::updateViewMidiDeviceStatusMenu (void)  void MainForm::updateViewMidiDeviceStatusMenu (void)
780  {  {
781          m_ui.viewMidiDeviceStatusMenu->clear();          m_ui.viewMidiDeviceStatusMenu->clear();
# Line 806  bool MainForm::newSession (void) Line 854  bool MainForm::newSession (void)
854          m_iUntitled++;          m_iUntitled++;
855    
856          // Stabilize form.          // Stabilize form.
857          m_sFilename = QString::null;          m_sFilename = QString();
858          m_iDirtyCount = 0;          m_iDirtyCount = 0;
859          appendMessages(tr("New session: \"%1\".").arg(sessionName(m_sFilename)));          appendMessages(tr("New session: \"%1\".").arg(sessionName(m_sFilename)));
860          stabilizeForm();          stabilizeForm();
# Line 818  bool MainForm::newSession (void) Line 866  bool MainForm::newSession (void)
866  // Open an existing sampler session.  // Open an existing sampler session.
867  bool MainForm::openSession (void)  bool MainForm::openSession (void)
868  {  {
869          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
870                  return false;                  return false;
871    
872          // Ask for the filename to open...          // Ask for the filename to open...
873          QString sFilename = QFileDialog::getOpenFileName(this,          QString sFilename = QFileDialog::getOpenFileName(this,
874                  QSAMPLER_TITLE ": " + tr("Open Session"), // Caption.                  tr("Open Session"),                       // Caption.
875                  m_pOptions->sSessionDir,                  // Start here.                  m_pOptions->sSessionDir,                  // Start here.
876                  tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)                  tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)
877          );          );
# Line 844  bool MainForm::openSession (void) Line 892  bool MainForm::openSession (void)
892  // Save current sampler session with another name.  // Save current sampler session with another name.
893  bool MainForm::saveSession ( bool bPrompt )  bool MainForm::saveSession ( bool bPrompt )
894  {  {
895          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
896                  return false;                  return false;
897    
898          QString sFilename = m_sFilename;          QString sFilename = m_sFilename;
# Line 856  bool MainForm::saveSession ( bool bPromp Line 904  bool MainForm::saveSession ( bool bPromp
904                          sFilename = m_pOptions->sSessionDir;                          sFilename = m_pOptions->sSessionDir;
905                  // Prompt the guy...                  // Prompt the guy...
906                  sFilename = QFileDialog::getSaveFileName(this,                  sFilename = QFileDialog::getSaveFileName(this,
907                          QSAMPLER_TITLE ": " + tr("Save Session"), // Caption.                          tr("Save Session"),                       // Caption.
908                          sFilename,                                // Start here.                          sFilename,                                // Start here.
909                          tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)                          tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)
910                  );                  );
# Line 866  bool MainForm::saveSession ( bool bPromp Line 914  bool MainForm::saveSession ( bool bPromp
914                  // Enforce .lscp extension...                  // Enforce .lscp extension...
915                  if (QFileInfo(sFilename).suffix().isEmpty())                  if (QFileInfo(sFilename).suffix().isEmpty())
916                          sFilename += ".lscp";                          sFilename += ".lscp";
917            #if 0
918                  // Check if already exists...                  // Check if already exists...
919                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
920                          if (QMessageBox::warning(this,                          if (QMessageBox::warning(this,
921                                  QSAMPLER_TITLE ": " + tr("Warning"),                                  tr("Warning"),
922                                  tr("The file already exists:\n\n"                                  tr("The file already exists:\n\n"
923                                  "\"%1\"\n\n"                                  "\"%1\"\n\n"
924                                  "Do you want to replace it?")                                  "Do you want to replace it?")
# Line 878  bool MainForm::saveSession ( bool bPromp Line 927  bool MainForm::saveSession ( bool bPromp
927                                  == QMessageBox::No)                                  == QMessageBox::No)
928                                  return false;                                  return false;
929                  }                  }
930            #endif
931          }          }
932    
933          // Save it right away.          // Save it right away.
# Line 893  bool MainForm::closeSession ( bool bForc Line 943  bool MainForm::closeSession ( bool bForc
943          // Are we dirty enough to prompt it?          // Are we dirty enough to prompt it?
944          if (m_iDirtyCount > 0) {          if (m_iDirtyCount > 0) {
945                  switch (QMessageBox::warning(this,                  switch (QMessageBox::warning(this,
946                          QSAMPLER_TITLE ": " + tr("Warning"),                          tr("Warning"),
947                          tr("The current session has been changed:\n\n"                          tr("The current session has been changed:\n\n"
948                          "\"%1\"\n\n"                          "\"%1\"\n\n"
949                          "Do you want to save the changes?")                          "Do you want to save the changes?")
# Line 918  bool MainForm::closeSession ( bool bForc Line 968  bool MainForm::closeSession ( bool bForc
968                  m_pWorkspace->setUpdatesEnabled(false);                  m_pWorkspace->setUpdatesEnabled(false);
969                  const QList<QMdiSubWindow *>& wlist                  const QList<QMdiSubWindow *>& wlist
970                          = m_pWorkspace->subWindowList();                          = m_pWorkspace->subWindowList();
971                  const int iStripCount = wlist.count();                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
972                  for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                          ChannelStrip *pChannelStrip
973                          ChannelStrip *pChannelStrip = NULL;                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                         QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                         if (pMdiSubWindow)  
                                 pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
974                          if (pChannelStrip) {                          if (pChannelStrip) {
975                                  Channel *pChannel = pChannelStrip->channel();                                  Channel *pChannel = pChannelStrip->channel();
976                                  if (bForce && pChannel)                                  if (bForce && pChannel)
977                                          pChannel->removeChannel();                                          pChannel->removeChannel();
978                                  delete pChannelStrip;                                  delete pChannelStrip;
979                          }                          }
980                          if (pMdiSubWindow)                          delete pMdiSubWindow;
                                 delete pMdiSubWindow;  
981                  }                  }
982                  m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
983                  // We're now clean, for sure.                  // We're now clean, for sure.
# Line 945  bool MainForm::closeSession ( bool bForc Line 991  bool MainForm::closeSession ( bool bForc
991  // Load a session from specific file path.  // Load a session from specific file path.
992  bool MainForm::loadSessionFile ( const QString& sFilename )  bool MainForm::loadSessionFile ( const QString& sFilename )
993  {  {
994          if (m_pClient == NULL)          if (m_pClient == nullptr)
995                  return false;                  return false;
996    
997          // Open and read from real file.          // Open and read from real file.
# Line 1021  bool MainForm::loadSessionFile ( const Q Line 1067  bool MainForm::loadSessionFile ( const Q
1067  // Save current session to specific file path.  // Save current session to specific file path.
1068  bool MainForm::saveSessionFile ( const QString& sFilename )  bool MainForm::saveSessionFile ( const QString& sFilename )
1069  {  {
1070          if (m_pClient == NULL)          if (m_pClient == nullptr)
1071                  return false;                  return false;
1072    
1073          // Check whether server is apparently OK...          // Check whether server is apparently OK...
# Line 1060  bool MainForm::saveSessionFile ( const Q Line 1106  bool MainForm::saveSessionFile ( const Q
1106          // It is assumed that this new kind of device+session file          // It is assumed that this new kind of device+session file
1107          // will be loaded from a complete initialized server...          // will be loaded from a complete initialized server...
1108          int *piDeviceIDs;          int *piDeviceIDs;
1109          int  iDevice;          int  i, iDevice;
1110          ts << "RESET" << endl;          ts << "RESET" << endl;
1111    
1112          // Audio device mapping.          // Audio device mapping.
1113          QMap<int, int> audioDeviceMap;          QMap<int, int> audioDeviceMap; iDevice = 0;
1114          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);
1115          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1116                  ts << endl;                  Device device(Device::Audio, piDeviceIDs[i]);
1117                  Device device(Device::Audio, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1118                    if (device.driverName().toUpper() == "PLUGIN")
1119                            continue;
1120                  // Audio device specification...                  // Audio device specification...
1121                    ts << endl;
1122                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1123                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1124                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
# Line 1100  bool MainForm::saveSessionFile ( const Q Line 1149  bool MainForm::saveSessionFile ( const Q
1149                          iPort++;                          iPort++;
1150                  }                  }
1151                  // Audio device index/id mapping.                  // Audio device index/id mapping.
1152                  audioDeviceMap[device.deviceID()] = iDevice;                  audioDeviceMap.insert(device.deviceID(), iDevice++);
1153                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1154                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1155          }          }
1156    
1157          // MIDI device mapping.          // MIDI device mapping.
1158          QMap<int, int> midiDeviceMap;          QMap<int, int> midiDeviceMap; iDevice = 0;
1159          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);
1160          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1161                  ts << endl;                  Device device(Device::Midi, piDeviceIDs[i]);
1162                  Device device(Device::Midi, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1163                    if (device.driverName().toUpper() == "PLUGIN")
1164                            continue;
1165                  // MIDI device specification...                  // MIDI device specification...
1166                    ts << endl;
1167                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1168                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1169                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
# Line 1142  bool MainForm::saveSessionFile ( const Q Line 1194  bool MainForm::saveSessionFile ( const Q
1194                          iPort++;                          iPort++;
1195                  }                  }
1196                  // MIDI device index/id mapping.                  // MIDI device index/id mapping.
1197                  midiDeviceMap[device.deviceID()] = iDevice;                  midiDeviceMap.insert(device.deviceID(), iDevice++);
1198                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1199                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1200          }          }
# Line 1205  bool MainForm::saveSessionFile ( const Q Line 1257  bool MainForm::saveSessionFile ( const Q
1257                  }                  }
1258                  ts << endl;                  ts << endl;
1259                  // Check for errors...                  // Check for errors...
1260                  if (pInstrs == NULL && ::lscp_client_get_errno(m_pClient)) {                  if (pInstrs == nullptr && ::lscp_client_get_errno(m_pClient)) {
1261                          appendMessagesClient("lscp_list_midi_instruments");                          appendMessagesClient("lscp_list_midi_instruments");
1262                          iErrors++;                          iErrors++;
1263                  }                  }
1264                  // MIDI strument index/id mapping.                  // MIDI strument index/id mapping.
1265                  midiInstrumentMap[iMidiMap] = iMap;                  midiInstrumentMap.insert(iMidiMap, iMap);
1266          }          }
1267          // Check for errors...          // Check for errors...
1268          if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {          if (piMaps == nullptr && ::lscp_client_get_errno(m_pClient)) {
1269                  appendMessagesClient("lscp_list_midi_instrument_maps");                  appendMessagesClient("lscp_list_midi_instrument_maps");
1270                  iErrors++;                  iErrors++;
1271          }          }
1272  #endif  // CONFIG_MIDI_INSTRUMENT  #endif  // CONFIG_MIDI_INSTRUMENT
1273    
1274          // Sampler channel mapping.          // Sampler channel mapping...
1275            int iChannelID = 0;
1276          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
1277                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
1278          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
1279          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
1280                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
1281                  if (pChannelStrip) {                  if (pChannelStrip) {
1282                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1283                          if (pChannel) {                          if (pChannel) {
1284                                  const int iChannelID = pChannel->channelID();                                  // Avoid "artifial" plug-in devices...
1285                                    const int iAudioDevice = pChannel->audioDevice();
1286                                    if (!audioDeviceMap.contains(iAudioDevice))
1287                                            continue;
1288                                    const int iMidiDevice = pChannel->midiDevice();
1289                                    if (!midiDeviceMap.contains(iMidiDevice))
1290                                            continue;
1291                                    // Go for regular, canonical devices...
1292                                  ts << "# " << tr("Channel") << " " << iChannelID << endl;                                  ts << "# " << tr("Channel") << " " << iChannelID << endl;
1293                                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
1294                                  if (audioDeviceMap.isEmpty()) {                                  if (audioDeviceMap.isEmpty()) {
# Line 1239  bool MainForm::saveSessionFile ( const Q Line 1296  bool MainForm::saveSessionFile ( const Q
1296                                                  << " " << pChannel->audioDriver() << endl;                                                  << " " << pChannel->audioDriver() << endl;
1297                                  } else {                                  } else {
1298                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannelID                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannelID
1299                                                  << " " << audioDeviceMap[pChannel->audioDevice()] << endl;                                                  << " " << audioDeviceMap.value(iAudioDevice) << endl;
1300                                  }                                  }
1301                                  if (midiDeviceMap.isEmpty()) {                                  if (midiDeviceMap.isEmpty()) {
1302                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID
1303                                                  << " " << pChannel->midiDriver() << endl;                                                  << " " << pChannel->midiDriver() << endl;
1304                                  } else {                                  } else {
1305                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannelID                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannelID
1306                                                  << " " << midiDeviceMap[pChannel->midiDevice()] << endl;                                                  << " " << midiDeviceMap.value(iMidiDevice) << endl;
1307                                  }                                  }
1308                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID
1309                                          << " " << pChannel->midiPort() << endl;                                          << " " << pChannel->midiPort() << endl;
# Line 1277  bool MainForm::saveSessionFile ( const Q Line 1334  bool MainForm::saveSessionFile ( const Q
1334                                  if (pChannel->channelSolo())                                  if (pChannel->channelSolo())
1335                                          ts << "SET CHANNEL SOLO " << iChannelID << " 1" << endl;                                          ts << "SET CHANNEL SOLO " << iChannelID << " 1" << endl;
1336                          #ifdef CONFIG_MIDI_INSTRUMENT                          #ifdef CONFIG_MIDI_INSTRUMENT
1337                                  if (pChannel->midiMap() >= 0) {                                  const int iMidiMap = pChannel->midiMap();
1338                                    if (midiInstrumentMap.contains(iMidiMap)) {
1339                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannelID                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannelID
1340                                                  << " " << midiInstrumentMap[pChannel->midiMap()] << endl;                                                  << " " << midiInstrumentMap.value(iMidiMap) << endl;
1341                                  }                                  }
1342                          #endif                          #endif
1343                          #ifdef CONFIG_FXSEND                          #ifdef CONFIG_FXSEND
# Line 1318  bool MainForm::saveSessionFile ( const Q Line 1376  bool MainForm::saveSessionFile ( const Q
1376                                  }                                  }
1377                          #endif                          #endif
1378                                  ts << endl;                                  ts << endl;
1379                                    // Go for next channel...
1380                                    ++iChannelID;
1381                          }                          }
1382                  }                  }
1383                  // Try to keep it snappy :)                  // Try to keep it snappy :)
# Line 1423  void MainForm::fileSaveAs (void) Line 1483  void MainForm::fileSaveAs (void)
1483  // Reset the sampler instance.  // Reset the sampler instance.
1484  void MainForm::fileReset (void)  void MainForm::fileReset (void)
1485  {  {
1486          if (m_pClient == NULL)          if (m_pClient == nullptr)
1487                  return;                  return;
1488    
1489          // Ask user whether he/she want's an internal sampler reset...          // Ask user whether he/she want's an internal sampler reset...
1490          if (m_pOptions && m_pOptions->bConfirmReset) {          if (m_pOptions && m_pOptions->bConfirmReset) {
1491                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");                  const QString& sTitle = tr("Warning");
1492                  const QString& sText = tr(                  const QString& sText = tr(
1493                          "Resetting the sampler instance will close\n"                          "Resetting the sampler instance will close\n"
1494                          "all device and channel configurations.\n\n"                          "all device and channel configurations.\n\n"
# Line 1479  void MainForm::fileReset (void) Line 1539  void MainForm::fileReset (void)
1539  // Restart the client/server instance.  // Restart the client/server instance.
1540  void MainForm::fileRestart (void)  void MainForm::fileRestart (void)
1541  {  {
1542          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1543                  return;                  return;
1544    
1545          bool bRestart = true;          bool bRestart = true;
# Line 1487  void MainForm::fileRestart (void) Line 1547  void MainForm::fileRestart (void)
1547          // Ask user whether he/she want's a complete restart...          // Ask user whether he/she want's a complete restart...
1548          // (if we're currently up and running)          // (if we're currently up and running)
1549          if (m_pOptions && m_pOptions->bConfirmRestart) {          if (m_pOptions && m_pOptions->bConfirmRestart) {
1550                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");                  const QString& sTitle = tr("Warning");
1551                  const QString& sText = tr(                  const QString& sText = tr(
1552                          "New settings will be effective after\n"                          "New settings will be effective after\n"
1553                          "restarting the client/server connection.\n\n"                          "restarting the client/server connection.\n\n"
# Line 1547  void MainForm::editAddChannel (void) Line 1607  void MainForm::editAddChannel (void)
1607    
1608  void MainForm::addChannelStrip (void)  void MainForm::addChannelStrip (void)
1609  {  {
1610          if (m_pClient == NULL)          if (m_pClient == nullptr)
1611                  return;                  return;
1612    
1613          // Just create the channel instance...          // Just create the channel instance...
1614          Channel *pChannel = new Channel();          Channel *pChannel = new Channel();
1615          if (pChannel == NULL)          if (pChannel == nullptr)
1616                  return;                  return;
1617    
1618          // 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 1648  void MainForm::editRemoveChannel (void)
1648    
1649  void MainForm::removeChannelStrip (void)  void MainForm::removeChannelStrip (void)
1650  {  {
1651          if (m_pClient == NULL)          if (m_pClient == nullptr)
1652                  return;                  return;
1653    
1654          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1655          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1656                  return;                  return;
1657    
1658          Channel *pChannel = pChannelStrip->channel();          Channel *pChannel = pChannelStrip->channel();
1659          if (pChannel == NULL)          if (pChannel == nullptr)
1660                  return;                  return;
1661    
1662          // Prompt user if he/she's sure about this...          // Prompt user if he/she's sure about this...
1663          if (m_pOptions && m_pOptions->bConfirmRemove) {          if (m_pOptions && m_pOptions->bConfirmRemove) {
1664                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");                  const QString& sTitle = tr("Warning");
1665                  const QString& sText = tr(                  const QString& sText = tr(
1666                          "About to remove channel:\n\n"                          "About to remove channel:\n\n"
1667                          "%1\n\n"                          "%1\n\n"
# Line 1644  void MainForm::removeChannelStrip (void) Line 1704  void MainForm::removeChannelStrip (void)
1704  // Setup current sampler channel.  // Setup current sampler channel.
1705  void MainForm::editSetupChannel (void)  void MainForm::editSetupChannel (void)
1706  {  {
1707          if (m_pClient == NULL)          if (m_pClient == nullptr)
1708                  return;                  return;
1709    
1710          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1711          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1712                  return;                  return;
1713    
1714          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1659  void MainForm::editSetupChannel (void) Line 1719  void MainForm::editSetupChannel (void)
1719  // Edit current sampler channel.  // Edit current sampler channel.
1720  void MainForm::editEditChannel (void)  void MainForm::editEditChannel (void)
1721  {  {
1722          if (m_pClient == NULL)          if (m_pClient == nullptr)
1723                  return;                  return;
1724    
1725          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1726          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1727                  return;                  return;
1728    
1729          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1674  void MainForm::editEditChannel (void) Line 1734  void MainForm::editEditChannel (void)
1734  // Reset current sampler channel.  // Reset current sampler channel.
1735  void MainForm::editResetChannel (void)  void MainForm::editResetChannel (void)
1736  {  {
1737          if (m_pClient == NULL)          if (m_pClient == nullptr)
1738                  return;                  return;
1739    
1740          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1741          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1742                  return;                  return;
1743    
1744          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1689  void MainForm::editResetChannel (void) Line 1749  void MainForm::editResetChannel (void)
1749  // Reset all sampler channels.  // Reset all sampler channels.
1750  void MainForm::editResetAllChannels (void)  void MainForm::editResetAllChannels (void)
1751  {  {
1752          if (m_pClient == NULL)          if (m_pClient == nullptr)
1753                  return;                  return;
1754    
1755          // Invoque the channel strip procedure,          // Invoque the channel strip procedure,
# Line 1697  void MainForm::editResetAllChannels (voi Line 1757  void MainForm::editResetAllChannels (voi
1757          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1758          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
1759                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
1760          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
1761          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
1762                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
1763                  if (pChannelStrip)                  if (pChannelStrip)
1764                          pChannelStrip->channelReset();                          pChannelStrip->channelReset();
1765          }          }
# Line 1761  void MainForm::viewMessages ( bool bOn ) Line 1818  void MainForm::viewMessages ( bool bOn )
1818  // Show/hide the MIDI instrument list-view form.  // Show/hide the MIDI instrument list-view form.
1819  void MainForm::viewInstruments (void)  void MainForm::viewInstruments (void)
1820  {  {
1821          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1822                  return;                  return;
1823    
1824          if (m_pInstrumentListForm) {          if (m_pInstrumentListForm) {
# Line 1780  void MainForm::viewInstruments (void) Line 1837  void MainForm::viewInstruments (void)
1837  // Show/hide the device configurator form.  // Show/hide the device configurator form.
1838  void MainForm::viewDevices (void)  void MainForm::viewDevices (void)
1839  {  {
1840          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1841                  return;                  return;
1842    
1843          if (m_pDeviceForm) {          if (m_pDeviceForm) {
# Line 1799  void MainForm::viewDevices (void) Line 1856  void MainForm::viewDevices (void)
1856  // Show options dialog.  // Show options dialog.
1857  void MainForm::viewOptions (void)  void MainForm::viewOptions (void)
1858  {  {
1859          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1860                  return;                  return;
1861    
1862          OptionsForm* pOptionsForm = new OptionsForm(this);          OptionsForm* pOptionsForm = new OptionsForm(this);
# Line 1841  void MainForm::viewOptions (void) Line 1898  void MainForm::viewOptions (void)
1898                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)     ||                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)     ||
1899                                  (iOldBaseFontSize   !=  m_pOptions->iBaseFontSize)) {                                  (iOldBaseFontSize   !=  m_pOptions->iBaseFontSize)) {
1900                                  QMessageBox::information(this,                                  QMessageBox::information(this,
1901                                          QSAMPLER_TITLE ": " + tr("Information"),                                          tr("Information"),
1902                                          tr("Some settings may be only effective\n"                                          tr("Some settings may be only effective\n"
1903                                          "next time you start this program."));                                          "next time you start this program."));
1904                                  updateMessagesCapture();                                  updateMessagesCapture();
# Line 1905  void MainForm::channelsArrange (void) Line 1962  void MainForm::channelsArrange (void)
1962    
1963          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1964          int y = 0;          int y = 0;
1965          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
1966          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  pMdiSubWindow->adjustSize();
1967                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);                  const QRect& frameRect
1968                  if (pMdiSubWindow) {                          = pMdiSubWindow->frameGeometry();
1969                          pMdiSubWindow->adjustSize();                  int w = m_pWorkspace->width();
1970                          int iWidth = m_pWorkspace->width();                  if (w < frameRect.width())
1971                          if (iWidth < pMdiSubWindow->width())                          w = frameRect.width();
1972                                  iWidth = pMdiSubWindow->width();                  const int h = frameRect.height();
1973                          const int iHeight = pMdiSubWindow->frameGeometry().height();                  pMdiSubWindow->setGeometry(0, y, w, h);
1974                          pMdiSubWindow->setGeometry(0, y, iWidth, iHeight);                  y += h;
                         y += iHeight;  
                 }  
1975          }          }
1976          m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
1977    
# Line 1927  void MainForm::channelsArrange (void) Line 1982  void MainForm::channelsArrange (void)
1982  // Auto-arrange channel strips.  // Auto-arrange channel strips.
1983  void MainForm::channelsAutoArrange ( bool bOn )  void MainForm::channelsAutoArrange ( bool bOn )
1984  {  {
1985          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1986                  return;                  return;
1987    
1988          // Toggle the auto-arrange flag.          // Toggle the auto-arrange flag.
# Line 2031  void MainForm::helpAbout (void) Line 2086  void MainForm::helpAbout (void)
2086          sText += "</small>";          sText += "</small>";
2087          sText += "</p>\n";          sText += "</p>\n";
2088    
2089          QMessageBox::about(this, tr("About") + " " QSAMPLER_TITLE, sText);          QMessageBox::about(this, tr("About"), sText);
2090  }  }
2091    
2092    
# Line 2044  void MainForm::stabilizeForm (void) Line 2099  void MainForm::stabilizeForm (void)
2099          QString sSessionName = sessionName(m_sFilename);          QString sSessionName = sessionName(m_sFilename);
2100          if (m_iDirtyCount > 0)          if (m_iDirtyCount > 0)
2101                  sSessionName += " *";                  sSessionName += " *";
2102          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));          setWindowTitle(sSessionName);
2103    
2104          // Update the main menu state...          // Update the main menu state...
2105          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
2106          const QList<QMdiSubWindow *>& wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist = m_pWorkspace->subWindowList();
2107          const bool bHasClient = (m_pOptions != NULL && m_pClient != NULL);          const bool bHasClient = (m_pOptions != nullptr && m_pClient != nullptr);
2108          const bool bHasChannel = (bHasClient && pChannelStrip != NULL);          const bool bHasChannel = (bHasClient && pChannelStrip != nullptr);
2109          const bool bHasChannels = (bHasClient && wlist.count() > 0);          const bool bHasChannels = (bHasClient && wlist.count() > 0);
2110          m_ui.fileNewAction->setEnabled(bHasClient);          m_ui.fileNewAction->setEnabled(bHasClient);
2111          m_ui.fileOpenAction->setEnabled(bHasClient);          m_ui.fileOpenAction->setEnabled(bHasClient);
2112          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
2113          m_ui.fileSaveAsAction->setEnabled(bHasClient);          m_ui.fileSaveAsAction->setEnabled(bHasClient);
2114          m_ui.fileResetAction->setEnabled(bHasClient);          m_ui.fileResetAction->setEnabled(bHasClient);
2115          m_ui.fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);          m_ui.fileRestartAction->setEnabled(bHasClient || m_pServer == nullptr);
2116          m_ui.editAddChannelAction->setEnabled(bHasClient);          m_ui.editAddChannelAction->setEnabled(bHasClient);
2117          m_ui.editRemoveChannelAction->setEnabled(bHasChannel);          m_ui.editRemoveChannelAction->setEnabled(bHasChannel);
2118          m_ui.editSetupChannelAction->setEnabled(bHasChannel);          m_ui.editSetupChannelAction->setEnabled(bHasChannel);
# Line 2206  void MainForm::updateAllChannelStrips ( Line 2261  void MainForm::updateAllChannelStrips (
2261    
2262          // Retrieve the current channel list.          // Retrieve the current channel list.
2263          int *piChannelIDs = ::lscp_list_channels(m_pClient);          int *piChannelIDs = ::lscp_list_channels(m_pClient);
2264          if (piChannelIDs == NULL) {          if (piChannelIDs == nullptr) {
2265                  if (::lscp_client_get_errno(m_pClient)) {                  if (::lscp_client_get_errno(m_pClient)) {
2266                          appendMessagesClient("lscp_list_channels");                          appendMessagesClient("lscp_list_channels");
2267                          appendMessagesError(                          appendMessagesError(
# Line 2226  void MainForm::updateAllChannelStrips ( Line 2281  void MainForm::updateAllChannelStrips (
2281                  if (bRemoveDeadStrips) {                  if (bRemoveDeadStrips) {
2282                          const QList<QMdiSubWindow *>& wlist                          const QList<QMdiSubWindow *>& wlist
2283                                  = m_pWorkspace->subWindowList();                                  = m_pWorkspace->subWindowList();
2284                          const int iStripCount = wlist.count();                          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2285                          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                                  ChannelStrip *pChannelStrip
2286                                  ChannelStrip *pChannelStrip = NULL;                                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                                 if (pMdiSubWindow)  
                                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2287                                  if (pChannelStrip) {                                  if (pChannelStrip) {
2288                                          bool bExists = false;                                          bool bExists = false;
2289                                          for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {                                          for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {
2290                                                  Channel *pChannel = pChannelStrip->channel();                                                  Channel *pChannel = pChannelStrip->channel();
2291                                                  if (pChannel == NULL)                                                  if (pChannel == nullptr)
2292                                                          break;                                                          break;
2293                                                  if (piChannelIDs[iChannel] == pChannel->channelID()) {                                                  if (piChannelIDs[iChannel] == pChannel->channelID()) {
2294                                                          // strip exists, don't touch it                                                          // strip exists, don't touch it
# Line 2259  void MainForm::updateAllChannelStrips ( Line 2311  void MainForm::updateAllChannelStrips (
2311  // Update the recent files list and menu.  // Update the recent files list and menu.
2312  void MainForm::updateRecentFiles ( const QString& sFilename )  void MainForm::updateRecentFiles ( const QString& sFilename )
2313  {  {
2314          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2315                  return;                  return;
2316    
2317          // Remove from list if already there (avoid duplicates)          // Remove from list if already there (avoid duplicates)
# Line 2274  void MainForm::updateRecentFiles ( const Line 2326  void MainForm::updateRecentFiles ( const
2326  // Update the recent files list and menu.  // Update the recent files list and menu.
2327  void MainForm::updateRecentFilesMenu (void)  void MainForm::updateRecentFilesMenu (void)
2328  {  {
2329          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2330                  return;                  return;
2331    
2332          // Time to keep the list under limits.          // Time to keep the list under limits.
# Line 2308  void MainForm::updateInstrumentNames (vo Line 2360  void MainForm::updateInstrumentNames (vo
2360                  return;                  return;
2361    
2362          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2363          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2364          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2365                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2366                  if (pChannelStrip)                  if (pChannelStrip)
2367                          pChannelStrip->updateInstrumentName(true);                          pChannelStrip->updateInstrumentName(true);
2368          }          }
# Line 2324  void MainForm::updateInstrumentNames (vo Line 2373  void MainForm::updateInstrumentNames (vo
2373  // Force update of the channels display font.  // Force update of the channels display font.
2374  void MainForm::updateDisplayFont (void)  void MainForm::updateDisplayFont (void)
2375  {  {
2376          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2377                  return;                  return;
2378    
2379          // Check if display font is legal.          // Check if display font is legal.
# Line 2343  void MainForm::updateDisplayFont (void) Line 2392  void MainForm::updateDisplayFont (void)
2392                  return;                  return;
2393    
2394          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2395          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2396          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2397                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2398                  if (pChannelStrip)                  if (pChannelStrip)
2399                          pChannelStrip->setDisplayFont(font);                          pChannelStrip->setDisplayFont(font);
2400          }          }
# Line 2366  void MainForm::updateDisplayEffect (void Line 2412  void MainForm::updateDisplayEffect (void
2412                  return;                  return;
2413    
2414          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2415          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2416          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2417                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2418                  if (pChannelStrip)                  if (pChannelStrip)
2419                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2420          }          }
# Line 2382  void MainForm::updateDisplayEffect (void Line 2425  void MainForm::updateDisplayEffect (void
2425  // Force update of the channels maximum volume setting.  // Force update of the channels maximum volume setting.
2426  void MainForm::updateMaxVolume (void)  void MainForm::updateMaxVolume (void)
2427  {  {
2428          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2429                  return;                  return;
2430    
2431  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
# Line 2399  void MainForm::updateMaxVolume (void) Line 2442  void MainForm::updateMaxVolume (void)
2442                  return;                  return;
2443    
2444          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2445          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2446          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2447                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2448                  if (pChannelStrip)                  if (pChannelStrip)
2449                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2450          }          }
# Line 2449  void MainForm::appendMessagesError( cons Line 2489  void MainForm::appendMessagesError( cons
2489          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2490    
2491          if (m_pOptions && m_pOptions->bConfirmError) {          if (m_pOptions && m_pOptions->bConfirmError) {
2492                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Error");                  const QString& sTitle = tr("Error");
2493          #if 0          #if 0
2494                  QMessageBox::critical(this, sTitle, sText, QMessageBox::Cancel);                  QMessageBox::critical(this, sTitle, sText, QMessageBox::Cancel);
2495          #else          #else
# Line 2472  void MainForm::appendMessagesError( cons Line 2512  void MainForm::appendMessagesError( cons
2512  // This is a special message format, just for client results.  // This is a special message format, just for client results.
2513  void MainForm::appendMessagesClient( const QString& s )  void MainForm::appendMessagesClient( const QString& s )
2514  {  {
2515          if (m_pClient == NULL)          if (m_pClient == nullptr)
2516                  return;                  return;
2517    
2518          appendMessagesColor(s + QString(": %1 (errno=%2)")          appendMessagesColor(s + QString(": %1 (errno=%2)")
# Line 2487  void MainForm::appendMessagesClient( con Line 2527  void MainForm::appendMessagesClient( con
2527  // Force update of the messages font.  // Force update of the messages font.
2528  void MainForm::updateMessagesFont (void)  void MainForm::updateMessagesFont (void)
2529  {  {
2530          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2531                  return;                  return;
2532    
2533          if (m_pMessages && !m_pOptions->sMessagesFont.isEmpty()) {          if (m_pMessages && !m_pOptions->sMessagesFont.isEmpty()) {
# Line 2501  void MainForm::updateMessagesFont (void) Line 2541  void MainForm::updateMessagesFont (void)
2541  // Update messages window line limit.  // Update messages window line limit.
2542  void MainForm::updateMessagesLimit (void)  void MainForm::updateMessagesLimit (void)
2543  {  {
2544          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2545                  return;                  return;
2546    
2547          if (m_pMessages) {          if (m_pMessages) {
# Line 2516  void MainForm::updateMessagesLimit (void Line 2556  void MainForm::updateMessagesLimit (void
2556  // Enablement of the messages capture feature.  // Enablement of the messages capture feature.
2557  void MainForm::updateMessagesCapture (void)  void MainForm::updateMessagesCapture (void)
2558  {  {
2559          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2560                  return;                  return;
2561    
2562          if (m_pMessages)          if (m_pMessages)
# Line 2530  void MainForm::updateMessagesCapture (vo Line 2570  void MainForm::updateMessagesCapture (vo
2570  // The channel strip creation executive.  // The channel strip creation executive.
2571  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )
2572  {  {
2573          if (m_pClient == NULL || pChannel == NULL)          if (m_pClient == nullptr || pChannel == nullptr)
2574                  return NULL;                  return nullptr;
2575    
2576          // Add a new channel itema...          // Add a new channel itema...
2577          ChannelStrip *pChannelStrip = new ChannelStrip();          ChannelStrip *pChannelStrip = new ChannelStrip();
2578          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
2579                  return NULL;                  return nullptr;
2580    
2581          // Set some initial channel strip options...          // Set some initial channel strip options...
2582          if (m_pOptions) {          if (m_pOptions) {
# Line 2552  ChannelStrip *MainForm::createChannelStr Line 2592  ChannelStrip *MainForm::createChannelStr
2592          }          }
2593    
2594          // Add it to workspace...          // Add it to workspace...
2595          m_pWorkspace->addSubWindow(pChannelStrip,          QMdiSubWindow *pMdiSubWindow
2596                  Qt::SubWindow | Qt::FramelessWindowHint);                  = m_pWorkspace->addSubWindow(pChannelStrip,
2597                            Qt::SubWindow | Qt::FramelessWindowHint);
2598            pMdiSubWindow->setAttribute(Qt::WA_DeleteOnClose);
2599    
2600          // Actual channel strip setup...          // Actual channel strip setup...
2601          pChannelStrip->setup(pChannel);          pChannelStrip->setup(pChannel);
# Line 2577  void MainForm::destroyChannelStrip ( Cha Line 2619  void MainForm::destroyChannelStrip ( Cha
2619  {  {
2620          QMdiSubWindow *pMdiSubWindow          QMdiSubWindow *pMdiSubWindow
2621                  = static_cast<QMdiSubWindow *> (pChannelStrip->parentWidget());                  = static_cast<QMdiSubWindow *> (pChannelStrip->parentWidget());
2622          if (pMdiSubWindow == NULL)          if (pMdiSubWindow == nullptr)
2623                  return;                  return;
2624    
2625          // Just delete the channel strip.          // Just delete the channel strip.
# Line 2596  ChannelStrip *MainForm::activeChannelStr Line 2638  ChannelStrip *MainForm::activeChannelStr
2638          if (pMdiSubWindow)          if (pMdiSubWindow)
2639                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2640          else          else
2641                  return NULL;                  return nullptr;
2642  }  }
2643    
2644    
2645  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2646  ChannelStrip *MainForm::channelStripAt ( int iStrip )  ChannelStrip *MainForm::channelStripAt ( int iStrip )
2647  {  {
2648          if (!m_pWorkspace) return NULL;          if (!m_pWorkspace) return nullptr;
2649    
2650          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
2651                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
2652          if (wlist.isEmpty())          if (wlist.isEmpty())
2653                  return NULL;                  return nullptr;
2654    
2655          if (iStrip < 0 || iStrip >= wlist.count())          if (iStrip < 0 || iStrip >= wlist.count())
2656                  return NULL;                  return nullptr;
2657    
2658          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2659          if (pMdiSubWindow)          if (pMdiSubWindow)
2660                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2661          else          else
2662                  return NULL;                  return nullptr;
2663  }  }
2664    
2665    
# Line 2627  ChannelStrip *MainForm::channelStrip ( i Line 2669  ChannelStrip *MainForm::channelStrip ( i
2669          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
2670                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
2671          if (wlist.isEmpty())          if (wlist.isEmpty())
2672                  return NULL;                  return nullptr;
2673    
2674          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2675          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2676                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2677                  if (pChannelStrip) {                  if (pChannelStrip) {
2678                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
2679                          if (pChannel && pChannel->channelID() == iChannelID)                          if (pChannel && pChannel->channelID() == iChannelID)
# Line 2643  ChannelStrip *MainForm::channelStrip ( i Line 2682  ChannelStrip *MainForm::channelStrip ( i
2682          }          }
2683    
2684          // Not found.          // Not found.
2685          return NULL;          return nullptr;
2686  }  }
2687    
2688    
# Line 2658  void MainForm::channelsMenuAboutToShow ( Line 2697  void MainForm::channelsMenuAboutToShow (
2697                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
2698          if (!wlist.isEmpty()) {          if (!wlist.isEmpty()) {
2699                  m_ui.channelsMenu->addSeparator();                  m_ui.channelsMenu->addSeparator();
2700                  const int iStripCount = wlist.count();                  int iStrip = 0;
2701                  for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2702                          ChannelStrip *pChannelStrip = NULL;                          ChannelStrip *pChannelStrip
2703                          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                         if (pMdiSubWindow)  
                                 pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2704                          if (pChannelStrip) {                          if (pChannelStrip) {
2705                                  QAction *pAction = m_ui.channelsMenu->addAction(                                  QAction *pAction = m_ui.channelsMenu->addAction(
2706                                          pChannelStrip->windowTitle(),                                          pChannelStrip->windowTitle(),
# Line 2672  void MainForm::channelsMenuAboutToShow ( Line 2709  void MainForm::channelsMenuAboutToShow (
2709                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);
2710                                  pAction->setData(iStrip);                                  pAction->setData(iStrip);
2711                          }                          }
2712                            ++iStrip;
2713                  }                  }
2714          }          }
2715  }  }
# Line 2682  void MainForm::channelsMenuActivated (vo Line 2720  void MainForm::channelsMenuActivated (vo
2720  {  {
2721          // Retrive channel index from action data...          // Retrive channel index from action data...
2722          QAction *pAction = qobject_cast<QAction *> (sender());          QAction *pAction = qobject_cast<QAction *> (sender());
2723          if (pAction == NULL)          if (pAction == nullptr)
2724                  return;                  return;
2725    
2726          ChannelStrip *pChannelStrip = channelStripAt(pAction->data().toInt());          ChannelStrip *pChannelStrip = channelStripAt(pAction->data().toInt());
# Line 2713  void MainForm::stopSchedule (void) Line 2751  void MainForm::stopSchedule (void)
2751  // Timer slot funtion.  // Timer slot funtion.
2752  void MainForm::timerSlot (void)  void MainForm::timerSlot (void)
2753  {  {
2754          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2755                  return;                  return;
2756    
2757          // 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 2786  void MainForm::timerSlot (void)
2786                                  // Update the channel stream usage for each strip...                                  // Update the channel stream usage for each strip...
2787                                  const QList<QMdiSubWindow *>& wlist                                  const QList<QMdiSubWindow *>& wlist
2788                                          = m_pWorkspace->subWindowList();                                          = m_pWorkspace->subWindowList();
2789                                  const int iStripCount = wlist.count();                                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2790                                  for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                                          ChannelStrip *pChannelStrip
2791                                          ChannelStrip *pChannelStrip = NULL;                                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                                         QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                                         if (pMdiSubWindow)  
                                                 pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2792                                          if (pChannelStrip && pChannelStrip->isVisible())                                          if (pChannelStrip && pChannelStrip->isVisible())
2793                                                  pChannelStrip->updateChannelUsage();                                                  pChannelStrip->updateChannelUsage();
2794                                  }                                  }
2795                          }                          }
2796                  }                  }
2797    
2798            #if CONFIG_LSCP_CLIENT_CONNECTION_LOST
2799                    // If we lost connection to server: Try to automatically reconnect if we
2800                    // did not start the server.
2801                    //
2802                    // TODO: If we started the server, then we might inform the user that
2803                    // the server probably crashed and asking user ONCE whether we should
2804                    // restart the server.
2805                    if (lscp_client_connection_lost(m_pClient) && !m_pServer)
2806                            startAutoReconnectClient();
2807            #endif // CONFIG_LSCP_CLIENT_CONNECTION_LOST
2808          }          }
2809    
2810          // Register the next timer slot.          // Register the next timer slot.
# Line 2772  void MainForm::timerSlot (void) Line 2818  void MainForm::timerSlot (void)
2818  // Start linuxsampler server...  // Start linuxsampler server...
2819  void MainForm::startServer (void)  void MainForm::startServer (void)
2820  {  {
2821          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2822                  return;                  return;
2823    
2824          // Aren't already a client, are we?          // Aren't already a client, are we?
# Line 2782  void MainForm::startServer (void) Line 2828  void MainForm::startServer (void)
2828          // Is the server process instance still here?          // Is the server process instance still here?
2829          if (m_pServer) {          if (m_pServer) {
2830                  if (QMessageBox::warning(this,                  if (QMessageBox::warning(this,
2831                          QSAMPLER_TITLE ": " + tr("Warning"),                          tr("Warning"),
2832                          tr("Could not start the LinuxSampler server.\n\n"                          tr("Could not start the LinuxSampler server.\n\n"
2833                          "Maybe it is already started."),                          "Maybe it is already started."),
2834                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
# Line 2852  void MainForm::stopServer ( bool bIntera Line 2898  void MainForm::stopServer ( bool bIntera
2898    
2899          if (m_pServer && bInteractive) {          if (m_pServer && bInteractive) {
2900                  if (QMessageBox::question(this,                  if (QMessageBox::question(this,
2901                          QSAMPLER_TITLE ": " + tr("The backend's fate ..."),                          tr("The backend's fate ..."),
2902                          tr("You have the option to keep the sampler backend (LinuxSampler)\n"                          tr("You have the option to keep the sampler backend (LinuxSampler)\n"
2903                          "running in the background. The sampler would continue to work\n"                          "running in the background. The sampler would continue to work\n"
2904                          "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 2910  void MainForm::stopServer ( bool bIntera
2910                  }                  }
2911          }          }
2912    
2913            bool bGraceWait = true;
2914    
2915          // And try to stop server.          // And try to stop server.
2916          if (m_pServer && m_bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2917                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2918                  if (m_pServer->state() == QProcess::Running) {                  if (m_pServer->state() == QProcess::Running) {
2919                  #if defined(_WIN32)                  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
2920                          // Try harder...                          // Try harder...
2921                          m_pServer->kill();                          m_pServer->kill();
2922                  #else                  #else
2923                          // Try softly...                          // Try softly...
2924                          m_pServer->terminate();                          m_pServer->terminate();
2925                            bool bFinished = m_pServer->waitForFinished(QSAMPLER_TIMER_MSECS * 1000);
2926                            if (bFinished) bGraceWait = false;
2927                  #endif                  #endif
2928                  }                  }
2929          }       // Do final processing anyway.          }       // Do final processing anyway.
2930          else processServerExit();          else processServerExit();
2931    
2932          // Give it some time to terminate gracefully and stabilize...          // Give it some time to terminate gracefully and stabilize...
2933          QTime t;          if (bGraceWait) {
2934          t.start();                  QElapsedTimer timer;
2935          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                  timer.start();
2936                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  while (timer.elapsed() < QSAMPLER_TIMER_MSECS)
2937                            QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2938            }
2939  }  }
2940    
2941    
# Line 2911  void MainForm::processServerExit (void) Line 2963  void MainForm::processServerExit (void)
2963                          // Force final server shutdown...                          // Force final server shutdown...
2964                          m_pServer->kill();                          m_pServer->kill();
2965                          // Give it some time to terminate gracefully and stabilize...                          // Give it some time to terminate gracefully and stabilize...
2966                          QTime t;                          QElapsedTimer timer;
2967                          t.start();                          timer.start();
2968                          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                          while (timer.elapsed() < QSAMPLER_TIMER_MSECS)
2969                                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2970                  }                  }
2971                  // Force final server shutdown...                  // Force final server shutdown...
# Line 2921  void MainForm::processServerExit (void) Line 2973  void MainForm::processServerExit (void)
2973                          tr("Server was stopped with exit status %1.")                          tr("Server was stopped with exit status %1.")
2974                          .arg(m_pServer->exitStatus()));                          .arg(m_pServer->exitStatus()));
2975                  delete m_pServer;                  delete m_pServer;
2976                  m_pServer = NULL;                  m_pServer = nullptr;
2977          }          }
2978    
2979          // Again, make status visible stable.          // Again, make status visible stable.
# Line 2937  lscp_status_t qsampler_client_callback ( Line 2989  lscp_status_t qsampler_client_callback (
2989          lscp_event_t event, const char *pchData, int cchData, void *pvData )          lscp_event_t event, const char *pchData, int cchData, void *pvData )
2990  {  {
2991          MainForm* pMainForm = (MainForm *) pvData;          MainForm* pMainForm = (MainForm *) pvData;
2992          if (pMainForm == NULL)          if (pMainForm == nullptr)
2993                  return LSCP_FAILED;                  return LSCP_FAILED;
2994    
2995          // 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 3003  lscp_status_t qsampler_client_callback (
3003    
3004    
3005  // Start our almighty client...  // Start our almighty client...
3006  bool MainForm::startClient (void)  bool MainForm::startClient (bool bReconnectOnly)
3007  {  {
3008          // Have it a setup?          // Have it a setup?
3009          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
3010                  return false;                  return false;
3011    
3012          // Aren't we already started, are we?          // Aren't we already started, are we?
# Line 2968  bool MainForm::startClient (void) Line 3020  bool MainForm::startClient (void)
3020          m_pClient = ::lscp_client_create(          m_pClient = ::lscp_client_create(
3021                  m_pOptions->sServerHost.toUtf8().constData(),                  m_pOptions->sServerHost.toUtf8().constData(),
3022                  m_pOptions->iServerPort, qsampler_client_callback, this);                  m_pOptions->iServerPort, qsampler_client_callback, this);
3023          if (m_pClient == NULL) {          if (m_pClient == nullptr) {
3024                  // Is this the first try?                  // Is this the first try?
3025                  // maybe we need to start a local server...                  // maybe we need to start a local server...
3026                  if ((m_pServer && m_pServer->state() == QProcess::Running)                  if ((m_pServer && m_pServer->state() == QProcess::Running)
3027                          || !m_pOptions->bServerStart) {                          || !m_pOptions->bServerStart || bReconnectOnly)
3028                          appendMessagesError(                  {
3029                                  tr("Could not connect to server as client.\n\nSorry."));                          // if this method is called from autoReconnectClient()
3030                            // then don't bother user with an error message...
3031                            if (!bReconnectOnly) {
3032                                    appendMessagesError(
3033                                            tr("Could not connect to server as client.\n\nSorry.")
3034                                    );
3035                            }
3036                  } else {                  } else {
3037                          startServer();                          startServer();
3038                  }                  }
# Line 3038  bool MainForm::startClient (void) Line 3096  bool MainForm::startClient (void)
3096          if (!m_pOptions->sSessionFile.isEmpty()) {          if (!m_pOptions->sSessionFile.isEmpty()) {
3097                  // Just load the prabably startup session...                  // Just load the prabably startup session...
3098                  if (loadSessionFile(m_pOptions->sSessionFile)) {                  if (loadSessionFile(m_pOptions->sSessionFile)) {
3099                          m_pOptions->sSessionFile = QString::null;                          m_pOptions->sSessionFile = QString();
3100                          return true;                          return true;
3101                  }                  }
3102          }          }
# Line 3054  bool MainForm::startClient (void) Line 3112  bool MainForm::startClient (void)
3112  // Stop client...  // Stop client...
3113  void MainForm::stopClient (void)  void MainForm::stopClient (void)
3114  {  {
3115          if (m_pClient == NULL)          if (m_pClient == nullptr)
3116                  return;                  return;
3117    
3118          // Log prepare here.          // Log prepare here.
# Line 3086  void MainForm::stopClient (void) Line 3144  void MainForm::stopClient (void)
3144          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
3145          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);
3146          ::lscp_client_destroy(m_pClient);          ::lscp_client_destroy(m_pClient);
3147          m_pClient = NULL;          m_pClient = nullptr;
3148    
3149          // Hard-notify instrumnet and device configuration forms,          // Hard-notify instrumnet and device configuration forms,
3150          // if visible, that we're running out...          // if visible, that we're running out...
# Line 3103  void MainForm::stopClient (void) Line 3161  void MainForm::stopClient (void)
3161  }  }
3162    
3163    
3164    void MainForm::startAutoReconnectClient (void)
3165    {
3166            stopClient();
3167            appendMessages(tr("Trying to reconnect..."));
3168            QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(autoReconnectClient()));
3169    }
3170    
3171    
3172    void MainForm::autoReconnectClient (void)
3173    {
3174            const bool bSuccess = startClient(true);
3175            if (!bSuccess)
3176                    QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(autoReconnectClient()));
3177    }
3178    
3179    
3180  // Channel strip activation/selection.  // Channel strip activation/selection.
3181  void MainForm::activateStrip ( QMdiSubWindow *pMdiSubWindow )  void MainForm::activateStrip ( QMdiSubWindow *pMdiSubWindow )
3182  {  {
3183          ChannelStrip *pChannelStrip = NULL;          ChannelStrip *pChannelStrip = nullptr;
3184          if (pMdiSubWindow)          if (pMdiSubWindow)
3185                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
3186          if (pChannelStrip)          if (pChannelStrip)

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

  ViewVC Help
Powered by ViewVC