/[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 3849 by capela, Thu Jan 7 16:18:02 2021 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-2021, 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 42  Line 46 
46  #include <QProcess>  #include <QProcess>
47  #include <QMessageBox>  #include <QMessageBox>
48    
 #include <QRegExp>  
49  #include <QTextStream>  #include <QTextStream>
50  #include <QFileDialog>  #include <QFileDialog>
51  #include <QFileInfo>  #include <QFileInfo>
# Line 58  Line 61 
61  #include <QTimer>  #include <QTimer>
62  #include <QDateTime>  #include <QDateTime>
63    
64  #if QT_VERSION >= 0x050000  #include <QElapsedTimer>
65    
66    #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
67  #include <QMimeData>  #include <QMimeData>
68  #endif  #endif
69    
70  #if QT_VERSION < 0x040500  #if QT_VERSION < QT_VERSION_CHECK(4, 5, 0)
71  namespace Qt {  namespace Qt {
72  const WindowFlags WindowCloseButtonHint = WindowFlags(0x08000000);  const WindowFlags WindowCloseButtonHint = WindowFlags(0x08000000);
73  }  }
74  #endif  #endif
75    
 #ifdef HAVE_SIGNAL_H  
 #include <signal.h>  
 #endif  
   
76  #ifdef CONFIG_LIBGIG  #ifdef CONFIG_LIBGIG
77    #pragma GCC diagnostic push
78    #pragma GCC diagnostic ignored "-Wunused-parameter"
79  #include <gig.h>  #include <gig.h>
80    #pragma GCC diagnostic pop
81  #endif  #endif
82    
83  // Needed for lroundf()  // Deprecated QTextStreamFunctions/Qt namespaces workaround.
84  #include <math.h>  #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
85    #define endl    Qt::endl
86    #endif
87    
88  #ifndef CONFIG_ROUND  // Needed for lroundf()
89    #ifdef CONFIG_ROUND
90    #include <cmath>
91    #else
92  static inline long lroundf ( float x )  static inline long lroundf ( float x )
93  {  {
94          if (x >= 0.0f)          if (x >= 0.0f)
# Line 91  static inline long lroundf ( float x ) Line 100  static inline long lroundf ( float x )
100    
101    
102  // All winsock apps needs this.  // All winsock apps needs this.
103  #if defined(_WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
104  static WSADATA _wsaData;  static WSADATA _wsaData;
105    #undef HAVE_SIGNAL_H
106  #endif  #endif
107    
108    
# Line 103  static WSADATA _wsaData; Line 113  static WSADATA _wsaData;
113    
114  #include <QSocketNotifier>  #include <QSocketNotifier>
115    
116    #include <unistd.h>
117  #include <sys/types.h>  #include <sys/types.h>
118  #include <sys/socket.h>  #include <sys/socket.h>
   
119  #include <signal.h>  #include <signal.h>
120    
121  // File descriptor for SIGUSR1 notifier.  // File descriptor for SIGUSR1 notifier.
122  static int g_fdUsr1[2];  static int g_fdSigusr1[2] = { -1, -1 };
123    
124  // Unix SIGUSR1 signal handler.  // Unix SIGUSR1 signal handler.
125  static void qsampler_sigusr1_handler ( int /* signo */ )  static void qsampler_sigusr1_handler ( int /* signo */ )
126  {  {
127          char c = 1;          char c = 1;
128    
129          (::write(g_fdUsr1[0], &c, sizeof(c)) > 0);          (::write(g_fdSigusr1[0], &c, sizeof(c)) > 0);
130    }
131    
132    // File descriptor for SIGTERM notifier.
133    static int g_fdSigterm[2] = { -1, -1 };
134    
135    // Unix SIGTERM signal handler.
136    static void qsampler_sigterm_handler ( int /* signo */ )
137    {
138            char c = 1;
139    
140            (::write(g_fdSigterm[0], &c, sizeof(c)) > 0);
141  }  }
142    
143  #endif  // HAVE_SIGNAL_H  #endif  // HAVE_SIGNAL_H
# Line 194  protected: Line 215  protected:
215  // QSampler::MainForm -- Main window form implementation.  // QSampler::MainForm -- Main window form implementation.
216    
217  // Kind of singleton reference.  // Kind of singleton reference.
218  MainForm *MainForm::g_pMainForm = NULL;  MainForm *MainForm::g_pMainForm = nullptr;
219    
220  MainForm::MainForm ( QWidget *pParent )  MainForm::MainForm ( QWidget *pParent )
221          : QMainWindow(pParent)          : QMainWindow(pParent)
# Line 205  MainForm::MainForm ( QWidget *pParent ) Line 226  MainForm::MainForm ( QWidget *pParent )
226          g_pMainForm = this;          g_pMainForm = this;
227    
228          // Initialize some pointer references.          // Initialize some pointer references.
229          m_pOptions = NULL;          m_pOptions = nullptr;
230    
231          // All child forms are to be created later, not earlier than setup.          // All child forms are to be created later, not earlier than setup.
232          m_pMessages = NULL;          m_pMessages = nullptr;
233          m_pInstrumentListForm = NULL;          m_pInstrumentListForm = nullptr;
234          m_pDeviceForm = NULL;          m_pDeviceForm = nullptr;
235    
236          // We'll start clean.          // We'll start clean.
237          m_iUntitled   = 0;          m_iUntitled   = 0;
238          m_iDirtySetup = 0;          m_iDirtySetup = 0;
239          m_iDirtyCount = 0;          m_iDirtyCount = 0;
240    
241          m_pServer = NULL;          m_pServer = nullptr;
242          m_pClient = NULL;          m_pClient = nullptr;
243    
244          m_iStartDelay = 0;          m_iStartDelay = 0;
245          m_iTimerDelay = 0;          m_iTimerDelay = 0;
# Line 233  MainForm::MainForm ( QWidget *pParent ) Line 254  MainForm::MainForm ( QWidget *pParent )
254          // LADISH Level 1 suport.          // LADISH Level 1 suport.
255    
256          // Initialize file descriptors for SIGUSR1 socket notifier.          // Initialize file descriptors for SIGUSR1 socket notifier.
257          ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdUsr1);          ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigusr1);
258          m_pUsr1Notifier          m_pSigusr1Notifier
259                  = new QSocketNotifier(g_fdUsr1[1], QSocketNotifier::Read, this);                  = new QSocketNotifier(g_fdSigusr1[1], QSocketNotifier::Read, this);
260    
261          QObject::connect(m_pUsr1Notifier,          QObject::connect(m_pSigusr1Notifier,
262                  SIGNAL(activated(int)),                  SIGNAL(activated(int)),
263                  SLOT(handle_sigusr1()));                  SLOT(handle_sigusr1()));
264    
265          // Install SIGUSR1 signal handler.          // Install SIGUSR1 signal handler.
266      struct sigaction usr1;          struct sigaction sigusr1;
267      usr1.sa_handler = qsampler_sigusr1_handler;          sigusr1.sa_handler = qsampler_sigusr1_handler;
268      sigemptyset(&usr1.sa_mask);          sigemptyset(&sigusr1.sa_mask);
269      usr1.sa_flags = 0;          sigusr1.sa_flags = 0;
270      usr1.sa_flags |= SA_RESTART;          sigusr1.sa_flags |= SA_RESTART;
271      ::sigaction(SIGUSR1, &usr1, NULL);          ::sigaction(SIGUSR1, &sigusr1, nullptr);
272    
273            // Initialize file descriptors for SIGTERM socket notifier.
274            ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigterm);
275            m_pSigtermNotifier
276                    = new QSocketNotifier(g_fdSigterm[1], QSocketNotifier::Read, this);
277    
278            QObject::connect(m_pSigtermNotifier,
279                    SIGNAL(activated(int)),
280                    SLOT(handle_sigterm()));
281    
282            // Install SIGTERM signal handler.
283            struct sigaction sigterm;
284            sigterm.sa_handler = qsampler_sigterm_handler;
285            sigemptyset(&sigterm.sa_mask);
286            sigterm.sa_flags = 0;
287            sigterm.sa_flags |= SA_RESTART;
288            ::sigaction(SIGTERM, &sigterm, nullptr);
289            ::sigaction(SIGQUIT, &sigterm, nullptr);
290    
291            // Ignore SIGHUP/SIGINT signals.
292            ::signal(SIGHUP, SIG_IGN);
293            ::signal(SIGINT, SIG_IGN);
294    
295  #else   // HAVE_SIGNAL_H  #else   // HAVE_SIGNAL_H
296    
297          m_pUsr1Notifier = NULL;          m_pSigusr1Notifier = nullptr;
298            m_pSigtermNotifier = nullptr;
299                    
300  #endif  // !HAVE_SIGNAL_H  #endif  // !HAVE_SIGNAL_H
301    
# Line 324  MainForm::MainForm ( QWidget *pParent ) Line 368  MainForm::MainForm ( QWidget *pParent )
368          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
369          statusBar()->addWidget(pLabel);          statusBar()->addWidget(pLabel);
370    
371  #if defined(_WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
372          WSAStartup(MAKEWORD(1, 1), &_wsaData);          WSAStartup(MAKEWORD(1, 1), &_wsaData);
373  #endif  #endif
374    
# Line 425  MainForm::~MainForm() Line 469  MainForm::~MainForm()
469          // Do final processing anyway.          // Do final processing anyway.
470          processServerExit();          processServerExit();
471    
472  #if defined(_WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
473          WSACleanup();          WSACleanup();
474  #endif  #endif
475    
476  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
477          if (m_pUsr1Notifier)          if (m_pSigusr1Notifier)
478                  delete m_pUsr1Notifier;                  delete m_pSigusr1Notifier;
479            if (m_pSigtermNotifier)
480                    delete m_pSigtermNotifier;
481  #endif  #endif
482    
483          // Finally drop any widgets around...          // Finally drop any widgets around...
# Line 460  MainForm::~MainForm() Line 506  MainForm::~MainForm()
506  #endif  #endif
507    
508          // Pseudo-singleton reference shut-down.          // Pseudo-singleton reference shut-down.
509          g_pMainForm = NULL;          g_pMainForm = nullptr;
510  }  }
511    
512    
# Line 597  void MainForm::closeEvent ( QCloseEvent Line 643  void MainForm::closeEvent ( QCloseEvent
643  void MainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )  void MainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
644  {  {
645          // Accept external drags only...          // Accept external drags only...
646          if (pDragEnterEvent->source() == NULL          if (pDragEnterEvent->source() == nullptr
647                  && pDragEnterEvent->mimeData()->hasUrls()) {                  && pDragEnterEvent->mimeData()->hasUrls()) {
648                  pDragEnterEvent->accept();                  pDragEnterEvent->accept();
649          } else {          } else {
# Line 621  void MainForm::dropEvent ( QDropEvent *p Line 667  void MainForm::dropEvent ( QDropEvent *p
667                          if (QFileInfo(sPath).exists()) {                          if (QFileInfo(sPath).exists()) {
668                                  // Try to create a new channel from instrument file...                                  // Try to create a new channel from instrument file...
669                                  Channel *pChannel = new Channel();                                  Channel *pChannel = new Channel();
670                                  if (pChannel == NULL)                                  if (pChannel == nullptr)
671                                          return;                                          return;
672                                  // Start setting the instrument filename...                                  // Start setting the instrument filename...
673                                  pChannel->setInstrument(sPath, 0);                                  pChannel->setInstrument(sPath, 0);
# Line 721  void MainForm::handle_sigusr1 (void) Line 767  void MainForm::handle_sigusr1 (void)
767    
768          char c;          char c;
769    
770          if (::read(g_fdUsr1[1], &c, sizeof(c)) > 0)          if (::read(g_fdSigusr1[1], &c, sizeof(c)) > 0)
771                  saveSession(false);                  saveSession(false);
772    
773  #endif  #endif
774  }  }
775    
776    
777    void MainForm::handle_sigterm (void)
778    {
779    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
780    
781            char c;
782    
783            if (::read(g_fdSigterm[1], &c, sizeof(c)) > 0)
784                    close();
785    
786    #endif
787    }
788    
789    
790  void MainForm::updateViewMidiDeviceStatusMenu (void)  void MainForm::updateViewMidiDeviceStatusMenu (void)
791  {  {
792          m_ui.viewMidiDeviceStatusMenu->clear();          m_ui.viewMidiDeviceStatusMenu->clear();
# Line 806  bool MainForm::newSession (void) Line 865  bool MainForm::newSession (void)
865          m_iUntitled++;          m_iUntitled++;
866    
867          // Stabilize form.          // Stabilize form.
868          m_sFilename = QString::null;          m_sFilename = QString();
869          m_iDirtyCount = 0;          m_iDirtyCount = 0;
870          appendMessages(tr("New session: \"%1\".").arg(sessionName(m_sFilename)));          appendMessages(tr("New session: \"%1\".").arg(sessionName(m_sFilename)));
871          stabilizeForm();          stabilizeForm();
# Line 818  bool MainForm::newSession (void) Line 877  bool MainForm::newSession (void)
877  // Open an existing sampler session.  // Open an existing sampler session.
878  bool MainForm::openSession (void)  bool MainForm::openSession (void)
879  {  {
880          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
881                  return false;                  return false;
882    
883          // Ask for the filename to open...          // Ask for the filename to open...
884          QString sFilename = QFileDialog::getOpenFileName(this,          QString sFilename = QFileDialog::getOpenFileName(this,
885                  QSAMPLER_TITLE ": " + tr("Open Session"), // Caption.                  tr("Open Session"),                       // Caption.
886                  m_pOptions->sSessionDir,                  // Start here.                  m_pOptions->sSessionDir,                  // Start here.
887                  tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)                  tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)
888          );          );
# Line 844  bool MainForm::openSession (void) Line 903  bool MainForm::openSession (void)
903  // Save current sampler session with another name.  // Save current sampler session with another name.
904  bool MainForm::saveSession ( bool bPrompt )  bool MainForm::saveSession ( bool bPrompt )
905  {  {
906          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
907                  return false;                  return false;
908    
909          QString sFilename = m_sFilename;          QString sFilename = m_sFilename;
# Line 856  bool MainForm::saveSession ( bool bPromp Line 915  bool MainForm::saveSession ( bool bPromp
915                          sFilename = m_pOptions->sSessionDir;                          sFilename = m_pOptions->sSessionDir;
916                  // Prompt the guy...                  // Prompt the guy...
917                  sFilename = QFileDialog::getSaveFileName(this,                  sFilename = QFileDialog::getSaveFileName(this,
918                          QSAMPLER_TITLE ": " + tr("Save Session"), // Caption.                          tr("Save Session"),                       // Caption.
919                          sFilename,                                // Start here.                          sFilename,                                // Start here.
920                          tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)                          tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)
921                  );                  );
# Line 866  bool MainForm::saveSession ( bool bPromp Line 925  bool MainForm::saveSession ( bool bPromp
925                  // Enforce .lscp extension...                  // Enforce .lscp extension...
926                  if (QFileInfo(sFilename).suffix().isEmpty())                  if (QFileInfo(sFilename).suffix().isEmpty())
927                          sFilename += ".lscp";                          sFilename += ".lscp";
928            #if 0
929                  // Check if already exists...                  // Check if already exists...
930                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
931                          if (QMessageBox::warning(this,                          if (QMessageBox::warning(this,
932                                  QSAMPLER_TITLE ": " + tr("Warning"),                                  tr("Warning"),
933                                  tr("The file already exists:\n\n"                                  tr("The file already exists:\n\n"
934                                  "\"%1\"\n\n"                                  "\"%1\"\n\n"
935                                  "Do you want to replace it?")                                  "Do you want to replace it?")
# Line 878  bool MainForm::saveSession ( bool bPromp Line 938  bool MainForm::saveSession ( bool bPromp
938                                  == QMessageBox::No)                                  == QMessageBox::No)
939                                  return false;                                  return false;
940                  }                  }
941            #endif
942          }          }
943    
944          // Save it right away.          // Save it right away.
# Line 893  bool MainForm::closeSession ( bool bForc Line 954  bool MainForm::closeSession ( bool bForc
954          // Are we dirty enough to prompt it?          // Are we dirty enough to prompt it?
955          if (m_iDirtyCount > 0) {          if (m_iDirtyCount > 0) {
956                  switch (QMessageBox::warning(this,                  switch (QMessageBox::warning(this,
957                          QSAMPLER_TITLE ": " + tr("Warning"),                          tr("Warning"),
958                          tr("The current session has been changed:\n\n"                          tr("The current session has been changed:\n\n"
959                          "\"%1\"\n\n"                          "\"%1\"\n\n"
960                          "Do you want to save the changes?")                          "Do you want to save the changes?")
# Line 918  bool MainForm::closeSession ( bool bForc Line 979  bool MainForm::closeSession ( bool bForc
979                  m_pWorkspace->setUpdatesEnabled(false);                  m_pWorkspace->setUpdatesEnabled(false);
980                  const QList<QMdiSubWindow *>& wlist                  const QList<QMdiSubWindow *>& wlist
981                          = m_pWorkspace->subWindowList();                          = m_pWorkspace->subWindowList();
982                  const int iStripCount = wlist.count();                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
983                  for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                          ChannelStrip *pChannelStrip
984                          ChannelStrip *pChannelStrip = NULL;                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                         QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                         if (pMdiSubWindow)  
                                 pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
985                          if (pChannelStrip) {                          if (pChannelStrip) {
986                                  Channel *pChannel = pChannelStrip->channel();                                  Channel *pChannel = pChannelStrip->channel();
987                                  if (bForce && pChannel)                                  if (bForce && pChannel)
988                                          pChannel->removeChannel();                                          pChannel->removeChannel();
989                                  delete pChannelStrip;                                  delete pChannelStrip;
990                          }                          }
991                          if (pMdiSubWindow)                          delete pMdiSubWindow;
                                 delete pMdiSubWindow;  
992                  }                  }
993                  m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
994                  // We're now clean, for sure.                  // We're now clean, for sure.
# Line 945  bool MainForm::closeSession ( bool bForc Line 1002  bool MainForm::closeSession ( bool bForc
1002  // Load a session from specific file path.  // Load a session from specific file path.
1003  bool MainForm::loadSessionFile ( const QString& sFilename )  bool MainForm::loadSessionFile ( const QString& sFilename )
1004  {  {
1005          if (m_pClient == NULL)          if (m_pClient == nullptr)
1006                  return false;                  return false;
1007    
1008          // Open and read from real file.          // Open and read from real file.
# Line 1021  bool MainForm::loadSessionFile ( const Q Line 1078  bool MainForm::loadSessionFile ( const Q
1078  // Save current session to specific file path.  // Save current session to specific file path.
1079  bool MainForm::saveSessionFile ( const QString& sFilename )  bool MainForm::saveSessionFile ( const QString& sFilename )
1080  {  {
1081          if (m_pClient == NULL)          if (m_pClient == nullptr)
1082                  return false;                  return false;
1083    
1084          // Check whether server is apparently OK...          // Check whether server is apparently OK...
# Line 1060  bool MainForm::saveSessionFile ( const Q Line 1117  bool MainForm::saveSessionFile ( const Q
1117          // It is assumed that this new kind of device+session file          // It is assumed that this new kind of device+session file
1118          // will be loaded from a complete initialized server...          // will be loaded from a complete initialized server...
1119          int *piDeviceIDs;          int *piDeviceIDs;
1120          int  iDevice;          int  i, iDevice;
1121          ts << "RESET" << endl;          ts << "RESET" << endl;
1122    
1123          // Audio device mapping.          // Audio device mapping.
1124          QMap<int, int> audioDeviceMap;          QMap<int, int> audioDeviceMap; iDevice = 0;
1125          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);
1126          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1127                  ts << endl;                  Device device(Device::Audio, piDeviceIDs[i]);
1128                  Device device(Device::Audio, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1129                    if (device.driverName().toUpper() == "PLUGIN")
1130                            continue;
1131                  // Audio device specification...                  // Audio device specification...
1132                    ts << endl;
1133                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1134                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1135                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
# Line 1100  bool MainForm::saveSessionFile ( const Q Line 1160  bool MainForm::saveSessionFile ( const Q
1160                          iPort++;                          iPort++;
1161                  }                  }
1162                  // Audio device index/id mapping.                  // Audio device index/id mapping.
1163                  audioDeviceMap[device.deviceID()] = iDevice;                  audioDeviceMap.insert(device.deviceID(), iDevice++);
1164                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1165                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1166          }          }
1167    
1168          // MIDI device mapping.          // MIDI device mapping.
1169          QMap<int, int> midiDeviceMap;          QMap<int, int> midiDeviceMap; iDevice = 0;
1170          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);
1171          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1172                  ts << endl;                  Device device(Device::Midi, piDeviceIDs[i]);
1173                  Device device(Device::Midi, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1174                    if (device.driverName().toUpper() == "PLUGIN")
1175                            continue;
1176                  // MIDI device specification...                  // MIDI device specification...
1177                    ts << endl;
1178                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1179                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1180                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
# Line 1142  bool MainForm::saveSessionFile ( const Q Line 1205  bool MainForm::saveSessionFile ( const Q
1205                          iPort++;                          iPort++;
1206                  }                  }
1207                  // MIDI device index/id mapping.                  // MIDI device index/id mapping.
1208                  midiDeviceMap[device.deviceID()] = iDevice;                  midiDeviceMap.insert(device.deviceID(), iDevice++);
1209                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1210                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1211          }          }
# Line 1205  bool MainForm::saveSessionFile ( const Q Line 1268  bool MainForm::saveSessionFile ( const Q
1268                  }                  }
1269                  ts << endl;                  ts << endl;
1270                  // Check for errors...                  // Check for errors...
1271                  if (pInstrs == NULL && ::lscp_client_get_errno(m_pClient)) {                  if (pInstrs == nullptr && ::lscp_client_get_errno(m_pClient)) {
1272                          appendMessagesClient("lscp_list_midi_instruments");                          appendMessagesClient("lscp_list_midi_instruments");
1273                          iErrors++;                          iErrors++;
1274                  }                  }
1275                  // MIDI strument index/id mapping.                  // MIDI strument index/id mapping.
1276                  midiInstrumentMap[iMidiMap] = iMap;                  midiInstrumentMap.insert(iMidiMap, iMap);
1277          }          }
1278          // Check for errors...          // Check for errors...
1279          if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {          if (piMaps == nullptr && ::lscp_client_get_errno(m_pClient)) {
1280                  appendMessagesClient("lscp_list_midi_instrument_maps");                  appendMessagesClient("lscp_list_midi_instrument_maps");
1281                  iErrors++;                  iErrors++;
1282          }          }
1283  #endif  // CONFIG_MIDI_INSTRUMENT  #endif  // CONFIG_MIDI_INSTRUMENT
1284    
1285          // Sampler channel mapping.          // Sampler channel mapping...
1286            int iChannelID = 0;
1287          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
1288                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
1289          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
1290          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
1291                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
1292                  if (pChannelStrip) {                  if (pChannelStrip) {
1293                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1294                          if (pChannel) {                          if (pChannel) {
1295                                  const int iChannelID = pChannel->channelID();                                  // Avoid "artifial" plug-in devices...
1296                                    const int iAudioDevice = pChannel->audioDevice();
1297                                    if (!audioDeviceMap.contains(iAudioDevice))
1298                                            continue;
1299                                    const int iMidiDevice = pChannel->midiDevice();
1300                                    if (!midiDeviceMap.contains(iMidiDevice))
1301                                            continue;
1302                                    // Go for regular, canonical devices...
1303                                  ts << "# " << tr("Channel") << " " << iChannelID << endl;                                  ts << "# " << tr("Channel") << " " << iChannelID << endl;
1304                                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
1305                                  if (audioDeviceMap.isEmpty()) {                                  if (audioDeviceMap.isEmpty()) {
# Line 1239  bool MainForm::saveSessionFile ( const Q Line 1307  bool MainForm::saveSessionFile ( const Q
1307                                                  << " " << pChannel->audioDriver() << endl;                                                  << " " << pChannel->audioDriver() << endl;
1308                                  } else {                                  } else {
1309                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannelID                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannelID
1310                                                  << " " << audioDeviceMap[pChannel->audioDevice()] << endl;                                                  << " " << audioDeviceMap.value(iAudioDevice) << endl;
1311                                  }                                  }
1312                                  if (midiDeviceMap.isEmpty()) {                                  if (midiDeviceMap.isEmpty()) {
1313                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID
1314                                                  << " " << pChannel->midiDriver() << endl;                                                  << " " << pChannel->midiDriver() << endl;
1315                                  } else {                                  } else {
1316                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannelID                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannelID
1317                                                  << " " << midiDeviceMap[pChannel->midiDevice()] << endl;                                                  << " " << midiDeviceMap.value(iMidiDevice) << endl;
1318                                  }                                  }
1319                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID
1320                                          << " " << pChannel->midiPort() << endl;                                          << " " << pChannel->midiPort() << endl;
# Line 1277  bool MainForm::saveSessionFile ( const Q Line 1345  bool MainForm::saveSessionFile ( const Q
1345                                  if (pChannel->channelSolo())                                  if (pChannel->channelSolo())
1346                                          ts << "SET CHANNEL SOLO " << iChannelID << " 1" << endl;                                          ts << "SET CHANNEL SOLO " << iChannelID << " 1" << endl;
1347                          #ifdef CONFIG_MIDI_INSTRUMENT                          #ifdef CONFIG_MIDI_INSTRUMENT
1348                                  if (pChannel->midiMap() >= 0) {                                  const int iMidiMap = pChannel->midiMap();
1349                                    if (midiInstrumentMap.contains(iMidiMap)) {
1350                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannelID                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannelID
1351                                                  << " " << midiInstrumentMap[pChannel->midiMap()] << endl;                                                  << " " << midiInstrumentMap.value(iMidiMap) << endl;
1352                                  }                                  }
1353                          #endif                          #endif
1354                          #ifdef CONFIG_FXSEND                          #ifdef CONFIG_FXSEND
# Line 1318  bool MainForm::saveSessionFile ( const Q Line 1387  bool MainForm::saveSessionFile ( const Q
1387                                  }                                  }
1388                          #endif                          #endif
1389                                  ts << endl;                                  ts << endl;
1390                                    // Go for next channel...
1391                                    ++iChannelID;
1392                          }                          }
1393                  }                  }
1394                  // Try to keep it snappy :)                  // Try to keep it snappy :)
# Line 1423  void MainForm::fileSaveAs (void) Line 1494  void MainForm::fileSaveAs (void)
1494  // Reset the sampler instance.  // Reset the sampler instance.
1495  void MainForm::fileReset (void)  void MainForm::fileReset (void)
1496  {  {
1497          if (m_pClient == NULL)          if (m_pClient == nullptr)
1498                  return;                  return;
1499    
1500          // Ask user whether he/she want's an internal sampler reset...          // Ask user whether he/she want's an internal sampler reset...
1501          if (m_pOptions && m_pOptions->bConfirmReset) {          if (m_pOptions && m_pOptions->bConfirmReset) {
1502                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");                  const QString& sTitle = tr("Warning");
1503                  const QString& sText = tr(                  const QString& sText = tr(
1504                          "Resetting the sampler instance will close\n"                          "Resetting the sampler instance will close\n"
1505                          "all device and channel configurations.\n\n"                          "all device and channel configurations.\n\n"
# Line 1479  void MainForm::fileReset (void) Line 1550  void MainForm::fileReset (void)
1550  // Restart the client/server instance.  // Restart the client/server instance.
1551  void MainForm::fileRestart (void)  void MainForm::fileRestart (void)
1552  {  {
1553          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1554                  return;                  return;
1555    
1556          bool bRestart = true;          bool bRestart = true;
# Line 1487  void MainForm::fileRestart (void) Line 1558  void MainForm::fileRestart (void)
1558          // Ask user whether he/she want's a complete restart...          // Ask user whether he/she want's a complete restart...
1559          // (if we're currently up and running)          // (if we're currently up and running)
1560          if (m_pOptions && m_pOptions->bConfirmRestart) {          if (m_pOptions && m_pOptions->bConfirmRestart) {
1561                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");                  const QString& sTitle = tr("Warning");
1562                  const QString& sText = tr(                  const QString& sText = tr(
1563                          "New settings will be effective after\n"                          "New settings will be effective after\n"
1564                          "restarting the client/server connection.\n\n"                          "restarting the client/server connection.\n\n"
# Line 1547  void MainForm::editAddChannel (void) Line 1618  void MainForm::editAddChannel (void)
1618    
1619  void MainForm::addChannelStrip (void)  void MainForm::addChannelStrip (void)
1620  {  {
1621          if (m_pClient == NULL)          if (m_pClient == nullptr)
1622                  return;                  return;
1623    
1624          // Just create the channel instance...          // Just create the channel instance...
1625          Channel *pChannel = new Channel();          Channel *pChannel = new Channel();
1626          if (pChannel == NULL)          if (pChannel == nullptr)
1627                  return;                  return;
1628    
1629          // 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 1659  void MainForm::editRemoveChannel (void)
1659    
1660  void MainForm::removeChannelStrip (void)  void MainForm::removeChannelStrip (void)
1661  {  {
1662          if (m_pClient == NULL)          if (m_pClient == nullptr)
1663                  return;                  return;
1664    
1665          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1666          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1667                  return;                  return;
1668    
1669          Channel *pChannel = pChannelStrip->channel();          Channel *pChannel = pChannelStrip->channel();
1670          if (pChannel == NULL)          if (pChannel == nullptr)
1671                  return;                  return;
1672    
1673          // Prompt user if he/she's sure about this...          // Prompt user if he/she's sure about this...
1674          if (m_pOptions && m_pOptions->bConfirmRemove) {          if (m_pOptions && m_pOptions->bConfirmRemove) {
1675                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");                  const QString& sTitle = tr("Warning");
1676                  const QString& sText = tr(                  const QString& sText = tr(
1677                          "About to remove channel:\n\n"                          "About to remove channel:\n\n"
1678                          "%1\n\n"                          "%1\n\n"
# Line 1644  void MainForm::removeChannelStrip (void) Line 1715  void MainForm::removeChannelStrip (void)
1715  // Setup current sampler channel.  // Setup current sampler channel.
1716  void MainForm::editSetupChannel (void)  void MainForm::editSetupChannel (void)
1717  {  {
1718          if (m_pClient == NULL)          if (m_pClient == nullptr)
1719                  return;                  return;
1720    
1721          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1722          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1723                  return;                  return;
1724    
1725          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1659  void MainForm::editSetupChannel (void) Line 1730  void MainForm::editSetupChannel (void)
1730  // Edit current sampler channel.  // Edit current sampler channel.
1731  void MainForm::editEditChannel (void)  void MainForm::editEditChannel (void)
1732  {  {
1733          if (m_pClient == NULL)          if (m_pClient == nullptr)
1734                  return;                  return;
1735    
1736          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1737          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1738                  return;                  return;
1739    
1740          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1674  void MainForm::editEditChannel (void) Line 1745  void MainForm::editEditChannel (void)
1745  // Reset current sampler channel.  // Reset current sampler channel.
1746  void MainForm::editResetChannel (void)  void MainForm::editResetChannel (void)
1747  {  {
1748          if (m_pClient == NULL)          if (m_pClient == nullptr)
1749                  return;                  return;
1750    
1751          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1752          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1753                  return;                  return;
1754    
1755          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1689  void MainForm::editResetChannel (void) Line 1760  void MainForm::editResetChannel (void)
1760  // Reset all sampler channels.  // Reset all sampler channels.
1761  void MainForm::editResetAllChannels (void)  void MainForm::editResetAllChannels (void)
1762  {  {
1763          if (m_pClient == NULL)          if (m_pClient == nullptr)
1764                  return;                  return;
1765    
1766          // Invoque the channel strip procedure,          // Invoque the channel strip procedure,
# Line 1697  void MainForm::editResetAllChannels (voi Line 1768  void MainForm::editResetAllChannels (voi
1768          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1769          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
1770                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
1771          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
1772          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
1773                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
1774                  if (pChannelStrip)                  if (pChannelStrip)
1775                          pChannelStrip->channelReset();                          pChannelStrip->channelReset();
1776          }          }
# Line 1761  void MainForm::viewMessages ( bool bOn ) Line 1829  void MainForm::viewMessages ( bool bOn )
1829  // Show/hide the MIDI instrument list-view form.  // Show/hide the MIDI instrument list-view form.
1830  void MainForm::viewInstruments (void)  void MainForm::viewInstruments (void)
1831  {  {
1832          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1833                  return;                  return;
1834    
1835          if (m_pInstrumentListForm) {          if (m_pInstrumentListForm) {
# Line 1780  void MainForm::viewInstruments (void) Line 1848  void MainForm::viewInstruments (void)
1848  // Show/hide the device configurator form.  // Show/hide the device configurator form.
1849  void MainForm::viewDevices (void)  void MainForm::viewDevices (void)
1850  {  {
1851          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1852                  return;                  return;
1853    
1854          if (m_pDeviceForm) {          if (m_pDeviceForm) {
# Line 1799  void MainForm::viewDevices (void) Line 1867  void MainForm::viewDevices (void)
1867  // Show options dialog.  // Show options dialog.
1868  void MainForm::viewOptions (void)  void MainForm::viewOptions (void)
1869  {  {
1870          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1871                  return;                  return;
1872    
1873          OptionsForm* pOptionsForm = new OptionsForm(this);          OptionsForm* pOptionsForm = new OptionsForm(this);
# Line 1811  void MainForm::viewOptions (void) Line 1879  void MainForm::viewOptions (void)
1879                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)
1880                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();
1881                  // To track down deferred or immediate changes.                  // To track down deferred or immediate changes.
1882                  const QString sOldServerHost      = m_pOptions->sServerHost;                  const QString sOldServerHost       = m_pOptions->sServerHost;
1883                  const int     iOldServerPort      = m_pOptions->iServerPort;                  const int     iOldServerPort       = m_pOptions->iServerPort;
1884                  const int     iOldServerTimeout   = m_pOptions->iServerTimeout;                  const int     iOldServerTimeout    = m_pOptions->iServerTimeout;
1885                  const bool    bOldServerStart     = m_pOptions->bServerStart;                  const bool    bOldServerStart      = m_pOptions->bServerStart;
1886                  const QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;                  const QString sOldServerCmdLine    = m_pOptions->sServerCmdLine;
1887                  const bool    bOldMessagesLog     = m_pOptions->bMessagesLog;                  const bool    bOldMessagesLog      = m_pOptions->bMessagesLog;
1888                  const QString sOldMessagesLogPath = m_pOptions->sMessagesLogPath;                  const QString sOldMessagesLogPath  = m_pOptions->sMessagesLogPath;
1889                  const QString sOldDisplayFont     = m_pOptions->sDisplayFont;                  const QString sOldDisplayFont      = m_pOptions->sDisplayFont;
1890                  const bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;                  const bool    bOldDisplayEffect    = m_pOptions->bDisplayEffect;
1891                  const int     iOldMaxVolume       = m_pOptions->iMaxVolume;                  const int     iOldMaxVolume        = m_pOptions->iMaxVolume;
1892                  const QString sOldMessagesFont    = m_pOptions->sMessagesFont;                  const QString sOldMessagesFont     = m_pOptions->sMessagesFont;
1893                  const bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;                  const bool    bOldKeepOnTop        = m_pOptions->bKeepOnTop;
1894                  const bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;                  const bool    bOldStdoutCapture    = m_pOptions->bStdoutCapture;
1895                  const int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;                  const int     bOldMessagesLimit    = m_pOptions->bMessagesLimit;
1896                  const int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;                  const int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1897                  const bool    bOldCompletePath    = m_pOptions->bCompletePath;                  const bool    bOldCompletePath     = m_pOptions->bCompletePath;
1898                  const bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;                  const bool    bOldInstrumentNames  = m_pOptions->bInstrumentNames;
1899                  const int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;                  const int     iOldMaxRecentFiles   = m_pOptions->iMaxRecentFiles;
1900                  const int     iOldBaseFontSize    = m_pOptions->iBaseFontSize;                  const int     iOldBaseFontSize     = m_pOptions->iBaseFontSize;
1901                    const QString sOldCustomStyleTheme = m_pOptions->sCustomStyleTheme;
1902                    const QString sOldCustomColorTheme = m_pOptions->sCustomColorTheme;
1903                  // Load the current setup settings.                  // Load the current setup settings.
1904                  pOptionsForm->setup(m_pOptions);                  pOptionsForm->setup(m_pOptions);
1905                  // Show the setup dialog...                  // Show the setup dialog...
1906                  if (pOptionsForm->exec()) {                  if (pOptionsForm->exec()) {
1907                          // Warn if something will be only effective on next run.                          // Warn if something will be only effective on next run.
1908                            int iNeedRestart = 0;
1909                          if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||                          if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1910                                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||                                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture)) {
1911                                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||                                  updateMessagesCapture();
1912                                    ++iNeedRestart;
1913                            }
1914                            if (( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1915                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)     ||                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)     ||
1916                                  (iOldBaseFontSize   !=  m_pOptions->iBaseFontSize)) {                                  (iOldBaseFontSize   !=  m_pOptions->iBaseFontSize)) {
1917                                  QMessageBox::information(this,                                  ++iNeedRestart;
1918                                          QSAMPLER_TITLE ": " + tr("Information"),                          }
1919                                          tr("Some settings may be only effective\n"                          // Check whether restart is needed or whether
1920                                          "next time you start this program."));                          // custom options maybe set up immediately...
1921                                  updateMessagesCapture();                          if (m_pOptions->sCustomStyleTheme != sOldCustomStyleTheme) {
1922                                    if (m_pOptions->sCustomStyleTheme.isEmpty()) {
1923                                            ++iNeedRestart;
1924                                    } else {
1925                                            QApplication::setStyle(
1926                                                    QStyleFactory::create(m_pOptions->sCustomStyleTheme));
1927                                    }
1928                            }
1929                            if (m_pOptions->sCustomColorTheme != sOldCustomColorTheme) {
1930                                    if (m_pOptions->sCustomColorTheme.isEmpty()) {
1931                                            ++iNeedRestart;
1932                                    } else {
1933                                            QPalette pal;
1934                                            if (PaletteForm::namedPalette(
1935                                                            &m_pOptions->settings(), m_pOptions->sCustomColorTheme, pal))
1936                                                    QApplication::setPalette(pal);
1937                                    }
1938                          }                          }
1939                          // Check wheather something immediate has changed.                          // Check wheather something immediate has changed.
1940                          if (( bOldMessagesLog && !m_pOptions->bMessagesLog) ||                          if (( bOldMessagesLog && !m_pOptions->bMessagesLog) ||
# Line 1872  void MainForm::viewOptions (void) Line 1962  void MainForm::viewOptions (void)
1962                                  (!bOldMessagesLimit &&  m_pOptions->bMessagesLimit) ||                                  (!bOldMessagesLimit &&  m_pOptions->bMessagesLimit) ||
1963                                  (iOldMessagesLimitLines !=  m_pOptions->iMessagesLimitLines))                                  (iOldMessagesLimitLines !=  m_pOptions->iMessagesLimitLines))
1964                                  updateMessagesLimit();                                  updateMessagesLimit();
1965                            // Show restart needed message...
1966                            if (iNeedRestart > 0) {
1967                                    QMessageBox::information(this,
1968                                            tr("Information"),
1969                                            tr("Some settings may be only effective\n"
1970                                            "next time you start this program."));
1971                            }
1972                          // And now the main thing, whether we'll do client/server recycling?                          // And now the main thing, whether we'll do client/server recycling?
1973                          if ((sOldServerHost != m_pOptions->sServerHost) ||                          if ((sOldServerHost != m_pOptions->sServerHost) ||
1974                                  (iOldServerPort != m_pOptions->iServerPort) ||                                  (iOldServerPort != m_pOptions->iServerPort) ||
# Line 1905  void MainForm::channelsArrange (void) Line 2002  void MainForm::channelsArrange (void)
2002    
2003          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2004          int y = 0;          int y = 0;
2005          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2006          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  pMdiSubWindow->adjustSize();
2007                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);                  const QRect& frameRect
2008                  if (pMdiSubWindow) {                          = pMdiSubWindow->frameGeometry();
2009                          pMdiSubWindow->adjustSize();                  int w = m_pWorkspace->width();
2010                          int iWidth = m_pWorkspace->width();                  if (w < frameRect.width())
2011                          if (iWidth < pMdiSubWindow->width())                          w = frameRect.width();
2012                                  iWidth = pMdiSubWindow->width();                  const int h = frameRect.height();
2013                          const int iHeight = pMdiSubWindow->frameGeometry().height();                  pMdiSubWindow->setGeometry(0, y, w, h);
2014                          pMdiSubWindow->setGeometry(0, y, iWidth, iHeight);                  y += h;
                         y += iHeight;  
                 }  
2015          }          }
2016          m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
2017    
# Line 1927  void MainForm::channelsArrange (void) Line 2022  void MainForm::channelsArrange (void)
2022  // Auto-arrange channel strips.  // Auto-arrange channel strips.
2023  void MainForm::channelsAutoArrange ( bool bOn )  void MainForm::channelsAutoArrange ( bool bOn )
2024  {  {
2025          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2026                  return;                  return;
2027    
2028          // Toggle the auto-arrange flag.          // Toggle the auto-arrange flag.
# Line 2008  void MainForm::helpAbout (void) Line 2103  void MainForm::helpAbout (void)
2103                  sText += "</font></small>";                  sText += "</font></small>";
2104          }          }
2105          sText += "<br />\n";          sText += "<br />\n";
2106          sText += tr("Using") + ": ";          sText += tr("Using: Qt %1").arg(qVersion());
2107    #if defined(QT_STATIC)
2108            sText += "-static";
2109    #endif
2110            sText += ", ";
2111          sText += ::lscp_client_package();          sText += ::lscp_client_package();
2112          sText += " ";          sText += " ";
2113          sText += ::lscp_client_version();          sText += ::lscp_client_version();
# Line 2031  void MainForm::helpAbout (void) Line 2130  void MainForm::helpAbout (void)
2130          sText += "</small>";          sText += "</small>";
2131          sText += "</p>\n";          sText += "</p>\n";
2132    
2133          QMessageBox::about(this, tr("About") + " " QSAMPLER_TITLE, sText);          QMessageBox::about(this, tr("About"), sText);
2134  }  }
2135    
2136    
# Line 2044  void MainForm::stabilizeForm (void) Line 2143  void MainForm::stabilizeForm (void)
2143          QString sSessionName = sessionName(m_sFilename);          QString sSessionName = sessionName(m_sFilename);
2144          if (m_iDirtyCount > 0)          if (m_iDirtyCount > 0)
2145                  sSessionName += " *";                  sSessionName += " *";
2146          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));          setWindowTitle(sSessionName);
2147    
2148          // Update the main menu state...          // Update the main menu state...
2149          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
2150          const QList<QMdiSubWindow *>& wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist = m_pWorkspace->subWindowList();
2151          const bool bHasClient = (m_pOptions != NULL && m_pClient != NULL);          const bool bHasClient = (m_pOptions != nullptr && m_pClient != nullptr);
2152          const bool bHasChannel = (bHasClient && pChannelStrip != NULL);          const bool bHasChannel = (bHasClient && pChannelStrip != nullptr);
2153          const bool bHasChannels = (bHasClient && wlist.count() > 0);          const bool bHasChannels = (bHasClient && wlist.count() > 0);
2154          m_ui.fileNewAction->setEnabled(bHasClient);          m_ui.fileNewAction->setEnabled(bHasClient);
2155          m_ui.fileOpenAction->setEnabled(bHasClient);          m_ui.fileOpenAction->setEnabled(bHasClient);
2156          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
2157          m_ui.fileSaveAsAction->setEnabled(bHasClient);          m_ui.fileSaveAsAction->setEnabled(bHasClient);
2158          m_ui.fileResetAction->setEnabled(bHasClient);          m_ui.fileResetAction->setEnabled(bHasClient);
2159          m_ui.fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);          m_ui.fileRestartAction->setEnabled(bHasClient || m_pServer == nullptr);
2160          m_ui.editAddChannelAction->setEnabled(bHasClient);          m_ui.editAddChannelAction->setEnabled(bHasClient);
2161          m_ui.editRemoveChannelAction->setEnabled(bHasChannel);          m_ui.editRemoveChannelAction->setEnabled(bHasChannel);
2162          m_ui.editSetupChannelAction->setEnabled(bHasChannel);          m_ui.editSetupChannelAction->setEnabled(bHasChannel);
# Line 2206  void MainForm::updateAllChannelStrips ( Line 2305  void MainForm::updateAllChannelStrips (
2305    
2306          // Retrieve the current channel list.          // Retrieve the current channel list.
2307          int *piChannelIDs = ::lscp_list_channels(m_pClient);          int *piChannelIDs = ::lscp_list_channels(m_pClient);
2308          if (piChannelIDs == NULL) {          if (piChannelIDs == nullptr) {
2309                  if (::lscp_client_get_errno(m_pClient)) {                  if (::lscp_client_get_errno(m_pClient)) {
2310                          appendMessagesClient("lscp_list_channels");                          appendMessagesClient("lscp_list_channels");
2311                          appendMessagesError(                          appendMessagesError(
# Line 2226  void MainForm::updateAllChannelStrips ( Line 2325  void MainForm::updateAllChannelStrips (
2325                  if (bRemoveDeadStrips) {                  if (bRemoveDeadStrips) {
2326                          const QList<QMdiSubWindow *>& wlist                          const QList<QMdiSubWindow *>& wlist
2327                                  = m_pWorkspace->subWindowList();                                  = m_pWorkspace->subWindowList();
2328                          const int iStripCount = wlist.count();                          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2329                          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                                  ChannelStrip *pChannelStrip
2330                                  ChannelStrip *pChannelStrip = NULL;                                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                                 if (pMdiSubWindow)  
                                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2331                                  if (pChannelStrip) {                                  if (pChannelStrip) {
2332                                          bool bExists = false;                                          bool bExists = false;
2333                                          for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {                                          for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {
2334                                                  Channel *pChannel = pChannelStrip->channel();                                                  Channel *pChannel = pChannelStrip->channel();
2335                                                  if (pChannel == NULL)                                                  if (pChannel == nullptr)
2336                                                          break;                                                          break;
2337                                                  if (piChannelIDs[iChannel] == pChannel->channelID()) {                                                  if (piChannelIDs[iChannel] == pChannel->channelID()) {
2338                                                          // strip exists, don't touch it                                                          // strip exists, don't touch it
# Line 2259  void MainForm::updateAllChannelStrips ( Line 2355  void MainForm::updateAllChannelStrips (
2355  // Update the recent files list and menu.  // Update the recent files list and menu.
2356  void MainForm::updateRecentFiles ( const QString& sFilename )  void MainForm::updateRecentFiles ( const QString& sFilename )
2357  {  {
2358          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2359                  return;                  return;
2360    
2361          // Remove from list if already there (avoid duplicates)          // Remove from list if already there (avoid duplicates)
# Line 2274  void MainForm::updateRecentFiles ( const Line 2370  void MainForm::updateRecentFiles ( const
2370  // Update the recent files list and menu.  // Update the recent files list and menu.
2371  void MainForm::updateRecentFilesMenu (void)  void MainForm::updateRecentFilesMenu (void)
2372  {  {
2373          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2374                  return;                  return;
2375    
2376          // Time to keep the list under limits.          // Time to keep the list under limits.
# Line 2308  void MainForm::updateInstrumentNames (vo Line 2404  void MainForm::updateInstrumentNames (vo
2404                  return;                  return;
2405    
2406          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2407          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2408          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2409                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2410                  if (pChannelStrip)                  if (pChannelStrip)
2411                          pChannelStrip->updateInstrumentName(true);                          pChannelStrip->updateInstrumentName(true);
2412          }          }
# Line 2324  void MainForm::updateInstrumentNames (vo Line 2417  void MainForm::updateInstrumentNames (vo
2417  // Force update of the channels display font.  // Force update of the channels display font.
2418  void MainForm::updateDisplayFont (void)  void MainForm::updateDisplayFont (void)
2419  {  {
2420          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2421                  return;                  return;
2422    
2423          // Check if display font is legal.          // Check if display font is legal.
# Line 2343  void MainForm::updateDisplayFont (void) Line 2436  void MainForm::updateDisplayFont (void)
2436                  return;                  return;
2437    
2438          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2439          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2440          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2441                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2442                  if (pChannelStrip)                  if (pChannelStrip)
2443                          pChannelStrip->setDisplayFont(font);                          pChannelStrip->setDisplayFont(font);
2444          }          }
# Line 2366  void MainForm::updateDisplayEffect (void Line 2456  void MainForm::updateDisplayEffect (void
2456                  return;                  return;
2457    
2458          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2459          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2460          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2461                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2462                  if (pChannelStrip)                  if (pChannelStrip)
2463                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2464          }          }
# Line 2382  void MainForm::updateDisplayEffect (void Line 2469  void MainForm::updateDisplayEffect (void
2469  // Force update of the channels maximum volume setting.  // Force update of the channels maximum volume setting.
2470  void MainForm::updateMaxVolume (void)  void MainForm::updateMaxVolume (void)
2471  {  {
2472          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2473                  return;                  return;
2474    
2475  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
# Line 2399  void MainForm::updateMaxVolume (void) Line 2486  void MainForm::updateMaxVolume (void)
2486                  return;                  return;
2487    
2488          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2489          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2490          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2491                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2492                  if (pChannelStrip)                  if (pChannelStrip)
2493                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2494          }          }
# Line 2416  void MainForm::updateMaxVolume (void) Line 2500  void MainForm::updateMaxVolume (void)
2500  // QSampler::MainForm -- Messages window form handlers.  // QSampler::MainForm -- Messages window form handlers.
2501    
2502  // Messages output methods.  // Messages output methods.
2503  void MainForm::appendMessages( const QString& s )  void MainForm::appendMessages ( const QString& s )
2504  {  {
2505          if (m_pMessages)          if (m_pMessages)
2506                  m_pMessages->appendMessages(s);                  m_pMessages->appendMessages(s);
# Line 2424  void MainForm::appendMessages( const QSt Line 2508  void MainForm::appendMessages( const QSt
2508          statusBar()->showMessage(s, 3000);          statusBar()->showMessage(s, 3000);
2509  }  }
2510    
2511  void MainForm::appendMessagesColor( const QString& s, const QString& c )  void MainForm::appendMessagesColor ( const QString& s, const QColor& rgb )
2512  {  {
2513          if (m_pMessages)          if (m_pMessages)
2514                  m_pMessages->appendMessagesColor(s, c);                  m_pMessages->appendMessagesColor(s, rgb);
2515    
2516          statusBar()->showMessage(s, 3000);          statusBar()->showMessage(s, 3000);
2517  }  }
2518    
2519  void MainForm::appendMessagesText( const QString& s )  void MainForm::appendMessagesText ( const QString& s )
2520  {  {
2521          if (m_pMessages)          if (m_pMessages)
2522                  m_pMessages->appendMessagesText(s);                  m_pMessages->appendMessagesText(s);
2523  }  }
2524    
2525  void MainForm::appendMessagesError( const QString& sText )  void MainForm::appendMessagesError ( const QString& s )
2526  {  {
2527          if (m_pMessages)          if (m_pMessages)
2528                  m_pMessages->show();                  m_pMessages->show();
2529    
2530          appendMessagesColor(sText.simplified(), "#ff0000");          appendMessagesColor(s.simplified(), Qt::red);
2531    
2532          // Make it look responsive...:)          // Make it look responsive...:)
2533          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2534    
2535          if (m_pOptions && m_pOptions->bConfirmError) {          if (m_pOptions && m_pOptions->bConfirmError) {
2536                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Error");                  const QString& sTitle = tr("Error");
2537          #if 0          #if 0
2538                  QMessageBox::critical(this, sTitle, sText, QMessageBox::Cancel);                  QMessageBox::critical(this, sTitle, sText, QMessageBox::Cancel);
2539          #else          #else
2540                  QMessageBox mbox(this);                  QMessageBox mbox(this);
2541                  mbox.setIcon(QMessageBox::Critical);                  mbox.setIcon(QMessageBox::Critical);
2542                  mbox.setWindowTitle(sTitle);                  mbox.setWindowTitle(sTitle);
2543                  mbox.setText(sText);                  mbox.setText(s);
2544                  mbox.setStandardButtons(QMessageBox::Cancel);                  mbox.setStandardButtons(QMessageBox::Cancel);
2545                  QCheckBox cbox(tr("Don't show this again"));                  QCheckBox cbox(tr("Don't show this again"));
2546                  cbox.setChecked(false);                  cbox.setChecked(false);
# Line 2472  void MainForm::appendMessagesError( cons Line 2556  void MainForm::appendMessagesError( cons
2556  // This is a special message format, just for client results.  // This is a special message format, just for client results.
2557  void MainForm::appendMessagesClient( const QString& s )  void MainForm::appendMessagesClient( const QString& s )
2558  {  {
2559          if (m_pClient == NULL)          if (m_pClient == nullptr)
2560                  return;                  return;
2561    
2562          appendMessagesColor(s + QString(": %1 (errno=%2)")          appendMessagesColor(s + QString(": %1 (errno=%2)")
# Line 2487  void MainForm::appendMessagesClient( con Line 2571  void MainForm::appendMessagesClient( con
2571  // Force update of the messages font.  // Force update of the messages font.
2572  void MainForm::updateMessagesFont (void)  void MainForm::updateMessagesFont (void)
2573  {  {
2574          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2575                  return;                  return;
2576    
2577          if (m_pMessages && !m_pOptions->sMessagesFont.isEmpty()) {          if (m_pMessages && !m_pOptions->sMessagesFont.isEmpty()) {
# Line 2501  void MainForm::updateMessagesFont (void) Line 2585  void MainForm::updateMessagesFont (void)
2585  // Update messages window line limit.  // Update messages window line limit.
2586  void MainForm::updateMessagesLimit (void)  void MainForm::updateMessagesLimit (void)
2587  {  {
2588          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2589                  return;                  return;
2590    
2591          if (m_pMessages) {          if (m_pMessages) {
# Line 2516  void MainForm::updateMessagesLimit (void Line 2600  void MainForm::updateMessagesLimit (void
2600  // Enablement of the messages capture feature.  // Enablement of the messages capture feature.
2601  void MainForm::updateMessagesCapture (void)  void MainForm::updateMessagesCapture (void)
2602  {  {
2603          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2604                  return;                  return;
2605    
2606          if (m_pMessages)          if (m_pMessages)
# Line 2530  void MainForm::updateMessagesCapture (vo Line 2614  void MainForm::updateMessagesCapture (vo
2614  // The channel strip creation executive.  // The channel strip creation executive.
2615  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )
2616  {  {
2617          if (m_pClient == NULL || pChannel == NULL)          if (m_pClient == nullptr || pChannel == nullptr)
2618                  return NULL;                  return nullptr;
2619    
2620          // Add a new channel itema...          // Add a new channel itema...
2621          ChannelStrip *pChannelStrip = new ChannelStrip();          ChannelStrip *pChannelStrip = new ChannelStrip();
2622          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
2623                  return NULL;                  return nullptr;
2624    
2625          // Set some initial channel strip options...          // Set some initial channel strip options...
2626          if (m_pOptions) {          if (m_pOptions) {
# Line 2552  ChannelStrip *MainForm::createChannelStr Line 2636  ChannelStrip *MainForm::createChannelStr
2636          }          }
2637    
2638          // Add it to workspace...          // Add it to workspace...
2639          m_pWorkspace->addSubWindow(pChannelStrip,          QMdiSubWindow *pMdiSubWindow
2640                  Qt::SubWindow | Qt::FramelessWindowHint);                  = m_pWorkspace->addSubWindow(pChannelStrip,
2641                            Qt::SubWindow | Qt::FramelessWindowHint);
2642            pMdiSubWindow->setAttribute(Qt::WA_DeleteOnClose);
2643    
2644          // Actual channel strip setup...          // Actual channel strip setup...
2645          pChannelStrip->setup(pChannel);          pChannelStrip->setup(pChannel);
# Line 2577  void MainForm::destroyChannelStrip ( Cha Line 2663  void MainForm::destroyChannelStrip ( Cha
2663  {  {
2664          QMdiSubWindow *pMdiSubWindow          QMdiSubWindow *pMdiSubWindow
2665                  = static_cast<QMdiSubWindow *> (pChannelStrip->parentWidget());                  = static_cast<QMdiSubWindow *> (pChannelStrip->parentWidget());
2666          if (pMdiSubWindow == NULL)          if (pMdiSubWindow == nullptr)
2667                  return;                  return;
2668    
2669          // Just delete the channel strip.          // Just delete the channel strip.
# Line 2596  ChannelStrip *MainForm::activeChannelStr Line 2682  ChannelStrip *MainForm::activeChannelStr
2682          if (pMdiSubWindow)          if (pMdiSubWindow)
2683                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2684          else          else
2685                  return NULL;                  return nullptr;
2686  }  }
2687    
2688    
2689  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2690  ChannelStrip *MainForm::channelStripAt ( int iStrip )  ChannelStrip *MainForm::channelStripAt ( int iStrip )
2691  {  {
2692          if (!m_pWorkspace) return NULL;          if (!m_pWorkspace) return nullptr;
2693    
2694          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
2695                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
2696          if (wlist.isEmpty())          if (wlist.isEmpty())
2697                  return NULL;                  return nullptr;
2698    
2699          if (iStrip < 0 || iStrip >= wlist.count())          if (iStrip < 0 || iStrip >= wlist.count())
2700                  return NULL;                  return nullptr;
2701    
2702          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2703          if (pMdiSubWindow)          if (pMdiSubWindow)
2704                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2705          else          else
2706                  return NULL;                  return nullptr;
2707  }  }
2708    
2709    
# Line 2627  ChannelStrip *MainForm::channelStrip ( i Line 2713  ChannelStrip *MainForm::channelStrip ( i
2713          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
2714                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
2715          if (wlist.isEmpty())          if (wlist.isEmpty())
2716                  return NULL;                  return nullptr;
2717    
2718          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2719          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2720                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2721                  if (pChannelStrip) {                  if (pChannelStrip) {
2722                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
2723                          if (pChannel && pChannel->channelID() == iChannelID)                          if (pChannel && pChannel->channelID() == iChannelID)
# Line 2643  ChannelStrip *MainForm::channelStrip ( i Line 2726  ChannelStrip *MainForm::channelStrip ( i
2726          }          }
2727    
2728          // Not found.          // Not found.
2729          return NULL;          return nullptr;
2730  }  }
2731    
2732    
# Line 2658  void MainForm::channelsMenuAboutToShow ( Line 2741  void MainForm::channelsMenuAboutToShow (
2741                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
2742          if (!wlist.isEmpty()) {          if (!wlist.isEmpty()) {
2743                  m_ui.channelsMenu->addSeparator();                  m_ui.channelsMenu->addSeparator();
2744                  const int iStripCount = wlist.count();                  int iStrip = 0;
2745                  for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2746                          ChannelStrip *pChannelStrip = NULL;                          ChannelStrip *pChannelStrip
2747                          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                         if (pMdiSubWindow)  
                                 pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2748                          if (pChannelStrip) {                          if (pChannelStrip) {
2749                                  QAction *pAction = m_ui.channelsMenu->addAction(                                  QAction *pAction = m_ui.channelsMenu->addAction(
2750                                          pChannelStrip->windowTitle(),                                          pChannelStrip->windowTitle(),
# Line 2672  void MainForm::channelsMenuAboutToShow ( Line 2753  void MainForm::channelsMenuAboutToShow (
2753                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);
2754                                  pAction->setData(iStrip);                                  pAction->setData(iStrip);
2755                          }                          }
2756                            ++iStrip;
2757                  }                  }
2758          }          }
2759  }  }
# Line 2682  void MainForm::channelsMenuActivated (vo Line 2764  void MainForm::channelsMenuActivated (vo
2764  {  {
2765          // Retrive channel index from action data...          // Retrive channel index from action data...
2766          QAction *pAction = qobject_cast<QAction *> (sender());          QAction *pAction = qobject_cast<QAction *> (sender());
2767          if (pAction == NULL)          if (pAction == nullptr)
2768                  return;                  return;
2769    
2770          ChannelStrip *pChannelStrip = channelStripAt(pAction->data().toInt());          ChannelStrip *pChannelStrip = channelStripAt(pAction->data().toInt());
# Line 2713  void MainForm::stopSchedule (void) Line 2795  void MainForm::stopSchedule (void)
2795  // Timer slot funtion.  // Timer slot funtion.
2796  void MainForm::timerSlot (void)  void MainForm::timerSlot (void)
2797  {  {
2798          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2799                  return;                  return;
2800    
2801          // 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 2830  void MainForm::timerSlot (void)
2830                                  // Update the channel stream usage for each strip...                                  // Update the channel stream usage for each strip...
2831                                  const QList<QMdiSubWindow *>& wlist                                  const QList<QMdiSubWindow *>& wlist
2832                                          = m_pWorkspace->subWindowList();                                          = m_pWorkspace->subWindowList();
2833                                  const int iStripCount = wlist.count();                                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2834                                  for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                                          ChannelStrip *pChannelStrip
2835                                          ChannelStrip *pChannelStrip = NULL;                                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                                         QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                                         if (pMdiSubWindow)  
                                                 pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2836                                          if (pChannelStrip && pChannelStrip->isVisible())                                          if (pChannelStrip && pChannelStrip->isVisible())
2837                                                  pChannelStrip->updateChannelUsage();                                                  pChannelStrip->updateChannelUsage();
2838                                  }                                  }
2839                          }                          }
2840                  }                  }
2841    
2842            #if CONFIG_LSCP_CLIENT_CONNECTION_LOST
2843                    // If we lost connection to server: Try to automatically reconnect if we
2844                    // did not start the server.
2845                    //
2846                    // TODO: If we started the server, then we might inform the user that
2847                    // the server probably crashed and asking user ONCE whether we should
2848                    // restart the server.
2849                    if (lscp_client_connection_lost(m_pClient) && !m_pServer)
2850                            startAutoReconnectClient();
2851            #endif // CONFIG_LSCP_CLIENT_CONNECTION_LOST
2852          }          }
2853    
2854          // Register the next timer slot.          // Register the next timer slot.
# Line 2772  void MainForm::timerSlot (void) Line 2862  void MainForm::timerSlot (void)
2862  // Start linuxsampler server...  // Start linuxsampler server...
2863  void MainForm::startServer (void)  void MainForm::startServer (void)
2864  {  {
2865          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2866                  return;                  return;
2867    
2868          // Aren't already a client, are we?          // Aren't already a client, are we?
# Line 2782  void MainForm::startServer (void) Line 2872  void MainForm::startServer (void)
2872          // Is the server process instance still here?          // Is the server process instance still here?
2873          if (m_pServer) {          if (m_pServer) {
2874                  if (QMessageBox::warning(this,                  if (QMessageBox::warning(this,
2875                          QSAMPLER_TITLE ": " + tr("Warning"),                          tr("Warning"),
2876                          tr("Could not start the LinuxSampler server.\n\n"                          tr("Could not start the LinuxSampler server.\n\n"
2877                          "Maybe it is already started."),                          "Maybe it is already started."),
2878                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
# Line 2835  void MainForm::startServer (void) Line 2925  void MainForm::startServer (void)
2925    
2926          // Show startup results...          // Show startup results...
2927          appendMessages(          appendMessages(
2928                  tr("Server was started with PID=%1.").arg((long) m_pServer->pid()));                  tr("Server was started with PID=%1.")
2929                    #if QT_VERSION < QT_VERSION_CHECK(5, 3, 0)
2930                            .arg(quint64(m_pServer->pid())));
2931                    #else
2932                            .arg(quint64(m_pServer->processId())));
2933                    #endif
2934    
2935          // Reset (yet again) the timer counters,          // Reset (yet again) the timer counters,
2936          // but this time is deferred as the user opted.          // but this time is deferred as the user opted.
# Line 2852  void MainForm::stopServer ( bool bIntera Line 2947  void MainForm::stopServer ( bool bIntera
2947    
2948          if (m_pServer && bInteractive) {          if (m_pServer && bInteractive) {
2949                  if (QMessageBox::question(this,                  if (QMessageBox::question(this,
2950                          QSAMPLER_TITLE ": " + tr("The backend's fate ..."),                          tr("The backend's fate ..."),
2951                          tr("You have the option to keep the sampler backend (LinuxSampler)\n"                          tr("You have the option to keep the sampler backend (LinuxSampler)\n"
2952                          "running in the background. The sampler would continue to work\n"                          "running in the background. The sampler would continue to work\n"
2953                          "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 2959  void MainForm::stopServer ( bool bIntera
2959                  }                  }
2960          }          }
2961    
2962            bool bGraceWait = true;
2963    
2964          // And try to stop server.          // And try to stop server.
2965          if (m_pServer && m_bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2966                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2967                  if (m_pServer->state() == QProcess::Running) {                  if (m_pServer->state() == QProcess::Running) {
2968                  #if defined(_WIN32)                  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
2969                          // Try harder...                          // Try harder...
2970                          m_pServer->kill();                          m_pServer->kill();
2971                  #else                  #else
2972                          // Try softly...                          // Try softly...
2973                          m_pServer->terminate();                          m_pServer->terminate();
2974                            bool bFinished = m_pServer->waitForFinished(QSAMPLER_TIMER_MSECS * 1000);
2975                            if (bFinished) bGraceWait = false;
2976                  #endif                  #endif
2977                  }                  }
2978          }       // Do final processing anyway.          }       // Do final processing anyway.
2979          else processServerExit();          else processServerExit();
2980    
2981          // Give it some time to terminate gracefully and stabilize...          // Give it some time to terminate gracefully and stabilize...
2982          QTime t;          if (bGraceWait) {
2983          t.start();                  QElapsedTimer timer;
2984          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                  timer.start();
2985                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  while (timer.elapsed() < QSAMPLER_TIMER_MSECS)
2986                            QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2987            }
2988  }  }
2989    
2990    
# Line 2911  void MainForm::processServerExit (void) Line 3012  void MainForm::processServerExit (void)
3012                          // Force final server shutdown...                          // Force final server shutdown...
3013                          m_pServer->kill();                          m_pServer->kill();
3014                          // Give it some time to terminate gracefully and stabilize...                          // Give it some time to terminate gracefully and stabilize...
3015                          QTime t;                          QElapsedTimer timer;
3016                          t.start();                          timer.start();
3017                          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                          while (timer.elapsed() < QSAMPLER_TIMER_MSECS)
3018                                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
3019                  }                  }
3020                  // Force final server shutdown...                  // Force final server shutdown...
# Line 2921  void MainForm::processServerExit (void) Line 3022  void MainForm::processServerExit (void)
3022                          tr("Server was stopped with exit status %1.")                          tr("Server was stopped with exit status %1.")
3023                          .arg(m_pServer->exitStatus()));                          .arg(m_pServer->exitStatus()));
3024                  delete m_pServer;                  delete m_pServer;
3025                  m_pServer = NULL;                  m_pServer = nullptr;
3026          }          }
3027    
3028          // Again, make status visible stable.          // Again, make status visible stable.
# Line 2937  lscp_status_t qsampler_client_callback ( Line 3038  lscp_status_t qsampler_client_callback (
3038          lscp_event_t event, const char *pchData, int cchData, void *pvData )          lscp_event_t event, const char *pchData, int cchData, void *pvData )
3039  {  {
3040          MainForm* pMainForm = (MainForm *) pvData;          MainForm* pMainForm = (MainForm *) pvData;
3041          if (pMainForm == NULL)          if (pMainForm == nullptr)
3042                  return LSCP_FAILED;                  return LSCP_FAILED;
3043    
3044          // 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 3052  lscp_status_t qsampler_client_callback (
3052    
3053    
3054  // Start our almighty client...  // Start our almighty client...
3055  bool MainForm::startClient (void)  bool MainForm::startClient (bool bReconnectOnly)
3056  {  {
3057          // Have it a setup?          // Have it a setup?
3058          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
3059                  return false;                  return false;
3060    
3061          // Aren't we already started, are we?          // Aren't we already started, are we?
# Line 2968  bool MainForm::startClient (void) Line 3069  bool MainForm::startClient (void)
3069          m_pClient = ::lscp_client_create(          m_pClient = ::lscp_client_create(
3070                  m_pOptions->sServerHost.toUtf8().constData(),                  m_pOptions->sServerHost.toUtf8().constData(),
3071                  m_pOptions->iServerPort, qsampler_client_callback, this);                  m_pOptions->iServerPort, qsampler_client_callback, this);
3072          if (m_pClient == NULL) {          if (m_pClient == nullptr) {
3073                  // Is this the first try?                  // Is this the first try?
3074                  // maybe we need to start a local server...                  // maybe we need to start a local server...
3075                  if ((m_pServer && m_pServer->state() == QProcess::Running)                  if ((m_pServer && m_pServer->state() == QProcess::Running)
3076                          || !m_pOptions->bServerStart) {                          || !m_pOptions->bServerStart || bReconnectOnly)
3077                          appendMessagesError(                  {
3078                                  tr("Could not connect to server as client.\n\nSorry."));                          // if this method is called from autoReconnectClient()
3079                            // then don't bother user with an error message...
3080                            if (!bReconnectOnly) {
3081                                    appendMessagesError(
3082                                            tr("Could not connect to server as client.\n\nSorry.")
3083                                    );
3084                            }
3085                  } else {                  } else {
3086                          startServer();                          startServer();
3087                  }                  }
# Line 3038  bool MainForm::startClient (void) Line 3145  bool MainForm::startClient (void)
3145          if (!m_pOptions->sSessionFile.isEmpty()) {          if (!m_pOptions->sSessionFile.isEmpty()) {
3146                  // Just load the prabably startup session...                  // Just load the prabably startup session...
3147                  if (loadSessionFile(m_pOptions->sSessionFile)) {                  if (loadSessionFile(m_pOptions->sSessionFile)) {
3148                          m_pOptions->sSessionFile = QString::null;                          m_pOptions->sSessionFile = QString();
3149                          return true;                          return true;
3150                  }                  }
3151          }          }
# Line 3054  bool MainForm::startClient (void) Line 3161  bool MainForm::startClient (void)
3161  // Stop client...  // Stop client...
3162  void MainForm::stopClient (void)  void MainForm::stopClient (void)
3163  {  {
3164          if (m_pClient == NULL)          if (m_pClient == nullptr)
3165                  return;                  return;
3166    
3167          // Log prepare here.          // Log prepare here.
# Line 3086  void MainForm::stopClient (void) Line 3193  void MainForm::stopClient (void)
3193          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
3194          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);
3195          ::lscp_client_destroy(m_pClient);          ::lscp_client_destroy(m_pClient);
3196          m_pClient = NULL;          m_pClient = nullptr;
3197    
3198          // Hard-notify instrumnet and device configuration forms,          // Hard-notify instrumnet and device configuration forms,
3199          // if visible, that we're running out...          // if visible, that we're running out...
# Line 3103  void MainForm::stopClient (void) Line 3210  void MainForm::stopClient (void)
3210  }  }
3211    
3212    
3213    void MainForm::startAutoReconnectClient (void)
3214    {
3215            stopClient();
3216            appendMessages(tr("Trying to reconnect..."));
3217            QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(autoReconnectClient()));
3218    }
3219    
3220    
3221    void MainForm::autoReconnectClient (void)
3222    {
3223            const bool bSuccess = startClient(true);
3224            if (!bSuccess)
3225                    QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(autoReconnectClient()));
3226    }
3227    
3228    
3229  // Channel strip activation/selection.  // Channel strip activation/selection.
3230  void MainForm::activateStrip ( QMdiSubWindow *pMdiSubWindow )  void MainForm::activateStrip ( QMdiSubWindow *pMdiSubWindow )
3231  {  {
3232          ChannelStrip *pChannelStrip = NULL;          ChannelStrip *pChannelStrip = nullptr;
3233          if (pMdiSubWindow)          if (pMdiSubWindow)
3234                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
3235          if (pChannelStrip)          if (pChannelStrip)

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

  ViewVC Help
Powered by ViewVC