/[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 2441 by capela, Wed Apr 10 09:11:37 2013 UTC revision 3760 by capela, Mon Mar 30 16:38:22 2020 UTC
# Line 1  Line 1 
1  // qsamplerMainForm.cpp  // qsamplerMainForm.cpp
2  //  //
3  /****************************************************************************  /****************************************************************************
4     Copyright (C) 2004-2013, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2020, rncbc aka Rui Nuno Capela. All rights reserved.
5     Copyright (C) 2007, 2008 Christian Schoenebeck     Copyright (C) 2007-2019 Christian Schoenebeck
6    
7     This program is free software; you can redistribute it and/or     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License     modify it under the terms of the GNU General Public License
# Line 35  Line 35 
35  #include "qsamplerOptionsForm.h"  #include "qsamplerOptionsForm.h"
36  #include "qsamplerDeviceStatusForm.h"  #include "qsamplerDeviceStatusForm.h"
37    
38    #include "qsamplerPaletteForm.h"
39    
40    #include <QStyleFactory>
41    
42  #include <QMdiArea>  #include <QMdiArea>
43  #include <QMdiSubWindow>  #include <QMdiSubWindow>
44    
# Line 58  Line 62 
62  #include <QTimer>  #include <QTimer>
63  #include <QDateTime>  #include <QDateTime>
64    
65  #if QT_VERSION >= 0x050000  #include <QElapsedTimer>
66    
67    #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
68  #include <QMimeData>  #include <QMimeData>
69  #endif  #endif
70    
71  #if QT_VERSION < 0x040500  #if QT_VERSION < QT_VERSION_CHECK(4, 5, 0)
72  namespace Qt {  namespace Qt {
73  const WindowFlags WindowCloseButtonHint = WindowFlags(0x08000000);  const WindowFlags WindowCloseButtonHint = WindowFlags(0x08000000);
 #if QT_VERSION < 0x040200  
 const WindowFlags CustomizeWindowHint   = WindowFlags(0x02000000);  
 #endif  
74  }  }
75  #endif  #endif
76    
77  #ifdef HAVE_SIGNAL_H  // Deprecated QTextStreamFunctions/Qt namespaces workaround.
78  #include <signal.h>  #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
79    #define endl    Qt::endl
80  #endif  #endif
81    
82    
83  #ifdef CONFIG_LIBGIG  #ifdef CONFIG_LIBGIG
84  #include <gig.h>  #include <gig.h>
85  #endif  #endif
# Line 94  static inline long lroundf ( float x ) Line 99  static inline long lroundf ( float x )
99    
100    
101  // All winsock apps needs this.  // All winsock apps needs this.
102  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
103  static WSADATA _wsaData;  static WSADATA _wsaData;
104    #undef HAVE_SIGNAL_H
105  #endif  #endif
106    
107    
# Line 106  static WSADATA _wsaData; Line 112  static WSADATA _wsaData;
112    
113  #include <QSocketNotifier>  #include <QSocketNotifier>
114    
115    #include <unistd.h>
116  #include <sys/types.h>  #include <sys/types.h>
117  #include <sys/socket.h>  #include <sys/socket.h>
   
118  #include <signal.h>  #include <signal.h>
119    
120  // File descriptor for SIGUSR1 notifier.  // File descriptor for SIGUSR1 notifier.
121  static int g_fdUsr1[2];  static int g_fdSigusr1[2] = { -1, -1 };
122    
123  // Unix SIGUSR1 signal handler.  // Unix SIGUSR1 signal handler.
124  static void qsampler_sigusr1_handler ( int /* signo */ )  static void qsampler_sigusr1_handler ( int /* signo */ )
125  {  {
126          char c = 1;          char c = 1;
127    
128          (::write(g_fdUsr1[0], &c, sizeof(c)) > 0);          (::write(g_fdSigusr1[0], &c, sizeof(c)) > 0);
129    }
130    
131    // File descriptor for SIGTERM notifier.
132    static int g_fdSigterm[2] = { -1, -1 };
133    
134    // Unix SIGTERM signal handler.
135    static void qsampler_sigterm_handler ( int /* signo */ )
136    {
137            char c = 1;
138    
139            (::write(g_fdSigterm[0], &c, sizeof(c)) > 0);
140  }  }
141    
142  #endif  // HAVE_SIGNAL_H  #endif  // HAVE_SIGNAL_H
143    
144    
145  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
146  // qsampler -- namespace  // QSampler -- namespace
147    
148    
149  namespace QSampler {  namespace QSampler {
# Line 146  namespace QSampler { Line 163  namespace QSampler {
163    
164    
165  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
166  // LscpEvent -- specialty for LSCP callback comunication.  // QSampler::LscpEvent -- specialty for LSCP callback comunication.
   
167    
168  class LscpEvent : public QEvent  class LscpEvent : public QEvent
169  {  {
# Line 162  public: Line 178  public:
178          }          }
179    
180          // Accessors.          // Accessors.
181          lscp_event_t event() { return m_event; }          lscp_event_t  event() { return m_event; }
182          QString&     data()  { return m_data;  }          const QString& data() { return m_data;  }
183    
184  private:  private:
185    
# Line 175  private: Line 191  private:
191    
192    
193  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
194  // qsamplerMainForm -- Main window form implementation.  // QSampler::Workspace -- Main window workspace (MDI Area) decl.
195    
196    class Workspace : public QMdiArea
197    {
198    public:
199    
200            Workspace(MainForm *pMainForm) : QMdiArea(pMainForm) {}
201    
202    protected:
203    
204            void resizeEvent(QResizeEvent *)
205            {
206                    MainForm *pMainForm = static_cast<MainForm *> (parentWidget());
207                    if (pMainForm)
208                            pMainForm->channelsArrangeAuto();
209            }
210    };
211    
212    
213    //-------------------------------------------------------------------------
214    // QSampler::MainForm -- Main window form implementation.
215    
216  // Kind of singleton reference.  // Kind of singleton reference.
217  MainForm* MainForm::g_pMainForm = NULL;  MainForm *MainForm::g_pMainForm = nullptr;
218    
219  MainForm::MainForm ( QWidget *pParent )  MainForm::MainForm ( QWidget *pParent )
220          : QMainWindow(pParent)          : QMainWindow(pParent)
# Line 189  MainForm::MainForm ( QWidget *pParent ) Line 225  MainForm::MainForm ( QWidget *pParent )
225          g_pMainForm = this;          g_pMainForm = this;
226    
227          // Initialize some pointer references.          // Initialize some pointer references.
228          m_pOptions = NULL;          m_pOptions = nullptr;
229    
230          // All child forms are to be created later, not earlier than setup.          // All child forms are to be created later, not earlier than setup.
231          m_pMessages = NULL;          m_pMessages = nullptr;
232          m_pInstrumentListForm = NULL;          m_pInstrumentListForm = nullptr;
233          m_pDeviceForm = NULL;          m_pDeviceForm = nullptr;
234    
235          // We'll start clean.          // We'll start clean.
236          m_iUntitled   = 0;          m_iUntitled   = 0;
237            m_iDirtySetup = 0;
238          m_iDirtyCount = 0;          m_iDirtyCount = 0;
239    
240          m_pServer = NULL;          m_pServer = nullptr;
241          m_pClient = NULL;          m_pClient = nullptr;
242    
243          m_iStartDelay = 0;          m_iStartDelay = 0;
244          m_iTimerDelay = 0;          m_iTimerDelay = 0;
# Line 216  MainForm::MainForm ( QWidget *pParent ) Line 253  MainForm::MainForm ( QWidget *pParent )
253          // LADISH Level 1 suport.          // LADISH Level 1 suport.
254    
255          // Initialize file descriptors for SIGUSR1 socket notifier.          // Initialize file descriptors for SIGUSR1 socket notifier.
256          ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdUsr1);          ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigusr1);
257          m_pUsr1Notifier          m_pSigusr1Notifier
258                  = new QSocketNotifier(g_fdUsr1[1], QSocketNotifier::Read, this);                  = new QSocketNotifier(g_fdSigusr1[1], QSocketNotifier::Read, this);
259    
260          QObject::connect(m_pUsr1Notifier,          QObject::connect(m_pSigusr1Notifier,
261                  SIGNAL(activated(int)),                  SIGNAL(activated(int)),
262                  SLOT(handle_sigusr1()));                  SLOT(handle_sigusr1()));
263    
264          // Install SIGUSR1 signal handler.          // Install SIGUSR1 signal handler.
265      struct sigaction usr1;          struct sigaction sigusr1;
266      usr1.sa_handler = qsampler_sigusr1_handler;          sigusr1.sa_handler = qsampler_sigusr1_handler;
267      sigemptyset(&usr1.sa_mask);          sigemptyset(&sigusr1.sa_mask);
268      usr1.sa_flags = 0;          sigusr1.sa_flags = 0;
269      usr1.sa_flags |= SA_RESTART;          sigusr1.sa_flags |= SA_RESTART;
270      ::sigaction(SIGUSR1, &usr1, NULL);          ::sigaction(SIGUSR1, &sigusr1, nullptr);
271    
272            // Initialize file descriptors for SIGTERM socket notifier.
273            ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigterm);
274            m_pSigtermNotifier
275                    = new QSocketNotifier(g_fdSigterm[1], QSocketNotifier::Read, this);
276    
277            QObject::connect(m_pSigtermNotifier,
278                    SIGNAL(activated(int)),
279                    SLOT(handle_sigterm()));
280    
281            // Install SIGTERM signal handler.
282            struct sigaction sigterm;
283            sigterm.sa_handler = qsampler_sigterm_handler;
284            sigemptyset(&sigterm.sa_mask);
285            sigterm.sa_flags = 0;
286            sigterm.sa_flags |= SA_RESTART;
287            ::sigaction(SIGTERM, &sigterm, nullptr);
288            ::sigaction(SIGQUIT, &sigterm, nullptr);
289    
290            // Ignore SIGHUP/SIGINT signals.
291            ::signal(SIGHUP, SIG_IGN);
292            ::signal(SIGINT, SIG_IGN);
293    
294  #else   // HAVE_SIGNAL_H  #else   // HAVE_SIGNAL_H
295    
296          m_pUsr1Notifier = NULL;          m_pSigusr1Notifier = nullptr;
297            m_pSigtermNotifier = nullptr;
298                    
299  #endif  // !HAVE_SIGNAL_H  #endif  // !HAVE_SIGNAL_H
300    
# Line 257  MainForm::MainForm ( QWidget *pParent ) Line 317  MainForm::MainForm ( QWidget *pParent )
317          QObject::connect(m_pVolumeSlider,          QObject::connect(m_pVolumeSlider,
318                  SIGNAL(valueChanged(int)),                  SIGNAL(valueChanged(int)),
319                  SLOT(volumeChanged(int)));                  SLOT(volumeChanged(int)));
         //m_ui.channelsToolbar->setHorizontallyStretchable(true);  
         //m_ui.channelsToolbar->setStretchableWidget(m_pVolumeSlider);  
320          m_ui.channelsToolbar->addWidget(m_pVolumeSlider);          m_ui.channelsToolbar->addWidget(m_pVolumeSlider);
321          // Volume spin-box          // Volume spin-box
322          m_ui.channelsToolbar->addSeparator();          m_ui.channelsToolbar->addSeparator();
323          m_pVolumeSpinBox = new QSpinBox(m_ui.channelsToolbar);          m_pVolumeSpinBox = new QSpinBox(m_ui.channelsToolbar);
         m_pVolumeSpinBox->setMaximumHeight(24);  
324          m_pVolumeSpinBox->setSuffix(" %");          m_pVolumeSpinBox->setSuffix(" %");
325          m_pVolumeSpinBox->setMinimum(0);          m_pVolumeSpinBox->setMinimum(0);
326          m_pVolumeSpinBox->setMaximum(100);          m_pVolumeSpinBox->setMaximum(100);
# Line 275  MainForm::MainForm ( QWidget *pParent ) Line 332  MainForm::MainForm ( QWidget *pParent )
332  #endif  #endif
333    
334          // Make it an MDI workspace.          // Make it an MDI workspace.
335          m_pWorkspace = new QMdiArea(this);          m_pWorkspace = new Workspace(this);
336          m_pWorkspace->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);          m_pWorkspace->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
337          m_pWorkspace->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);          m_pWorkspace->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
338          // Set the activation connection.          // Set the activation connection.
# Line 310  MainForm::MainForm ( QWidget *pParent ) Line 367  MainForm::MainForm ( QWidget *pParent )
367          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
368          statusBar()->addWidget(pLabel);          statusBar()->addWidget(pLabel);
369    
370  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
371          WSAStartup(MAKEWORD(1, 1), &_wsaData);          WSAStartup(MAKEWORD(1, 1), &_wsaData);
372  #endif  #endif
373    
# Line 398  MainForm::MainForm ( QWidget *pParent ) Line 455  MainForm::MainForm ( QWidget *pParent )
455          QObject::connect(m_ui.channelsMenu,          QObject::connect(m_ui.channelsMenu,
456                  SIGNAL(aboutToShow()),                  SIGNAL(aboutToShow()),
457                  SLOT(channelsMenuAboutToShow()));                  SLOT(channelsMenuAboutToShow()));
458    #ifdef CONFIG_VOLUME
459            QObject::connect(m_ui.channelsToolbar,
460                    SIGNAL(orientationChanged(Qt::Orientation)),
461                    SLOT(channelsToolbarOrientation(Qt::Orientation)));
462    #endif
463  }  }
464    
465  // Destructor.  // Destructor.
# Line 406  MainForm::~MainForm() Line 468  MainForm::~MainForm()
468          // Do final processing anyway.          // Do final processing anyway.
469          processServerExit();          processServerExit();
470    
471  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
472          WSACleanup();          WSACleanup();
473  #endif  #endif
474    
475  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
476          if (m_pUsr1Notifier)          if (m_pSigusr1Notifier)
477                  delete m_pUsr1Notifier;                  delete m_pSigusr1Notifier;
478            if (m_pSigtermNotifier)
479                    delete m_pSigtermNotifier;
480  #endif  #endif
481    
482          // Finally drop any widgets around...          // Finally drop any widgets around...
# Line 441  MainForm::~MainForm() Line 505  MainForm::~MainForm()
505  #endif  #endif
506    
507          // Pseudo-singleton reference shut-down.          // Pseudo-singleton reference shut-down.
508          g_pMainForm = NULL;          g_pMainForm = nullptr;
509  }  }
510    
511    
# Line 479  void MainForm::setup ( Options *pOptions Line 543  void MainForm::setup ( Options *pOptions
543          updateMessagesFont();          updateMessagesFont();
544          updateMessagesLimit();          updateMessagesLimit();
545          updateMessagesCapture();          updateMessagesCapture();
546    
547          // Set the visibility signal.          // Set the visibility signal.
548          QObject::connect(m_pMessages,          QObject::connect(m_pMessages,
549                  SIGNAL(visibilityChanged(bool)),                  SIGNAL(visibilityChanged(bool)),
# Line 544  bool MainForm::queryClose (void) Line 609  bool MainForm::queryClose (void)
609                                  || m_ui.channelsToolbar->isVisible());                                  || m_ui.channelsToolbar->isVisible());
610                          m_pOptions->bStatusbar = statusBar()->isVisible();                          m_pOptions->bStatusbar = statusBar()->isVisible();
611                          // Save the dock windows state.                          // Save the dock windows state.
                         const QString sDockables = saveState().toBase64().data();  
