/[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 2681 by capela, Wed Dec 24 14:23:06 2014 UTC revision 3759 by capela, Sat Mar 28 00:28:13 2020 UTC
# Line 1  Line 1 
1  // qsamplerMainForm.cpp  // qsamplerMainForm.cpp
2  //  //
3  /****************************************************************************  /****************************************************************************
4     Copyright (C) 2004-2014, 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 Christian Schoenebeck     Copyright (C) 2007-2019 Christian Schoenebeck
6    
7     This program is free software; you can redistribute it and/or     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License     modify it under the terms of the GNU General Public License
# Line 58  Line 58 
58  #include <QTimer>  #include <QTimer>
59  #include <QDateTime>  #include <QDateTime>
60    
61  #if QT_VERSION >= 0x050000  #include <QElapsedTimer>
62    
63    #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
64  #include <QMimeData>  #include <QMimeData>
65  #endif  #endif
66    
67  #if QT_VERSION < 0x040500  #if QT_VERSION < QT_VERSION_CHECK(4, 5, 0)
68  namespace Qt {  namespace Qt {
69  const WindowFlags WindowCloseButtonHint = WindowFlags(0x08000000);  const WindowFlags WindowCloseButtonHint = WindowFlags(0x08000000);
70  }  }
71  #endif  #endif
72    
73  #ifdef HAVE_SIGNAL_H  // Deprecated QTextStreamFunctions/Qt namespaces workaround.
74  #include <signal.h>  #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
75    #define endl    Qt::endl
76  #endif  #endif
77    
78    
79  #ifdef CONFIG_LIBGIG  #ifdef CONFIG_LIBGIG
80  #include <gig.h>  #include <gig.h>
81  #endif  #endif
# Line 91  static inline long lroundf ( float x ) Line 95  static inline long lroundf ( float x )
95    
96    
97  // All winsock apps needs this.  // All winsock apps needs this.
98  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
99  static WSADATA _wsaData;  static WSADATA _wsaData;
100    #undef HAVE_SIGNAL_H
101  #endif  #endif
102    
103    
# Line 103  static WSADATA _wsaData; Line 108  static WSADATA _wsaData;
108    
109  #include <QSocketNotifier>  #include <QSocketNotifier>
110    
111    #include <unistd.h>
112  #include <sys/types.h>  #include <sys/types.h>
113  #include <sys/socket.h>  #include <sys/socket.h>
   
114  #include <signal.h>  #include <signal.h>
115    
116  // File descriptor for SIGUSR1 notifier.  // File descriptor for SIGUSR1 notifier.
117  static int g_fdUsr1[2];  static int g_fdSigusr1[2] = { -1, -1 };
118    
119  // Unix SIGUSR1 signal handler.  // Unix SIGUSR1 signal handler.
120  static void qsampler_sigusr1_handler ( int /* signo */ )  static void qsampler_sigusr1_handler ( int /* signo */ )
121  {  {
122          char c = 1;          char c = 1;
123    
124          (::write(g_fdUsr1[0], &c, sizeof(c)) > 0);          (::write(g_fdSigusr1[0], &c, sizeof(c)) > 0);
125    }
126    
127    // File descriptor for SIGTERM notifier.
128    static int g_fdSigterm[2] = { -1, -1 };
129    
130    // Unix SIGTERM signal handler.
131    static void qsampler_sigterm_handler ( int /* signo */ )
132    {
133            char c = 1;
134    
135            (::write(g_fdSigterm[0], &c, sizeof(c)) > 0);
136  }  }
137    
138  #endif  // HAVE_SIGNAL_H  #endif  // HAVE_SIGNAL_H
139    
140    
141  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
142  // qsampler -- namespace  // QSampler -- namespace
143    
144    
145  namespace QSampler {  namespace QSampler {
# Line 143  namespace QSampler { Line 159  namespace QSampler {
159    
160    
161  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
162  // LscpEvent -- specialty for LSCP callback comunication.  // QSampler::LscpEvent -- specialty for LSCP callback comunication.
   
163    
164  class LscpEvent : public QEvent  class LscpEvent : public QEvent
165  {  {
# Line 159  public: Line 174  public:
174          }          }
175    
176          // Accessors.          // Accessors.
177          lscp_event_t event() { return m_event; }          lscp_event_t  event() { return m_event; }
178          QString&     data()  { return m_data;  }          const QString& data() { return m_data;  }
179    
180  private:  private:
181    
# Line 172  private: Line 187  private:
187    
188    
189  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
190  // qsamplerMainForm -- Main window form implementation.  // QSampler::Workspace -- Main window workspace (MDI Area) decl.
191    
192    class Workspace : public QMdiArea
193    {
194    public:
195    
196            Workspace(MainForm *pMainForm) : QMdiArea(pMainForm) {}
197    
198    protected:
199    
200            void resizeEvent(QResizeEvent *)
201            {
202                    MainForm *pMainForm = static_cast<MainForm *> (parentWidget());
203                    if (pMainForm)
204                            pMainForm->channelsArrangeAuto();
205            }
206    };
207    
208    
209    //-------------------------------------------------------------------------
210    // QSampler::MainForm -- Main window form implementation.
211    
212  // Kind of singleton reference.  // Kind of singleton reference.
213  MainForm* MainForm::g_pMainForm = NULL;  MainForm *MainForm::g_pMainForm = nullptr;
214    
215  MainForm::MainForm ( QWidget *pParent )  MainForm::MainForm ( QWidget *pParent )
216          : QMainWindow(pParent)          : QMainWindow(pParent)
# Line 186  MainForm::MainForm ( QWidget *pParent ) Line 221  MainForm::MainForm ( QWidget *pParent )
221          g_pMainForm = this;          g_pMainForm = this;
222    
223          // Initialize some pointer references.          // Initialize some pointer references.
224          m_pOptions = NULL;          m_pOptions = nullptr;
225    
226          // All child forms are to be created later, not earlier than setup.          // All child forms are to be created later, not earlier than setup.
227          m_pMessages = NULL;          m_pMessages = nullptr;
228          m_pInstrumentListForm = NULL;          m_pInstrumentListForm = nullptr;
229          m_pDeviceForm = NULL;          m_pDeviceForm = nullptr;
230    
231          // We'll start clean.          // We'll start clean.
232          m_iUntitled   = 0;          m_iUntitled   = 0;
233            m_iDirtySetup = 0;
234          m_iDirtyCount = 0;          m_iDirtyCount = 0;
235    
236          m_pServer = NULL;          m_pServer = nullptr;
237          m_pClient = NULL;          m_pClient = nullptr;
238    
239          m_iStartDelay = 0;          m_iStartDelay = 0;
240          m_iTimerDelay = 0;          m_iTimerDelay = 0;
# Line 213  MainForm::MainForm ( QWidget *pParent ) Line 249  MainForm::MainForm ( QWidget *pParent )
249          // LADISH Level 1 suport.          // LADISH Level 1 suport.
250    
251          // Initialize file descriptors for SIGUSR1 socket notifier.          // Initialize file descriptors for SIGUSR1 socket notifier.
252          ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdUsr1);          ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigusr1);
253          m_pUsr1Notifier          m_pSigusr1Notifier
254                  = new QSocketNotifier(g_fdUsr1[1], QSocketNotifier::Read, this);                  = new QSocketNotifier(g_fdSigusr1[1], QSocketNotifier::Read, this);
255    
256          QObject::connect(m_pUsr1Notifier,          QObject::connect(m_pSigusr1Notifier,
257                  SIGNAL(activated(int)),                  SIGNAL(activated(int)),
258                  SLOT(handle_sigusr1()));                  SLOT(handle_sigusr1()));
259    
260          // Install SIGUSR1 signal handler.          // Install SIGUSR1 signal handler.
261      struct sigaction usr1;          struct sigaction sigusr1;
262      usr1.sa_handler = qsampler_sigusr1_handler;          sigusr1.sa_handler = qsampler_sigusr1_handler;
263      sigemptyset(&usr1.sa_mask);          sigemptyset(&sigusr1.sa_mask);
264      usr1.sa_flags = 0;          sigusr1.sa_flags = 0;
265      usr1.sa_flags |= SA_RESTART;          sigusr1.sa_flags |= SA_RESTART;
266      ::sigaction(SIGUSR1, &usr1, NULL);          ::sigaction(SIGUSR1, &sigusr1, nullptr);
267    
268            // Initialize file descriptors for SIGTERM socket notifier.
269            ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigterm);
270            m_pSigtermNotifier
271                    = new QSocketNotifier(g_fdSigterm[1], QSocketNotifier::Read, this);
272    
273            QObject::connect(m_pSigtermNotifier,
274                    SIGNAL(activated(int)),
275                    SLOT(handle_sigterm()));
276    
277            // Install SIGTERM signal handler.
278            struct sigaction sigterm;
279            sigterm.sa_handler = qsampler_sigterm_handler;
280            sigemptyset(&sigterm.sa_mask);
281            sigterm.sa_flags = 0;
282            sigterm.sa_flags |= SA_RESTART;
283            ::sigaction(SIGTERM, &sigterm, nullptr);
284            ::sigaction(SIGQUIT, &sigterm, nullptr);
285    
286            // Ignore SIGHUP/SIGINT signals.
287            ::signal(SIGHUP, SIG_IGN);
288            ::signal(SIGINT, SIG_IGN);
289    
290  #else   // HAVE_SIGNAL_H  #else   // HAVE_SIGNAL_H
291    
292          m_pUsr1Notifier = NULL;          m_pSigusr1Notifier = nullptr;
293            m_pSigtermNotifier = nullptr;
294                    
295  #endif  // !HAVE_SIGNAL_H  #endif  // !HAVE_SIGNAL_H
296    
# Line 269  MainForm::MainForm ( QWidget *pParent ) Line 328  MainForm::MainForm ( QWidget *pParent )
328  #endif  #endif
329    
330          // Make it an MDI workspace.          // Make it an MDI workspace.
331          m_pWorkspace = new QMdiArea(this);          m_pWorkspace = new Workspace(this);
332          m_pWorkspace->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);          m_pWorkspace->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
333          m_pWorkspace->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);          m_pWorkspace->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
334          // Set the activation connection.          // Set the activation connection.
# Line 304  MainForm::MainForm ( QWidget *pParent ) Line 363  MainForm::MainForm ( QWidget *pParent )
363          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
364          statusBar()->addWidget(pLabel);          statusBar()->addWidget(pLabel);
365    
366  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
367          WSAStartup(MAKEWORD(1, 1), &_wsaData);          WSAStartup(MAKEWORD(1, 1), &_wsaData);
368  #endif  #endif
369    
# Line 405  MainForm::~MainForm() Line 464  MainForm::~MainForm()
464          // Do final processing anyway.          // Do final processing anyway.
465          processServerExit();          processServerExit();
466    
467  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
468          WSACleanup();          WSACleanup();
469  #endif  #endif
470    
471  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
472          if (m_pUsr1Notifier)          if (m_pSigusr1Notifier)
473                  delete m_pUsr1Notifier;                  delete m_pSigusr1Notifier;
474            if (m_pSigtermNotifier)
475                    delete m_pSigtermNotifier;
476  #endif  #endif
477    
478          // Finally drop any widgets around...          // Finally drop any widgets around...
# Line 440  MainForm::~MainForm() Line 501  MainForm::~MainForm()
501  #endif  #endif
502    
503          // Pseudo-singleton reference shut-down.          // Pseudo-singleton reference shut-down.
504          g_pMainForm = NULL;          g_pMainForm = nullptr;
505  }  }
506    
507    
# Line 478  void MainForm::setup ( Options *pOptions Line 539  void MainForm::setup ( Options *pOptions
539          updateMessagesFont();          updateMessagesFont();
540          updateMessagesLimit();          updateMessagesLimit();
541          updateMessagesCapture();          updateMessagesCapture();
542    
543          // Set the visibility signal.          // Set the visibility signal.
544          QObject::connect(m_pMessages,          QObject::connect(m_pMessages,
545                  SIGNAL(visibilityChanged(bool)),                  SIGNAL(visibilityChanged(bool)),
# Line 543  bool MainForm::queryClose (void) Line 605  bool MainForm::queryClose (void)
605                                  || m_ui.channelsToolbar->isVisible());                                  || m_ui.channelsToolbar->isVisible());
606                          m_pOptions->bStatusbar = statusBar()->isVisible();                          m_pOptions->bStatusbar = statusBar()->isVisible();
607                          // Save the dock windows state.                          // Save the dock windows state.
                         const QString sDockables = saveState().toBase64().data();  
