/[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 2978 by capela, Mon Aug 15 19:10:16 2016 UTC revision 3759 by capela, Sat Mar 28 00:28:13 2020 UTC
# Line 1  Line 1 
1  // qsamplerMainForm.cpp  // qsamplerMainForm.cpp
2  //  //
3  /****************************************************************************  /****************************************************************************
4     Copyright (C) 2004-2016, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2020, rncbc aka Rui Nuno Capela. All rights reserved.
5     Copyright (C) 2007,2008,2015 Christian Schoenebeck     Copyright (C) 2007-2019 Christian Schoenebeck
6    
7     This program is free software; you can redistribute it and/or     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License     modify it under the terms of the GNU General Public License
# Line 58  Line 58 
58  #include <QTimer>  #include <QTimer>
59  #include <QDateTime>  #include <QDateTime>
60    
61  #if QT_VERSION >= 0x050000  #include <QElapsedTimer>
62    
63    #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
64  #include <QMimeData>  #include <QMimeData>
65  #endif  #endif
66    
67  #if QT_VERSION < 0x040500  #if QT_VERSION < QT_VERSION_CHECK(4, 5, 0)
68  namespace Qt {  namespace Qt {
69  const WindowFlags WindowCloseButtonHint = WindowFlags(0x08000000);  const WindowFlags WindowCloseButtonHint = WindowFlags(0x08000000);
70  }  }
71  #endif  #endif
72    
73  #ifdef HAVE_SIGNAL_H  // Deprecated QTextStreamFunctions/Qt namespaces workaround.
74  #include <signal.h>  #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
75    #define endl    Qt::endl
76  #endif  #endif
77    
78    
79  #ifdef CONFIG_LIBGIG  #ifdef CONFIG_LIBGIG
80  #include <gig.h>  #include <gig.h>
81  #endif  #endif
# Line 91  static inline long lroundf ( float x ) Line 95  static inline long lroundf ( float x )
95    
96    
97  // All winsock apps needs this.  // All winsock apps needs this.
98  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
99  static WSADATA _wsaData;  static WSADATA _wsaData;
100    #undef HAVE_SIGNAL_H
101  #endif  #endif
102    
103    
# Line 103  static WSADATA _wsaData; Line 108  static WSADATA _wsaData;
108    
109  #include <QSocketNotifier>  #include <QSocketNotifier>
110    
111    #include <unistd.h>
112  #include <sys/types.h>  #include <sys/types.h>
113  #include <sys/socket.h>  #include <sys/socket.h>
   
114  #include <signal.h>  #include <signal.h>
115    
116  // File descriptor for SIGUSR1 notifier.  // File descriptor for SIGUSR1 notifier.
117  static int g_fdUsr1[2];  static int g_fdSigusr1[2] = { -1, -1 };
118    
119  // Unix SIGUSR1 signal handler.  // Unix SIGUSR1 signal handler.
120  static void qsampler_sigusr1_handler ( int /* signo */ )  static void qsampler_sigusr1_handler ( int /* signo */ )
121  {  {
122          char c = 1;          char c = 1;
123    
124          (::write(g_fdUsr1[0], &c, sizeof(c)) > 0);          (::write(g_fdSigusr1[0], &c, sizeof(c)) > 0);
125    }
126    
127    // File descriptor for SIGTERM notifier.
128    static int g_fdSigterm[2] = { -1, -1 };
129    
130    // Unix SIGTERM signal handler.
131    static void qsampler_sigterm_handler ( int /* signo */ )
132    {
133            char c = 1;
134    
135            (::write(g_fdSigterm[0], &c, sizeof(c)) > 0);
136  }  }
137    
138  #endif  // HAVE_SIGNAL_H  #endif  // HAVE_SIGNAL_H
139    
140    
141  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
142  // qsampler -- namespace  // QSampler -- namespace
143    
144    
145  namespace QSampler {  namespace QSampler {
# Line 143  namespace QSampler { Line 159  namespace QSampler {
159    
160    
161  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
162  // LscpEvent -- specialty for LSCP callback comunication.  // QSampler::LscpEvent -- specialty for LSCP callback comunication.
   
163    
164  class LscpEvent : public QEvent  class LscpEvent : public QEvent
165  {  {
# Line 159  public: Line 174  public:
174          }          }
175    
176          // Accessors.          // Accessors.
177          lscp_event_t event() { return m_event; }          lscp_event_t  event() { return m_event; }
178          QString&     data()  { return m_data;  }          const QString& data() { return m_data;  }
179    
180  private:  private:
181    
# Line 172  private: Line 187  private:
187    
188    
189  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
190  // qsamplerMainForm -- Main window form implementation.  // QSampler::Workspace -- Main window workspace (MDI Area) decl.
191    
192    class Workspace : public QMdiArea
193    {
194    public:
195    
196            Workspace(MainForm *pMainForm) : QMdiArea(pMainForm) {}
197    
198    protected:
199    
200            void resizeEvent(QResizeEvent *)
201            {
202                    MainForm *pMainForm = static_cast<MainForm *> (parentWidget());
203                    if (pMainForm)
204                            pMainForm->channelsArrangeAuto();
205            }
206    };
207    
208    
209    //-------------------------------------------------------------------------
210    // QSampler::MainForm -- Main window form implementation.
211    
212  // Kind of singleton reference.  // Kind of singleton reference.
213  MainForm* MainForm::g_pMainForm = NULL;  MainForm *MainForm::g_pMainForm = nullptr;
214    
215  MainForm::MainForm ( QWidget *pParent )  MainForm::MainForm ( QWidget *pParent )
216          : QMainWindow(pParent)          : QMainWindow(pParent)
# Line 186  MainForm::MainForm ( QWidget *pParent ) Line 221  MainForm::MainForm ( QWidget *pParent )
221          g_pMainForm = this;          g_pMainForm = this;
222    
223          // Initialize some pointer references.          // Initialize some pointer references.
224          m_pOptions = NULL;          m_pOptions = nullptr;
225    
226          // All child forms are to be created later, not earlier than setup.          // All child forms are to be created later, not earlier than setup.
227          m_pMessages = NULL;          m_pMessages = nullptr;
228          m_pInstrumentListForm = NULL;          m_pInstrumentListForm = nullptr;
229          m_pDeviceForm = NULL;          m_pDeviceForm = nullptr;
230    
231          // We'll start clean.          // We'll start clean.
232          m_iUntitled   = 0;          m_iUntitled   = 0;
233          m_iDirtySetup = 0;          m_iDirtySetup = 0;
234          m_iDirtyCount = 0;          m_iDirtyCount = 0;
235    
236          m_pServer = NULL;          m_pServer = nullptr;
237          m_pClient = NULL;          m_pClient = nullptr;
238    
239          m_iStartDelay = 0;          m_iStartDelay = 0;
240          m_iTimerDelay = 0;          m_iTimerDelay = 0;
# Line 214  MainForm::MainForm ( QWidget *pParent ) Line 249  MainForm::MainForm ( QWidget *pParent )
249          // LADISH Level 1 suport.          // LADISH Level 1 suport.
250    
251          // Initialize file descriptors for SIGUSR1 socket notifier.          // Initialize file descriptors for SIGUSR1 socket notifier.
252          ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdUsr1);          ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigusr1);
253          m_pUsr1Notifier          m_pSigusr1Notifier
254                  = new QSocketNotifier(g_fdUsr1[1], QSocketNotifier::Read, this);                  = new QSocketNotifier(g_fdSigusr1[1], QSocketNotifier::Read, this);
255    
256          QObject::connect(m_pUsr1Notifier,          QObject::connect(m_pSigusr1Notifier,
257                  SIGNAL(activated(int)),                  SIGNAL(activated(int)),
258                  SLOT(handle_sigusr1()));                  SLOT(handle_sigusr1()));
259    
260          // Install SIGUSR1 signal handler.          // Install SIGUSR1 signal handler.
261      struct sigaction usr1;          struct sigaction sigusr1;
262      usr1.sa_handler = qsampler_sigusr1_handler;          sigusr1.sa_handler = qsampler_sigusr1_handler;
263      sigemptyset(&usr1.sa_mask);          sigemptyset(&sigusr1.sa_mask);
264      usr1.sa_flags = 0;          sigusr1.sa_flags = 0;
265      usr1.sa_flags |= SA_RESTART;          sigusr1.sa_flags |= SA_RESTART;
266      ::sigaction(SIGUSR1, &usr1, NULL);          ::sigaction(SIGUSR1, &sigusr1, nullptr);
267    
268            // Initialize file descriptors for SIGTERM socket notifier.
269            ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigterm);
270            m_pSigtermNotifier
271                    = new QSocketNotifier(g_fdSigterm[1], QSocketNotifier::Read, this);
272    
273            QObject::connect(m_pSigtermNotifier,
274                    SIGNAL(activated(int)),
275                    SLOT(handle_sigterm()));
276    
277            // Install SIGTERM signal handler.
278            struct sigaction sigterm;
279            sigterm.sa_handler = qsampler_sigterm_handler;
280            sigemptyset(&sigterm.sa_mask);
281            sigterm.sa_flags = 0;
282            sigterm.sa_flags |= SA_RESTART;
283            ::sigaction(SIGTERM, &sigterm, nullptr);
284            ::sigaction(SIGQUIT, &sigterm, nullptr);
285    
286            // Ignore SIGHUP/SIGINT signals.
287            ::signal(SIGHUP, SIG_IGN);
288            ::signal(SIGINT, SIG_IGN);
289    
290  #else   // HAVE_SIGNAL_H  #else   // HAVE_SIGNAL_H
291    
292          m_pUsr1Notifier = NULL;          m_pSigusr1Notifier = nullptr;
293            m_pSigtermNotifier = nullptr;
294                    
295  #endif  // !HAVE_SIGNAL_H  #endif  // !HAVE_SIGNAL_H
296    
# Line 270  MainForm::MainForm ( QWidget *pParent ) Line 328  MainForm::MainForm ( QWidget *pParent )
328  #endif  #endif
329    
330          // Make it an MDI workspace.          // Make it an MDI workspace.
331          m_pWorkspace = new QMdiArea(this);          m_pWorkspace = new Workspace(this);
332          m_pWorkspace->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);          m_pWorkspace->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
333          m_pWorkspace->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);          m_pWorkspace->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
334          // Set the activation connection.          // Set the activation connection.
# Line 305  MainForm::MainForm ( QWidget *pParent ) Line 363  MainForm::MainForm ( QWidget *pParent )
363          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
364          statusBar()->addWidget(pLabel);          statusBar()->addWidget(pLabel);
365    
366  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
367          WSAStartup(MAKEWORD(1, 1), &_wsaData);          WSAStartup(MAKEWORD(1, 1), &_wsaData);
368  #endif  #endif
369    
# Line 406  MainForm::~MainForm() Line 464  MainForm::~MainForm()
464          // Do final processing anyway.          // Do final processing anyway.
465          processServerExit();          processServerExit();
466    
467  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
468          WSACleanup();          WSACleanup();
469  #endif  #endif
470    
471  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
472          if (m_pUsr1Notifier)          if (m_pSigusr1Notifier)
473                  delete m_pUsr1Notifier;                  delete m_pSigusr1Notifier;
474            if (m_pSigtermNotifier)
475                    delete m_pSigtermNotifier;
476  #endif  #endif
477    
478          // Finally drop any widgets around...          // Finally drop any widgets around...
# Line 441  MainForm::~MainForm() Line 501  MainForm::~MainForm()
501  #endif  #endif
502    
503          // Pseudo-singleton reference shut-down.          // Pseudo-singleton reference shut-down.
504          g_pMainForm = NULL;          g_pMainForm = nullptr;
505  }  }
506    
507    
# Line 578  void MainForm::closeEvent ( QCloseEvent Line 638  void MainForm::closeEvent ( QCloseEvent
638  void MainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )  void MainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
639  {  {
640          // Accept external drags only...          // Accept external drags only...
641          if (pDragEnterEvent->source() == NULL          if (pDragEnterEvent->source() == nullptr
642                  && pDragEnterEvent->mimeData()->hasUrls()) {                  && pDragEnterEvent->mimeData()->hasUrls()) {
643                  pDragEnterEvent->accept();                  pDragEnterEvent->accept();
644          } else {          } else {
# Line 602  void MainForm::dropEvent ( QDropEvent *p Line 662  void MainForm::dropEvent ( QDropEvent *p
662                          if (QFileInfo(sPath).exists()) {                          if (QFileInfo(sPath).exists()) {
663                                  // Try to create a new channel from instrument file...                                  // Try to create a new channel from instrument file...
664                                  Channel *pChannel = new Channel();                                  Channel *pChannel = new Channel();
665                                  if (pChannel == NULL)                                  if (pChannel == nullptr)
666                                          return;                                          return;
667                                  // Start setting the instrument filename...                                  // Start setting the instrument filename...
668                                  pChannel->setInstrument(sPath, 0);                                  pChannel->setInstrument(sPath, 0);
# Line 695  void MainForm::customEvent ( QEvent* pEv Line 755  void MainForm::customEvent ( QEvent* pEv
755  }  }
756    
757    
758  // Window resize event handler.  // LADISH Level 1 -- SIGUSR1 signal handler.
759  void MainForm::resizeEvent ( QResizeEvent * )  void MainForm::handle_sigusr1 (void)
760  {  {
761          if (m_pOptions->bAutoArrange)  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
762                  channelsArrange();  
763            char c;
764    
765            if (::read(g_fdSigusr1[1], &c, sizeof(c)) > 0)
766                    saveSession(false);
767    
768    #endif
769  }  }
770    
771    
772  // LADISH Level 1 -- SIGUSR1 signal handler.  void MainForm::handle_sigterm (void)
 void MainForm::handle_sigusr1 (void)  
773  {  {
774  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
775    
776          char c;          char c;
777    
778          if (::read(g_fdUsr1[1], &c, sizeof(c)) > 0)          if (::read(g_fdSigterm[1], &c, sizeof(c)) > 0)
779                  saveSession(false);                  close();
780    
781  #endif  #endif
782  }  }
# Line 742  void MainForm::contextMenuEvent( QContex Line 807  void MainForm::contextMenuEvent( QContex
807    
808    
809  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
810  // qsamplerMainForm -- Brainless public property accessors.  // QSampler::MainForm -- Brainless public property accessors.
811    
812  // The global options settings property.  // The global options settings property.
813  Options *MainForm::options (void) const  Options *MainForm::options (void) const
# Line 766  MainForm *MainForm::getInstance (void) Line 831  MainForm *MainForm::getInstance (void)
831    
832    
833  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
834  // qsamplerMainForm -- Session file stuff.  // QSampler::MainForm -- Session file stuff.
835    
836  // Format the displayable session filename.  // Format the displayable session filename.
837  QString MainForm::sessionName ( const QString& sFilename )  QString MainForm::sessionName ( const QString& sFilename )
# Line 795  bool MainForm::newSession (void) Line 860  bool MainForm::newSession (void)
860          m_iUntitled++;          m_iUntitled++;
861    
862          // Stabilize form.          // Stabilize form.
863          m_sFilename = QString::null;          m_sFilename = QString();
864          m_iDirtyCount = 0;          m_iDirtyCount = 0;
865          appendMessages(tr("New session: \"%1\".").arg(sessionName(m_sFilename)));          appendMessages(tr("New session: \"%1\".").arg(sessionName(m_sFilename)));
866          stabilizeForm();          stabilizeForm();
# Line 807  bool MainForm::newSession (void) Line 872  bool MainForm::newSession (void)
872  // Open an existing sampler session.  // Open an existing sampler session.
873  bool MainForm::openSession (void)  bool MainForm::openSession (void)
874  {  {
875          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
876                  return false;                  return false;
877    
878          // Ask for the filename to open...          // Ask for the filename to open...
879          QString sFilename = QFileDialog::getOpenFileName(this,          QString sFilename = QFileDialog::getOpenFileName(this,
880                  QSAMPLER_TITLE ": " + tr("Open Session"), // Caption.                  tr("Open Session"),                       // Caption.
881                  m_pOptions->sSessionDir,                  // Start here.                  m_pOptions->sSessionDir,                  // Start here.
882                  tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)                  tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)
883          );          );
# Line 833  bool MainForm::openSession (void) Line 898  bool MainForm::openSession (void)
898  // Save current sampler session with another name.  // Save current sampler session with another name.
899  bool MainForm::saveSession ( bool bPrompt )  bool MainForm::saveSession ( bool bPrompt )
900  {  {
901          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
902                  return false;                  return false;
903    
904          QString sFilename = m_sFilename;          QString sFilename = m_sFilename;
# Line 845  bool MainForm::saveSession ( bool bPromp Line 910  bool MainForm::saveSession ( bool bPromp
910                          sFilename = m_pOptions->sSessionDir;                          sFilename = m_pOptions->sSessionDir;
911                  // Prompt the guy...                  // Prompt the guy...
912                  sFilename = QFileDialog::getSaveFileName(this,                  sFilename = QFileDialog::getSaveFileName(this,
913                          QSAMPLER_TITLE ": " + tr("Save Session"), // Caption.                          tr("Save Session"),                       // Caption.
914                          sFilename,                                // Start here.                          sFilename,                                // Start here.
915                          tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)                          tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)
916                  );                  );
# Line 855  bool MainForm::saveSession ( bool bPromp Line 920  bool MainForm::saveSession ( bool bPromp
920                  // Enforce .lscp extension...                  // Enforce .lscp extension...
921                  if (QFileInfo(sFilename).suffix().isEmpty())                  if (QFileInfo(sFilename).suffix().isEmpty())
922                          sFilename += ".lscp";                          sFilename += ".lscp";
923            #if 0
924                  // Check if already exists...                  // Check if already exists...
925                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
926                          if (QMessageBox::warning(this,                          if (QMessageBox::warning(this,
927                                  QSAMPLER_TITLE ": " + tr("Warning"),                                  tr("Warning"),
928                                  tr("The file already exists:\n\n"                                  tr("The file already exists:\n\n"
929                                  "\"%1\"\n\n"                                  "\"%1\"\n\n"
930                                  "Do you want to replace it?")                                  "Do you want to replace it?")
# Line 867  bool MainForm::saveSession ( bool bPromp Line 933  bool MainForm::saveSession ( bool bPromp
933                                  == QMessageBox::No)                                  == QMessageBox::No)
934                                  return false;                                  return false;
935                  }                  }
936            #endif
937          }          }
938    
939          // Save it right away.          // Save it right away.
# Line 882  bool MainForm::closeSession ( bool bForc Line 949  bool MainForm::closeSession ( bool bForc
949          // Are we dirty enough to prompt it?          // Are we dirty enough to prompt it?
950          if (m_iDirtyCount > 0) {          if (m_iDirtyCount > 0) {
951                  switch (QMessageBox::warning(this,                  switch (QMessageBox::warning(this,
952                          QSAMPLER_TITLE ": " + tr("Warning"),                          tr("Warning"),
953                          tr("The current session has been changed:\n\n"                          tr("The current session has been changed:\n\n"
954                          "\"%1\"\n\n"                          "\"%1\"\n\n"
955                          "Do you want to save the changes?")                          "Do you want to save the changes?")
# Line 907  bool MainForm::closeSession ( bool bForc Line 974  bool MainForm::closeSession ( bool bForc
974                  m_pWorkspace->setUpdatesEnabled(false);                  m_pWorkspace->setUpdatesEnabled(false);
975                  const QList<QMdiSubWindow *>& wlist                  const QList<QMdiSubWindow *>& wlist
976                          = m_pWorkspace->subWindowList();                          = m_pWorkspace->subWindowList();
977                  const int iStripCount = wlist.count();                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
978                  for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                          ChannelStrip *pChannelStrip
979                          ChannelStrip *pChannelStrip = NULL;                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                         QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                         if (pMdiSubWindow)  
                                 pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
980                          if (pChannelStrip) {                          if (pChannelStrip) {
981                                  Channel *pChannel = pChannelStrip->channel();                                  Channel *pChannel = pChannelStrip->channel();
982                                  if (bForce && pChannel)                                  if (bForce && pChannel)
983                                          pChannel->removeChannel();                                          pChannel->removeChannel();
984                                  delete pChannelStrip;                                  delete pChannelStrip;
985                          }                          }
986                          if (pMdiSubWindow)                          delete pMdiSubWindow;
                                 delete pMdiSubWindow;  
987                  }                  }
988                  m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
989                  // We're now clean, for sure.                  // We're now clean, for sure.
# Line 934  bool MainForm::closeSession ( bool bForc Line 997  bool MainForm::closeSession ( bool bForc
997  // Load a session from specific file path.  // Load a session from specific file path.
998  bool MainForm::loadSessionFile ( const QString& sFilename )  bool MainForm::loadSessionFile ( const QString& sFilename )
999  {  {
1000          if (m_pClient == NULL)          if (m_pClient == nullptr)
1001                  return false;                  return false;
1002    
1003          // Open and read from real file.          // Open and read from real file.
# Line 1010  bool MainForm::loadSessionFile ( const Q Line 1073  bool MainForm::loadSessionFile ( const Q
1073  // Save current session to specific file path.  // Save current session to specific file path.
1074  bool MainForm::saveSessionFile ( const QString& sFilename )  bool MainForm::saveSessionFile ( const QString& sFilename )
1075  {  {
1076          if (m_pClient == NULL)          if (m_pClient == nullptr)
1077                  return false;                  return false;
1078    
1079          // Check whether server is apparently OK...          // Check whether server is apparently OK...
# Line 1035  bool MainForm::saveSessionFile ( const Q Line 1098  bool MainForm::saveSessionFile ( const Q
1098          int iErrors = 0;          int iErrors = 0;
1099          QTextStream ts(&file);          QTextStream ts(&file);
1100          ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;          ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;
1101          ts << "# " << tr("Version")          ts << "# " << tr("Version") << ": " CONFIG_BUILD_VERSION << endl;
1102          << ": " QSAMPLER_VERSION << endl;  //      ts << "# " << tr("Build") << ": " CONFIG_BUILD_DATE << endl;
         ts << "# " << tr("Build")  
         << ": " __DATE__ " " __TIME__ << endl;  
1103          ts << "#"  << endl;          ts << "#"  << endl;
1104          ts << "# " << tr("File")          ts << "# " << tr("File")
1105          << ": " << QFileInfo(sFilename).fileName() << endl;          << ": " << QFileInfo(sFilename).fileName() << endl;
# Line 1051  bool MainForm::saveSessionFile ( const Q Line 1112  bool MainForm::saveSessionFile ( const Q
1112          // It is assumed that this new kind of device+session file          // It is assumed that this new kind of device+session file
1113          // will be loaded from a complete initialized server...          // will be loaded from a complete initialized server...
1114          int *piDeviceIDs;          int *piDeviceIDs;
1115          int  iDevice;          int  i, iDevice;
1116          ts << "RESET" << endl;          ts << "RESET" << endl;
1117    
1118          // Audio device mapping.          // Audio device mapping.
1119          QMap<int, int> audioDeviceMap;          QMap<int, int> audioDeviceMap; iDevice = 0;
1120          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);
1121          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1122                  ts << endl;                  Device device(Device::Audio, piDeviceIDs[i]);
1123                  Device device(Device::Audio, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1124                    if (device.driverName().toUpper() == "PLUGIN")
1125                            continue;
1126                  // Audio device specification...                  // Audio device specification...
1127                    ts << endl;
1128                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1129                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1130                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
# Line 1091  bool MainForm::saveSessionFile ( const Q Line 1155  bool MainForm::saveSessionFile ( const Q
1155                          iPort++;                          iPort++;
1156                  }                  }
1157                  // Audio device index/id mapping.                  // Audio device index/id mapping.
1158                  audioDeviceMap[device.deviceID()] = iDevice;                  audioDeviceMap.insert(device.deviceID(), iDevice++);
1159                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1160                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1161          }          }
1162    
1163          // MIDI device mapping.          // MIDI device mapping.
1164          QMap<int, int> midiDeviceMap;          QMap<int, int> midiDeviceMap; iDevice = 0;
1165          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);
1166          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1167                  ts << endl;                  Device device(Device::Midi, piDeviceIDs[i]);
1168                  Device device(Device::Midi, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1169                    if (device.driverName().toUpper() == "PLUGIN")
1170                            continue;
1171                  // MIDI device specification...                  // MIDI device specification...
1172                    ts << endl;
1173                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1174                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1175                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
# Line 1133  bool MainForm::saveSessionFile ( const Q Line 1200  bool MainForm::saveSessionFile ( const Q
1200                          iPort++;                          iPort++;
1201                  }                  }
1202                  // MIDI device index/id mapping.                  // MIDI device index/id mapping.
1203                  midiDeviceMap[device.deviceID()] = iDevice;                  midiDeviceMap.insert(device.deviceID(), iDevice++);
1204                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1205                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1206          }          }
# Line 1196  bool MainForm::saveSessionFile ( const Q Line 1263  bool MainForm::saveSessionFile ( const Q
1263                  }                  }
1264                  ts << endl;                  ts << endl;
1265                  // Check for errors...                  // Check for errors...
1266                  if (pInstrs == NULL && ::lscp_client_get_errno(m_pClient)) {                  if (pInstrs == nullptr && ::lscp_client_get_errno(m_pClient)) {
1267                          appendMessagesClient("lscp_list_midi_instruments");                          appendMessagesClient("lscp_list_midi_instruments");
1268                          iErrors++;                          iErrors++;
1269                  }                  }
1270                  // MIDI strument index/id mapping.                  // MIDI strument index/id mapping.
1271                  midiInstrumentMap[iMidiMap] = iMap;                  midiInstrumentMap.insert(iMidiMap, iMap);
1272          }          }
1273          // Check for errors...          // Check for errors...
1274          if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {          if (piMaps == nullptr && ::lscp_client_get_errno(m_pClient)) {
1275                  appendMessagesClient("lscp_list_midi_instrument_maps");                  appendMessagesClient("lscp_list_midi_instrument_maps");
1276                  iErrors++;                  iErrors++;
1277          }          }
1278  #endif  // CONFIG_MIDI_INSTRUMENT  #endif  // CONFIG_MIDI_INSTRUMENT
1279    
1280          // Sampler channel mapping.          // Sampler channel mapping...
1281            int iChannelID = 0;
1282          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
1283                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
1284          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
1285          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
1286                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
1287                  if (pChannelStrip) {                  if (pChannelStrip) {
1288                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1289                          if (pChannel) {                          if (pChannel) {
1290                                  const int iChannelID = pChannel->channelID();                                  // Avoid "artifial" plug-in devices...
1291                                    const int iAudioDevice = pChannel->audioDevice();
1292                                    if (!audioDeviceMap.contains(iAudioDevice))
1293                                            continue;
1294                                    const int iMidiDevice = pChannel->midiDevice();
1295                                    if (!midiDeviceMap.contains(iMidiDevice))
1296                                            continue;
1297                                    // Go for regular, canonical devices...
1298                                  ts << "# " << tr("Channel") << " " << iChannelID << endl;                                  ts << "# " << tr("Channel") << " " << iChannelID << endl;
1299                                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
1300                                  if (audioDeviceMap.isEmpty()) {                                  if (audioDeviceMap.isEmpty()) {
# Line 1230  bool MainForm::saveSessionFile ( const Q Line 1302  bool MainForm::saveSessionFile ( const Q
1302                                                  << " " << pChannel->audioDriver() << endl;                                                  << " " << pChannel->audioDriver() << endl;
1303                                  } else {                                  } else {
1304                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannelID                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannelID
1305                                                  << " " << audioDeviceMap[pChannel->audioDevice()] << endl;                                                  << " " << audioDeviceMap.value(iAudioDevice) << endl;
1306                                  }                                  }
1307                                  if (midiDeviceMap.isEmpty()) {                                  if (midiDeviceMap.isEmpty()) {
1308                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID
1309                                                  << " " << pChannel->midiDriver() << endl;                                                  << " " << pChannel->midiDriver() << endl;
1310                                  } else {                                  } else {
1311                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannelID                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannelID
1312                                                  << " " << midiDeviceMap[pChannel->midiDevice()] << endl;                                                  << " " << midiDeviceMap.value(iMidiDevice) << endl;
1313                                  }                                  }
1314                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID
1315                                          << " " << pChannel->midiPort() << endl;                                          << " " << pChannel->midiPort() << endl;
# Line 1268  bool MainForm::saveSessionFile ( const Q Line 1340  bool MainForm::saveSessionFile ( const Q
1340                                  if (pChannel->channelSolo())                                  if (pChannel->channelSolo())
1341                                          ts << "SET CHANNEL SOLO " << iChannelID << " 1" << endl;                                          ts << "SET CHANNEL SOLO " << iChannelID << " 1" << endl;
1342                          #ifdef CONFIG_MIDI_INSTRUMENT                          #ifdef CONFIG_MIDI_INSTRUMENT
1343                                  if (pChannel->midiMap() >= 0) {                                  const int iMidiMap = pChannel->midiMap();
1344                                    if (midiInstrumentMap.contains(iMidiMap)) {
1345                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannelID                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannelID
1346                                                  << " " << midiInstrumentMap[pChannel->midiMap()] << endl;                                                  << " " << midiInstrumentMap.value(iMidiMap) << endl;
1347                                  }                                  }
1348                          #endif                          #endif
1349                          #ifdef CONFIG_FXSEND                          #ifdef CONFIG_FXSEND
# Line 1309  bool MainForm::saveSessionFile ( const Q Line 1382  bool MainForm::saveSessionFile ( const Q
1382                                  }                                  }
1383                          #endif                          #endif
1384                                  ts << endl;                                  ts << endl;
1385                                    // Go for next channel...
1386                                    ++iChannelID;
1387                          }                          }
1388                  }                  }
1389                  // Try to keep it snappy :)                  // Try to keep it snappy :)
# Line 1360  void MainForm::sessionDirty (void) Line 1435  void MainForm::sessionDirty (void)
1435    
1436    
1437  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1438  // qsamplerMainForm -- File Action slots.  // QSampler::MainForm -- File Action slots.
1439    
1440  // Create a new sampler session.  // Create a new sampler session.
1441  void MainForm::fileNew (void)  void MainForm::fileNew (void)
# Line 1414  void MainForm::fileSaveAs (void) Line 1489  void MainForm::fileSaveAs (void)
1489  // Reset the sampler instance.  // Reset the sampler instance.
1490  void MainForm::fileReset (void)  void MainForm::fileReset (void)
1491  {  {
1492          if (m_pClient == NULL)          if (m_pClient == nullptr)
1493                  return;                  return;
1494    
1495          // Ask user whether he/she want's an internal sampler reset...          // Ask user whether he/she want's an internal sampler reset...
1496          if (m_pOptions && m_pOptions->bConfirmReset) {          if (m_pOptions && m_pOptions->bConfirmReset) {
1497                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");                  const QString& sTitle = tr("Warning");
1498                  const QString& sText = tr(                  const QString& sText = tr(
1499                          "Resetting the sampler instance will close\n"                          "Resetting the sampler instance will close\n"
1500                          "all device and channel configurations.\n\n"                          "all device and channel configurations.\n\n"
# Line 1470  void MainForm::fileReset (void) Line 1545  void MainForm::fileReset (void)
1545  // Restart the client/server instance.  // Restart the client/server instance.
1546  void MainForm::fileRestart (void)  void MainForm::fileRestart (void)
1547  {  {
1548          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1549                  return;                  return;
1550    
1551          bool bRestart = true;          bool bRestart = true;
# Line 1478  void MainForm::fileRestart (void) Line 1553  void MainForm::fileRestart (void)
1553          // Ask user whether he/she want's a complete restart...          // Ask user whether he/she want's a complete restart...
1554          // (if we're currently up and running)          // (if we're currently up and running)
1555          if (m_pOptions && m_pOptions->bConfirmRestart) {          if (m_pOptions && m_pOptions->bConfirmRestart) {
1556                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");                  const QString& sTitle = tr("Warning");
1557                  const QString& sText = tr(                  const QString& sText = tr(
1558                          "New settings will be effective after\n"                          "New settings will be effective after\n"
1559                          "restarting the client/server connection.\n\n"                          "restarting the client/server connection.\n\n"
# Line 1526  void MainForm::fileExit (void) Line 1601  void MainForm::fileExit (void)
1601    
1602    
1603  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1604  // qsamplerMainForm -- Edit Action slots.  // QSampler::MainForm -- Edit Action slots.
1605    
1606  // Add a new sampler channel.  // Add a new sampler channel.
1607  void MainForm::editAddChannel (void)  void MainForm::editAddChannel (void)
# Line 1538  void MainForm::editAddChannel (void) Line 1613  void MainForm::editAddChannel (void)
1613    
1614  void MainForm::addChannelStrip (void)  void MainForm::addChannelStrip (void)
1615  {  {
1616          if (m_pClient == NULL)          if (m_pClient == nullptr)
1617                  return;                  return;
1618    
1619          // Just create the channel instance...          // Just create the channel instance...
1620          Channel *pChannel = new Channel();          Channel *pChannel = new Channel();
1621          if (pChannel == NULL)          if (pChannel == nullptr)
1622                  return;                  return;
1623    
1624          // Before we show it up, may be we'll          // Before we show it up, may be we'll
# Line 1561  void MainForm::addChannelStrip (void) Line 1636  void MainForm::addChannelStrip (void)
1636          }          }
1637    
1638          // Do we auto-arrange?          // Do we auto-arrange?
1639          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
1640    
1641          // Make that an overall update.          // Make that an overall update.
1642          m_iDirtyCount++;          m_iDirtyCount++;
# Line 1580  void MainForm::editRemoveChannel (void) Line 1654  void MainForm::editRemoveChannel (void)
1654    
1655  void MainForm::removeChannelStrip (void)  void MainForm::removeChannelStrip (void)
1656  {  {
1657          if (m_pClient == NULL)          if (m_pClient == nullptr)
1658                  return;                  return;
1659    
1660          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1661          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1662                  return;                  return;
1663    
1664          Channel *pChannel = pChannelStrip->channel();          Channel *pChannel = pChannelStrip->channel();
1665          if (pChannel == NULL)          if (pChannel == nullptr)
1666                  return;                  return;
1667    
1668          // Prompt user if he/she's sure about this...          // Prompt user if he/she's sure about this...
1669          if (m_pOptions && m_pOptions->bConfirmRemove) {          if (m_pOptions && m_pOptions->bConfirmRemove) {
1670                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");                  const QString& sTitle = tr("Warning");
1671                  const QString& sText = tr(                  const QString& sText = tr(
1672                          "About to remove channel:\n\n"                          "About to remove channel:\n\n"
1673                          "%1\n\n"                          "%1\n\n"
# Line 1636  void MainForm::removeChannelStrip (void) Line 1710  void MainForm::removeChannelStrip (void)
1710  // Setup current sampler channel.  // Setup current sampler channel.
1711  void MainForm::editSetupChannel (void)  void MainForm::editSetupChannel (void)
1712  {  {
1713          if (m_pClient == NULL)          if (m_pClient == nullptr)
1714                  return;                  return;
1715    
1716          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1717          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1718                  return;                  return;
1719    
1720          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1651  void MainForm::editSetupChannel (void) Line 1725  void MainForm::editSetupChannel (void)
1725  // Edit current sampler channel.  // Edit current sampler channel.
1726  void MainForm::editEditChannel (void)  void MainForm::editEditChannel (void)
1727  {  {
1728          if (m_pClient == NULL)          if (m_pClient == nullptr)
1729                  return;                  return;
1730    
1731          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1732          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1733                  return;                  return;
1734    
1735          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1666  void MainForm::editEditChannel (void) Line 1740  void MainForm::editEditChannel (void)
1740  // Reset current sampler channel.  // Reset current sampler channel.
1741  void MainForm::editResetChannel (void)  void MainForm::editResetChannel (void)
1742  {  {
1743          if (m_pClient == NULL)          if (m_pClient == nullptr)
1744                  return;                  return;
1745    
1746          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1747          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1748                  return;                  return;
1749    
1750          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1681  void MainForm::editResetChannel (void) Line 1755  void MainForm::editResetChannel (void)
1755  // Reset all sampler channels.  // Reset all sampler channels.
1756  void MainForm::editResetAllChannels (void)  void MainForm::editResetAllChannels (void)
1757  {  {
1758          if (m_pClient == NULL)          if (m_pClient == nullptr)
1759                  return;                  return;
1760    
1761          // Invoque the channel strip procedure,          // Invoque the channel strip procedure,
# Line 1689  void MainForm::editResetAllChannels (voi Line 1763  void MainForm::editResetAllChannels (voi
1763          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1764          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
1765                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
1766          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
1767          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
1768                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
1769                  if (pChannelStrip)                  if (pChannelStrip)
1770                          pChannelStrip->channelReset();                          pChannelStrip->channelReset();
1771          }          }
# Line 1703  void MainForm::editResetAllChannels (voi Line 1774  void MainForm::editResetAllChannels (voi
1774    
1775    
1776  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1777  // qsamplerMainForm -- View Action slots.  // QSampler::MainForm -- View Action slots.
1778    
1779  // Show/hide the main program window menubar.  // Show/hide the main program window menubar.
1780  void MainForm::viewMenubar ( bool bOn )  void MainForm::viewMenubar ( bool bOn )
# Line 1753  void MainForm::viewMessages ( bool bOn ) Line 1824  void MainForm::viewMessages ( bool bOn )
1824  // Show/hide the MIDI instrument list-view form.  // Show/hide the MIDI instrument list-view form.
1825  void MainForm::viewInstruments (void)  void MainForm::viewInstruments (void)
1826  {  {
1827          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1828                  return;                  return;
1829    
1830          if (m_pInstrumentListForm) {          if (m_pInstrumentListForm) {
# Line 1772  void MainForm::viewInstruments (void) Line 1843  void MainForm::viewInstruments (void)
1843  // Show/hide the device configurator form.  // Show/hide the device configurator form.
1844  void MainForm::viewDevices (void)  void MainForm::viewDevices (void)
1845  {  {
1846          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1847                  return;                  return;
1848    
1849          if (m_pDeviceForm) {          if (m_pDeviceForm) {
# Line 1791  void MainForm::viewDevices (void) Line 1862  void MainForm::viewDevices (void)
1862  // Show options dialog.  // Show options dialog.
1863  void MainForm::viewOptions (void)  void MainForm::viewOptions (void)
1864  {  {
1865          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1866                  return;                  return;
1867    
1868          OptionsForm* pOptionsForm = new OptionsForm(this);          OptionsForm* pOptionsForm = new OptionsForm(this);
# Line 1833  void MainForm::viewOptions (void) Line 1904  void MainForm::viewOptions (void)
1904                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)     ||                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)     ||
1905                                  (iOldBaseFontSize   !=  m_pOptions->iBaseFontSize)) {                                  (iOldBaseFontSize   !=  m_pOptions->iBaseFontSize)) {
1906                                  QMessageBox::information(this,                                  QMessageBox::information(this,
1907                                          QSAMPLER_TITLE ": " + tr("Information"),                                          tr("Information"),
1908                                          tr("Some settings may be only effective\n"                                          tr("Some settings may be only effective\n"
1909                                          "next time you start this program."));                                          "next time you start this program."));
1910                                  updateMessagesCapture();                                  updateMessagesCapture();
# Line 1884  void MainForm::viewOptions (void) Line 1955  void MainForm::viewOptions (void)
1955    
1956    
1957  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1958  // qsamplerMainForm -- Channels action slots.  // QSampler::MainForm -- Channels action slots.
1959    
1960  // Arrange channel strips.  // Arrange channel strips.
1961  void MainForm::channelsArrange (void)  void MainForm::channelsArrange (void)
# Line 1897  void MainForm::channelsArrange (void) Line 1968  void MainForm::channelsArrange (void)
1968    
1969          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1970          int y = 0;          int y = 0;
1971          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
1972          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  pMdiSubWindow->adjustSize();
1973                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);                  const QRect& frameRect
1974                  if (pMdiSubWindow) {                          = pMdiSubWindow->frameGeometry();
1975                          pMdiSubWindow->adjustSize();                  int w = m_pWorkspace->width();
1976                          int iWidth = m_pWorkspace->width();                  if (w < frameRect.width())
1977                          if (iWidth < pMdiSubWindow->width())                          w = frameRect.width();
1978                                  iWidth = pMdiSubWindow->width();                  const int h = frameRect.height();
1979                          const int iHeight = pMdiSubWindow->frameGeometry().height();                  pMdiSubWindow->setGeometry(0, y, w, h);
1980                          pMdiSubWindow->setGeometry(0, y, iWidth, iHeight);                  y += h;
                         y += iHeight;  
                 }  
1981          }          }
1982          m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
1983    
# Line 1919  void MainForm::channelsArrange (void) Line 1988  void MainForm::channelsArrange (void)
1988  // Auto-arrange channel strips.  // Auto-arrange channel strips.
1989  void MainForm::channelsAutoArrange ( bool bOn )  void MainForm::channelsAutoArrange ( bool bOn )
1990  {  {
1991          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1992                  return;                  return;
1993    
1994          // Toggle the auto-arrange flag.          // Toggle the auto-arrange flag.
1995          m_pOptions->bAutoArrange = bOn;          m_pOptions->bAutoArrange = bOn;
1996    
1997          // If on, update whole workspace...          // If on, update whole workspace...
1998          if (m_pOptions->bAutoArrange)          channelsArrangeAuto();
1999    }
2000    
2001    
2002    void MainForm::channelsArrangeAuto (void)
2003    {
2004            if (m_pOptions && m_pOptions->bAutoArrange)
2005                  channelsArrange();                  channelsArrange();
2006  }  }
2007    
2008    
2009  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2010  // qsamplerMainForm -- Help Action slots.  // QSampler::MainForm -- Help Action slots.
2011    
2012  // Show information about the Qt toolkit.  // Show information about the Qt toolkit.
2013  void MainForm::helpAboutQt (void)  void MainForm::helpAboutQt (void)
# Line 1944  void MainForm::helpAboutQt (void) Line 2019  void MainForm::helpAboutQt (void)
2019  // Show information about application program.  // Show information about application program.
2020  void MainForm::helpAbout (void)  void MainForm::helpAbout (void)
2021  {  {
2022          // Stuff the about box text...          QStringList list;
         QString sText = "<p>\n";  
         sText += "<b>" QSAMPLER_TITLE " - " + tr(QSAMPLER_SUBTITLE) + "</b><br />\n";  
         sText += "<br />\n";  
         sText += tr("Version") + ": <b>" QSAMPLER_VERSION "</b><br />\n";  
         sText += "<small>" + tr("Build") + ": " __DATE__ " " __TIME__ "</small><br />\n";  
2023  #ifdef CONFIG_DEBUG  #ifdef CONFIG_DEBUG
2024          sText += "<small><font color=\"red\">";          list << tr("Debugging option enabled.");
         sText += tr("Debugging option enabled.");  
         sText += "</font></small><br />";  
2025  #endif  #endif
2026  #ifndef CONFIG_LIBGIG  #ifndef CONFIG_LIBGIG
2027          sText += "<small><font color=\"red\">";          list << tr("GIG (libgig) file support disabled.");
         sText += tr("GIG (libgig) file support disabled.");  
         sText += "</font></small><br />";  
2028  #endif  #endif
2029  #ifndef CONFIG_INSTRUMENT_NAME  #ifndef CONFIG_INSTRUMENT_NAME
2030          sText += "<small><font color=\"red\">";          list << tr("LSCP (liblscp) instrument_name support disabled.");
         sText += tr("LSCP (liblscp) instrument_name support disabled.");  
         sText += "</font></small><br />";  
2031  #endif  #endif
2032  #ifndef CONFIG_MUTE_SOLO  #ifndef CONFIG_MUTE_SOLO
2033          sText += "<small><font color=\"red\">";          list << tr("Sampler channel Mute/Solo support disabled.");
         sText += tr("Sampler channel Mute/Solo support disabled.");  
         sText += "</font></small><br />";  
2034  #endif  #endif
2035  #ifndef CONFIG_AUDIO_ROUTING  #ifndef CONFIG_AUDIO_ROUTING
2036          sText += "<small><font color=\"red\">";          list << tr("LSCP (liblscp) audio_routing support disabled.");
         sText += tr("LSCP (liblscp) audio_routing support disabled.");  
         sText += "</font></small><br />";  
2037  #endif  #endif
2038  #ifndef CONFIG_FXSEND  #ifndef CONFIG_FXSEND
2039          sText += "<small><font color=\"red\">";          list << tr("Sampler channel Effect Sends support disabled.");
         sText += tr("Sampler channel Effect Sends support disabled.");  
         sText += "</font></small><br />";  
2040  #endif  #endif
2041  #ifndef CONFIG_VOLUME  #ifndef CONFIG_VOLUME
2042          sText += "<small><font color=\"red\">";          list << tr("Global volume support disabled.");
         sText += tr("Global volume support disabled.");  
         sText += "</font></small><br />";  
2043  #endif  #endif
2044  #ifndef CONFIG_MIDI_INSTRUMENT  #ifndef CONFIG_MIDI_INSTRUMENT
2045          sText += "<small><font color=\"red\">";          list << tr("MIDI instrument mapping support disabled.");
         sText += tr("MIDI instrument mapping support disabled.");  
         sText += "</font></small><br />";  
2046  #endif  #endif
2047  #ifndef CONFIG_EDIT_INSTRUMENT  #ifndef CONFIG_EDIT_INSTRUMENT
2048          sText += "<small><font color=\"red\">";          list << tr("Instrument editing support disabled.");
         sText += tr("Instrument editing support disabled.");  
         sText += "</font></small><br />";  
2049  #endif  #endif
2050  #ifndef CONFIG_EVENT_CHANNEL_MIDI  #ifndef CONFIG_EVENT_CHANNEL_MIDI
2051          sText += "<small><font color=\"red\">";          list << tr("Channel MIDI event support disabled.");
         sText += tr("Channel MIDI event support disabled.");  
         sText += "</font></small><br />";  
2052  #endif  #endif
2053  #ifndef CONFIG_EVENT_DEVICE_MIDI  #ifndef CONFIG_EVENT_DEVICE_MIDI
2054          sText += "<small><font color=\"red\">";          list << tr("Device MIDI event support disabled.");
         sText += tr("Device MIDI event support disabled.");  
         sText += "</font></small><br />";  
2055  #endif  #endif
2056  #ifndef CONFIG_MAX_VOICES  #ifndef CONFIG_MAX_VOICES
2057          sText += "<small><font color=\"red\">";          list << tr("Runtime max. voices / disk streams support disabled.");
         sText += tr("Runtime max. voices / disk streams support disabled.");  
         sText += "</font></small><br />";  
2058  #endif  #endif
2059    
2060            // Stuff the about box text...
2061            QString sText = "<p>\n";
2062            sText += "<b>" QSAMPLER_TITLE " - " + tr(QSAMPLER_SUBTITLE) + "</b><br />\n";
2063            sText += "<br />\n";
2064            sText += tr("Version") + ": <b>" CONFIG_BUILD_VERSION "</b><br />\n";
2065    //      sText += "<small>" + tr("Build") + ": " CONFIG_BUILD_DATE "</small><br />\n";
2066            if (!list.isEmpty()) {
2067                    sText += "<small><font color=\"red\">";
2068                    sText += list.join("<br />\n");
2069                    sText += "</font></small>";
2070            }
2071          sText += "<br />\n";          sText += "<br />\n";
2072          sText += tr("Using") + ": ";          sText += tr("Using") + ": ";
2073          sText += ::lscp_client_package();          sText += ::lscp_client_package();
# Line 2034  void MainForm::helpAbout (void) Line 2092  void MainForm::helpAbout (void)
2092          sText += "</small>";          sText += "</small>";
2093          sText += "</p>\n";          sText += "</p>\n";
2094    
2095          QMessageBox::about(this, tr("About") + " " QSAMPLER_TITLE, sText);          QMessageBox::about(this, tr("About"), sText);
2096  }  }
2097    
2098    
2099  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2100  // qsamplerMainForm -- Main window stabilization.  // QSampler::MainForm -- Main window stabilization.
2101    
2102  void MainForm::stabilizeForm (void)  void MainForm::stabilizeForm (void)
2103  {  {
# Line 2047  void MainForm::stabilizeForm (void) Line 2105  void MainForm::stabilizeForm (void)
2105          QString sSessionName = sessionName(m_sFilename);          QString sSessionName = sessionName(m_sFilename);
2106          if (m_iDirtyCount > 0)          if (m_iDirtyCount > 0)
2107                  sSessionName += " *";                  sSessionName += " *";
2108          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));          setWindowTitle(sSessionName);
2109    
2110          // Update the main menu state...          // Update the main menu state...
2111          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
2112          const QList<QMdiSubWindow *>& wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist = m_pWorkspace->subWindowList();
2113          const bool bHasClient = (m_pOptions != NULL && m_pClient != NULL);          const bool bHasClient = (m_pOptions != nullptr && m_pClient != nullptr);
2114          const bool bHasChannel = (bHasClient && pChannelStrip != NULL);          const bool bHasChannel = (bHasClient && pChannelStrip != nullptr);
2115          const bool bHasChannels = (bHasClient && wlist.count() > 0);          const bool bHasChannels = (bHasClient && wlist.count() > 0);
2116          m_ui.fileNewAction->setEnabled(bHasClient);          m_ui.fileNewAction->setEnabled(bHasClient);
2117          m_ui.fileOpenAction->setEnabled(bHasClient);          m_ui.fileOpenAction->setEnabled(bHasClient);
2118          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
2119          m_ui.fileSaveAsAction->setEnabled(bHasClient);          m_ui.fileSaveAsAction->setEnabled(bHasClient);
2120          m_ui.fileResetAction->setEnabled(bHasClient);          m_ui.fileResetAction->setEnabled(bHasClient);
2121          m_ui.fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);          m_ui.fileRestartAction->setEnabled(bHasClient || m_pServer == nullptr);
2122          m_ui.editAddChannelAction->setEnabled(bHasClient);          m_ui.editAddChannelAction->setEnabled(bHasClient);
2123          m_ui.editRemoveChannelAction->setEnabled(bHasChannel);          m_ui.editRemoveChannelAction->setEnabled(bHasChannel);
2124          m_ui.editSetupChannelAction->setEnabled(bHasChannel);          m_ui.editSetupChannelAction->setEnabled(bHasChannel);
# Line 2191  void MainForm::updateSession (void) Line 2249  void MainForm::updateSession (void)
2249          updateAllChannelStrips(false);          updateAllChannelStrips(false);
2250    
2251          // Do we auto-arrange?          // Do we auto-arrange?
2252          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
2253    
2254          // Remember to refresh devices and instruments...          // Remember to refresh devices and instruments...
2255          if (m_pInstrumentListForm)          if (m_pInstrumentListForm)
# Line 2210  void MainForm::updateAllChannelStrips ( Line 2267  void MainForm::updateAllChannelStrips (
2267    
2268          // Retrieve the current channel list.          // Retrieve the current channel list.
2269          int *piChannelIDs = ::lscp_list_channels(m_pClient);          int *piChannelIDs = ::lscp_list_channels(m_pClient);
2270          if (piChannelIDs == NULL) {          if (piChannelIDs == nullptr) {
2271                  if (::lscp_client_get_errno(m_pClient)) {                  if (::lscp_client_get_errno(m_pClient)) {
2272                          appendMessagesClient("lscp_list_channels");                          appendMessagesClient("lscp_list_channels");
2273                          appendMessagesError(                          appendMessagesError(
# Line 2225  void MainForm::updateAllChannelStrips ( Line 2282  void MainForm::updateAllChannelStrips (
2282                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));
2283                  }                  }
2284                  // Do we auto-arrange?                  // Do we auto-arrange?
2285                  if (m_pOptions && m_pOptions->bAutoArrange)                  channelsArrangeAuto();
                         channelsArrange();  
2286                  // remove dead channel strips                  // remove dead channel strips
2287                  if (bRemoveDeadStrips) {                  if (bRemoveDeadStrips) {
2288                          const QList<QMdiSubWindow *>& wlist                          const QList<QMdiSubWindow *>& wlist
2289                                  = m_pWorkspace->subWindowList();                                  = m_pWorkspace->subWindowList();
2290                          const int iStripCount = wlist.count();                          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2291                          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                                  ChannelStrip *pChannelStrip
2292                                  ChannelStrip *pChannelStrip = NULL;                                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                                 if (pMdiSubWindow)  
                                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2293                                  if (pChannelStrip) {                                  if (pChannelStrip) {
2294                                          bool bExists = false;                                          bool bExists = false;
2295                                          for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {                                          for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {
2296                                                  Channel *pChannel = pChannelStrip->channel();                                                  Channel *pChannel = pChannelStrip->channel();
2297                                                  if (pChannel == NULL)                                                  if (pChannel == nullptr)
2298                                                          break;                                                          break;
2299                                                  if (piChannelIDs[iChannel] == pChannel->channelID()) {                                                  if (piChannelIDs[iChannel] == pChannel->channelID()) {
2300                                                          // strip exists, don't touch it                                                          // strip exists, don't touch it
# Line 2264  void MainForm::updateAllChannelStrips ( Line 2317  void MainForm::updateAllChannelStrips (
2317  // Update the recent files list and menu.  // Update the recent files list and menu.
2318  void MainForm::updateRecentFiles ( const QString& sFilename )  void MainForm::updateRecentFiles ( const QString& sFilename )
2319  {  {
2320          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2321                  return;                  return;
2322    
2323          // Remove from list if already there (avoid duplicates)          // Remove from list if already there (avoid duplicates)
# Line 2279  void MainForm::updateRecentFiles ( const Line 2332  void MainForm::updateRecentFiles ( const
2332  // Update the recent files list and menu.  // Update the recent files list and menu.
2333  void MainForm::updateRecentFilesMenu (void)  void MainForm::updateRecentFilesMenu (void)
2334  {  {
2335          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2336                  return;                  return;
2337    
2338          // Time to keep the list under limits.          // Time to keep the list under limits.
# Line 2313  void MainForm::updateInstrumentNames (vo Line 2366  void MainForm::updateInstrumentNames (vo
2366                  return;                  return;
2367    
2368          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2369          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2370          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2371                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2372                  if (pChannelStrip)                  if (pChannelStrip)
2373                          pChannelStrip->updateInstrumentName(true);                          pChannelStrip->updateInstrumentName(true);
2374          }          }
# Line 2329  void MainForm::updateInstrumentNames (vo Line 2379  void MainForm::updateInstrumentNames (vo
2379  // Force update of the channels display font.  // Force update of the channels display font.
2380  void MainForm::updateDisplayFont (void)  void MainForm::updateDisplayFont (void)
2381  {  {
2382          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2383                  return;                  return;
2384    
2385          // Check if display font is legal.          // Check if display font is legal.
# Line 2348  void MainForm::updateDisplayFont (void) Line 2398  void MainForm::updateDisplayFont (void)
2398                  return;                  return;
2399    
2400          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2401          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2402          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2403                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2404                  if (pChannelStrip)                  if (pChannelStrip)
2405                          pChannelStrip->setDisplayFont(font);                          pChannelStrip->setDisplayFont(font);
2406          }          }
# Line 2371  void MainForm::updateDisplayEffect (void Line 2418  void MainForm::updateDisplayEffect (void
2418                  return;                  return;
2419    
2420          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2421          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2422          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2423                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2424                  if (pChannelStrip)                  if (pChannelStrip)
2425                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2426          }          }
# Line 2387  void MainForm::updateDisplayEffect (void Line 2431  void MainForm::updateDisplayEffect (void
2431  // Force update of the channels maximum volume setting.  // Force update of the channels maximum volume setting.
2432  void MainForm::updateMaxVolume (void)  void MainForm::updateMaxVolume (void)
2433  {  {
2434          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2435                  return;                  return;
2436    
2437  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
# Line 2404  void MainForm::updateMaxVolume (void) Line 2448  void MainForm::updateMaxVolume (void)
2448                  return;                  return;
2449    
2450          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2451          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2452          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2453                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2454                  if (pChannelStrip)                  if (pChannelStrip)
2455                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2456          }          }
# Line 2418  void MainForm::updateMaxVolume (void) Line 2459  void MainForm::updateMaxVolume (void)
2459    
2460    
2461  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2462  // qsamplerMainForm -- Messages window form handlers.  // QSampler::MainForm -- Messages window form handlers.
2463    
2464  // Messages output methods.  // Messages output methods.
2465  void MainForm::appendMessages( const QString& s )  void MainForm::appendMessages( const QString& s )
# Line 2454  void MainForm::appendMessagesError( cons Line 2495  void MainForm::appendMessagesError( cons
2495          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2496    
2497          if (m_pOptions && m_pOptions->bConfirmError) {          if (m_pOptions && m_pOptions->bConfirmError) {
2498                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Error");                  const QString& sTitle = tr("Error");
2499          #if 0          #if 0
2500                  QMessageBox::critical(this, sTitle, sText, QMessageBox::Cancel);                  QMessageBox::critical(this, sTitle, sText, QMessageBox::Cancel);
2501          #else          #else
# Line 2477  void MainForm::appendMessagesError( cons Line 2518  void MainForm::appendMessagesError( cons
2518  // This is a special message format, just for client results.  // This is a special message format, just for client results.
2519  void MainForm::appendMessagesClient( const QString& s )  void MainForm::appendMessagesClient( const QString& s )
2520  {  {
2521          if (m_pClient == NULL)          if (m_pClient == nullptr)
2522                  return;                  return;
2523    
2524          appendMessagesColor(s + QString(": %1 (errno=%2)")          appendMessagesColor(s + QString(": %1 (errno=%2)")
# Line 2492  void MainForm::appendMessagesClient( con Line 2533  void MainForm::appendMessagesClient( con
2533  // Force update of the messages font.  // Force update of the messages font.
2534  void MainForm::updateMessagesFont (void)  void MainForm::updateMessagesFont (void)
2535  {  {
2536          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2537                  return;                  return;
2538    
2539          if (m_pMessages && !m_pOptions->sMessagesFont.isEmpty()) {          if (m_pMessages && !m_pOptions->sMessagesFont.isEmpty()) {
# Line 2506  void MainForm::updateMessagesFont (void) Line 2547  void MainForm::updateMessagesFont (void)
2547  // Update messages window line limit.  // Update messages window line limit.
2548  void MainForm::updateMessagesLimit (void)  void MainForm::updateMessagesLimit (void)
2549  {  {
2550          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2551                  return;                  return;
2552    
2553          if (m_pMessages) {          if (m_pMessages) {
# Line 2521  void MainForm::updateMessagesLimit (void Line 2562  void MainForm::updateMessagesLimit (void
2562  // Enablement of the messages capture feature.  // Enablement of the messages capture feature.
2563  void MainForm::updateMessagesCapture (void)  void MainForm::updateMessagesCapture (void)
2564  {  {
2565          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2566                  return;                  return;
2567    
2568          if (m_pMessages)          if (m_pMessages)
# Line 2530  void MainForm::updateMessagesCapture (vo Line 2571  void MainForm::updateMessagesCapture (vo
2571    
2572    
2573  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2574  // qsamplerMainForm -- MDI channel strip management.  // QSampler::MainForm -- MDI channel strip management.
2575    
2576  // The channel strip creation executive.  // The channel strip creation executive.
2577  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )
2578  {  {
2579          if (m_pClient == NULL || pChannel == NULL)          if (m_pClient == nullptr || pChannel == nullptr)
2580                  return NULL;                  return nullptr;
2581    
2582          // Add a new channel itema...          // Add a new channel itema...
2583          ChannelStrip *pChannelStrip = new ChannelStrip();          ChannelStrip *pChannelStrip = new ChannelStrip();
2584          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
2585                  return NULL;                  return nullptr;
2586    
2587          // Set some initial channel strip options...          // Set some initial channel strip options...
2588          if (m_pOptions) {          if (m_pOptions) {
# Line 2557  ChannelStrip *MainForm::createChannelStr Line 2598  ChannelStrip *MainForm::createChannelStr
2598          }          }
2599    
2600          // Add it to workspace...          // Add it to workspace...
2601          m_pWorkspace->addSubWindow(pChannelStrip,          QMdiSubWindow *pMdiSubWindow
2602                  Qt::SubWindow | Qt::FramelessWindowHint);                  = m_pWorkspace->addSubWindow(pChannelStrip,
2603                            Qt::SubWindow | Qt::FramelessWindowHint);
2604            pMdiSubWindow->setAttribute(Qt::WA_DeleteOnClose);
2605    
2606          // Actual channel strip setup...          // Actual channel strip setup...
2607          pChannelStrip->setup(pChannel);          pChannelStrip->setup(pChannel);
# Line 2582  void MainForm::destroyChannelStrip ( Cha Line 2625  void MainForm::destroyChannelStrip ( Cha
2625  {  {
2626          QMdiSubWindow *pMdiSubWindow          QMdiSubWindow *pMdiSubWindow
2627                  = static_cast<QMdiSubWindow *> (pChannelStrip->parentWidget());                  = static_cast<QMdiSubWindow *> (pChannelStrip->parentWidget());
2628          if (pMdiSubWindow == NULL)          if (pMdiSubWindow == nullptr)
2629                  return;                  return;
2630    
2631          // Just delete the channel strip.          // Just delete the channel strip.
# Line 2590  void MainForm::destroyChannelStrip ( Cha Line 2633  void MainForm::destroyChannelStrip ( Cha
2633          delete pMdiSubWindow;          delete pMdiSubWindow;
2634    
2635          // Do we auto-arrange?          // Do we auto-arrange?
2636          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
2637  }  }
2638    
2639    
# Line 2602  ChannelStrip *MainForm::activeChannelStr Line 2644  ChannelStrip *MainForm::activeChannelStr
2644          if (pMdiSubWindow)          if (pMdiSubWindow)
2645                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2646          else          else
2647                  return NULL;                  return nullptr;
2648  }  }
2649    
2650    
2651  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2652  ChannelStrip *MainForm::channelStripAt ( int iStrip )  ChannelStrip *MainForm::channelStripAt ( int iStrip )
2653  {  {
2654          if (!m_pWorkspace) return NULL;          if (!m_pWorkspace) return nullptr;
2655    
2656          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
2657                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
2658          if (wlist.isEmpty())          if (wlist.isEmpty())
2659                  return NULL;                  return nullptr;
2660    
2661          if (iStrip < 0 || iStrip >= wlist.count())          if (iStrip < 0 || iStrip >= wlist.count())
2662                  return NULL;                  return nullptr;
2663    
2664          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2665          if (pMdiSubWindow)          if (pMdiSubWindow)
2666                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2667          else          else
2668                  return NULL;                  return nullptr;
2669  }  }
2670    
2671    
# Line 2633  ChannelStrip *MainForm::channelStrip ( i Line 2675  ChannelStrip *MainForm::channelStrip ( i
2675          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
2676                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
2677          if (wlist.isEmpty())          if (wlist.isEmpty())
2678                  return NULL;                  return nullptr;
2679    
2680          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2681          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2682                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2683                  if (pChannelStrip) {                  if (pChannelStrip) {
2684                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
2685                          if (pChannel && pChannel->channelID() == iChannelID)                          if (pChannel && pChannel->channelID() == iChannelID)
# Line 2649  ChannelStrip *MainForm::channelStrip ( i Line 2688  ChannelStrip *MainForm::channelStrip ( i
2688          }          }
2689    
2690          // Not found.          // Not found.
2691          return NULL;          return nullptr;
2692  }  }
2693    
2694    
# Line 2664  void MainForm::channelsMenuAboutToShow ( Line 2703  void MainForm::channelsMenuAboutToShow (
2703                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
2704          if (!wlist.isEmpty()) {          if (!wlist.isEmpty()) {
2705                  m_ui.channelsMenu->addSeparator();                  m_ui.channelsMenu->addSeparator();
2706                  const int iStripCount = wlist.count();                  int iStrip = 0;
2707                  for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2708                          ChannelStrip *pChannelStrip = NULL;                          ChannelStrip *pChannelStrip
2709                          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                         if (pMdiSubWindow)  
                                 pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2710                          if (pChannelStrip) {                          if (pChannelStrip) {
2711                                  QAction *pAction = m_ui.channelsMenu->addAction(                                  QAction *pAction = m_ui.channelsMenu->addAction(
2712                                          pChannelStrip->windowTitle(),                                          pChannelStrip->windowTitle(),
# Line 2678  void MainForm::channelsMenuAboutToShow ( Line 2715  void MainForm::channelsMenuAboutToShow (
2715                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);
2716                                  pAction->setData(iStrip);                                  pAction->setData(iStrip);
2717                          }                          }
2718                            ++iStrip;
2719                  }                  }
2720          }          }
2721  }  }
# Line 2688  void MainForm::channelsMenuActivated (vo Line 2726  void MainForm::channelsMenuActivated (vo
2726  {  {
2727          // Retrive channel index from action data...          // Retrive channel index from action data...
2728          QAction *pAction = qobject_cast<QAction *> (sender());          QAction *pAction = qobject_cast<QAction *> (sender());
2729          if (pAction == NULL)          if (pAction == nullptr)
2730                  return;                  return;
2731    
2732          ChannelStrip *pChannelStrip = channelStripAt(pAction->data().toInt());          ChannelStrip *pChannelStrip = channelStripAt(pAction->data().toInt());
# Line 2700  void MainForm::channelsMenuActivated (vo Line 2738  void MainForm::channelsMenuActivated (vo
2738    
2739    
2740  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2741  // qsamplerMainForm -- Timer stuff.  // QSampler::MainForm -- Timer stuff.
2742    
2743  // Set the pseudo-timer delay schedule.  // Set the pseudo-timer delay schedule.
2744  void MainForm::startSchedule ( int iStartDelay )  void MainForm::startSchedule ( int iStartDelay )
# Line 2719  void MainForm::stopSchedule (void) Line 2757  void MainForm::stopSchedule (void)
2757  // Timer slot funtion.  // Timer slot funtion.
2758  void MainForm::timerSlot (void)  void MainForm::timerSlot (void)
2759  {  {
2760          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2761                  return;                  return;
2762    
2763          // Is it the first shot on server start after a few delay?          // Is it the first shot on server start after a few delay?
# Line 2754  void MainForm::timerSlot (void) Line 2792  void MainForm::timerSlot (void)
2792                                  // Update the channel stream usage for each strip...                                  // Update the channel stream usage for each strip...
2793                                  const QList<QMdiSubWindow *>& wlist                                  const QList<QMdiSubWindow *>& wlist
2794                                          = m_pWorkspace->subWindowList();                                          = m_pWorkspace->subWindowList();
2795                                  const int iStripCount = wlist.count();                                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2796                                  for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                                          ChannelStrip *pChannelStrip
2797                                          ChannelStrip *pChannelStrip = NULL;                                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                                         QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                                         if (pMdiSubWindow)  
                                                 pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2798                                          if (pChannelStrip && pChannelStrip->isVisible())                                          if (pChannelStrip && pChannelStrip->isVisible())
2799                                                  pChannelStrip->updateChannelUsage();                                                  pChannelStrip->updateChannelUsage();
2800                                  }                                  }
2801                          }                          }
2802                  }                  }
2803    
2804            #if CONFIG_LSCP_CLIENT_CONNECTION_LOST
2805                    // If we lost connection to server: Try to automatically reconnect if we
2806                    // did not start the server.
2807                    //
2808                    // TODO: If we started the server, then we might inform the user that
2809                    // the server probably crashed and asking user ONCE whether we should
2810                    // restart the server.
2811                    if (lscp_client_connection_lost(m_pClient) && !m_pServer)
2812                            startAutoReconnectClient();
2813            #endif // CONFIG_LSCP_CLIENT_CONNECTION_LOST
2814          }          }
2815    
2816          // Register the next timer slot.          // Register the next timer slot.
# Line 2773  void MainForm::timerSlot (void) Line 2819  void MainForm::timerSlot (void)
2819    
2820    
2821  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2822  // qsamplerMainForm -- Server stuff.  // QSampler::MainForm -- Server stuff.
2823    
2824  // Start linuxsampler server...  // Start linuxsampler server...
2825  void MainForm::startServer (void)  void MainForm::startServer (void)
2826  {  {
2827          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2828                  return;                  return;
2829    
2830          // Aren't already a client, are we?          // Aren't already a client, are we?
# Line 2788  void MainForm::startServer (void) Line 2834  void MainForm::startServer (void)
2834          // Is the server process instance still here?          // Is the server process instance still here?
2835          if (m_pServer) {          if (m_pServer) {
2836                  if (QMessageBox::warning(this,                  if (QMessageBox::warning(this,
2837                          QSAMPLER_TITLE ": " + tr("Warning"),                          tr("Warning"),
2838                          tr("Could not start the LinuxSampler server.\n\n"                          tr("Could not start the LinuxSampler server.\n\n"
2839                          "Maybe it is already started."),                          "Maybe it is already started."),
2840                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
# Line 2807  void MainForm::startServer (void) Line 2853  void MainForm::startServer (void)
2853    
2854          // OK. Let's build the startup process...          // OK. Let's build the startup process...
2855          m_pServer = new QProcess();          m_pServer = new QProcess();
2856          bForceServerStop = true;          m_bForceServerStop = true;
2857    
2858          // Setup stdout/stderr capture...          // Setup stdout/stderr capture...
2859          m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);          m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);
# Line 2851  void MainForm::startServer (void) Line 2897  void MainForm::startServer (void)
2897    
2898    
2899  // Stop linuxsampler server...  // Stop linuxsampler server...
2900  void MainForm::stopServer (bool bInteractive)  void MainForm::stopServer ( bool bInteractive )
2901  {  {
2902          // Stop client code.          // Stop client code.
2903          stopClient();          stopClient();
2904    
2905          if (m_pServer && bInteractive) {          if (m_pServer && bInteractive) {
2906                  if (QMessageBox::question(this,                  if (QMessageBox::question(this,
2907                          QSAMPLER_TITLE ": " + tr("The backend's fate ..."),                          tr("The backend's fate ..."),
2908                          tr("You have the option to keep the sampler backend (LinuxSampler)\n"                          tr("You have the option to keep the sampler backend (LinuxSampler)\n"
2909                          "running in the background. The sampler would continue to work\n"                          "running in the background. The sampler would continue to work\n"
2910                          "according to your current sampler session and you could alter the\n"                          "according to your current sampler session and you could alter the\n"
2911                          "sampler session at any time by relaunching QSampler.\n\n"                          "sampler session at any time by relaunching QSampler.\n\n"
2912                          "Do you want LinuxSampler to stop?"),                          "Do you want LinuxSampler to stop?"),
2913                          QMessageBox::Yes | QMessageBox::No,                          QMessageBox::Yes | QMessageBox::No,
2914                          QMessageBox::Yes) == QMessageBox::No)                          QMessageBox::Yes) == QMessageBox::No) {
2915                  {                          m_bForceServerStop = false;
                         bForceServerStop = false;  
2916                  }                  }
2917          }          }
2918    
2919            bool bGraceWait = true;
2920    
2921          // And try to stop server.          // And try to stop server.
2922          if (m_pServer && bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2923                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2924                  if (m_pServer->state() == QProcess::Running) {                  if (m_pServer->state() == QProcess::Running) {
2925                  #if defined(WIN32)                  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
2926                          // Try harder...                          // Try harder...
2927                          m_pServer->kill();                          m_pServer->kill();
2928                  #else                  #else
2929                          // Try softly...                          // Try softly...
2930                          m_pServer->terminate();                          m_pServer->terminate();
2931                            bool bFinished = m_pServer->waitForFinished(QSAMPLER_TIMER_MSECS * 1000);
2932                            if (bFinished) bGraceWait = false;
2933                  #endif                  #endif
2934                  }                  }
2935          }       // Do final processing anyway.          }       // Do final processing anyway.
2936          else processServerExit();          else processServerExit();
2937    
2938          // Give it some time to terminate gracefully and stabilize...          // Give it some time to terminate gracefully and stabilize...
2939          QTime t;          if (bGraceWait) {
2940          t.start();                  QElapsedTimer timer;
2941          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                  timer.start();
2942                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  while (timer.elapsed() < QSAMPLER_TIMER_MSECS)
2943                            QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2944            }
2945  }  }
2946    
2947    
# Line 2912  void MainForm::processServerExit (void) Line 2963  void MainForm::processServerExit (void)
2963          if (m_pMessages)          if (m_pMessages)
2964                  m_pMessages->flushStdoutBuffer();                  m_pMessages->flushStdoutBuffer();
2965    
2966          if (m_pServer && bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2967                  if (m_pServer->state() != QProcess::NotRunning) {                  if (m_pServer->state() != QProcess::NotRunning) {
2968                          appendMessages(tr("Server is being forced..."));                          appendMessages(tr("Server is being forced..."));
2969                          // Force final server shutdown...                          // Force final server shutdown...
2970                          m_pServer->kill();                          m_pServer->kill();
2971                          // Give it some time to terminate gracefully and stabilize...                          // Give it some time to terminate gracefully and stabilize...
2972                          QTime t;                          QElapsedTimer timer;
2973                          t.start();                          timer.start();
2974                          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                          while (timer.elapsed() < QSAMPLER_TIMER_MSECS)
2975                                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2976                  }                  }
2977                  // Force final server shutdown...                  // Force final server shutdown...
# Line 2928  void MainForm::processServerExit (void) Line 2979  void MainForm::processServerExit (void)
2979                          tr("Server was stopped with exit status %1.")                          tr("Server was stopped with exit status %1.")
2980                          .arg(m_pServer->exitStatus()));                          .arg(m_pServer->exitStatus()));
2981                  delete m_pServer;                  delete m_pServer;
2982                  m_pServer = NULL;                  m_pServer = nullptr;
2983          }          }
2984    
2985          // Again, make status visible stable.          // Again, make status visible stable.
# Line 2937  void MainForm::processServerExit (void) Line 2988  void MainForm::processServerExit (void)
2988    
2989    
2990  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2991  // qsamplerMainForm -- Client stuff.  // QSampler::MainForm -- Client stuff.
2992    
2993  // The LSCP client callback procedure.  // The LSCP client callback procedure.
2994  lscp_status_t qsampler_client_callback ( lscp_client_t */*pClient*/,  lscp_status_t qsampler_client_callback ( lscp_client_t */*pClient*/,
2995          lscp_event_t event, const char *pchData, int cchData, void *pvData )          lscp_event_t event, const char *pchData, int cchData, void *pvData )
2996  {  {
2997          MainForm* pMainForm = (MainForm *) pvData;          MainForm* pMainForm = (MainForm *) pvData;
2998          if (pMainForm == NULL)          if (pMainForm == nullptr)
2999                  return LSCP_FAILED;                  return LSCP_FAILED;
3000    
3001          // ATTN: DO NOT EVER call any GUI code here,          // ATTN: DO NOT EVER call any GUI code here,
# Line 2958  lscp_status_t qsampler_client_callback ( Line 3009  lscp_status_t qsampler_client_callback (
3009    
3010    
3011  // Start our almighty client...  // Start our almighty client...
3012  bool MainForm::startClient (void)  bool MainForm::startClient (bool bReconnectOnly)
3013  {  {
3014          // Have it a setup?          // Have it a setup?
3015          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
3016                  return false;                  return false;
3017    
3018          // Aren't we already started, are we?          // Aren't we already started, are we?
# Line 2975  bool MainForm::startClient (void) Line 3026  bool MainForm::startClient (void)
3026          m_pClient = ::lscp_client_create(          m_pClient = ::lscp_client_create(
3027                  m_pOptions->sServerHost.toUtf8().constData(),                  m_pOptions->sServerHost.toUtf8().constData(),
3028                  m_pOptions->iServerPort, qsampler_client_callback, this);                  m_pOptions->iServerPort, qsampler_client_callback, this);
3029          if (m_pClient == NULL) {          if (m_pClient == nullptr) {
3030                  // Is this the first try?                  // Is this the first try?
3031                  // maybe we need to start a local server...                  // maybe we need to start a local server...
3032                  if ((m_pServer && m_pServer->state() == QProcess::Running)                  if ((m_pServer && m_pServer->state() == QProcess::Running)
3033                          || !m_pOptions->bServerStart) {                          || !m_pOptions->bServerStart || bReconnectOnly)
3034                          appendMessagesError(                  {
3035                                  tr("Could not connect to server as client.\n\nSorry."));                          // if this method is called from autoReconnectClient()
3036                            // then don't bother user with an error message...
3037                            if (!bReconnectOnly) {
3038                                    appendMessagesError(
3039                                            tr("Could not connect to server as client.\n\nSorry.")
3040                                    );
3041                            }
3042                  } else {                  } else {
3043                          startServer();                          startServer();
3044                  }                  }
# Line 2989  bool MainForm::startClient (void) Line 3046  bool MainForm::startClient (void)
3046                  stabilizeForm();                  stabilizeForm();
3047                  return false;                  return false;
3048          }          }
3049    
3050          // Just set receive timeout value, blindly.          // Just set receive timeout value, blindly.
3051          ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);          ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
3052          appendMessages(          appendMessages(
# Line 3044  bool MainForm::startClient (void) Line 3102  bool MainForm::startClient (void)
3102          if (!m_pOptions->sSessionFile.isEmpty()) {          if (!m_pOptions->sSessionFile.isEmpty()) {
3103                  // Just load the prabably startup session...                  // Just load the prabably startup session...
3104                  if (loadSessionFile(m_pOptions->sSessionFile)) {                  if (loadSessionFile(m_pOptions->sSessionFile)) {
3105                          m_pOptions->sSessionFile = QString::null;                          m_pOptions->sSessionFile = QString();
3106                          return true;                          return true;
3107                  }                  }
3108          }          }
# Line 3060  bool MainForm::startClient (void) Line 3118  bool MainForm::startClient (void)
3118  // Stop client...  // Stop client...
3119  void MainForm::stopClient (void)  void MainForm::stopClient (void)
3120  {  {
3121          if (m_pClient == NULL)          if (m_pClient == nullptr)
3122                  return;                  return;
3123    
3124          // Log prepare here.          // Log prepare here.
# Line 3092  void MainForm::stopClient (void) Line 3150  void MainForm::stopClient (void)
3150          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
3151          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);
3152          ::lscp_client_destroy(m_pClient);          ::lscp_client_destroy(m_pClient);
3153          m_pClient = NULL;          m_pClient = nullptr;
3154    
3155          // Hard-notify instrumnet and device configuration forms,          // Hard-notify instrumnet and device configuration forms,
3156          // if visible, that we're running out...          // if visible, that we're running out...
# Line 3109  void MainForm::stopClient (void) Line 3167  void MainForm::stopClient (void)
3167  }  }
3168    
3169    
3170    void MainForm::startAutoReconnectClient (void)
3171    {
3172            stopClient();
3173            appendMessages(tr("Trying to reconnect..."));
3174            QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(autoReconnectClient()));
3175    }
3176    
3177    
3178    void MainForm::autoReconnectClient (void)
3179    {
3180            const bool bSuccess = startClient(true);
3181            if (!bSuccess)
3182                    QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(autoReconnectClient()));
3183    }
3184    
3185    
3186  // Channel strip activation/selection.  // Channel strip activation/selection.
3187  void MainForm::activateStrip ( QMdiSubWindow *pMdiSubWindow )  void MainForm::activateStrip ( QMdiSubWindow *pMdiSubWindow )
3188  {  {
3189          ChannelStrip *pChannelStrip = NULL;          ChannelStrip *pChannelStrip = nullptr;
3190          if (pMdiSubWindow)          if (pMdiSubWindow)
3191                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
3192          if (pChannelStrip)          if (pChannelStrip)

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

  ViewVC Help
Powered by ViewVC