/[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 2077 by capela, Wed Mar 31 09:07:30 2010 UTC revision 3855 by capela, Thu Feb 4 10:09:42 2021 UTC
# Line 1  Line 1 
1  // qsamplerMainForm.cpp  // qsamplerMainForm.cpp
2  //  //
3  /****************************************************************************  /****************************************************************************
4     Copyright (C) 2004-2010, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2021, rncbc aka Rui Nuno Capela. All rights reserved.
5     Copyright (C) 2007, 2008 Christian Schoenebeck     Copyright (C) 2007-2019 Christian Schoenebeck
6    
7     This program is free software; you can redistribute it and/or     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License     modify it under the terms of the GNU General Public License
# Line 35  Line 35 
35  #include "qsamplerOptionsForm.h"  #include "qsamplerOptionsForm.h"
36  #include "qsamplerDeviceStatusForm.h"  #include "qsamplerDeviceStatusForm.h"
37    
38    #include "qsamplerPaletteForm.h"
39    
40    #include <QStyleFactory>
41    
42    #include <QMdiArea>
43    #include <QMdiSubWindow>
44    
45  #include <QApplication>  #include <QApplication>
 #include <QWorkspace>  
46  #include <QProcess>  #include <QProcess>
47  #include <QMessageBox>  #include <QMessageBox>
48    
 #include <QRegExp>  
49  #include <QTextStream>  #include <QTextStream>
50  #include <QFileDialog>  #include <QFileDialog>
51  #include <QFileInfo>  #include <QFileInfo>
# Line 56  Line 61 
61  #include <QTimer>  #include <QTimer>
62  #include <QDateTime>  #include <QDateTime>
63    
64  #if QT_VERSION < 0x040500  #include <QElapsedTimer>
65    
66    #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
67    #include <QMimeData>
68    #endif
69    
70    #if QT_VERSION < QT_VERSION_CHECK(4, 5, 0)
71  namespace Qt {  namespace Qt {
72  const WindowFlags WindowCloseButtonHint = WindowFlags(0x08000000);  const WindowFlags WindowCloseButtonHint = WindowFlags(0x08000000);
 #if QT_VERSION < 0x040200  
 const WindowFlags CustomizeWindowHint   = WindowFlags(0x02000000);  
 #endif  
73  }  }
74  #endif  #endif
75    
 #ifdef HAVE_SIGNAL_H  
 #include <signal.h>  
 #endif  
   
76  #ifdef CONFIG_LIBGIG  #ifdef CONFIG_LIBGIG
77    #if defined(Q_CC_GNU) || defined(Q_CC_MINGW)
78    #pragma GCC diagnostic push
79    #pragma GCC diagnostic ignored "-Wunused-parameter"
80    #endif
81  #include <gig.h>  #include <gig.h>
82    #if defined(Q_CC_GNU) || defined(Q_CC_MINGW)
83    #pragma GCC diagnostic pop
84    #endif
85  #endif  #endif
86    
87  // Needed for lroundf()  // Deprecated QTextStreamFunctions/Qt namespaces workaround.
88  #include <math.h>  #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
89    #define endl    Qt::endl
90    #endif
91    
92  #ifndef CONFIG_ROUND  // Needed for lroundf()
93    #ifdef CONFIG_ROUND
94    #include <cmath>
95    #else
96  static inline long lroundf ( float x )  static inline long lroundf ( float x )
97  {  {
98          if (x >= 0.0f)          if (x >= 0.0f)
# Line 88  static inline long lroundf ( float x ) Line 104  static inline long lroundf ( float x )
104    
105    
106  // All winsock apps needs this.  // All winsock apps needs this.
107  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
108  static WSADATA _wsaData;  static WSADATA _wsaData;
109    #undef HAVE_SIGNAL_H
110  #endif  #endif
111    
112    
113    //-------------------------------------------------------------------------
114    // LADISH Level 1 support stuff.
115    
116    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
117    
118    #include <QSocketNotifier>
119    
120    #include <unistd.h>
121    #include <sys/types.h>
122    #include <sys/socket.h>
123    #include <signal.h>
124    
125    // File descriptor for SIGUSR1 notifier.
126    static int g_fdSigusr1[2] = { -1, -1 };
127    
128    // Unix SIGUSR1 signal handler.
129    static void qsampler_sigusr1_handler ( int /* signo */ )
130    {
131            char c = 1;
132    
133            (::write(g_fdSigusr1[0], &c, sizeof(c)) > 0);
134    }
135    
136    // File descriptor for SIGTERM notifier.
137    static int g_fdSigterm[2] = { -1, -1 };
138    
139    // Unix SIGTERM signal handler.
140    static void qsampler_sigterm_handler ( int /* signo */ )
141    {
142            char c = 1;
143    
144            (::write(g_fdSigterm[0], &c, sizeof(c)) > 0);
145    }
146    
147    #endif  // HAVE_SIGNAL_H
148    
149    
150    //-------------------------------------------------------------------------
151    // QSampler -- namespace
152    
153    
154  namespace QSampler {  namespace QSampler {
155    
156  // Timer constant stuff.  // Timer constant stuff.
# Line 107  namespace QSampler { Line 165  namespace QSampler {
165    
166  // Specialties for thread-callback comunication.  // Specialties for thread-callback comunication.
167  #define QSAMPLER_LSCP_EVENT   QEvent::Type(QEvent::User + 1)  #define QSAMPLER_LSCP_EVENT   QEvent::Type(QEvent::User + 1)
 #define QSAMPLER_SAVE_EVENT   QEvent::Type(QEvent::User + 2)  
168    
169    
170  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
171  // LscpEvent -- specialty for LSCP callback comunication.  // QSampler::LscpEvent -- specialty for LSCP callback comunication.
   
172    
173  class LscpEvent : public QEvent  class LscpEvent : public QEvent
174  {  {
# Line 127  public: Line 183  public:
183          }          }
184    
185          // Accessors.          // Accessors.
186          lscp_event_t event() { return m_event; }          lscp_event_t  event() { return m_event; }
187          QString&     data()  { return m_data;  }          const QString& data() { return m_data;  }
188    
189  private:  private:
190    
# Line 140  private: Line 196  private:
196    
197    
198  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
199  // LADISH Level 1 support stuff.  // QSampler::Workspace -- Main window workspace (MDI Area) decl.
200    
201  void qsampler_on_sigusr1 ( int /*signo*/ )  class Workspace : public QMdiArea
202  {  {
203          QApplication::postEvent(  public:
204                  MainForm::getInstance(),  
205                  new QEvent(QSAMPLER_SAVE_EVENT));          Workspace(MainForm *pMainForm) : QMdiArea(pMainForm) {}
206  }  
207    protected:
208    
209            void resizeEvent(QResizeEvent *)
210            {
211                    MainForm *pMainForm = static_cast<MainForm *> (parentWidget());
212                    if (pMainForm)
213                            pMainForm->channelsArrangeAuto();
214            }
215    };
216    
217    
218  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
219  // qsamplerMainForm -- Main window form implementation.  // QSampler::MainForm -- Main window form implementation.
220    
221  // Kind of singleton reference.  // Kind of singleton reference.
222  MainForm* MainForm::g_pMainForm = NULL;  MainForm *MainForm::g_pMainForm = nullptr;
223    
224  MainForm::MainForm ( QWidget *pParent )  MainForm::MainForm ( QWidget *pParent )
225          : QMainWindow(pParent)          : QMainWindow(pParent)
# Line 165  MainForm::MainForm ( QWidget *pParent ) Line 230  MainForm::MainForm ( QWidget *pParent )
230          g_pMainForm = this;          g_pMainForm = this;
231    
232          // Initialize some pointer references.          // Initialize some pointer references.
233          m_pOptions = NULL;          m_pOptions = nullptr;
234    
235          // All child forms are to be created later, not earlier than setup.          // All child forms are to be created later, not earlier than setup.
236          m_pMessages = NULL;          m_pMessages = nullptr;
237          m_pInstrumentListForm = NULL;          m_pInstrumentListForm = nullptr;
238          m_pDeviceForm = NULL;          m_pDeviceForm = nullptr;
239    
240          // We'll start clean.          // We'll start clean.
241          m_iUntitled   = 0;          m_iUntitled   = 0;
242            m_iDirtySetup = 0;
243          m_iDirtyCount = 0;          m_iDirtyCount = 0;
244    
245          m_pServer = NULL;          m_pServer = nullptr;
246          m_pClient = NULL;          m_pClient = nullptr;
247    
248          m_iStartDelay = 0;          m_iStartDelay = 0;
249          m_iTimerDelay = 0;          m_iTimerDelay = 0;
250    
251          m_iTimerSlot = 0;          m_iTimerSlot = 0;
252    
253  #ifdef HAVE_SIGNAL_H  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
254    
255          // Set to ignore any fatal "Broken pipe" signals.          // Set to ignore any fatal "Broken pipe" signals.
256          ::signal(SIGPIPE, SIG_IGN);          ::signal(SIGPIPE, SIG_IGN);
257    
258          // LADISH Level 1 suport.          // LADISH Level 1 suport.
259          ::signal(SIGUSR1, qsampler_on_sigusr1);  
260  #endif          // Initialize file descriptors for SIGUSR1 socket notifier.
261            ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigusr1);
262            m_pSigusr1Notifier
263                    = new QSocketNotifier(g_fdSigusr1[1], QSocketNotifier::Read, this);
264    
265            QObject::connect(m_pSigusr1Notifier,
266                    SIGNAL(activated(int)),
267                    SLOT(handle_sigusr1()));
268    
269            // Install SIGUSR1 signal handler.
270            struct sigaction sigusr1;
271            sigusr1.sa_handler = qsampler_sigusr1_handler;
272            sigemptyset(&sigusr1.sa_mask);
273            sigusr1.sa_flags = 0;
274            sigusr1.sa_flags |= SA_RESTART;
275            ::sigaction(SIGUSR1, &sigusr1, nullptr);
276    
277            // Initialize file descriptors for SIGTERM socket notifier.
278            ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigterm);
279            m_pSigtermNotifier
280                    = new QSocketNotifier(g_fdSigterm[1], QSocketNotifier::Read, this);
281    
282            QObject::connect(m_pSigtermNotifier,
283                    SIGNAL(activated(int)),
284                    SLOT(handle_sigterm()));
285    
286            // Install SIGTERM signal handler.
287            struct sigaction sigterm;
288            sigterm.sa_handler = qsampler_sigterm_handler;
289            sigemptyset(&sigterm.sa_mask);
290            sigterm.sa_flags = 0;
291            sigterm.sa_flags |= SA_RESTART;
292            ::sigaction(SIGTERM, &sigterm, nullptr);
293            ::sigaction(SIGQUIT, &sigterm, nullptr);
294    
295            // Ignore SIGHUP/SIGINT signals.
296            ::signal(SIGHUP, SIG_IGN);
297            ::signal(SIGINT, SIG_IGN);
298    
299    #else   // HAVE_SIGNAL_H
300    
301            m_pSigusr1Notifier = nullptr;
302            m_pSigtermNotifier = nullptr;
303            
304    #endif  // !HAVE_SIGNAL_H
305    
306  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
307          // Make some extras into the toolbar...          // Make some extras into the toolbar...
# Line 210  MainForm::MainForm ( QWidget *pParent ) Line 322  MainForm::MainForm ( QWidget *pParent )
322          QObject::connect(m_pVolumeSlider,          QObject::connect(m_pVolumeSlider,
323                  SIGNAL(valueChanged(int)),                  SIGNAL(valueChanged(int)),
324                  SLOT(volumeChanged(int)));                  SLOT(volumeChanged(int)));
         //m_ui.channelsToolbar->setHorizontallyStretchable(true);  
         //m_ui.channelsToolbar->setStretchableWidget(m_pVolumeSlider);  
325          m_ui.channelsToolbar->addWidget(m_pVolumeSlider);          m_ui.channelsToolbar->addWidget(m_pVolumeSlider);
326          // Volume spin-box          // Volume spin-box
327          m_ui.channelsToolbar->addSeparator();          m_ui.channelsToolbar->addSeparator();
328          m_pVolumeSpinBox = new QSpinBox(m_ui.channelsToolbar);          m_pVolumeSpinBox = new QSpinBox(m_ui.channelsToolbar);
         m_pVolumeSpinBox->setMaximumHeight(24);  
329          m_pVolumeSpinBox->setSuffix(" %");          m_pVolumeSpinBox->setSuffix(" %");
330          m_pVolumeSpinBox->setMinimum(0);          m_pVolumeSpinBox->setMinimum(0);
331          m_pVolumeSpinBox->setMaximum(100);          m_pVolumeSpinBox->setMaximum(100);
# Line 228  MainForm::MainForm ( QWidget *pParent ) Line 337  MainForm::MainForm ( QWidget *pParent )
337  #endif  #endif
338    
339          // Make it an MDI workspace.          // Make it an MDI workspace.
340          m_pWorkspace = new QWorkspace(this);          m_pWorkspace = new Workspace(this);
341          m_pWorkspace->setScrollBarsEnabled(true);          m_pWorkspace->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
342            m_pWorkspace->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
343          // Set the activation connection.          // Set the activation connection.
344          QObject::connect(m_pWorkspace,          QObject::connect(m_pWorkspace,
345                  SIGNAL(windowActivated(QWidget *)),                  SIGNAL(subWindowActivated(QMdiSubWindow *)),
346                  SLOT(activateStrip(QWidget *)));                  SLOT(activateStrip(QMdiSubWindow *)));
347          // Make it shine :-)          // Make it shine :-)
348          setCentralWidget(m_pWorkspace);          setCentralWidget(m_pWorkspace);
349    
# Line 262  MainForm::MainForm ( QWidget *pParent ) Line 372  MainForm::MainForm ( QWidget *pParent )
372          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
373          statusBar()->addWidget(pLabel);          statusBar()->addWidget(pLabel);
374    
375  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
376          WSAStartup(MAKEWORD(1, 1), &_wsaData);          WSAStartup(MAKEWORD(1, 1), &_wsaData);
377  #endif  #endif
378    
# Line 350  MainForm::MainForm ( QWidget *pParent ) Line 460  MainForm::MainForm ( QWidget *pParent )
460          QObject::connect(m_ui.channelsMenu,          QObject::connect(m_ui.channelsMenu,
461                  SIGNAL(aboutToShow()),                  SIGNAL(aboutToShow()),
462                  SLOT(channelsMenuAboutToShow()));                  SLOT(channelsMenuAboutToShow()));
463    #ifdef CONFIG_VOLUME
464            QObject::connect(m_ui.channelsToolbar,
465                    SIGNAL(orientationChanged(Qt::Orientation)),
466                    SLOT(channelsToolbarOrientation(Qt::Orientation)));
467    #endif
468  }  }
469    
470  // Destructor.  // Destructor.
# Line 358  MainForm::~MainForm() Line 473  MainForm::~MainForm()
473          // Do final processing anyway.          // Do final processing anyway.
474          processServerExit();          processServerExit();
475    
476  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
477          WSACleanup();          WSACleanup();
478  #endif  #endif
479    
480    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
481            if (m_pSigusr1Notifier)
482                    delete m_pSigusr1Notifier;
483            if (m_pSigtermNotifier)
484                    delete m_pSigtermNotifier;
485    #endif
486    
487          // Finally drop any widgets around...          // Finally drop any widgets around...
488          if (m_pDeviceForm)          if (m_pDeviceForm)
489                  delete m_pDeviceForm;                  delete m_pDeviceForm;
# Line 388  MainForm::~MainForm() Line 510  MainForm::~MainForm()
510  #endif  #endif
511    
512          // Pseudo-singleton reference shut-down.          // Pseudo-singleton reference shut-down.
513          g_pMainForm = NULL;          g_pMainForm = nullptr;
514  }  }
515    
516    
# Line 426  void MainForm::setup ( Options *pOptions Line 548  void MainForm::setup ( Options *pOptions
548          updateMessagesFont();          updateMessagesFont();
549          updateMessagesLimit();          updateMessagesLimit();
550          updateMessagesCapture();          updateMessagesCapture();
551    
552          // Set the visibility signal.          // Set the visibility signal.
553          QObject::connect(m_pMessages,          QObject::connect(m_pMessages,
554                  SIGNAL(visibilityChanged(bool)),                  SIGNAL(visibilityChanged(bool)),
# Line 491  bool MainForm::queryClose (void) Line 614  bool MainForm::queryClose (void)
614                                  || m_ui.channelsToolbar->isVisible());                                  || m_ui.channelsToolbar->isVisible());
615                          m_pOptions->bStatusbar = statusBar()->isVisible();                          m_pOptions->bStatusbar = statusBar()->isVisible();
616                          // Save the dock windows state.                          // Save the dock windows state.
                         const QString sDockables = saveState().toBase64().data();  
