/[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 3758 by capela, Fri Mar 27 17:57:40 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    
 #ifdef HAVE_SIGNAL_H  
 #include <signal.h>  
 #endif  
   
73  #ifdef CONFIG_LIBGIG  #ifdef CONFIG_LIBGIG
74  #include <gig.h>  #include <gig.h>
75  #endif  #endif
# Line 91  static inline long lroundf ( float x ) Line 89  static inline long lroundf ( float x )
89    
90    
91  // All winsock apps needs this.  // All winsock apps needs this.
92  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
93  static WSADATA _wsaData;  static WSADATA _wsaData;
94    #undef HAVE_SIGNAL_H
95  #endif  #endif
96    
97    
# Line 103  static WSADATA _wsaData; Line 102  static WSADATA _wsaData;
102    
103  #include <QSocketNotifier>  #include <QSocketNotifier>
104    
105    #include <unistd.h>
106  #include <sys/types.h>  #include <sys/types.h>
107  #include <sys/socket.h>  #include <sys/socket.h>
   
108  #include <signal.h>  #include <signal.h>
109    
110  // File descriptor for SIGUSR1 notifier.  // File descriptor for SIGUSR1 notifier.
111  static int g_fdUsr1[2];  static int g_fdSigusr1[2] = { -1, -1 };
112    
113  // Unix SIGUSR1 signal handler.  // Unix SIGUSR1 signal handler.
114  static void qsampler_sigusr1_handler ( int /* signo */ )  static void qsampler_sigusr1_handler ( int /* signo */ )
115  {  {
116          char c = 1;          char c = 1;
117    
118          (::write(g_fdUsr1[0], &c, sizeof(c)) > 0);          (::write(g_fdSigusr1[0], &c, sizeof(c)) > 0);
119    }
120    
121    // File descriptor for SIGTERM notifier.
122    static int g_fdSigterm[2] = { -1, -1 };
123    
124    // Unix SIGTERM signal handler.
125    static void qsampler_sigterm_handler ( int /* signo */ )
126    {
127            char c = 1;
128    
129            (::write(g_fdSigterm[0], &c, sizeof(c)) > 0);
130  }  }
131    
132  #endif  // HAVE_SIGNAL_H  #endif  // HAVE_SIGNAL_H
133    
134    
135  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
136  // qsampler -- namespace  // QSampler -- namespace
137    
138    
139  namespace QSampler {  namespace QSampler {
# Line 143  namespace QSampler { Line 153  namespace QSampler {
153    
154    
155  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
156  // LscpEvent -- specialty for LSCP callback comunication.  // QSampler::LscpEvent -- specialty for LSCP callback comunication.
   
157    
158  class LscpEvent : public QEvent  class LscpEvent : public QEvent
159  {  {
# Line 159  public: Line 168  public:
168          }          }
169    
170          // Accessors.          // Accessors.
171          lscp_event_t event() { return m_event; }          lscp_event_t  event() { return m_event; }
172          QString&     data()  { return m_data;  }          const QString& data() { return m_data;  }
173    
174  private:  private:
175    
# Line 172  private: Line 181  private:
181    
182    
183  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
184  // qsamplerMainForm -- Main window form implementation.  // QSampler::Workspace -- Main window workspace (MDI Area) decl.
185    
186    class Workspace : public QMdiArea
187    {
188    public:
189    
190            Workspace(MainForm *pMainForm) : QMdiArea(pMainForm) {}
191    
192    protected:
193    
194            void resizeEvent(QResizeEvent *)
195            {
196                    MainForm *pMainForm = static_cast<MainForm *> (parentWidget());
197                    if (pMainForm)
198                            pMainForm->channelsArrangeAuto();
199            }
200    };
201    
202    
203    //-------------------------------------------------------------------------
204    // QSampler::MainForm -- Main window form implementation.
205    
206  // Kind of singleton reference.  // Kind of singleton reference.
207  MainForm* MainForm::g_pMainForm = NULL;  MainForm *MainForm::g_pMainForm = nullptr;
208    
209  MainForm::MainForm ( QWidget *pParent )  MainForm::MainForm ( QWidget *pParent )
210          : QMainWindow(pParent)          : QMainWindow(pParent)
# Line 186  MainForm::MainForm ( QWidget *pParent ) Line 215  MainForm::MainForm ( QWidget *pParent )
215          g_pMainForm = this;          g_pMainForm = this;
216    
217          // Initialize some pointer references.          // Initialize some pointer references.
218          m_pOptions = NULL;          m_pOptions = nullptr;
219    
220          // All child forms are to be created later, not earlier than setup.          // All child forms are to be created later, not earlier than setup.
221          m_pMessages = NULL;          m_pMessages = nullptr;
222          m_pInstrumentListForm = NULL;          m_pInstrumentListForm = nullptr;
223          m_pDeviceForm = NULL;          m_pDeviceForm = nullptr;
224    
225          // We'll start clean.          // We'll start clean.
226          m_iUntitled   = 0;          m_iUntitled   = 0;
227          m_iDirtySetup = 0;          m_iDirtySetup = 0;
228          m_iDirtyCount = 0;          m_iDirtyCount = 0;
229    
230          m_pServer = NULL;          m_pServer = nullptr;
231          m_pClient = NULL;          m_pClient = nullptr;
232    
233          m_iStartDelay = 0;          m_iStartDelay = 0;
234          m_iTimerDelay = 0;          m_iTimerDelay = 0;
# Line 214  MainForm::MainForm ( QWidget *pParent ) Line 243  MainForm::MainForm ( QWidget *pParent )
243          // LADISH Level 1 suport.          // LADISH Level 1 suport.
244    
245          // Initialize file descriptors for SIGUSR1 socket notifier.          // Initialize file descriptors for SIGUSR1 socket notifier.
246          ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdUsr1);          ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigusr1);
247          m_pUsr1Notifier          m_pSigusr1Notifier
248                  = new QSocketNotifier(g_fdUsr1[1], QSocketNotifier::Read, this);                  = new QSocketNotifier(g_fdSigusr1[1], QSocketNotifier::Read, this);
249    
250          QObject::connect(m_pUsr1Notifier,          QObject::connect(m_pSigusr1Notifier,
251                  SIGNAL(activated(int)),                  SIGNAL(activated(int)),
252                  SLOT(handle_sigusr1()));                  SLOT(handle_sigusr1()));
253    
254          // Install SIGUSR1 signal handler.          // Install SIGUSR1 signal handler.
255      struct sigaction usr1;          struct sigaction sigusr1;
256      usr1.sa_handler = qsampler_sigusr1_handler;          sigusr1.sa_handler = qsampler_sigusr1_handler;
257      sigemptyset(&usr1.sa_mask);          sigemptyset(&sigusr1.sa_mask);
258      usr1.sa_flags = 0;          sigusr1.sa_flags = 0;
259      usr1.sa_flags |= SA_RESTART;          sigusr1.sa_flags |= SA_RESTART;
260      ::sigaction(SIGUSR1, &usr1, NULL);          ::sigaction(SIGUSR1, &sigusr1, nullptr);
261    
262            // Initialize file descriptors for SIGTERM socket notifier.
263            ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigterm);
264            m_pSigtermNotifier
265                    = new QSocketNotifier(g_fdSigterm[1], QSocketNotifier::Read, this);
266    
267            QObject::connect(m_pSigtermNotifier,
268                    SIGNAL(activated(int)),
269                    SLOT(handle_sigterm()));
270    
271            // Install SIGTERM signal handler.
272            struct sigaction sigterm;
273            sigterm.sa_handler = qsampler_sigterm_handler;
274            sigemptyset(&sigterm.sa_mask);
275            sigterm.sa_flags = 0;
276            sigterm.sa_flags |= SA_RESTART;
277            ::sigaction(SIGTERM, &sigterm, nullptr);
278            ::sigaction(SIGQUIT, &sigterm, nullptr);
279    
280            // Ignore SIGHUP/SIGINT signals.
281            ::signal(SIGHUP, SIG_IGN);
282            ::signal(SIGINT, SIG_IGN);
283    
284  #else   // HAVE_SIGNAL_H  #else   // HAVE_SIGNAL_H
285    
286          m_pUsr1Notifier = NULL;          m_pSigusr1Notifier = nullptr;
287            m_pSigtermNotifier = nullptr;
288                    
289  #endif  // !HAVE_SIGNAL_H  #endif  // !HAVE_SIGNAL_H
290    
# Line 270  MainForm::MainForm ( QWidget *pParent ) Line 322  MainForm::MainForm ( QWidget *pParent )
322  #endif  #endif
323    
324          // Make it an MDI workspace.          // Make it an MDI workspace.
325          m_pWorkspace = new QMdiArea(this);          m_pWorkspace = new Workspace(this);
326          m_pWorkspace->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);          m_pWorkspace->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
327          m_pWorkspace->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);          m_pWorkspace->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
328          // Set the activation connection.          // Set the activation connection.
# Line 305  MainForm::MainForm ( QWidget *pParent ) Line 357  MainForm::MainForm ( QWidget *pParent )
357          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
358          statusBar()->addWidget(pLabel);          statusBar()->addWidget(pLabel);
359    
360  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
361          WSAStartup(MAKEWORD(1, 1), &_wsaData);          WSAStartup(MAKEWORD(1, 1), &_wsaData);
362  #endif  #endif
363    
# Line 406  MainForm::~MainForm() Line 458  MainForm::~MainForm()
458          // Do final processing anyway.          // Do final processing anyway.
459          processServerExit();          processServerExit();
460    
461  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
462          WSACleanup();          WSACleanup();
463  #endif  #endif
464    
465  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
466          if (m_pUsr1Notifier)          if (m_pSigusr1Notifier)
467                  delete m_pUsr1Notifier;                  delete m_pSigusr1Notifier;
468            if (m_pSigtermNotifier)
469                    delete m_pSigtermNotifier;
470  #endif  #endif
471    
472          // Finally drop any widgets around...          // Finally drop any widgets around...
# Line 441  MainForm::~MainForm() Line 495  MainForm::~MainForm()
495  #endif  #endif
496    
497          // Pseudo-singleton reference shut-down.          // Pseudo-singleton reference shut-down.
498          g_pMainForm = NULL;          g_pMainForm = nullptr;
499  }  }
500    
501    
# Line 578  void MainForm::closeEvent ( QCloseEvent Line 632  void MainForm::closeEvent ( QCloseEvent
632  void MainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )  void MainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
633  {  {
634          // Accept external drags only...          // Accept external drags only...
635          if (pDragEnterEvent->source() == NULL          if (pDragEnterEvent->source() == nullptr
636                  && pDragEnterEvent->mimeData()->hasUrls()) {                  && pDragEnterEvent->mimeData()->hasUrls()) {
637                  pDragEnterEvent->accept();                  pDragEnterEvent->accept();
638          } else {          } else {
# Line 602  void MainForm::dropEvent ( QDropEvent *p Line 656  void MainForm::dropEvent ( QDropEvent *p
656                          if (QFileInfo(sPath).exists()) {                          if (QFileInfo(sPath).exists()) {
657                                  // Try to create a new channel from instrument file...                                  // Try to create a new channel from instrument file...
658                                  Channel *pChannel = new Channel();                                  Channel *pChannel = new Channel();
659                                  if (pChannel == NULL)                                  if (pChannel == nullptr)
660                                          return;                                          return;
661                                  // Start setting the instrument filename...                                  // Start setting the instrument filename...
662                                  pChannel->setInstrument(sPath, 0);                                  pChannel->setInstrument(sPath, 0);
# Line 695  void MainForm::customEvent ( QEvent* pEv Line 749  void MainForm::customEvent ( QEvent* pEv
749  }  }
750    
751    
752  // Window resize event handler.  // LADISH Level 1 -- SIGUSR1 signal handler.
753  void MainForm::resizeEvent ( QResizeEvent * )  void MainForm::handle_sigusr1 (void)
754  {  {
755          if (m_pOptions->bAutoArrange)  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
756                  channelsArrange();  
757            char c;
758    
759            if (::read(g_fdSigusr1[1], &c, sizeof(c)) > 0)
760                    saveSession(false);
761    
762    #endif
763  }  }
764    
765    
766  // LADISH Level 1 -- SIGUSR1 signal handler.  void MainForm::handle_sigterm (void)
 void MainForm::handle_sigusr1 (void)  
767  {  {
768  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
769    
770          char c;          char c;
771    
772          if (::read(g_fdUsr1[1], &c, sizeof(c)) > 0)          if (::read(g_fdSigterm[1], &c, sizeof(c)) > 0)
773                  saveSession(false);                  close();
774    
775  #endif  #endif
776  }  }
# Line 742  void MainForm::contextMenuEvent( QContex Line 801  void MainForm::contextMenuEvent( QContex
801    
802    
803  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
804  // qsamplerMainForm -- Brainless public property accessors.  // QSampler::MainForm -- Brainless public property accessors.
805    
806  // The global options settings property.  // The global options settings property.
807  Options *MainForm::options (void) const  Options *MainForm::options (void) const
# Line 766  MainForm *MainForm::getInstance (void) Line 825  MainForm *MainForm::getInstance (void)
825    
826    
827  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
828  // qsamplerMainForm -- Session file stuff.  // QSampler::MainForm -- Session file stuff.
829    
830  // Format the displayable session filename.  // Format the displayable session filename.
831  QString MainForm::sessionName ( const QString& sFilename )  QString MainForm::sessionName ( const QString& sFilename )
# Line 795  bool MainForm::newSession (void) Line 854  bool MainForm::newSession (void)
854          m_iUntitled++;          m_iUntitled++;
855    
856          // Stabilize form.          // Stabilize form.
857          m_sFilename = QString::null;          m_sFilename = QString();
858          m_iDirtyCount = 0;          m_iDirtyCount = 0;
859          appendMessages(tr("New session: \"%1\".").arg(sessionName(m_sFilename)));          appendMessages(tr("New session: \"%1\".").arg(sessionName(m_sFilename)));
860          stabilizeForm();          stabilizeForm();
# Line 807  bool MainForm::newSession (void) Line 866  bool MainForm::newSession (void)
866  // Open an existing sampler session.  // Open an existing sampler session.
867  bool MainForm::openSession (void)  bool MainForm::openSession (void)
868  {  {
869          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
870                  return false;                  return false;
871    
872          // Ask for the filename to open...          // Ask for the filename to open...
873          QString sFilename = QFileDialog::getOpenFileName(this,          QString sFilename = QFileDialog::getOpenFileName(this,
874                  QSAMPLER_TITLE ": " + tr("Open Session"), // Caption.                  tr("Open Session"),                       // Caption.
875                  m_pOptions->sSessionDir,                  // Start here.                  m_pOptions->sSessionDir,                  // Start here.
876                  tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)                  tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)
877          );          );
# Line 833  bool MainForm::openSession (void) Line 892  bool MainForm::openSession (void)
892  // Save current sampler session with another name.  // Save current sampler session with another name.
893  bool MainForm::saveSession ( bool bPrompt )  bool MainForm::saveSession ( bool bPrompt )
894  {  {
895          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
896                  return false;                  return false;
897    
898          QString sFilename = m_sFilename;          QString sFilename = m_sFilename;
# Line 845  bool MainForm::saveSession ( bool bPromp Line 904  bool MainForm::saveSession ( bool bPromp
904                          sFilename = m_pOptions->sSessionDir;                          sFilename = m_pOptions->sSessionDir;
905                  // Prompt the guy...                  // Prompt the guy...
906                  sFilename = QFileDialog::getSaveFileName(this,                  sFilename = QFileDialog::getSaveFileName(this,
907                          QSAMPLER_TITLE ": " + tr("Save Session"), // Caption.                          tr("Save Session"),                       // Caption.
908                          sFilename,                                // Start here.                          sFilename,                                // Start here.
909                          tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)                          tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)
910                  );                  );
# Line 855  bool MainForm::saveSession ( bool bPromp Line 914  bool MainForm::saveSession ( bool bPromp
914                  // Enforce .lscp extension...                  // Enforce .lscp extension...
915                  if (QFileInfo(sFilename).suffix().isEmpty())                  if (QFileInfo(sFilename).suffix().isEmpty())
916                          sFilename += ".lscp";                          sFilename += ".lscp";
917            #if 0
918                  // Check if already exists...                  // Check if already exists...
919                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
920                          if (QMessageBox::warning(this,                          if (QMessageBox::warning(this,
921                                  QSAMPLER_TITLE ": " + tr("Warning"),                                  tr("Warning"),
922                                  tr("The file already exists:\n\n"                                  tr("The file already exists:\n\n"
923                                  "\"%1\"\n\n"                                  "\"%1\"\n\n"
924                                  "Do you want to replace it?")                                  "Do you want to replace it?")
# Line 867  bool MainForm::saveSession ( bool bPromp Line 927  bool MainForm::saveSession ( bool bPromp
927                                  == QMessageBox::No)                                  == QMessageBox::No)
928                                  return false;                                  return false;
929                  }                  }
930            #endif
931          }          }
932    
933          // Save it right away.          // Save it right away.
# Line 882  bool MainForm::closeSession ( bool bForc Line 943  bool MainForm::closeSession ( bool bForc
943          // Are we dirty enough to prompt it?          // Are we dirty enough to prompt it?
944          if (m_iDirtyCount > 0) {          if (m_iDirtyCount > 0) {
945                  switch (QMessageBox::warning(this,                  switch (QMessageBox::warning(this,
946                          QSAMPLER_TITLE ": " + tr("Warning"),                          tr("Warning"),
947                          tr("The current session has been changed:\n\n"                          tr("The current session has been changed:\n\n"
948                          "\"%1\"\n\n"                          "\"%1\"\n\n"
949                          "Do you want to save the changes?")                          "Do you want to save the changes?")
# Line 907  bool MainForm::closeSession ( bool bForc Line 968  bool MainForm::closeSession ( bool bForc
968                  m_pWorkspace->setUpdatesEnabled(false);                  m_pWorkspace->setUpdatesEnabled(false);
969                  const QList<QMdiSubWindow *>& wlist                  const QList<QMdiSubWindow *>& wlist
970                          = m_pWorkspace->subWindowList();                          = m_pWorkspace->subWindowList();
971                  const int iStripCount = wlist.count();                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
972                  for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                          ChannelStrip *pChannelStrip
973                          ChannelStrip *pChannelStrip = NULL;                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                         QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                         if (pMdiSubWindow)  
                                 pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
974                          if (pChannelStrip) {                          if (pChannelStrip) {
975                                  Channel *pChannel = pChannelStrip->channel();                                  Channel *pChannel = pChannelStrip->channel();
976                                  if (bForce && pChannel)                                  if (bForce && pChannel)
977                                          pChannel->removeChannel();                                          pChannel->removeChannel();
978                                  delete pChannelStrip;                                  delete pChannelStrip;
979                          }                          }
980                          if (pMdiSubWindow)                          delete pMdiSubWindow;
                                 delete pMdiSubWindow;  
981                  }                  }
982                  m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
983                  // We're now clean, for sure.                  // We're now clean, for sure.
# Line 934  bool MainForm::closeSession ( bool bForc Line 991  bool MainForm::closeSession ( bool bForc
991  // Load a session from specific file path.  // Load a session from specific file path.
992  bool MainForm::loadSessionFile ( const QString& sFilename )  bool MainForm::loadSessionFile ( const QString& sFilename )
993  {  {
994          if (m_pClient == NULL)          if (m_pClient == nullptr)
995                  return false;                  return false;
996    
997          // Open and read from real file.          // Open and read from real file.
# Line 1010  bool MainForm::loadSessionFile ( const Q Line 1067  bool MainForm::loadSessionFile ( const Q
1067  // Save current session to specific file path.  // Save current session to specific file path.
1068  bool MainForm::saveSessionFile ( const QString& sFilename )  bool MainForm::saveSessionFile ( const QString& sFilename )
1069  {  {
1070          if (m_pClient == NULL)          if (m_pClient == nullptr)
1071                  return false;                  return false;
1072    
1073          // Check whether server is apparently OK...          // Check whether server is apparently OK...
# Line 1034  bool MainForm::saveSessionFile ( const Q Line 1091  bool MainForm::saveSessionFile ( const Q
1091          // Write the file.          // Write the file.
1092          int iErrors = 0;          int iErrors = 0;
1093          QTextStream ts(&file);          QTextStream ts(&file);
1094          ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;          ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << Qt::endl;
1095          ts << "# " << tr("Version")          ts << "# " << tr("Version") << ": " CONFIG_BUILD_VERSION << Qt::endl;
1096          << ": " QSAMPLER_VERSION << endl;  //      ts << "# " << tr("Build") << ": " CONFIG_BUILD_DATE << Qt::endl;
1097          ts << "# " << tr("Build")          ts << "#"  << Qt::endl;
         << ": " __DATE__ " " __TIME__ << endl;  
         ts << "#"  << endl;  
1098          ts << "# " << tr("File")          ts << "# " << tr("File")
1099          << ": " << QFileInfo(sFilename).fileName() << endl;          << ": " << QFileInfo(sFilename).fileName() << Qt::endl;
1100          ts << "# " << tr("Date")          ts << "# " << tr("Date")
1101          << ": " << QDate::currentDate().toString("MMM dd yyyy")          << ": " << QDate::currentDate().toString("MMM dd yyyy")
1102          << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;          << " "  << QTime::currentTime().toString("hh:mm:ss") << Qt::endl;
1103          ts << "#"  << endl;          ts << "#"  << Qt::endl;
1104          ts << endl;          ts << Qt::endl;
1105    
1106          // It is assumed that this new kind of device+session file          // It is assumed that this new kind of device+session file
1107          // will be loaded from a complete initialized server...          // will be loaded from a complete initialized server...
1108          int *piDeviceIDs;          int *piDeviceIDs;
1109          int  iDevice;          int  i, iDevice;
1110          ts << "RESET" << endl;          ts << "RESET" << Qt::endl;
1111    
1112          // Audio device mapping.          // Audio device mapping.
1113          QMap<int, int> audioDeviceMap;          QMap<int, int> audioDeviceMap; iDevice = 0;
1114          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);
1115          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1116                  ts << endl;                  Device device(Device::Audio, piDeviceIDs[i]);
1117                  Device device(Device::Audio, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1118                    if (device.driverName().toUpper() == "PLUGIN")
1119                            continue;
1120                  // Audio device specification...                  // Audio device specification...
1121                    ts << Qt::endl;
1122                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1123                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << Qt::endl;
1124                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
1125                  DeviceParamMap::ConstIterator deviceParam;                  DeviceParamMap::ConstIterator deviceParam;
1126                  for (deviceParam = device.params().begin();                  for (deviceParam = device.params().begin();
# Line 1072  bool MainForm::saveSessionFile ( const Q Line 1130  bool MainForm::saveSessionFile ( const Q
1130                          if (param.value.isEmpty()) ts << "# ";                          if (param.value.isEmpty()) ts << "# ";
1131                          ts << " " << deviceParam.key() << "='" << param.value << "'";                          ts << " " << deviceParam.key() << "='" << param.value << "'";
1132                  }                  }
1133                  ts << endl;                  ts << Qt::endl;
1134                  // Audio channel parameters...                  // Audio channel parameters...
1135                  int iPort = 0;                  int iPort = 0;
1136                  QListIterator<DevicePort *> iter(device.ports());                  QListIterator<DevicePort *> iter(device.ports());
# Line 1086  bool MainForm::saveSessionFile ( const Q Line 1144  bool MainForm::saveSessionFile ( const Q
1144                                  if (param.fix || param.value.isEmpty()) ts << "# ";                                  if (param.fix || param.value.isEmpty()) ts << "# ";
1145                                  ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice                                  ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice
1146                                          << " " << iPort << " " << portParam.key()                                          << " " << iPort << " " << portParam.key()
1147                                          << "='" << param.value << "'" << endl;                                          << "='" << param.value << "'" << Qt::endl;
1148                          }                          }
1149                          iPort++;                          iPort++;
1150                  }                  }
1151                  // Audio device index/id mapping.                  // Audio device index/id mapping.
1152                  audioDeviceMap[device.deviceID()] = iDevice;                  audioDeviceMap.insert(device.deviceID(), iDevice++);
1153                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1154                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1155          }          }
1156    
1157          // MIDI device mapping.          // MIDI device mapping.
1158          QMap<int, int> midiDeviceMap;          QMap<int, int> midiDeviceMap; iDevice = 0;
1159          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);
1160          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1161                  ts << endl;                  Device device(Device::Midi, piDeviceIDs[i]);
1162                  Device device(Device::Midi, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1163                    if (device.driverName().toUpper() == "PLUGIN")
1164                            continue;
1165                  // MIDI device specification...                  // MIDI device specification...
1166                    ts << Qt::endl;
1167                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1168                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << Qt::endl;
1169                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
1170                  DeviceParamMap::ConstIterator deviceParam;                  DeviceParamMap::ConstIterator deviceParam;
1171                  for (deviceParam = device.params().begin();                  for (deviceParam = device.params().begin();
# Line 1114  bool MainForm::saveSessionFile ( const Q Line 1175  bool MainForm::saveSessionFile ( const Q
1175                          if (param.value.isEmpty()) ts << "# ";                          if (param.value.isEmpty()) ts << "# ";
1176                          ts << " " << deviceParam.key() << "='" << param.value << "'";                          ts << " " << deviceParam.key() << "='" << param.value << "'";
1177                  }                  }
1178                  ts << endl;                  ts << Qt::endl;
1179                  // MIDI port parameters...                  // MIDI port parameters...
1180                  int iPort = 0;                  int iPort = 0;
1181                  QListIterator<DevicePort *> iter(device.ports());                  QListIterator<DevicePort *> iter(device.ports());
# Line 1128  bool MainForm::saveSessionFile ( const Q Line 1189  bool MainForm::saveSessionFile ( const Q
1189                                  if (param.fix || param.value.isEmpty()) ts << "# ";                                  if (param.fix || param.value.isEmpty()) ts << "# ";
1190                                  ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice                                  ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice
1191                                  << " " << iPort << " " << portParam.key()                                  << " " << iPort << " " << portParam.key()
1192                                  << "='" << param.value << "'" << endl;                                  << "='" << param.value << "'" << Qt::endl;
1193                          }                          }
1194                          iPort++;                          iPort++;
1195                  }                  }
1196                  // MIDI device index/id mapping.                  // MIDI device index/id mapping.
1197                  midiDeviceMap[device.deviceID()] = iDevice;                  midiDeviceMap.insert(device.deviceID(), iDevice++);
1198                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1199                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1200          }          }
1201          ts << endl;          ts << Qt::endl;
1202    
1203  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
1204          // MIDI instrument mapping...          // MIDI instrument mapping...
# Line 1150  bool MainForm::saveSessionFile ( const Q Line 1211  bool MainForm::saveSessionFile ( const Q
1211                  ts << "# " << tr("MIDI instrument map") << " " << iMap;                  ts << "# " << tr("MIDI instrument map") << " " << iMap;
1212                  if (pszMapName)                  if (pszMapName)
1213                          ts << " - " << pszMapName;                          ts << " - " << pszMapName;
1214                  ts << endl;                  ts << Qt::endl;
1215                  ts << "ADD MIDI_INSTRUMENT_MAP";                  ts << "ADD MIDI_INSTRUMENT_MAP";
1216                  if (pszMapName)                  if (pszMapName)
1217                          ts << " '" << pszMapName << "'";                          ts << " '" << pszMapName << "'";
1218                  ts << endl;                  ts << Qt::endl;
1219                  // MIDI instrument mapping...                  // MIDI instrument mapping...
1220                  lscp_midi_instrument_t *pInstrs                  lscp_midi_instrument_t *pInstrs
1221                          = ::lscp_list_midi_instruments(m_pClient, iMidiMap);                          = ::lscp_list_midi_instruments(m_pClient, iMidiMap);
# Line 1185  bool MainForm::saveSessionFile ( const Q Line 1246  bool MainForm::saveSessionFile ( const Q
1246                                  }                                  }
1247                                  if (pInstrInfo->name)                                  if (pInstrInfo->name)
1248                                          ts << " '" << pInstrInfo->name << "'";                                          ts << " '" << pInstrInfo->name << "'";
1249                                  ts << endl;                                  ts << Qt::endl;
1250                          }       // Check for errors...                          }       // Check for errors...
1251                          else if (::lscp_client_get_errno(m_pClient)) {                          else if (::lscp_client_get_errno(m_pClient)) {
1252                                  appendMessagesClient("lscp_get_midi_instrument_info");                                  appendMessagesClient("lscp_get_midi_instrument_info");
# Line 1194  bool MainForm::saveSessionFile ( const Q Line 1255  bool MainForm::saveSessionFile ( const Q
1255                          // Try to keep it snappy :)                          // Try to keep it snappy :)
1256                          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1257                  }                  }
1258                  ts << endl;                  ts << Qt::endl;
1259                  // Check for errors...                  // Check for errors...
1260                  if (pInstrs == NULL && ::lscp_client_get_errno(m_pClient)) {                  if (pInstrs == nullptr && ::lscp_client_get_errno(m_pClient)) {
1261                          appendMessagesClient("lscp_list_midi_instruments");                          appendMessagesClient("lscp_list_midi_instruments");
1262                          iErrors++;                          iErrors++;
1263                  }                  }
1264                  // MIDI strument index/id mapping.                  // MIDI strument index/id mapping.
1265                  midiInstrumentMap[iMidiMap] = iMap;                  midiInstrumentMap.insert(iMidiMap, iMap);
1266          }          }
1267          // Check for errors...          // Check for errors...
1268          if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {          if (piMaps == nullptr && ::lscp_client_get_errno(m_pClient)) {
1269                  appendMessagesClient("lscp_list_midi_instrument_maps");                  appendMessagesClient("lscp_list_midi_instrument_maps");
1270                  iErrors++;                  iErrors++;
1271          }          }
1272  #endif  // CONFIG_MIDI_INSTRUMENT  #endif  // CONFIG_MIDI_INSTRUMENT
1273    
1274          // Sampler channel mapping.          // Sampler channel mapping...
1275            int iChannelID = 0;
1276          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
1277                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
1278          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
1279          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
1280                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
1281                  if (pChannelStrip) {                  if (pChannelStrip) {
1282                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1283                          if (pChannel) {                          if (pChannel) {
1284                                  const int iChannelID = pChannel->channelID();                                  // Avoid "artifial" plug-in devices...
1285                                  ts << "# " << tr("Channel") << " " << iChannelID << endl;                                  const int iAudioDevice = pChannel->audioDevice();
1286                                  ts << "ADD CHANNEL" << endl;                                  if (!audioDeviceMap.contains(iAudioDevice))
1287                                            continue;
1288                                    const int iMidiDevice = pChannel->midiDevice();
1289                                    if (!midiDeviceMap.contains(iMidiDevice))
1290                                            continue;
1291                                    // Go for regular, canonical devices...
1292                                    ts << "# " << tr("Channel") << " " << iChannelID << Qt::endl;
1293                                    ts << "ADD CHANNEL" << Qt::endl;
1294                                  if (audioDeviceMap.isEmpty()) {                                  if (audioDeviceMap.isEmpty()) {
1295                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannelID                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannelID
1296                                                  << " " << pChannel->audioDriver() << endl;                                                  << " " << pChannel->audioDriver() << Qt::endl;
1297                                  } else {                                  } else {
1298                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannelID                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannelID
1299                                                  << " " << audioDeviceMap[pChannel->audioDevice()] << endl;                                                  << " " << audioDeviceMap.value(iAudioDevice) << Qt::endl;
1300                                  }                                  }
1301                                  if (midiDeviceMap.isEmpty()) {                                  if (midiDeviceMap.isEmpty()) {
1302                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID
1303                                                  << " " << pChannel->midiDriver() << endl;                                                  << " " << pChannel->midiDriver() << Qt::endl;
1304                                  } else {                                  } else {
1305                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannelID                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannelID
1306                                                  << " " << midiDeviceMap[pChannel->midiDevice()] << endl;                                                  << " " << midiDeviceMap.value(iMidiDevice) << Qt::endl;
1307                                  }                                  }
1308                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID
1309                                          << " " << pChannel->midiPort() << endl;                                          << " " << pChannel->midiPort() << Qt::endl;
1310                                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannelID << " ";                                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannelID << " ";
1311                                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)                                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
1312                                          ts << "ALL";                                          ts << "ALL";
1313                                  else                                  else
1314                                          ts << pChannel->midiChannel();                                          ts << pChannel->midiChannel();
1315                                  ts << endl;                                  ts << Qt::endl;
1316                                  ts << "LOAD ENGINE " << pChannel->engineName()                                  ts << "LOAD ENGINE " << pChannel->engineName()
1317                                          << " " << iChannelID << endl;                                          << " " << iChannelID << Qt::endl;
1318                                  if (pChannel->instrumentStatus() < 100) ts << "# ";                                  if (pChannel->instrumentStatus() < 100) ts << "# ";
1319                                  ts << "LOAD INSTRUMENT NON_MODAL '"                                  ts << "LOAD INSTRUMENT NON_MODAL '"
1320                                          << pChannel->instrumentFile() << "' "                                          << pChannel->instrumentFile() << "' "
1321                                          << pChannel->instrumentNr() << " " << iChannelID << endl;                                          << pChannel->instrumentNr() << " " << iChannelID << Qt::endl;
1322                                  ChannelRoutingMap::ConstIterator audioRoute;                                  ChannelRoutingMap::ConstIterator audioRoute;
1323                                  for (audioRoute = pChannel->audioRouting().begin();                                  for (audioRoute = pChannel->audioRouting().begin();
1324                                                  audioRoute != pChannel->audioRouting().end();                                                  audioRoute != pChannel->audioRouting().end();
1325                                                          ++audioRoute) {                                                          ++audioRoute) {
1326                                          ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannelID                                          ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannelID
1327                                                  << " " << audioRoute.key()                                                  << " " << audioRoute.key()
1328                                                  << " " << audioRoute.value() << endl;                                                  << " " << audioRoute.value() << Qt::endl;
1329                                  }                                  }
1330                                  ts << "SET CHANNEL VOLUME " << iChannelID                                  ts << "SET CHANNEL VOLUME " << iChannelID
1331                                          << " " << pChannel->volume() << endl;                                          << " " << pChannel->volume() << Qt::endl;
1332                                  if (pChannel->channelMute())                                  if (pChannel->channelMute())
1333                                          ts << "SET CHANNEL MUTE " << iChannelID << " 1" << endl;                                          ts << "SET CHANNEL MUTE " << iChannelID << " 1" << Qt::endl;
1334                                  if (pChannel->channelSolo())                                  if (pChannel->channelSolo())
1335                                          ts << "SET CHANNEL SOLO " << iChannelID << " 1" << endl;                                          ts << "SET CHANNEL SOLO " << iChannelID << " 1" << Qt::endl;
1336                          #ifdef CONFIG_MIDI_INSTRUMENT                          #ifdef CONFIG_MIDI_INSTRUMENT
1337                                  if (pChannel->midiMap() >= 0) {                                  const int iMidiMap = pChannel->midiMap();
1338                                    if (midiInstrumentMap.contains(iMidiMap)) {
1339                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannelID                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannelID
1340                                                  << " " << midiInstrumentMap[pChannel->midiMap()] << endl;                                                  << " " << midiInstrumentMap.value(iMidiMap) << Qt::endl;
1341                                  }                                  }
1342                          #endif                          #endif
1343                          #ifdef CONFIG_FXSEND                          #ifdef CONFIG_FXSEND
# Line 1285  bool MainForm::saveSessionFile ( const Q Line 1352  bool MainForm::saveSessionFile ( const Q
1352                                                          << " " << pFxSendInfo->midi_controller;                                                          << " " << pFxSendInfo->midi_controller;
1353                                                  if (pFxSendInfo->name)                                                  if (pFxSendInfo->name)
1354                                                          ts << " '" << pFxSendInfo->name << "'";                                                          ts << " '" << pFxSendInfo->name << "'";
1355                                                  ts << endl;                                                  ts << Qt::endl;
1356                                                  int *piRouting = pFxSendInfo->audio_routing;                                                  int *piRouting = pFxSendInfo->audio_routing;
1357                                                  for (int iAudioSrc = 0;                                                  for (int iAudioSrc = 0;
1358                                                                  piRouting && piRouting[iAudioSrc] >= 0;                                                                  piRouting && piRouting[iAudioSrc] >= 0;
# Line 1294  bool MainForm::saveSessionFile ( const Q Line 1361  bool MainForm::saveSessionFile ( const Q
1361                                                                  << iChannelID                                                                  << iChannelID
1362                                                                  << " " << iFxSend                                                                  << " " << iFxSend
1363                                                                  << " " << iAudioSrc                                                                  << " " << iAudioSrc
1364                                                                  << " " << piRouting[iAudioSrc] << endl;                                                                  << " " << piRouting[iAudioSrc] << Qt::endl;
1365                                                  }                                                  }
1366                                          #ifdef CONFIG_FXSEND_LEVEL                                          #ifdef CONFIG_FXSEND_LEVEL
1367                                                  ts << "SET FX_SEND LEVEL " << iChannelID                                                  ts << "SET FX_SEND LEVEL " << iChannelID
1368                                                          << " " << iFxSend                                                          << " " << iFxSend
1369                                                          << " " << pFxSendInfo->level << endl;                                                          << " " << pFxSendInfo->level << Qt::endl;
1370                                          #endif                                          #endif
1371                                          }       // Check for errors...                                          }       // Check for errors...
1372                                          else if (::lscp_client_get_errno(m_pClient)) {                                          else if (::lscp_client_get_errno(m_pClient)) {
# Line 1308  bool MainForm::saveSessionFile ( const Q Line 1375  bool MainForm::saveSessionFile ( const Q
1375                                          }                                          }
1376                                  }                                  }
1377                          #endif                          #endif
1378                                  ts << endl;                                  ts << Qt::endl;
1379                                    // Go for next channel...
1380                                    ++iChannelID;
1381                          }                          }
1382                  }                  }
1383                  // Try to keep it snappy :)                  // Try to keep it snappy :)
# Line 1316  bool MainForm::saveSessionFile ( const Q Line 1385  bool MainForm::saveSessionFile ( const Q
1385          }          }
1386    
1387  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
1388          ts << "# " << tr("Global volume level") << endl;          ts << "# " << tr("Global volume level") << Qt::endl;
1389          ts << "SET VOLUME " << ::lscp_get_volume(m_pClient) << endl;          ts << "SET VOLUME " << ::lscp_get_volume(m_pClient) << Qt::endl;
1390          ts << endl;          ts << Qt::endl;
1391  #endif  #endif
1392    
1393          // Ok. we've wrote it.          // Ok. we've wrote it.
# Line 1360  void MainForm::sessionDirty (void) Line 1429  void MainForm::sessionDirty (void)
1429    
1430    
1431  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1432  // qsamplerMainForm -- File Action slots.  // QSampler::MainForm -- File Action slots.
1433    
1434  // Create a new sampler session.  // Create a new sampler session.
1435  void MainForm::fileNew (void)  void MainForm::fileNew (void)
# Line 1414  void MainForm::fileSaveAs (void) Line 1483  void MainForm::fileSaveAs (void)
1483  // Reset the sampler instance.  // Reset the sampler instance.
1484  void MainForm::fileReset (void)  void MainForm::fileReset (void)
1485  {  {
1486          if (m_pClient == NULL)          if (m_pClient == nullptr)
1487                  return;                  return;
1488    
1489          // Ask user whether he/she want's an internal sampler reset...          // Ask user whether he/she want's an internal sampler reset...
1490          if (m_pOptions && m_pOptions->bConfirmReset) {          if (m_pOptions && m_pOptions->bConfirmReset) {
1491                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");                  const QString& sTitle = tr("Warning");
1492                  const QString& sText = tr(                  const QString& sText = tr(
1493                          "Resetting the sampler instance will close\n"                          "Resetting the sampler instance will close\n"
1494                          "all device and channel configurations.\n\n"                          "all device and channel configurations.\n\n"
# Line 1470  void MainForm::fileReset (void) Line 1539  void MainForm::fileReset (void)
1539  // Restart the client/server instance.  // Restart the client/server instance.
1540  void MainForm::fileRestart (void)  void MainForm::fileRestart (void)
1541  {  {
1542          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1543                  return;                  return;
1544    
1545          bool bRestart = true;          bool bRestart = true;
# Line 1478  void MainForm::fileRestart (void) Line 1547  void MainForm::fileRestart (void)
1547          // Ask user whether he/she want's a complete restart...          // Ask user whether he/she want's a complete restart...
1548          // (if we're currently up and running)          // (if we're currently up and running)
1549          if (m_pOptions && m_pOptions->bConfirmRestart) {          if (m_pOptions && m_pOptions->bConfirmRestart) {
1550                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");                  const QString& sTitle = tr("Warning");
1551                  const QString& sText = tr(                  const QString& sText = tr(
1552                          "New settings will be effective after\n"                          "New settings will be effective after\n"
1553                          "restarting the client/server connection.\n\n"                          "restarting the client/server connection.\n\n"
# Line 1526  void MainForm::fileExit (void) Line 1595  void MainForm::fileExit (void)
1595    
1596    
1597  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1598  // qsamplerMainForm -- Edit Action slots.  // QSampler::MainForm -- Edit Action slots.
1599    
1600  // Add a new sampler channel.  // Add a new sampler channel.
1601  void MainForm::editAddChannel (void)  void MainForm::editAddChannel (void)
# Line 1538  void MainForm::editAddChannel (void) Line 1607  void MainForm::editAddChannel (void)
1607    
1608  void MainForm::addChannelStrip (void)  void MainForm::addChannelStrip (void)
1609  {  {
1610          if (m_pClient == NULL)          if (m_pClient == nullptr)
1611                  return;                  return;
1612    
1613          // Just create the channel instance...          // Just create the channel instance...
1614          Channel *pChannel = new Channel();          Channel *pChannel = new Channel();
1615          if (pChannel == NULL)          if (pChannel == nullptr)
1616                  return;                  return;
1617    
1618          // Before we show it up, may be we'll          // Before we show it up, may be we'll
# Line 1561  void MainForm::addChannelStrip (void) Line 1630  void MainForm::addChannelStrip (void)
1630          }          }
1631    
1632          // Do we auto-arrange?          // Do we auto-arrange?
1633          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
1634    
1635          // Make that an overall update.          // Make that an overall update.
1636          m_iDirtyCount++;          m_iDirtyCount++;
# Line 1580  void MainForm::editRemoveChannel (void) Line 1648  void MainForm::editRemoveChannel (void)
1648    
1649  void MainForm::removeChannelStrip (void)  void MainForm::removeChannelStrip (void)
1650  {  {
1651          if (m_pClient == NULL)          if (m_pClient == nullptr)
1652                  return;                  return;
1653    
1654          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1655          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1656                  return;                  return;
1657    
1658          Channel *pChannel = pChannelStrip->channel();          Channel *pChannel = pChannelStrip->channel();
1659          if (pChannel == NULL)          if (pChannel == nullptr)
1660                  return;                  return;
1661    
1662          // Prompt user if he/she's sure about this...          // Prompt user if he/she's sure about this...
1663          if (m_pOptions && m_pOptions->bConfirmRemove) {          if (m_pOptions && m_pOptions->bConfirmRemove) {
1664                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");                  const QString& sTitle = tr("Warning");
1665                  const QString& sText = tr(                  const QString& sText = tr(
1666                          "About to remove channel:\n\n"                          "About to remove channel:\n\n"
1667                          "%1\n\n"                          "%1\n\n"
# Line 1636  void MainForm::removeChannelStrip (void) Line 1704  void MainForm::removeChannelStrip (void)
1704  // Setup current sampler channel.  // Setup current sampler channel.
1705  void MainForm::editSetupChannel (void)  void MainForm::editSetupChannel (void)
1706  {  {
1707          if (m_pClient == NULL)          if (m_pClient == nullptr)
1708                  return;                  return;
1709    
1710          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1711          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1712                  return;                  return;
1713    
1714          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1651  void MainForm::editSetupChannel (void) Line 1719  void MainForm::editSetupChannel (void)
1719  // Edit current sampler channel.  // Edit current sampler channel.
1720  void MainForm::editEditChannel (void)  void MainForm::editEditChannel (void)
1721  {  {
1722          if (m_pClient == NULL)          if (m_pClient == nullptr)
1723                  return;                  return;
1724    
1725          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1726          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1727                  return;                  return;
1728    
1729          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1666  void MainForm::editEditChannel (void) Line 1734  void MainForm::editEditChannel (void)
1734  // Reset current sampler channel.  // Reset current sampler channel.
1735  void MainForm::editResetChannel (void)  void MainForm::editResetChannel (void)
1736  {  {
1737          if (m_pClient == NULL)          if (m_pClient == nullptr)
1738                  return;                  return;
1739    
1740          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1741          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1742                  return;                  return;
1743    
1744          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1681  void MainForm::editResetChannel (void) Line 1749  void MainForm::editResetChannel (void)
1749  // Reset all sampler channels.  // Reset all sampler channels.
1750  void MainForm::editResetAllChannels (void)  void MainForm::editResetAllChannels (void)
1751  {  {
1752          if (m_pClient == NULL)          if (m_pClient == nullptr)
1753                  return;                  return;
1754    
1755          // Invoque the channel strip procedure,          // Invoque the channel strip procedure,
# Line 1689  void MainForm::editResetAllChannels (voi Line 1757  void MainForm::editResetAllChannels (voi
1757          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1758          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
1759                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
1760          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
1761          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
1762                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
1763                  if (pChannelStrip)                  if (pChannelStrip)
1764                          pChannelStrip->channelReset();                          pChannelStrip->channelReset();
1765          }          }
# Line 1703  void MainForm::editResetAllChannels (voi Line 1768  void MainForm::editResetAllChannels (voi
1768    
1769    
1770  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1771  // qsamplerMainForm -- View Action slots.  // QSampler::MainForm -- View Action slots.
1772    
1773  // Show/hide the main program window menubar.  // Show/hide the main program window menubar.
1774  void MainForm::viewMenubar ( bool bOn )  void MainForm::viewMenubar ( bool bOn )
# Line 1753  void MainForm::viewMessages ( bool bOn ) Line 1818  void MainForm::viewMessages ( bool bOn )
1818  // Show/hide the MIDI instrument list-view form.  // Show/hide the MIDI instrument list-view form.
1819  void MainForm::viewInstruments (void)  void MainForm::viewInstruments (void)
1820  {  {
1821          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1822                  return;                  return;
1823    
1824          if (m_pInstrumentListForm) {          if (m_pInstrumentListForm) {
# Line 1772  void MainForm::viewInstruments (void) Line 1837  void MainForm::viewInstruments (void)
1837  // Show/hide the device configurator form.  // Show/hide the device configurator form.
1838  void MainForm::viewDevices (void)  void MainForm::viewDevices (void)
1839  {  {
1840          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1841                  return;                  return;
1842    
1843          if (m_pDeviceForm) {          if (m_pDeviceForm) {
# Line 1791  void MainForm::viewDevices (void) Line 1856  void MainForm::viewDevices (void)
1856  // Show options dialog.  // Show options dialog.
1857  void MainForm::viewOptions (void)  void MainForm::viewOptions (void)
1858  {  {
1859          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1860                  return;                  return;
1861    
1862          OptionsForm* pOptionsForm = new OptionsForm(this);          OptionsForm* pOptionsForm = new OptionsForm(this);
# Line 1833  void MainForm::viewOptions (void) Line 1898  void MainForm::viewOptions (void)
1898                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)     ||                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)     ||
1899                                  (iOldBaseFontSize   !=  m_pOptions->iBaseFontSize)) {                                  (iOldBaseFontSize   !=  m_pOptions->iBaseFontSize)) {
1900                                  QMessageBox::information(this,                                  QMessageBox::information(this,
1901                                          QSAMPLER_TITLE ": " + tr("Information"),                                          tr("Information"),
1902                                          tr("Some settings may be only effective\n"                                          tr("Some settings may be only effective\n"
1903                                          "next time you start this program."));                                          "next time you start this program."));
1904                                  updateMessagesCapture();                                  updateMessagesCapture();
# Line 1884  void MainForm::viewOptions (void) Line 1949  void MainForm::viewOptions (void)
1949    
1950    
1951  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1952  // qsamplerMainForm -- Channels action slots.  // QSampler::MainForm -- Channels action slots.
1953    
1954  // Arrange channel strips.  // Arrange channel strips.
1955  void MainForm::channelsArrange (void)  void MainForm::channelsArrange (void)
# Line 1897  void MainForm::channelsArrange (void) Line 1962  void MainForm::channelsArrange (void)
1962    
1963          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1964          int y = 0;          int y = 0;
1965          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
1966          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  pMdiSubWindow->adjustSize();
1967                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);                  const QRect& frameRect
1968                  if (pMdiSubWindow) {                          = pMdiSubWindow->frameGeometry();
1969                          pMdiSubWindow->adjustSize();                  int w = m_pWorkspace->width();
1970                          int iWidth = m_pWorkspace->width();                  if (w < frameRect.width())
1971                          if (iWidth < pMdiSubWindow->width())                          w = frameRect.width();
1972                                  iWidth = pMdiSubWindow->width();                  const int h = frameRect.height();
1973                          const int iHeight = pMdiSubWindow->frameGeometry().height();                  pMdiSubWindow->setGeometry(0, y, w, h);
1974                          pMdiSubWindow->setGeometry(0, y, iWidth, iHeight);                  y += h;
                         y += iHeight;  
                 }  
1975          }          }
1976          m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
1977    
# Line 1919  void MainForm::channelsArrange (void) Line 1982  void MainForm::channelsArrange (void)
1982  // Auto-arrange channel strips.  // Auto-arrange channel strips.
1983  void MainForm::channelsAutoArrange ( bool bOn )  void MainForm::channelsAutoArrange ( bool bOn )
1984  {  {
1985          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1986                  return;                  return;
1987    
1988          // Toggle the auto-arrange flag.          // Toggle the auto-arrange flag.
1989          m_pOptions->bAutoArrange = bOn;          m_pOptions->bAutoArrange = bOn;
1990    
1991          // If on, update whole workspace...          // If on, update whole workspace...
1992          if (m_pOptions->bAutoArrange)          channelsArrangeAuto();
1993    }
1994    
1995    
1996    void MainForm::channelsArrangeAuto (void)
1997    {
1998            if (m_pOptions && m_pOptions->bAutoArrange)
1999                  channelsArrange();                  channelsArrange();
2000  }  }
2001    
2002    
2003  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2004  // qsamplerMainForm -- Help Action slots.  // QSampler::MainForm -- Help Action slots.
2005    
2006  // Show information about the Qt toolkit.  // Show information about the Qt toolkit.
2007  void MainForm::helpAboutQt (void)  void MainForm::helpAboutQt (void)
# Line 1944  void MainForm::helpAboutQt (void) Line 2013  void MainForm::helpAboutQt (void)
2013  // Show information about application program.  // Show information about application program.
2014  void MainForm::helpAbout (void)  void MainForm::helpAbout (void)
2015  {  {
2016          // 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";  
2017  #ifdef CONFIG_DEBUG  #ifdef CONFIG_DEBUG
2018          sText += "<small><font color=\"red\">";          list << tr("Debugging option enabled.");
         sText += tr("Debugging option enabled.");  
         sText += "</font></small><br />";  
2019  #endif  #endif
2020  #ifndef CONFIG_LIBGIG  #ifndef CONFIG_LIBGIG
2021          sText += "<small><font color=\"red\">";          list << tr("GIG (libgig) file support disabled.");
         sText += tr("GIG (libgig) file support disabled.");  
         sText += "</font></small><br />";  
2022  #endif  #endif
2023  #ifndef CONFIG_INSTRUMENT_NAME  #ifndef CONFIG_INSTRUMENT_NAME
2024          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 />";  
2025  #endif  #endif
2026  #ifndef CONFIG_MUTE_SOLO  #ifndef CONFIG_MUTE_SOLO
2027          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 />";  
2028  #endif  #endif
2029  #ifndef CONFIG_AUDIO_ROUTING  #ifndef CONFIG_AUDIO_ROUTING
2030          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 />";  
2031  #endif  #endif
2032  #ifndef CONFIG_FXSEND  #ifndef CONFIG_FXSEND
2033          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 />";  
2034  #endif  #endif
2035  #ifndef CONFIG_VOLUME  #ifndef CONFIG_VOLUME
2036          sText += "<small><font color=\"red\">";          list << tr("Global volume support disabled.");
         sText += tr("Global volume support disabled.");  
         sText += "</font></small><br />";  
2037  #endif  #endif
2038  #ifndef CONFIG_MIDI_INSTRUMENT  #ifndef CONFIG_MIDI_INSTRUMENT
2039          sText += "<small><font color=\"red\">";          list << tr("MIDI instrument mapping support disabled.");
         sText += tr("MIDI instrument mapping support disabled.");  
         sText += "</font></small><br />";  
2040  #endif  #endif
2041  #ifndef CONFIG_EDIT_INSTRUMENT  #ifndef CONFIG_EDIT_INSTRUMENT
2042          sText += "<small><font color=\"red\">";          list << tr("Instrument editing support disabled.");
         sText += tr("Instrument editing support disabled.");  
         sText += "</font></small><br />";  
2043  #endif  #endif
2044  #ifndef CONFIG_EVENT_CHANNEL_MIDI  #ifndef CONFIG_EVENT_CHANNEL_MIDI
2045          sText += "<small><font color=\"red\">";          list << tr("Channel MIDI event support disabled.");
         sText += tr("Channel MIDI event support disabled.");  
         sText += "</font></small><br />";  
2046  #endif  #endif
2047  #ifndef CONFIG_EVENT_DEVICE_MIDI  #ifndef CONFIG_EVENT_DEVICE_MIDI
2048          sText += "<small><font color=\"red\">";          list << tr("Device MIDI event support disabled.");
         sText += tr("Device MIDI event support disabled.");  
         sText += "</font></small><br />";  
2049  #endif  #endif
2050  #ifndef CONFIG_MAX_VOICES  #ifndef CONFIG_MAX_VOICES
2051          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 />";  
2052  #endif  #endif
2053    
2054            // Stuff the about box text...
2055            QString sText = "<p>\n";
2056            sText += "<b>" QSAMPLER_TITLE " - " + tr(QSAMPLER_SUBTITLE) + "</b><br />\n";
2057            sText += "<br />\n";
2058            sText += tr("Version") + ": <b>" CONFIG_BUILD_VERSION "</b><br />\n";
2059    //      sText += "<small>" + tr("Build") + ": " CONFIG_BUILD_DATE "</small><br />\n";
2060            if (!list.isEmpty()) {
2061                    sText += "<small><font color=\"red\">";
2062                    sText += list.join("<br />\n");
2063                    sText += "</font></small>";
2064            }
2065          sText += "<br />\n";          sText += "<br />\n";
2066          sText += tr("Using") + ": ";          sText += tr("Using") + ": ";
2067          sText += ::lscp_client_package();          sText += ::lscp_client_package();
# Line 2034  void MainForm::helpAbout (void) Line 2086  void MainForm::helpAbout (void)
2086          sText += "</small>";          sText += "</small>";
2087          sText += "</p>\n";          sText += "</p>\n";
2088    
2089          QMessageBox::about(this, tr("About") + " " QSAMPLER_TITLE, sText);          QMessageBox::about(this, tr("About"), sText);
2090  }  }
2091    
2092    
2093  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2094  // qsamplerMainForm -- Main window stabilization.  // QSampler::MainForm -- Main window stabilization.
2095    
2096  void MainForm::stabilizeForm (void)  void MainForm::stabilizeForm (void)
2097  {  {
# Line 2047  void MainForm::stabilizeForm (void) Line 2099  void MainForm::stabilizeForm (void)
2099          QString sSessionName = sessionName(m_sFilename);          QString sSessionName = sessionName(m_sFilename);
2100          if (m_iDirtyCount > 0)          if (m_iDirtyCount > 0)
2101                  sSessionName += " *";                  sSessionName += " *";
2102          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));          setWindowTitle(sSessionName);
2103    
2104          // Update the main menu state...          // Update the main menu state...
2105          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
2106          const QList<QMdiSubWindow *>& wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist = m_pWorkspace->subWindowList();
2107          const bool bHasClient = (m_pOptions != NULL && m_pClient != NULL);          const bool bHasClient = (m_pOptions != nullptr && m_pClient != nullptr);
2108          const bool bHasChannel = (bHasClient && pChannelStrip != NULL);          const bool bHasChannel = (bHasClient && pChannelStrip != nullptr);
2109          const bool bHasChannels = (bHasClient && wlist.count() > 0);          const bool bHasChannels = (bHasClient && wlist.count() > 0);
2110          m_ui.fileNewAction->setEnabled(bHasClient);          m_ui.fileNewAction->setEnabled(bHasClient);
2111          m_ui.fileOpenAction->setEnabled(bHasClient);          m_ui.fileOpenAction->setEnabled(bHasClient);
2112          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
2113          m_ui.fileSaveAsAction->setEnabled(bHasClient);          m_ui.fileSaveAsAction->setEnabled(bHasClient);
2114          m_ui.fileResetAction->setEnabled(bHasClient);          m_ui.fileResetAction->setEnabled(bHasClient);
2115          m_ui.fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);          m_ui.fileRestartAction->setEnabled(bHasClient || m_pServer == nullptr);
2116          m_ui.editAddChannelAction->setEnabled(bHasClient);          m_ui.editAddChannelAction->setEnabled(bHasClient);
2117          m_ui.editRemoveChannelAction->setEnabled(bHasChannel);          m_ui.editRemoveChannelAction->setEnabled(bHasChannel);
2118          m_ui.editSetupChannelAction->setEnabled(bHasChannel);          m_ui.editSetupChannelAction->setEnabled(bHasChannel);
# Line 2191  void MainForm::updateSession (void) Line 2243  void MainForm::updateSession (void)
2243          updateAllChannelStrips(false);          updateAllChannelStrips(false);
2244    
2245          // Do we auto-arrange?          // Do we auto-arrange?
2246          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
2247    
2248          // Remember to refresh devices and instruments...          // Remember to refresh devices and instruments...
2249          if (m_pInstrumentListForm)          if (m_pInstrumentListForm)
# Line 2210  void MainForm::updateAllChannelStrips ( Line 2261  void MainForm::updateAllChannelStrips (
2261    
2262          // Retrieve the current channel list.          // Retrieve the current channel list.
2263          int *piChannelIDs = ::lscp_list_channels(m_pClient);          int *piChannelIDs = ::lscp_list_channels(m_pClient);
2264          if (piChannelIDs == NULL) {          if (piChannelIDs == nullptr) {
2265                  if (::lscp_client_get_errno(m_pClient)) {                  if (::lscp_client_get_errno(m_pClient)) {
2266                          appendMessagesClient("lscp_list_channels");                          appendMessagesClient("lscp_list_channels");
2267                          appendMessagesError(                          appendMessagesError(
# Line 2225  void MainForm::updateAllChannelStrips ( Line 2276  void MainForm::updateAllChannelStrips (
2276                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));
2277                  }                  }
2278                  // Do we auto-arrange?                  // Do we auto-arrange?
2279                  if (m_pOptions && m_pOptions->bAutoArrange)                  channelsArrangeAuto();
                         channelsArrange();  
2280                  // remove dead channel strips                  // remove dead channel strips
2281                  if (bRemoveDeadStrips) {                  if (bRemoveDeadStrips) {
2282                          const QList<QMdiSubWindow *>& wlist                          const QList<QMdiSubWindow *>& wlist
2283                                  = m_pWorkspace->subWindowList();                                  = m_pWorkspace->subWindowList();
2284                          const int iStripCount = wlist.count();                          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2285                          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                                  ChannelStrip *pChannelStrip
2286                                  ChannelStrip *pChannelStrip = NULL;                                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                                 if (pMdiSubWindow)  
                                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2287                                  if (pChannelStrip) {                                  if (pChannelStrip) {
2288                                          bool bExists = false;                                          bool bExists = false;
2289                                          for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {                                          for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {
2290                                                  Channel *pChannel = pChannelStrip->channel();                                                  Channel *pChannel = pChannelStrip->channel();
2291                                                  if (pChannel == NULL)                                                  if (pChannel == nullptr)
2292                                                          break;                                                          break;
2293                                                  if (piChannelIDs[iChannel] == pChannel->channelID()) {                                                  if (piChannelIDs[iChannel] == pChannel->channelID()) {
2294                                                          // strip exists, don't touch it                                                          // strip exists, don't touch it
# Line 2264  void MainForm::updateAllChannelStrips ( Line 2311  void MainForm::updateAllChannelStrips (
2311  // Update the recent files list and menu.  // Update the recent files list and menu.
2312  void MainForm::updateRecentFiles ( const QString& sFilename )  void MainForm::updateRecentFiles ( const QString& sFilename )
2313  {  {
2314          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2315                  return;                  return;
2316    
2317          // Remove from list if already there (avoid duplicates)          // Remove from list if already there (avoid duplicates)
# Line 2279  void MainForm::updateRecentFiles ( const Line 2326  void MainForm::updateRecentFiles ( const
2326  // Update the recent files list and menu.  // Update the recent files list and menu.
2327  void MainForm::updateRecentFilesMenu (void)  void MainForm::updateRecentFilesMenu (void)
2328  {  {
2329          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2330                  return;                  return;
2331    
2332          // Time to keep the list under limits.          // Time to keep the list under limits.
# Line 2313  void MainForm::updateInstrumentNames (vo Line 2360  void MainForm::updateInstrumentNames (vo
2360                  return;                  return;
2361    
2362          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2363          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2364          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2365                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2366                  if (pChannelStrip)                  if (pChannelStrip)
2367                          pChannelStrip->updateInstrumentName(true);                          pChannelStrip->updateInstrumentName(true);
2368          }          }
# Line 2329  void MainForm::updateInstrumentNames (vo Line 2373  void MainForm::updateInstrumentNames (vo
2373  // Force update of the channels display font.  // Force update of the channels display font.
2374  void MainForm::updateDisplayFont (void)  void MainForm::updateDisplayFont (void)
2375  {  {
2376          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2377                  return;                  return;
2378    
2379          // Check if display font is legal.          // Check if display font is legal.
# Line 2348  void MainForm::updateDisplayFont (void) Line 2392  void MainForm::updateDisplayFont (void)
2392                  return;                  return;
2393    
2394          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2395          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2396          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2397                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2398                  if (pChannelStrip)                  if (pChannelStrip)
2399                          pChannelStrip->setDisplayFont(font);                          pChannelStrip->setDisplayFont(font);
2400          }          }
# Line 2371  void MainForm::updateDisplayEffect (void Line 2412  void MainForm::updateDisplayEffect (void
2412                  return;                  return;
2413    
2414          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2415          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2416          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2417                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2418                  if (pChannelStrip)                  if (pChannelStrip)
2419                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2420          }          }
# Line 2387  void MainForm::updateDisplayEffect (void Line 2425  void MainForm::updateDisplayEffect (void
2425  // Force update of the channels maximum volume setting.  // Force update of the channels maximum volume setting.
2426  void MainForm::updateMaxVolume (void)  void MainForm::updateMaxVolume (void)
2427  {  {
2428          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2429                  return;                  return;
2430    
2431  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
# Line 2404  void MainForm::updateMaxVolume (void) Line 2442  void MainForm::updateMaxVolume (void)
2442                  return;                  return;
2443    
2444          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2445          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2446          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2447                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2448                  if (pChannelStrip)                  if (pChannelStrip)
2449                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2450          }          }
# Line 2418  void MainForm::updateMaxVolume (void) Line 2453  void MainForm::updateMaxVolume (void)
2453    
2454    
2455  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2456  // qsamplerMainForm -- Messages window form handlers.  // QSampler::MainForm -- Messages window form handlers.
2457    
2458  // Messages output methods.  // Messages output methods.
2459  void MainForm::appendMessages( const QString& s )  void MainForm::appendMessages( const QString& s )
# Line 2454  void MainForm::appendMessagesError( cons Line 2489  void MainForm::appendMessagesError( cons
2489          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2490    
2491          if (m_pOptions && m_pOptions->bConfirmError) {          if (m_pOptions && m_pOptions->bConfirmError) {
2492                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Error");                  const QString& sTitle = tr("Error");
2493          #if 0          #if 0
2494                  QMessageBox::critical(this, sTitle, sText, QMessageBox::Cancel);                  QMessageBox::critical(this, sTitle, sText, QMessageBox::Cancel);
2495          #else          #else
# Line 2477  void MainForm::appendMessagesError( cons Line 2512  void MainForm::appendMessagesError( cons
2512  // This is a special message format, just for client results.  // This is a special message format, just for client results.
2513  void MainForm::appendMessagesClient( const QString& s )  void MainForm::appendMessagesClient( const QString& s )
2514  {  {
2515          if (m_pClient == NULL)          if (m_pClient == nullptr)
2516                  return;                  return;
2517    
2518          appendMessagesColor(s + QString(": %1 (errno=%2)")          appendMessagesColor(s + QString(": %1 (errno=%2)")
# Line 2492  void MainForm::appendMessagesClient( con Line 2527  void MainForm::appendMessagesClient( con
2527  // Force update of the messages font.  // Force update of the messages font.
2528  void MainForm::updateMessagesFont (void)  void MainForm::updateMessagesFont (void)
2529  {  {
2530          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2531                  return;                  return;
2532    
2533          if (m_pMessages && !m_pOptions->sMessagesFont.isEmpty()) {          if (m_pMessages && !m_pOptions->sMessagesFont.isEmpty()) {
# Line 2506  void MainForm::updateMessagesFont (void) Line 2541  void MainForm::updateMessagesFont (void)
2541  // Update messages window line limit.  // Update messages window line limit.
2542  void MainForm::updateMessagesLimit (void)  void MainForm::updateMessagesLimit (void)
2543  {  {
2544          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2545                  return;                  return;
2546    
2547          if (m_pMessages) {          if (m_pMessages) {
# Line 2521  void MainForm::updateMessagesLimit (void Line 2556  void MainForm::updateMessagesLimit (void
2556  // Enablement of the messages capture feature.  // Enablement of the messages capture feature.
2557  void MainForm::updateMessagesCapture (void)  void MainForm::updateMessagesCapture (void)
2558  {  {
2559          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2560                  return;                  return;
2561    
2562          if (m_pMessages)          if (m_pMessages)
# Line 2530  void MainForm::updateMessagesCapture (vo Line 2565  void MainForm::updateMessagesCapture (vo
2565    
2566    
2567  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2568  // qsamplerMainForm -- MDI channel strip management.  // QSampler::MainForm -- MDI channel strip management.
2569    
2570  // The channel strip creation executive.  // The channel strip creation executive.
2571  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )
2572  {  {
2573          if (m_pClient == NULL || pChannel == NULL)          if (m_pClient == nullptr || pChannel == nullptr)
2574                  return NULL;                  return nullptr;
2575    
2576          // Add a new channel itema...          // Add a new channel itema...
2577          ChannelStrip *pChannelStrip = new ChannelStrip();          ChannelStrip *pChannelStrip = new ChannelStrip();
2578          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
2579                  return NULL;                  return nullptr;
2580    
2581          // Set some initial channel strip options...          // Set some initial channel strip options...
2582          if (m_pOptions) {          if (m_pOptions) {
# Line 2557  ChannelStrip *MainForm::createChannelStr Line 2592  ChannelStrip *MainForm::createChannelStr
2592          }          }
2593    
2594          // Add it to workspace...          // Add it to workspace...
2595          m_pWorkspace->addSubWindow(pChannelStrip,          QMdiSubWindow *pMdiSubWindow
2596                  Qt::SubWindow | Qt::FramelessWindowHint);                  = m_pWorkspace->addSubWindow(pChannelStrip,
2597                            Qt::SubWindow | Qt::FramelessWindowHint);
2598            pMdiSubWindow->setAttribute(Qt::WA_DeleteOnClose);
2599    
2600          // Actual channel strip setup...          // Actual channel strip setup...
2601          pChannelStrip->setup(pChannel);          pChannelStrip->setup(pChannel);
# Line 2582  void MainForm::destroyChannelStrip ( Cha Line 2619  void MainForm::destroyChannelStrip ( Cha
2619  {  {
2620          QMdiSubWindow *pMdiSubWindow          QMdiSubWindow *pMdiSubWindow
2621                  = static_cast<QMdiSubWindow *> (pChannelStrip->parentWidget());                  = static_cast<QMdiSubWindow *> (pChannelStrip->parentWidget());
2622          if (pMdiSubWindow == NULL)          if (pMdiSubWindow == nullptr)
2623                  return;                  return;
2624    
2625          // Just delete the channel strip.          // Just delete the channel strip.
# Line 2590  void MainForm::destroyChannelStrip ( Cha Line 2627  void MainForm::destroyChannelStrip ( Cha
2627          delete pMdiSubWindow;          delete pMdiSubWindow;
2628    
2629          // Do we auto-arrange?          // Do we auto-arrange?
2630          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
2631  }  }
2632    
2633    
# Line 2602  ChannelStrip *MainForm::activeChannelStr Line 2638  ChannelStrip *MainForm::activeChannelStr
2638          if (pMdiSubWindow)          if (pMdiSubWindow)
2639                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2640          else          else
2641                  return NULL;                  return nullptr;
2642  }  }
2643    
2644    
2645  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2646  ChannelStrip *MainForm::channelStripAt ( int iStrip )  ChannelStrip *MainForm::channelStripAt ( int iStrip )
2647  {  {
2648          if (!m_pWorkspace) return NULL;          if (!m_pWorkspace) return nullptr;
2649    
2650          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
2651                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
2652          if (wlist.isEmpty())          if (wlist.isEmpty())
2653                  return NULL;                  return nullptr;
2654    
2655          if (iStrip < 0 || iStrip >= wlist.count())          if (iStrip < 0 || iStrip >= wlist.count())
2656                  return NULL;                  return nullptr;
2657    
2658          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2659          if (pMdiSubWindow)          if (pMdiSubWindow)
2660                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2661          else          else
2662                  return NULL;                  return nullptr;
2663  }  }
2664    
2665    
# Line 2633  ChannelStrip *MainForm::channelStrip ( i Line 2669  ChannelStrip *MainForm::channelStrip ( i
2669          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
2670                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
2671          if (wlist.isEmpty())          if (wlist.isEmpty())
2672                  return NULL;                  return nullptr;
2673    
2674          const int iStripCount = wlist.count();          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2675          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  ChannelStrip *pChannelStrip
2676                  ChannelStrip *pChannelStrip = NULL;                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2677                  if (pChannelStrip) {                  if (pChannelStrip) {
2678                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
2679                          if (pChannel && pChannel->channelID() == iChannelID)                          if (pChannel && pChannel->channelID() == iChannelID)
# Line 2649  ChannelStrip *MainForm::channelStrip ( i Line 2682  ChannelStrip *MainForm::channelStrip ( i
2682          }          }
2683    
2684          // Not found.          // Not found.
2685          return NULL;          return nullptr;
2686  }  }
2687    
2688    
# Line 2664  void MainForm::channelsMenuAboutToShow ( Line 2697  void MainForm::channelsMenuAboutToShow (
2697                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
2698          if (!wlist.isEmpty()) {          if (!wlist.isEmpty()) {
2699                  m_ui.channelsMenu->addSeparator();                  m_ui.channelsMenu->addSeparator();
2700                  const int iStripCount = wlist.count();                  int iStrip = 0;
2701                  for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2702                          ChannelStrip *pChannelStrip = NULL;                          ChannelStrip *pChannelStrip
2703                          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                         if (pMdiSubWindow)  
                                 pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2704                          if (pChannelStrip) {                          if (pChannelStrip) {
2705                                  QAction *pAction = m_ui.channelsMenu->addAction(                                  QAction *pAction = m_ui.channelsMenu->addAction(
2706                                          pChannelStrip->windowTitle(),                                          pChannelStrip->windowTitle(),
# Line 2678  void MainForm::channelsMenuAboutToShow ( Line 2709  void MainForm::channelsMenuAboutToShow (
2709                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);
2710                                  pAction->setData(iStrip);                                  pAction->setData(iStrip);
2711                          }                          }
2712                            ++iStrip;
2713                  }                  }
2714          }          }
2715  }  }
# Line 2688  void MainForm::channelsMenuActivated (vo Line 2720  void MainForm::channelsMenuActivated (vo
2720  {  {
2721          // Retrive channel index from action data...          // Retrive channel index from action data...
2722          QAction *pAction = qobject_cast<QAction *> (sender());          QAction *pAction = qobject_cast<QAction *> (sender());
2723          if (pAction == NULL)          if (pAction == nullptr)
2724                  return;                  return;
2725    
2726          ChannelStrip *pChannelStrip = channelStripAt(pAction->data().toInt());          ChannelStrip *pChannelStrip = channelStripAt(pAction->data().toInt());
# Line 2700  void MainForm::channelsMenuActivated (vo Line 2732  void MainForm::channelsMenuActivated (vo
2732    
2733    
2734  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2735  // qsamplerMainForm -- Timer stuff.  // QSampler::MainForm -- Timer stuff.
2736    
2737  // Set the pseudo-timer delay schedule.  // Set the pseudo-timer delay schedule.
2738  void MainForm::startSchedule ( int iStartDelay )  void MainForm::startSchedule ( int iStartDelay )
# Line 2719  void MainForm::stopSchedule (void) Line 2751  void MainForm::stopSchedule (void)
2751  // Timer slot funtion.  // Timer slot funtion.
2752  void MainForm::timerSlot (void)  void MainForm::timerSlot (void)
2753  {  {
2754          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2755                  return;                  return;
2756    
2757          // Is it the first shot on server start after a few delay?          // Is it the first shot on server start after a few delay?
# Line 2754  void MainForm::timerSlot (void) Line 2786  void MainForm::timerSlot (void)
2786                                  // Update the channel stream usage for each strip...                                  // Update the channel stream usage for each strip...
2787                                  const QList<QMdiSubWindow *>& wlist                                  const QList<QMdiSubWindow *>& wlist
2788                                          = m_pWorkspace->subWindowList();                                          = m_pWorkspace->subWindowList();
2789                                  const int iStripCount = wlist.count();                                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2790                                  for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {                                          ChannelStrip *pChannelStrip
2791                                          ChannelStrip *pChannelStrip = NULL;                                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                                         QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);  
                                         if (pMdiSubWindow)  
                                                 pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2792                                          if (pChannelStrip && pChannelStrip->isVisible())                                          if (pChannelStrip && pChannelStrip->isVisible())
2793                                                  pChannelStrip->updateChannelUsage();                                                  pChannelStrip->updateChannelUsage();
2794                                  }                                  }
2795                          }                          }
2796                  }                  }
2797    
2798            #if CONFIG_LSCP_CLIENT_CONNECTION_LOST
2799                    // If we lost connection to server: Try to automatically reconnect if we
2800                    // did not start the server.
2801                    //
2802                    // TODO: If we started the server, then we might inform the user that
2803                    // the server probably crashed and asking user ONCE whether we should
2804                    // restart the server.
2805                    if (lscp_client_connection_lost(m_pClient) && !m_pServer)
2806                            startAutoReconnectClient();
2807            #endif // CONFIG_LSCP_CLIENT_CONNECTION_LOST
2808          }          }
2809    
2810          // Register the next timer slot.          // Register the next timer slot.
# Line 2773  void MainForm::timerSlot (void) Line 2813  void MainForm::timerSlot (void)
2813    
2814    
2815  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2816  // qsamplerMainForm -- Server stuff.  // QSampler::MainForm -- Server stuff.
2817    
2818  // Start linuxsampler server...  // Start linuxsampler server...
2819  void MainForm::startServer (void)  void MainForm::startServer (void)
2820  {  {
2821          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2822                  return;                  return;
2823    
2824          // Aren't already a client, are we?          // Aren't already a client, are we?
# Line 2788  void MainForm::startServer (void) Line 2828  void MainForm::startServer (void)
2828          // Is the server process instance still here?          // Is the server process instance still here?
2829          if (m_pServer) {          if (m_pServer) {
2830                  if (QMessageBox::warning(this,                  if (QMessageBox::warning(this,
2831                          QSAMPLER_TITLE ": " + tr("Warning"),                          tr("Warning"),
2832                          tr("Could not start the LinuxSampler server.\n\n"                          tr("Could not start the LinuxSampler server.\n\n"
2833                          "Maybe it is already started."),                          "Maybe it is already started."),
2834                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
# Line 2807  void MainForm::startServer (void) Line 2847  void MainForm::startServer (void)
2847    
2848          // OK. Let's build the startup process...          // OK. Let's build the startup process...
2849          m_pServer = new QProcess();          m_pServer = new QProcess();
2850          bForceServerStop = true;          m_bForceServerStop = true;
2851    
2852          // Setup stdout/stderr capture...          // Setup stdout/stderr capture...
2853          m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);          m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);
# Line 2851  void MainForm::startServer (void) Line 2891  void MainForm::startServer (void)
2891    
2892    
2893  // Stop linuxsampler server...  // Stop linuxsampler server...
2894  void MainForm::stopServer (bool bInteractive)  void MainForm::stopServer ( bool bInteractive )
2895  {  {
2896          // Stop client code.          // Stop client code.
2897          stopClient();          stopClient();
2898    
2899          if (m_pServer && bInteractive) {          if (m_pServer && bInteractive) {
2900                  if (QMessageBox::question(this,                  if (QMessageBox::question(this,
2901                          QSAMPLER_TITLE ": " + tr("The backend's fate ..."),                          tr("The backend's fate ..."),
2902                          tr("You have the option to keep the sampler backend (LinuxSampler)\n"                          tr("You have the option to keep the sampler backend (LinuxSampler)\n"
2903                          "running in the background. The sampler would continue to work\n"                          "running in the background. The sampler would continue to work\n"
2904                          "according to your current sampler session and you could alter the\n"                          "according to your current sampler session and you could alter the\n"
2905                          "sampler session at any time by relaunching QSampler.\n\n"                          "sampler session at any time by relaunching QSampler.\n\n"
2906                          "Do you want LinuxSampler to stop?"),                          "Do you want LinuxSampler to stop?"),
2907                          QMessageBox::Yes | QMessageBox::No,                          QMessageBox::Yes | QMessageBox::No,
2908                          QMessageBox::Yes) == QMessageBox::No)                          QMessageBox::Yes) == QMessageBox::No) {
2909                  {                          m_bForceServerStop = false;
                         bForceServerStop = false;  
2910                  }                  }
2911          }          }
2912    
2913            bool bGraceWait = true;
2914    
2915          // And try to stop server.          // And try to stop server.
2916          if (m_pServer && bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2917                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2918                  if (m_pServer->state() == QProcess::Running) {                  if (m_pServer->state() == QProcess::Running) {
2919                  #if defined(WIN32)                  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
2920                          // Try harder...                          // Try harder...
2921                          m_pServer->kill();                          m_pServer->kill();
2922                  #else                  #else
2923                          // Try softly...                          // Try softly...
2924                          m_pServer->terminate();                          m_pServer->terminate();
2925                            bool bFinished = m_pServer->waitForFinished(QSAMPLER_TIMER_MSECS * 1000);
2926                            if (bFinished) bGraceWait = false;
2927                  #endif                  #endif
2928                  }                  }
2929          }       // Do final processing anyway.          }       // Do final processing anyway.
2930          else processServerExit();          else processServerExit();
2931    
2932          // Give it some time to terminate gracefully and stabilize...          // Give it some time to terminate gracefully and stabilize...
2933          QTime t;          if (bGraceWait) {
2934          t.start();                  QElapsedTimer timer;
2935          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                  timer.start();
2936                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  while (timer.elapsed() < QSAMPLER_TIMER_MSECS)
2937                            QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2938            }
2939  }  }
2940    
2941    
# Line 2912  void MainForm::processServerExit (void) Line 2957  void MainForm::processServerExit (void)
2957          if (m_pMessages)          if (m_pMessages)
2958                  m_pMessages->flushStdoutBuffer();                  m_pMessages->flushStdoutBuffer();
2959    
2960          if (m_pServer && bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2961                  if (m_pServer->state() != QProcess::NotRunning) {                  if (m_pServer->state() != QProcess::NotRunning) {
2962                          appendMessages(tr("Server is being forced..."));                          appendMessages(tr("Server is being forced..."));
2963                          // Force final server shutdown...                          // Force final server shutdown...
2964                          m_pServer->kill();                          m_pServer->kill();
2965                          // Give it some time to terminate gracefully and stabilize...                          // Give it some time to terminate gracefully and stabilize...
2966                          QTime t;                          QElapsedTimer timer;
2967                          t.start();                          timer.start();
2968                          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                          while (timer.elapsed() < QSAMPLER_TIMER_MSECS)
2969                                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2970                  }                  }
2971                  // Force final server shutdown...                  // Force final server shutdown...
# Line 2928  void MainForm::processServerExit (void) Line 2973  void MainForm::processServerExit (void)
2973                          tr("Server was stopped with exit status %1.")                          tr("Server was stopped with exit status %1.")
2974                          .arg(m_pServer->exitStatus()));                          .arg(m_pServer->exitStatus()));
2975                  delete m_pServer;                  delete m_pServer;
2976                  m_pServer = NULL;                  m_pServer = nullptr;
2977          }          }
2978    
2979          // Again, make status visible stable.          // Again, make status visible stable.
# Line 2937  void MainForm::processServerExit (void) Line 2982  void MainForm::processServerExit (void)
2982    
2983    
2984  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2985  // qsamplerMainForm -- Client stuff.  // QSampler::MainForm -- Client stuff.
2986    
2987  // The LSCP client callback procedure.  // The LSCP client callback procedure.
2988  lscp_status_t qsampler_client_callback ( lscp_client_t */*pClient*/,  lscp_status_t qsampler_client_callback ( lscp_client_t */*pClient*/,
2989          lscp_event_t event, const char *pchData, int cchData, void *pvData )          lscp_event_t event, const char *pchData, int cchData, void *pvData )
2990  {  {
2991          MainForm* pMainForm = (MainForm *) pvData;          MainForm* pMainForm = (MainForm *) pvData;
2992          if (pMainForm == NULL)          if (pMainForm == nullptr)
2993                  return LSCP_FAILED;                  return LSCP_FAILED;
2994    
2995          // ATTN: DO NOT EVER call any GUI code here,          // ATTN: DO NOT EVER call any GUI code here,
# Line 2958  lscp_status_t qsampler_client_callback ( Line 3003  lscp_status_t qsampler_client_callback (
3003    
3004    
3005  // Start our almighty client...  // Start our almighty client...
3006  bool MainForm::startClient (void)  bool MainForm::startClient (bool bReconnectOnly)
3007  {  {
3008          // Have it a setup?          // Have it a setup?
3009          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
3010                  return false;                  return false;
3011    
3012          // Aren't we already started, are we?          // Aren't we already started, are we?
# Line 2975  bool MainForm::startClient (void) Line 3020  bool MainForm::startClient (void)
3020          m_pClient = ::lscp_client_create(          m_pClient = ::lscp_client_create(
3021                  m_pOptions->sServerHost.toUtf8().constData(),                  m_pOptions->sServerHost.toUtf8().constData(),
3022                  m_pOptions->iServerPort, qsampler_client_callback, this);                  m_pOptions->iServerPort, qsampler_client_callback, this);
3023          if (m_pClient == NULL) {          if (m_pClient == nullptr) {
3024                  // Is this the first try?                  // Is this the first try?
3025                  // maybe we need to start a local server...                  // maybe we need to start a local server...
3026                  if ((m_pServer && m_pServer->state() == QProcess::Running)                  if ((m_pServer && m_pServer->state() == QProcess::Running)
3027                          || !m_pOptions->bServerStart) {                          || !m_pOptions->bServerStart || bReconnectOnly)
3028                          appendMessagesError(                  {
3029                                  tr("Could not connect to server as client.\n\nSorry."));                          // if this method is called from autoReconnectClient()
3030                            // then don't bother user with an error message...
3031                            if (!bReconnectOnly) {
3032                                    appendMessagesError(
3033                                            tr("Could not connect to server as client.\n\nSorry.")
3034                                    );
3035                            }
3036                  } else {                  } else {
3037                          startServer();                          startServer();
3038                  }                  }
# Line 2989  bool MainForm::startClient (void) Line 3040  bool MainForm::startClient (void)
3040                  stabilizeForm();                  stabilizeForm();
3041                  return false;                  return false;
3042          }          }
3043    
3044          // Just set receive timeout value, blindly.          // Just set receive timeout value, blindly.
3045          ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);          ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
3046          appendMessages(          appendMessages(
# Line 3044  bool MainForm::startClient (void) Line 3096  bool MainForm::startClient (void)
3096          if (!m_pOptions->sSessionFile.isEmpty()) {          if (!m_pOptions->sSessionFile.isEmpty()) {
3097                  // Just load the prabably startup session...                  // Just load the prabably startup session...
3098                  if (loadSessionFile(m_pOptions->sSessionFile)) {                  if (loadSessionFile(m_pOptions->sSessionFile)) {
3099                          m_pOptions->sSessionFile = QString::null;                          m_pOptions->sSessionFile = QString();
3100                          return true;                          return true;
3101                  }                  }
3102          }          }
# Line 3060  bool MainForm::startClient (void) Line 3112  bool MainForm::startClient (void)
3112  // Stop client...  // Stop client...
3113  void MainForm::stopClient (void)  void MainForm::stopClient (void)
3114  {  {
3115          if (m_pClient == NULL)          if (m_pClient == nullptr)
3116                  return;                  return;
3117    
3118          // Log prepare here.          // Log prepare here.
# Line 3092  void MainForm::stopClient (void) Line 3144  void MainForm::stopClient (void)
3144          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
3145          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);
3146          ::lscp_client_destroy(m_pClient);          ::lscp_client_destroy(m_pClient);
3147          m_pClient = NULL;          m_pClient = nullptr;
3148    
3149          // Hard-notify instrumnet and device configuration forms,          // Hard-notify instrumnet and device configuration forms,
3150          // if visible, that we're running out...          // if visible, that we're running out...
# Line 3109  void MainForm::stopClient (void) Line 3161  void MainForm::stopClient (void)
3161  }  }
3162    
3163    
3164    void MainForm::startAutoReconnectClient (void)
3165    {
3166            stopClient();
3167            appendMessages(tr("Trying to reconnect..."));
3168            QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(autoReconnectClient()));
3169    }
3170    
3171    
3172    void MainForm::autoReconnectClient (void)
3173    {
3174            const bool bSuccess = startClient(true);
3175            if (!bSuccess)
3176                    QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(autoReconnectClient()));
3177    }
3178    
3179    
3180  // Channel strip activation/selection.  // Channel strip activation/selection.
3181  void MainForm::activateStrip ( QMdiSubWindow *pMdiSubWindow )  void MainForm::activateStrip ( QMdiSubWindow *pMdiSubWindow )
3182  {  {
3183          ChannelStrip *pChannelStrip = NULL;          ChannelStrip *pChannelStrip = nullptr;
3184          if (pMdiSubWindow)          if (pMdiSubWindow)
3185                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
3186          if (pChannelStrip)          if (pChannelStrip)

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

  ViewVC Help
Powered by ViewVC