608                          m_pOptions->settings().setValue("/Layout/DockWindows", saveState());                          m_pOptions->settings().setValue("/Layout/DockWindows", saveState());
609                          // And the children, and the main windows state,.                          // And the children, and the main windows state,.
610                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);
# Line 577  void MainForm::closeEvent ( QCloseEvent Line 638  void MainForm::closeEvent ( QCloseEvent
638  void MainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )  void MainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
639  {  {
640          // Accept external drags only...          // Accept external drags only...
641          if (pDragEnterEvent->source() == NULL          if (pDragEnterEvent->source() == nullptr
642                  && pDragEnterEvent->mimeData()->hasUrls()) {                  && pDragEnterEvent->mimeData()->hasUrls()) {
643                  pDragEnterEvent->accept();                  pDragEnterEvent->accept();
644          } else {          } else {
# Line 586  void MainForm::dragEnterEvent ( QDragEnt Line 647  void MainForm::dragEnterEvent ( QDragEnt
647  }  }
648    
649    
650  void MainForm::dropEvent ( QDropEvent* pDropEvent )  void MainForm::dropEvent ( QDropEvent *pDropEvent )
651  {  {
652          // Accept externally originated drops only...          // Accept externally originated drops only...
653          if (pDropEvent->source())          if (pDropEvent->source())
# Line 601  void MainForm::dropEvent ( QDropEvent* p Line 662  void MainForm::dropEvent ( QDropEvent* p
662                          if (QFileInfo(sPath).exists()) {                          if (QFileInfo(sPath).exists()) {
663                                  // Try to create a new channel from instrument file...                                  // Try to create a new channel from instrument file...
664                                  Channel *pChannel = new Channel();                                  Channel *pChannel = new Channel();
665                                  if (pChannel == NULL)                                  if (pChannel == nullptr)
666                                          return;                                          return;
667                                  // Start setting the instrument filename...                                  // Start setting the instrument filename...
668                                  pChannel->setInstrument(sPath, 0);                                  pChannel->setInstrument(sPath, 0);
# Line 642  void MainForm::customEvent ( QEvent* pEv Line 703  void MainForm::customEvent ( QEvent* pEv
703                                  updateAllChannelStrips(true);                                  updateAllChannelStrips(true);
704                                  break;                                  break;
705                          case LSCP_EVENT_CHANNEL_INFO: {                          case LSCP_EVENT_CHANNEL_INFO: {
706                                  int iChannelID = pLscpEvent->data().toInt();                                  const int iChannelID = pLscpEvent->data().toInt();
707                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);
708                                  if (pChannelStrip)                                  if (pChannelStrip)
709                                          channelStripChanged(pChannelStrip);                                          channelStripChanged(pChannelStrip);
# Line 701  void MainForm::handle_sigusr1 (void) Line 762  void MainForm::handle_sigusr1 (void)
762    
763          char c;          char c;
764    
765          if (::read(g_fdUsr1[1], &c, sizeof(c)) > 0)          if (::read(g_fdSigusr1[1], &c, sizeof(c)) > 0)
766                  saveSession(false);                  saveSession(false);
767    
768  #endif  #endif
769  }  }
770    
771    
772    void MainForm::handle_sigterm (void)
773    {
774    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
775    
776            char c;
777    
778            if (::read(g_fdSigterm[1], &c, sizeof(c)) > 0)
779                    close();
780    
781    #endif
782    }
783    
784    
785  void MainForm::updateViewMidiDeviceStatusMenu (void)  void MainForm::updateViewMidiDeviceStatusMenu (void)
786  {  {
787          m_ui.viewMidiDeviceStatusMenu->clear();          m_ui.viewMidiDeviceStatusMenu->clear();
# Line 733  void MainForm::contextMenuEvent( QContex Line 807  void MainForm::contextMenuEvent( QContex
807    
808    
809  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
810  // qsamplerMainForm -- Brainless public property accessors.  // QSampler::MainForm -- Brainless public property accessors.
811    
812  // The global options settings property.  // The global options settings property.
813  Options *MainForm::options (void) const  Options *MainForm::options (void) const
# Line 757  MainForm *MainForm::getInstance (void) Line 831  MainForm *MainForm::getInstance (void)
831    
832    
833  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
834  // qsamplerMainForm -- Session file stuff.  // QSampler::MainForm -- Session file stuff.
835    
836  // Format the displayable session filename.  // Format the displayable session filename.
837  QString MainForm::sessionName ( const QString& sFilename )  QString MainForm::sessionName ( const QString& sFilename )
838  {  {
839          bool bCompletePath = (m_pOptions && m_pOptions->bCompletePath);          const bool bCompletePath = (m_pOptions && m_pOptions->bCompletePath);
840          QString sSessionName = sFilename;          QString sSessionName = sFilename;
841          if (sSessionName.isEmpty())          if (sSessionName.isEmpty())
842                  sSessionName = tr("Untitled") + QString::number(m_iUntitled);                  sSessionName = tr("Untitled") + QString::number(m_iUntitled);
# Line 786  bool MainForm::newSession (void) Line 860  bool MainForm::newSession (void)
860          m_iUntitled++;          m_iUntitled++;
861    
862          // Stabilize form.          // Stabilize form.
863          m_sFilename = QString::null;          m_sFilename = QString();
864          m_iDirtyCount = 0;          m_iDirtyCount = 0;
865          appendMessages(tr("New session: \"%1\".").arg(sessionName(m_sFilename)));          appendMessages(tr("New session: \"%1\".").arg(sessionName(m_sFilename)));
866          stabilizeForm();          stabilizeForm();
# Line 798  bool MainForm::newSession (void) Line 872  bool MainForm::newSession (void)
872  // Open an existing sampler session.  // Open an existing sampler session.
873  bool MainForm::openSession (void)  bool MainForm::openSession (void)
874  {  {
875          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
876                  return false;                  return false;
877    
878          // Ask for the filename to open...          // Ask for the filename to open...
879          QString sFilename = QFileDialog::getOpenFileName(this,          QString sFilename = QFileDialog::getOpenFileName(this,
880                  QSAMPLER_TITLE ": " + tr("Open Session"), // Caption.                  tr("Open Session"),                       // Caption.
881                  m_pOptions->sSessionDir,                  // Start here.                  m_pOptions->sSessionDir,                  // Start here.
882                  tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)                  tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)
883          );          );
# Line 824  bool MainForm::openSession (void) Line 898  bool MainForm::openSession (void)
898  // Save current sampler session with another name.  // Save current sampler session with another name.
899  bool MainForm::saveSession ( bool bPrompt )  bool MainForm::saveSession ( bool bPrompt )
900  {  {
901          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
902                  return false;                  return false;
903    
904          QString sFilename = m_sFilename;          QString sFilename = m_sFilename;
# Line 836  bool MainForm::saveSession ( bool bPromp Line 910  bool MainForm::saveSession ( bool bPromp
910                          sFilename = m_pOptions->sSessionDir;                          sFilename = m_pOptions->sSessionDir;
911                  // Prompt the guy...                  // Prompt the guy...
912                  sFilename = QFileDialog::getSaveFileName(this,                  sFilename = QFileDialog::getSaveFileName(this,
913                          QSAMPLER_TITLE ": " + tr("Save Session"), // Caption.                          tr("Save Session"),                       // Caption.
914                          sFilename,                                // Start here.                          sFilename,                                // Start here.
915                          tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)                          tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)
916                  );                  );
# Line 846  bool MainForm::saveSession ( bool bPromp Line 920  bool MainForm::saveSession ( bool bPromp
920                  // Enforce .lscp extension...                  // Enforce .lscp extension...
921                  if (QFileInfo(sFilename).suffix().isEmpty())                  if (QFileInfo(sFilename).suffix().isEmpty())
922                          sFilename += ".lscp";                          sFilename += ".lscp";
923            #if 0
924                  // Check if already exists...                  // Check if already exists...
925                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
926                          if (QMessageBox::warning(this,                          if (QMessageBox::warning(this,
927                                  QSAMPLER_TITLE ": " + tr("Warning"),                                  tr("Warning"),
928                                  tr("The file already exists:\n\n"                                  tr("The file already exists:\n\n"
929                                  "\"%1\"\n\n"                                  "\"%1\"\n\n"
930                                  "Do you want to replace it?")                                  "Do you want to replace it?")
# Line 858  bool MainForm::saveSession ( bool bPromp Line 933  bool MainForm::saveSession ( bool bPromp
933                                  == QMessageBox::No)                                  == QMessageBox::No)
934                                  return false;                                  return false;
935                  }                  }
936            #endif
937          }          }
938    
939          // Save it right away.          // Save it right away.
# Line 873  bool MainForm::closeSession ( bool bForc Line 949  bool MainForm::closeSession ( bool bForc
949          // Are we dirty enough to prompt it?          // Are we dirty enough to prompt it?
950          if (m_iDirtyCount > 0) {          if (m_iDirtyCount > 0) {
951                  switch (QMessageBox::warning(this,                  switch (QMessageBox::warning(this,
952                          QSAMPLER_TITLE ": " + tr("Warning"),                          tr("Warning"),
953                          tr("The current session has been changed:\n\n"                          tr("The current session has been changed:\n\n"
954                          "\"%1\"\n\n"                          "\"%1\"\n\n"
955                          "Do you want to save the changes?")                          "Do you want to save the changes?")
# Line 896  bool MainForm::closeSession ( bool bForc Line 972  bool MainForm::closeSession ( bool bForc
972          if (bClose) {          if (bClose) {
973                  // Remove all channel strips from sight...                  // Remove all channel strips from sight...
974                  m_pWorkspace->setUpdatesEnabled(false);                  m_pWorkspace->setUpdatesEnabled(false);
975                  QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();                  const QList<QMdiSubWindow *>& wlist
976                  for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {                          = m_pWorkspace->subWindowList();
977                          ChannelStrip *pChannelStrip = NULL;                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
978                          QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                          ChannelStrip *pChannelStrip
979                          if (pMdiSubWindow)                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                                 pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
980                          if (pChannelStrip) {                          if (pChannelStrip) {
981                                  Channel *pChannel = pChannelStrip->channel();                                  Channel *pChannel = pChannelStrip->channel();
982                                  if (bForce && pChannel)                                  if (bForce && pChannel)
983                                          pChannel->removeChannel();                                          pChannel->removeChannel();
984                                  delete pChannelStrip;                                  delete pChannelStrip;
985                          }                          }
986                          if (pMdiSubWindow)                          delete pMdiSubWindow;
                                 delete pMdiSubWindow;  
987                  }                  }
988                  m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
989                  // We're now clean, for sure.                  // We're now clean, for sure.
# Line 923  bool MainForm::closeSession ( bool bForc Line 997  bool MainForm::closeSession ( bool bForc
997  // Load a session from specific file path.  // Load a session from specific file path.
998  bool MainForm::loadSessionFile ( const QString& sFilename )  bool MainForm::loadSessionFile ( const QString& sFilename )
999  {  {
1000          if (m_pClient == NULL)          if (m_pClient == nullptr)
1001                  return false;                  return false;
1002    
1003          // Open and read from real file.          // Open and read from real file.
# Line 999  bool MainForm::loadSessionFile ( const Q Line 1073  bool MainForm::loadSessionFile ( const Q
1073  // Save current session to specific file path.  // Save current session to specific file path.
1074  bool MainForm::saveSessionFile ( const QString& sFilename )  bool MainForm::saveSessionFile ( const QString& sFilename )
1075  {  {
1076          if (m_pClient == NULL)          if (m_pClient == nullptr)
1077                  return false;                  return false;
1078    
1079          // Check whether server is apparently OK...          // Check whether server is apparently OK...
# Line 1021  bool MainForm::saveSessionFile ( const Q Line 1095  bool MainForm::saveSessionFile ( const Q
1095          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1096    
1097          // Write the file.          // Write the file.
1098          int  iErrors = 0;          int iErrors = 0;
1099          QTextStream ts(&file);          QTextStream ts(&file);
1100          ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;          ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;
1101          ts << "# " << tr("Version")          ts << "# " << tr("Version") << ": " CONFIG_BUILD_VERSION << endl;
1102          << ": " QSAMPLER_VERSION << endl;  //      ts << "# " << tr("Build") << ": " CONFIG_BUILD_DATE << endl;
         ts << "# " << tr("Build")  
         << ": " __DATE__ " " __TIME__ << endl;  
1103          ts << "#"  << endl;          ts << "#"  << endl;
1104          ts << "# " << tr("File")          ts << "# " << tr("File")
1105          << ": " << QFileInfo(sFilename).fileName() << endl;          << ": " << QFileInfo(sFilename).fileName() << endl;
# Line 1040  bool MainForm::saveSessionFile ( const Q Line 1112  bool MainForm::saveSessionFile ( const Q
1112          // It is assumed that this new kind of device+session file          // It is assumed that this new kind of device+session file
1113          // will be loaded from a complete initialized server...          // will be loaded from a complete initialized server...
1114          int *piDeviceIDs;          int *piDeviceIDs;
1115          int  iDevice;          int  i, iDevice;
1116          ts << "RESET" << endl;          ts << "RESET" << endl;
1117    
1118          // Audio device mapping.          // Audio device mapping.
1119          QMap<int, int> audioDeviceMap;          QMap<int, int> audioDeviceMap; iDevice = 0;
1120          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);
1121          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1122                  ts << endl;                  Device device(Device::Audio, piDeviceIDs[i]);
1123                  Device device(Device::Audio, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1124                    if (device.driverName().toUpper() == "PLUGIN")
1125                            continue;
1126                  // Audio device specification...                  // Audio device specification...
1127                    ts << endl;
1128                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1129                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1130                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
# Line 1080  bool MainForm::saveSessionFile ( const Q Line 1155  bool MainForm::saveSessionFile ( const Q
1155                          iPort++;                          iPort++;
1156                  }                  }
1157                  // Audio device index/id mapping.                  // Audio device index/id mapping.
1158                  audioDeviceMap[device.deviceID()] = iDevice;                  audioDeviceMap.insert(device.deviceID(), iDevice++);
1159                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1160                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1161          }          }
1162    
1163          // MIDI device mapping.          // MIDI device mapping.
1164          QMap<int, int> midiDeviceMap;          QMap<int, int> midiDeviceMap; iDevice = 0;
1165          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);
1166          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1167                  ts << endl;                  Device device(Device::Midi, piDeviceIDs[i]);
1168                  Device device(Device::Midi, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1169                    if (device.driverName().toUpper() == "PLUGIN")
1170                            continue;
1171                  // MIDI device specification...                  // MIDI device specification...
1172                    ts << endl;
1173                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1174                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1175                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
# Line 1122  bool MainForm::saveSessionFile ( const Q Line 1200  bool MainForm::saveSessionFile ( const Q
1200                          iPort++;                          iPort++;
1201                  }                  }
1202                  // MIDI device index/id mapping.                  // MIDI device index/id mapping.
1203                  midiDeviceMap[device.deviceID()] = iDevice;                  midiDeviceMap.insert(device.deviceID(), iDevice++);
1204                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1205                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1206          }          }
# Line 1133  bool MainForm::saveSessionFile ( const Q Line 1211  bool MainForm::saveSessionFile ( const Q
1211          QMap<int, int> midiInstrumentMap;          QMap<int, int> midiInstrumentMap;
1212          int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);          int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);
1213          for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {          for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {
1214                  int iMidiMap = piMaps[iMap];                  const int iMidiMap = piMaps[iMap];
1215                  const char *pszMapName                  const char *pszMapName
1216                          = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);                          = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);
1217                  ts << "# " << tr("MIDI instrument map") << " " << iMap;                  ts << "# " << tr("MIDI instrument map") << " " << iMap;
# Line 1185  bool MainForm::saveSessionFile ( const Q Line 1263  bool MainForm::saveSessionFile ( const Q
1263                  }                  }
1264                  ts << endl;                  ts << endl;
1265                  // Check for errors...                  // Check for errors...
1266                  if (pInstrs == NULL && ::lscp_client_get_errno(m_pClient)) {                  if (pInstrs == nullptr && ::lscp_client_get_errno(m_pClient)) {
1267                          appendMessagesClient("lscp_list_midi_instruments");                          appendMessagesClient("lscp_list_midi_instruments");
1268                          iErrors++;                          iErrors++;
1269                  }                  }
1270                  // MIDI strument index/id mapping.                  // MIDI strument index/id mapping.
1271                  midiInstrumentMap[iMidiMap] = iMap;                  midiInstrumentMap.insert(iMidiMap, iMap);
1272          }          }
1273          // Check for errors...          // Check for errors...
1274          if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {          if (piMaps == nullptr && ::lscp_client_get_errno(m_pClient)) {
1275                  appendMessagesClient("lscp_list_midi_instrument_maps");                  appendMessagesClient("lscp_list_midi_instrument_maps");
1276                  iErrors++;                  iErrors++;
1277          }          }
1278  #endif  // CONFIG_MIDI_INSTRUMENT  #endif  // CONFIG_MIDI_INSTRUMENT
1279    
1280          // Sampler channel mapping.          // Sampler channel mapping...
1281          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          int iChannelID = 0;
1282          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          const QList<QMdiSubWindow *>& wlist
1283                  ChannelStrip *pChannelStrip = NULL;                  = m_pWorkspace->subWindowList();
1284                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
1285                  if (pMdiSubWindow)                  ChannelStrip *pChannelStrip
1286                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
1287                  if (pChannelStrip) {                  if (pChannelStrip) {
1288                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1289                          if (pChannel) {                          if (pChannel) {
1290                                  ts << "# " << tr("Channel") << " " << iChannel << endl;                                  // Avoid "artifial" plug-in devices...
1291                                    const int iAudioDevice = pChannel->audioDevice();
1292                                    if (!audioDeviceMap.contains(iAudioDevice))
1293                                            continue;
1294                                    const int iMidiDevice = pChannel->midiDevice();
1295                                    if (!midiDeviceMap.contains(iMidiDevice))
1296                                            continue;
1297                                    // Go for regular, canonical devices...
1298                                    ts << "# " << tr("Channel") << " " << iChannelID << endl;
1299                                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
1300                                  if (audioDeviceMap.isEmpty()) {                                  if (audioDeviceMap.isEmpty()) {
1301                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannelID
1302                                                  << " " << pChannel->audioDriver() << endl;                                                  << " " << pChannel->audioDriver() << endl;
1303                                  } else {                                  } else {
1304                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannelID
1305                                                  << " " << audioDeviceMap[pChannel->audioDevice()] << endl;                                                  << " " << audioDeviceMap.value(iAudioDevice) << endl;
1306                                  }                                  }
1307                                  if (midiDeviceMap.isEmpty()) {                                  if (midiDeviceMap.isEmpty()) {
1308                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannel                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID
1309                                                  << " " << pChannel->midiDriver() << endl;                                                  << " " << pChannel->midiDriver() << endl;
1310                                  } else {                                  } else {
1311                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannel                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannelID
1312                                                  << " " << midiDeviceMap[pChannel->midiDevice()] << endl;                                                  << " " << midiDeviceMap.value(iMidiDevice) << endl;
1313                                  }                                  }
1314                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID
1315                                          << " " << pChannel->midiPort() << endl;                                          << " " << pChannel->midiPort() << endl;
1316                                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";                                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannelID << " ";
1317                                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)                                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
1318                                          ts << "ALL";                                          ts << "ALL";
1319                                  else                                  else
1320                                          ts << pChannel->midiChannel();                                          ts << pChannel->midiChannel();
1321                                  ts << endl;                                  ts << endl;
1322                                  ts << "LOAD ENGINE " << pChannel->engineName()                                  ts << "LOAD ENGINE " << pChannel->engineName()
1323                                          << " " << iChannel << endl;                                          << " " << iChannelID << endl;
1324                                  if (pChannel->instrumentStatus() < 100) ts << "# ";                                  if (pChannel->instrumentStatus() < 100) ts << "# ";
1325                                  ts << "LOAD INSTRUMENT NON_MODAL '"                                  ts << "LOAD INSTRUMENT NON_MODAL '"
1326                                          << pChannel->instrumentFile() << "' "                                          << pChannel->instrumentFile() << "' "
1327                                          << pChannel->instrumentNr() << " " << iChannel << endl;                                          << pChannel->instrumentNr() << " " << iChannelID << endl;
1328                                  ChannelRoutingMap::ConstIterator audioRoute;                                  ChannelRoutingMap::ConstIterator audioRoute;
1329                                  for (audioRoute = pChannel->audioRouting().begin();                                  for (audioRoute = pChannel->audioRouting().begin();
1330                                                  audioRoute != pChannel->audioRouting().end();                                                  audioRoute != pChannel->audioRouting().end();
1331                                                          ++audioRoute) {                                                          ++audioRoute) {
1332                                          ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannelID
1333                                                  << " " << audioRoute.key()                                                  << " " << audioRoute.key()
1334                                                  << " " << audioRoute.value() << endl;                                                  << " " << audioRoute.value() << endl;
1335                                  }                                  }
1336                                  ts << "SET CHANNEL VOLUME " << iChannel                                  ts << "SET CHANNEL VOLUME " << iChannelID
1337                                          << " " << pChannel->volume() << endl;                                          << " " << pChannel->volume() << endl;
1338                                  if (pChannel->channelMute())                                  if (pChannel->channelMute())
1339                                          ts << "SET CHANNEL MUTE " << iChannel << " 1" << endl;                                          ts << "SET CHANNEL MUTE " << iChannelID << " 1" << endl;
1340                                  if (pChannel->channelSolo())                                  if (pChannel->channelSolo())
1341                                          ts << "SET CHANNEL SOLO " << iChannel << " 1" << endl;                                          ts << "SET CHANNEL SOLO " << iChannelID << " 1" << endl;
1342                          #ifdef CONFIG_MIDI_INSTRUMENT                          #ifdef CONFIG_MIDI_INSTRUMENT
1343                                  if (pChannel->midiMap() >= 0) {                                  const int iMidiMap = pChannel->midiMap();
1344                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannel                                  if (midiInstrumentMap.contains(iMidiMap)) {
1345                                                  << " " << midiInstrumentMap[pChannel->midiMap()] << endl;                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannelID
1346                                                    << " " << midiInstrumentMap.value(iMidiMap) << endl;
1347                                  }                                  }
1348                          #endif                          #endif
1349                          #ifdef CONFIG_FXSEND                          #ifdef CONFIG_FXSEND
                                 int iChannelID = pChannel->channelID();  
1350                                  int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID);                                  int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID);
1351                                  for (int iFxSend = 0;                                  for (int iFxSend = 0;
1352                                                  piFxSends && piFxSends[iFxSend] >= 0;                                                  piFxSends && piFxSends[iFxSend] >= 0;
# Line 1268  bool MainForm::saveSessionFile ( const Q Line 1354  bool MainForm::saveSessionFile ( const Q
1354                                          lscp_fxsend_info_t *pFxSendInfo = ::lscp_get_fxsend_info(                                          lscp_fxsend_info_t *pFxSendInfo = ::lscp_get_fxsend_info(
1355                                                  m_pClient, iChannelID, piFxSends[iFxSend]);                                                  m_pClient, iChannelID, piFxSends[iFxSend]);
1356                                          if (pFxSendInfo) {                                          if (pFxSendInfo) {
1357                                                  ts << "CREATE FX_SEND " << iChannel                                                  ts << "CREATE FX_SEND " << iChannelID
1358                                                          << " " << pFxSendInfo->midi_controller;                                                          << " " << pFxSendInfo->midi_controller;
1359                                                  if (pFxSendInfo->name)                                                  if (pFxSendInfo->name)
1360                                                          ts << " '" << pFxSendInfo->name << "'";                                                          ts << " '" << pFxSendInfo->name << "'";
# Line 1278  bool MainForm::saveSessionFile ( const Q Line 1364  bool MainForm::saveSessionFile ( const Q
1364                                                                  piRouting && piRouting[iAudioSrc] >= 0;                                                                  piRouting && piRouting[iAudioSrc] >= 0;
1365                                                                          iAudioSrc++) {                                                                          iAudioSrc++) {
1366                                                          ts << "SET FX_SEND AUDIO_OUTPUT_CHANNEL "                                                          ts << "SET FX_SEND AUDIO_OUTPUT_CHANNEL "
1367                                                                  << iChannel                                                                  << iChannelID
1368                                                                  << " " << iFxSend                                                                  << " " << iFxSend
1369                                                                  << " " << iAudioSrc                                                                  << " " << iAudioSrc
1370                                                                  << " " << piRouting[iAudioSrc] << endl;                                                                  << " " << piRouting[iAudioSrc] << endl;
1371                                                  }                                                  }
1372                                          #ifdef CONFIG_FXSEND_LEVEL                                          #ifdef CONFIG_FXSEND_LEVEL
1373                                                  ts << "SET FX_SEND LEVEL " << iChannel                                                  ts << "SET FX_SEND LEVEL " << iChannelID
1374                                                          << " " << iFxSend                                                          << " " << iFxSend
1375                                                          << " " << pFxSendInfo->level << endl;                                                          << " " << pFxSendInfo->level << endl;
1376                                          #endif                                          #endif
# Line 1296  bool MainForm::saveSessionFile ( const Q Line 1382  bool MainForm::saveSessionFile ( const Q
1382                                  }                                  }
1383                          #endif                          #endif
1384                                  ts << endl;                                  ts << endl;
1385                                    // Go for next channel...
1386                                    ++iChannelID;
1387                          }                          }
1388                  }                  }
1389                  // Try to keep it snappy :)                  // Try to keep it snappy :)
# Line 1347  void MainForm::sessionDirty (void) Line 1435  void MainForm::sessionDirty (void)
1435    
1436    
1437  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1438  // qsamplerMainForm -- File Action slots.  // QSampler::MainForm -- File Action slots.
1439    
1440  // Create a new sampler session.  // Create a new sampler session.
1441  void MainForm::fileNew (void)  void MainForm::fileNew (void)
# Line 1371  void MainForm::fileOpenRecent (void) Line 1459  void MainForm::fileOpenRecent (void)
1459          // Retrive filename index from action data...          // Retrive filename index from action data...
1460          QAction *pAction = qobject_cast<QAction *> (sender());          QAction *pAction = qobject_cast<QAction *> (sender());
1461          if (pAction && m_pOptions) {          if (pAction && m_pOptions) {
1462                  int iIndex = pAction->data().toInt();                  const int iIndex = pAction->data().toInt();
1463                  if (iIndex >= 0 && iIndex < m_pOptions->recentFiles.count()) {                  if (iIndex >= 0 && iIndex < m_pOptions->recentFiles.count()) {
1464                          QString sFilename = m_pOptions->recentFiles[iIndex];                          QString sFilename = m_pOptions->recentFiles[iIndex];
1465                          // Check if we can safely close the current session...                          // Check if we can safely close the current session...
# Line 1401  void MainForm::fileSaveAs (void) Line 1489  void MainForm::fileSaveAs (void)
1489  // Reset the sampler instance.  // Reset the sampler instance.
1490  void MainForm::fileReset (void)  void MainForm::fileReset (void)
1491  {  {
1492          if (m_pClient == NULL)          if (m_pClient == nullptr)
1493                  return;                  return;
1494    
1495          // Ask user whether he/she want's an internal sampler reset...          // Ask user whether he/she want's an internal sampler reset...
1496          if (QMessageBox::warning(this,          if (m_pOptions && m_pOptions->bConfirmReset) {
1497                  QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sTitle = tr("Warning");
1498                  tr("Resetting the sampler instance will close\n"                  const QString& sText = tr(
1499                  "all device and channel configurations.\n\n"                          "Resetting the sampler instance will close\n"
1500                  "Please note that this operation may cause\n"                          "all device and channel configurations.\n\n"
1501                  "temporary MIDI and Audio disruption.\n\n"                          "Please note that this operation may cause\n"
1502                  "Do you want to reset the sampler engine now?"),                          "temporary MIDI and Audio disruption.\n\n"
1503                  QMessageBox::Ok | QMessageBox::Cancel)                          "Do you want to reset the sampler engine now?");
1504                  == QMessageBox::Cancel)          #if 0
1505                  return;                  if (QMessageBox::warning(this, sTitle, sText,
1506                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1507                            return;
1508            #else
1509                    QMessageBox mbox(this);
1510                    mbox.setIcon(QMessageBox::Warning);
1511                    mbox.setWindowTitle(sTitle);
1512                    mbox.setText(sText);
1513                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1514                    QCheckBox cbox(tr("Don't ask this again"));
1515                    cbox.setChecked(false);
1516                    cbox.blockSignals(true);
1517                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1518                    if (mbox.exec() == QMessageBox::Cancel)
1519                            return;
1520                    if (cbox.isChecked())
1521                            m_pOptions->bConfirmReset = false;
1522            #endif
1523            }
1524    
1525          // Trye closing the current session, first...          // Trye closing the current session, first...
1526          if (!closeSession(true))          if (!closeSession(true))
# Line 1439  void MainForm::fileReset (void) Line 1545  void MainForm::fileReset (void)
1545  // Restart the client/server instance.  // Restart the client/server instance.
1546  void MainForm::fileRestart (void)  void MainForm::fileRestart (void)
1547  {  {
1548          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1549                  return;                  return;
1550    
1551          bool bRestart = true;          bool bRestart = true;
1552    
1553          // Ask user whether he/she want's a complete restart...          // Ask user whether he/she want's a complete restart...
1554          // (if we're currently up and running)          // (if we're currently up and running)
1555          if (bRestart && m_pClient) {          if (m_pOptions && m_pOptions->bConfirmRestart) {
1556                  bRestart = (QMessageBox::warning(this,                  const QString& sTitle = tr("Warning");
1557                          QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sText = tr(
1558                          tr("New settings will be effective after\n"                          "New settings will be effective after\n"
1559                          "restarting the client/server connection.\n\n"                          "restarting the client/server connection.\n\n"
1560                          "Please note that this operation may cause\n"                          "Please note that this operation may cause\n"
1561                          "temporary MIDI and Audio disruption.\n\n"                          "temporary MIDI and Audio disruption.\n\n"
1562                          "Do you want to restart the connection now?"),                          "Do you want to restart the connection now?");
1563                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok);          #if 0
1564                    if (QMessageBox::warning(this, sTitle, sText,
1565                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1566                            bRestart = false;
1567            #else
1568                    QMessageBox mbox(this);
1569                    mbox.setIcon(QMessageBox::Warning);
1570                    mbox.setWindowTitle(sTitle);
1571                    mbox.setText(sText);
1572                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1573                    QCheckBox cbox(tr("Don't ask this again"));
1574                    cbox.setChecked(false);
1575                    cbox.blockSignals(true);
1576                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1577                    if (mbox.exec() == QMessageBox::Cancel)
1578                            bRestart = false;
1579                    else
1580                    if (cbox.isChecked())
1581                            m_pOptions->bConfirmRestart = false;
1582            #endif
1583          }          }
1584    
1585          // Are we still for it?          // Are we still for it?
# Line 1476  void MainForm::fileExit (void) Line 1601  void MainForm::fileExit (void)
1601    
1602    
1603  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1604  // qsamplerMainForm -- Edit Action slots.  // QSampler::MainForm -- Edit Action slots.
1605    
1606  // Add a new sampler channel.  // Add a new sampler channel.
1607  void MainForm::editAddChannel (void)  void MainForm::editAddChannel (void)
1608  {  {
1609          if (m_pClient == NULL)          ++m_iDirtySetup;
1610            addChannelStrip();
1611            --m_iDirtySetup;
1612    }
1613    
1614    void MainForm::addChannelStrip (void)
1615    {
1616            if (m_pClient == nullptr)
1617                  return;                  return;
1618    
1619          // Just create the channel instance...          // Just create the channel instance...
1620          Channel *pChannel = new Channel();          Channel *pChannel = new Channel();
1621          if (pChannel == NULL)          if (pChannel == nullptr)
1622                  return;                  return;
1623    
1624          // Before we show it up, may be we'll          // Before we show it up, may be we'll
# Line 1504  void MainForm::editAddChannel (void) Line 1636  void MainForm::editAddChannel (void)
1636          }          }
1637    
1638          // Do we auto-arrange?          // Do we auto-arrange?
1639          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
1640    
1641          // Make that an overall update.          // Make that an overall update.
1642          m_iDirtyCount++;          m_iDirtyCount++;
# Line 1516  void MainForm::editAddChannel (void) Line 1647  void MainForm::editAddChannel (void)
1647  // Remove current sampler channel.  // Remove current sampler channel.
1648  void MainForm::editRemoveChannel (void)  void MainForm::editRemoveChannel (void)
1649  {  {
1650          if (m_pClient == NULL)          ++m_iDirtySetup;
1651            removeChannelStrip();
1652            --m_iDirtySetup;
1653    }
1654    
1655    void MainForm::removeChannelStrip (void)
1656    {
1657            if (m_pClient == nullptr)
1658                  return;                  return;
1659    
1660          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1661          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1662                  return;                  return;
1663    
1664          Channel *pChannel = pChannelStrip->channel();          Channel *pChannel = pChannelStrip->channel();
1665          if (pChannel == NULL)          if (pChannel == nullptr)
1666                  return;                  return;
1667    
1668          // Prompt user if he/she's sure about this...          // Prompt user if he/she's sure about this...
1669          if (m_pOptions && m_pOptions->bConfirmRemove) {          if (m_pOptions && m_pOptions->bConfirmRemove) {
1670                  if (QMessageBox::warning(this,                  const QString& sTitle = tr("Warning");
1671                          QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sText = tr(
1672                          tr("About to remove channel:\n\n"                          "About to remove channel:\n\n"
1673                          "%1\n\n"                          "%1\n\n"
1674                          "Are you sure?")                          "Are you sure?")
1675                          .arg(pChannelStrip->windowTitle()),                          .arg(pChannelStrip->windowTitle());
1676                          QMessageBox::Ok | QMessageBox::Cancel)          #if 0
1677                          == QMessageBox::Cancel)                  if (QMessageBox::warning(this, sTitle, sText,
1678                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1679                          return;                          return;
1680            #else
1681                    QMessageBox mbox(this);
1682                    mbox.setIcon(QMessageBox::Warning);
1683                    mbox.setWindowTitle(sTitle);
1684                    mbox.setText(sText);
1685                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1686                    QCheckBox cbox(tr("Don't ask this again"));
1687                    cbox.setChecked(false);
1688                    cbox.blockSignals(true);
1689                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1690                    if (mbox.exec() == QMessageBox::Cancel)
1691                            return;
1692                    if (cbox.isChecked())
1693                            m_pOptions->bConfirmRemove = false;
1694            #endif
1695          }          }
1696    
1697          // Remove the existing sampler channel.          // Remove the existing sampler channel.
1698          if (!pChannel->removeChannel())          if (!pChannel->removeChannel())
1699                  return;                  return;
1700    
         // We'll be dirty, for sure...  
         m_iDirtyCount++;  
   
1701          // Just delete the channel strip.          // Just delete the channel strip.
1702          destroyChannelStrip(pChannelStrip);          destroyChannelStrip(pChannelStrip);
1703    
1704            // We'll be dirty, for sure...
1705            m_iDirtyCount++;
1706            stabilizeForm();
1707  }  }
1708    
1709    
1710  // Setup current sampler channel.  // Setup current sampler channel.
1711  void MainForm::editSetupChannel (void)  void MainForm::editSetupChannel (void)
1712  {  {
1713          if (m_pClient == NULL)          if (m_pClient == nullptr)
1714                  return;                  return;
1715    
1716          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1717          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1718                  return;                  return;
1719    
1720          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1570  void MainForm::editSetupChannel (void) Line 1725  void MainForm::editSetupChannel (void)
1725  // Edit current sampler channel.  // Edit current sampler channel.
1726  void MainForm::editEditChannel (void)  void MainForm::editEditChannel (void)
1727  {  {
1728          if (m_pClient == NULL)          if (m_pClient == nullptr)
1729                  return;                  return;
1730    
1731          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1732          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1733                  return;                  return;
1734    
1735          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1585  void MainForm::editEditChannel (void) Line 1740  void MainForm::editEditChannel (void)
1740  // Reset current sampler channel.  // Reset current sampler channel.
1741  void MainForm::editResetChannel (void)  void MainForm::editResetChannel (void)
1742  {  {
1743          if (m_pClient == NULL)          if (m_pClient == nullptr)
1744                  return;                  return;
1745    
1746          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1747          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1748                  return;                  return;
1749    
1750          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1600  void MainForm::editResetChannel (void) Line 1755  void MainForm::editResetChannel (void)
1755  // Reset all sampler channels.  // Reset all sampler channels.
1756  void MainForm::editResetAllChannels (void)  void MainForm::editResetAllChannels (void)
1757  {  {
1758          if (m_pClient == NULL)          if (m_pClient == nullptr)
1759                  return;                  return;
1760    
1761          // Invoque the channel strip procedure,          // Invoque the channel strip procedure,
1762          // for all channels out there...          // for all channels out there...
1763          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1764          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
1765          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {                  = m_pWorkspace->subWindowList();
1766                  ChannelStrip *pChannelStrip = NULL;          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
1767                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                  ChannelStrip *pChannelStrip
1768                  if (pMdiSubWindow)                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
1769                  if (pChannelStrip)                  if (pChannelStrip)
1770                          pChannelStrip->channelReset();                          pChannelStrip->channelReset();
1771          }          }
# Line 1620  void MainForm::editResetAllChannels (voi Line 1774  void MainForm::editResetAllChannels (voi
1774    
1775    
1776  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1777  // qsamplerMainForm -- View Action slots.  // QSampler::MainForm -- View Action slots.
1778    
1779  // Show/hide the main program window menubar.  // Show/hide the main program window menubar.
1780  void MainForm::viewMenubar ( bool bOn )  void MainForm::viewMenubar ( bool bOn )
# Line 1670  void MainForm::viewMessages ( bool bOn ) Line 1824  void MainForm::viewMessages ( bool bOn )
1824  // Show/hide the MIDI instrument list-view form.  // Show/hide the MIDI instrument list-view form.
1825  void MainForm::viewInstruments (void)  void MainForm::viewInstruments (void)
1826  {  {
1827          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1828                  return;                  return;
1829    
1830          if (m_pInstrumentListForm) {          if (m_pInstrumentListForm) {
# Line 1689  void MainForm::viewInstruments (void) Line 1843  void MainForm::viewInstruments (void)
1843  // Show/hide the device configurator form.  // Show/hide the device configurator form.
1844  void MainForm::viewDevices (void)  void MainForm::viewDevices (void)
1845  {  {
1846          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1847                  return;                  return;
1848    
1849          if (m_pDeviceForm) {          if (m_pDeviceForm) {
# Line 1708  void MainForm::viewDevices (void) Line 1862  void MainForm::viewDevices (void)
1862  // Show options dialog.  // Show options dialog.
1863  void MainForm::viewOptions (void)  void MainForm::viewOptions (void)
1864  {  {
1865          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1866                  return;                  return;
1867    
1868          OptionsForm* pOptionsForm = new OptionsForm(this);          OptionsForm* pOptionsForm = new OptionsForm(this);
# Line 1720  void MainForm::viewOptions (void) Line 1874  void MainForm::viewOptions (void)
1874                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)
1875                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();
1876                  // To track down deferred or immediate changes.                  // To track down deferred or immediate changes.
1877                  QString sOldServerHost      = m_pOptions->sServerHost;                  const QString sOldServerHost      = m_pOptions->sServerHost;
1878                  int     iOldServerPort      = m_pOptions->iServerPort;                  const int     iOldServerPort      = m_pOptions->iServerPort;
1879                  int     iOldServerTimeout   = m_pOptions->iServerTimeout;                  const int     iOldServerTimeout   = m_pOptions->iServerTimeout;
1880                  bool    bOldServerStart     = m_pOptions->bServerStart;                  const bool    bOldServerStart     = m_pOptions->bServerStart;
1881                  QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;                  const QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;
1882                  bool    bOldMessagesLog     = m_pOptions->bMessagesLog;                  const bool    bOldMessagesLog     = m_pOptions->bMessagesLog;
1883                  QString sOldMessagesLogPath = m_pOptions->sMessagesLogPath;                  const QString sOldMessagesLogPath = m_pOptions->sMessagesLogPath;
1884                  QString sOldDisplayFont     = m_pOptions->sDisplayFont;                  const QString sOldDisplayFont     = m_pOptions->sDisplayFont;
1885                  bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;                  const bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1886                  int     iOldMaxVolume       = m_pOptions->iMaxVolume;                  const int     iOldMaxVolume       = m_pOptions->iMaxVolume;
1887                  QString sOldMessagesFont    = m_pOptions->sMessagesFont;                  const QString sOldMessagesFont    = m_pOptions->sMessagesFont;
1888                  bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;                  const bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;
1889                  bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;                  const bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;
1890                  int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;                  const int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;
1891                  int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;                  const int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1892                  bool    bOldCompletePath    = m_pOptions->bCompletePath;                  const bool    bOldCompletePath    = m_pOptions->bCompletePath;
1893                  bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;                  const bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1894                  int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;                  const int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1895                  int     iOldBaseFontSize    = m_pOptions->iBaseFontSize;                  const int     iOldBaseFontSize    = m_pOptions->iBaseFontSize;
1896                  // Load the current setup settings.                  // Load the current setup settings.
1897                  pOptionsForm->setup(m_pOptions);                  pOptionsForm->setup(m_pOptions);
1898                  // Show the setup dialog...                  // Show the setup dialog...
# Line 1750  void MainForm::viewOptions (void) Line 1904  void MainForm::viewOptions (void)
1904                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)     ||                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)     ||
1905                                  (iOldBaseFontSize   !=  m_pOptions->iBaseFontSize)) {                                  (iOldBaseFontSize   !=  m_pOptions->iBaseFontSize)) {
1906                                  QMessageBox::information(this,                                  QMessageBox::information(this,
1907                                          QSAMPLER_TITLE ": " + tr("Information"),                                          tr("Information"),
1908                                          tr("Some settings may be only effective\n"                                          tr("Some settings may be only effective\n"
1909                                          "next time you start this program."));                                          "next time you start this program."));
1910                                  updateMessagesCapture();                                  updateMessagesCapture();
# Line 1801  void MainForm::viewOptions (void) Line 1955  void MainForm::viewOptions (void)
1955    
1956    
1957  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1958  // qsamplerMainForm -- Channels action slots.  // QSampler::MainForm -- Channels action slots.
1959    
1960  // Arrange channel strips.  // Arrange channel strips.
1961  void MainForm::channelsArrange (void)  void MainForm::channelsArrange (void)
1962  {  {
1963          // Full width vertical tiling          // Full width vertical tiling
1964          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
1965                    = m_pWorkspace->subWindowList();
1966          if (wlist.isEmpty())          if (wlist.isEmpty())
1967                  return;                  return;
1968    
1969          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1970          int y = 0;          int y = 0;
1971          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
1972                  ChannelStrip *pChannelStrip = NULL;                  pMdiSubWindow->adjustSize();
1973                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                  const QRect& frameRect
1974                  if (pMdiSubWindow)                          = pMdiSubWindow->frameGeometry();
1975                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  int w = m_pWorkspace->width();
1976                  if (pChannelStrip) {                  if (w < frameRect.width())
1977                  /*  if (pChannelStrip->testWState(WState_Maximized | WState_Minimized)) {                          w = frameRect.width();
1978                                  // Prevent flicker...                  const int h = frameRect.height();
1979                                  pChannelStrip->hide();                  pMdiSubWindow->setGeometry(0, y, w, h);
1980                                  pChannelStrip->showNormal();                  y += h;
                         }   */  
                         pChannelStrip->adjustSize();  
                         int iWidth  = m_pWorkspace->width();  
                         if (iWidth < pChannelStrip->width())  
                                 iWidth = pChannelStrip->width();  
                 //  int iHeight = pChannelStrip->height()  
                 //              + pChannelStrip->parentWidget()->baseSize().height();  
                         int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();  
                         pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);  
                         y += iHeight;  
                 }  
1981          }          }
1982          m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
1983    
# Line 1844  void MainForm::channelsArrange (void) Line 1988  void MainForm::channelsArrange (void)
1988  // Auto-arrange channel strips.  // Auto-arrange channel strips.
1989  void MainForm::channelsAutoArrange ( bool bOn )  void MainForm::channelsAutoArrange ( bool bOn )
1990  {  {
1991          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1992                  return;                  return;
1993    
1994          // Toggle the auto-arrange flag.          // Toggle the auto-arrange flag.
1995          m_pOptions->bAutoArrange = bOn;          m_pOptions->bAutoArrange = bOn;
1996    
1997          // If on, update whole workspace...          // If on, update whole workspace...
1998          if (m_pOptions->bAutoArrange)          channelsArrangeAuto();
1999    }
2000    
2001    
2002    void MainForm::channelsArrangeAuto (void)
2003    {
2004            if (m_pOptions && m_pOptions->bAutoArrange)
2005                  channelsArrange();                  channelsArrange();
2006  }  }
2007    
2008    
2009  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2010  // qsamplerMainForm -- Help Action slots.  // QSampler::MainForm -- Help Action slots.
2011    
2012  // Show information about the Qt toolkit.  // Show information about the Qt toolkit.
2013  void MainForm::helpAboutQt (void)  void MainForm::helpAboutQt (void)
# Line 1869  void MainForm::helpAboutQt (void) Line 2019  void MainForm::helpAboutQt (void)
2019  // Show information about application program.  // Show information about application program.
2020  void MainForm::helpAbout (void)  void MainForm::helpAbout (void)
2021  {  {
2022          // Stuff the about box text...          QStringList list;
         QString sText = "<p>\n";  
         sText += "<b>" QSAMPLER_TITLE " - " + tr(QSAMPLER_SUBTITLE) + "</b><br />\n";  
         sText += "<br />\n";  
         sText += tr("Version") + ": <b>" QSAMPLER_VERSION "</b><br />\n";  
         sText += "<small>" + tr("Build") + ": " __DATE__ " " __TIME__ "</small><br />\n";  
2023  #ifdef CONFIG_DEBUG  #ifdef CONFIG_DEBUG
2024          sText += "<small><font color=\"red\">";          list << tr("Debugging option enabled.");
         sText += tr("Debugging option enabled.");  
         sText += "</font></small><br />";  
2025  #endif  #endif
2026  #ifndef CONFIG_LIBGIG  #ifndef CONFIG_LIBGIG
2027          sText += "<small><font color=\"red\">";          list << tr("GIG (libgig) file support disabled.");
         sText += tr("GIG (libgig) file support disabled.");  
         sText += "</font></small><br />";  
2028  #endif  #endif
2029  #ifndef CONFIG_INSTRUMENT_NAME  #ifndef CONFIG_INSTRUMENT_NAME
2030          sText += "<small><font color=\"red\">";          list << tr("LSCP (liblscp) instrument_name support disabled.");
         sText += tr("LSCP (liblscp) instrument_name support disabled.");  
         sText += "</font></small><br />";  
2031  #endif  #endif
2032  #ifndef CONFIG_MUTE_SOLO  #ifndef CONFIG_MUTE_SOLO
2033          sText += "<small><font color=\"red\">";          list << tr("Sampler channel Mute/Solo support disabled.");
         sText += tr("Sampler channel Mute/Solo support disabled.");  
         sText += "</font></small><br />";  
2034  #endif  #endif
2035  #ifndef CONFIG_AUDIO_ROUTING  #ifndef CONFIG_AUDIO_ROUTING
2036          sText += "<small><font color=\"red\">";          list << tr("LSCP (liblscp) audio_routing support disabled.");
         sText += tr("LSCP (liblscp) audio_routing support disabled.");  
         sText += "</font></small><br />";  
2037  #endif  #endif
2038  #ifndef CONFIG_FXSEND  #ifndef CONFIG_FXSEND
2039          sText += "<small><font color=\"red\">";          list << tr("Sampler channel Effect Sends support disabled.");
         sText += tr("Sampler channel Effect Sends support disabled.");  
         sText += "</font></small><br />";  
2040  #endif  #endif
2041  #ifndef CONFIG_VOLUME  #ifndef CONFIG_VOLUME
2042          sText += "<small><font color=\"red\">";          list << tr("Global volume support disabled.");
         sText += tr("Global volume support disabled.");  
         sText += "</font></small><br />";  
2043  #endif  #endif
2044  #ifndef CONFIG_MIDI_INSTRUMENT  #ifndef CONFIG_MIDI_INSTRUMENT
2045          sText += "<small><font color=\"red\">";          list << tr("MIDI instrument mapping support disabled.");
         sText += tr("MIDI instrument mapping support disabled.");  
         sText += "</font></small><br />";  
2046  #endif  #endif
2047  #ifndef CONFIG_EDIT_INSTRUMENT  #ifndef CONFIG_EDIT_INSTRUMENT
2048          sText += "<small><font color=\"red\">";          list << tr("Instrument editing support disabled.");
         sText += tr("Instrument editing support disabled.");  
         sText += "</font></small><br />";  
2049  #endif  #endif
2050  #ifndef CONFIG_EVENT_CHANNEL_MIDI  #ifndef CONFIG_EVENT_CHANNEL_MIDI
2051          sText += "<small><font color=\"red\">";          list << tr("Channel MIDI event support disabled.");
         sText += tr("Channel MIDI event support disabled.");  
         sText += "</font></small><br />";  
2052  #endif  #endif
2053  #ifndef CONFIG_EVENT_DEVICE_MIDI  #ifndef CONFIG_EVENT_DEVICE_MIDI
2054          sText += "<small><font color=\"red\">";          list << tr("Device MIDI event support disabled.");
         sText += tr("Device MIDI event support disabled.");  
         sText += "</font></small><br />";  
2055  #endif  #endif
2056  #ifndef CONFIG_MAX_VOICES  #ifndef CONFIG_MAX_VOICES
2057          sText += "<small><font color=\"red\">";          list << tr("Runtime max. voices / disk streams support disabled.");
         sText += tr("Runtime max. voices / disk streams support disabled.");  
         sText += "</font></small><br />";  
2058  #endif  #endif
2059    
2060            // Stuff the about box text...
2061            QString sText = "<p>\n";
2062            sText += "<b>" QSAMPLER_TITLE " - " + tr(QSAMPLER_SUBTITLE) + "</b><br />\n";
2063            sText += "<br />\n";
2064            sText += tr("Version") + ": <b>" CONFIG_BUILD_VERSION "</b><br />\n";
2065    //      sText += "<small>" + tr("Build") + ": " CONFIG_BUILD_DATE "</small><br />\n";
2066            if (!list.isEmpty()) {
2067                    sText += "<small><font color=\"red\">";
2068                    sText += list.join("<br />\n");
2069                    sText += "</font></small>";
2070            }
2071          sText += "<br />\n";          sText += "<br />\n";
2072          sText += tr("Using") + ": ";          sText += tr("Using") + ": ";
2073          sText += ::lscp_client_package();          sText += ::lscp_client_package();
# Line 1959  void MainForm::helpAbout (void) Line 2092  void MainForm::helpAbout (void)
2092          sText += "</small>";          sText += "</small>";
2093          sText += "</p>\n";          sText += "</p>\n";
2094    
2095          QMessageBox::about(this, tr("About") + " " QSAMPLER_TITLE, sText);          QMessageBox::about(this, tr("About"), sText);
2096  }  }
2097    
2098    
2099  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2100  // qsamplerMainForm -- Main window stabilization.  // QSampler::MainForm -- Main window stabilization.
2101    
2102  void MainForm::stabilizeForm (void)  void MainForm::stabilizeForm (void)
2103  {  {
# Line 1972  void MainForm::stabilizeForm (void) Line 2105  void MainForm::stabilizeForm (void)
2105          QString sSessionName = sessionName(m_sFilename);          QString sSessionName = sessionName(m_sFilename);
2106          if (m_iDirtyCount > 0)          if (m_iDirtyCount > 0)
2107                  sSessionName += " *";                  sSessionName += " *";
2108          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));          setWindowTitle(sSessionName);
2109    
2110          // Update the main menu state...          // Update the main menu state...
2111          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
2112          bool bHasClient = (m_pOptions != NULL && m_pClient != NULL);          const QList<QMdiSubWindow *>& wlist = m_pWorkspace->subWindowList();
2113          bool bHasChannel = (bHasClient && pChannelStrip != NULL);          const bool bHasClient = (m_pOptions != nullptr && m_pClient != nullptr);
2114          bool bHasChannels = (bHasClient && m_pWorkspace->subWindowList().count() > 0);          const bool bHasChannel = (bHasClient && pChannelStrip != nullptr);
2115            const bool bHasChannels = (bHasClient && wlist.count() > 0);
2116          m_ui.fileNewAction->setEnabled(bHasClient);          m_ui.fileNewAction->setEnabled(bHasClient);
2117          m_ui.fileOpenAction->setEnabled(bHasClient);          m_ui.fileOpenAction->setEnabled(bHasClient);
2118          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
2119          m_ui.fileSaveAsAction->setEnabled(bHasClient);          m_ui.fileSaveAsAction->setEnabled(bHasClient);
2120          m_ui.fileResetAction->setEnabled(bHasClient);          m_ui.fileResetAction->setEnabled(bHasClient);
2121          m_ui.fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);          m_ui.fileRestartAction->setEnabled(bHasClient || m_pServer == nullptr);
2122          m_ui.editAddChannelAction->setEnabled(bHasClient);          m_ui.editAddChannelAction->setEnabled(bHasClient);
2123          m_ui.editRemoveChannelAction->setEnabled(bHasChannel);          m_ui.editRemoveChannelAction->setEnabled(bHasChannel);
2124          m_ui.editSetupChannelAction->setEnabled(bHasChannel);          m_ui.editSetupChannelAction->setEnabled(bHasChannel);
# Line 2058  void MainForm::volumeChanged ( int iVolu Line 2192  void MainForm::volumeChanged ( int iVolu
2192                  m_pVolumeSpinBox->setValue(iVolume);                  m_pVolumeSpinBox->setValue(iVolume);
2193    
2194          // Do it as commanded...          // Do it as commanded...
2195          float fVolume = 0.01f * float(iVolume);          const float fVolume = 0.01f * float(iVolume);
2196          if (::lscp_set_volume(m_pClient, fVolume) == LSCP_OK)          if (::lscp_set_volume(m_pClient, fVolume) == LSCP_OK)
2197                  appendMessages(QObject::tr("Volume: %1.").arg(fVolume));                  appendMessages(QObject::tr("Volume: %1.").arg(fVolume));
2198          else          else
# Line 2093  void MainForm::channelStripChanged ( Cha Line 2227  void MainForm::channelStripChanged ( Cha
2227  void MainForm::updateSession (void)  void MainForm::updateSession (void)
2228  {  {
2229  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
2230          int iVolume = ::lroundf(100.0f * ::lscp_get_volume(m_pClient));          const int iVolume = ::lroundf(100.0f * ::lscp_get_volume(m_pClient));
2231          m_iVolumeChanging++;          m_iVolumeChanging++;
2232          m_pVolumeSlider->setValue(iVolume);          m_pVolumeSlider->setValue(iVolume);
2233          m_pVolumeSpinBox->setValue(iVolume);          m_pVolumeSpinBox->setValue(iVolume);
# Line 2101  void MainForm::updateSession (void) Line 2235  void MainForm::updateSession (void)
2235  #endif  #endif
2236  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
2237          // FIXME: Make some room for default instrument maps...          // FIXME: Make some room for default instrument maps...
2238          int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);          const int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);
2239          if (iMaps < 0)          if (iMaps < 0)
2240                  appendMessagesClient("lscp_get_midi_instrument_maps");                  appendMessagesClient("lscp_get_midi_instrument_maps");
2241          else if (iMaps < 1) {          else if (iMaps < 1) {
# Line 2115  void MainForm::updateSession (void) Line 2249  void MainForm::updateSession (void)
2249          updateAllChannelStrips(false);          updateAllChannelStrips(false);
2250    
2251          // Do we auto-arrange?          // Do we auto-arrange?
2252          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
2253    
2254          // Remember to refresh devices and instruments...          // Remember to refresh devices and instruments...
2255          if (m_pInstrumentListForm)          if (m_pInstrumentListForm)
# Line 2128  void MainForm::updateSession (void) Line 2261  void MainForm::updateSession (void)
2261    
2262  void MainForm::updateAllChannelStrips ( bool bRemoveDeadStrips )  void MainForm::updateAllChannelStrips ( bool bRemoveDeadStrips )
2263  {  {
2264            // Skip if setting up a new channel strip...
2265            if (m_iDirtySetup > 0)
2266                    return;
2267    
2268          // Retrieve the current channel list.          // Retrieve the current channel list.
2269          int *piChannelIDs = ::lscp_list_channels(m_pClient);          int *piChannelIDs = ::lscp_list_channels(m_pClient);
2270          if (piChannelIDs == NULL) {          if (piChannelIDs == nullptr) {
2271                  if (::lscp_client_get_errno(m_pClient)) {                  if (::lscp_client_get_errno(m_pClient)) {
2272                          appendMessagesClient("lscp_list_channels");                          appendMessagesClient("lscp_list_channels");
2273                          appendMessagesError(                          appendMessagesError(
# Line 2145  void MainForm::updateAllChannelStrips ( Line 2282  void MainForm::updateAllChannelStrips (
2282                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));
2283                  }                  }
2284                  // Do we auto-arrange?                  // Do we auto-arrange?
2285                  if (m_pOptions && m_pOptions->bAutoArrange)                  channelsArrangeAuto();
                         channelsArrange();  
2286                  // remove dead channel strips                  // remove dead channel strips
2287                  if (bRemoveDeadStrips) {                  if (bRemoveDeadStrips) {
2288                          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();                          const QList<QMdiSubWindow *>& wlist
2289                          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {                                  = m_pWorkspace->subWindowList();
2290                                  ChannelStrip *pChannelStrip = NULL;                          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2291                                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                                  ChannelStrip *pChannelStrip
2292                                  if (pMdiSubWindow)                                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2293                                  if (pChannelStrip) {                                  if (pChannelStrip) {
2294                                          bool bExists = false;                                          bool bExists = false;
2295                                          for (int j = 0; piChannelIDs[j] >= 0; ++j) {                                          for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {
2296                                                  if (!pChannelStrip->channel())                                                  Channel *pChannel = pChannelStrip->channel();
2297                                                    if (pChannel == nullptr)
2298                                                          break;                                                          break;
2299                                                  if (piChannelIDs[j] == pChannelStrip->channel()->channelID()) {                                                  if (piChannelIDs[iChannel] == pChannel->channelID()) {
2300                                                          // strip exists, don't touch it                                                          // strip exists, don't touch it
2301                                                          bExists = true;                                                          bExists = true;
2302                                                          break;                                                          break;
# Line 2181  void MainForm::updateAllChannelStrips ( Line 2317  void MainForm::updateAllChannelStrips (
2317  // Update the recent files list and menu.  // Update the recent files list and menu.
2318  void MainForm::updateRecentFiles ( const QString& sFilename )  void MainForm::updateRecentFiles ( const QString& sFilename )
2319  {  {
2320          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2321                  return;                  return;
2322    
2323          // Remove from list if already there (avoid duplicates)          // Remove from list if already there (avoid duplicates)
2324          int iIndex = m_pOptions->recentFiles.indexOf(sFilename);          const int iIndex = m_pOptions->recentFiles.indexOf(sFilename);
2325          if (iIndex >= 0)          if (iIndex >= 0)
2326                  m_pOptions->recentFiles.removeAt(iIndex);                  m_pOptions->recentFiles.removeAt(iIndex);
2327          // Put it to front...          // Put it to front...
# Line 2196  void MainForm::updateRecentFiles ( const Line 2332  void MainForm::updateRecentFiles ( const
2332  // Update the recent files list and menu.  // Update the recent files list and menu.
2333  void MainForm::updateRecentFilesMenu (void)  void MainForm::updateRecentFilesMenu (void)
2334  {  {
2335          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2336                  return;                  return;
2337    
2338          // Time to keep the list under limits.          // Time to keep the list under limits.
# Line 2224  void MainForm::updateRecentFilesMenu (vo Line 2360  void MainForm::updateRecentFilesMenu (vo
2360  void MainForm::updateInstrumentNames (void)  void MainForm::updateInstrumentNames (void)
2361  {  {
2362          // Full channel list update...          // Full channel list update...
2363          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2364                    = m_pWorkspace->subWindowList();
2365          if (wlist.isEmpty())          if (wlist.isEmpty())
2366                  return;                  return;
2367    
2368          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2369          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2370                  ChannelStrip *pChannelStrip = (ChannelStrip *) wlist.at(iChannel);                  ChannelStrip *pChannelStrip
2371                            = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2372                  if (pChannelStrip)                  if (pChannelStrip)
2373                          pChannelStrip->updateInstrumentName(true);                          pChannelStrip->updateInstrumentName(true);
2374          }          }
# Line 2241  void MainForm::updateInstrumentNames (vo Line 2379  void MainForm::updateInstrumentNames (vo
2379  // Force update of the channels display font.  // Force update of the channels display font.
2380  void MainForm::updateDisplayFont (void)  void MainForm::updateDisplayFont (void)
2381  {  {
2382          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2383                  return;                  return;
2384    
2385          // Check if display font is legal.          // Check if display font is legal.
2386          if (m_pOptions->sDisplayFont.isEmpty())          if (m_pOptions->sDisplayFont.isEmpty())
2387                  return;                  return;
2388    
2389          // Realize it.          // Realize it.
2390          QFont font;          QFont font;
2391          if (!font.fromString(m_pOptions->sDisplayFont))          if (!font.fromString(m_pOptions->sDisplayFont))
2392                  return;                  return;
2393    
2394          // Full channel list update...          // Full channel list update...
2395          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2396                    = m_pWorkspace->subWindowList();
2397          if (wlist.isEmpty())          if (wlist.isEmpty())
2398                  return;                  return;
2399    
2400          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2401          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2402                  ChannelStrip *pChannelStrip = NULL;                  ChannelStrip *pChannelStrip
2403                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2404                  if (pChannelStrip)                  if (pChannelStrip)
2405                          pChannelStrip->setDisplayFont(font);                          pChannelStrip->setDisplayFont(font);
2406          }          }
# Line 2274  void MainForm::updateDisplayFont (void) Line 2412  void MainForm::updateDisplayFont (void)
2412  void MainForm::updateDisplayEffect (void)  void MainForm::updateDisplayEffect (void)
2413  {  {
2414          // Full channel list update...          // Full channel list update...
2415          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2416                    = m_pWorkspace->subWindowList();
2417          if (wlist.isEmpty())          if (wlist.isEmpty())
2418                  return;                  return;
2419    
2420          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2421          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2422                  ChannelStrip *pChannelStrip = NULL;                  ChannelStrip *pChannelStrip
2423                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2424                  if (pChannelStrip)                  if (pChannelStrip)
2425                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2426          }          }
# Line 2294  void MainForm::updateDisplayEffect (void Line 2431  void MainForm::updateDisplayEffect (void
2431  // Force update of the channels maximum volume setting.  // Force update of the channels maximum volume setting.
2432  void MainForm::updateMaxVolume (void)  void MainForm::updateMaxVolume (void)
2433  {  {
2434          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2435                  return;                  return;
2436    
2437  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
# Line 2305  void MainForm::updateMaxVolume (void) Line 2442  void MainForm::updateMaxVolume (void)
2442  #endif  #endif
2443    
2444          // Full channel list update...          // Full channel list update...
2445          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2446                    = m_pWorkspace->subWindowList();
2447          if (wlist.isEmpty())          if (wlist.isEmpty())
2448                  return;                  return;
2449    
2450          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2451          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2452                  ChannelStrip *pChannelStrip = NULL;                  ChannelStrip *pChannelStrip
2453                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2454                  if (pChannelStrip)                  if (pChannelStrip)
2455                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2456          }          }
# Line 2323  void MainForm::updateMaxVolume (void) Line 2459  void MainForm::updateMaxVolume (void)
2459    
2460    
2461  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2462  // qsamplerMainForm -- Messages window form handlers.  // QSampler::MainForm -- Messages window form handlers.
2463    
2464  // Messages output methods.  // Messages output methods.
2465  void MainForm::appendMessages( const QString& s )  void MainForm::appendMessages( const QString& s )
# Line 2348  void MainForm::appendMessagesText( const Line 2484  void MainForm::appendMessagesText( const
2484                  m_pMessages->appendMessagesText(s);                  m_pMessages->appendMessagesText(s);
2485  }  }
2486    
2487  void MainForm::appendMessagesError( const QString& s )  void MainForm::appendMessagesError( const QString& sText )
2488  {  {
2489          if (m_pMessages)          if (m_pMessages)
2490                  m_pMessages->show();                  m_pMessages->show();
2491    
2492          appendMessagesColor(s.simplified(), "#ff0000");          appendMessagesColor(sText.simplified(), "#ff0000");
2493    
2494          // Make it look responsive...:)          // Make it look responsive...:)
2495          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2496    
2497          QMessageBox::critical(this,          if (m_pOptions && m_pOptions->bConfirmError) {
2498                  QSAMPLER_TITLE ": " + tr("Error"), s, QMessageBox::Cancel);                  const QString& sTitle = tr("Error");
2499            #if 0
2500                    QMessageBox::critical(this, sTitle, sText, QMessageBox::Cancel);
2501            #else
2502                    QMessageBox mbox(this);
2503                    mbox.setIcon(QMessageBox::Critical);
2504                    mbox.setWindowTitle(sTitle);
2505                    mbox.setText(sText);
2506                    mbox.setStandardButtons(QMessageBox::Cancel);
2507                    QCheckBox cbox(tr("Don't show this again"));
2508                    cbox.setChecked(false);
2509                    cbox.blockSignals(true);
2510                    mbox.addButton(&cbox, QMessageBox::ActionRole);
2511                    if (mbox.exec() && cbox.isChecked())
2512                            m_pOptions->bConfirmError = false;
2513            #endif
2514            }
2515  }  }
2516    
2517    
2518  // This is a special message format, just for client results.  // This is a special message format, just for client results.
2519  void MainForm::appendMessagesClient( const QString& s )  void MainForm::appendMessagesClient( const QString& s )
2520  {  {
2521          if (m_pClient == NULL)          if (m_pClient == nullptr)
2522                  return;                  return;
2523    
2524          appendMessagesColor(s + QString(": %1 (errno=%2)")          appendMessagesColor(s + QString(": %1 (errno=%2)")
# Line 2381  void MainForm::appendMessagesClient( con Line 2533  void MainForm::appendMessagesClient( con
2533  // Force update of the messages font.  // Force update of the messages font.
2534  void MainForm::updateMessagesFont (void)  void MainForm::updateMessagesFont (void)
2535  {  {
2536          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2537                  return;                  return;
2538    
2539          if (m_pMessages && !m_pOptions->sMessagesFont.isEmpty()) {          if (m_pMessages && !m_pOptions->sMessagesFont.isEmpty()) {
# Line 2395  void MainForm::updateMessagesFont (void) Line 2547  void MainForm::updateMessagesFont (void)
2547  // Update messages window line limit.  // Update messages window line limit.
2548  void MainForm::updateMessagesLimit (void)  void MainForm::updateMessagesLimit (void)
2549  {  {
2550          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2551                  return;                  return;
2552    
2553          if (m_pMessages) {          if (m_pMessages) {
# Line 2410  void MainForm::updateMessagesLimit (void Line 2562  void MainForm::updateMessagesLimit (void
2562  // Enablement of the messages capture feature.  // Enablement of the messages capture feature.
2563  void MainForm::updateMessagesCapture (void)  void MainForm::updateMessagesCapture (void)
2564  {  {
2565          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2566                  return;                  return;
2567    
2568          if (m_pMessages)          if (m_pMessages)
# Line 2419  void MainForm::updateMessagesCapture (vo Line 2571  void MainForm::updateMessagesCapture (vo
2571    
2572    
2573  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2574  // qsamplerMainForm -- MDI channel strip management.  // QSampler::MainForm -- MDI channel strip management.
2575    
2576  // The channel strip creation executive.  // The channel strip creation executive.
2577  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )
2578  {  {
2579          if (m_pClient == NULL || pChannel == NULL)          if (m_pClient == nullptr || pChannel == nullptr)
2580                  return NULL;                  return nullptr;
2581    
2582          // Add a new channel itema...          // Add a new channel itema...
2583          ChannelStrip *pChannelStrip = new ChannelStrip();          ChannelStrip *pChannelStrip = new ChannelStrip();
2584          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
2585                  return NULL;                  return nullptr;
2586    
2587          // Set some initial channel strip options...          // Set some initial channel strip options...
2588          if (m_pOptions) {          if (m_pOptions) {
# Line 2438  ChannelStrip *MainForm::createChannelStr Line 2590  ChannelStrip *MainForm::createChannelStr
2590                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2591                  // We'll need a display font.                  // We'll need a display font.
2592                  QFont font;                  QFont font;
2593                  if (font.fromString(m_pOptions->sDisplayFont))                  if (!m_pOptions->sDisplayFont.isEmpty() &&
2594                            font.fromString(m_pOptions->sDisplayFont))
2595                          pChannelStrip->setDisplayFont(font);                          pChannelStrip->setDisplayFont(font);
2596                  // Maximum allowed volume setting.                  // Maximum allowed volume setting.
2597                  pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                  pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2598          }          }
2599    
2600          // Add it to workspace...          // Add it to workspace...
2601          m_pWorkspace->addSubWindow(pChannelStrip,          QMdiSubWindow *pMdiSubWindow
2602                  Qt::SubWindow | Qt::FramelessWindowHint);                  = m_pWorkspace->addSubWindow(pChannelStrip,
2603                            Qt::SubWindow | Qt::FramelessWindowHint);
2604            pMdiSubWindow->setAttribute(Qt::WA_DeleteOnClose);
2605    
2606          // Actual channel strip setup...          // Actual channel strip setup...
2607          pChannelStrip->setup(pChannel);          pChannelStrip->setup(pChannel);
# Line 2470  void MainForm::destroyChannelStrip ( Cha Line 2625  void MainForm::destroyChannelStrip ( Cha
2625  {  {
2626          QMdiSubWindow *pMdiSubWindow          QMdiSubWindow *pMdiSubWindow
2627                  = static_cast<QMdiSubWindow *> (pChannelStrip->parentWidget());                  = static_cast<QMdiSubWindow *> (pChannelStrip->parentWidget());
2628          if (pMdiSubWindow == NULL)          if (pMdiSubWindow == nullptr)
2629                  return;                  return;
2630    
2631          // Just delete the channel strip.          // Just delete the channel strip.
# Line 2478  void MainForm::destroyChannelStrip ( Cha Line 2633  void MainForm::destroyChannelStrip ( Cha
2633          delete pMdiSubWindow;          delete pMdiSubWindow;
2634    
2635          // Do we auto-arrange?          // Do we auto-arrange?
2636          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
   
         stabilizeForm();  
2637  }  }
2638    
2639    
# Line 2492  ChannelStrip *MainForm::activeChannelStr Line 2644  ChannelStrip *MainForm::activeChannelStr
2644          if (pMdiSubWindow)          if (pMdiSubWindow)
2645                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2646          else          else
2647                  return NULL;                  return nullptr;
2648  }  }
2649    
2650    
2651  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2652  ChannelStrip *MainForm::channelStripAt ( int iChannel )  ChannelStrip *MainForm::channelStripAt ( int iStrip )
2653  {  {
2654          if (!m_pWorkspace) return NULL;          if (!m_pWorkspace) return nullptr;
2655    
2656          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2657                    = m_pWorkspace->subWindowList();
2658          if (wlist.isEmpty())          if (wlist.isEmpty())
2659                  return NULL;                  return nullptr;
2660    
2661          if (iChannel < 0 || iChannel >= wlist.size())          if (iStrip < 0 || iStrip >= wlist.count())
2662                  return NULL;                  return nullptr;
2663    
2664          QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2665          if (pMdiSubWindow)          if (pMdiSubWindow)
2666                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2667          else          else
2668                  return NULL;                  return nullptr;
2669  }  }
2670    
2671    
2672  // Retrieve a channel strip by sampler channel id.  // Retrieve a channel strip by sampler channel id.
2673  ChannelStrip *MainForm::channelStrip ( int iChannelID )  ChannelStrip *MainForm::channelStrip ( int iChannelID )
2674  {  {
2675          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2676                    = m_pWorkspace->subWindowList();
2677          if (wlist.isEmpty())          if (wlist.isEmpty())
2678                  return NULL;                  return nullptr;
2679    
2680          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2681                  ChannelStrip *pChannelStrip = NULL;                  ChannelStrip *pChannelStrip
2682                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2683                  if (pChannelStrip) {                  if (pChannelStrip) {
2684                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
2685                          if (pChannel && pChannel->channelID() == iChannelID)                          if (pChannel && pChannel->channelID() == iChannelID)
# Line 2536  ChannelStrip *MainForm::channelStrip ( i Line 2688  ChannelStrip *MainForm::channelStrip ( i
2688          }          }
2689    
2690          // Not found.          // Not found.
2691          return NULL;          return nullptr;
2692  }  }
2693    
2694    
# Line 2547  void MainForm::channelsMenuAboutToShow ( Line 2699  void MainForm::channelsMenuAboutToShow (
2699          m_ui.channelsMenu->addAction(m_ui.channelsArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsArrangeAction);
2700          m_ui.channelsMenu->addAction(m_ui.channelsAutoArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsAutoArrangeAction);
2701    
2702          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2703                    = m_pWorkspace->subWindowList();
2704          if (!wlist.isEmpty()) {          if (!wlist.isEmpty()) {
2705                  m_ui.channelsMenu->addSeparator();                  m_ui.channelsMenu->addSeparator();
2706                  for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {                  int iStrip = 0;
2707                          ChannelStrip *pChannelStrip = NULL;                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2708                          QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                          ChannelStrip *pChannelStrip
2709                          if (pMdiSubWindow)                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                                 pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2710                          if (pChannelStrip) {                          if (pChannelStrip) {
2711                                  QAction *pAction = m_ui.channelsMenu->addAction(                                  QAction *pAction = m_ui.channelsMenu->addAction(
2712                                          pChannelStrip->windowTitle(),                                          pChannelStrip->windowTitle(),
2713                                          this, SLOT(channelsMenuActivated()));                                          this, SLOT(channelsMenuActivated()));
2714                                  pAction->setCheckable(true);                                  pAction->setCheckable(true);
2715                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);
2716                                  pAction->setData(iChannel);                                  pAction->setData(iStrip);
2717                          }                          }
2718                            ++iStrip;
2719                  }                  }
2720          }          }
2721  }  }
# Line 2573  void MainForm::channelsMenuActivated (vo Line 2726  void MainForm::channelsMenuActivated (vo
2726  {  {
2727          // Retrive channel index from action data...          // Retrive channel index from action data...
2728          QAction *pAction = qobject_cast<QAction *> (sender());          QAction *pAction = qobject_cast<QAction *> (sender());
2729          if (pAction == NULL)          if (pAction == nullptr)
2730                  return;                  return;
2731    
2732          ChannelStrip *pChannelStrip = channelStripAt(pAction->data().toInt());          ChannelStrip *pChannelStrip = channelStripAt(pAction->data().toInt());
# Line 2585  void MainForm::channelsMenuActivated (vo Line 2738  void MainForm::channelsMenuActivated (vo
2738    
2739    
2740  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2741  // qsamplerMainForm -- Timer stuff.  // QSampler::MainForm -- Timer stuff.
2742    
2743  // Set the pseudo-timer delay schedule.  // Set the pseudo-timer delay schedule.
2744  void MainForm::startSchedule ( int iStartDelay )  void MainForm::startSchedule ( int iStartDelay )
# Line 2604  void MainForm::stopSchedule (void) Line 2757  void MainForm::stopSchedule (void)
2757  // Timer slot funtion.  // Timer slot funtion.
2758  void MainForm::timerSlot (void)  void MainForm::timerSlot (void)
2759  {  {
2760          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2761                  return;                  return;
2762    
2763          // Is it the first shot on server start after a few delay?          // Is it the first shot on server start after a few delay?
# Line 2626  void MainForm::timerSlot (void) Line 2779  void MainForm::timerSlot (void)
2779                          ChannelStrip *pChannelStrip = iter.next();                          ChannelStrip *pChannelStrip = iter.next();
2780                          // If successfull, remove from pending list...                          // If successfull, remove from pending list...
2781                          if (pChannelStrip->updateChannelInfo()) {                          if (pChannelStrip->updateChannelInfo()) {
2782                                  int iChannelStrip = m_changedStrips.indexOf(pChannelStrip);                                  const int iChannelStrip = m_changedStrips.indexOf(pChannelStrip);
2783                                  if (iChannelStrip >= 0)                                  if (iChannelStrip >= 0)
2784                                          m_changedStrips.removeAt(iChannelStrip);                                          m_changedStrips.removeAt(iChannelStrip);
2785                          }                          }
# Line 2637  void MainForm::timerSlot (void) Line 2790  void MainForm::timerSlot (void)
2790                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {
2791                                  m_iTimerSlot = 0;                                  m_iTimerSlot = 0;
2792                                  // Update the channel stream usage for each strip...                                  // Update the channel stream usage for each strip...
2793                                  QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();                                  const QList<QMdiSubWindow *>& wlist
2794                                  for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {                                          = m_pWorkspace->subWindowList();
2795                                          ChannelStrip *pChannelStrip = NULL;                                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2796                                          QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                                          ChannelStrip *pChannelStrip
2797                                          if (pMdiSubWindow)                                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                                                 pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2798                                          if (pChannelStrip && pChannelStrip->isVisible())                                          if (pChannelStrip && pChannelStrip->isVisible())
2799                                                  pChannelStrip->updateChannelUsage();                                                  pChannelStrip->updateChannelUsage();
2800                                  }                                  }
2801                          }                          }
2802                  }                  }
2803    
2804            #if CONFIG_LSCP_CLIENT_CONNECTION_LOST
2805                    // If we lost connection to server: Try to automatically reconnect if we
2806                    // did not start the server.
2807                    //
2808                    // TODO: If we started the server, then we might inform the user that
2809                    // the server probably crashed and asking user ONCE whether we should
2810                    // restart the server.
2811                    if (lscp_client_connection_lost(m_pClient) && !m_pServer)
2812                            startAutoReconnectClient();
2813            #endif // CONFIG_LSCP_CLIENT_CONNECTION_LOST
2814          }          }
2815    
2816          // Register the next timer slot.          // Register the next timer slot.
# Line 2656  void MainForm::timerSlot (void) Line 2819  void MainForm::timerSlot (void)
2819    
2820    
2821  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2822  // qsamplerMainForm -- Server stuff.  // QSampler::MainForm -- Server stuff.
2823    
2824  // Start linuxsampler server...  // Start linuxsampler server...
2825  void MainForm::startServer (void)  void MainForm::startServer (void)
2826  {  {
2827          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2828                  return;                  return;
2829    
2830          // Aren't already a client, are we?          // Aren't already a client, are we?
# Line 2671  void MainForm::startServer (void) Line 2834  void MainForm::startServer (void)
2834          // Is the server process instance still here?          // Is the server process instance still here?
2835          if (m_pServer) {          if (m_pServer) {
2836                  if (QMessageBox::warning(this,                  if (QMessageBox::warning(this,
2837                          QSAMPLER_TITLE ": " + tr("Warning"),                          tr("Warning"),
2838                          tr("Could not start the LinuxSampler server.\n\n"                          tr("Could not start the LinuxSampler server.\n\n"
2839                          "Maybe it is already started."),                          "Maybe it is already started."),
2840                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
# Line 2690  void MainForm::startServer (void) Line 2853  void MainForm::startServer (void)
2853    
2854          // OK. Let's build the startup process...          // OK. Let's build the startup process...
2855          m_pServer = new QProcess();          m_pServer = new QProcess();
2856          bForceServerStop = true;          m_bForceServerStop = true;
2857    
2858          // Setup stdout/stderr capture...          // Setup stdout/stderr capture...
2859  //      if (m_pOptions->bStdoutCapture) {          m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);
2860                  m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);          QObject::connect(m_pServer,
2861                  QObject::connect(m_pServer,                  SIGNAL(readyReadStandardOutput()),
2862                          SIGNAL(readyReadStandardOutput()),                  SLOT(readServerStdout()));
2863                          SLOT(readServerStdout()));          QObject::connect(m_pServer,
2864                  QObject::connect(m_pServer,                  SIGNAL(readyReadStandardError()),
2865                          SIGNAL(readyReadStandardError()),                  SLOT(readServerStdout()));
                         SLOT(readServerStdout()));  
 //      }  
2866    
2867          // The unforgiveable signal communication...          // The unforgiveable signal communication...
2868          QObject::connect(m_pServer,          QObject::connect(m_pServer,
# Line 2736  void MainForm::startServer (void) Line 2897  void MainForm::startServer (void)
2897    
2898    
2899  // Stop linuxsampler server...  // Stop linuxsampler server...
2900  void MainForm::stopServer (bool bInteractive)  void MainForm::stopServer ( bool bInteractive )
2901  {  {
2902          // Stop client code.          // Stop client code.
2903          stopClient();          stopClient();
2904    
2905          if (m_pServer && bInteractive) {          if (m_pServer && bInteractive) {
2906                  if (QMessageBox::question(this,                  if (QMessageBox::question(this,
2907                          QSAMPLER_TITLE ": " + tr("The backend's fate ..."),                          tr("The backend's fate ..."),
2908                          tr("You have the option to keep the sampler backend (LinuxSampler)\n"                          tr("You have the option to keep the sampler backend (LinuxSampler)\n"
2909                          "running in the background. The sampler would continue to work\n"                          "running in the background. The sampler would continue to work\n"
2910                          "according to your current sampler session and you could alter the\n"                          "according to your current sampler session and you could alter the\n"
2911                          "sampler session at any time by relaunching QSampler.\n\n"                          "sampler session at any time by relaunching QSampler.\n\n"
2912                          "Do you want LinuxSampler to stop?"),                          "Do you want LinuxSampler to stop?"),
2913                          QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)                          QMessageBox::Yes | QMessageBox::No,
2914                  {                          QMessageBox::Yes) == QMessageBox::No) {
2915                          bForceServerStop = false;                          m_bForceServerStop = false;
2916                  }                  }
2917          }          }
2918    
2919            bool bGraceWait = true;
2920    
2921          // And try to stop server.          // And try to stop server.
2922          if (m_pServer && bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2923                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2924                  if (m_pServer->state() == QProcess::Running) {                  if (m_pServer->state() == QProcess::Running) {
2925                  #if defined(WIN32)                  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
2926                          // Try harder...                          // Try harder...
2927                          m_pServer->kill();                          m_pServer->kill();
2928                  #else                  #else
2929                          // Try softly...                          // Try softly...
2930                          m_pServer->terminate();                          m_pServer->terminate();
2931                            bool bFinished = m_pServer->waitForFinished(QSAMPLER_TIMER_MSECS * 1000);
2932                            if (bFinished) bGraceWait = false;
2933                  #endif                  #endif
2934                  }                  }
2935          }       // Do final processing anyway.          }       // Do final processing anyway.
2936          else processServerExit();          else processServerExit();
2937    
2938          // Give it some time to terminate gracefully and stabilize...          // Give it some time to terminate gracefully and stabilize...
2939          QTime t;          if (bGraceWait) {
2940          t.start();                  QElapsedTimer timer;
2941          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                  timer.start();
2942                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  while (timer.elapsed() < QSAMPLER_TIMER_MSECS)
2943                            QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2944            }
2945  }  }
2946    
2947    
# Line 2796  void MainForm::processServerExit (void) Line 2963  void MainForm::processServerExit (void)
2963          if (m_pMessages)          if (m_pMessages)
2964                  m_pMessages->flushStdoutBuffer();                  m_pMessages->flushStdoutBuffer();
2965    
2966          if (m_pServer && bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2967                  if (m_pServer->state() != QProcess::NotRunning) {                  if (m_pServer->state() != QProcess::NotRunning) {
2968                          appendMessages(tr("Server is being forced..."));                          appendMessages(tr("Server is being forced..."));
2969                          // Force final server shutdown...                          // Force final server shutdown...
2970                          m_pServer->kill();                          m_pServer->kill();
2971                          // Give it some time to terminate gracefully and stabilize...                          // Give it some time to terminate gracefully and stabilize...
2972                          QTime t;                          QElapsedTimer timer;
2973                          t.start();                          timer.start();
2974                          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                          while (timer.elapsed() < QSAMPLER_TIMER_MSECS)
2975                                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2976                  }                  }
2977                  // Force final server shutdown...                  // Force final server shutdown...
# Line 2812  void MainForm::processServerExit (void) Line 2979  void MainForm::processServerExit (void)
2979                          tr("Server was stopped with exit status %1.")                          tr("Server was stopped with exit status %1.")
2980                          .arg(m_pServer->exitStatus()));                          .arg(m_pServer->exitStatus()));
2981                  delete m_pServer;                  delete m_pServer;
2982                  m_pServer = NULL;                  m_pServer = nullptr;
2983          }          }
2984    
2985          // Again, make status visible stable.          // Again, make status visible stable.
# Line 2821  void MainForm::processServerExit (void) Line 2988  void MainForm::processServerExit (void)
2988    
2989    
2990  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2991  // qsamplerMainForm -- Client stuff.  // QSampler::MainForm -- Client stuff.
2992    
2993  // The LSCP client callback procedure.  // The LSCP client callback procedure.
2994  lscp_status_t qsampler_client_callback ( lscp_client_t */*pClient*/,  lscp_status_t qsampler_client_callback ( lscp_client_t */*pClient*/,
2995          lscp_event_t event, const char *pchData, int cchData, void *pvData )          lscp_event_t event, const char *pchData, int cchData, void *pvData )
2996  {  {
2997          MainForm* pMainForm = (MainForm *) pvData;          MainForm* pMainForm = (MainForm *) pvData;
2998          if (pMainForm == NULL)          if (pMainForm == nullptr)
2999                  return LSCP_FAILED;                  return LSCP_FAILED;
3000    
3001          // ATTN: DO NOT EVER call any GUI code here,          // ATTN: DO NOT EVER call any GUI code here,
# Line 2842  lscp_status_t qsampler_client_callback ( Line 3009  lscp_status_t qsampler_client_callback (
3009    
3010    
3011  // Start our almighty client...  // Start our almighty client...
3012  bool MainForm::startClient (void)  bool MainForm::startClient (bool bReconnectOnly)
3013  {  {
3014          // Have it a setup?          // Have it a setup?
3015          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
3016                  return false;                  return false;
3017    
3018          // Aren't we already started, are we?          // Aren't we already started, are we?
# Line 2859  bool MainForm::startClient (void) Line 3026  bool MainForm::startClient (void)
3026          m_pClient = ::lscp_client_create(          m_pClient = ::lscp_client_create(
3027                  m_pOptions->sServerHost.toUtf8().constData(),                  m_pOptions->sServerHost.toUtf8().constData(),
3028                  m_pOptions->iServerPort, qsampler_client_callback, this);                  m_pOptions->iServerPort, qsampler_client_callback, this);
3029          if (m_pClient == NULL) {          if (m_pClient == nullptr) {
3030                  // Is this the first try?                  // Is this the first try?
3031                  // maybe we need to start a local server...                  // maybe we need to start a local server...
3032                  if ((m_pServer && m_pServer->state() == QProcess::Running)                  if ((m_pServer && m_pServer->state() == QProcess::Running)
3033                          || !m_pOptions->bServerStart) {                          || !m_pOptions->bServerStart || bReconnectOnly)
3034                          appendMessagesError(                  {
3035                                  tr("Could not connect to server as client.\n\nSorry."));                          // if this method is called from autoReconnectClient()
3036                            // then don't bother user with an error message...
3037                            if (!bReconnectOnly) {
3038                                    appendMessagesError(
3039                                            tr("Could not connect to server as client.\n\nSorry.")
3040                                    );
3041                            }
3042                  } else {                  } else {
3043                          startServer();                          startServer();
3044                  }                  }
# Line 2873  bool MainForm::startClient (void) Line 3046  bool MainForm::startClient (void)
3046                  stabilizeForm();                  stabilizeForm();
3047                  return false;                  return false;
3048          }          }
3049    
3050          // Just set receive timeout value, blindly.          // Just set receive timeout value, blindly.
3051          ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);          ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
3052          appendMessages(          appendMessages(
# Line 2928  bool MainForm::startClient (void) Line 3102  bool MainForm::startClient (void)
3102          if (!m_pOptions->sSessionFile.isEmpty()) {          if (!m_pOptions->sSessionFile.isEmpty()) {
3103                  // Just load the prabably startup session...                  // Just load the prabably startup session...
3104                  if (loadSessionFile(m_pOptions->sSessionFile)) {                  if (loadSessionFile(m_pOptions->sSessionFile)) {
3105                          m_pOptions->sSessionFile = QString::null;                          m_pOptions->sSessionFile = QString();
3106                          return true;                          return true;
3107                  }                  }
3108          }          }
# Line 2944  bool MainForm::startClient (void) Line 3118  bool MainForm::startClient (void)
3118  // Stop client...  // Stop client...
3119  void MainForm::stopClient (void)  void MainForm::stopClient (void)
3120  {  {
3121          if (m_pClient == NULL)          if (m_pClient == nullptr)
3122                  return;                  return;
3123    
3124          // Log prepare here.          // Log prepare here.
# Line 2976  void MainForm::stopClient (void) Line 3150  void MainForm::stopClient (void)
3150          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
3151          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);
3152          ::lscp_client_destroy(m_pClient);          ::lscp_client_destroy(m_pClient);
3153          m_pClient = NULL;          m_pClient = nullptr;
3154    
3155          // Hard-notify instrumnet and device configuration forms,          // Hard-notify instrumnet and device configuration forms,
3156          // if visible, that we're running out...          // if visible, that we're running out...
# Line 2993  void MainForm::stopClient (void) Line 3167  void MainForm::stopClient (void)
3167  }  }
3168    
3169    
3170    void MainForm::startAutoReconnectClient (void)
3171    {
3172            stopClient();
3173            appendMessages(tr("Trying to reconnect..."));
3174            QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(autoReconnectClient()));
3175    }
3176    
3177    
3178    void MainForm::autoReconnectClient (void)
3179    {
3180            const bool bSuccess = startClient(true);
3181            if (!bSuccess)
3182                    QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(autoReconnectClient()));
3183    }
3184    
3185    
3186  // Channel strip activation/selection.  // Channel strip activation/selection.
3187  void MainForm::activateStrip ( QMdiSubWindow *pMdiSubWindow )  void MainForm::activateStrip ( QMdiSubWindow *pMdiSubWindow )
3188  {  {
3189          ChannelStrip *pChannelStrip = NULL;          ChannelStrip *pChannelStrip = nullptr;
3190          if (pMdiSubWindow)          if (pMdiSubWindow)
3191                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
3192          if (pChannelStrip)          if (pChannelStrip)

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

  ViewVC Help
Powered by ViewVC