617                          m_pOptions->settings().setValue("/Layout/DockWindows", saveState());                          m_pOptions->settings().setValue("/Layout/DockWindows", saveState());
618                          // And the children, and the main windows state,.                          // And the children, and the main windows state,.
619                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);
# Line 525  void MainForm::closeEvent ( QCloseEvent Line 647  void MainForm::closeEvent ( QCloseEvent
647  void MainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )  void MainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
648  {  {
649          // Accept external drags only...          // Accept external drags only...
650          if (pDragEnterEvent->source() == NULL          if (pDragEnterEvent->source() == nullptr
651                  && pDragEnterEvent->mimeData()->hasUrls()) {                  && pDragEnterEvent->mimeData()->hasUrls()) {
652                  pDragEnterEvent->accept();                  pDragEnterEvent->accept();
653          } else {          } else {
# Line 534  void MainForm::dragEnterEvent ( QDragEnt Line 656  void MainForm::dragEnterEvent ( QDragEnt
656  }  }
657    
658    
659  void MainForm::dropEvent ( QDropEvent* pDropEvent )  void MainForm::dropEvent ( QDropEvent *pDropEvent )
660  {  {
661          // Accept externally originated drops only...          // Accept externally originated drops only...
662          if (pDropEvent->source())          if (pDropEvent->source())
# Line 545  void MainForm::dropEvent ( QDropEvent* p Line 667  void MainForm::dropEvent ( QDropEvent* p
667                  QListIterator<QUrl> iter(pMimeData->urls());                  QListIterator<QUrl> iter(pMimeData->urls());
668                  while (iter.hasNext()) {                  while (iter.hasNext()) {
669                          const QString& sPath = iter.next().toLocalFile();                          const QString& sPath = iter.next().toLocalFile();
670                          if (Channel::isInstrumentFile(sPath)) {                  //      if (Channel::isDlsInstrumentFile(sPath)) {
671                            if (QFileInfo(sPath).exists()) {
672                                  // Try to create a new channel from instrument file...                                  // Try to create a new channel from instrument file...
673                                  Channel *pChannel = new Channel();                                  Channel *pChannel = new Channel();
674                                  if (pChannel == NULL)                                  if (pChannel == nullptr)
675                                          return;                                          return;
676                                  // Start setting the instrument filename...                                  // Start setting the instrument filename...
677                                  pChannel->setInstrument(sPath, 0);                                  pChannel->setInstrument(sPath, 0);
# Line 589  void MainForm::customEvent ( QEvent* pEv Line 712  void MainForm::customEvent ( QEvent* pEv
712                                  updateAllChannelStrips(true);                                  updateAllChannelStrips(true);
713                                  break;                                  break;
714                          case LSCP_EVENT_CHANNEL_INFO: {                          case LSCP_EVENT_CHANNEL_INFO: {
715                                  int iChannelID = pLscpEvent->data().toInt();                                  const int iChannelID = pLscpEvent->data().toInt();
716                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);
717                                  if (pChannelStrip)                                  if (pChannelStrip)
718                                          channelStripChanged(pChannelStrip);                                          channelStripChanged(pChannelStrip);
# Line 637  void MainForm::customEvent ( QEvent* pEv Line 760  void MainForm::customEvent ( QEvent* pEv
760                                          .arg(::lscp_event_to_text(pLscpEvent->event()))                                          .arg(::lscp_event_to_text(pLscpEvent->event()))
761                                          .arg(pLscpEvent->data()), "#996699");                                          .arg(pLscpEvent->data()), "#996699");
762                  }                  }
763          }       // LADISH1 Level 1 support...          }
764          else if (pEvent->type() == QSAMPLER_SAVE_EVENT)  }
765    
766    
767    // LADISH Level 1 -- SIGUSR1 signal handler.
768    void MainForm::handle_sigusr1 (void)
769    {
770    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
771    
772            char c;
773    
774            if (::read(g_fdSigusr1[1], &c, sizeof(c)) > 0)
775                  saveSession(false);                  saveSession(false);
776    
777    #endif
778    }
779    
780    
781    void MainForm::handle_sigterm (void)
782    {
783    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
784    
785            char c;
786    
787            if (::read(g_fdSigterm[1], &c, sizeof(c)) > 0)
788                    close();
789    
790    #endif
791  }  }
792    
793    
# Line 668  void MainForm::contextMenuEvent( QContex Line 816  void MainForm::contextMenuEvent( QContex
816    
817    
818  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
819  // qsamplerMainForm -- Brainless public property accessors.  // QSampler::MainForm -- Brainless public property accessors.
820    
821  // The global options settings property.  // The global options settings property.
822  Options *MainForm::options (void) const  Options *MainForm::options (void) const
# Line 692  MainForm *MainForm::getInstance (void) Line 840  MainForm *MainForm::getInstance (void)
840    
841    
842  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
843  // qsamplerMainForm -- Session file stuff.  // QSampler::MainForm -- Session file stuff.
844    
845  // Format the displayable session filename.  // Format the displayable session filename.
846  QString MainForm::sessionName ( const QString& sFilename )  QString MainForm::sessionName ( const QString& sFilename )
847  {  {
848          bool bCompletePath = (m_pOptions && m_pOptions->bCompletePath);          const bool bCompletePath = (m_pOptions && m_pOptions->bCompletePath);
849          QString sSessionName = sFilename;          QString sSessionName = sFilename;
850          if (sSessionName.isEmpty())          if (sSessionName.isEmpty())
851                  sSessionName = tr("Untitled") + QString::number(m_iUntitled);                  sSessionName = tr("Untitled") + QString::number(m_iUntitled);
# Line 721  bool MainForm::newSession (void) Line 869  bool MainForm::newSession (void)
869          m_iUntitled++;          m_iUntitled++;
870    
871          // Stabilize form.          // Stabilize form.
872          m_sFilename = QString::null;          m_sFilename = QString();
873          m_iDirtyCount = 0;          m_iDirtyCount = 0;
874          appendMessages(tr("New session: \"%1\".").arg(sessionName(m_sFilename)));          appendMessages(tr("New session: \"%1\".").arg(sessionName(m_sFilename)));
875          stabilizeForm();          stabilizeForm();
# Line 733  bool MainForm::newSession (void) Line 881  bool MainForm::newSession (void)
881  // Open an existing sampler session.  // Open an existing sampler session.
882  bool MainForm::openSession (void)  bool MainForm::openSession (void)
883  {  {
884          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
885                  return false;                  return false;
886    
887          // Ask for the filename to open...          // Ask for the filename to open...
888          QString sFilename = QFileDialog::getOpenFileName(this,          QString sFilename = QFileDialog::getOpenFileName(this,
889                  QSAMPLER_TITLE ": " + tr("Open Session"), // Caption.                  tr("Open Session"),                       // Caption.
890                  m_pOptions->sSessionDir,                  // Start here.                  m_pOptions->sSessionDir,                  // Start here.
891                  tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)                  tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)
892          );          );
# Line 759  bool MainForm::openSession (void) Line 907  bool MainForm::openSession (void)
907  // Save current sampler session with another name.  // Save current sampler session with another name.
908  bool MainForm::saveSession ( bool bPrompt )  bool MainForm::saveSession ( bool bPrompt )
909  {  {
910          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
911                  return false;                  return false;
912    
913          QString sFilename = m_sFilename;          QString sFilename = m_sFilename;
# Line 771  bool MainForm::saveSession ( bool bPromp Line 919  bool MainForm::saveSession ( bool bPromp
919                          sFilename = m_pOptions->sSessionDir;                          sFilename = m_pOptions->sSessionDir;
920                  // Prompt the guy...                  // Prompt the guy...
921                  sFilename = QFileDialog::getSaveFileName(this,                  sFilename = QFileDialog::getSaveFileName(this,
922                          QSAMPLER_TITLE ": " + tr("Save Session"), // Caption.                          tr("Save Session"),                       // Caption.
923                          sFilename,                                // Start here.                          sFilename,                                // Start here.
924                          tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)                          tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)
925                  );                  );
# Line 781  bool MainForm::saveSession ( bool bPromp Line 929  bool MainForm::saveSession ( bool bPromp
929                  // Enforce .lscp extension...                  // Enforce .lscp extension...
930                  if (QFileInfo(sFilename).suffix().isEmpty())                  if (QFileInfo(sFilename).suffix().isEmpty())
931                          sFilename += ".lscp";                          sFilename += ".lscp";
932            #if 0
933                  // Check if already exists...                  // Check if already exists...
934                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
935                          if (QMessageBox::warning(this,                          if (QMessageBox::warning(this,
936                                  QSAMPLER_TITLE ": " + tr("Warning"),                                  tr("Warning"),
937                                  tr("The file already exists:\n\n"                                  tr("The file already exists:\n\n"
938                                  "\"%1\"\n\n"                                  "\"%1\"\n\n"
939                                  "Do you want to replace it?")                                  "Do you want to replace it?")
# Line 793  bool MainForm::saveSession ( bool bPromp Line 942  bool MainForm::saveSession ( bool bPromp
942                                  == QMessageBox::No)                                  == QMessageBox::No)
943                                  return false;                                  return false;
944                  }                  }
945            #endif
946          }          }
947    
948          // Save it right away.          // Save it right away.
# Line 808  bool MainForm::closeSession ( bool bForc Line 958  bool MainForm::closeSession ( bool bForc
958          // Are we dirty enough to prompt it?          // Are we dirty enough to prompt it?
959          if (m_iDirtyCount > 0) {          if (m_iDirtyCount > 0) {
960                  switch (QMessageBox::warning(this,                  switch (QMessageBox::warning(this,
961                          QSAMPLER_TITLE ": " + tr("Warning"),                          tr("Warning"),
962                          tr("The current session has been changed:\n\n"                          tr("The current session has been changed:\n\n"
963                          "\"%1\"\n\n"                          "\"%1\"\n\n"
964                          "Do you want to save the changes?")                          "Do you want to save the changes?")
# Line 831  bool MainForm::closeSession ( bool bForc Line 981  bool MainForm::closeSession ( bool bForc
981          if (bClose) {          if (bClose) {
982                  // Remove all channel strips from sight...                  // Remove all channel strips from sight...
983                  m_pWorkspace->setUpdatesEnabled(false);                  m_pWorkspace->setUpdatesEnabled(false);
984                  QWidgetList wlist = m_pWorkspace->windowList();                  const QList<QMdiSubWindow *>& wlist
985                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                          = m_pWorkspace->subWindowList();
986                          ChannelStrip *pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
987                            ChannelStrip *pChannelStrip
988                                    = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
989                          if (pChannelStrip) {                          if (pChannelStrip) {
990                                  Channel *pChannel = pChannelStrip->channel();                                  Channel *pChannel = pChannelStrip->channel();
991                                  if (bForce && pChannel)                                  if (bForce && pChannel)
992                                          pChannel->removeChannel();                                          pChannel->removeChannel();
993                                  delete pChannelStrip;                                  delete pChannelStrip;
994                          }                          }
995                            delete pMdiSubWindow;
996                  }                  }
997                  m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
998                  // We're now clean, for sure.                  // We're now clean, for sure.
# Line 853  bool MainForm::closeSession ( bool bForc Line 1006  bool MainForm::closeSession ( bool bForc
1006  // Load a session from specific file path.  // Load a session from specific file path.
1007  bool MainForm::loadSessionFile ( const QString& sFilename )  bool MainForm::loadSessionFile ( const QString& sFilename )
1008  {  {
1009          if (m_pClient == NULL)          if (m_pClient == nullptr)
1010                  return false;                  return false;
1011    
1012          // Open and read from real file.          // Open and read from real file.
# Line 929  bool MainForm::loadSessionFile ( const Q Line 1082  bool MainForm::loadSessionFile ( const Q
1082  // Save current session to specific file path.  // Save current session to specific file path.
1083  bool MainForm::saveSessionFile ( const QString& sFilename )  bool MainForm::saveSessionFile ( const QString& sFilename )
1084  {  {
1085          if (m_pClient == NULL)          if (m_pClient == nullptr)
1086                  return false;                  return false;
1087    
1088          // Check whether server is apparently OK...          // Check whether server is apparently OK...
# Line 951  bool MainForm::saveSessionFile ( const Q Line 1104  bool MainForm::saveSessionFile ( const Q
1104          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1105    
1106          // Write the file.          // Write the file.
1107          int  iErrors = 0;          int iErrors = 0;
1108          QTextStream ts(&file);          QTextStream ts(&file);
1109          ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;          ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;
1110          ts << "# " << tr("Version")          ts << "# " << tr("Version") << ": " CONFIG_BUILD_VERSION << endl;
1111          << ": " QSAMPLER_VERSION << endl;  //      ts << "# " << tr("Build") << ": " CONFIG_BUILD_DATE << endl;
         ts << "# " << tr("Build")  
         << ": " __DATE__ " " __TIME__ << endl;  
1112          ts << "#"  << endl;          ts << "#"  << endl;
1113          ts << "# " << tr("File")          ts << "# " << tr("File")
1114          << ": " << QFileInfo(sFilename).fileName() << endl;          << ": " << QFileInfo(sFilename).fileName() << endl;
# Line 970  bool MainForm::saveSessionFile ( const Q Line 1121  bool MainForm::saveSessionFile ( const Q
1121          // It is assumed that this new kind of device+session file          // It is assumed that this new kind of device+session file
1122          // will be loaded from a complete initialized server...          // will be loaded from a complete initialized server...
1123          int *piDeviceIDs;          int *piDeviceIDs;
1124          int  iDevice;          int  i, iDevice;
1125          ts << "RESET" << endl;          ts << "RESET" << endl;
1126    
1127          // Audio device mapping.          // Audio device mapping.
1128          QMap<int, int> audioDeviceMap;          QMap<int, int> audioDeviceMap; iDevice = 0;
1129          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);
1130          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1131                  ts << endl;                  Device device(Device::Audio, piDeviceIDs[i]);
1132                  Device device(Device::Audio, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1133                    if (device.driverName().toUpper() == "PLUGIN")
1134                            continue;
1135                  // Audio device specification...                  // Audio device specification...
1136                    ts << endl;
1137                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1138                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1139                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
# Line 1010  bool MainForm::saveSessionFile ( const Q Line 1164  bool MainForm::saveSessionFile ( const Q
1164                          iPort++;                          iPort++;
1165                  }                  }
1166                  // Audio device index/id mapping.                  // Audio device index/id mapping.
1167                  audioDeviceMap[device.deviceID()] = iDevice;                  audioDeviceMap.insert(device.deviceID(), iDevice++);
1168                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1169                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1170          }          }
1171    
1172          // MIDI device mapping.          // MIDI device mapping.
1173          QMap<int, int> midiDeviceMap;          QMap<int, int> midiDeviceMap; iDevice = 0;
1174          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);
1175          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1176                  ts << endl;                  Device device(Device::Midi, piDeviceIDs[i]);
1177                  Device device(Device::Midi, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1178                    if (device.driverName().toUpper() == "PLUGIN")
1179                            continue;
1180                  // MIDI device specification...                  // MIDI device specification...
1181                    ts << endl;
1182                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1183                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1184                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
# Line 1052  bool MainForm::saveSessionFile ( const Q Line 1209  bool MainForm::saveSessionFile ( const Q
1209                          iPort++;                          iPort++;
1210                  }                  }
1211                  // MIDI device index/id mapping.                  // MIDI device index/id mapping.
1212                  midiDeviceMap[device.deviceID()] = iDevice;                  midiDeviceMap.insert(device.deviceID(), iDevice++);
1213                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1214                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1215          }          }
# Line 1063  bool MainForm::saveSessionFile ( const Q Line 1220  bool MainForm::saveSessionFile ( const Q
1220          QMap<int, int> midiInstrumentMap;          QMap<int, int> midiInstrumentMap;
1221          int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);          int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);
1222          for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {          for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {
1223                  int iMidiMap = piMaps[iMap];                  const int iMidiMap = piMaps[iMap];
1224                  const char *pszMapName                  const char *pszMapName
1225                          = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);                          = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);
1226                  ts << "# " << tr("MIDI instrument map") << " " << iMap;                  ts << "# " << tr("MIDI instrument map") << " " << iMap;
# Line 1115  bool MainForm::saveSessionFile ( const Q Line 1272  bool MainForm::saveSessionFile ( const Q
1272                  }                  }
1273                  ts << endl;                  ts << endl;
1274                  // Check for errors...                  // Check for errors...
1275                  if (pInstrs == NULL && ::lscp_client_get_errno(m_pClient)) {                  if (pInstrs == nullptr && ::lscp_client_get_errno(m_pClient)) {
1276                          appendMessagesClient("lscp_list_midi_instruments");                          appendMessagesClient("lscp_list_midi_instruments");
1277                          iErrors++;                          iErrors++;
1278                  }                  }
1279                  // MIDI strument index/id mapping.                  // MIDI strument index/id mapping.
1280                  midiInstrumentMap[iMidiMap] = iMap;                  midiInstrumentMap.insert(iMidiMap, iMap);
1281          }          }
1282          // Check for errors...          // Check for errors...
1283          if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {          if (piMaps == nullptr && ::lscp_client_get_errno(m_pClient)) {
1284                  appendMessagesClient("lscp_list_midi_instrument_maps");                  appendMessagesClient("lscp_list_midi_instrument_maps");
1285                  iErrors++;                  iErrors++;
1286          }          }
1287  #endif  // CONFIG_MIDI_INSTRUMENT  #endif  // CONFIG_MIDI_INSTRUMENT
1288    
1289          // Sampler channel mapping.          // Sampler channel mapping...
1290          QWidgetList wlist = m_pWorkspace->windowList();          int iChannelID = 0;
1291          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          const QList<QMdiSubWindow *>& wlist
1292                  ChannelStrip* pChannelStrip                  = m_pWorkspace->subWindowList();
1293                          = static_cast<ChannelStrip *> (wlist.at(iChannel));          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
1294                    ChannelStrip *pChannelStrip
1295                            = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
1296                  if (pChannelStrip) {                  if (pChannelStrip) {
1297                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1298                          if (pChannel) {                          if (pChannel) {
1299                                  ts << "# " << tr("Channel") << " " << iChannel << endl;                                  // Avoid "artifial" plug-in devices...
1300                                    const int iAudioDevice = pChannel->audioDevice();
1301                                    if (!audioDeviceMap.contains(iAudioDevice))
1302                                            continue;
1303                                    const int iMidiDevice = pChannel->midiDevice();
1304                                    if (!midiDeviceMap.contains(iMidiDevice))
1305                                            continue;
1306                                    // Go for regular, canonical devices...
1307                                    ts << "# " << tr("Channel") << " " << iChannelID << endl;
1308                                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
1309                                  if (audioDeviceMap.isEmpty()) {                                  if (audioDeviceMap.isEmpty()) {
1310                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannelID
1311                                                  << " " << pChannel->audioDriver() << endl;                                                  << " " << pChannel->audioDriver() << endl;
1312                                  } else {                                  } else {
1313                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannelID
1314                                                  << " " << audioDeviceMap[pChannel->audioDevice()] << endl;                                                  << " " << audioDeviceMap.value(iAudioDevice) << endl;
1315                                  }                                  }
1316                                  if (midiDeviceMap.isEmpty()) {                                  if (midiDeviceMap.isEmpty()) {
1317                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannel                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID
1318                                                  << " " << pChannel->midiDriver() << endl;                                                  << " " << pChannel->midiDriver() << endl;
1319                                  } else {                                  } else {
1320                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannel                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannelID
1321                                                  << " " << midiDeviceMap[pChannel->midiDevice()] << endl;                                                  << " " << midiDeviceMap.value(iMidiDevice) << endl;
1322                                  }                                  }
1323                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID
1324                                          << " " << pChannel->midiPort() << endl;                                          << " " << pChannel->midiPort() << endl;
1325                                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";                                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannelID << " ";
1326                                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)                                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
1327                                          ts << "ALL";                                          ts << "ALL";
1328                                  else                                  else
1329                                          ts << pChannel->midiChannel();                                          ts << pChannel->midiChannel();
1330                                  ts << endl;                                  ts << endl;
1331                                  ts << "LOAD ENGINE " << pChannel->engineName()                                  ts << "LOAD ENGINE " << pChannel->engineName()
1332                                          << " " << iChannel << endl;                                          << " " << iChannelID << endl;
1333                                  if (pChannel->instrumentStatus() < 100) ts << "# ";                                  if (pChannel->instrumentStatus() < 100) ts << "# ";
1334                                  ts << "LOAD INSTRUMENT NON_MODAL '"                                  ts << "LOAD INSTRUMENT NON_MODAL '"
1335                                          << pChannel->instrumentFile() << "' "                                          << pChannel->instrumentFile() << "' "
1336                                          << pChannel->instrumentNr() << " " << iChannel << endl;                                          << pChannel->instrumentNr() << " " << iChannelID << endl;
1337                                  ChannelRoutingMap::ConstIterator audioRoute;                                  ChannelRoutingMap::ConstIterator audioRoute;
1338                                  for (audioRoute = pChannel->audioRouting().begin();                                  for (audioRoute = pChannel->audioRouting().begin();
1339                                                  audioRoute != pChannel->audioRouting().end();                                                  audioRoute != pChannel->audioRouting().end();
1340                                                          ++audioRoute) {                                                          ++audioRoute) {
1341                                          ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannelID
1342                                                  << " " << audioRoute.key()                                                  << " " << audioRoute.key()
1343                                                  << " " << audioRoute.value() << endl;                                                  << " " << audioRoute.value() << endl;
1344                                  }                                  }
1345                                  ts << "SET CHANNEL VOLUME " << iChannel                                  ts << "SET CHANNEL VOLUME " << iChannelID
1346                                          << " " << pChannel->volume() << endl;                                          << " " << pChannel->volume() << endl;
1347                                  if (pChannel->channelMute())                                  if (pChannel->channelMute())
1348                                          ts << "SET CHANNEL MUTE " << iChannel << " 1" << endl;                                          ts << "SET CHANNEL MUTE " << iChannelID << " 1" << endl;
1349                                  if (pChannel->channelSolo())                                  if (pChannel->channelSolo())
1350                                          ts << "SET CHANNEL SOLO " << iChannel << " 1" << endl;                                          ts << "SET CHANNEL SOLO " << iChannelID << " 1" << endl;
1351  #ifdef CONFIG_MIDI_INSTRUMENT                          #ifdef CONFIG_MIDI_INSTRUMENT
1352                                  if (pChannel->midiMap() >= 0) {                                  const int iMidiMap = pChannel->midiMap();
1353                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannel                                  if (midiInstrumentMap.contains(iMidiMap)) {
1354                                                  << " " << midiInstrumentMap[pChannel->midiMap()] << endl;                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannelID
1355                                                    << " " << midiInstrumentMap.value(iMidiMap) << endl;
1356                                  }                                  }
1357  #endif                          #endif
1358  #ifdef CONFIG_FXSEND                          #ifdef CONFIG_FXSEND
                                 int iChannelID = pChannel->channelID();  
1359                                  int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID);                                  int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID);
1360                                  for (int iFxSend = 0;                                  for (int iFxSend = 0;
1361                                                  piFxSends && piFxSends[iFxSend] >= 0;                                                  piFxSends && piFxSends[iFxSend] >= 0;
# Line 1196  bool MainForm::saveSessionFile ( const Q Line 1363  bool MainForm::saveSessionFile ( const Q
1363                                          lscp_fxsend_info_t *pFxSendInfo = ::lscp_get_fxsend_info(                                          lscp_fxsend_info_t *pFxSendInfo = ::lscp_get_fxsend_info(
1364                                                  m_pClient, iChannelID, piFxSends[iFxSend]);                                                  m_pClient, iChannelID, piFxSends[iFxSend]);
1365                                          if (pFxSendInfo) {                                          if (pFxSendInfo) {
1366                                                  ts << "CREATE FX_SEND " << iChannel                                                  ts << "CREATE FX_SEND " << iChannelID
1367                                                          << " " << pFxSendInfo->midi_controller;                                                          << " " << pFxSendInfo->midi_controller;
1368                                                  if (pFxSendInfo->name)                                                  if (pFxSendInfo->name)
1369                                                          ts << " '" << pFxSendInfo->name << "'";                                                          ts << " '" << pFxSendInfo->name << "'";
# Line 1206  bool MainForm::saveSessionFile ( const Q Line 1373  bool MainForm::saveSessionFile ( const Q
1373                                                                  piRouting && piRouting[iAudioSrc] >= 0;                                                                  piRouting && piRouting[iAudioSrc] >= 0;
1374                                                                          iAudioSrc++) {                                                                          iAudioSrc++) {
1375                                                          ts << "SET FX_SEND AUDIO_OUTPUT_CHANNEL "                                                          ts << "SET FX_SEND AUDIO_OUTPUT_CHANNEL "
1376                                                                  << iChannel                                                                  << iChannelID
1377                                                                  << " " << iFxSend                                                                  << " " << iFxSend
1378                                                                  << " " << iAudioSrc                                                                  << " " << iAudioSrc
1379                                                                  << " " << piRouting[iAudioSrc] << endl;                                                                  << " " << piRouting[iAudioSrc] << endl;
1380                                                  }                                                  }
1381  #ifdef CONFIG_FXSEND_LEVEL                                          #ifdef CONFIG_FXSEND_LEVEL
1382                                                  ts << "SET FX_SEND LEVEL " << iChannel                                                  ts << "SET FX_SEND LEVEL " << iChannelID
1383                                                          << " " << iFxSend                                                          << " " << iFxSend
1384                                                          << " " << pFxSendInfo->level << endl;                                                          << " " << pFxSendInfo->level << endl;
1385  #endif                                          #endif
1386                                          }       // Check for errors...                                          }       // Check for errors...
1387                                          else if (::lscp_client_get_errno(m_pClient)) {                                          else if (::lscp_client_get_errno(m_pClient)) {
1388                                                  appendMessagesClient("lscp_get_fxsend_info");                                                  appendMessagesClient("lscp_get_fxsend_info");
1389                                                  iErrors++;                                                  iErrors++;
1390                                          }                                          }
1391                                  }                                  }
1392  #endif                          #endif
1393                                  ts << endl;                                  ts << endl;
1394                                    // Go for next channel...
1395                                    ++iChannelID;
1396                          }                          }
1397                  }                  }
1398                  // Try to keep it snappy :)                  // Try to keep it snappy :)
# Line 1275  void MainForm::sessionDirty (void) Line 1444  void MainForm::sessionDirty (void)
1444    
1445    
1446  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1447  // qsamplerMainForm -- File Action slots.  // QSampler::MainForm -- File Action slots.
1448    
1449  // Create a new sampler session.  // Create a new sampler session.
1450  void MainForm::fileNew (void)  void MainForm::fileNew (void)
# Line 1299  void MainForm::fileOpenRecent (void) Line 1468  void MainForm::fileOpenRecent (void)
1468          // Retrive filename index from action data...          // Retrive filename index from action data...
1469          QAction *pAction = qobject_cast<QAction *> (sender());          QAction *pAction = qobject_cast<QAction *> (sender());
1470          if (pAction && m_pOptions) {          if (pAction && m_pOptions) {
1471                  int iIndex = pAction->data().toInt();                  const int iIndex = pAction->data().toInt();
1472                  if (iIndex >= 0 && iIndex < m_pOptions->recentFiles.count()) {                  if (iIndex >= 0 && iIndex < m_pOptions->recentFiles.count()) {
1473                          QString sFilename = m_pOptions->recentFiles[iIndex];                          QString sFilename = m_pOptions->recentFiles[iIndex];
1474                          // Check if we can safely close the current session...                          // Check if we can safely close the current session...
# Line 1329  void MainForm::fileSaveAs (void) Line 1498  void MainForm::fileSaveAs (void)
1498  // Reset the sampler instance.  // Reset the sampler instance.
1499  void MainForm::fileReset (void)  void MainForm::fileReset (void)
1500  {  {
1501          if (m_pClient == NULL)          if (m_pClient == nullptr)
1502                  return;                  return;
1503    
1504          // Ask user whether he/she want's an internal sampler reset...          // Ask user whether he/she want's an internal sampler reset...
1505          if (QMessageBox::warning(this,          if (m_pOptions && m_pOptions->bConfirmReset) {
1506                  QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sTitle = tr("Warning");
1507                  tr("Resetting the sampler instance will close\n"                  const QString& sText = tr(
1508                  "all device and channel configurations.\n\n"                          "Resetting the sampler instance will close\n"
1509                  "Please note that this operation may cause\n"                          "all device and channel configurations.\n\n"
1510                  "temporary MIDI and Audio disruption.\n\n"                          "Please note that this operation may cause\n"
1511                  "Do you want to reset the sampler engine now?"),                          "temporary MIDI and Audio disruption.\n\n"
1512                  QMessageBox::Ok | QMessageBox::Cancel)                          "Do you want to reset the sampler engine now?");
1513                  == QMessageBox::Cancel)          #if 0
1514                  return;                  if (QMessageBox::warning(this, sTitle, sText,
1515                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1516                            return;
1517            #else
1518                    QMessageBox mbox(this);
1519                    mbox.setIcon(QMessageBox::Warning);
1520                    mbox.setWindowTitle(sTitle);
1521                    mbox.setText(sText);
1522                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1523                    QCheckBox cbox(tr("Don't ask this again"));
1524                    cbox.setChecked(false);
1525                    cbox.blockSignals(true);
1526                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1527                    if (mbox.exec() == QMessageBox::Cancel)
1528                            return;
1529                    if (cbox.isChecked())
1530                            m_pOptions->bConfirmReset = false;
1531            #endif
1532            }
1533    
1534          // Trye closing the current session, first...          // Trye closing the current session, first...
1535          if (!closeSession(true))          if (!closeSession(true))
# Line 1367  void MainForm::fileReset (void) Line 1554  void MainForm::fileReset (void)
1554  // Restart the client/server instance.  // Restart the client/server instance.
1555  void MainForm::fileRestart (void)  void MainForm::fileRestart (void)
1556  {  {
1557          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1558                  return;                  return;
1559    
1560          bool bRestart = true;          bool bRestart = true;
1561    
1562          // Ask user whether he/she want's a complete restart...          // Ask user whether he/she want's a complete restart...
1563          // (if we're currently up and running)          // (if we're currently up and running)
1564          if (bRestart && m_pClient) {          if (m_pOptions && m_pOptions->bConfirmRestart) {
1565                  bRestart = (QMessageBox::warning(this,                  const QString& sTitle = tr("Warning");
1566                          QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sText = tr(
1567                          tr("New settings will be effective after\n"                          "New settings will be effective after\n"
1568                          "restarting the client/server connection.\n\n"                          "restarting the client/server connection.\n\n"
1569                          "Please note that this operation may cause\n"                          "Please note that this operation may cause\n"
1570                          "temporary MIDI and Audio disruption.\n\n"                          "temporary MIDI and Audio disruption.\n\n"
1571                          "Do you want to restart the connection now?"),                          "Do you want to restart the connection now?");
1572                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok);          #if 0
1573                    if (QMessageBox::warning(this, sTitle, sText,
1574                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1575                            bRestart = false;
1576            #else
1577                    QMessageBox mbox(this);
1578                    mbox.setIcon(QMessageBox::Warning);
1579                    mbox.setWindowTitle(sTitle);
1580                    mbox.setText(sText);
1581                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1582                    QCheckBox cbox(tr("Don't ask this again"));
1583                    cbox.setChecked(false);
1584                    cbox.blockSignals(true);
1585                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1586                    if (mbox.exec() == QMessageBox::Cancel)
1587                            bRestart = false;
1588                    else
1589                    if (cbox.isChecked())
1590                            m_pOptions->bConfirmRestart = false;
1591            #endif
1592          }          }
1593    
1594          // Are we still for it?          // Are we still for it?
# Line 1404  void MainForm::fileExit (void) Line 1610  void MainForm::fileExit (void)
1610    
1611    
1612  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1613  // qsamplerMainForm -- Edit Action slots.  // QSampler::MainForm -- Edit Action slots.
1614    
1615  // Add a new sampler channel.  // Add a new sampler channel.
1616  void MainForm::editAddChannel (void)  void MainForm::editAddChannel (void)
1617  {  {
1618          if (m_pClient == NULL)          ++m_iDirtySetup;
1619            addChannelStrip();
1620            --m_iDirtySetup;
1621    }
1622    
1623    void MainForm::addChannelStrip (void)
1624    {
1625            if (m_pClient == nullptr)
1626                  return;                  return;
1627    
1628          // Just create the channel instance...          // Just create the channel instance...
1629          Channel *pChannel = new Channel();          Channel *pChannel = new Channel();
1630          if (pChannel == NULL)          if (pChannel == nullptr)
1631                  return;                  return;
1632    
1633          // Before we show it up, may be we'll          // Before we show it up, may be we'll
# Line 1432  void MainForm::editAddChannel (void) Line 1645  void MainForm::editAddChannel (void)
1645          }          }
1646    
1647          // Do we auto-arrange?          // Do we auto-arrange?
1648          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
1649    
1650          // Make that an overall update.          // Make that an overall update.
1651          m_iDirtyCount++;          m_iDirtyCount++;
# Line 1444  void MainForm::editAddChannel (void) Line 1656  void MainForm::editAddChannel (void)
1656  // Remove current sampler channel.  // Remove current sampler channel.
1657  void MainForm::editRemoveChannel (void)  void MainForm::editRemoveChannel (void)
1658  {  {
1659          if (m_pClient == NULL)          ++m_iDirtySetup;
1660            removeChannelStrip();
1661            --m_iDirtySetup;
1662    }
1663    
1664    void MainForm::removeChannelStrip (void)
1665    {
1666            if (m_pClient == nullptr)
1667                  return;                  return;
1668    
1669          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1670          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1671                  return;                  return;
1672    
1673          Channel *pChannel = pChannelStrip->channel();          Channel *pChannel = pChannelStrip->channel();
1674          if (pChannel == NULL)          if (pChannel == nullptr)
1675                  return;                  return;
1676    
1677          // Prompt user if he/she's sure about this...          // Prompt user if he/she's sure about this...
1678          if (m_pOptions && m_pOptions->bConfirmRemove) {          if (m_pOptions && m_pOptions->bConfirmRemove) {
1679                  if (QMessageBox::warning(this,                  const QString& sTitle = tr("Warning");
1680                          QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sText = tr(
1681                          tr("About to remove channel:\n\n"                          "About to remove channel:\n\n"
1682                          "%1\n\n"                          "%1\n\n"
1683                          "Are you sure?")                          "Are you sure?")
1684                          .arg(pChannelStrip->windowTitle()),                          .arg(pChannelStrip->windowTitle());
1685                          QMessageBox::Ok | QMessageBox::Cancel)          #if 0
1686                          == QMessageBox::Cancel)                  if (QMessageBox::warning(this, sTitle, sText,
1687                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1688                            return;
1689            #else
1690                    QMessageBox mbox(this);
1691                    mbox.setIcon(QMessageBox::Warning);
1692                    mbox.setWindowTitle(sTitle);
1693                    mbox.setText(sText);
1694                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1695                    QCheckBox cbox(tr("Don't ask this again"));
1696                    cbox.setChecked(false);
1697                    cbox.blockSignals(true);
1698                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1699                    if (mbox.exec() == QMessageBox::Cancel)
1700                          return;                          return;
1701                    if (cbox.isChecked())
1702                            m_pOptions->bConfirmRemove = false;
1703            #endif
1704          }          }
1705    
1706          // Remove the existing sampler channel.          // Remove the existing sampler channel.
# Line 1473  void MainForm::editRemoveChannel (void) Line 1708  void MainForm::editRemoveChannel (void)
1708                  return;                  return;
1709    
1710          // Just delete the channel strip.          // Just delete the channel strip.
1711          delete pChannelStrip;          destroyChannelStrip(pChannelStrip);
   
         // Do we auto-arrange?  
         if (m_pOptions && m_pOptions->bAutoArrange)  
                 channelsArrange();  
1712    
1713          // We'll be dirty, for sure...          // We'll be dirty, for sure...
1714          m_iDirtyCount++;          m_iDirtyCount++;
# Line 1488  void MainForm::editRemoveChannel (void) Line 1719  void MainForm::editRemoveChannel (void)
1719  // Setup current sampler channel.  // Setup current sampler channel.
1720  void MainForm::editSetupChannel (void)  void MainForm::editSetupChannel (void)
1721  {  {
1722          if (m_pClient == NULL)          if (m_pClient == nullptr)
1723                  return;                  return;
1724    
1725          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1726          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1727                  return;                  return;
1728    
1729          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1503  void MainForm::editSetupChannel (void) Line 1734  void MainForm::editSetupChannel (void)
1734  // Edit current sampler channel.  // Edit current sampler channel.
1735  void MainForm::editEditChannel (void)  void MainForm::editEditChannel (void)
1736  {  {
1737          if (m_pClient == NULL)          if (m_pClient == nullptr)
1738                  return;                  return;
1739    
1740          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1741          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1742                  return;                  return;
1743    
1744          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1518  void MainForm::editEditChannel (void) Line 1749  void MainForm::editEditChannel (void)
1749  // Reset current sampler channel.  // Reset current sampler channel.
1750  void MainForm::editResetChannel (void)  void MainForm::editResetChannel (void)
1751  {  {
1752          if (m_pClient == NULL)          if (m_pClient == nullptr)
1753                  return;                  return;
1754    
1755          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1756          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1757                  return;                  return;
1758    
1759          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1533  void MainForm::editResetChannel (void) Line 1764  void MainForm::editResetChannel (void)
1764  // Reset all sampler channels.  // Reset all sampler channels.
1765  void MainForm::editResetAllChannels (void)  void MainForm::editResetAllChannels (void)
1766  {  {
1767          if (m_pClient == NULL)          if (m_pClient == nullptr)
1768                  return;                  return;
1769    
1770          // Invoque the channel strip procedure,          // Invoque the channel strip procedure,
1771          // for all channels out there...          // for all channels out there...
1772          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1773          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
1774          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                  = m_pWorkspace->subWindowList();
1775                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
1776                    ChannelStrip *pChannelStrip
1777                            = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
1778                  if (pChannelStrip)                  if (pChannelStrip)
1779                          pChannelStrip->channelReset();                          pChannelStrip->channelReset();
1780          }          }
# Line 1550  void MainForm::editResetAllChannels (voi Line 1783  void MainForm::editResetAllChannels (voi
1783    
1784    
1785  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1786  // qsamplerMainForm -- View Action slots.  // QSampler::MainForm -- View Action slots.
1787    
1788  // Show/hide the main program window menubar.  // Show/hide the main program window menubar.
1789  void MainForm::viewMenubar ( bool bOn )  void MainForm::viewMenubar ( bool bOn )
# Line 1600  void MainForm::viewMessages ( bool bOn ) Line 1833  void MainForm::viewMessages ( bool bOn )
1833  // Show/hide the MIDI instrument list-view form.  // Show/hide the MIDI instrument list-view form.
1834  void MainForm::viewInstruments (void)  void MainForm::viewInstruments (void)
1835  {  {
1836          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1837                  return;                  return;
1838    
1839          if (m_pInstrumentListForm) {          if (m_pInstrumentListForm) {
# Line 1619  void MainForm::viewInstruments (void) Line 1852  void MainForm::viewInstruments (void)
1852  // Show/hide the device configurator form.  // Show/hide the device configurator form.
1853  void MainForm::viewDevices (void)  void MainForm::viewDevices (void)
1854  {  {
1855          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1856                  return;                  return;
1857    
1858          if (m_pDeviceForm) {          if (m_pDeviceForm) {
# Line 1638  void MainForm::viewDevices (void) Line 1871  void MainForm::viewDevices (void)
1871  // Show options dialog.  // Show options dialog.
1872  void MainForm::viewOptions (void)  void MainForm::viewOptions (void)
1873  {  {
1874          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1875                  return;                  return;
1876    
1877          OptionsForm* pOptionsForm = new OptionsForm(this);          OptionsForm* pOptionsForm = new OptionsForm(this);
1878          if (pOptionsForm) {          if (pOptionsForm) {
1879                  // Check out some initial nullities(tm)...                  // Check out some initial nullities(tm)...
1880                  ChannelStrip* pChannelStrip = activeChannelStrip();                  ChannelStrip *pChannelStrip = activeChannelStrip();
1881                  if (m_pOptions->sDisplayFont.isEmpty() && pChannelStrip)                  if (m_pOptions->sDisplayFont.isEmpty() && pChannelStrip)
1882                          m_pOptions->sDisplayFont = pChannelStrip->displayFont().toString();                          m_pOptions->sDisplayFont = pChannelStrip->displayFont().toString();
1883                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)
1884                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();
1885                  // To track down deferred or immediate changes.                  // To track down deferred or immediate changes.
1886                  QString sOldServerHost      = m_pOptions->sServerHost;                  const QString sOldServerHost       = m_pOptions->sServerHost;
1887                  int     iOldServerPort      = m_pOptions->iServerPort;                  const int     iOldServerPort       = m_pOptions->iServerPort;
1888                  int     iOldServerTimeout   = m_pOptions->iServerTimeout;                  const int     iOldServerTimeout    = m_pOptions->iServerTimeout;
1889                  bool    bOldServerStart     = m_pOptions->bServerStart;                  const bool    bOldServerStart      = m_pOptions->bServerStart;
1890                  QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;                  const QString sOldServerCmdLine    = m_pOptions->sServerCmdLine;
1891                  bool    bOldMessagesLog     = m_pOptions->bMessagesLog;                  const bool    bOldMessagesLog      = m_pOptions->bMessagesLog;
1892                  QString sOldMessagesLogPath = m_pOptions->sMessagesLogPath;                  const QString sOldMessagesLogPath  = m_pOptions->sMessagesLogPath;
1893                  QString sOldDisplayFont     = m_pOptions->sDisplayFont;                  const QString sOldDisplayFont      = m_pOptions->sDisplayFont;
1894                  bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;                  const bool    bOldDisplayEffect    = m_pOptions->bDisplayEffect;
1895                  int     iOldMaxVolume       = m_pOptions->iMaxVolume;                  const int     iOldMaxVolume        = m_pOptions->iMaxVolume;
1896                  QString sOldMessagesFont    = m_pOptions->sMessagesFont;                  const QString sOldMessagesFont     = m_pOptions->sMessagesFont;
1897                  bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;                  const bool    bOldKeepOnTop        = m_pOptions->bKeepOnTop;
1898                  bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;                  const bool    bOldStdoutCapture    = m_pOptions->bStdoutCapture;
1899                  int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;                  const int     bOldMessagesLimit    = m_pOptions->bMessagesLimit;
1900                  int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;                  const int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1901                  bool    bOldCompletePath    = m_pOptions->bCompletePath;                  const bool    bOldCompletePath     = m_pOptions->bCompletePath;
1902                  bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;                  const bool    bOldInstrumentNames  = m_pOptions->bInstrumentNames;
1903                  int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;                  const int     iOldMaxRecentFiles   = m_pOptions->iMaxRecentFiles;
1904                  int     iOldBaseFontSize    = m_pOptions->iBaseFontSize;                  const int     iOldBaseFontSize     = m_pOptions->iBaseFontSize;
1905                    const QString sOldCustomStyleTheme = m_pOptions->sCustomStyleTheme;
1906                    const QString sOldCustomColorTheme = m_pOptions->sCustomColorTheme;
1907                  // Load the current setup settings.                  // Load the current setup settings.
1908                  pOptionsForm->setup(m_pOptions);                  pOptionsForm->setup(m_pOptions);
1909                  // Show the setup dialog...                  // Show the setup dialog...
1910                  if (pOptionsForm->exec()) {                  if (pOptionsForm->exec()) {
1911                          // Warn if something will be only effective on next run.                          // Warn if something will be only effective on next run.
1912                            int iNeedRestart = 0;
1913                          if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||                          if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1914                                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||                                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture)) {
1915                                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||                                  updateMessagesCapture();
1916                                    ++iNeedRestart;
1917                            }
1918                            if (( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1919                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)     ||                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)     ||
1920                                  (iOldBaseFontSize   !=  m_pOptions->iBaseFontSize)) {                                  (iOldBaseFontSize   !=  m_pOptions->iBaseFontSize)) {
1921                                  QMessageBox::information(this,                                  ++iNeedRestart;
1922                                          QSAMPLER_TITLE ": " + tr("Information"),                          }
1923                                          tr("Some settings may be only effective\n"                          // Check whether restart is needed or whether
1924                                          "next time you start this program."));                          // custom options maybe set up immediately...
1925                                  updateMessagesCapture();                          if (m_pOptions->sCustomStyleTheme != sOldCustomStyleTheme) {
1926                                    if (m_pOptions->sCustomStyleTheme.isEmpty()) {
1927                                            ++iNeedRestart;
1928                                    } else {
1929                                            QApplication::setStyle(
1930                                                    QStyleFactory::create(m_pOptions->sCustomStyleTheme));
1931                                    }
1932                            }
1933                            if (m_pOptions->sCustomColorTheme != sOldCustomColorTheme) {
1934                                    if (m_pOptions->sCustomColorTheme.isEmpty()) {
1935                                            ++iNeedRestart;
1936                                    } else {
1937                                            QPalette pal;
1938                                            if (PaletteForm::namedPalette(
1939                                                            &m_pOptions->settings(), m_pOptions->sCustomColorTheme, pal))
1940                                                    QApplication::setPalette(pal);
1941                                    }
1942                          }                          }
1943                          // Check wheather something immediate has changed.                          // Check wheather something immediate has changed.
1944                          if (( bOldMessagesLog && !m_pOptions->bMessagesLog) ||                          if (( bOldMessagesLog && !m_pOptions->bMessagesLog) ||
# Line 1711  void MainForm::viewOptions (void) Line 1966  void MainForm::viewOptions (void)
1966                                  (!bOldMessagesLimit &&  m_pOptions->bMessagesLimit) ||                                  (!bOldMessagesLimit &&  m_pOptions->bMessagesLimit) ||
1967                                  (iOldMessagesLimitLines !=  m_pOptions->iMessagesLimitLines))                                  (iOldMessagesLimitLines !=  m_pOptions->iMessagesLimitLines))
1968                                  updateMessagesLimit();                                  updateMessagesLimit();
1969                            // Show restart needed message...
1970                            if (iNeedRestart > 0) {
1971                                    QMessageBox::information(this,
1972                                            tr("Information"),
1973                                            tr("Some settings may be only effective\n"
1974                                            "next time you start this program."));
1975                            }
1976                          // And now the main thing, whether we'll do client/server recycling?                          // And now the main thing, whether we'll do client/server recycling?
1977                          if ((sOldServerHost != m_pOptions->sServerHost) ||                          if ((sOldServerHost != m_pOptions->sServerHost) ||
1978                                  (iOldServerPort != m_pOptions->iServerPort) ||                                  (iOldServerPort != m_pOptions->iServerPort) ||
# Line 1731  void MainForm::viewOptions (void) Line 1993  void MainForm::viewOptions (void)
1993    
1994    
1995  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1996  // qsamplerMainForm -- Channels action slots.  // QSampler::MainForm -- Channels action slots.
1997    
1998  // Arrange channel strips.  // Arrange channel strips.
1999  void MainForm::channelsArrange (void)  void MainForm::channelsArrange (void)
2000  {  {
2001          // Full width vertical tiling          // Full width vertical tiling
2002          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2003                    = m_pWorkspace->subWindowList();
2004          if (wlist.isEmpty())          if (wlist.isEmpty())
2005                  return;                  return;
2006    
2007          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2008          int y = 0;          int y = 0;
2009          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2010                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  pMdiSubWindow->adjustSize();
2011          /*  if (pChannelStrip->testWState(WState_Maximized | WState_Minimized)) {                  const QRect& frameRect
2012                          // Prevent flicker...                          = pMdiSubWindow->frameGeometry();
2013                          pChannelStrip->hide();                  int w = m_pWorkspace->width();
2014                          pChannelStrip->showNormal();                  if (w < frameRect.width())
2015                  }   */                          w = frameRect.width();
2016                  pChannelStrip->adjustSize();                  const int h = frameRect.height();
2017                  int iWidth  = m_pWorkspace->width();                  pMdiSubWindow->setGeometry(0, y, w, h);
2018                  if (iWidth < pChannelStrip->width())                  y += h;
                         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;  
2019          }          }
2020          m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
2021    
# Line 1769  void MainForm::channelsArrange (void) Line 2026  void MainForm::channelsArrange (void)
2026  // Auto-arrange channel strips.  // Auto-arrange channel strips.
2027  void MainForm::channelsAutoArrange ( bool bOn )  void MainForm::channelsAutoArrange ( bool bOn )
2028  {  {
2029          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2030                  return;                  return;
2031    
2032          // Toggle the auto-arrange flag.          // Toggle the auto-arrange flag.
2033          m_pOptions->bAutoArrange = bOn;          m_pOptions->bAutoArrange = bOn;
2034    
2035          // If on, update whole workspace...          // If on, update whole workspace...
2036          if (m_pOptions->bAutoArrange)          channelsArrangeAuto();
2037    }
2038    
2039    
2040    void MainForm::channelsArrangeAuto (void)
2041    {
2042            if (m_pOptions && m_pOptions->bAutoArrange)
2043                  channelsArrange();                  channelsArrange();
2044  }  }
2045    
2046    
2047  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2048  // qsamplerMainForm -- Help Action slots.  // QSampler::MainForm -- Help Action slots.
2049    
2050  // Show information about the Qt toolkit.  // Show information about the Qt toolkit.
2051  void MainForm::helpAboutQt (void)  void MainForm::helpAboutQt (void)
# Line 1794  void MainForm::helpAboutQt (void) Line 2057  void MainForm::helpAboutQt (void)
2057  // Show information about application program.  // Show information about application program.
2058  void MainForm::helpAbout (void)  void MainForm::helpAbout (void)
2059  {  {
2060          // 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";  
2061  #ifdef CONFIG_DEBUG  #ifdef CONFIG_DEBUG
2062          sText += "<small><font color=\"red\">";          list << tr("Debugging option enabled.");
         sText += tr("Debugging option enabled.");  
         sText += "</font></small><br />";  
2063  #endif  #endif
2064  #ifndef CONFIG_LIBGIG  #ifndef CONFIG_LIBGIG
2065          sText += "<small><font color=\"red\">";          list << tr("GIG (libgig) file support disabled.");
         sText += tr("GIG (libgig) file support disabled.");  
         sText += "</font></small><br />";  
2066  #endif  #endif
2067  #ifndef CONFIG_INSTRUMENT_NAME  #ifndef CONFIG_INSTRUMENT_NAME
2068          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 />";  
2069  #endif  #endif
2070  #ifndef CONFIG_MUTE_SOLO  #ifndef CONFIG_MUTE_SOLO
2071          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 />";  
2072  #endif  #endif
2073  #ifndef CONFIG_AUDIO_ROUTING  #ifndef CONFIG_AUDIO_ROUTING
2074          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 />";  
2075  #endif  #endif
2076  #ifndef CONFIG_FXSEND  #ifndef CONFIG_FXSEND
2077          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 />";  
2078  #endif  #endif
2079  #ifndef CONFIG_VOLUME  #ifndef CONFIG_VOLUME
2080          sText += "<small><font color=\"red\">";          list << tr("Global volume support disabled.");
         sText += tr("Global volume support disabled.");  
         sText += "</font></small><br />";  
2081  #endif  #endif
2082  #ifndef CONFIG_MIDI_INSTRUMENT  #ifndef CONFIG_MIDI_INSTRUMENT
2083          sText += "<small><font color=\"red\">";          list << tr("MIDI instrument mapping support disabled.");
         sText += tr("MIDI instrument mapping support disabled.");  
         sText += "</font></small><br />";  
2084  #endif  #endif
2085  #ifndef CONFIG_EDIT_INSTRUMENT  #ifndef CONFIG_EDIT_INSTRUMENT
2086          sText += "<small><font color=\"red\">";          list << tr("Instrument editing support disabled.");
         sText += tr("Instrument editing support disabled.");  
         sText += "</font></small><br />";  
2087  #endif  #endif
2088  #ifndef CONFIG_EVENT_CHANNEL_MIDI  #ifndef CONFIG_EVENT_CHANNEL_MIDI
2089          sText += "<small><font color=\"red\">";          list << tr("Channel MIDI event support disabled.");
         sText += tr("Channel MIDI event support disabled.");  
         sText += "</font></small><br />";  
2090  #endif  #endif
2091  #ifndef CONFIG_EVENT_DEVICE_MIDI  #ifndef CONFIG_EVENT_DEVICE_MIDI
2092          sText += "<small><font color=\"red\">";          list << tr("Device MIDI event support disabled.");
         sText += tr("Device MIDI event support disabled.");  
         sText += "</font></small><br />";  
2093  #endif  #endif
2094  #ifndef CONFIG_MAX_VOICES  #ifndef CONFIG_MAX_VOICES
2095          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 />";  
2096  #endif  #endif
2097    
2098            // Stuff the about box text...
2099            QString sText = "<p>\n";
2100            sText += "<b>" QSAMPLER_TITLE " - " + tr(QSAMPLER_SUBTITLE) + "</b><br />\n";
2101          sText += "<br />\n";          sText += "<br />\n";
2102          sText += tr("Using") + ": ";          sText += tr("Version") + ": <b>" CONFIG_BUILD_VERSION "</b><br />\n";
2103    //      sText += "<small>" + tr("Build") + ": " CONFIG_BUILD_DATE "</small><br />\n";
2104            if (!list.isEmpty()) {
2105                    sText += "<small><font color=\"red\">";
2106                    sText += list.join("<br />\n");
2107                    sText += "</font></small>";
2108            }
2109            sText += "<br />\n";
2110            sText += tr("Using: Qt %1").arg(qVersion());
2111    #if defined(QT_STATIC)
2112            sText += "-static";
2113    #endif
2114            sText += ", ";
2115          sText += ::lscp_client_package();          sText += ::lscp_client_package();
2116          sText += " ";          sText += " ";
2117          sText += ::lscp_client_version();          sText += ::lscp_client_version();
# Line 1884  void MainForm::helpAbout (void) Line 2134  void MainForm::helpAbout (void)
2134          sText += "</small>";          sText += "</small>";
2135          sText += "</p>\n";          sText += "</p>\n";
2136    
2137          QMessageBox::about(this, tr("About") + " " QSAMPLER_TITLE, sText);          QMessageBox::about(this, tr("About"), sText);
2138  }  }
2139    
2140    
2141  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2142  // qsamplerMainForm -- Main window stabilization.  // QSampler::MainForm -- Main window stabilization.
2143    
2144  void MainForm::stabilizeForm (void)  void MainForm::stabilizeForm (void)
2145  {  {
# Line 1897  void MainForm::stabilizeForm (void) Line 2147  void MainForm::stabilizeForm (void)
2147          QString sSessionName = sessionName(m_sFilename);          QString sSessionName = sessionName(m_sFilename);
2148          if (m_iDirtyCount > 0)          if (m_iDirtyCount > 0)
2149                  sSessionName += " *";                  sSessionName += " *";
2150          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));          setWindowTitle(sSessionName);
2151    
2152          // Update the main menu state...          // Update the main menu state...
2153          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
2154          bool bHasClient = (m_pOptions != NULL && m_pClient != NULL);          const QList<QMdiSubWindow *>& wlist = m_pWorkspace->subWindowList();
2155          bool bHasChannel = (bHasClient && pChannelStrip != NULL);          const bool bHasClient = (m_pOptions != nullptr && m_pClient != nullptr);
2156          bool bHasChannels = (bHasClient && m_pWorkspace->windowList().count() > 0);          const bool bHasChannel = (bHasClient && pChannelStrip != nullptr);
2157            const bool bHasChannels = (bHasClient && wlist.count() > 0);
2158          m_ui.fileNewAction->setEnabled(bHasClient);          m_ui.fileNewAction->setEnabled(bHasClient);
2159          m_ui.fileOpenAction->setEnabled(bHasClient);          m_ui.fileOpenAction->setEnabled(bHasClient);
2160          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
2161          m_ui.fileSaveAsAction->setEnabled(bHasClient);          m_ui.fileSaveAsAction->setEnabled(bHasClient);
2162          m_ui.fileResetAction->setEnabled(bHasClient);          m_ui.fileResetAction->setEnabled(bHasClient);
2163          m_ui.fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);          m_ui.fileRestartAction->setEnabled(bHasClient || m_pServer == nullptr);
2164          m_ui.editAddChannelAction->setEnabled(bHasClient);          m_ui.editAddChannelAction->setEnabled(bHasClient);
2165          m_ui.editRemoveChannelAction->setEnabled(bHasChannel);          m_ui.editRemoveChannelAction->setEnabled(bHasChannel);
2166          m_ui.editSetupChannelAction->setEnabled(bHasChannel);          m_ui.editSetupChannelAction->setEnabled(bHasChannel);
# Line 1983  void MainForm::volumeChanged ( int iVolu Line 2234  void MainForm::volumeChanged ( int iVolu
2234                  m_pVolumeSpinBox->setValue(iVolume);                  m_pVolumeSpinBox->setValue(iVolume);
2235    
2236          // Do it as commanded...          // Do it as commanded...
2237          float fVolume = 0.01f * float(iVolume);          const float fVolume = 0.01f * float(iVolume);
2238          if (::lscp_set_volume(m_pClient, fVolume) == LSCP_OK)          if (::lscp_set_volume(m_pClient, fVolume) == LSCP_OK)
2239                  appendMessages(QObject::tr("Volume: %1.").arg(fVolume));                  appendMessages(QObject::tr("Volume: %1.").arg(fVolume));
2240          else          else
# Line 1999  void MainForm::volumeChanged ( int iVolu Line 2250  void MainForm::volumeChanged ( int iVolu
2250    
2251    
2252  // Channel change receiver slot.  // Channel change receiver slot.
2253  void MainForm::channelStripChanged(ChannelStrip* pChannelStrip)  void MainForm::channelStripChanged ( ChannelStrip *pChannelStrip )
2254  {  {
2255          // Add this strip to the changed list...          // Add this strip to the changed list...
2256          if (!m_changedStrips.contains(pChannelStrip)) {          if (!m_changedStrips.contains(pChannelStrip)) {
# Line 2018  void MainForm::channelStripChanged(Chann Line 2269  void MainForm::channelStripChanged(Chann
2269  void MainForm::updateSession (void)  void MainForm::updateSession (void)
2270  {  {
2271  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
2272          int iVolume = ::lroundf(100.0f * ::lscp_get_volume(m_pClient));          const int iVolume = ::lroundf(100.0f * ::lscp_get_volume(m_pClient));
2273          m_iVolumeChanging++;          m_iVolumeChanging++;
2274          m_pVolumeSlider->setValue(iVolume);          m_pVolumeSlider->setValue(iVolume);
2275          m_pVolumeSpinBox->setValue(iVolume);          m_pVolumeSpinBox->setValue(iVolume);
# Line 2026  void MainForm::updateSession (void) Line 2277  void MainForm::updateSession (void)
2277  #endif  #endif
2278  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
2279          // FIXME: Make some room for default instrument maps...          // FIXME: Make some room for default instrument maps...
2280          int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);          const int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);
2281          if (iMaps < 0)          if (iMaps < 0)
2282                  appendMessagesClient("lscp_get_midi_instrument_maps");                  appendMessagesClient("lscp_get_midi_instrument_maps");
2283          else if (iMaps < 1) {          else if (iMaps < 1) {
# Line 2040  void MainForm::updateSession (void) Line 2291  void MainForm::updateSession (void)
2291          updateAllChannelStrips(false);          updateAllChannelStrips(false);
2292    
2293          // Do we auto-arrange?          // Do we auto-arrange?
2294          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
2295    
2296          // Remember to refresh devices and instruments...          // Remember to refresh devices and instruments...
2297          if (m_pInstrumentListForm)          if (m_pInstrumentListForm)
# Line 2050  void MainForm::updateSession (void) Line 2300  void MainForm::updateSession (void)
2300                  m_pDeviceForm->refreshDevices();                  m_pDeviceForm->refreshDevices();
2301  }  }
2302    
2303  void MainForm::updateAllChannelStrips(bool bRemoveDeadStrips) {  
2304    void MainForm::updateAllChannelStrips ( bool bRemoveDeadStrips )
2305    {
2306            // Skip if setting up a new channel strip...
2307            if (m_iDirtySetup > 0)
2308                    return;
2309    
2310          // Retrieve the current channel list.          // Retrieve the current channel list.
2311          int *piChannelIDs = ::lscp_list_channels(m_pClient);          int *piChannelIDs = ::lscp_list_channels(m_pClient);
2312          if (piChannelIDs == NULL) {          if (piChannelIDs == nullptr) {
2313                  if (::lscp_client_get_errno(m_pClient)) {                  if (::lscp_client_get_errno(m_pClient)) {
2314                          appendMessagesClient("lscp_list_channels");                          appendMessagesClient("lscp_list_channels");
2315                          appendMessagesError(                          appendMessagesError(
# Line 2062  void MainForm::updateAllChannelStrips(bo Line 2318  void MainForm::updateAllChannelStrips(bo
2318          } else {          } else {
2319                  // Try to (re)create each channel.                  // Try to (re)create each channel.
2320                  m_pWorkspace->setUpdatesEnabled(false);                  m_pWorkspace->setUpdatesEnabled(false);
2321                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {
2322                          // Check if theres already a channel strip for this one...                          // Check if theres already a channel strip for this one...
2323                          if (!channelStrip(piChannelIDs[iChannel]))                          if (!channelStrip(piChannelIDs[iChannel]))
2324                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));
2325                  }                  }
   
2326                  // Do we auto-arrange?                  // Do we auto-arrange?
2327                  if (m_pOptions && m_pOptions->bAutoArrange)                  channelsArrangeAuto();
                         channelsArrange();  
   
                 stabilizeForm();  
   
2328                  // remove dead channel strips                  // remove dead channel strips
2329                  if (bRemoveDeadStrips) {                  if (bRemoveDeadStrips) {
2330                          for (int i = 0; channelStripAt(i); ++i) {                          const QList<QMdiSubWindow *>& wlist
2331                                  ChannelStrip* pChannelStrip = channelStripAt(i);                                  = m_pWorkspace->subWindowList();
2332                                  bool bExists = false;                          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2333                                  for (int j = 0; piChannelIDs[j] >= 0; ++j) {                                  ChannelStrip *pChannelStrip
2334                                          if (!pChannelStrip->channel()) break;                                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2335                                          if (piChannelIDs[j] == pChannelStrip->channel()->channelID()) {                                  if (pChannelStrip) {
2336                                                  // strip exists, don't touch it                                          bool bExists = false;
2337                                                  bExists = true;                                          for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {
2338                                                  break;                                                  Channel *pChannel = pChannelStrip->channel();
2339                                                    if (pChannel == nullptr)
2340                                                            break;
2341                                                    if (piChannelIDs[iChannel] == pChannel->channelID()) {
2342                                                            // strip exists, don't touch it
2343                                                            bExists = true;
2344                                                            break;
2345                                                    }
2346                                          }                                          }
2347                                            if (!bExists)
2348                                                    destroyChannelStrip(pChannelStrip);
2349                                  }                                  }
                                 if (!bExists) destroyChannelStrip(pChannelStrip);  
2350                          }                          }
2351                  }                  }
2352                  m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
2353          }          }
2354    
2355            stabilizeForm();
2356  }  }
2357    
2358    
2359  // Update the recent files list and menu.  // Update the recent files list and menu.
2360  void MainForm::updateRecentFiles ( const QString& sFilename )  void MainForm::updateRecentFiles ( const QString& sFilename )
2361  {  {
2362          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2363                  return;                  return;
2364    
2365          // Remove from list if already there (avoid duplicates)          // Remove from list if already there (avoid duplicates)
2366          int iIndex = m_pOptions->recentFiles.indexOf(sFilename);          const int iIndex = m_pOptions->recentFiles.indexOf(sFilename);
2367          if (iIndex >= 0)          if (iIndex >= 0)
2368                  m_pOptions->recentFiles.removeAt(iIndex);                  m_pOptions->recentFiles.removeAt(iIndex);
2369          // Put it to front...          // Put it to front...
# Line 2112  void MainForm::updateRecentFiles ( const Line 2374  void MainForm::updateRecentFiles ( const
2374  // Update the recent files list and menu.  // Update the recent files list and menu.
2375  void MainForm::updateRecentFilesMenu (void)  void MainForm::updateRecentFilesMenu (void)
2376  {  {
2377          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2378                  return;                  return;
2379    
2380          // Time to keep the list under limits.          // Time to keep the list under limits.
# Line 2140  void MainForm::updateRecentFilesMenu (vo Line 2402  void MainForm::updateRecentFilesMenu (vo
2402  void MainForm::updateInstrumentNames (void)  void MainForm::updateInstrumentNames (void)
2403  {  {
2404          // Full channel list update...          // Full channel list update...
2405          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2406                    = m_pWorkspace->subWindowList();
2407          if (wlist.isEmpty())          if (wlist.isEmpty())
2408                  return;                  return;
2409    
2410          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2411          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2412                  ChannelStrip *pChannelStrip = (ChannelStrip *) wlist.at(iChannel);                  ChannelStrip *pChannelStrip
2413                            = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2414                  if (pChannelStrip)                  if (pChannelStrip)
2415                          pChannelStrip->updateInstrumentName(true);                          pChannelStrip->updateInstrumentName(true);
2416          }          }
# Line 2157  void MainForm::updateInstrumentNames (vo Line 2421  void MainForm::updateInstrumentNames (vo
2421  // Force update of the channels display font.  // Force update of the channels display font.
2422  void MainForm::updateDisplayFont (void)  void MainForm::updateDisplayFont (void)
2423  {  {
2424          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2425                  return;                  return;
2426    
2427          // Check if display font is legal.          // Check if display font is legal.
2428          if (m_pOptions->sDisplayFont.isEmpty())          if (m_pOptions->sDisplayFont.isEmpty())
2429                  return;                  return;
2430    
2431          // Realize it.          // Realize it.
2432          QFont font;          QFont font;
2433          if (!font.fromString(m_pOptions->sDisplayFont))          if (!font.fromString(m_pOptions->sDisplayFont))
2434                  return;                  return;
2435    
2436          // Full channel list update...          // Full channel list update...
2437          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2438                    = m_pWorkspace->subWindowList();
2439          if (wlist.isEmpty())          if (wlist.isEmpty())
2440                  return;                  return;
2441    
2442          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2443          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2444                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  ChannelStrip *pChannelStrip
2445                            = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2446                  if (pChannelStrip)                  if (pChannelStrip)
2447                          pChannelStrip->setDisplayFont(font);                          pChannelStrip->setDisplayFont(font);
2448          }          }
# Line 2187  void MainForm::updateDisplayFont (void) Line 2454  void MainForm::updateDisplayFont (void)
2454  void MainForm::updateDisplayEffect (void)  void MainForm::updateDisplayEffect (void)
2455  {  {
2456          // Full channel list update...          // Full channel list update...
2457          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2458                    = m_pWorkspace->subWindowList();
2459          if (wlist.isEmpty())          if (wlist.isEmpty())
2460                  return;                  return;
2461    
2462          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2463          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2464                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  ChannelStrip *pChannelStrip
2465                            = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2466                  if (pChannelStrip)                  if (pChannelStrip)
2467                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2468          }          }
# Line 2204  void MainForm::updateDisplayEffect (void Line 2473  void MainForm::updateDisplayEffect (void
2473  // Force update of the channels maximum volume setting.  // Force update of the channels maximum volume setting.
2474  void MainForm::updateMaxVolume (void)  void MainForm::updateMaxVolume (void)
2475  {  {
2476          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2477                  return;                  return;
2478    
2479  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
# Line 2215  void MainForm::updateMaxVolume (void) Line 2484  void MainForm::updateMaxVolume (void)
2484  #endif  #endif
2485    
2486          // Full channel list update...          // Full channel list update...
2487          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2488                    = m_pWorkspace->subWindowList();
2489          if (wlist.isEmpty())          if (wlist.isEmpty())
2490                  return;                  return;
2491    
2492          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2493          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2494                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  ChannelStrip *pChannelStrip
2495                            = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2496                  if (pChannelStrip)                  if (pChannelStrip)
2497                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2498          }          }
# Line 2230  void MainForm::updateMaxVolume (void) Line 2501  void MainForm::updateMaxVolume (void)
2501    
2502    
2503  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2504  // qsamplerMainForm -- Messages window form handlers.  // QSampler::MainForm -- Messages window form handlers.
2505    
2506  // Messages output methods.  // Messages output methods.
2507  void MainForm::appendMessages( const QString& s )  void MainForm::appendMessages ( const QString& s )
2508  {  {
2509          if (m_pMessages)          if (m_pMessages)
2510                  m_pMessages->appendMessages(s);                  m_pMessages->appendMessages(s);
# Line 2241  void MainForm::appendMessages( const QSt Line 2512  void MainForm::appendMessages( const QSt
2512          statusBar()->showMessage(s, 3000);          statusBar()->showMessage(s, 3000);
2513  }  }
2514    
2515  void MainForm::appendMessagesColor( const QString& s, const QString& c )  void MainForm::appendMessagesColor ( const QString& s, const QColor& rgb )
2516  {  {
2517          if (m_pMessages)          if (m_pMessages)
2518                  m_pMessages->appendMessagesColor(s, c);                  m_pMessages->appendMessagesColor(s, rgb);
2519    
2520          statusBar()->showMessage(s, 3000);          statusBar()->showMessage(s, 3000);
2521  }  }
2522    
2523  void MainForm::appendMessagesText( const QString& s )  void MainForm::appendMessagesText ( const QString& s )
2524  {  {
2525          if (m_pMessages)          if (m_pMessages)
2526                  m_pMessages->appendMessagesText(s);                  m_pMessages->appendMessagesText(s);
2527  }  }
2528    
2529  void MainForm::appendMessagesError( const QString& s )  void MainForm::appendMessagesError ( const QString& s )
2530  {  {
2531          if (m_pMessages)          if (m_pMessages)
2532                  m_pMessages->show();                  m_pMessages->show();
2533    
2534          appendMessagesColor(s.simplified(), "#ff0000");          appendMessagesColor(s.simplified(), Qt::red);
2535    
2536          // Make it look responsive...:)          // Make it look responsive...:)
2537          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2538    
2539          QMessageBox::critical(this,          if (m_pOptions && m_pOptions->bConfirmError) {
2540                  QSAMPLER_TITLE ": " + tr("Error"), s, QMessageBox::Cancel);                  const QString& sTitle = tr("Error");
2541            #if 0
2542                    QMessageBox::critical(this, sTitle, sText, QMessageBox::Cancel);
2543            #else
2544                    QMessageBox mbox(this);
2545                    mbox.setIcon(QMessageBox::Critical);
2546                    mbox.setWindowTitle(sTitle);
2547                    mbox.setText(s);
2548                    mbox.setStandardButtons(QMessageBox::Cancel);
2549                    QCheckBox cbox(tr("Don't show this again"));
2550                    cbox.setChecked(false);
2551                    cbox.blockSignals(true);
2552                    mbox.addButton(&cbox, QMessageBox::ActionRole);
2553                    if (mbox.exec() && cbox.isChecked())
2554                            m_pOptions->bConfirmError = false;
2555            #endif
2556            }
2557  }  }
2558    
2559    
2560  // This is a special message format, just for client results.  // This is a special message format, just for client results.
2561  void MainForm::appendMessagesClient( const QString& s )  void MainForm::appendMessagesClient( const QString& s )
2562  {  {
2563          if (m_pClient == NULL)          if (m_pClient == nullptr)
2564                  return;                  return;
2565    
2566          appendMessagesColor(s + QString(": %1 (errno=%2)")          appendMessagesColor(s + QString(": %1 (errno=%2)")
# Line 2288  void MainForm::appendMessagesClient( con Line 2575  void MainForm::appendMessagesClient( con
2575  // Force update of the messages font.  // Force update of the messages font.
2576  void MainForm::updateMessagesFont (void)  void MainForm::updateMessagesFont (void)
2577  {  {
2578          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2579                  return;                  return;
2580    
2581          if (m_pMessages && !m_pOptions->sMessagesFont.isEmpty()) {          if (m_pMessages && !m_pOptions->sMessagesFont.isEmpty()) {
# Line 2302  void MainForm::updateMessagesFont (void) Line 2589  void MainForm::updateMessagesFont (void)
2589  // Update messages window line limit.  // Update messages window line limit.
2590  void MainForm::updateMessagesLimit (void)  void MainForm::updateMessagesLimit (void)
2591  {  {
2592          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2593                  return;                  return;
2594    
2595          if (m_pMessages) {          if (m_pMessages) {
# Line 2317  void MainForm::updateMessagesLimit (void Line 2604  void MainForm::updateMessagesLimit (void
2604  // Enablement of the messages capture feature.  // Enablement of the messages capture feature.
2605  void MainForm::updateMessagesCapture (void)  void MainForm::updateMessagesCapture (void)
2606  {  {
2607          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2608                  return;                  return;
2609    
2610          if (m_pMessages)          if (m_pMessages)
# Line 2326  void MainForm::updateMessagesCapture (vo Line 2613  void MainForm::updateMessagesCapture (vo
2613    
2614    
2615  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2616  // qsamplerMainForm -- MDI channel strip management.  // QSampler::MainForm -- MDI channel strip management.
2617    
2618  // The channel strip creation executive.  // The channel strip creation executive.
2619  ChannelStrip* MainForm::createChannelStrip ( Channel *pChannel )  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )
2620  {  {
2621          if (m_pClient == NULL || pChannel == NULL)          if (m_pClient == nullptr || pChannel == nullptr)
2622                  return NULL;                  return nullptr;
2623    
2624          // Add a new channel itema...          // Add a new channel itema...
2625          ChannelStrip *pChannelStrip = new ChannelStrip();          ChannelStrip *pChannelStrip = new ChannelStrip();
2626          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
2627                  return NULL;                  return nullptr;
2628    
2629          // Set some initial channel strip options...          // Set some initial channel strip options...
2630          if (m_pOptions) {          if (m_pOptions) {
# Line 2345  ChannelStrip* MainForm::createChannelStr Line 2632  ChannelStrip* MainForm::createChannelStr
2632                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2633                  // We'll need a display font.                  // We'll need a display font.
2634                  QFont font;                  QFont font;
2635                  if (font.fromString(m_pOptions->sDisplayFont))                  if (!m_pOptions->sDisplayFont.isEmpty() &&
2636                            font.fromString(m_pOptions->sDisplayFont))
2637                          pChannelStrip->setDisplayFont(font);                          pChannelStrip->setDisplayFont(font);
2638                  // Maximum allowed volume setting.                  // Maximum allowed volume setting.
2639                  pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                  pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2640          }          }
2641    
2642          // Add it to workspace...          // Add it to workspace...
2643          m_pWorkspace->addWindow(pChannelStrip, Qt::FramelessWindowHint);          QMdiSubWindow *pMdiSubWindow
2644                    = m_pWorkspace->addSubWindow(pChannelStrip,
2645                            Qt::SubWindow | Qt::FramelessWindowHint);
2646            pMdiSubWindow->setAttribute(Qt::WA_DeleteOnClose);
2647    
2648          // Actual channel strip setup...          // Actual channel strip setup...
2649          pChannelStrip->setup(pChannel);          pChannelStrip->setup(pChannel);
2650    
2651          QObject::connect(pChannelStrip,          QObject::connect(pChannelStrip,
2652                  SIGNAL(channelChanged(ChannelStrip*)),                  SIGNAL(channelChanged(ChannelStrip *)),
2653                  SLOT(channelStripChanged(ChannelStrip*)));                  SLOT(channelStripChanged(ChannelStrip *)));
2654    
2655          // Now we show up us to the world.          // Now we show up us to the world.
2656          pChannelStrip->show();          pChannelStrip->show();
# Line 2371  ChannelStrip* MainForm::createChannelStr Line 2662  ChannelStrip* MainForm::createChannelStr
2662          return pChannelStrip;          return pChannelStrip;
2663  }  }
2664    
2665  void MainForm::destroyChannelStrip(ChannelStrip* pChannelStrip) {  
2666    void MainForm::destroyChannelStrip ( ChannelStrip *pChannelStrip )
2667    {
2668            QMdiSubWindow *pMdiSubWindow
2669                    = static_cast<QMdiSubWindow *> (pChannelStrip->parentWidget());
2670            if (pMdiSubWindow == nullptr)
2671                    return;
2672    
2673          // Just delete the channel strip.          // Just delete the channel strip.
2674          delete pChannelStrip;          delete pChannelStrip;
2675            delete pMdiSubWindow;
2676    
2677          // Do we auto-arrange?          // Do we auto-arrange?
2678          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
   
         stabilizeForm();  
2679  }  }
2680    
2681    
2682  // Retrieve the active channel strip.  // Retrieve the active channel strip.
2683  ChannelStrip* MainForm::activeChannelStrip (void)  ChannelStrip *MainForm::activeChannelStrip (void)
2684  {  {
2685          return static_cast<ChannelStrip *> (m_pWorkspace->activeWindow());          QMdiSubWindow *pMdiSubWindow = m_pWorkspace->activeSubWindow();
2686            if (pMdiSubWindow)
2687                    return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2688            else
2689                    return nullptr;
2690  }  }
2691    
2692    
2693  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2694  ChannelStrip* MainForm::channelStripAt ( int iChannel )  ChannelStrip *MainForm::channelStripAt ( int iStrip )
2695  {  {
2696          if (!m_pWorkspace) return NULL;          if (!m_pWorkspace) return nullptr;
2697    
2698          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2699                    = m_pWorkspace->subWindowList();
2700          if (wlist.isEmpty())          if (wlist.isEmpty())
2701                  return NULL;                  return nullptr;
2702    
2703          if (iChannel < 0 || iChannel >= wlist.size())          if (iStrip < 0 || iStrip >= wlist.count())
2704                  return NULL;                  return nullptr;
2705    
2706          return dynamic_cast<ChannelStrip *> (wlist.at(iChannel));          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2707            if (pMdiSubWindow)
2708                    return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2709            else
2710                    return nullptr;
2711  }  }
2712    
2713    
2714  // Retrieve a channel strip by sampler channel id.  // Retrieve a channel strip by sampler channel id.
2715  ChannelStrip* MainForm::channelStrip ( int iChannelID )  ChannelStrip *MainForm::channelStrip ( int iChannelID )
2716  {  {
2717          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2718                    = m_pWorkspace->subWindowList();
2719          if (wlist.isEmpty())          if (wlist.isEmpty())
2720                  return NULL;                  return nullptr;
2721    
2722          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2723                  ChannelStrip* pChannelStrip                  ChannelStrip *pChannelStrip
2724                          = static_cast<ChannelStrip*> (wlist.at(iChannel));                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2725                  if (pChannelStrip) {                  if (pChannelStrip) {
2726                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
2727                          if (pChannel && pChannel->channelID() == iChannelID)                          if (pChannel && pChannel->channelID() == iChannelID)
# Line 2423  ChannelStrip* MainForm::channelStrip ( i Line 2730  ChannelStrip* MainForm::channelStrip ( i
2730          }          }
2731    
2732          // Not found.          // Not found.
2733          return NULL;          return nullptr;
2734  }  }
2735    
2736    
# Line 2434  void MainForm::channelsMenuAboutToShow ( Line 2741  void MainForm::channelsMenuAboutToShow (
2741          m_ui.channelsMenu->addAction(m_ui.channelsArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsArrangeAction);
2742          m_ui.channelsMenu->addAction(m_ui.channelsAutoArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsAutoArrangeAction);
2743    
2744          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2745                    = m_pWorkspace->subWindowList();
2746          if (!wlist.isEmpty()) {          if (!wlist.isEmpty()) {
2747                  m_ui.channelsMenu->addSeparator();                  m_ui.channelsMenu->addSeparator();
2748                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                  int iStrip = 0;
2749                          ChannelStrip* pChannelStrip                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2750                                  = static_cast<ChannelStrip*> (wlist.at(iChannel));                          ChannelStrip *pChannelStrip
2751                                    = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2752                          if (pChannelStrip) {                          if (pChannelStrip) {
2753                                  QAction *pAction = m_ui.channelsMenu->addAction(                                  QAction *pAction = m_ui.channelsMenu->addAction(
2754                                          pChannelStrip->windowTitle(),                                          pChannelStrip->windowTitle(),
2755                                          this, SLOT(channelsMenuActivated()));                                          this, SLOT(channelsMenuActivated()));
2756                                  pAction->setCheckable(true);                                  pAction->setCheckable(true);
2757                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);
2758                                  pAction->setData(iChannel);                                  pAction->setData(iStrip);
2759                          }                          }
2760                            ++iStrip;
2761                  }                  }
2762          }          }
2763  }  }
# Line 2458  void MainForm::channelsMenuActivated (vo Line 2768  void MainForm::channelsMenuActivated (vo
2768  {  {
2769          // Retrive channel index from action data...          // Retrive channel index from action data...
2770          QAction *pAction = qobject_cast<QAction *> (sender());          QAction *pAction = qobject_cast<QAction *> (sender());
2771          if (pAction == NULL)          if (pAction == nullptr)
2772                  return;                  return;
2773    
2774          ChannelStrip* pChannelStrip = channelStripAt(pAction->data().toInt());          ChannelStrip *pChannelStrip = channelStripAt(pAction->data().toInt());
2775          if (pChannelStrip) {          if (pChannelStrip) {
2776                  pChannelStrip->showNormal();                  pChannelStrip->showNormal();
2777                  pChannelStrip->setFocus();                  pChannelStrip->setFocus();
# Line 2470  void MainForm::channelsMenuActivated (vo Line 2780  void MainForm::channelsMenuActivated (vo
2780    
2781    
2782  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2783  // qsamplerMainForm -- Timer stuff.  // QSampler::MainForm -- Timer stuff.
2784    
2785  // Set the pseudo-timer delay schedule.  // Set the pseudo-timer delay schedule.
2786  void MainForm::startSchedule ( int iStartDelay )  void MainForm::startSchedule ( int iStartDelay )
# Line 2489  void MainForm::stopSchedule (void) Line 2799  void MainForm::stopSchedule (void)
2799  // Timer slot funtion.  // Timer slot funtion.
2800  void MainForm::timerSlot (void)  void MainForm::timerSlot (void)
2801  {  {
2802          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2803                  return;                  return;
2804    
2805          // 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 2511  void MainForm::timerSlot (void) Line 2821  void MainForm::timerSlot (void)
2821                          ChannelStrip *pChannelStrip = iter.next();                          ChannelStrip *pChannelStrip = iter.next();
2822                          // If successfull, remove from pending list...                          // If successfull, remove from pending list...
2823                          if (pChannelStrip->updateChannelInfo()) {                          if (pChannelStrip->updateChannelInfo()) {
2824                                  int iChannelStrip = m_changedStrips.indexOf(pChannelStrip);                                  const int iChannelStrip = m_changedStrips.indexOf(pChannelStrip);
2825                                  if (iChannelStrip >= 0)                                  if (iChannelStrip >= 0)
2826                                          m_changedStrips.removeAt(iChannelStrip);                                          m_changedStrips.removeAt(iChannelStrip);
2827                          }                          }
# Line 2522  void MainForm::timerSlot (void) Line 2832  void MainForm::timerSlot (void)
2832                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {
2833                                  m_iTimerSlot = 0;                                  m_iTimerSlot = 0;
2834                                  // Update the channel stream usage for each strip...                                  // Update the channel stream usage for each strip...
2835                                  QWidgetList wlist = m_pWorkspace->windowList();                                  const QList<QMdiSubWindow *>& wlist
2836                                  for (int iChannel = 0;                                          = m_pWorkspace->subWindowList();
2837                                                  iChannel < (int) wlist.count(); iChannel++) {                                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2838                                          ChannelStrip* pChannelStrip                                          ChannelStrip *pChannelStrip
2839                                                  = (ChannelStrip*) wlist.at(iChannel);                                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2840                                          if (pChannelStrip && pChannelStrip->isVisible())                                          if (pChannelStrip && pChannelStrip->isVisible())
2841                                                  pChannelStrip->updateChannelUsage();                                                  pChannelStrip->updateChannelUsage();
2842                                  }                                  }
2843                          }                          }
2844                  }                  }
2845    
2846            #if CONFIG_LSCP_CLIENT_CONNECTION_LOST
2847                    // If we lost connection to server: Try to automatically reconnect if we
2848                    // did not start the server.
2849                    //
2850                    // TODO: If we started the server, then we might inform the user that
2851                    // the server probably crashed and asking user ONCE whether we should
2852                    // restart the server.
2853                    if (lscp_client_connection_lost(m_pClient) && !m_pServer)
2854                            startAutoReconnectClient();
2855            #endif // CONFIG_LSCP_CLIENT_CONNECTION_LOST
2856          }          }
2857    
2858          // Register the next timer slot.          // Register the next timer slot.
# Line 2540  void MainForm::timerSlot (void) Line 2861  void MainForm::timerSlot (void)
2861    
2862    
2863  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2864  // qsamplerMainForm -- Server stuff.  // QSampler::MainForm -- Server stuff.
2865    
2866  // Start linuxsampler server...  // Start linuxsampler server...
2867  void MainForm::startServer (void)  void MainForm::startServer (void)
2868  {  {
2869          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2870                  return;                  return;
2871    
2872          // Aren't already a client, are we?          // Aren't already a client, are we?
# Line 2555  void MainForm::startServer (void) Line 2876  void MainForm::startServer (void)
2876          // Is the server process instance still here?          // Is the server process instance still here?
2877          if (m_pServer) {          if (m_pServer) {
2878                  if (QMessageBox::warning(this,                  if (QMessageBox::warning(this,
2879                          QSAMPLER_TITLE ": " + tr("Warning"),                          tr("Warning"),
2880                          tr("Could not start the LinuxSampler server.\n\n"                          tr("Could not start the LinuxSampler server.\n\n"
2881                          "Maybe it is already started."),                          "Maybe it is already started."),
2882                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
# Line 2574  void MainForm::startServer (void) Line 2895  void MainForm::startServer (void)
2895    
2896          // OK. Let's build the startup process...          // OK. Let's build the startup process...
2897          m_pServer = new QProcess();          m_pServer = new QProcess();
2898          bForceServerStop = true;          m_bForceServerStop = true;
2899    
2900          // Setup stdout/stderr capture...          // Setup stdout/stderr capture...
2901  //      if (m_pOptions->bStdoutCapture) {          m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);
2902  #if QT_VERSION >= 0x040200          QObject::connect(m_pServer,
2903                  m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);                  SIGNAL(readyReadStandardOutput()),
2904  #endif                  SLOT(readServerStdout()));
2905                  QObject::connect(m_pServer,          QObject::connect(m_pServer,
2906                          SIGNAL(readyReadStandardOutput()),                  SIGNAL(readyReadStandardError()),
2907                          SLOT(readServerStdout()));                  SLOT(readServerStdout()));
                 QObject::connect(m_pServer,  
                         SIGNAL(readyReadStandardError()),  
                         SLOT(readServerStdout()));  
 //      }  
2908    
2909          // The unforgiveable signal communication...          // The unforgiveable signal communication...
2910          QObject::connect(m_pServer,          QObject::connect(m_pServer,
# Line 2612  void MainForm::startServer (void) Line 2929  void MainForm::startServer (void)
2929    
2930          // Show startup results...          // Show startup results...
2931          appendMessages(          appendMessages(
2932                  tr("Server was started with PID=%1.").arg((long) m_pServer->pid()));                  tr("Server was started with PID=%1.")
2933                    #if QT_VERSION < QT_VERSION_CHECK(5, 3, 0)
2934                            .arg(quint64(m_pServer->pid())));
2935                    #else
2936                            .arg(quint64(m_pServer->processId())));
2937                    #endif
2938    
2939          // Reset (yet again) the timer counters,          // Reset (yet again) the timer counters,
2940          // but this time is deferred as the user opted.          // but this time is deferred as the user opted.
# Line 2622  void MainForm::startServer (void) Line 2944  void MainForm::startServer (void)
2944    
2945    
2946  // Stop linuxsampler server...  // Stop linuxsampler server...
2947  void MainForm::stopServer (bool bInteractive)  void MainForm::stopServer ( bool bInteractive )
2948  {  {
2949          // Stop client code.          // Stop client code.
2950          stopClient();          stopClient();
2951    
2952          if (m_pServer && bInteractive) {          if (m_pServer && bInteractive) {
2953                  if (QMessageBox::question(this,                  if (QMessageBox::question(this,
2954                          QSAMPLER_TITLE ": " + tr("The backend's fate ..."),                          tr("The backend's fate ..."),
2955                          tr("You have the option to keep the sampler backend (LinuxSampler)\n"                          tr("You have the option to keep the sampler backend (LinuxSampler)\n"
2956                          "running in the background. The sampler would continue to work\n"                          "running in the background. The sampler would continue to work\n"
2957                          "according to your current sampler session and you could alter the\n"                          "according to your current sampler session and you could alter the\n"
2958                          "sampler session at any time by relaunching QSampler.\n\n"                          "sampler session at any time by relaunching QSampler.\n\n"
2959                          "Do you want LinuxSampler to stop?"),                          "Do you want LinuxSampler to stop?"),
2960                          QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)                          QMessageBox::Yes | QMessageBox::No,
2961                  {                          QMessageBox::Yes) == QMessageBox::No) {
2962                          bForceServerStop = false;                          m_bForceServerStop = false;
2963                  }                  }
2964          }          }
2965    
2966            bool bGraceWait = true;
2967    
2968          // And try to stop server.          // And try to stop server.
2969          if (m_pServer && bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2970                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2971                  if (m_pServer->state() == QProcess::Running) {                  if (m_pServer->state() == QProcess::Running) {
2972  #if defined(WIN32)                  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
2973                          // Try harder...                          // Try harder...
2974                          m_pServer->kill();                          m_pServer->kill();
2975  #else                  #else
2976                          // Try softly...                          // Try softly...
2977                          m_pServer->terminate();                          m_pServer->terminate();
2978  #endif                          bool bFinished = m_pServer->waitForFinished(QSAMPLER_TIMER_MSECS * 1000);
2979                            if (bFinished) bGraceWait = false;
2980                    #endif
2981                  }                  }
2982          }       // Do final processing anyway.          }       // Do final processing anyway.
2983          else processServerExit();          else processServerExit();
2984    
2985          // Give it some time to terminate gracefully and stabilize...          // Give it some time to terminate gracefully and stabilize...
2986          QTime t;          if (bGraceWait) {
2987          t.start();                  QElapsedTimer timer;
2988          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                  timer.start();
2989                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  while (timer.elapsed() < QSAMPLER_TIMER_MSECS)
2990                            QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2991            }
2992  }  }
2993    
2994    
# Line 2682  void MainForm::processServerExit (void) Line 3010  void MainForm::processServerExit (void)
3010          if (m_pMessages)          if (m_pMessages)
3011                  m_pMessages->flushStdoutBuffer();                  m_pMessages->flushStdoutBuffer();
3012    
3013          if (m_pServer && bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
3014                  if (m_pServer->state() != QProcess::NotRunning) {                  if (m_pServer->state() != QProcess::NotRunning) {
3015                          appendMessages(tr("Server is being forced..."));                          appendMessages(tr("Server is being forced..."));
3016                          // Force final server shutdown...                          // Force final server shutdown...
3017                          m_pServer->kill();                          m_pServer->kill();
3018                          // Give it some time to terminate gracefully and stabilize...                          // Give it some time to terminate gracefully and stabilize...
3019                          QTime t;                          QElapsedTimer timer;
3020                          t.start();                          timer.start();
3021                          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                          while (timer.elapsed() < QSAMPLER_TIMER_MSECS)
3022                                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
3023                  }                  }
3024                  // Force final server shutdown...                  // Force final server shutdown...
# Line 2698  void MainForm::processServerExit (void) Line 3026  void MainForm::processServerExit (void)
3026                          tr("Server was stopped with exit status %1.")                          tr("Server was stopped with exit status %1.")
3027                          .arg(m_pServer->exitStatus()));                          .arg(m_pServer->exitStatus()));
3028                  delete m_pServer;                  delete m_pServer;
3029                  m_pServer = NULL;                  m_pServer = nullptr;
3030          }          }
3031    
3032          // Again, make status visible stable.          // Again, make status visible stable.
# Line 2707  void MainForm::processServerExit (void) Line 3035  void MainForm::processServerExit (void)
3035    
3036    
3037  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
3038  // qsamplerMainForm -- Client stuff.  // QSampler::MainForm -- Client stuff.
3039    
3040  // The LSCP client callback procedure.  // The LSCP client callback procedure.
3041  lscp_status_t qsampler_client_callback ( lscp_client_t */*pClient*/,  lscp_status_t qsampler_client_callback ( lscp_client_t */*pClient*/,
3042          lscp_event_t event, const char *pchData, int cchData, void *pvData )          lscp_event_t event, const char *pchData, int cchData, void *pvData )
3043  {  {
3044          MainForm* pMainForm = (MainForm *) pvData;          MainForm* pMainForm = (MainForm *) pvData;
3045          if (pMainForm == NULL)          if (pMainForm == nullptr)
3046                  return LSCP_FAILED;                  return LSCP_FAILED;
3047    
3048          // ATTN: DO NOT EVER call any GUI code here,          // ATTN: DO NOT EVER call any GUI code here,
# Line 2728  lscp_status_t qsampler_client_callback ( Line 3056  lscp_status_t qsampler_client_callback (
3056    
3057    
3058  // Start our almighty client...  // Start our almighty client...
3059  bool MainForm::startClient (void)  bool MainForm::startClient (bool bReconnectOnly)
3060  {  {
3061          // Have it a setup?          // Have it a setup?
3062          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
3063                  return false;                  return false;
3064    
3065          // Aren't we already started, are we?          // Aren't we already started, are we?
# Line 2745  bool MainForm::startClient (void) Line 3073  bool MainForm::startClient (void)
3073          m_pClient = ::lscp_client_create(          m_pClient = ::lscp_client_create(
3074                  m_pOptions->sServerHost.toUtf8().constData(),                  m_pOptions->sServerHost.toUtf8().constData(),
3075                  m_pOptions->iServerPort, qsampler_client_callback, this);                  m_pOptions->iServerPort, qsampler_client_callback, this);
3076          if (m_pClient == NULL) {          if (m_pClient == nullptr) {
3077                  // Is this the first try?                  // Is this the first try?
3078                  // maybe we need to start a local server...                  // maybe we need to start a local server...
3079                  if ((m_pServer && m_pServer->state() == QProcess::Running)                  if ((m_pServer && m_pServer->state() == QProcess::Running)
3080                          || !m_pOptions->bServerStart) {                          || !m_pOptions->bServerStart || bReconnectOnly)
3081                          appendMessagesError(                  {
3082                                  tr("Could not connect to server as client.\n\nSorry."));                          // if this method is called from autoReconnectClient()
3083                            // then don't bother user with an error message...
3084                            if (!bReconnectOnly) {
3085                                    appendMessagesError(
3086                                            tr("Could not connect to server as client.\n\nSorry.")
3087                                    );
3088                            }
3089                  } else {                  } else {
3090                          startServer();                          startServer();
3091                  }                  }
# Line 2759  bool MainForm::startClient (void) Line 3093  bool MainForm::startClient (void)
3093                  stabilizeForm();                  stabilizeForm();
3094                  return false;                  return false;
3095          }          }
3096    
3097          // Just set receive timeout value, blindly.          // Just set receive timeout value, blindly.
3098          ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);          ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
3099          appendMessages(          appendMessages(
# Line 2814  bool MainForm::startClient (void) Line 3149  bool MainForm::startClient (void)
3149          if (!m_pOptions->sSessionFile.isEmpty()) {          if (!m_pOptions->sSessionFile.isEmpty()) {
3150                  // Just load the prabably startup session...                  // Just load the prabably startup session...
3151                  if (loadSessionFile(m_pOptions->sSessionFile)) {                  if (loadSessionFile(m_pOptions->sSessionFile)) {
3152                          m_pOptions->sSessionFile = QString::null;                          m_pOptions->sSessionFile = QString();
3153                          return true;                          return true;
3154                  }                  }
3155          }          }
# Line 2830  bool MainForm::startClient (void) Line 3165  bool MainForm::startClient (void)
3165  // Stop client...  // Stop client...
3166  void MainForm::stopClient (void)  void MainForm::stopClient (void)
3167  {  {
3168          if (m_pClient == NULL)          if (m_pClient == nullptr)
3169                  return;                  return;
3170    
3171          // Log prepare here.          // Log prepare here.
# Line 2862  void MainForm::stopClient (void) Line 3197  void MainForm::stopClient (void)
3197          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
3198          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);
3199          ::lscp_client_destroy(m_pClient);          ::lscp_client_destroy(m_pClient);
3200          m_pClient = NULL;          m_pClient = nullptr;
3201    
3202          // Hard-notify instrumnet and device configuration forms,          // Hard-notify instrumnet and device configuration forms,
3203          // if visible, that we're running out...          // if visible, that we're running out...
# Line 2879  void MainForm::stopClient (void) Line 3214  void MainForm::stopClient (void)
3214  }  }
3215    
3216    
3217    void MainForm::startAutoReconnectClient (void)
3218    {
3219            stopClient();
3220            appendMessages(tr("Trying to reconnect..."));
3221            QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(autoReconnectClient()));
3222    }
3223    
3224    
3225    void MainForm::autoReconnectClient (void)
3226    {
3227            const bool bSuccess = startClient(true);
3228            if (!bSuccess)
3229                    QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(autoReconnectClient()));
3230    }
3231    
3232    
3233  // Channel strip activation/selection.  // Channel strip activation/selection.
3234  void MainForm::activateStrip ( QWidget *pWidget )  void MainForm::activateStrip ( QMdiSubWindow *pMdiSubWindow )
3235  {  {
3236          ChannelStrip *pChannelStrip          ChannelStrip *pChannelStrip = nullptr;
3237                  = static_cast<ChannelStrip *> (pWidget);          if (pMdiSubWindow)
3238                    pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
3239          if (pChannelStrip)          if (pChannelStrip)
3240                  pChannelStrip->setSelected(true);                  pChannelStrip->setSelected(true);
3241    
# Line 2891  void MainForm::activateStrip ( QWidget * Line 3243  void MainForm::activateStrip ( QWidget *
3243  }  }
3244    
3245    
3246    // Channel toolbar orientation change.
3247    void MainForm::channelsToolbarOrientation ( Qt::Orientation orientation )
3248    {
3249    #ifdef CONFIG_VOLUME
3250            m_pVolumeSlider->setOrientation(orientation);
3251            if (orientation == Qt::Horizontal) {
3252                    m_pVolumeSlider->setMinimumHeight(24);
3253                    m_pVolumeSlider->setMaximumHeight(32);
3254                    m_pVolumeSlider->setMinimumWidth(120);
3255                    m_pVolumeSlider->setMaximumWidth(640);
3256                    m_pVolumeSpinBox->setMaximumWidth(64);
3257                    m_pVolumeSpinBox->setButtonSymbols(QSpinBox::UpDownArrows);
3258            } else {
3259                    m_pVolumeSlider->setMinimumHeight(120);
3260                    m_pVolumeSlider->setMaximumHeight(480);
3261                    m_pVolumeSlider->setMinimumWidth(24);
3262                    m_pVolumeSlider->setMaximumWidth(32);
3263                    m_pVolumeSpinBox->setMaximumWidth(32);
3264                    m_pVolumeSpinBox->setButtonSymbols(QSpinBox::NoButtons);
3265            }
3266    #endif
3267    }
3268    
3269    
3270  } // namespace QSampler  } // namespace QSampler
3271    
3272    

Legend:
Removed from v.2077  
changed lines
  Added in v.3855

  ViewVC Help
Powered by ViewVC