612                          m_pOptions->settings().setValue("/Layout/DockWindows", saveState());                          m_pOptions->settings().setValue("/Layout/DockWindows", saveState());
613                          // And the children, and the main windows state,.                          // And the children, and the main windows state,.
614                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);
# Line 578  void MainForm::closeEvent ( QCloseEvent Line 642  void MainForm::closeEvent ( QCloseEvent
642  void MainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )  void MainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
643  {  {
644          // Accept external drags only...          // Accept external drags only...
645          if (pDragEnterEvent->source() == NULL          if (pDragEnterEvent->source() == nullptr
646                  && pDragEnterEvent->mimeData()->hasUrls()) {                  && pDragEnterEvent->mimeData()->hasUrls()) {
647                  pDragEnterEvent->accept();                  pDragEnterEvent->accept();
648          } else {          } else {
# Line 587  void MainForm::dragEnterEvent ( QDragEnt Line 651  void MainForm::dragEnterEvent ( QDragEnt
651  }  }
652    
653    
654  void MainForm::dropEvent ( QDropEvent* pDropEvent )  void MainForm::dropEvent ( QDropEvent *pDropEvent )
655  {  {
656          // Accept externally originated drops only...          // Accept externally originated drops only...
657          if (pDropEvent->source())          if (pDropEvent->source())
# Line 602  void MainForm::dropEvent ( QDropEvent* p Line 666  void MainForm::dropEvent ( QDropEvent* p
666                          if (QFileInfo(sPath).exists()) {                          if (QFileInfo(sPath).exists()) {
667                                  // Try to create a new channel from instrument file...                                  // Try to create a new channel from instrument file...
668                                  Channel *pChannel = new Channel();                                  Channel *pChannel = new Channel();
669                                  if (pChannel == NULL)                                  if (pChannel == nullptr)
670                                          return;                                          return;
671                                  // Start setting the instrument filename...                                  // Start setting the instrument filename...
672                                  pChannel->setInstrument(sPath, 0);                                  pChannel->setInstrument(sPath, 0);
# Line 643  void MainForm::customEvent ( QEvent* pEv Line 707  void MainForm::customEvent ( QEvent* pEv
707                                  updateAllChannelStrips(true);                                  updateAllChannelStrips(true);
708                                  break;                                  break;
709                          case LSCP_EVENT_CHANNEL_INFO: {                          case LSCP_EVENT_CHANNEL_INFO: {
710                                  int iChannelID = pLscpEvent->data().toInt();                                  const int iChannelID = pLscpEvent->data().toInt();
711                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);
712                                  if (pChannelStrip)                                  if (pChannelStrip)
713                                          channelStripChanged(pChannelStrip);                                          channelStripChanged(pChannelStrip);
# Line 702  void MainForm::handle_sigusr1 (void) Line 766  void MainForm::handle_sigusr1 (void)
766    
767          char c;          char c;
768    
769          if (::read(g_fdUsr1[1], &c, sizeof(c)) > 0)          if (::read(g_fdSigusr1[1], &c, sizeof(c)) > 0)
770                  saveSession(false);                  saveSession(false);
771    
772  #endif  #endif
773  }  }
774    
775    
776    void MainForm::handle_sigterm (void)
777    {
778    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
779    
780            char c;
781    
782            if (::read(g_fdSigterm[1], &c, sizeof(c)) > 0)
783                    close();
784    
785    #endif
786    }
787    
788    
789  void MainForm::updateViewMidiDeviceStatusMenu (void)  void MainForm::updateViewMidiDeviceStatusMenu (void)
790  {  {
791          m_ui.viewMidiDeviceStatusMenu->clear();          m_ui.viewMidiDeviceStatusMenu->clear();
# Line 734  void MainForm::contextMenuEvent( QContex Line 811  void MainForm::contextMenuEvent( QContex
811    
812    
813  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
814  // qsamplerMainForm -- Brainless public property accessors.  // QSampler::MainForm -- Brainless public property accessors.
815    
816  // The global options settings property.  // The global options settings property.
817  Options *MainForm::options (void) const  Options *MainForm::options (void) const
# Line 758  MainForm *MainForm::getInstance (void) Line 835  MainForm *MainForm::getInstance (void)
835    
836    
837  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
838  // qsamplerMainForm -- Session file stuff.  // QSampler::MainForm -- Session file stuff.
839    
840  // Format the displayable session filename.  // Format the displayable session filename.
841  QString MainForm::sessionName ( const QString& sFilename )  QString MainForm::sessionName ( const QString& sFilename )
842  {  {
843          bool bCompletePath = (m_pOptions && m_pOptions->bCompletePath);          const bool bCompletePath = (m_pOptions && m_pOptions->bCompletePath);
844          QString sSessionName = sFilename;          QString sSessionName = sFilename;
845          if (sSessionName.isEmpty())          if (sSessionName.isEmpty())
846                  sSessionName = tr("Untitled") + QString::number(m_iUntitled);                  sSessionName = tr("Untitled") + QString::number(m_iUntitled);
# Line 787  bool MainForm::newSession (void) Line 864  bool MainForm::newSession (void)
864          m_iUntitled++;          m_iUntitled++;
865    
866          // Stabilize form.          // Stabilize form.
867          m_sFilename = QString::null;          m_sFilename = QString();
868          m_iDirtyCount = 0;          m_iDirtyCount = 0;
869          appendMessages(tr("New session: \"%1\".").arg(sessionName(m_sFilename)));          appendMessages(tr("New session: \"%1\".").arg(sessionName(m_sFilename)));
870          stabilizeForm();          stabilizeForm();
# Line 799  bool MainForm::newSession (void) Line 876  bool MainForm::newSession (void)
876  // Open an existing sampler session.  // Open an existing sampler session.
877  bool MainForm::openSession (void)  bool MainForm::openSession (void)
878  {  {
879          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
880                  return false;                  return false;
881    
882          // Ask for the filename to open...          // Ask for the filename to open...
883          QString sFilename = QFileDialog::getOpenFileName(this,          QString sFilename = QFileDialog::getOpenFileName(this,
884                  QSAMPLER_TITLE ": " + tr("Open Session"), // Caption.                  tr("Open Session"),                       // Caption.
885                  m_pOptions->sSessionDir,                  // Start here.                  m_pOptions->sSessionDir,                  // Start here.
886                  tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)                  tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)
887          );          );
# Line 825  bool MainForm::openSession (void) Line 902  bool MainForm::openSession (void)
902  // Save current sampler session with another name.  // Save current sampler session with another name.
903  bool MainForm::saveSession ( bool bPrompt )  bool MainForm::saveSession ( bool bPrompt )
904  {  {
905          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
906                  return false;                  return false;
907    
908          QString sFilename = m_sFilename;          QString sFilename = m_sFilename;
# Line 837  bool MainForm::saveSession ( bool bPromp Line 914  bool MainForm::saveSession ( bool bPromp
914                          sFilename = m_pOptions->sSessionDir;                          sFilename = m_pOptions->sSessionDir;
915                  // Prompt the guy...                  // Prompt the guy...
916                  sFilename = QFileDialog::getSaveFileName(this,                  sFilename = QFileDialog::getSaveFileName(this,
917                          QSAMPLER_TITLE ": " + tr("Save Session"), // Caption.                          tr("Save Session"),                       // Caption.
918                          sFilename,                                // Start here.                          sFilename,                                // Start here.
919                          tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)                          tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)
920                  );                  );
# Line 847  bool MainForm::saveSession ( bool bPromp Line 924  bool MainForm::saveSession ( bool bPromp
924                  // Enforce .lscp extension...                  // Enforce .lscp extension...
925                  if (QFileInfo(sFilename).suffix().isEmpty())                  if (QFileInfo(sFilename).suffix().isEmpty())
926                          sFilename += ".lscp";                          sFilename += ".lscp";
927            #if 0
928                  // Check if already exists...                  // Check if already exists...
929                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
930                          if (QMessageBox::warning(this,                          if (QMessageBox::warning(this,
931                                  QSAMPLER_TITLE ": " + tr("Warning"),                                  tr("Warning"),
932                                  tr("The file already exists:\n\n"                                  tr("The file already exists:\n\n"
933                                  "\"%1\"\n\n"                                  "\"%1\"\n\n"
934                                  "Do you want to replace it?")                                  "Do you want to replace it?")
# Line 859  bool MainForm::saveSession ( bool bPromp Line 937  bool MainForm::saveSession ( bool bPromp
937                                  == QMessageBox::No)                                  == QMessageBox::No)
938                                  return false;                                  return false;
939                  }                  }
940            #endif
941          }          }
942    
943          // Save it right away.          // Save it right away.
# Line 874  bool MainForm::closeSession ( bool bForc Line 953  bool MainForm::closeSession ( bool bForc
953          // Are we dirty enough to prompt it?          // Are we dirty enough to prompt it?
954          if (m_iDirtyCount > 0) {          if (m_iDirtyCount > 0) {
955                  switch (QMessageBox::warning(this,                  switch (QMessageBox::warning(this,
956                          QSAMPLER_TITLE ": " + tr("Warning"),                          tr("Warning"),
957                          tr("The current session has been changed:\n\n"                          tr("The current session has been changed:\n\n"
958                          "\"%1\"\n\n"                          "\"%1\"\n\n"
959                          "Do you want to save the changes?")                          "Do you want to save the changes?")
# Line 897  bool MainForm::closeSession ( bool bForc Line 976  bool MainForm::closeSession ( bool bForc
976          if (bClose) {          if (bClose) {
977                  // Remove all channel strips from sight...                  // Remove all channel strips from sight...
978                  m_pWorkspace->setUpdatesEnabled(false);                  m_pWorkspace->setUpdatesEnabled(false);
979                  QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();                  const QList<QMdiSubWindow *>& wlist
980                  for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {                          = m_pWorkspace->subWindowList();
981                          ChannelStrip *pChannelStrip = NULL;                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
982                          QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                          ChannelStrip *pChannelStrip
983                          if (pMdiSubWindow)                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                                 pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
984                          if (pChannelStrip) {                          if (pChannelStrip) {
985                                  Channel *pChannel = pChannelStrip->channel();                                  Channel *pChannel = pChannelStrip->channel();
986                                  if (bForce && pChannel)                                  if (bForce && pChannel)
987                                          pChannel->removeChannel();                                          pChannel->removeChannel();
988                                  delete pChannelStrip;                                  delete pChannelStrip;
989                          }                          }
990                          if (pMdiSubWindow)                          delete pMdiSubWindow;
                                 delete pMdiSubWindow;  
991                  }                  }
992                  m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
993                  // We're now clean, for sure.                  // We're now clean, for sure.
# Line 924  bool MainForm::closeSession ( bool bForc Line 1001  bool MainForm::closeSession ( bool bForc
1001  // Load a session from specific file path.  // Load a session from specific file path.
1002  bool MainForm::loadSessionFile ( const QString& sFilename )  bool MainForm::loadSessionFile ( const QString& sFilename )
1003  {  {
1004          if (m_pClient == NULL)          if (m_pClient == nullptr)
1005                  return false;                  return false;
1006    
1007          // Open and read from real file.          // Open and read from real file.
# Line 1000  bool MainForm::loadSessionFile ( const Q Line 1077  bool MainForm::loadSessionFile ( const Q
1077  // Save current session to specific file path.  // Save current session to specific file path.
1078  bool MainForm::saveSessionFile ( const QString& sFilename )  bool MainForm::saveSessionFile ( const QString& sFilename )
1079  {  {
1080          if (m_pClient == NULL)          if (m_pClient == nullptr)
1081                  return false;                  return false;
1082    
1083          // Check whether server is apparently OK...          // Check whether server is apparently OK...
# Line 1022  bool MainForm::saveSessionFile ( const Q Line 1099  bool MainForm::saveSessionFile ( const Q
1099          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1100    
1101          // Write the file.          // Write the file.
1102          int  iErrors = 0;          int iErrors = 0;
1103          QTextStream ts(&file);          QTextStream ts(&file);
1104          ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;          ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;
1105          ts << "# " << tr("Version")          ts << "# " << tr("Version") << ": " CONFIG_BUILD_VERSION << endl;
1106          << ": " QSAMPLER_VERSION << endl;  //      ts << "# " << tr("Build") << ": " CONFIG_BUILD_DATE << endl;
         ts << "# " << tr("Build")  
         << ": " __DATE__ " " __TIME__ << endl;  
1107          ts << "#"  << endl;          ts << "#"  << endl;
1108          ts << "# " << tr("File")          ts << "# " << tr("File")
1109          << ": " << QFileInfo(sFilename).fileName() << endl;          << ": " << QFileInfo(sFilename).fileName() << endl;
# Line 1041  bool MainForm::saveSessionFile ( const Q Line 1116  bool MainForm::saveSessionFile ( const Q
1116          // It is assumed that this new kind of device+session file          // It is assumed that this new kind of device+session file
1117          // will be loaded from a complete initialized server...          // will be loaded from a complete initialized server...
1118          int *piDeviceIDs;          int *piDeviceIDs;
1119          int  iDevice;          int  i, iDevice;
1120          ts << "RESET" << endl;          ts << "RESET" << endl;
1121    
1122          // Audio device mapping.          // Audio device mapping.
1123          QMap<int, int> audioDeviceMap;          QMap<int, int> audioDeviceMap; iDevice = 0;
1124          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);
1125          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1126                  ts << endl;                  Device device(Device::Audio, piDeviceIDs[i]);
1127                  Device device(Device::Audio, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1128                    if (device.driverName().toUpper() == "PLUGIN")
1129                            continue;
1130                  // Audio device specification...                  // Audio device specification...
1131                    ts << endl;
1132                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1133                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1134                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
# Line 1081  bool MainForm::saveSessionFile ( const Q Line 1159  bool MainForm::saveSessionFile ( const Q
1159                          iPort++;                          iPort++;
1160                  }                  }
1161                  // Audio device index/id mapping.                  // Audio device index/id mapping.
1162                  audioDeviceMap[device.deviceID()] = iDevice;                  audioDeviceMap.insert(device.deviceID(), iDevice++);
1163                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1164                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1165          }          }
1166    
1167          // MIDI device mapping.          // MIDI device mapping.
1168          QMap<int, int> midiDeviceMap;          QMap<int, int> midiDeviceMap; iDevice = 0;
1169          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);
1170          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1171                  ts << endl;                  Device device(Device::Midi, piDeviceIDs[i]);
1172                  Device device(Device::Midi, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1173                    if (device.driverName().toUpper() == "PLUGIN")
1174                            continue;
1175                  // MIDI device specification...                  // MIDI device specification...
1176                    ts << endl;
1177                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1178                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1179                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
# Line 1123  bool MainForm::saveSessionFile ( const Q Line 1204  bool MainForm::saveSessionFile ( const Q
1204                          iPort++;                          iPort++;
1205                  }                  }
1206                  // MIDI device index/id mapping.                  // MIDI device index/id mapping.
1207                  midiDeviceMap[device.deviceID()] = iDevice;                  midiDeviceMap.insert(device.deviceID(), iDevice++);
1208                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1209                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1210          }          }
# Line 1134  bool MainForm::saveSessionFile ( const Q Line 1215  bool MainForm::saveSessionFile ( const Q
1215          QMap<int, int> midiInstrumentMap;          QMap<int, int> midiInstrumentMap;
1216          int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);          int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);
1217          for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {          for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {
1218                  int iMidiMap = piMaps[iMap];                  const int iMidiMap = piMaps[iMap];
1219                  const char *pszMapName                  const char *pszMapName
1220                          = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);                          = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);
1221                  ts << "# " << tr("MIDI instrument map") << " " << iMap;                  ts << "# " << tr("MIDI instrument map") << " " << iMap;
# Line 1186  bool MainForm::saveSessionFile ( const Q Line 1267  bool MainForm::saveSessionFile ( const Q
1267                  }                  }
1268                  ts << endl;                  ts << endl;
1269                  // Check for errors...                  // Check for errors...
1270                  if (pInstrs == NULL && ::lscp_client_get_errno(m_pClient)) {                  if (pInstrs == nullptr && ::lscp_client_get_errno(m_pClient)) {
1271                          appendMessagesClient("lscp_list_midi_instruments");                          appendMessagesClient("lscp_list_midi_instruments");
1272                          iErrors++;                          iErrors++;
1273                  }                  }
1274                  // MIDI strument index/id mapping.                  // MIDI strument index/id mapping.
1275                  midiInstrumentMap[iMidiMap] = iMap;                  midiInstrumentMap.insert(iMidiMap, iMap);
1276          }          }
1277          // Check for errors...          // Check for errors...
1278          if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {          if (piMaps == nullptr && ::lscp_client_get_errno(m_pClient)) {
1279                  appendMessagesClient("lscp_list_midi_instrument_maps");                  appendMessagesClient("lscp_list_midi_instrument_maps");
1280                  iErrors++;                  iErrors++;
1281          }          }
1282  #endif  // CONFIG_MIDI_INSTRUMENT  #endif  // CONFIG_MIDI_INSTRUMENT
1283    
1284          // Sampler channel mapping.          // Sampler channel mapping...
1285          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          int iChannelID = 0;
1286          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          const QList<QMdiSubWindow *>& wlist
1287                  ChannelStrip *pChannelStrip = NULL;                  = m_pWorkspace->subWindowList();
1288                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
1289                  if (pMdiSubWindow)                  ChannelStrip *pChannelStrip
1290                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
1291                  if (pChannelStrip) {                  if (pChannelStrip) {
1292                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1293                          if (pChannel) {                          if (pChannel) {
1294                                  ts << "# " << tr("Channel") << " " << iChannel << endl;                                  // Avoid "artifial" plug-in devices...
1295                                    const int iAudioDevice = pChannel->audioDevice();
1296                                    if (!audioDeviceMap.contains(iAudioDevice))
1297                                            continue;
1298                                    const int iMidiDevice = pChannel->midiDevice();
1299                                    if (!midiDeviceMap.contains(iMidiDevice))
1300                                            continue;
1301                                    // Go for regular, canonical devices...
1302                                    ts << "# " << tr("Channel") << " " << iChannelID << endl;
1303                                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
1304                                  if (audioDeviceMap.isEmpty()) {                                  if (audioDeviceMap.isEmpty()) {
1305                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannelID
1306                                                  << " " << pChannel->audioDriver() << endl;                                                  << " " << pChannel->audioDriver() << endl;
1307                                  } else {                                  } else {
1308                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannelID
1309                                                  << " " << audioDeviceMap[pChannel->audioDevice()] << endl;                                                  << " " << audioDeviceMap.value(iAudioDevice) << endl;
1310                                  }                                  }
1311                                  if (midiDeviceMap.isEmpty()) {                                  if (midiDeviceMap.isEmpty()) {
1312                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannel                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID
1313                                                  << " " << pChannel->midiDriver() << endl;                                                  << " " << pChannel->midiDriver() << endl;
1314                                  } else {                                  } else {
1315                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannel                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannelID
1316                                                  << " " << midiDeviceMap[pChannel->midiDevice()] << endl;                                                  << " " << midiDeviceMap.value(iMidiDevice) << endl;
1317                                  }                                  }
1318                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID
1319                                          << " " << pChannel->midiPort() << endl;                                          << " " << pChannel->midiPort() << endl;
1320                                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";                                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannelID << " ";
1321                                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)                                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
1322                                          ts << "ALL";                                          ts << "ALL";
1323                                  else                                  else
1324                                          ts << pChannel->midiChannel();                                          ts << pChannel->midiChannel();
1325                                  ts << endl;                                  ts << endl;
1326                                  ts << "LOAD ENGINE " << pChannel->engineName()                                  ts << "LOAD ENGINE " << pChannel->engineName()
1327                                          << " " << iChannel << endl;                                          << " " << iChannelID << endl;
1328                                  if (pChannel->instrumentStatus() < 100) ts << "# ";                                  if (pChannel->instrumentStatus() < 100) ts << "# ";
1329                                  ts << "LOAD INSTRUMENT NON_MODAL '"                                  ts << "LOAD INSTRUMENT NON_MODAL '"
1330                                          << pChannel->instrumentFile() << "' "                                          << pChannel->instrumentFile() << "' "
1331                                          << pChannel->instrumentNr() << " " << iChannel << endl;                                          << pChannel->instrumentNr() << " " << iChannelID << endl;
1332                                  ChannelRoutingMap::ConstIterator audioRoute;                                  ChannelRoutingMap::ConstIterator audioRoute;
1333                                  for (audioRoute = pChannel->audioRouting().begin();                                  for (audioRoute = pChannel->audioRouting().begin();
1334                                                  audioRoute != pChannel->audioRouting().end();                                                  audioRoute != pChannel->audioRouting().end();
1335                                                          ++audioRoute) {                                                          ++audioRoute) {
1336                                          ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannelID
1337                                                  << " " << audioRoute.key()                                                  << " " << audioRoute.key()
1338                                                  << " " << audioRoute.value() << endl;                                                  << " " << audioRoute.value() << endl;
1339                                  }                                  }
1340                                  ts << "SET CHANNEL VOLUME " << iChannel                                  ts << "SET CHANNEL VOLUME " << iChannelID
1341                                          << " " << pChannel->volume() << endl;                                          << " " << pChannel->volume() << endl;
1342                                  if (pChannel->channelMute())                                  if (pChannel->channelMute())
1343                                          ts << "SET CHANNEL MUTE " << iChannel << " 1" << endl;                                          ts << "SET CHANNEL MUTE " << iChannelID << " 1" << endl;
1344                                  if (pChannel->channelSolo())                                  if (pChannel->channelSolo())
1345                                          ts << "SET CHANNEL SOLO " << iChannel << " 1" << endl;                                          ts << "SET CHANNEL SOLO " << iChannelID << " 1" << endl;
1346                          #ifdef CONFIG_MIDI_INSTRUMENT                          #ifdef CONFIG_MIDI_INSTRUMENT
1347                                  if (pChannel->midiMap() >= 0) {                                  const int iMidiMap = pChannel->midiMap();
1348                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannel                                  if (midiInstrumentMap.contains(iMidiMap)) {
1349                                                  << " " << midiInstrumentMap[pChannel->midiMap()] << endl;                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannelID
1350                                                    << " " << midiInstrumentMap.value(iMidiMap) << endl;
1351                                  }                                  }
1352                          #endif                          #endif
1353                          #ifdef CONFIG_FXSEND                          #ifdef CONFIG_FXSEND
                                 int iChannelID = pChannel->channelID();  
1354                                  int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID);                                  int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID);
1355                                  for (int iFxSend = 0;                                  for (int iFxSend = 0;
1356                                                  piFxSends && piFxSends[iFxSend] >= 0;                                                  piFxSends && piFxSends[iFxSend] >= 0;
# Line 1269  bool MainForm::saveSessionFile ( const Q Line 1358  bool MainForm::saveSessionFile ( const Q
1358                                          lscp_fxsend_info_t *pFxSendInfo = ::lscp_get_fxsend_info(                                          lscp_fxsend_info_t *pFxSendInfo = ::lscp_get_fxsend_info(
1359                                                  m_pClient, iChannelID, piFxSends[iFxSend]);                                                  m_pClient, iChannelID, piFxSends[iFxSend]);
1360                                          if (pFxSendInfo) {                                          if (pFxSendInfo) {
1361                                                  ts << "CREATE FX_SEND " << iChannel                                                  ts << "CREATE FX_SEND " << iChannelID
1362                                                          << " " << pFxSendInfo->midi_controller;                                                          << " " << pFxSendInfo->midi_controller;
1363                                                  if (pFxSendInfo->name)                                                  if (pFxSendInfo->name)
1364                                                          ts << " '" << pFxSendInfo->name << "'";                                                          ts << " '" << pFxSendInfo->name << "'";
# Line 1279  bool MainForm::saveSessionFile ( const Q Line 1368  bool MainForm::saveSessionFile ( const Q
1368                                                                  piRouting && piRouting[iAudioSrc] >= 0;                                                                  piRouting && piRouting[iAudioSrc] >= 0;
1369                                                                          iAudioSrc++) {                                                                          iAudioSrc++) {
1370                                                          ts << "SET FX_SEND AUDIO_OUTPUT_CHANNEL "                                                          ts << "SET FX_SEND AUDIO_OUTPUT_CHANNEL "
1371                                                                  << iChannel                                                                  << iChannelID
1372                                                                  << " " << iFxSend                                                                  << " " << iFxSend
1373                                                                  << " " << iAudioSrc                                                                  << " " << iAudioSrc
1374                                                                  << " " << piRouting[iAudioSrc] << endl;                                                                  << " " << piRouting[iAudioSrc] << endl;
1375                                                  }                                                  }
1376                                          #ifdef CONFIG_FXSEND_LEVEL                                          #ifdef CONFIG_FXSEND_LEVEL
1377                                                  ts << "SET FX_SEND LEVEL " << iChannel                                                  ts << "SET FX_SEND LEVEL " << iChannelID
1378                                                          << " " << iFxSend                                                          << " " << iFxSend
1379                                                          << " " << pFxSendInfo->level << endl;                                                          << " " << pFxSendInfo->level << endl;
1380                                          #endif                                          #endif
# Line 1297  bool MainForm::saveSessionFile ( const Q Line 1386  bool MainForm::saveSessionFile ( const Q
1386                                  }                                  }
1387                          #endif                          #endif
1388                                  ts << endl;                                  ts << endl;
1389                                    // Go for next channel...
1390                                    ++iChannelID;
1391                          }                          }
1392                  }                  }
1393                  // Try to keep it snappy :)                  // Try to keep it snappy :)
# Line 1348  void MainForm::sessionDirty (void) Line 1439  void MainForm::sessionDirty (void)
1439    
1440    
1441  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1442  // qsamplerMainForm -- File Action slots.  // QSampler::MainForm -- File Action slots.
1443    
1444  // Create a new sampler session.  // Create a new sampler session.
1445  void MainForm::fileNew (void)  void MainForm::fileNew (void)
# Line 1372  void MainForm::fileOpenRecent (void) Line 1463  void MainForm::fileOpenRecent (void)
1463          // Retrive filename index from action data...          // Retrive filename index from action data...
1464          QAction *pAction = qobject_cast<QAction *> (sender());          QAction *pAction = qobject_cast<QAction *> (sender());
1465          if (pAction && m_pOptions) {          if (pAction && m_pOptions) {
1466                  int iIndex = pAction->data().toInt();                  const int iIndex = pAction->data().toInt();
1467                  if (iIndex >= 0 && iIndex < m_pOptions->recentFiles.count()) {                  if (iIndex >= 0 && iIndex < m_pOptions->recentFiles.count()) {
1468                          QString sFilename = m_pOptions->recentFiles[iIndex];                          QString sFilename = m_pOptions->recentFiles[iIndex];
1469                          // Check if we can safely close the current session...                          // Check if we can safely close the current session...
# Line 1402  void MainForm::fileSaveAs (void) Line 1493  void MainForm::fileSaveAs (void)
1493  // Reset the sampler instance.  // Reset the sampler instance.
1494  void MainForm::fileReset (void)  void MainForm::fileReset (void)
1495  {  {
1496          if (m_pClient == NULL)          if (m_pClient == nullptr)
1497                  return;                  return;
1498    
1499          // Ask user whether he/she want's an internal sampler reset...          // Ask user whether he/she want's an internal sampler reset...
1500          if (QMessageBox::warning(this,          if (m_pOptions && m_pOptions->bConfirmReset) {
1501                  QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sTitle = tr("Warning");
1502                  tr("Resetting the sampler instance will close\n"                  const QString& sText = tr(
1503                  "all device and channel configurations.\n\n"                          "Resetting the sampler instance will close\n"
1504                  "Please note that this operation may cause\n"                          "all device and channel configurations.\n\n"
1505                  "temporary MIDI and Audio disruption.\n\n"                          "Please note that this operation may cause\n"
1506                  "Do you want to reset the sampler engine now?"),                          "temporary MIDI and Audio disruption.\n\n"
1507                  QMessageBox::Ok | QMessageBox::Cancel)                          "Do you want to reset the sampler engine now?");
1508                  == QMessageBox::Cancel)          #if 0
1509                  return;                  if (QMessageBox::warning(this, sTitle, sText,
1510                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1511                            return;
1512            #else
1513                    QMessageBox mbox(this);
1514                    mbox.setIcon(QMessageBox::Warning);
1515                    mbox.setWindowTitle(sTitle);
1516                    mbox.setText(sText);
1517                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1518                    QCheckBox cbox(tr("Don't ask this again"));
1519                    cbox.setChecked(false);
1520                    cbox.blockSignals(true);
1521                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1522                    if (mbox.exec() == QMessageBox::Cancel)
1523                            return;
1524                    if (cbox.isChecked())
1525                            m_pOptions->bConfirmReset = false;
1526            #endif
1527            }
1528    
1529          // Trye closing the current session, first...          // Trye closing the current session, first...
1530          if (!closeSession(true))          if (!closeSession(true))
# Line 1440  void MainForm::fileReset (void) Line 1549  void MainForm::fileReset (void)
1549  // Restart the client/server instance.  // Restart the client/server instance.
1550  void MainForm::fileRestart (void)  void MainForm::fileRestart (void)
1551  {  {
1552          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1553                  return;                  return;
1554    
1555          bool bRestart = true;          bool bRestart = true;
1556    
1557          // Ask user whether he/she want's a complete restart...          // Ask user whether he/she want's a complete restart...
1558          // (if we're currently up and running)          // (if we're currently up and running)
1559          if (bRestart && m_pClient) {          if (m_pOptions && m_pOptions->bConfirmRestart) {
1560                  bRestart = (QMessageBox::warning(this,                  const QString& sTitle = tr("Warning");
1561                          QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sText = tr(
1562                          tr("New settings will be effective after\n"                          "New settings will be effective after\n"
1563                          "restarting the client/server connection.\n\n"                          "restarting the client/server connection.\n\n"
1564                          "Please note that this operation may cause\n"                          "Please note that this operation may cause\n"
1565                          "temporary MIDI and Audio disruption.\n\n"                          "temporary MIDI and Audio disruption.\n\n"
1566                          "Do you want to restart the connection now?"),                          "Do you want to restart the connection now?");
1567                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok);          #if 0
1568                    if (QMessageBox::warning(this, sTitle, sText,
1569                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1570                            bRestart = false;
1571            #else
1572                    QMessageBox mbox(this);
1573                    mbox.setIcon(QMessageBox::Warning);
1574                    mbox.setWindowTitle(sTitle);
1575                    mbox.setText(sText);
1576                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1577                    QCheckBox cbox(tr("Don't ask this again"));
1578                    cbox.setChecked(false);
1579                    cbox.blockSignals(true);
1580                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1581                    if (mbox.exec() == QMessageBox::Cancel)
1582                            bRestart = false;
1583                    else
1584                    if (cbox.isChecked())
1585                            m_pOptions->bConfirmRestart = false;
1586            #endif
1587          }          }
1588    
1589          // Are we still for it?          // Are we still for it?
# Line 1477  void MainForm::fileExit (void) Line 1605  void MainForm::fileExit (void)
1605    
1606    
1607  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1608  // qsamplerMainForm -- Edit Action slots.  // QSampler::MainForm -- Edit Action slots.
1609    
1610  // Add a new sampler channel.  // Add a new sampler channel.
1611  void MainForm::editAddChannel (void)  void MainForm::editAddChannel (void)
1612  {  {
1613          if (m_pClient == NULL)          ++m_iDirtySetup;
1614            addChannelStrip();
1615            --m_iDirtySetup;
1616    }
1617    
1618    void MainForm::addChannelStrip (void)
1619    {
1620            if (m_pClient == nullptr)
1621                  return;                  return;
1622    
1623          // Just create the channel instance...          // Just create the channel instance...
1624          Channel *pChannel = new Channel();          Channel *pChannel = new Channel();
1625          if (pChannel == NULL)          if (pChannel == nullptr)
1626                  return;                  return;
1627    
1628          // Before we show it up, may be we'll          // Before we show it up, may be we'll
# Line 1505  void MainForm::editAddChannel (void) Line 1640  void MainForm::editAddChannel (void)
1640          }          }
1641    
1642          // Do we auto-arrange?          // Do we auto-arrange?
1643          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
1644    
1645          // Make that an overall update.          // Make that an overall update.
1646          m_iDirtyCount++;          m_iDirtyCount++;
# Line 1517  void MainForm::editAddChannel (void) Line 1651  void MainForm::editAddChannel (void)
1651  // Remove current sampler channel.  // Remove current sampler channel.
1652  void MainForm::editRemoveChannel (void)  void MainForm::editRemoveChannel (void)
1653  {  {
1654          if (m_pClient == NULL)          ++m_iDirtySetup;
1655            removeChannelStrip();
1656            --m_iDirtySetup;
1657    }
1658    
1659    void MainForm::removeChannelStrip (void)
1660    {
1661            if (m_pClient == nullptr)
1662                  return;                  return;
1663    
1664          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1665          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1666                  return;                  return;
1667    
1668          Channel *pChannel = pChannelStrip->channel();          Channel *pChannel = pChannelStrip->channel();
1669          if (pChannel == NULL)          if (pChannel == nullptr)
1670                  return;                  return;
1671    
1672          // Prompt user if he/she's sure about this...          // Prompt user if he/she's sure about this...
1673          if (m_pOptions && m_pOptions->bConfirmRemove) {          if (m_pOptions && m_pOptions->bConfirmRemove) {
1674                  if (QMessageBox::warning(this,                  const QString& sTitle = tr("Warning");
1675                          QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sText = tr(
1676                          tr("About to remove channel:\n\n"                          "About to remove channel:\n\n"
1677                          "%1\n\n"                          "%1\n\n"
1678                          "Are you sure?")                          "Are you sure?")
1679                          .arg(pChannelStrip->windowTitle()),                          .arg(pChannelStrip->windowTitle());
1680                          QMessageBox::Ok | QMessageBox::Cancel)          #if 0
1681                          == QMessageBox::Cancel)                  if (QMessageBox::warning(this, sTitle, sText,
1682                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1683                            return;
1684            #else
1685                    QMessageBox mbox(this);
1686                    mbox.setIcon(QMessageBox::Warning);
1687                    mbox.setWindowTitle(sTitle);
1688                    mbox.setText(sText);
1689                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1690                    QCheckBox cbox(tr("Don't ask this again"));
1691                    cbox.setChecked(false);
1692                    cbox.blockSignals(true);
1693                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1694                    if (mbox.exec() == QMessageBox::Cancel)
1695                          return;                          return;
1696                    if (cbox.isChecked())
1697                            m_pOptions->bConfirmRemove = false;
1698            #endif
1699          }          }
1700    
1701          // Remove the existing sampler channel.          // Remove the existing sampler channel.
1702          if (!pChannel->removeChannel())          if (!pChannel->removeChannel())
1703                  return;                  return;
1704    
         // We'll be dirty, for sure...  
         m_iDirtyCount++;  
   
1705          // Just delete the channel strip.          // Just delete the channel strip.
1706          destroyChannelStrip(pChannelStrip);          destroyChannelStrip(pChannelStrip);
1707    
1708            // We'll be dirty, for sure...
1709            m_iDirtyCount++;
1710            stabilizeForm();
1711  }  }
1712    
1713    
1714  // Setup current sampler channel.  // Setup current sampler channel.
1715  void MainForm::editSetupChannel (void)  void MainForm::editSetupChannel (void)
1716  {  {
1717          if (m_pClient == NULL)          if (m_pClient == nullptr)
1718                  return;                  return;
1719    
1720          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1721          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1722                  return;                  return;
1723    
1724          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1571  void MainForm::editSetupChannel (void) Line 1729  void MainForm::editSetupChannel (void)
1729  // Edit current sampler channel.  // Edit current sampler channel.
1730  void MainForm::editEditChannel (void)  void MainForm::editEditChannel (void)
1731  {  {
1732          if (m_pClient == NULL)          if (m_pClient == nullptr)
1733                  return;                  return;
1734    
1735          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1736          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1737                  return;                  return;
1738    
1739          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1586  void MainForm::editEditChannel (void) Line 1744  void MainForm::editEditChannel (void)
1744  // Reset current sampler channel.  // Reset current sampler channel.
1745  void MainForm::editResetChannel (void)  void MainForm::editResetChannel (void)
1746  {  {
1747          if (m_pClient == NULL)          if (m_pClient == nullptr)
1748                  return;                  return;
1749    
1750          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1751          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1752                  return;                  return;
1753    
1754          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1601  void MainForm::editResetChannel (void) Line 1759  void MainForm::editResetChannel (void)
1759  // Reset all sampler channels.  // Reset all sampler channels.
1760  void MainForm::editResetAllChannels (void)  void MainForm::editResetAllChannels (void)
1761  {  {
1762          if (m_pClient == NULL)          if (m_pClient == nullptr)
1763                  return;                  return;
1764    
1765          // Invoque the channel strip procedure,          // Invoque the channel strip procedure,
1766          // for all channels out there...          // for all channels out there...
1767          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1768          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
1769          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {                  = m_pWorkspace->subWindowList();
1770                  ChannelStrip *pChannelStrip = NULL;          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
1771                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                  ChannelStrip *pChannelStrip
1772                  if (pMdiSubWindow)                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
1773                  if (pChannelStrip)                  if (pChannelStrip)
1774                          pChannelStrip->channelReset();                          pChannelStrip->channelReset();
1775          }          }
# Line 1621  void MainForm::editResetAllChannels (voi Line 1778  void MainForm::editResetAllChannels (voi
1778    
1779    
1780  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1781  // qsamplerMainForm -- View Action slots.  // QSampler::MainForm -- View Action slots.
1782    
1783  // Show/hide the main program window menubar.  // Show/hide the main program window menubar.
1784  void MainForm::viewMenubar ( bool bOn )  void MainForm::viewMenubar ( bool bOn )
# Line 1671  void MainForm::viewMessages ( bool bOn ) Line 1828  void MainForm::viewMessages ( bool bOn )
1828  // Show/hide the MIDI instrument list-view form.  // Show/hide the MIDI instrument list-view form.
1829  void MainForm::viewInstruments (void)  void MainForm::viewInstruments (void)
1830  {  {
1831          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1832                  return;                  return;
1833    
1834          if (m_pInstrumentListForm) {          if (m_pInstrumentListForm) {
# Line 1690  void MainForm::viewInstruments (void) Line 1847  void MainForm::viewInstruments (void)
1847  // Show/hide the device configurator form.  // Show/hide the device configurator form.
1848  void MainForm::viewDevices (void)  void MainForm::viewDevices (void)
1849  {  {
1850          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1851                  return;                  return;
1852    
1853          if (m_pDeviceForm) {          if (m_pDeviceForm) {
# Line 1709  void MainForm::viewDevices (void) Line 1866  void MainForm::viewDevices (void)
1866  // Show options dialog.  // Show options dialog.
1867  void MainForm::viewOptions (void)  void MainForm::viewOptions (void)
1868  {  {
1869          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1870                  return;                  return;
1871    
1872          OptionsForm* pOptionsForm = new OptionsForm(this);          OptionsForm* pOptionsForm = new OptionsForm(this);
# Line 1721  void MainForm::viewOptions (void) Line 1878  void MainForm::viewOptions (void)
1878                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)
1879                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();
1880                  // To track down deferred or immediate changes.                  // To track down deferred or immediate changes.
1881                  QString sOldServerHost      = m_pOptions->sServerHost;                  const QString sOldServerHost       = m_pOptions->sServerHost;
1882                  int     iOldServerPort      = m_pOptions->iServerPort;                  const int     iOldServerPort       = m_pOptions->iServerPort;
1883                  int     iOldServerTimeout   = m_pOptions->iServerTimeout;                  const int     iOldServerTimeout    = m_pOptions->iServerTimeout;
1884                  bool    bOldServerStart     = m_pOptions->bServerStart;                  const bool    bOldServerStart      = m_pOptions->bServerStart;
1885                  QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;                  const QString sOldServerCmdLine    = m_pOptions->sServerCmdLine;
1886                  bool    bOldMessagesLog     = m_pOptions->bMessagesLog;                  const bool    bOldMessagesLog      = m_pOptions->bMessagesLog;
1887                  QString sOldMessagesLogPath = m_pOptions->sMessagesLogPath;                  const QString sOldMessagesLogPath  = m_pOptions->sMessagesLogPath;
1888                  QString sOldDisplayFont     = m_pOptions->sDisplayFont;                  const QString sOldDisplayFont      = m_pOptions->sDisplayFont;
1889                  bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;                  const bool    bOldDisplayEffect    = m_pOptions->bDisplayEffect;
1890                  int     iOldMaxVolume       = m_pOptions->iMaxVolume;                  const int     iOldMaxVolume        = m_pOptions->iMaxVolume;
1891                  QString sOldMessagesFont    = m_pOptions->sMessagesFont;                  const QString sOldMessagesFont     = m_pOptions->sMessagesFont;
1892                  bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;                  const bool    bOldKeepOnTop        = m_pOptions->bKeepOnTop;
1893                  bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;                  const bool    bOldStdoutCapture    = m_pOptions->bStdoutCapture;
1894                  int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;                  const int     bOldMessagesLimit    = m_pOptions->bMessagesLimit;
1895                  int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;                  const int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1896                  bool    bOldCompletePath    = m_pOptions->bCompletePath;                  const bool    bOldCompletePath     = m_pOptions->bCompletePath;
1897                  bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;                  const bool    bOldInstrumentNames  = m_pOptions->bInstrumentNames;
1898                  int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;                  const int     iOldMaxRecentFiles   = m_pOptions->iMaxRecentFiles;
1899                  int     iOldBaseFontSize    = m_pOptions->iBaseFontSize;                  const int     iOldBaseFontSize     = m_pOptions->iBaseFontSize;
1900                    const QString sOldCustomStyleTheme = m_pOptions->sCustomStyleTheme;
1901                    const QString sOldCustomColorTheme = m_pOptions->sCustomColorTheme;
1902                  // Load the current setup settings.                  // Load the current setup settings.
1903                  pOptionsForm->setup(m_pOptions);                  pOptionsForm->setup(m_pOptions);
1904                  // Show the setup dialog...                  // Show the setup dialog...
1905                  if (pOptionsForm->exec()) {                  if (pOptionsForm->exec()) {
1906                          // Warn if something will be only effective on next run.                          // Warn if something will be only effective on next run.
1907                            int iNeedRestart = 0;
1908                          if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||                          if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1909                                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||                                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture)) {
1910                                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||                                  updateMessagesCapture();
1911                                    ++iNeedRestart;
1912                            }
1913                            if (( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1914                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)     ||                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)     ||
1915                                  (iOldBaseFontSize   !=  m_pOptions->iBaseFontSize)) {                                  (iOldBaseFontSize   !=  m_pOptions->iBaseFontSize)) {
1916                                  QMessageBox::information(this,                                  ++iNeedRestart;
1917                                          QSAMPLER_TITLE ": " + tr("Information"),                          }
1918                                          tr("Some settings may be only effective\n"                          // Check whether restart is needed or whether
1919                                          "next time you start this program."));                          // custom options maybe set up immediately...
1920                                  updateMessagesCapture();                          if (m_pOptions->sCustomStyleTheme != sOldCustomStyleTheme) {
1921                            #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
1922                                    ++iNeedRestart;
1923                            #else          
1924                                    if (m_pOptions->sCustomStyleTheme.isEmpty()) {
1925                                            ++iNeedRestart;
1926                                    } else {
1927                                            QApplication::setStyle(
1928                                                    QStyleFactory::create(m_pOptions->sCustomStyleTheme));
1929                                    }
1930                            #endif
1931                            }
1932                            if (m_pOptions->sCustomColorTheme != sOldCustomColorTheme) {
1933                            #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
1934                                    ++iNeedRestart;
1935                            #else
1936                                    if (m_pOptions->sCustomColorTheme.isEmpty()) {
1937                                            ++iNeedRestart;
1938                                    } else {
1939                                            QPalette pal;
1940                                            if (PaletteForm::namedPalette(
1941                                                            &m_pOptions->settings(), m_pOptions->sCustomColorTheme, pal))
1942                                                    QApplication::setPalette(pal);
1943                                    }
1944                            #endif
1945                          }                          }
1946                          // Check wheather something immediate has changed.                          // Check wheather something immediate has changed.
1947                          if (( bOldMessagesLog && !m_pOptions->bMessagesLog) ||                          if (( bOldMessagesLog && !m_pOptions->bMessagesLog) ||
# Line 1782  void MainForm::viewOptions (void) Line 1969  void MainForm::viewOptions (void)
1969                                  (!bOldMessagesLimit &&  m_pOptions->bMessagesLimit) ||                                  (!bOldMessagesLimit &&  m_pOptions->bMessagesLimit) ||
1970                                  (iOldMessagesLimitLines !=  m_pOptions->iMessagesLimitLines))                                  (iOldMessagesLimitLines !=  m_pOptions->iMessagesLimitLines))
1971                                  updateMessagesLimit();                                  updateMessagesLimit();
1972                            // Show restart needed message...
1973                            if (iNeedRestart > 0) {
1974                                    QMessageBox::information(this,
1975                                            tr("Information"),
1976                                            tr("Some settings may be only effective\n"
1977                                            "next time you start this program."));
1978                            }
1979                          // And now the main thing, whether we'll do client/server recycling?                          // And now the main thing, whether we'll do client/server recycling?
1980                          if ((sOldServerHost != m_pOptions->sServerHost) ||                          if ((sOldServerHost != m_pOptions->sServerHost) ||
1981                                  (iOldServerPort != m_pOptions->iServerPort) ||                                  (iOldServerPort != m_pOptions->iServerPort) ||
# Line 1802  void MainForm::viewOptions (void) Line 1996  void MainForm::viewOptions (void)
1996    
1997    
1998  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1999  // qsamplerMainForm -- Channels action slots.  // QSampler::MainForm -- Channels action slots.
2000    
2001  // Arrange channel strips.  // Arrange channel strips.
2002  void MainForm::channelsArrange (void)  void MainForm::channelsArrange (void)
2003  {  {
2004          // Full width vertical tiling          // Full width vertical tiling
2005          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2006                    = m_pWorkspace->subWindowList();
2007          if (wlist.isEmpty())          if (wlist.isEmpty())
2008                  return;                  return;
2009    
2010          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2011          int y = 0;          int y = 0;
2012          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2013                  ChannelStrip *pChannelStrip = NULL;                  pMdiSubWindow->adjustSize();
2014                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                  const QRect& frameRect
2015                  if (pMdiSubWindow)                          = pMdiSubWindow->frameGeometry();
2016                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  int w = m_pWorkspace->width();
2017                  if (pChannelStrip) {                  if (w < frameRect.width())
2018                  /*  if (pChannelStrip->testWState(WState_Maximized | WState_Minimized)) {                          w = frameRect.width();
2019                                  // Prevent flicker...                  const int h = frameRect.height();
2020                                  pChannelStrip->hide();                  pMdiSubWindow->setGeometry(0, y, w, h);
2021                                  pChannelStrip->showNormal();                  y += h;
                         }   */  
                         pChannelStrip->adjustSize();  
                         int iWidth  = m_pWorkspace->width();  
                         if (iWidth < pChannelStrip->width())  
                                 iWidth = pChannelStrip->width();  
                 //  int iHeight = pChannelStrip->height()  
                 //              + pChannelStrip->parentWidget()->baseSize().height();  
                         int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();  
                         pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);  
                         y += iHeight;  
                 }  
2022          }          }
2023          m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
2024    
# Line 1845  void MainForm::channelsArrange (void) Line 2029  void MainForm::channelsArrange (void)
2029  // Auto-arrange channel strips.  // Auto-arrange channel strips.
2030  void MainForm::channelsAutoArrange ( bool bOn )  void MainForm::channelsAutoArrange ( bool bOn )
2031  {  {
2032          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2033                  return;                  return;
2034    
2035          // Toggle the auto-arrange flag.          // Toggle the auto-arrange flag.
2036          m_pOptions->bAutoArrange = bOn;          m_pOptions->bAutoArrange = bOn;
2037    
2038          // If on, update whole workspace...          // If on, update whole workspace...
2039          if (m_pOptions->bAutoArrange)          channelsArrangeAuto();
2040    }
2041    
2042    
2043    void MainForm::channelsArrangeAuto (void)
2044    {
2045            if (m_pOptions && m_pOptions->bAutoArrange)
2046                  channelsArrange();                  channelsArrange();
2047  }  }
2048    
2049    
2050  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2051  // qsamplerMainForm -- Help Action slots.  // QSampler::MainForm -- Help Action slots.
2052    
2053  // Show information about the Qt toolkit.  // Show information about the Qt toolkit.
2054  void MainForm::helpAboutQt (void)  void MainForm::helpAboutQt (void)
# Line 1870  void MainForm::helpAboutQt (void) Line 2060  void MainForm::helpAboutQt (void)
2060  // Show information about application program.  // Show information about application program.
2061  void MainForm::helpAbout (void)  void MainForm::helpAbout (void)
2062  {  {
2063          // 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";  
2064  #ifdef CONFIG_DEBUG  #ifdef CONFIG_DEBUG
2065          sText += "<small><font color=\"red\">";          list << tr("Debugging option enabled.");
         sText += tr("Debugging option enabled.");  
         sText += "</font></small><br />";  
2066  #endif  #endif
2067  #ifndef CONFIG_LIBGIG  #ifndef CONFIG_LIBGIG
2068          sText += "<small><font color=\"red\">";          list << tr("GIG (libgig) file support disabled.");
         sText += tr("GIG (libgig) file support disabled.");  
         sText += "</font></small><br />";  
2069  #endif  #endif
2070  #ifndef CONFIG_INSTRUMENT_NAME  #ifndef CONFIG_INSTRUMENT_NAME
2071          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 />";  
2072  #endif  #endif
2073  #ifndef CONFIG_MUTE_SOLO  #ifndef CONFIG_MUTE_SOLO
2074          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 />";  
2075  #endif  #endif
2076  #ifndef CONFIG_AUDIO_ROUTING  #ifndef CONFIG_AUDIO_ROUTING
2077          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 />";  
2078  #endif  #endif
2079  #ifndef CONFIG_FXSEND  #ifndef CONFIG_FXSEND
2080          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 />";  
2081  #endif  #endif
2082  #ifndef CONFIG_VOLUME  #ifndef CONFIG_VOLUME
2083          sText += "<small><font color=\"red\">";          list << tr("Global volume support disabled.");
         sText += tr("Global volume support disabled.");  
         sText += "</font></small><br />";  
2084  #endif  #endif
2085  #ifndef CONFIG_MIDI_INSTRUMENT  #ifndef CONFIG_MIDI_INSTRUMENT
2086          sText += "<small><font color=\"red\">";          list << tr("MIDI instrument mapping support disabled.");
         sText += tr("MIDI instrument mapping support disabled.");  
         sText += "</font></small><br />";  
2087  #endif  #endif
2088  #ifndef CONFIG_EDIT_INSTRUMENT  #ifndef CONFIG_EDIT_INSTRUMENT
2089          sText += "<small><font color=\"red\">";          list << tr("Instrument editing support disabled.");
         sText += tr("Instrument editing support disabled.");  
         sText += "</font></small><br />";  
2090  #endif  #endif
2091  #ifndef CONFIG_EVENT_CHANNEL_MIDI  #ifndef CONFIG_EVENT_CHANNEL_MIDI
2092          sText += "<small><font color=\"red\">";          list << tr("Channel MIDI event support disabled.");
         sText += tr("Channel MIDI event support disabled.");  
         sText += "</font></small><br />";  
2093  #endif  #endif
2094  #ifndef CONFIG_EVENT_DEVICE_MIDI  #ifndef CONFIG_EVENT_DEVICE_MIDI
2095          sText += "<small><font color=\"red\">";          list << tr("Device MIDI event support disabled.");
         sText += tr("Device MIDI event support disabled.");  
         sText += "</font></small><br />";  
2096  #endif  #endif
2097  #ifndef CONFIG_MAX_VOICES  #ifndef CONFIG_MAX_VOICES
2098          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 />";  
2099  #endif  #endif
2100    
2101            // Stuff the about box text...
2102            QString sText = "<p>\n";
2103            sText += "<b>" QSAMPLER_TITLE " - " + tr(QSAMPLER_SUBTITLE) + "</b><br />\n";
2104            sText += "<br />\n";
2105            sText += tr("Version") + ": <b>" CONFIG_BUILD_VERSION "</b><br />\n";
2106    //      sText += "<small>" + tr("Build") + ": " CONFIG_BUILD_DATE "</small><br />\n";
2107            if (!list.isEmpty()) {
2108                    sText += "<small><font color=\"red\">";
2109                    sText += list.join("<br />\n");
2110                    sText += "</font></small>";
2111            }
2112          sText += "<br />\n";          sText += "<br />\n";
2113          sText += tr("Using") + ": ";          sText += tr("Using") + ": ";
2114          sText += ::lscp_client_package();          sText += ::lscp_client_package();
# Line 1960  void MainForm::helpAbout (void) Line 2133  void MainForm::helpAbout (void)
2133          sText += "</small>";          sText += "</small>";
2134          sText += "</p>\n";          sText += "</p>\n";
2135    
2136          QMessageBox::about(this, tr("About") + " " QSAMPLER_TITLE, sText);          QMessageBox::about(this, tr("About"), sText);
2137  }  }
2138    
2139    
2140  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2141  // qsamplerMainForm -- Main window stabilization.  // QSampler::MainForm -- Main window stabilization.
2142    
2143  void MainForm::stabilizeForm (void)  void MainForm::stabilizeForm (void)
2144  {  {
# Line 1973  void MainForm::stabilizeForm (void) Line 2146  void MainForm::stabilizeForm (void)
2146          QString sSessionName = sessionName(m_sFilename);          QString sSessionName = sessionName(m_sFilename);
2147          if (m_iDirtyCount > 0)          if (m_iDirtyCount > 0)
2148                  sSessionName += " *";                  sSessionName += " *";
2149          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));          setWindowTitle(sSessionName);
2150    
2151          // Update the main menu state...          // Update the main menu state...
2152          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
2153          bool bHasClient = (m_pOptions != NULL && m_pClient != NULL);          const QList<QMdiSubWindow *>& wlist = m_pWorkspace->subWindowList();
2154          bool bHasChannel = (bHasClient && pChannelStrip != NULL);          const bool bHasClient = (m_pOptions != nullptr && m_pClient != nullptr);
2155          bool bHasChannels = (bHasClient && m_pWorkspace->subWindowList().count() > 0);          const bool bHasChannel = (bHasClient && pChannelStrip != nullptr);
2156            const bool bHasChannels = (bHasClient && wlist.count() > 0);
2157          m_ui.fileNewAction->setEnabled(bHasClient);          m_ui.fileNewAction->setEnabled(bHasClient);
2158          m_ui.fileOpenAction->setEnabled(bHasClient);          m_ui.fileOpenAction->setEnabled(bHasClient);
2159          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
2160          m_ui.fileSaveAsAction->setEnabled(bHasClient);          m_ui.fileSaveAsAction->setEnabled(bHasClient);
2161          m_ui.fileResetAction->setEnabled(bHasClient);          m_ui.fileResetAction->setEnabled(bHasClient);
2162          m_ui.fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);          m_ui.fileRestartAction->setEnabled(bHasClient || m_pServer == nullptr);
2163          m_ui.editAddChannelAction->setEnabled(bHasClient);          m_ui.editAddChannelAction->setEnabled(bHasClient);
2164          m_ui.editRemoveChannelAction->setEnabled(bHasChannel);          m_ui.editRemoveChannelAction->setEnabled(bHasChannel);
2165          m_ui.editSetupChannelAction->setEnabled(bHasChannel);          m_ui.editSetupChannelAction->setEnabled(bHasChannel);
# Line 2059  void MainForm::volumeChanged ( int iVolu Line 2233  void MainForm::volumeChanged ( int iVolu
2233                  m_pVolumeSpinBox->setValue(iVolume);                  m_pVolumeSpinBox->setValue(iVolume);
2234    
2235          // Do it as commanded...          // Do it as commanded...
2236          float fVolume = 0.01f * float(iVolume);          const float fVolume = 0.01f * float(iVolume);
2237          if (::lscp_set_volume(m_pClient, fVolume) == LSCP_OK)          if (::lscp_set_volume(m_pClient, fVolume) == LSCP_OK)
2238                  appendMessages(QObject::tr("Volume: %1.").arg(fVolume));                  appendMessages(QObject::tr("Volume: %1.").arg(fVolume));
2239          else          else
# Line 2094  void MainForm::channelStripChanged ( Cha Line 2268  void MainForm::channelStripChanged ( Cha
2268  void MainForm::updateSession (void)  void MainForm::updateSession (void)
2269  {  {
2270  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
2271          int iVolume = ::lroundf(100.0f * ::lscp_get_volume(m_pClient));          const int iVolume = ::lroundf(100.0f * ::lscp_get_volume(m_pClient));
2272          m_iVolumeChanging++;          m_iVolumeChanging++;
2273          m_pVolumeSlider->setValue(iVolume);          m_pVolumeSlider->setValue(iVolume);
2274          m_pVolumeSpinBox->setValue(iVolume);          m_pVolumeSpinBox->setValue(iVolume);
# Line 2102  void MainForm::updateSession (void) Line 2276  void MainForm::updateSession (void)
2276  #endif  #endif
2277  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
2278          // FIXME: Make some room for default instrument maps...          // FIXME: Make some room for default instrument maps...
2279          int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);          const int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);
2280          if (iMaps < 0)          if (iMaps < 0)
2281                  appendMessagesClient("lscp_get_midi_instrument_maps");                  appendMessagesClient("lscp_get_midi_instrument_maps");
2282          else if (iMaps < 1) {          else if (iMaps < 1) {
# Line 2116  void MainForm::updateSession (void) Line 2290  void MainForm::updateSession (void)
2290          updateAllChannelStrips(false);          updateAllChannelStrips(false);
2291    
2292          // Do we auto-arrange?          // Do we auto-arrange?
2293          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
2294    
2295          // Remember to refresh devices and instruments...          // Remember to refresh devices and instruments...
2296          if (m_pInstrumentListForm)          if (m_pInstrumentListForm)
# Line 2129  void MainForm::updateSession (void) Line 2302  void MainForm::updateSession (void)
2302    
2303  void MainForm::updateAllChannelStrips ( bool bRemoveDeadStrips )  void MainForm::updateAllChannelStrips ( bool bRemoveDeadStrips )
2304  {  {
2305            // Skip if setting up a new channel strip...
2306            if (m_iDirtySetup > 0)
2307                    return;
2308    
2309          // Retrieve the current channel list.          // Retrieve the current channel list.
2310          int *piChannelIDs = ::lscp_list_channels(m_pClient);          int *piChannelIDs = ::lscp_list_channels(m_pClient);
2311          if (piChannelIDs == NULL) {          if (piChannelIDs == nullptr) {
2312                  if (::lscp_client_get_errno(m_pClient)) {                  if (::lscp_client_get_errno(m_pClient)) {
2313                          appendMessagesClient("lscp_list_channels");                          appendMessagesClient("lscp_list_channels");
2314                          appendMessagesError(                          appendMessagesError(
# Line 2146  void MainForm::updateAllChannelStrips ( Line 2323  void MainForm::updateAllChannelStrips (
2323                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));
2324                  }                  }
2325                  // Do we auto-arrange?                  // Do we auto-arrange?
2326                  if (m_pOptions && m_pOptions->bAutoArrange)                  channelsArrangeAuto();
                         channelsArrange();  
2327                  // remove dead channel strips                  // remove dead channel strips
2328                  if (bRemoveDeadStrips) {                  if (bRemoveDeadStrips) {
2329                          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();                          const QList<QMdiSubWindow *>& wlist
2330                          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {                                  = m_pWorkspace->subWindowList();
2331                                  ChannelStrip *pChannelStrip = NULL;                          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2332                                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                                  ChannelStrip *pChannelStrip
2333                                  if (pMdiSubWindow)                                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2334                                  if (pChannelStrip) {                                  if (pChannelStrip) {
2335                                          bool bExists = false;                                          bool bExists = false;
2336                                          for (int j = 0; piChannelIDs[j] >= 0; ++j) {                                          for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {
2337                                                  if (!pChannelStrip->channel())                                                  Channel *pChannel = pChannelStrip->channel();
2338                                                    if (pChannel == nullptr)
2339                                                          break;                                                          break;
2340                                                  if (piChannelIDs[j] == pChannelStrip->channel()->channelID()) {                                                  if (piChannelIDs[iChannel] == pChannel->channelID()) {
2341                                                          // strip exists, don't touch it                                                          // strip exists, don't touch it
2342                                                          bExists = true;                                                          bExists = true;
2343                                                          break;                                                          break;
# Line 2182  void MainForm::updateAllChannelStrips ( Line 2358  void MainForm::updateAllChannelStrips (
2358  // Update the recent files list and menu.  // Update the recent files list and menu.
2359  void MainForm::updateRecentFiles ( const QString& sFilename )  void MainForm::updateRecentFiles ( const QString& sFilename )
2360  {  {
2361          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2362                  return;                  return;
2363    
2364          // Remove from list if already there (avoid duplicates)          // Remove from list if already there (avoid duplicates)
2365          int iIndex = m_pOptions->recentFiles.indexOf(sFilename);          const int iIndex = m_pOptions->recentFiles.indexOf(sFilename);
2366          if (iIndex >= 0)          if (iIndex >= 0)
2367                  m_pOptions->recentFiles.removeAt(iIndex);                  m_pOptions->recentFiles.removeAt(iIndex);
2368          // Put it to front...          // Put it to front...
# Line 2197  void MainForm::updateRecentFiles ( const Line 2373  void MainForm::updateRecentFiles ( const
2373  // Update the recent files list and menu.  // Update the recent files list and menu.
2374  void MainForm::updateRecentFilesMenu (void)  void MainForm::updateRecentFilesMenu (void)
2375  {  {
2376          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2377                  return;                  return;
2378    
2379          // Time to keep the list under limits.          // Time to keep the list under limits.
# Line 2225  void MainForm::updateRecentFilesMenu (vo Line 2401  void MainForm::updateRecentFilesMenu (vo
2401  void MainForm::updateInstrumentNames (void)  void MainForm::updateInstrumentNames (void)
2402  {  {
2403          // Full channel list update...          // Full channel list update...
2404          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2405                    = m_pWorkspace->subWindowList();
2406          if (wlist.isEmpty())          if (wlist.isEmpty())
2407                  return;                  return;
2408    
2409          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2410          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2411                  ChannelStrip *pChannelStrip = (ChannelStrip *) wlist.at(iChannel);                  ChannelStrip *pChannelStrip
2412                            = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2413                  if (pChannelStrip)                  if (pChannelStrip)
2414                          pChannelStrip->updateInstrumentName(true);                          pChannelStrip->updateInstrumentName(true);
2415          }          }
# Line 2242  void MainForm::updateInstrumentNames (vo Line 2420  void MainForm::updateInstrumentNames (vo
2420  // Force update of the channels display font.  // Force update of the channels display font.
2421  void MainForm::updateDisplayFont (void)  void MainForm::updateDisplayFont (void)
2422  {  {
2423          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2424                  return;                  return;
2425    
2426          // Check if display font is legal.          // Check if display font is legal.
2427          if (m_pOptions->sDisplayFont.isEmpty())          if (m_pOptions->sDisplayFont.isEmpty())
2428                  return;                  return;
2429    
2430          // Realize it.          // Realize it.
2431          QFont font;          QFont font;
2432          if (!font.fromString(m_pOptions->sDisplayFont))          if (!font.fromString(m_pOptions->sDisplayFont))
2433                  return;                  return;
2434    
2435          // Full channel list update...          // Full channel list update...
2436          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2437                    = m_pWorkspace->subWindowList();
2438          if (wlist.isEmpty())          if (wlist.isEmpty())
2439                  return;                  return;
2440    
2441          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2442          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2443                  ChannelStrip *pChannelStrip = NULL;                  ChannelStrip *pChannelStrip
2444                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2445                  if (pChannelStrip)                  if (pChannelStrip)
2446                          pChannelStrip->setDisplayFont(font);                          pChannelStrip->setDisplayFont(font);
2447          }          }
# Line 2275  void MainForm::updateDisplayFont (void) Line 2453  void MainForm::updateDisplayFont (void)
2453  void MainForm::updateDisplayEffect (void)  void MainForm::updateDisplayEffect (void)
2454  {  {
2455          // Full channel list update...          // Full channel list update...
2456          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2457                    = m_pWorkspace->subWindowList();
2458          if (wlist.isEmpty())          if (wlist.isEmpty())
2459                  return;                  return;
2460    
2461          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2462          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2463                  ChannelStrip *pChannelStrip = NULL;                  ChannelStrip *pChannelStrip
2464                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2465                  if (pChannelStrip)                  if (pChannelStrip)
2466                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2467          }          }
# Line 2295  void MainForm::updateDisplayEffect (void Line 2472  void MainForm::updateDisplayEffect (void
2472  // Force update of the channels maximum volume setting.  // Force update of the channels maximum volume setting.
2473  void MainForm::updateMaxVolume (void)  void MainForm::updateMaxVolume (void)
2474  {  {
2475          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2476                  return;                  return;
2477    
2478  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
# Line 2306  void MainForm::updateMaxVolume (void) Line 2483  void MainForm::updateMaxVolume (void)
2483  #endif  #endif
2484    
2485          // Full channel list update...          // Full channel list update...
2486          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2487                    = m_pWorkspace->subWindowList();
2488          if (wlist.isEmpty())          if (wlist.isEmpty())
2489                  return;                  return;
2490    
2491          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2492          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2493                  ChannelStrip *pChannelStrip = NULL;                  ChannelStrip *pChannelStrip
2494                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2495                  if (pChannelStrip)                  if (pChannelStrip)
2496                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2497          }          }
# Line 2324  void MainForm::updateMaxVolume (void) Line 2500  void MainForm::updateMaxVolume (void)
2500    
2501    
2502  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2503  // qsamplerMainForm -- Messages window form handlers.  // QSampler::MainForm -- Messages window form handlers.
2504    
2505  // Messages output methods.  // Messages output methods.
2506  void MainForm::appendMessages( const QString& s )  void MainForm::appendMessages( const QString& s )
# Line 2349  void MainForm::appendMessagesText( const Line 2525  void MainForm::appendMessagesText( const
2525                  m_pMessages->appendMessagesText(s);                  m_pMessages->appendMessagesText(s);
2526  }  }
2527    
2528  void MainForm::appendMessagesError( const QString& s )  void MainForm::appendMessagesError( const QString& sText )
2529  {  {
2530          if (m_pMessages)          if (m_pMessages)
2531                  m_pMessages->show();                  m_pMessages->show();
2532    
2533          appendMessagesColor(s.simplified(), "#ff0000");          appendMessagesColor(sText.simplified(), "#ff0000");
2534    
2535          // Make it look responsive...:)          // Make it look responsive...:)
2536          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2537    
2538          QMessageBox::critical(this,          if (m_pOptions && m_pOptions->bConfirmError) {
2539                  QSAMPLER_TITLE ": " + tr("Error"), s, QMessageBox::Cancel);                  const QString& sTitle = tr("Error");
2540            #if 0
2541                    QMessageBox::critical(this, sTitle, sText, QMessageBox::Cancel);
2542            #else
2543                    QMessageBox mbox(this);
2544                    mbox.setIcon(QMessageBox::Critical);
2545                    mbox.setWindowTitle(sTitle);
2546                    mbox.setText(sText);
2547                    mbox.setStandardButtons(QMessageBox::Cancel);
2548                    QCheckBox cbox(tr("Don't show this again"));
2549                    cbox.setChecked(false);
2550                    cbox.blockSignals(true);
2551                    mbox.addButton(&cbox, QMessageBox::ActionRole);
2552                    if (mbox.exec() && cbox.isChecked())
2553                            m_pOptions->bConfirmError = false;
2554            #endif
2555            }
2556  }  }
2557    
2558    
2559  // This is a special message format, just for client results.  // This is a special message format, just for client results.
2560  void MainForm::appendMessagesClient( const QString& s )  void MainForm::appendMessagesClient( const QString& s )
2561  {  {
2562          if (m_pClient == NULL)          if (m_pClient == nullptr)
2563                  return;                  return;
2564    
2565          appendMessagesColor(s + QString(": %1 (errno=%2)")          appendMessagesColor(s + QString(": %1 (errno=%2)")
# Line 2382  void MainForm::appendMessagesClient( con Line 2574  void MainForm::appendMessagesClient( con
2574  // Force update of the messages font.  // Force update of the messages font.
2575  void MainForm::updateMessagesFont (void)  void MainForm::updateMessagesFont (void)
2576  {  {
2577          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2578                  return;                  return;
2579    
2580          if (m_pMessages && !m_pOptions->sMessagesFont.isEmpty()) {          if (m_pMessages && !m_pOptions->sMessagesFont.isEmpty()) {
# Line 2396  void MainForm::updateMessagesFont (void) Line 2588  void MainForm::updateMessagesFont (void)
2588  // Update messages window line limit.  // Update messages window line limit.
2589  void MainForm::updateMessagesLimit (void)  void MainForm::updateMessagesLimit (void)
2590  {  {
2591          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2592                  return;                  return;
2593    
2594          if (m_pMessages) {          if (m_pMessages) {
# Line 2411  void MainForm::updateMessagesLimit (void Line 2603  void MainForm::updateMessagesLimit (void
2603  // Enablement of the messages capture feature.  // Enablement of the messages capture feature.
2604  void MainForm::updateMessagesCapture (void)  void MainForm::updateMessagesCapture (void)
2605  {  {
2606          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2607                  return;                  return;
2608    
2609          if (m_pMessages)          if (m_pMessages)
# Line 2420  void MainForm::updateMessagesCapture (vo Line 2612  void MainForm::updateMessagesCapture (vo
2612    
2613    
2614  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2615  // qsamplerMainForm -- MDI channel strip management.  // QSampler::MainForm -- MDI channel strip management.
2616    
2617  // The channel strip creation executive.  // The channel strip creation executive.
2618  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )
2619  {  {
2620          if (m_pClient == NULL || pChannel == NULL)          if (m_pClient == nullptr || pChannel == nullptr)
2621                  return NULL;                  return nullptr;
2622    
2623          // Add a new channel itema...          // Add a new channel itema...
2624          ChannelStrip *pChannelStrip = new ChannelStrip();          ChannelStrip *pChannelStrip = new ChannelStrip();
2625          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
2626                  return NULL;                  return nullptr;
2627    
2628          // Set some initial channel strip options...          // Set some initial channel strip options...
2629          if (m_pOptions) {          if (m_pOptions) {
# Line 2439  ChannelStrip *MainForm::createChannelStr Line 2631  ChannelStrip *MainForm::createChannelStr
2631                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2632                  // We'll need a display font.                  // We'll need a display font.
2633                  QFont font;                  QFont font;
2634                  if (font.fromString(m_pOptions->sDisplayFont))                  if (!m_pOptions->sDisplayFont.isEmpty() &&
2635                            font.fromString(m_pOptions->sDisplayFont))
2636                          pChannelStrip->setDisplayFont(font);                          pChannelStrip->setDisplayFont(font);
2637                  // Maximum allowed volume setting.                  // Maximum allowed volume setting.
2638                  pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                  pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2639          }          }
2640    
2641          // Add it to workspace...          // Add it to workspace...
2642          m_pWorkspace->addSubWindow(pChannelStrip,          QMdiSubWindow *pMdiSubWindow
2643                  Qt::SubWindow | Qt::FramelessWindowHint);                  = m_pWorkspace->addSubWindow(pChannelStrip,
2644                            Qt::SubWindow | Qt::FramelessWindowHint);
2645            pMdiSubWindow->setAttribute(Qt::WA_DeleteOnClose);
2646    
2647          // Actual channel strip setup...          // Actual channel strip setup...
2648          pChannelStrip->setup(pChannel);          pChannelStrip->setup(pChannel);
# Line 2471  void MainForm::destroyChannelStrip ( Cha Line 2666  void MainForm::destroyChannelStrip ( Cha
2666  {  {
2667          QMdiSubWindow *pMdiSubWindow          QMdiSubWindow *pMdiSubWindow
2668                  = static_cast<QMdiSubWindow *> (pChannelStrip->parentWidget());                  = static_cast<QMdiSubWindow *> (pChannelStrip->parentWidget());
2669          if (pMdiSubWindow == NULL)          if (pMdiSubWindow == nullptr)
2670                  return;                  return;
2671    
2672          // Just delete the channel strip.          // Just delete the channel strip.
# Line 2479  void MainForm::destroyChannelStrip ( Cha Line 2674  void MainForm::destroyChannelStrip ( Cha
2674          delete pMdiSubWindow;          delete pMdiSubWindow;
2675    
2676          // Do we auto-arrange?          // Do we auto-arrange?
2677          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
   
         stabilizeForm();  
2678  }  }
2679    
2680    
# Line 2493  ChannelStrip *MainForm::activeChannelStr Line 2685  ChannelStrip *MainForm::activeChannelStr
2685          if (pMdiSubWindow)          if (pMdiSubWindow)
2686                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2687          else          else
2688                  return NULL;                  return nullptr;
2689  }  }
2690    
2691    
2692  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2693  ChannelStrip *MainForm::channelStripAt ( int iChannel )  ChannelStrip *MainForm::channelStripAt ( int iStrip )
2694  {  {
2695          if (!m_pWorkspace) return NULL;          if (!m_pWorkspace) return nullptr;
2696    
2697          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2698                    = m_pWorkspace->subWindowList();
2699          if (wlist.isEmpty())          if (wlist.isEmpty())
2700                  return NULL;                  return nullptr;
2701    
2702          if (iChannel < 0 || iChannel >= wlist.size())          if (iStrip < 0 || iStrip >= wlist.count())
2703                  return NULL;                  return nullptr;
2704    
2705          QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2706          if (pMdiSubWindow)          if (pMdiSubWindow)
2707                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2708          else          else
2709                  return NULL;                  return nullptr;
2710  }  }
2711    
2712    
2713  // Retrieve a channel strip by sampler channel id.  // Retrieve a channel strip by sampler channel id.
2714  ChannelStrip *MainForm::channelStrip ( int iChannelID )  ChannelStrip *MainForm::channelStrip ( int iChannelID )
2715  {  {
2716          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2717                    = m_pWorkspace->subWindowList();
2718          if (wlist.isEmpty())          if (wlist.isEmpty())
2719                  return NULL;                  return nullptr;
2720    
2721          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2722                  ChannelStrip *pChannelStrip = NULL;                  ChannelStrip *pChannelStrip
2723                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                 if (pMdiSubWindow)  
                         pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2724                  if (pChannelStrip) {                  if (pChannelStrip) {
2725                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
2726                          if (pChannel && pChannel->channelID() == iChannelID)                          if (pChannel && pChannel->channelID() == iChannelID)
# Line 2537  ChannelStrip *MainForm::channelStrip ( i Line 2729  ChannelStrip *MainForm::channelStrip ( i
2729          }          }
2730    
2731          // Not found.          // Not found.
2732          return NULL;          return nullptr;
2733  }  }
2734    
2735    
# Line 2548  void MainForm::channelsMenuAboutToShow ( Line 2740  void MainForm::channelsMenuAboutToShow (
2740          m_ui.channelsMenu->addAction(m_ui.channelsArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsArrangeAction);
2741          m_ui.channelsMenu->addAction(m_ui.channelsAutoArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsAutoArrangeAction);
2742    
2743          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2744                    = m_pWorkspace->subWindowList();
2745          if (!wlist.isEmpty()) {          if (!wlist.isEmpty()) {
2746                  m_ui.channelsMenu->addSeparator();                  m_ui.channelsMenu->addSeparator();
2747                  for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {                  int iStrip = 0;
2748                          ChannelStrip *pChannelStrip = NULL;                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2749                          QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                          ChannelStrip *pChannelStrip
2750                          if (pMdiSubWindow)                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                                 pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2751                          if (pChannelStrip) {                          if (pChannelStrip) {
2752                                  QAction *pAction = m_ui.channelsMenu->addAction(                                  QAction *pAction = m_ui.channelsMenu->addAction(
2753                                          pChannelStrip->windowTitle(),                                          pChannelStrip->windowTitle(),
2754                                          this, SLOT(channelsMenuActivated()));                                          this, SLOT(channelsMenuActivated()));
2755                                  pAction->setCheckable(true);                                  pAction->setCheckable(true);
2756                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);
2757                                  pAction->setData(iChannel);                                  pAction->setData(iStrip);
2758                          }                          }
2759                            ++iStrip;
2760                  }                  }
2761          }          }
2762  }  }
# Line 2574  void MainForm::channelsMenuActivated (vo Line 2767  void MainForm::channelsMenuActivated (vo
2767  {  {
2768          // Retrive channel index from action data...          // Retrive channel index from action data...
2769          QAction *pAction = qobject_cast<QAction *> (sender());          QAction *pAction = qobject_cast<QAction *> (sender());
2770          if (pAction == NULL)          if (pAction == nullptr)
2771                  return;                  return;
2772    
2773          ChannelStrip *pChannelStrip = channelStripAt(pAction->data().toInt());          ChannelStrip *pChannelStrip = channelStripAt(pAction->data().toInt());
# Line 2586  void MainForm::channelsMenuActivated (vo Line 2779  void MainForm::channelsMenuActivated (vo
2779    
2780    
2781  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2782  // qsamplerMainForm -- Timer stuff.  // QSampler::MainForm -- Timer stuff.
2783    
2784  // Set the pseudo-timer delay schedule.  // Set the pseudo-timer delay schedule.
2785  void MainForm::startSchedule ( int iStartDelay )  void MainForm::startSchedule ( int iStartDelay )
# Line 2605  void MainForm::stopSchedule (void) Line 2798  void MainForm::stopSchedule (void)
2798  // Timer slot funtion.  // Timer slot funtion.
2799  void MainForm::timerSlot (void)  void MainForm::timerSlot (void)
2800  {  {
2801          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2802                  return;                  return;
2803    
2804          // 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 2627  void MainForm::timerSlot (void) Line 2820  void MainForm::timerSlot (void)
2820                          ChannelStrip *pChannelStrip = iter.next();                          ChannelStrip *pChannelStrip = iter.next();
2821                          // If successfull, remove from pending list...                          // If successfull, remove from pending list...
2822                          if (pChannelStrip->updateChannelInfo()) {                          if (pChannelStrip->updateChannelInfo()) {
2823                                  int iChannelStrip = m_changedStrips.indexOf(pChannelStrip);                                  const int iChannelStrip = m_changedStrips.indexOf(pChannelStrip);
2824                                  if (iChannelStrip >= 0)                                  if (iChannelStrip >= 0)
2825                                          m_changedStrips.removeAt(iChannelStrip);                                          m_changedStrips.removeAt(iChannelStrip);
2826                          }                          }
# Line 2638  void MainForm::timerSlot (void) Line 2831  void MainForm::timerSlot (void)
2831                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {
2832                                  m_iTimerSlot = 0;                                  m_iTimerSlot = 0;
2833                                  // Update the channel stream usage for each strip...                                  // Update the channel stream usage for each strip...
2834                                  QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();                                  const QList<QMdiSubWindow *>& wlist
2835                                  for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {                                          = m_pWorkspace->subWindowList();
2836                                          ChannelStrip *pChannelStrip = NULL;                                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2837                                          QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                                          ChannelStrip *pChannelStrip
2838                                          if (pMdiSubWindow)                                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
                                                 pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());  
2839                                          if (pChannelStrip && pChannelStrip->isVisible())                                          if (pChannelStrip && pChannelStrip->isVisible())
2840                                                  pChannelStrip->updateChannelUsage();                                                  pChannelStrip->updateChannelUsage();
2841                                  }                                  }
2842                          }                          }
2843                  }                  }
2844    
2845            #if CONFIG_LSCP_CLIENT_CONNECTION_LOST
2846                    // If we lost connection to server: Try to automatically reconnect if we
2847                    // did not start the server.
2848                    //
2849                    // TODO: If we started the server, then we might inform the user that
2850                    // the server probably crashed and asking user ONCE whether we should
2851                    // restart the server.
2852                    if (lscp_client_connection_lost(m_pClient) && !m_pServer)
2853                            startAutoReconnectClient();
2854            #endif // CONFIG_LSCP_CLIENT_CONNECTION_LOST
2855          }          }
2856    
2857          // Register the next timer slot.          // Register the next timer slot.
# Line 2657  void MainForm::timerSlot (void) Line 2860  void MainForm::timerSlot (void)
2860    
2861    
2862  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2863  // qsamplerMainForm -- Server stuff.  // QSampler::MainForm -- Server stuff.
2864    
2865  // Start linuxsampler server...  // Start linuxsampler server...
2866  void MainForm::startServer (void)  void MainForm::startServer (void)
2867  {  {
2868          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2869                  return;                  return;
2870    
2871          // Aren't already a client, are we?          // Aren't already a client, are we?
# Line 2672  void MainForm::startServer (void) Line 2875  void MainForm::startServer (void)
2875          // Is the server process instance still here?          // Is the server process instance still here?
2876          if (m_pServer) {          if (m_pServer) {
2877                  if (QMessageBox::warning(this,                  if (QMessageBox::warning(this,
2878                          QSAMPLER_TITLE ": " + tr("Warning"),                          tr("Warning"),
2879                          tr("Could not start the LinuxSampler server.\n\n"                          tr("Could not start the LinuxSampler server.\n\n"
2880                          "Maybe it is already started."),                          "Maybe it is already started."),
2881                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
# Line 2691  void MainForm::startServer (void) Line 2894  void MainForm::startServer (void)
2894    
2895          // OK. Let's build the startup process...          // OK. Let's build the startup process...
2896          m_pServer = new QProcess();          m_pServer = new QProcess();
2897          bForceServerStop = true;          m_bForceServerStop = true;
2898    
2899          // Setup stdout/stderr capture...          // Setup stdout/stderr capture...
2900  //      if (m_pOptions->bStdoutCapture) {          m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);
2901          #if QT_VERSION >= 0x040200          QObject::connect(m_pServer,
2902                  m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);                  SIGNAL(readyReadStandardOutput()),
2903          #endif                  SLOT(readServerStdout()));
2904                  QObject::connect(m_pServer,          QObject::connect(m_pServer,
2905                          SIGNAL(readyReadStandardOutput()),                  SIGNAL(readyReadStandardError()),
2906                          SLOT(readServerStdout()));                  SLOT(readServerStdout()));
                 QObject::connect(m_pServer,  
                         SIGNAL(readyReadStandardError()),  
                         SLOT(readServerStdout()));  
 //      }  
2907    
2908          // The unforgiveable signal communication...          // The unforgiveable signal communication...
2909          QObject::connect(m_pServer,          QObject::connect(m_pServer,
# Line 2739  void MainForm::startServer (void) Line 2938  void MainForm::startServer (void)
2938    
2939    
2940  // Stop linuxsampler server...  // Stop linuxsampler server...
2941  void MainForm::stopServer (bool bInteractive)  void MainForm::stopServer ( bool bInteractive )
2942  {  {
2943          // Stop client code.          // Stop client code.
2944          stopClient();          stopClient();
2945    
2946          if (m_pServer && bInteractive) {          if (m_pServer && bInteractive) {
2947                  if (QMessageBox::question(this,                  if (QMessageBox::question(this,
2948                          QSAMPLER_TITLE ": " + tr("The backend's fate ..."),                          tr("The backend's fate ..."),
2949                          tr("You have the option to keep the sampler backend (LinuxSampler)\n"                          tr("You have the option to keep the sampler backend (LinuxSampler)\n"
2950                          "running in the background. The sampler would continue to work\n"                          "running in the background. The sampler would continue to work\n"
2951                          "according to your current sampler session and you could alter the\n"                          "according to your current sampler session and you could alter the\n"
2952                          "sampler session at any time by relaunching QSampler.\n\n"                          "sampler session at any time by relaunching QSampler.\n\n"
2953                          "Do you want LinuxSampler to stop?"),                          "Do you want LinuxSampler to stop?"),
2954                          QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)                          QMessageBox::Yes | QMessageBox::No,
2955                  {                          QMessageBox::Yes) == QMessageBox::No) {
2956                          bForceServerStop = false;                          m_bForceServerStop = false;
2957                  }                  }
2958          }          }
2959    
2960            bool bGraceWait = true;
2961    
2962          // And try to stop server.          // And try to stop server.
2963          if (m_pServer && bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2964                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2965                  if (m_pServer->state() == QProcess::Running) {                  if (m_pServer->state() == QProcess::Running) {
2966                  #if defined(WIN32)                  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
2967                          // Try harder...                          // Try harder...
2968                          m_pServer->kill();                          m_pServer->kill();
2969                  #else                  #else
2970                          // Try softly...                          // Try softly...
2971                          m_pServer->terminate();                          m_pServer->terminate();
2972                            bool bFinished = m_pServer->waitForFinished(QSAMPLER_TIMER_MSECS * 1000);
2973                            if (bFinished) bGraceWait = false;
2974                  #endif                  #endif
2975                  }                  }
2976          }       // Do final processing anyway.          }       // Do final processing anyway.
2977          else processServerExit();          else processServerExit();
2978    
2979          // Give it some time to terminate gracefully and stabilize...          // Give it some time to terminate gracefully and stabilize...
2980          QTime t;          if (bGraceWait) {
2981          t.start();                  QElapsedTimer timer;
2982          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                  timer.start();
2983                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  while (timer.elapsed() < QSAMPLER_TIMER_MSECS)
2984                            QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2985            }
2986  }  }
2987    
2988    
# Line 2799  void MainForm::processServerExit (void) Line 3004  void MainForm::processServerExit (void)
3004          if (m_pMessages)          if (m_pMessages)
3005                  m_pMessages->flushStdoutBuffer();                  m_pMessages->flushStdoutBuffer();
3006    
3007          if (m_pServer && bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
3008                  if (m_pServer->state() != QProcess::NotRunning) {                  if (m_pServer->state() != QProcess::NotRunning) {
3009                          appendMessages(tr("Server is being forced..."));                          appendMessages(tr("Server is being forced..."));
3010                          // Force final server shutdown...                          // Force final server shutdown...
3011                          m_pServer->kill();                          m_pServer->kill();
3012                          // Give it some time to terminate gracefully and stabilize...                          // Give it some time to terminate gracefully and stabilize...
3013                          QTime t;                          QElapsedTimer timer;
3014                          t.start();                          timer.start();
3015                          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                          while (timer.elapsed() < QSAMPLER_TIMER_MSECS)
3016                                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
3017                  }                  }
3018                  // Force final server shutdown...                  // Force final server shutdown...
# Line 2815  void MainForm::processServerExit (void) Line 3020  void MainForm::processServerExit (void)
3020                          tr("Server was stopped with exit status %1.")                          tr("Server was stopped with exit status %1.")
3021                          .arg(m_pServer->exitStatus()));                          .arg(m_pServer->exitStatus()));
3022                  delete m_pServer;                  delete m_pServer;
3023                  m_pServer = NULL;                  m_pServer = nullptr;
3024          }          }
3025    
3026          // Again, make status visible stable.          // Again, make status visible stable.
# Line 2824  void MainForm::processServerExit (void) Line 3029  void MainForm::processServerExit (void)
3029    
3030    
3031  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
3032  // qsamplerMainForm -- Client stuff.  // QSampler::MainForm -- Client stuff.
3033    
3034  // The LSCP client callback procedure.  // The LSCP client callback procedure.
3035  lscp_status_t qsampler_client_callback ( lscp_client_t */*pClient*/,  lscp_status_t qsampler_client_callback ( lscp_client_t */*pClient*/,
3036          lscp_event_t event, const char *pchData, int cchData, void *pvData )          lscp_event_t event, const char *pchData, int cchData, void *pvData )
3037  {  {
3038          MainForm* pMainForm = (MainForm *) pvData;          MainForm* pMainForm = (MainForm *) pvData;
3039          if (pMainForm == NULL)          if (pMainForm == nullptr)
3040                  return LSCP_FAILED;                  return LSCP_FAILED;
3041    
3042          // ATTN: DO NOT EVER call any GUI code here,          // ATTN: DO NOT EVER call any GUI code here,
# Line 2845  lscp_status_t qsampler_client_callback ( Line 3050  lscp_status_t qsampler_client_callback (
3050    
3051    
3052  // Start our almighty client...  // Start our almighty client...
3053  bool MainForm::startClient (void)  bool MainForm::startClient (bool bReconnectOnly)
3054  {  {
3055          // Have it a setup?          // Have it a setup?
3056          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
3057                  return false;                  return false;
3058    
3059          // Aren't we already started, are we?          // Aren't we already started, are we?
# Line 2862  bool MainForm::startClient (void) Line 3067  bool MainForm::startClient (void)
3067          m_pClient = ::lscp_client_create(          m_pClient = ::lscp_client_create(
3068                  m_pOptions->sServerHost.toUtf8().constData(),                  m_pOptions->sServerHost.toUtf8().constData(),
3069                  m_pOptions->iServerPort, qsampler_client_callback, this);                  m_pOptions->iServerPort, qsampler_client_callback, this);
3070          if (m_pClient == NULL) {          if (m_pClient == nullptr) {
3071                  // Is this the first try?                  // Is this the first try?
3072                  // maybe we need to start a local server...                  // maybe we need to start a local server...
3073                  if ((m_pServer && m_pServer->state() == QProcess::Running)                  if ((m_pServer && m_pServer->state() == QProcess::Running)
3074                          || !m_pOptions->bServerStart) {                          || !m_pOptions->bServerStart || bReconnectOnly)
3075                          appendMessagesError(                  {
3076                                  tr("Could not connect to server as client.\n\nSorry."));                          // if this method is called from autoReconnectClient()
3077                            // then don't bother user with an error message...
3078                            if (!bReconnectOnly) {
3079                                    appendMessagesError(
3080                                            tr("Could not connect to server as client.\n\nSorry.")
3081                                    );
3082                            }
3083                  } else {                  } else {
3084                          startServer();                          startServer();
3085                  }                  }
# Line 2876  bool MainForm::startClient (void) Line 3087  bool MainForm::startClient (void)
3087                  stabilizeForm();                  stabilizeForm();
3088                  return false;                  return false;
3089          }          }
3090    
3091          // Just set receive timeout value, blindly.          // Just set receive timeout value, blindly.
3092          ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);          ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
3093          appendMessages(          appendMessages(
# Line 2931  bool MainForm::startClient (void) Line 3143  bool MainForm::startClient (void)
3143          if (!m_pOptions->sSessionFile.isEmpty()) {          if (!m_pOptions->sSessionFile.isEmpty()) {
3144                  // Just load the prabably startup session...                  // Just load the prabably startup session...
3145                  if (loadSessionFile(m_pOptions->sSessionFile)) {                  if (loadSessionFile(m_pOptions->sSessionFile)) {
3146                          m_pOptions->sSessionFile = QString::null;                          m_pOptions->sSessionFile = QString();
3147                          return true;                          return true;
3148                  }                  }
3149          }          }
# Line 2947  bool MainForm::startClient (void) Line 3159  bool MainForm::startClient (void)
3159  // Stop client...  // Stop client...
3160  void MainForm::stopClient (void)  void MainForm::stopClient (void)
3161  {  {
3162          if (m_pClient == NULL)          if (m_pClient == nullptr)
3163                  return;                  return;
3164    
3165          // Log prepare here.          // Log prepare here.
# Line 2979  void MainForm::stopClient (void) Line 3191  void MainForm::stopClient (void)
3191          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
3192          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);
3193          ::lscp_client_destroy(m_pClient);          ::lscp_client_destroy(m_pClient);
3194          m_pClient = NULL;          m_pClient = nullptr;
3195    
3196          // Hard-notify instrumnet and device configuration forms,          // Hard-notify instrumnet and device configuration forms,
3197          // if visible, that we're running out...          // if visible, that we're running out...
# Line 2996  void MainForm::stopClient (void) Line 3208  void MainForm::stopClient (void)
3208  }  }
3209    
3210    
3211    void MainForm::startAutoReconnectClient (void)
3212    {
3213            stopClient();
3214            appendMessages(tr("Trying to reconnect..."));
3215            QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(autoReconnectClient()));
3216    }
3217    
3218    
3219    void MainForm::autoReconnectClient (void)
3220    {
3221            const bool bSuccess = startClient(true);
3222            if (!bSuccess)
3223                    QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(autoReconnectClient()));
3224    }
3225    
3226    
3227  // Channel strip activation/selection.  // Channel strip activation/selection.
3228  void MainForm::activateStrip ( QMdiSubWindow *pMdiSubWindow )  void MainForm::activateStrip ( QMdiSubWindow *pMdiSubWindow )
3229  {  {
3230          ChannelStrip *pChannelStrip = NULL;          ChannelStrip *pChannelStrip = nullptr;
3231          if (pMdiSubWindow)          if (pMdiSubWindow)
3232                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
3233          if (pChannelStrip)          if (pChannelStrip)
# Line 3009  void MainForm::activateStrip ( QMdiSubWi Line 3237  void MainForm::activateStrip ( QMdiSubWi
3237  }  }
3238    
3239    
3240    // Channel toolbar orientation change.
3241    void MainForm::channelsToolbarOrientation ( Qt::Orientation orientation )
3242    {
3243    #ifdef CONFIG_VOLUME
3244            m_pVolumeSlider->setOrientation(orientation);
3245            if (orientation == Qt::Horizontal) {
3246                    m_pVolumeSlider->setMinimumHeight(24);
3247                    m_pVolumeSlider->setMaximumHeight(32);
3248                    m_pVolumeSlider->setMinimumWidth(120);
3249                    m_pVolumeSlider->setMaximumWidth(640);
3250                    m_pVolumeSpinBox->setMaximumWidth(64);
3251                    m_pVolumeSpinBox->setButtonSymbols(QSpinBox::UpDownArrows);
3252            } else {
3253                    m_pVolumeSlider->setMinimumHeight(120);
3254                    m_pVolumeSlider->setMaximumHeight(480);
3255                    m_pVolumeSlider->setMinimumWidth(24);
3256                    m_pVolumeSlider->setMaximumWidth(32);
3257                    m_pVolumeSpinBox->setMaximumWidth(32);
3258                    m_pVolumeSpinBox->setButtonSymbols(QSpinBox::NoButtons);
3259            }
3260    #endif
3261    }
3262    
3263    
3264  } // namespace QSampler  } // namespace QSampler
3265    
3266    

Legend:
Removed from v.2441  
changed lines
  Added in v.3760

  ViewVC Help
Powered by ViewVC