/[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 3789 by capela, Thu Jun 11 19:26:44 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 35  Line 35 
35  #include "qsamplerOptionsForm.h"  #include "qsamplerOptionsForm.h"
36  #include "qsamplerDeviceStatusForm.h"  #include "qsamplerDeviceStatusForm.h"
37    
38    #include "qsamplerPaletteForm.h"
39    
40    #include <QStyleFactory>
41    
42  #include <QMdiArea>  #include <QMdiArea>
43  #include <QMdiSubWindow>  #include <QMdiSubWindow>
44    
# Line 58  Line 62 
62  #include <QTimer>  #include <QTimer>
63  #include <QDateTime>  #include <QDateTime>
64    
65  #if QT_VERSION >= 0x050000  #include <QElapsedTimer>
66    
67    #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
68  #include <QMimeData>  #include <QMimeData>
69  #endif  #endif
70    
71  #if QT_VERSION < 0x040500  #if QT_VERSION < QT_VERSION_CHECK(4, 5, 0)
72  namespace Qt {  namespace Qt {
73  const WindowFlags WindowCloseButtonHint = WindowFlags(0x08000000);  const WindowFlags WindowCloseButtonHint = WindowFlags(0x08000000);
74  }  }
75  #endif  #endif
76    
 #ifdef HAVE_SIGNAL_H  
 #include <signal.h>  
 #endif  
   
77  #ifdef CONFIG_LIBGIG  #ifdef CONFIG_LIBGIG
78  #include <gig.h>  #include <gig.h>
79  #endif  #endif
80    
81    // Deprecated QTextStreamFunctions/Qt namespaces workaround.
82    #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
83    #define endl    Qt::endl
84    #endif
85    
86  // Needed for lroundf()  // Needed for lroundf()
87  #include <math.h>  #include <math.h>
88    
# Line 91  static inline long lroundf ( float x ) Line 98  static inline long lroundf ( float x )
98    
99    
100  // All winsock apps needs this.  // All winsock apps needs this.
101  #if defined(_WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
102  static WSADATA _wsaData;  static WSADATA _wsaData;
103    #undef HAVE_SIGNAL_H
104  #endif  #endif
105    
106    
# Line 103  static WSADATA _wsaData; Line 111  static WSADATA _wsaData;
111    
112  #include <QSocketNotifier>  #include <QSocketNotifier>
113    
114    #include <unistd.h>
115  #include <sys/types.h>  #include <sys/types.h>
116  #include <sys/socket.h>  #include <sys/socket.h>
   
117  #include <signal.h>  #include <signal.h>
118    
119  // File descriptor for SIGUSR1 notifier.  // File descriptor for SIGUSR1 notifier.
120  static int g_fdUsr1[2];  static int g_fdSigusr1[2] = { -1, -1 };
121    
122  // Unix SIGUSR1 signal handler.  // Unix SIGUSR1 signal handler.
123  static void qsampler_sigusr1_handler ( int /* signo */ )  static void qsampler_sigusr1_handler ( int /* signo */ )
124  {  {
125          char c = 1;          char c = 1;
126    
127          (::write(g_fdUsr1[0], &c, sizeof(c)) > 0);          (::write(g_fdSigusr1[0], &c, sizeof(c)) > 0);
128    }
129    
130    // File descriptor for SIGTERM notifier.
131    static int g_fdSigterm[2] = { -1, -1 };
132    
133    // Unix SIGTERM signal handler.
134    static void qsampler_sigterm_handler ( int /* signo */ )
135    {
136            char c = 1;
137    
138            (::write(g_fdSigterm[0], &c, sizeof(c)) > 0);
139  }  }
140    
141  #endif  // HAVE_SIGNAL_H  #endif  // HAVE_SIGNAL_H
# Line 194  protected: Line 213  protected:
213  // QSampler::MainForm -- Main window form implementation.  // QSampler::MainForm -- Main window form implementation.
214    
215  // Kind of singleton reference.  // Kind of singleton reference.
216  MainForm *MainForm::g_pMainForm = NULL;  MainForm *MainForm::g_pMainForm = nullptr;
217    
218  MainForm::MainForm ( QWidget *pParent )  MainForm::MainForm ( QWidget *pParent )
219          : QMainWindow(pParent)          : QMainWindow(pParent)
# Line 205  MainForm::MainForm ( QWidget *pParent ) Line 224  MainForm::MainForm ( QWidget *pParent )
224          g_pMainForm = this;          g_pMainForm = this;
225    
226          // Initialize some pointer references.          // Initialize some pointer references.
227          m_pOptions = NULL;          m_pOptions = nullptr;
228    
229          // All child forms are to be created later, not earlier than setup.          // All child forms are to be created later, not earlier than setup.
230          m_pMessages = NULL;          m_pMessages = nullptr;
231          m_pInstrumentListForm = NULL;          m_pInstrumentListForm = nullptr;
232          m_pDeviceForm = NULL;          m_pDeviceForm = nullptr;
233    
234          // We'll start clean.          // We'll start clean.
235          m_iUntitled   = 0;          m_iUntitled   = 0;
236          m_iDirtySetup = 0;          m_iDirtySetup = 0;
237          m_iDirtyCount = 0;          m_iDirtyCount = 0;
238    
239          m_pServer = NULL;          m_pServer = nullptr;
240          m_pClient = NULL;          m_pClient = nullptr;
241    
242          m_iStartDelay = 0;          m_iStartDelay = 0;
243          m_iTimerDelay = 0;          m_iTimerDelay = 0;
# Line 233  MainForm::MainForm ( QWidget *pParent ) Line 252  MainForm::MainForm ( QWidget *pParent )
252          // LADISH Level 1 suport.          // LADISH Level 1 suport.
253    
254          // Initialize file descriptors for SIGUSR1 socket notifier.          // Initialize file descriptors for SIGUSR1 socket notifier.
255          ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdUsr1);          ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigusr1);
256          m_pUsr1Notifier          m_pSigusr1Notifier
257                  = new QSocketNotifier(g_fdUsr1[1], QSocketNotifier::Read, this);                  = new QSocketNotifier(g_fdSigusr1[1], QSocketNotifier::Read, this);
258    
259          QObject::connect(m_pUsr1Notifier,          QObject::connect(m_pSigusr1Notifier,
260                  SIGNAL(activated(int)),                  SIGNAL(activated(int)),
261                  SLOT(handle_sigusr1()));                  SLOT(handle_sigusr1()));
262    
263          // Install SIGUSR1 signal handler.          // Install SIGUSR1 signal handler.
264      struct sigaction usr1;          struct sigaction sigusr1;
265      usr1.sa_handler = qsampler_sigusr1_handler;          sigusr1.sa_handler = qsampler_sigusr1_handler;
266      sigemptyset(&usr1.sa_mask);          sigemptyset(&sigusr1.sa_mask);
267      usr1.sa_flags = 0;          sigusr1.sa_flags = 0;
268      usr1.sa_flags |= SA_RESTART;          sigusr1.sa_flags |= SA_RESTART;
269      ::sigaction(SIGUSR1, &usr1, NULL);          ::sigaction(SIGUSR1, &sigusr1, nullptr);
270    
271            // Initialize file descriptors for SIGTERM socket notifier.
272            ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigterm);
273            m_pSigtermNotifier
274                    = new QSocketNotifier(g_fdSigterm[1], QSocketNotifier::Read, this);
275    
276            QObject::connect(m_pSigtermNotifier,
277                    SIGNAL(activated(int)),
278                    SLOT(handle_sigterm()));
279    
280            // Install SIGTERM signal handler.
281            struct sigaction sigterm;
282            sigterm.sa_handler = qsampler_sigterm_handler;
283            sigemptyset(&sigterm.sa_mask);
284            sigterm.sa_flags = 0;
285            sigterm.sa_flags |= SA_RESTART;
286            ::sigaction(SIGTERM, &sigterm, nullptr);
287            ::sigaction(SIGQUIT, &sigterm, nullptr);
288    
289            // Ignore SIGHUP/SIGINT signals.
290            ::signal(SIGHUP, SIG_IGN);
291            ::signal(SIGINT, SIG_IGN);
292    
293  #else   // HAVE_SIGNAL_H  #else   // HAVE_SIGNAL_H
294    
295          m_pUsr1Notifier = NULL;          m_pSigusr1Notifier = nullptr;
296            m_pSigtermNotifier = nullptr;
297                    
298  #endif  // !HAVE_SIGNAL_H  #endif  // !HAVE_SIGNAL_H
299    
# Line 324  MainForm::MainForm ( QWidget *pParent ) Line 366  MainForm::MainForm ( QWidget *pParent )
366          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
367          statusBar()->addWidget(pLabel);          statusBar()->addWidget(pLabel);
368    
369  #if defined(_WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
370          WSAStartup(MAKEWORD(1, 1), &_wsaData);          WSAStartup(MAKEWORD(1, 1), &_wsaData);
371  #endif  #endif
372    
# Line 425  MainForm::~MainForm() Line 467  MainForm::~MainForm()
467          // Do final processing anyway.          // Do final processing anyway.
468          processServerExit();          processServerExit();
469    
470  #if defined(_WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
471          WSACleanup();          WSACleanup();
472  #endif  #endif
473    
474  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
475          if (m_pUsr1Notifier)          if (m_pSigusr1Notifier)
476                  delete m_pUsr1Notifier;                  delete m_pSigusr1Notifier;
477            if (m_pSigtermNotifier)
478                    delete m_pSigtermNotifier;
479  #endif  #endif
480    
481          // Finally drop any widgets around...          // Finally drop any widgets around...
# Line 460  MainForm::~MainForm() Line 504  MainForm::~MainForm()
504  #endif  #endif
505    
506          // Pseudo-singleton reference shut-down.          // Pseudo-singleton reference shut-down.
507          g_pMainForm = NULL;          g_pMainForm = nullptr;
508  }  }
509    
510    
# Line 597  void MainForm::closeEvent ( QCloseEvent Line 641  void MainForm::closeEvent ( QCloseEvent
641  void MainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )  void MainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
642  {  {
643          // Accept external drags only...          // Accept external drags only...
644          if (pDragEnterEvent->source() == NULL          if (pDragEnterEvent->source() == nullptr
645                  && pDragEnterEvent->mimeData()->hasUrls()) {                  && pDragEnterEvent->mimeData()->hasUrls()) {
646                  pDragEnterEvent->accept();                  pDragEnterEvent->accept();
647          } else {          } else {
# Line 621  void MainForm::dropEvent ( QDropEvent *p Line 665  void MainForm::dropEvent ( QDropEvent *p
665                          if (QFileInfo(sPath).exists()) {                          if (QFileInfo(sPath).exists()) {
666                                  // Try to create a new channel from instrument file...                                  // Try to create a new channel from instrument file...
667                                  Channel *pChannel = new Channel();                                  Channel *pChannel = new Channel();
668                                  if (pChannel == NULL)                                  if (pChannel == nullptr)
669                                          return;                                          return;
670                                  // Start setting the instrument filename...                                  // Start setting the instrument filename...
671                                  pChannel->setInstrument(sPath, 0);                                  pChannel->setInstrument(sPath, 0);
# Line 721  void MainForm::handle_sigusr1 (void) Line 765  void MainForm::handle_sigusr1 (void)
765    
766          char c;          char c;
767    
768          if (::read(g_fdUsr1[1], &c, sizeof(c)) > 0)          if (::read(g_fdSigusr1[1], &c, sizeof(c)) > 0)
769                  saveSession(false);                  saveSession(false);
770    
771  #endif  #endif
772  }  }
773    
774    
775    void MainForm::handle_sigterm (void)
776    {
777    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
778    
779            char c;
780    
781            if (::read(g_fdSigterm[1], &c, sizeof(c)) > 0)
782                    close();
783    
784    #endif
785    }
786    
787    
788  void MainForm::updateViewMidiDeviceStatusMenu (void)  void MainForm::updateViewMidiDeviceStatusMenu (void)
789  {  {
790          m_ui.viewMidiDeviceStatusMenu->clear();          m_ui.viewMidiDeviceStatusMenu->clear();
# Line 806  bool MainForm::newSession (void) Line 863  bool MainForm::newSession (void)
863          m_iUntitled++;          m_iUntitled++;
864    
865          // Stabilize form.          // Stabilize form.
866          m_sFilename = QString::null;          m_sFilename = QString();
867          m_iDirtyCount = 0;          m_iDirtyCount = 0;
868          appendMessages(tr("New session: \"%1\".").arg(sessionName(m_sFilename)));          appendMessages(tr("New session: \"%1\".").arg(sessionName(m_sFilename)));
869          stabilizeForm();          stabilizeForm();
# Line 818  bool MainForm::newSession (void) Line 875  bool MainForm::newSession (void)
875  // Open an existing sampler session.  // Open an existing sampler session.
876  bool MainForm::openSession (void)  bool MainForm::openSession (void)
877  {  {
878          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
879                  return false;                  return false;
880    
881          // Ask for the filename to open...          // Ask for the filename to open...
882          QString sFilename = QFileDialog::getOpenFileName(this,          QString sFilename = QFileDialog::getOpenFileName(this,
883                  QSAMPLER_TITLE ": " + tr("Open Session"), // Caption.                  tr("Open Session"),                       // Caption.
884                  m_pOptions->sSessionDir,                  // Start here.                  m_pOptions->sSessionDir,                  // Start here.
885                  tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)                  tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)
886          );          );
# Line 844  bool MainForm::openSession (void) Line 901  bool MainForm::openSession (void)
901  // Save current sampler session with another name.  // Save current sampler session with another name.
902  bool MainForm::saveSession ( bool bPrompt )  bool MainForm::saveSession ( bool bPrompt )
903  {  {
904          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
905                  return false;                  return false;
906    
907          QString sFilename = m_sFilename;          QString sFilename = m_sFilename;
# Line 856  bool MainForm::saveSession ( bool bPromp Line 913  bool MainForm::saveSession ( bool bPromp
913                          sFilename = m_pOptions->sSessionDir;                          sFilename = m_pOptions->sSessionDir;
914                  // Prompt the guy...                  // Prompt the guy...
915                  sFilename = QFileDialog::getSaveFileName(this,                  sFilename = QFileDialog::getSaveFileName(this,
916                          QSAMPLER_TITLE ": " + tr("Save Session"), // Caption.                          tr("Save Session"),                       // Caption.
917                          sFilename,                                // Start here.                          sFilename,                                // Start here.
918                          tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)                          tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)
919                  );                  );
# Line 866  bool MainForm::saveSession ( bool bPromp Line 923  bool MainForm::saveSession ( bool bPromp
923                  // Enforce .lscp extension...                  // Enforce .lscp extension...
924                  if (QFileInfo(sFilename).suffix().isEmpty())                  if (QFileInfo(sFilename).suffix().isEmpty())
925                          sFilename += ".lscp";                          sFilename += ".lscp";
926            #if 0
927                  // Check if already exists...                  // Check if already exists...
928                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
929                          if (QMessageBox::warning(this,                          if (QMessageBox::warning(this,
930                                  QSAMPLER_TITLE ": " + tr("Warning"),                                  tr("Warning"),
931                                  tr("The file already exists:\n\n"                                  tr("The file already exists:\n\n"
932                                  "\"%1\"\n\n"                                  "\"%1\"\n\n"
933                                  "Do you want to replace it?")                                  "Do you want to replace it?")
# Line 878  bool MainForm::saveSession ( bool bPromp Line 936  bool MainForm::saveSession ( bool bPromp
936                                  == QMessageBox::No)                                  == QMessageBox::No)
937                                  return false;                                  return false;
938                  }                  }
939            #endif
940          }          }
941    
942          // Save it right away.          // Save it right away.
# Line 893  bool MainForm::closeSession ( bool bForc Line 952  bool MainForm::closeSession ( bool bForc
952          // Are we dirty enough to prompt it?          // Are we dirty enough to prompt it?
953          if (m_iDirtyCount > 0) {          if (m_iDirtyCount > 0) {
954                  switch (QMessageBox::warning(this,                  switch (QMessageBox::warning(this,
955                          QSAMPLER_TITLE ": " + tr("Warning"),                          tr("Warning"),
956                          tr("The current session has been changed:\n\n"                          tr("The current session has been changed:\n\n"
957                          "\"%1\"\n\n"                          "\"%1\"\n\n"
958                          "Do you want to save the changes?")                          "Do you want to save the changes?")
# Line 918  bool MainForm::closeSession ( bool bForc Line 977  bool MainForm::closeSession ( bool bForc
977                  m_pWorkspace->setUpdatesEnabled(false);                  m_pWorkspace->setUpdatesEnabled(false);
978                  const QList<QMdiSubWindow *>& wlist                  const QList<QMdiSubWindow *>& wlist
979                          = m_pWorkspace->subWindowList();                          = m_pWorkspace->subWindowList();
980                  const int iStripCount = wlist.count();                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
981                  for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                          ChannelStrip *pChannelStrip
982                          ChannelStrip *pChannelStrip = NULL;                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                         QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                         if (pMdiSubWindow)  
                                 pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
983                          if (pChannelStrip) {                          if (pChannelStrip) {
984                                  Channel *pChannel = pChannelStrip->channel();                                  Channel *pChannel = pChannelStrip->channel();
985                                  if (bForce && pChannel)                                  if (bForce && pChannel)
986                                          pChannel->removeChannel();                                          pChannel->removeChannel();
987                                  delete pChannelStrip;                                  delete pChannelStrip;
988                          }                          }
989                          if (pMdiSubWindow)                          delete pMdiSubWindow;
                                 delete pMdiSubWindow;  
990                  }                  }
991                  m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
992                  // We're now clean, for sure.                  // We're now clean, for sure.
# Line 945  bool MainForm::closeSession ( bool bForc Line 1000  bool MainForm::closeSession ( bool bForc
1000  // Load a session from specific file path.  // Load a session from specific file path.
1001  bool MainForm::loadSessionFile ( const QString& sFilename )  bool MainForm::loadSessionFile ( const QString& sFilename )
1002  {  {
1003          if (m_pClient == NULL)          if (m_pClient == nullptr)
1004                  return false;                  return false;
1005    
1006          // Open and read from real file.          // Open and read from real file.
# Line 1021  bool MainForm::loadSessionFile ( const Q Line 1076  bool MainForm::loadSessionFile ( const Q
1076  // Save current session to specific file path.  // Save current session to specific file path.
1077  bool MainForm::saveSessionFile ( const QString& sFilename )  bool MainForm::saveSessionFile ( const QString& sFilename )
1078  {  {
1079          if (m_pClient == NULL)          if (m_pClient == nullptr)
1080                  return false;                  return false;
1081    
1082          // Check whether server is apparently OK...          // Check whether server is apparently OK...
# Line 1060  bool MainForm::saveSessionFile ( const Q Line 1115  bool MainForm::saveSessionFile ( const Q
1115          // It is assumed that this new kind of device+session file          // It is assumed that this new kind of device+session file
1116          // will be loaded from a complete initialized server...          // will be loaded from a complete initialized server...
1117          int *piDeviceIDs;          int *piDeviceIDs;
1118          int  iDevice;          int  i, iDevice;
1119          ts << "RESET" << endl;          ts << "RESET" << endl;
1120    
1121          // Audio device mapping.          // Audio device mapping.
1122          QMap<int, int> audioDeviceMap;          QMap<int, int> audioDeviceMap; iDevice = 0;
1123          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);
1124          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1125                  ts << endl;                  Device device(Device::Audio, piDeviceIDs[i]);
1126                  Device device(Device::Audio, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1127                    if (device.driverName().toUpper() == "PLUGIN")
1128                            continue;
1129                  // Audio device specification...                  // Audio device specification...
1130                    ts << endl;
1131                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1132                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1133                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
# Line 1100  bool MainForm::saveSessionFile ( const Q Line 1158  bool MainForm::saveSessionFile ( const Q
1158                          iPort++;                          iPort++;
1159                  }                  }
1160                  // Audio device index/id mapping.                  // Audio device index/id mapping.
1161                  audioDeviceMap[device.deviceID()] = iDevice;                  audioDeviceMap.insert(device.deviceID(), iDevice++);
1162                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1163                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1164          }          }
1165    
1166          // MIDI device mapping.          // MIDI device mapping.
1167          QMap<int, int> midiDeviceMap;          QMap<int, int> midiDeviceMap; iDevice = 0;
1168          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);
1169          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1170                  ts << endl;                  Device device(Device::Midi, piDeviceIDs[i]);
1171                  Device device(Device::Midi, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1172                    if (device.driverName().toUpper() == "PLUGIN")
1173                            continue;
1174                  // MIDI device specification...                  // MIDI device specification...
1175                    ts << endl;
1176                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1177                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1178                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
# Line 1142  bool MainForm::saveSessionFile ( const Q Line 1203  bool MainForm::saveSessionFile ( const Q
1203                          iPort++;                          iPort++;
1204                  }                  }
1205                  // MIDI device index/id mapping.                  // MIDI device index/id mapping.
1206                  midiDeviceMap[device.deviceID()] = iDevice;                  midiDeviceMap.insert(device.deviceID(), iDevice++);
1207                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1208                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1209          }          }
# Line 1205  bool MainForm::saveSessionFile ( const Q Line 1266  bool MainForm::saveSessionFile ( const Q
1266                  }                  }
1267                  ts << endl;                  ts << endl;
1268                  // Check for errors...                  // Check for errors...
1269                  if (pInstrs == NULL && ::lscp_client_get_errno(m_pClient)) {                  if (pInstrs == nullptr && ::lscp_client_get_errno(m_pClient)) {
1270                          appendMessagesClient("lscp_list_midi_instruments");                          appendMessagesClient("lscp_list_midi_instruments");
1271                          iErrors++;                          iErrors++;
1272                  }                  }
1273                  // MIDI strument index/id mapping.                  // MIDI strument index/id mapping.
1274                  midiInstrumentMap[iMidiMap] = iMap;                  midiInstrumentMap.insert(iMidiMap, iMap);
1275          }          }
1276          // Check for errors...          // Check for errors...
1277          if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {          if (piMaps == nullptr && ::lscp_client_get_errno(m_pClient)) {
1278                  appendMessagesClient("lscp_list_midi_instrument_maps");                  appendMessagesClient("lscp_list_midi_instrument_maps");
1279                  iErrors++;                  iErrors++;
1280          }          }
1281  #endif  // CONFIG_MIDI_INSTRUMENT  #endif  // CONFIG_MIDI_INSTRUMENT
1282    
1283          // Sampler channel mapping.          // Sampler channel mapping...
1284            int iChannelID = 0;
1285          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
1286                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
1287          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
1288          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
1289                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
1290                  if (pChannelStrip) {                  if (pChannelStrip) {
1291                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1292                          if (pChannel) {                          if (pChannel) {
1293                                  const int iChannelID = pChannel->channelID();                                  // Avoid "artifial" plug-in devices...
1294                                    const int iAudioDevice = pChannel->audioDevice();
1295                                    if (!audioDeviceMap.contains(iAudioDevice))
1296                                            continue;
1297                                    const int iMidiDevice = pChannel->midiDevice();
1298                                    if (!midiDeviceMap.contains(iMidiDevice))
1299                                            continue;
1300                                    // Go for regular, canonical devices...
1301                                  ts << "# " << tr("Channel") << " " << iChannelID << endl;                                  ts << "# " << tr("Channel") << " " << iChannelID << endl;
1302                                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
1303                                  if (audioDeviceMap.isEmpty()) {                                  if (audioDeviceMap.isEmpty()) {
# Line 1239  bool MainForm::saveSessionFile ( const Q Line 1305  bool MainForm::saveSessionFile ( const Q
1305                                                  << " " << pChannel->audioDriver() << endl;                                                  << " " << pChannel->audioDriver() << endl;
1306                                  } else {                                  } else {
1307                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannelID                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannelID
1308                                                  << " " << audioDeviceMap[pChannel->audioDevice()] << endl;                                                  << " " << audioDeviceMap.value(iAudioDevice) << endl;
1309                                  }                                  }
1310                                  if (midiDeviceMap.isEmpty()) {                                  if (midiDeviceMap.isEmpty()) {
1311                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID
1312                                                  << " " << pChannel->midiDriver() << endl;                                                  << " " << pChannel->midiDriver() << endl;
1313                                  } else {                                  } else {
1314                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannelID                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannelID
1315                                                  << " " << midiDeviceMap[pChannel->midiDevice()] << endl;                                                  << " " << midiDeviceMap.value(iMidiDevice) << endl;
1316                                  }                                  }
1317                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID
1318                                          << " " << pChannel->midiPort() << endl;                                          << " " << pChannel->midiPort() << endl;
# Line 1277  bool MainForm::saveSessionFile ( const Q Line 1343  bool MainForm::saveSessionFile ( const Q
1343                                  if (pChannel->channelSolo())                                  if (pChannel->channelSolo())
1344                                          ts << "SET CHANNEL SOLO " << iChannelID << " 1" << endl;                                          ts << "SET CHANNEL SOLO " << iChannelID << " 1" << endl;
1345                          #ifdef CONFIG_MIDI_INSTRUMENT                          #ifdef CONFIG_MIDI_INSTRUMENT
1346                                  if (pChannel->midiMap() >= 0) {                                  const int iMidiMap = pChannel->midiMap();
1347                                    if (midiInstrumentMap.contains(iMidiMap)) {
1348                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannelID                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannelID
1349                                                  << " " << midiInstrumentMap[pChannel->midiMap()] << endl;                                                  << " " << midiInstrumentMap.value(iMidiMap) << endl;
1350                                  }                                  }
1351                          #endif                          #endif
1352                          #ifdef CONFIG_FXSEND                          #ifdef CONFIG_FXSEND
# Line 1318  bool MainForm::saveSessionFile ( const Q Line 1385  bool MainForm::saveSessionFile ( const Q
1385                                  }                                  }
1386                          #endif                          #endif
1387                                  ts << endl;                                  ts << endl;
1388                                    // Go for next channel...
1389                                    ++iChannelID;
1390                          }                          }
1391                  }                  }
1392                  // Try to keep it snappy :)                  // Try to keep it snappy :)
# Line 1423  void MainForm::fileSaveAs (void) Line 1492  void MainForm::fileSaveAs (void)
1492  // Reset the sampler instance.  // Reset the sampler instance.
1493  void MainForm::fileReset (void)  void MainForm::fileReset (void)
1494  {  {
1495          if (m_pClient == NULL)          if (m_pClient == nullptr)
1496                  return;                  return;
1497    
1498          // Ask user whether he/she want's an internal sampler reset...          // Ask user whether he/she want's an internal sampler reset...
1499          if (m_pOptions && m_pOptions->bConfirmReset) {          if (m_pOptions && m_pOptions->bConfirmReset) {
1500                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");                  const QString& sTitle = tr("Warning");
1501                  const QString& sText = tr(                  const QString& sText = tr(
1502                          "Resetting the sampler instance will close\n"                          "Resetting the sampler instance will close\n"
1503                          "all device and channel configurations.\n\n"                          "all device and channel configurations.\n\n"
# Line 1479  void MainForm::fileReset (void) Line 1548  void MainForm::fileReset (void)
1548  // Restart the client/server instance.  // Restart the client/server instance.
1549  void MainForm::fileRestart (void)  void MainForm::fileRestart (void)
1550  {  {
1551          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1552                  return;                  return;
1553    
1554          bool bRestart = true;          bool bRestart = true;
# Line 1487  void MainForm::fileRestart (void) Line 1556  void MainForm::fileRestart (void)
1556          // Ask user whether he/she want's a complete restart...          // Ask user whether he/she want's a complete restart...
1557          // (if we're currently up and running)          // (if we're currently up and running)
1558          if (m_pOptions && m_pOptions->bConfirmRestart) {          if (m_pOptions && m_pOptions->bConfirmRestart) {
1559                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");                  const QString& sTitle = tr("Warning");
1560                  const QString& sText = tr(                  const QString& sText = tr(
1561                          "New settings will be effective after\n"                          "New settings will be effective after\n"
1562                          "restarting the client/server connection.\n\n"                          "restarting the client/server connection.\n\n"
# Line 1547  void MainForm::editAddChannel (void) Line 1616  void MainForm::editAddChannel (void)
1616    
1617  void MainForm::addChannelStrip (void)  void MainForm::addChannelStrip (void)
1618  {  {
1619          if (m_pClient == NULL)          if (m_pClient == nullptr)
1620                  return;                  return;
1621    
1622          // Just create the channel instance...          // Just create the channel instance...
1623          Channel *pChannel = new Channel();          Channel *pChannel = new Channel();
1624          if (pChannel == NULL)          if (pChannel == nullptr)
1625                  return;                  return;
1626    
1627          // 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 1657  void MainForm::editRemoveChannel (void)
1657    
1658  void MainForm::removeChannelStrip (void)  void MainForm::removeChannelStrip (void)
1659  {  {
1660          if (m_pClient == NULL)          if (m_pClient == nullptr)
1661                  return;                  return;
1662    
1663          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1664          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1665                  return;                  return;
1666    
1667          Channel *pChannel = pChannelStrip->channel();          Channel *pChannel = pChannelStrip->channel();
1668          if (pChannel == NULL)          if (pChannel == nullptr)
1669                  return;                  return;
1670    
1671          // Prompt user if he/she's sure about this...          // Prompt user if he/she's sure about this...
1672          if (m_pOptions && m_pOptions->bConfirmRemove) {          if (m_pOptions && m_pOptions->bConfirmRemove) {
1673                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");                  const QString& sTitle = tr("Warning");
1674                  const QString& sText = tr(                  const QString& sText = tr(
1675                          "About to remove channel:\n\n"                          "About to remove channel:\n\n"
1676                          "%1\n\n"                          "%1\n\n"
# Line 1644  void MainForm::removeChannelStrip (void) Line 1713  void MainForm::removeChannelStrip (void)
1713  // Setup current sampler channel.  // Setup current sampler channel.
1714  void MainForm::editSetupChannel (void)  void MainForm::editSetupChannel (void)
1715  {  {
1716          if (m_pClient == NULL)          if (m_pClient == nullptr)
1717                  return;                  return;
1718    
1719          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1720          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1721                  return;                  return;
1722    
1723          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1659  void MainForm::editSetupChannel (void) Line 1728  void MainForm::editSetupChannel (void)
1728  // Edit current sampler channel.  // Edit current sampler channel.
1729  void MainForm::editEditChannel (void)  void MainForm::editEditChannel (void)
1730  {  {
1731          if (m_pClient == NULL)          if (m_pClient == nullptr)
1732                  return;                  return;
1733    
1734          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1735          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1736                  return;                  return;
1737    
1738          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1674  void MainForm::editEditChannel (void) Line 1743  void MainForm::editEditChannel (void)
1743  // Reset current sampler channel.  // Reset current sampler channel.
1744  void MainForm::editResetChannel (void)  void MainForm::editResetChannel (void)
1745  {  {
1746          if (m_pClient == NULL)          if (m_pClient == nullptr)
1747                  return;                  return;
1748    
1749          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1750          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1751                  return;                  return;
1752    
1753          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1689  void MainForm::editResetChannel (void) Line 1758  void MainForm::editResetChannel (void)
1758  // Reset all sampler channels.  // Reset all sampler channels.
1759  void MainForm::editResetAllChannels (void)  void MainForm::editResetAllChannels (void)
1760  {  {
1761          if (m_pClient == NULL)          if (m_pClient == nullptr)
1762                  return;                  return;
1763    
1764          // Invoque the channel strip procedure,          // Invoque the channel strip procedure,
# Line 1697  void MainForm::editResetAllChannels (voi Line 1766  void MainForm::editResetAllChannels (voi
1766          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1767          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
1768                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
1769          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
1770          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
1771                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
1772                  if (pChannelStrip)                  if (pChannelStrip)
1773                          pChannelStrip->channelReset();                          pChannelStrip->channelReset();
1774          }          }
# Line 1761  void MainForm::viewMessages ( bool bOn ) Line 1827  void MainForm::viewMessages ( bool bOn )
1827  // Show/hide the MIDI instrument list-view form.  // Show/hide the MIDI instrument list-view form.
1828  void MainForm::viewInstruments (void)  void MainForm::viewInstruments (void)
1829  {  {
1830          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1831                  return;                  return;
1832    
1833          if (m_pInstrumentListForm) {          if (m_pInstrumentListForm) {
# Line 1780  void MainForm::viewInstruments (void) Line 1846  void MainForm::viewInstruments (void)
1846  // Show/hide the device configurator form.  // Show/hide the device configurator form.
1847  void MainForm::viewDevices (void)  void MainForm::viewDevices (void)
1848  {  {
1849          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1850                  return;                  return;
1851    
1852          if (m_pDeviceForm) {          if (m_pDeviceForm) {
# Line 1799  void MainForm::viewDevices (void) Line 1865  void MainForm::viewDevices (void)
1865  // Show options dialog.  // Show options dialog.
1866  void MainForm::viewOptions (void)  void MainForm::viewOptions (void)
1867  {  {
1868          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1869                  return;                  return;
1870    
1871          OptionsForm* pOptionsForm = new OptionsForm(this);          OptionsForm* pOptionsForm = new OptionsForm(this);
# Line 1811  void MainForm::viewOptions (void) Line 1877  void MainForm::viewOptions (void)
1877                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)
1878                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();
1879                  // To track down deferred or immediate changes.                  // To track down deferred or immediate changes.
1880                  const QString sOldServerHost      = m_pOptions->sServerHost;                  const QString sOldServerHost       = m_pOptions->sServerHost;
1881                  const int     iOldServerPort      = m_pOptions->iServerPort;                  const int     iOldServerPort       = m_pOptions->iServerPort;
1882                  const int     iOldServerTimeout   = m_pOptions->iServerTimeout;                  const int     iOldServerTimeout    = m_pOptions->iServerTimeout;
1883                  const bool    bOldServerStart     = m_pOptions->bServerStart;                  const bool    bOldServerStart      = m_pOptions->bServerStart;
1884                  const QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;                  const QString sOldServerCmdLine    = m_pOptions->sServerCmdLine;
1885                  const bool    bOldMessagesLog     = m_pOptions->bMessagesLog;                  const bool    bOldMessagesLog      = m_pOptions->bMessagesLog;
1886                  const QString sOldMessagesLogPath = m_pOptions->sMessagesLogPath;                  const QString sOldMessagesLogPath  = m_pOptions->sMessagesLogPath;
1887                  const QString sOldDisplayFont     = m_pOptions->sDisplayFont;                  const QString sOldDisplayFont      = m_pOptions->sDisplayFont;
1888                  const bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;                  const bool    bOldDisplayEffect    = m_pOptions->bDisplayEffect;
1889                  const int     iOldMaxVolume       = m_pOptions->iMaxVolume;                  const int     iOldMaxVolume        = m_pOptions->iMaxVolume;
1890                  const QString sOldMessagesFont    = m_pOptions->sMessagesFont;                  const QString sOldMessagesFont     = m_pOptions->sMessagesFont;
1891                  const bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;                  const bool    bOldKeepOnTop        = m_pOptions->bKeepOnTop;
1892                  const bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;                  const bool    bOldStdoutCapture    = m_pOptions->bStdoutCapture;
1893                  const int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;                  const int     bOldMessagesLimit    = m_pOptions->bMessagesLimit;
1894                  const int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;                  const int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1895                  const bool    bOldCompletePath    = m_pOptions->bCompletePath;                  const bool    bOldCompletePath     = m_pOptions->bCompletePath;
1896                  const bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;                  const bool    bOldInstrumentNames  = m_pOptions->bInstrumentNames;
1897                  const int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;                  const int     iOldMaxRecentFiles   = m_pOptions->iMaxRecentFiles;
1898                  const int     iOldBaseFontSize    = m_pOptions->iBaseFontSize;                  const int     iOldBaseFontSize     = m_pOptions->iBaseFontSize;
1899                    const QString sOldCustomStyleTheme = m_pOptions->sCustomStyleTheme;
1900                    const QString sOldCustomColorTheme = m_pOptions->sCustomColorTheme;
1901                  // Load the current setup settings.                  // Load the current setup settings.
1902                  pOptionsForm->setup(m_pOptions);                  pOptionsForm->setup(m_pOptions);
1903                  // Show the setup dialog...                  // Show the setup dialog...
1904                  if (pOptionsForm->exec()) {                  if (pOptionsForm->exec()) {
1905                          // Warn if something will be only effective on next run.                          // Warn if something will be only effective on next run.
1906                            int iNeedRestart = 0;
1907                          if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||                          if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1908                                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||                                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture)) {
1909                                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||                                  updateMessagesCapture();
1910                                    ++iNeedRestart;
1911                            }
1912                            if (( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1913                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)     ||                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)     ||
1914                                  (iOldBaseFontSize   !=  m_pOptions->iBaseFontSize)) {                                  (iOldBaseFontSize   !=  m_pOptions->iBaseFontSize)) {
1915                                  QMessageBox::information(this,                                  ++iNeedRestart;
1916                                          QSAMPLER_TITLE ": " + tr("Information"),                          }
1917                                          tr("Some settings may be only effective\n"                          // Check whether restart is needed or whether
1918                                          "next time you start this program."));                          // custom options maybe set up immediately...
1919                                  updateMessagesCapture();                          if (m_pOptions->sCustomStyleTheme != sOldCustomStyleTheme) {
1920                                    if (m_pOptions->sCustomStyleTheme.isEmpty()) {
1921                                            ++iNeedRestart;
1922                                    } else {
1923                                            QApplication::setStyle(
1924                                                    QStyleFactory::create(m_pOptions->sCustomStyleTheme));
1925                                    }
1926                            }
1927                            if (m_pOptions->sCustomColorTheme != sOldCustomColorTheme) {
1928                                    if (m_pOptions->sCustomColorTheme.isEmpty()) {
1929                                            ++iNeedRestart;
1930                                    } else {
1931                                            QPalette pal;
1932                                            if (PaletteForm::namedPalette(
1933                                                            &m_pOptions->settings(), m_pOptions->sCustomColorTheme, pal))
1934                                                    QApplication::setPalette(pal);
1935                                    }
1936                          }                          }
1937                          // Check wheather something immediate has changed.                          // Check wheather something immediate has changed.
1938                          if (( bOldMessagesLog && !m_pOptions->bMessagesLog) ||                          if (( bOldMessagesLog && !m_pOptions->bMessagesLog) ||
# Line 1872  void MainForm::viewOptions (void) Line 1960  void MainForm::viewOptions (void)
1960                                  (!bOldMessagesLimit &&  m_pOptions->bMessagesLimit) ||                                  (!bOldMessagesLimit &&  m_pOptions->bMessagesLimit) ||
1961                                  (iOldMessagesLimitLines !=  m_pOptions->iMessagesLimitLines))                                  (iOldMessagesLimitLines !=  m_pOptions->iMessagesLimitLines))
1962                                  updateMessagesLimit();                                  updateMessagesLimit();
1963                            // Show restart needed message...
1964                            if (iNeedRestart > 0) {
1965                                    QMessageBox::information(this,
1966                                            tr("Information"),
1967                                            tr("Some settings may be only effective\n"
1968                                            "next time you start this program."));
1969                            }
1970                          // And now the main thing, whether we'll do client/server recycling?                          // And now the main thing, whether we'll do client/server recycling?
1971                          if ((sOldServerHost != m_pOptions->sServerHost) ||                          if ((sOldServerHost != m_pOptions->sServerHost) ||
1972                                  (iOldServerPort != m_pOptions->iServerPort) ||                                  (iOldServerPort != m_pOptions->iServerPort) ||
# Line 1905  void MainForm::channelsArrange (void) Line 2000  void MainForm::channelsArrange (void)
2000    
2001          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2002          int y = 0;          int y = 0;
2003          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2004          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  pMdiSubWindow->adjustSize();
2005                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);                  const QRect& frameRect
2006                  if (pMdiSubWindow) {                          = pMdiSubWindow->frameGeometry();
2007                          pMdiSubWindow->adjustSize();                  int w = m_pWorkspace->width();
2008                          int iWidth = m_pWorkspace->width();                  if (w < frameRect.width())
2009                          if (iWidth < pMdiSubWindow->width())                          w = frameRect.width();
2010                                  iWidth = pMdiSubWindow->width();                  const int h = frameRect.height();
2011                          const int iHeight = pMdiSubWindow->frameGeometry().height();                  pMdiSubWindow->setGeometry(0, y, w, h);
2012                          pMdiSubWindow->setGeometry(0, y, iWidth, iHeight);                  y += h;
                         y += iHeight;  
                 }  
2013          }          }
2014          m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
2015    
# Line 1927  void MainForm::channelsArrange (void) Line 2020  void MainForm::channelsArrange (void)
2020  // Auto-arrange channel strips.  // Auto-arrange channel strips.
2021  void MainForm::channelsAutoArrange ( bool bOn )  void MainForm::channelsAutoArrange ( bool bOn )
2022  {  {
2023          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2024                  return;                  return;
2025    
2026          // Toggle the auto-arrange flag.          // Toggle the auto-arrange flag.
# Line 2031  void MainForm::helpAbout (void) Line 2124  void MainForm::helpAbout (void)
2124          sText += "</small>";          sText += "</small>";
2125          sText += "</p>\n";          sText += "</p>\n";
2126    
2127          QMessageBox::about(this, tr("About") + " " QSAMPLER_TITLE, sText);          QMessageBox::about(this, tr("About"), sText);
2128  }  }
2129    
2130    
# Line 2044  void MainForm::stabilizeForm (void) Line 2137  void MainForm::stabilizeForm (void)
2137          QString sSessionName = sessionName(m_sFilename);          QString sSessionName = sessionName(m_sFilename);
2138          if (m_iDirtyCount > 0)          if (m_iDirtyCount > 0)
2139                  sSessionName += " *";                  sSessionName += " *";
2140          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));          setWindowTitle(sSessionName);
2141    
2142          // Update the main menu state...          // Update the main menu state...
2143          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
2144          const QList<QMdiSubWindow *>& wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist = m_pWorkspace->subWindowList();
2145          const bool bHasClient = (m_pOptions != NULL && m_pClient != NULL);          const bool bHasClient = (m_pOptions != nullptr && m_pClient != nullptr);
2146          const bool bHasChannel = (bHasClient && pChannelStrip != NULL);          const bool bHasChannel = (bHasClient && pChannelStrip != nullptr);
2147          const bool bHasChannels = (bHasClient && wlist.count() > 0);          const bool bHasChannels = (bHasClient && wlist.count() > 0);
2148          m_ui.fileNewAction->setEnabled(bHasClient);          m_ui.fileNewAction->setEnabled(bHasClient);
2149          m_ui.fileOpenAction->setEnabled(bHasClient);          m_ui.fileOpenAction->setEnabled(bHasClient);
2150          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
2151          m_ui.fileSaveAsAction->setEnabled(bHasClient);          m_ui.fileSaveAsAction->setEnabled(bHasClient);
2152          m_ui.fileResetAction->setEnabled(bHasClient);          m_ui.fileResetAction->setEnabled(bHasClient);
2153          m_ui.fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);          m_ui.fileRestartAction->setEnabled(bHasClient || m_pServer == nullptr);
2154          m_ui.editAddChannelAction->setEnabled(bHasClient);          m_ui.editAddChannelAction->setEnabled(bHasClient);
2155          m_ui.editRemoveChannelAction->setEnabled(bHasChannel);          m_ui.editRemoveChannelAction->setEnabled(bHasChannel);
2156          m_ui.editSetupChannelAction->setEnabled(bHasChannel);          m_ui.editSetupChannelAction->setEnabled(bHasChannel);
# Line 2206  void MainForm::updateAllChannelStrips ( Line 2299  void MainForm::updateAllChannelStrips (
2299    
2300          // Retrieve the current channel list.          // Retrieve the current channel list.
2301          int *piChannelIDs = ::lscp_list_channels(m_pClient);          int *piChannelIDs = ::lscp_list_channels(m_pClient);
2302          if (piChannelIDs == NULL) {          if (piChannelIDs == nullptr) {
2303                  if (::lscp_client_get_errno(m_pClient)) {                  if (::lscp_client_get_errno(m_pClient)) {
2304                          appendMessagesClient("lscp_list_channels");                          appendMessagesClient("lscp_list_channels");
2305                          appendMessagesError(                          appendMessagesError(
# Line 2226  void MainForm::updateAllChannelStrips ( Line 2319  void MainForm::updateAllChannelStrips (
2319                  if (bRemoveDeadStrips) {                  if (bRemoveDeadStrips) {
2320                          const QList<QMdiSubWindow *>& wlist                          const QList<QMdiSubWindow *>& wlist
2321                                  = m_pWorkspace->subWindowList();                                  = m_pWorkspace->subWindowList();
2322                          const int iStripCount = wlist.count();                          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2323                          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                                  ChannelStrip *pChannelStrip
2324                                  ChannelStrip *pChannelStrip = NULL;                                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                                 if (pMdiSubWindow)  
                                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2325                                  if (pChannelStrip) {                                  if (pChannelStrip) {
2326                                          bool bExists = false;                                          bool bExists = false;
2327                                          for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {                                          for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {
2328                                                  Channel *pChannel = pChannelStrip->channel();                                                  Channel *pChannel = pChannelStrip->channel();
2329                                                  if (pChannel == NULL)                                                  if (pChannel == nullptr)
2330                                                          break;                                                          break;
2331                                                  if (piChannelIDs[iChannel] == pChannel->channelID()) {                                                  if (piChannelIDs[iChannel] == pChannel->channelID()) {
2332                                                          // strip exists, don't touch it                                                          // strip exists, don't touch it
# Line 2259  void MainForm::updateAllChannelStrips ( Line 2349  void MainForm::updateAllChannelStrips (
2349  // Update the recent files list and menu.  // Update the recent files list and menu.
2350  void MainForm::updateRecentFiles ( const QString& sFilename )  void MainForm::updateRecentFiles ( const QString& sFilename )
2351  {  {
2352          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2353                  return;                  return;
2354    
2355          // Remove from list if already there (avoid duplicates)          // Remove from list if already there (avoid duplicates)
# Line 2274  void MainForm::updateRecentFiles ( const Line 2364  void MainForm::updateRecentFiles ( const
2364  // Update the recent files list and menu.  // Update the recent files list and menu.
2365  void MainForm::updateRecentFilesMenu (void)  void MainForm::updateRecentFilesMenu (void)
2366  {  {
2367          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2368                  return;                  return;
2369    
2370          // Time to keep the list under limits.          // Time to keep the list under limits.
# Line 2308  void MainForm::updateInstrumentNames (vo Line 2398  void MainForm::updateInstrumentNames (vo
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->updateInstrumentName(true);                          pChannelStrip->updateInstrumentName(true);
2406          }          }
# Line 2324  void MainForm::updateInstrumentNames (vo Line 2411  void MainForm::updateInstrumentNames (vo
2411  // Force update of the channels display font.  // Force update of the channels display font.
2412  void MainForm::updateDisplayFont (void)  void MainForm::updateDisplayFont (void)
2413  {  {
2414          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2415                  return;                  return;
2416    
2417          // Check if display font is legal.          // Check if display font is legal.
# Line 2343  void MainForm::updateDisplayFont (void) Line 2430  void MainForm::updateDisplayFont (void)
2430                  return;                  return;
2431    
2432          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2433          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2434          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2435                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2436                  if (pChannelStrip)                  if (pChannelStrip)
2437                          pChannelStrip->setDisplayFont(font);                          pChannelStrip->setDisplayFont(font);
2438          }          }
# Line 2366  void MainForm::updateDisplayEffect (void Line 2450  void MainForm::updateDisplayEffect (void
2450                  return;                  return;
2451    
2452          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2453          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2454          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2455                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2456                  if (pChannelStrip)                  if (pChannelStrip)
2457                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2458          }          }
# Line 2382  void MainForm::updateDisplayEffect (void Line 2463  void MainForm::updateDisplayEffect (void
2463  // Force update of the channels maximum volume setting.  // Force update of the channels maximum volume setting.
2464  void MainForm::updateMaxVolume (void)  void MainForm::updateMaxVolume (void)
2465  {  {
2466          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2467                  return;                  return;
2468    
2469  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
# Line 2399  void MainForm::updateMaxVolume (void) Line 2480  void MainForm::updateMaxVolume (void)
2480                  return;                  return;
2481    
2482          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2483          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2484          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2485                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2486                  if (pChannelStrip)                  if (pChannelStrip)
2487                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2488          }          }
# Line 2416  void MainForm::updateMaxVolume (void) Line 2494  void MainForm::updateMaxVolume (void)
2494  // QSampler::MainForm -- Messages window form handlers.  // QSampler::MainForm -- Messages window form handlers.
2495    
2496  // Messages output methods.  // Messages output methods.
2497  void MainForm::appendMessages( const QString& s )  void MainForm::appendMessages ( const QString& s )
2498  {  {
2499          if (m_pMessages)          if (m_pMessages)
2500                  m_pMessages->appendMessages(s);                  m_pMessages->appendMessages(s);
# Line 2424  void MainForm::appendMessages( const QSt Line 2502  void MainForm::appendMessages( const QSt
2502          statusBar()->showMessage(s, 3000);          statusBar()->showMessage(s, 3000);
2503  }  }
2504    
2505  void MainForm::appendMessagesColor( const QString& s, const QString& c )  void MainForm::appendMessagesColor ( const QString& s, const QColor& rgb )
2506  {  {
2507          if (m_pMessages)          if (m_pMessages)
2508                  m_pMessages->appendMessagesColor(s, c);                  m_pMessages->appendMessagesColor(s, rgb);
2509    
2510          statusBar()->showMessage(s, 3000);          statusBar()->showMessage(s, 3000);
2511  }  }
2512    
2513  void MainForm::appendMessagesText( const QString& s )  void MainForm::appendMessagesText ( const QString& s )
2514  {  {
2515          if (m_pMessages)          if (m_pMessages)
2516                  m_pMessages->appendMessagesText(s);                  m_pMessages->appendMessagesText(s);
2517  }  }
2518    
2519  void MainForm::appendMessagesError( const QString& sText )  void MainForm::appendMessagesError ( const QString& s )
2520  {  {
2521          if (m_pMessages)          if (m_pMessages)
2522                  m_pMessages->show();                  m_pMessages->show();
2523    
2524          appendMessagesColor(sText.simplified(), "#ff0000");          appendMessagesColor(s.simplified(), Qt::red);
2525    
2526          // Make it look responsive...:)          // Make it look responsive...:)
2527          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2528    
2529          if (m_pOptions && m_pOptions->bConfirmError) {          if (m_pOptions && m_pOptions->bConfirmError) {
2530                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Error");                  const QString& sTitle = tr("Error");
2531          #if 0          #if 0
2532                  QMessageBox::critical(this, sTitle, sText, QMessageBox::Cancel);                  QMessageBox::critical(this, sTitle, sText, QMessageBox::Cancel);
2533          #else          #else
2534                  QMessageBox mbox(this);                  QMessageBox mbox(this);
2535                  mbox.setIcon(QMessageBox::Critical);                  mbox.setIcon(QMessageBox::Critical);
2536                  mbox.setWindowTitle(sTitle);                  mbox.setWindowTitle(sTitle);
2537                  mbox.setText(sText);                  mbox.setText(s);
2538                  mbox.setStandardButtons(QMessageBox::Cancel);                  mbox.setStandardButtons(QMessageBox::Cancel);
2539                  QCheckBox cbox(tr("Don't show this again"));                  QCheckBox cbox(tr("Don't show this again"));
2540                  cbox.setChecked(false);                  cbox.setChecked(false);
# Line 2472  void MainForm::appendMessagesError( cons Line 2550  void MainForm::appendMessagesError( cons
2550  // This is a special message format, just for client results.  // This is a special message format, just for client results.
2551  void MainForm::appendMessagesClient( const QString& s )  void MainForm::appendMessagesClient( const QString& s )
2552  {  {
2553          if (m_pClient == NULL)          if (m_pClient == nullptr)
2554                  return;                  return;
2555    
2556          appendMessagesColor(s + QString(": %1 (errno=%2)")          appendMessagesColor(s + QString(": %1 (errno=%2)")
# Line 2487  void MainForm::appendMessagesClient( con Line 2565  void MainForm::appendMessagesClient( con
2565  // Force update of the messages font.  // Force update of the messages font.
2566  void MainForm::updateMessagesFont (void)  void MainForm::updateMessagesFont (void)
2567  {  {
2568          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2569                  return;                  return;
2570    
2571          if (m_pMessages && !m_pOptions->sMessagesFont.isEmpty()) {          if (m_pMessages && !m_pOptions->sMessagesFont.isEmpty()) {
# Line 2501  void MainForm::updateMessagesFont (void) Line 2579  void MainForm::updateMessagesFont (void)
2579  // Update messages window line limit.  // Update messages window line limit.
2580  void MainForm::updateMessagesLimit (void)  void MainForm::updateMessagesLimit (void)
2581  {  {
2582          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2583                  return;                  return;
2584    
2585          if (m_pMessages) {          if (m_pMessages) {
# Line 2516  void MainForm::updateMessagesLimit (void Line 2594  void MainForm::updateMessagesLimit (void
2594  // Enablement of the messages capture feature.  // Enablement of the messages capture feature.
2595  void MainForm::updateMessagesCapture (void)  void MainForm::updateMessagesCapture (void)
2596  {  {
2597          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2598                  return;                  return;
2599    
2600          if (m_pMessages)          if (m_pMessages)
# Line 2530  void MainForm::updateMessagesCapture (vo Line 2608  void MainForm::updateMessagesCapture (vo
2608  // The channel strip creation executive.  // The channel strip creation executive.
2609  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )
2610  {  {
2611          if (m_pClient == NULL || pChannel == NULL)          if (m_pClient == nullptr || pChannel == nullptr)
2612                  return NULL;                  return nullptr;
2613    
2614          // Add a new channel itema...          // Add a new channel itema...
2615          ChannelStrip *pChannelStrip = new ChannelStrip();          ChannelStrip *pChannelStrip = new ChannelStrip();
2616          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
2617                  return NULL;                  return nullptr;
2618    
2619          // Set some initial channel strip options...          // Set some initial channel strip options...
2620          if (m_pOptions) {          if (m_pOptions) {
# Line 2552  ChannelStrip *MainForm::createChannelStr Line 2630  ChannelStrip *MainForm::createChannelStr
2630          }          }
2631    
2632          // Add it to workspace...          // Add it to workspace...
2633          m_pWorkspace->addSubWindow(pChannelStrip,          QMdiSubWindow *pMdiSubWindow
2634                  Qt::SubWindow | Qt::FramelessWindowHint);                  = m_pWorkspace->addSubWindow(pChannelStrip,
2635                            Qt::SubWindow | Qt::FramelessWindowHint);
2636            pMdiSubWindow->setAttribute(Qt::WA_DeleteOnClose);
2637    
2638          // Actual channel strip setup...          // Actual channel strip setup...
2639          pChannelStrip->setup(pChannel);          pChannelStrip->setup(pChannel);
# Line 2577  void MainForm::destroyChannelStrip ( Cha Line 2657  void MainForm::destroyChannelStrip ( Cha
2657  {  {
2658          QMdiSubWindow *pMdiSubWindow          QMdiSubWindow *pMdiSubWindow
2659                  = static_cast<QMdiSubWindow *> (pChannelStrip->parentWidget());                  = static_cast<QMdiSubWindow *> (pChannelStrip->parentWidget());
2660          if (pMdiSubWindow == NULL)          if (pMdiSubWindow == nullptr)
2661                  return;                  return;
2662    
2663          // Just delete the channel strip.          // Just delete the channel strip.
# Line 2596  ChannelStrip *MainForm::activeChannelStr Line 2676  ChannelStrip *MainForm::activeChannelStr
2676          if (pMdiSubWindow)          if (pMdiSubWindow)
2677                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2678          else          else
2679                  return NULL;                  return nullptr;
2680  }  }
2681    
2682    
2683  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2684  ChannelStrip *MainForm::channelStripAt ( int iStrip )  ChannelStrip *MainForm::channelStripAt ( int iStrip )
2685  {  {
2686          if (!m_pWorkspace) return NULL;          if (!m_pWorkspace) return nullptr;
2687    
2688          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
2689                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
2690          if (wlist.isEmpty())          if (wlist.isEmpty())
2691                  return NULL;                  return nullptr;
2692    
2693          if (iStrip < 0 || iStrip >= wlist.count())          if (iStrip < 0 || iStrip >= wlist.count())
2694                  return NULL;                  return nullptr;
2695    
2696          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2697          if (pMdiSubWindow)          if (pMdiSubWindow)
2698                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2699          else          else
2700                  return NULL;                  return nullptr;
2701  }  }
2702    
2703    
# Line 2627  ChannelStrip *MainForm::channelStrip ( i Line 2707  ChannelStrip *MainForm::channelStrip ( i
2707          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
2708                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
2709          if (wlist.isEmpty())          if (wlist.isEmpty())
2710                  return NULL;                  return nullptr;
2711    
2712          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2713          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2714                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2715                  if (pChannelStrip) {                  if (pChannelStrip) {
2716                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
2717                          if (pChannel && pChannel->channelID() == iChannelID)                          if (pChannel && pChannel->channelID() == iChannelID)
# Line 2643  ChannelStrip *MainForm::channelStrip ( i Line 2720  ChannelStrip *MainForm::channelStrip ( i
2720          }          }
2721    
2722          // Not found.          // Not found.
2723          return NULL;          return nullptr;
2724  }  }
2725    
2726    
# Line 2658  void MainForm::channelsMenuAboutToShow ( Line 2735  void MainForm::channelsMenuAboutToShow (
2735                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
2736          if (!wlist.isEmpty()) {          if (!wlist.isEmpty()) {
2737                  m_ui.channelsMenu->addSeparator();                  m_ui.channelsMenu->addSeparator();
2738                  const int iStripCount = wlist.count();                  int iStrip = 0;
2739                  for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2740                          ChannelStrip *pChannelStrip = NULL;                          ChannelStrip *pChannelStrip
2741                          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                         if (pMdiSubWindow)  
                                 pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2742                          if (pChannelStrip) {                          if (pChannelStrip) {
2743                                  QAction *pAction = m_ui.channelsMenu->addAction(                                  QAction *pAction = m_ui.channelsMenu->addAction(
2744                                          pChannelStrip->windowTitle(),                                          pChannelStrip->windowTitle(),
# Line 2672  void MainForm::channelsMenuAboutToShow ( Line 2747  void MainForm::channelsMenuAboutToShow (
2747                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);
2748                                  pAction->setData(iStrip);                                  pAction->setData(iStrip);
2749                          }                          }
2750                            ++iStrip;
2751                  }                  }
2752          }          }
2753  }  }
# Line 2682  void MainForm::channelsMenuActivated (vo Line 2758  void MainForm::channelsMenuActivated (vo
2758  {  {
2759          // Retrive channel index from action data...          // Retrive channel index from action data...
2760          QAction *pAction = qobject_cast<QAction *> (sender());          QAction *pAction = qobject_cast<QAction *> (sender());
2761          if (pAction == NULL)          if (pAction == nullptr)
2762                  return;                  return;
2763    
2764          ChannelStrip *pChannelStrip = channelStripAt(pAction->data().toInt());          ChannelStrip *pChannelStrip = channelStripAt(pAction->data().toInt());
# Line 2713  void MainForm::stopSchedule (void) Line 2789  void MainForm::stopSchedule (void)
2789  // Timer slot funtion.  // Timer slot funtion.
2790  void MainForm::timerSlot (void)  void MainForm::timerSlot (void)
2791  {  {
2792          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2793                  return;                  return;
2794    
2795          // 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 2824  void MainForm::timerSlot (void)
2824                                  // Update the channel stream usage for each strip...                                  // Update the channel stream usage for each strip...
2825                                  const QList<QMdiSubWindow *>& wlist                                  const QList<QMdiSubWindow *>& wlist
2826                                          = m_pWorkspace->subWindowList();                                          = m_pWorkspace->subWindowList();
2827                                  const int iStripCount = wlist.count();                                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2828                                  for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                                          ChannelStrip *pChannelStrip
2829                                          ChannelStrip *pChannelStrip = NULL;                                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                                         QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                                         if (pMdiSubWindow)  
                                                 pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2830                                          if (pChannelStrip && pChannelStrip->isVisible())                                          if (pChannelStrip && pChannelStrip->isVisible())
2831                                                  pChannelStrip->updateChannelUsage();                                                  pChannelStrip->updateChannelUsage();
2832                                  }                                  }
2833                          }                          }
2834                  }                  }
2835    
2836            #if CONFIG_LSCP_CLIENT_CONNECTION_LOST
2837                    // If we lost connection to server: Try to automatically reconnect if we
2838                    // did not start the server.
2839                    //
2840                    // TODO: If we started the server, then we might inform the user that
2841                    // the server probably crashed and asking user ONCE whether we should
2842                    // restart the server.
2843                    if (lscp_client_connection_lost(m_pClient) && !m_pServer)
2844                            startAutoReconnectClient();
2845            #endif // CONFIG_LSCP_CLIENT_CONNECTION_LOST
2846          }          }
2847    
2848          // Register the next timer slot.          // Register the next timer slot.
# Line 2772  void MainForm::timerSlot (void) Line 2856  void MainForm::timerSlot (void)
2856  // Start linuxsampler server...  // Start linuxsampler server...
2857  void MainForm::startServer (void)  void MainForm::startServer (void)
2858  {  {
2859          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2860                  return;                  return;
2861    
2862          // Aren't already a client, are we?          // Aren't already a client, are we?
# Line 2782  void MainForm::startServer (void) Line 2866  void MainForm::startServer (void)
2866          // Is the server process instance still here?          // Is the server process instance still here?
2867          if (m_pServer) {          if (m_pServer) {
2868                  if (QMessageBox::warning(this,                  if (QMessageBox::warning(this,
2869                          QSAMPLER_TITLE ": " + tr("Warning"),                          tr("Warning"),
2870                          tr("Could not start the LinuxSampler server.\n\n"                          tr("Could not start the LinuxSampler server.\n\n"
2871                          "Maybe it is already started."),                          "Maybe it is already started."),
2872                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
# Line 2852  void MainForm::stopServer ( bool bIntera Line 2936  void MainForm::stopServer ( bool bIntera
2936    
2937          if (m_pServer && bInteractive) {          if (m_pServer && bInteractive) {
2938                  if (QMessageBox::question(this,                  if (QMessageBox::question(this,
2939                          QSAMPLER_TITLE ": " + tr("The backend's fate ..."),                          tr("The backend's fate ..."),
2940                          tr("You have the option to keep the sampler backend (LinuxSampler)\n"                          tr("You have the option to keep the sampler backend (LinuxSampler)\n"
2941                          "running in the background. The sampler would continue to work\n"                          "running in the background. The sampler would continue to work\n"
2942                          "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 2948  void MainForm::stopServer ( bool bIntera
2948                  }                  }
2949          }          }
2950    
2951            bool bGraceWait = true;
2952    
2953          // And try to stop server.          // And try to stop server.
2954          if (m_pServer && m_bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2955                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2956                  if (m_pServer->state() == QProcess::Running) {                  if (m_pServer->state() == QProcess::Running) {
2957                  #if defined(_WIN32)                  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
2958                          // Try harder...                          // Try harder...
2959                          m_pServer->kill();                          m_pServer->kill();
2960                  #else                  #else
2961                          // Try softly...                          // Try softly...
2962                          m_pServer->terminate();                          m_pServer->terminate();
2963                            bool bFinished = m_pServer->waitForFinished(QSAMPLER_TIMER_MSECS * 1000);
2964                            if (bFinished) bGraceWait = false;
2965                  #endif                  #endif
2966                  }                  }
2967          }       // Do final processing anyway.          }       // Do final processing anyway.
2968          else processServerExit();          else processServerExit();
2969    
2970          // Give it some time to terminate gracefully and stabilize...          // Give it some time to terminate gracefully and stabilize...
2971          QTime t;          if (bGraceWait) {
2972          t.start();                  QElapsedTimer timer;
2973          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                  timer.start();
2974                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  while (timer.elapsed() < QSAMPLER_TIMER_MSECS)
2975                            QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2976            }
2977  }  }
2978    
2979    
# Line 2911  void MainForm::processServerExit (void) Line 3001  void MainForm::processServerExit (void)
3001                          // Force final server shutdown...                          // Force final server shutdown...
3002                          m_pServer->kill();                          m_pServer->kill();
3003                          // Give it some time to terminate gracefully and stabilize...                          // Give it some time to terminate gracefully and stabilize...
3004                          QTime t;                          QElapsedTimer timer;
3005                          t.start();                          timer.start();
3006                          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                          while (timer.elapsed() < QSAMPLER_TIMER_MSECS)
3007                                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
3008                  }                  }
3009                  // Force final server shutdown...                  // Force final server shutdown...
# Line 2921  void MainForm::processServerExit (void) Line 3011  void MainForm::processServerExit (void)
3011                          tr("Server was stopped with exit status %1.")                          tr("Server was stopped with exit status %1.")
3012                          .arg(m_pServer->exitStatus()));                          .arg(m_pServer->exitStatus()));
3013                  delete m_pServer;                  delete m_pServer;
3014                  m_pServer = NULL;                  m_pServer = nullptr;
3015          }          }
3016    
3017          // Again, make status visible stable.          // Again, make status visible stable.
# Line 2937  lscp_status_t qsampler_client_callback ( Line 3027  lscp_status_t qsampler_client_callback (
3027          lscp_event_t event, const char *pchData, int cchData, void *pvData )          lscp_event_t event, const char *pchData, int cchData, void *pvData )
3028  {  {
3029          MainForm* pMainForm = (MainForm *) pvData;          MainForm* pMainForm = (MainForm *) pvData;
3030          if (pMainForm == NULL)          if (pMainForm == nullptr)
3031                  return LSCP_FAILED;                  return LSCP_FAILED;
3032    
3033          // 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 3041  lscp_status_t qsampler_client_callback (
3041    
3042    
3043  // Start our almighty client...  // Start our almighty client...
3044  bool MainForm::startClient (void)  bool MainForm::startClient (bool bReconnectOnly)
3045  {  {
3046          // Have it a setup?          // Have it a setup?
3047          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
3048                  return false;                  return false;
3049    
3050          // Aren't we already started, are we?          // Aren't we already started, are we?
# Line 2968  bool MainForm::startClient (void) Line 3058  bool MainForm::startClient (void)
3058          m_pClient = ::lscp_client_create(          m_pClient = ::lscp_client_create(
3059                  m_pOptions->sServerHost.toUtf8().constData(),                  m_pOptions->sServerHost.toUtf8().constData(),
3060                  m_pOptions->iServerPort, qsampler_client_callback, this);                  m_pOptions->iServerPort, qsampler_client_callback, this);
3061          if (m_pClient == NULL) {          if (m_pClient == nullptr) {
3062                  // Is this the first try?                  // Is this the first try?
3063                  // maybe we need to start a local server...                  // maybe we need to start a local server...
3064                  if ((m_pServer && m_pServer->state() == QProcess::Running)                  if ((m_pServer && m_pServer->state() == QProcess::Running)
3065                          || !m_pOptions->bServerStart) {                          || !m_pOptions->bServerStart || bReconnectOnly)
3066                          appendMessagesError(                  {
3067                                  tr("Could not connect to server as client.\n\nSorry."));                          // if this method is called from autoReconnectClient()
3068                            // then don't bother user with an error message...
3069                            if (!bReconnectOnly) {
3070                                    appendMessagesError(
3071                                            tr("Could not connect to server as client.\n\nSorry.")
3072                                    );
3073                            }
3074                  } else {                  } else {
3075                          startServer();                          startServer();
3076                  }                  }
# Line 3038  bool MainForm::startClient (void) Line 3134  bool MainForm::startClient (void)
3134          if (!m_pOptions->sSessionFile.isEmpty()) {          if (!m_pOptions->sSessionFile.isEmpty()) {
3135                  // Just load the prabably startup session...                  // Just load the prabably startup session...
3136                  if (loadSessionFile(m_pOptions->sSessionFile)) {                  if (loadSessionFile(m_pOptions->sSessionFile)) {
3137                          m_pOptions->sSessionFile = QString::null;                          m_pOptions->sSessionFile = QString();
3138                          return true;                          return true;
3139                  }                  }
3140          }          }
# Line 3054  bool MainForm::startClient (void) Line 3150  bool MainForm::startClient (void)
3150  // Stop client...  // Stop client...
3151  void MainForm::stopClient (void)  void MainForm::stopClient (void)
3152  {  {
3153          if (m_pClient == NULL)          if (m_pClient == nullptr)
3154                  return;                  return;
3155    
3156          // Log prepare here.          // Log prepare here.
# Line 3086  void MainForm::stopClient (void) Line 3182  void MainForm::stopClient (void)
3182          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
3183          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);
3184          ::lscp_client_destroy(m_pClient);          ::lscp_client_destroy(m_pClient);
3185          m_pClient = NULL;          m_pClient = nullptr;
3186    
3187          // Hard-notify instrumnet and device configuration forms,          // Hard-notify instrumnet and device configuration forms,
3188          // if visible, that we're running out...          // if visible, that we're running out...
# Line 3103  void MainForm::stopClient (void) Line 3199  void MainForm::stopClient (void)
3199  }  }
3200    
3201    
3202    void MainForm::startAutoReconnectClient (void)
3203    {
3204            stopClient();
3205            appendMessages(tr("Trying to reconnect..."));
3206            QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(autoReconnectClient()));
3207    }
3208    
3209    
3210    void MainForm::autoReconnectClient (void)
3211    {
3212            const bool bSuccess = startClient(true);
3213            if (!bSuccess)
3214                    QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(autoReconnectClient()));
3215    }
3216    
3217    
3218  // Channel strip activation/selection.  // Channel strip activation/selection.
3219  void MainForm::activateStrip ( QMdiSubWindow *pMdiSubWindow )  void MainForm::activateStrip ( QMdiSubWindow *pMdiSubWindow )
3220  {  {
3221          ChannelStrip *pChannelStrip = NULL;          ChannelStrip *pChannelStrip = nullptr;
3222          if (pMdiSubWindow)          if (pMdiSubWindow)
3223                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
3224          if (pChannelStrip)          if (pChannelStrip)

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

  ViewVC Help
Powered by ViewVC