/[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 1803 by schoenebeck, Sun Dec 7 13:58:16 2008 UTC revision 3789 by capela, Thu Jun 11 19:26:44 2020 UTC
# Line 1  Line 1 
1  // qsamplerMainForm.cpp  // qsamplerMainForm.cpp
2  //  //
3  /****************************************************************************  /****************************************************************************
4     Copyright (C) 2004-2008, 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>
43    #include <QMdiSubWindow>
44    
45  #include <QApplication>  #include <QApplication>
 #include <QWorkspace>  
46  #include <QProcess>  #include <QProcess>
47  #include <QMessageBox>  #include <QMessageBox>
48    
# Line 56  Line 62 
62  #include <QTimer>  #include <QTimer>
63  #include <QDateTime>  #include <QDateTime>
64    
65    #include <QElapsedTimer>
66    
67  #ifdef HAVE_SIGNAL_H  #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
68  #include <signal.h>  #include <QMimeData>
69    #endif
70    
71    #if QT_VERSION < QT_VERSION_CHECK(4, 5, 0)
72    namespace Qt {
73    const WindowFlags WindowCloseButtonHint = WindowFlags(0x08000000);
74    }
75  #endif  #endif
76    
77  #ifdef CONFIG_LIBGIG  #ifdef CONFIG_LIBGIG
78  #include <gig.h>  #include <gig.h>
79  #endif  #endif
80    
81    // Deprecated QTextStreamFunctions/Qt namespaces workaround.
82    #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
83    #define endl    Qt::endl
84    #endif
85    
86  // Needed for lroundf()  // Needed for lroundf()
87  #include <math.h>  #include <math.h>
88    
# Line 80  static inline long lroundf ( float x ) Line 98  static inline long lroundf ( float x )
98    
99    
100  // All winsock apps needs this.  // All winsock apps needs this.
101  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
102  static WSADATA _wsaData;  static WSADATA _wsaData;
103    #undef HAVE_SIGNAL_H
104  #endif  #endif
105    
106    
107    //-------------------------------------------------------------------------
108    // LADISH Level 1 support stuff.
109    
110    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
111    
112    #include <QSocketNotifier>
113    
114    #include <unistd.h>
115    #include <sys/types.h>
116    #include <sys/socket.h>
117    #include <signal.h>
118    
119    // File descriptor for SIGUSR1 notifier.
120    static int g_fdSigusr1[2] = { -1, -1 };
121    
122    // Unix SIGUSR1 signal handler.
123    static void qsampler_sigusr1_handler ( int /* signo */ )
124    {
125            char c = 1;
126    
127            (::write(g_fdSigusr1[0], &c, sizeof(c)) > 0);
128    }
129    
130    // File descriptor for SIGTERM notifier.
131    static int g_fdSigterm[2] = { -1, -1 };
132    
133    // Unix SIGTERM signal handler.
134    static void qsampler_sigterm_handler ( int /* signo */ )
135    {
136            char c = 1;
137    
138            (::write(g_fdSigterm[0], &c, sizeof(c)) > 0);
139    }
140    
141    #endif  // HAVE_SIGNAL_H
142    
143    
144    //-------------------------------------------------------------------------
145    // QSampler -- namespace
146    
147    
148  namespace QSampler {  namespace QSampler {
149    
150  // Timer constant stuff.  // Timer constant stuff.
# Line 97  namespace QSampler { Line 157  namespace QSampler {
157  #define QSAMPLER_STATUS_SESSION 3       // Current session modification state.  #define QSAMPLER_STATUS_SESSION 3       // Current session modification state.
158    
159    
160  //-------------------------------------------------------------------------  // Specialties for thread-callback comunication.
161  // CustomEvent -- specialty for callback comunication.  #define QSAMPLER_LSCP_EVENT   QEvent::Type(QEvent::User + 1)
162    
 #define QSAMPLER_CUSTOM_EVENT   QEvent::Type(QEvent::User + 0)  
163    
164  class CustomEvent : public QEvent  //-------------------------------------------------------------------------
165    // QSampler::LscpEvent -- specialty for LSCP callback comunication.
166    
167    class LscpEvent : public QEvent
168  {  {
169  public:  public:
170    
171          // Constructor.          // Constructor.
172          CustomEvent(lscp_event_t event, const char *pchData, int cchData)          LscpEvent(lscp_event_t event, const char *pchData, int cchData)
173                  : QEvent(QSAMPLER_CUSTOM_EVENT)                  : QEvent(QSAMPLER_LSCP_EVENT)
174          {          {
175                  m_event = event;                  m_event = event;
176                  m_data  = QString::fromUtf8(pchData, cchData);                  m_data  = QString::fromUtf8(pchData, cchData);
177          }          }
178    
179          // Accessors.          // Accessors.
180          lscp_event_t event() { return m_event; }          lscp_event_t  event() { return m_event; }
181          QString&     data()  { return m_data;  }          const QString& data() { return m_data;  }
182    
183  private:  private:
184    
# Line 128  private: Line 190  private:
190    
191    
192  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
193  // qsamplerMainForm -- Main window form implementation.  // QSampler::Workspace -- Main window workspace (MDI Area) decl.
194    
195    class Workspace : public QMdiArea
196    {
197    public:
198    
199            Workspace(MainForm *pMainForm) : QMdiArea(pMainForm) {}
200    
201    protected:
202    
203            void resizeEvent(QResizeEvent *)
204            {
205                    MainForm *pMainForm = static_cast<MainForm *> (parentWidget());
206                    if (pMainForm)
207                            pMainForm->channelsArrangeAuto();
208            }
209    };
210    
211    
212    //-------------------------------------------------------------------------
213    // QSampler::MainForm -- Main window form implementation.
214    
215  // Kind of singleton reference.  // Kind of singleton reference.
216  MainForm* MainForm::g_pMainForm = NULL;  MainForm *MainForm::g_pMainForm = nullptr;
217    
218  MainForm::MainForm ( QWidget *pParent )  MainForm::MainForm ( QWidget *pParent )
219          : QMainWindow(pParent)          : QMainWindow(pParent)
# Line 142  MainForm::MainForm ( QWidget *pParent ) Line 224  MainForm::MainForm ( QWidget *pParent )
224          g_pMainForm = this;          g_pMainForm = this;
225    
226          // Initialize some pointer references.          // Initialize some pointer references.
227          m_pOptions = NULL;          m_pOptions = nullptr;
228    
229          // All child forms are to be created later, not earlier than setup.          // All child forms are to be created later, not earlier than setup.
230          m_pMessages = NULL;          m_pMessages = nullptr;
231          m_pInstrumentListForm = NULL;          m_pInstrumentListForm = nullptr;
232          m_pDeviceForm = NULL;          m_pDeviceForm = nullptr;
233    
234          // We'll start clean.          // We'll start clean.
235          m_iUntitled   = 0;          m_iUntitled   = 0;
236            m_iDirtySetup = 0;
237          m_iDirtyCount = 0;          m_iDirtyCount = 0;
238    
239          m_pServer = NULL;          m_pServer = nullptr;
240          m_pClient = NULL;          m_pClient = nullptr;
241    
242          m_iStartDelay = 0;          m_iStartDelay = 0;
243          m_iTimerDelay = 0;          m_iTimerDelay = 0;
244    
245          m_iTimerSlot = 0;          m_iTimerSlot = 0;
246    
247  #ifdef HAVE_SIGNAL_H  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
248    
249          // Set to ignore any fatal "Broken pipe" signals.          // Set to ignore any fatal "Broken pipe" signals.
250          ::signal(SIGPIPE, SIG_IGN);          ::signal(SIGPIPE, SIG_IGN);
251  #endif  
252            // LADISH Level 1 suport.
253    
254            // Initialize file descriptors for SIGUSR1 socket notifier.
255            ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigusr1);
256            m_pSigusr1Notifier
257                    = new QSocketNotifier(g_fdSigusr1[1], QSocketNotifier::Read, this);
258    
259            QObject::connect(m_pSigusr1Notifier,
260                    SIGNAL(activated(int)),
261                    SLOT(handle_sigusr1()));
262    
263            // Install SIGUSR1 signal handler.
264            struct sigaction sigusr1;
265            sigusr1.sa_handler = qsampler_sigusr1_handler;
266            sigemptyset(&sigusr1.sa_mask);
267            sigusr1.sa_flags = 0;
268            sigusr1.sa_flags |= SA_RESTART;
269            ::sigaction(SIGUSR1, &sigusr1, nullptr);
270    
271            // Initialize file descriptors for SIGTERM socket notifier.
272            ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigterm);
273            m_pSigtermNotifier
274                    = new QSocketNotifier(g_fdSigterm[1], QSocketNotifier::Read, this);
275    
276            QObject::connect(m_pSigtermNotifier,
277                    SIGNAL(activated(int)),
278                    SLOT(handle_sigterm()));
279    
280            // Install SIGTERM signal handler.
281            struct sigaction sigterm;
282            sigterm.sa_handler = qsampler_sigterm_handler;
283            sigemptyset(&sigterm.sa_mask);
284            sigterm.sa_flags = 0;
285            sigterm.sa_flags |= SA_RESTART;
286            ::sigaction(SIGTERM, &sigterm, nullptr);
287            ::sigaction(SIGQUIT, &sigterm, nullptr);
288    
289            // Ignore SIGHUP/SIGINT signals.
290            ::signal(SIGHUP, SIG_IGN);
291            ::signal(SIGINT, SIG_IGN);
292    
293    #else   // HAVE_SIGNAL_H
294    
295            m_pSigusr1Notifier = nullptr;
296            m_pSigtermNotifier = nullptr;
297            
298    #endif  // !HAVE_SIGNAL_H
299    
300  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
301          // Make some extras into the toolbar...          // Make some extras into the toolbar...
# Line 185  MainForm::MainForm ( QWidget *pParent ) Line 316  MainForm::MainForm ( QWidget *pParent )
316          QObject::connect(m_pVolumeSlider,          QObject::connect(m_pVolumeSlider,
317                  SIGNAL(valueChanged(int)),                  SIGNAL(valueChanged(int)),
318                  SLOT(volumeChanged(int)));                  SLOT(volumeChanged(int)));
         //m_ui.channelsToolbar->setHorizontallyStretchable(true);  
         //m_ui.channelsToolbar->setStretchableWidget(m_pVolumeSlider);  
319          m_ui.channelsToolbar->addWidget(m_pVolumeSlider);          m_ui.channelsToolbar->addWidget(m_pVolumeSlider);
320          // Volume spin-box          // Volume spin-box
321          m_ui.channelsToolbar->addSeparator();          m_ui.channelsToolbar->addSeparator();
322          m_pVolumeSpinBox = new QSpinBox(m_ui.channelsToolbar);          m_pVolumeSpinBox = new QSpinBox(m_ui.channelsToolbar);
         m_pVolumeSpinBox->setMaximumHeight(24);  
323          m_pVolumeSpinBox->setSuffix(" %");          m_pVolumeSpinBox->setSuffix(" %");
324          m_pVolumeSpinBox->setMinimum(0);          m_pVolumeSpinBox->setMinimum(0);
325          m_pVolumeSpinBox->setMaximum(100);          m_pVolumeSpinBox->setMaximum(100);
# Line 203  MainForm::MainForm ( QWidget *pParent ) Line 331  MainForm::MainForm ( QWidget *pParent )
331  #endif  #endif
332    
333          // Make it an MDI workspace.          // Make it an MDI workspace.
334          m_pWorkspace = new QWorkspace(this);          m_pWorkspace = new Workspace(this);
335          m_pWorkspace->setScrollBarsEnabled(true);          m_pWorkspace->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
336            m_pWorkspace->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
337          // Set the activation connection.          // Set the activation connection.
338          QObject::connect(m_pWorkspace,          QObject::connect(m_pWorkspace,
339                  SIGNAL(windowActivated(QWidget *)),                  SIGNAL(subWindowActivated(QMdiSubWindow *)),
340                  SLOT(activateStrip(QWidget *)));                  SLOT(activateStrip(QMdiSubWindow *)));
341          // Make it shine :-)          // Make it shine :-)
342          setCentralWidget(m_pWorkspace);          setCentralWidget(m_pWorkspace);
343    
# Line 237  MainForm::MainForm ( QWidget *pParent ) Line 366  MainForm::MainForm ( QWidget *pParent )
366          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
367          statusBar()->addWidget(pLabel);          statusBar()->addWidget(pLabel);
368    
369  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
370          WSAStartup(MAKEWORD(1, 1), &_wsaData);          WSAStartup(MAKEWORD(1, 1), &_wsaData);
371  #endif  #endif
372    
# Line 325  MainForm::MainForm ( QWidget *pParent ) Line 454  MainForm::MainForm ( QWidget *pParent )
454          QObject::connect(m_ui.channelsMenu,          QObject::connect(m_ui.channelsMenu,
455                  SIGNAL(aboutToShow()),                  SIGNAL(aboutToShow()),
456                  SLOT(channelsMenuAboutToShow()));                  SLOT(channelsMenuAboutToShow()));
457    #ifdef CONFIG_VOLUME
458            QObject::connect(m_ui.channelsToolbar,
459                    SIGNAL(orientationChanged(Qt::Orientation)),
460                    SLOT(channelsToolbarOrientation(Qt::Orientation)));
461    #endif
462  }  }
463    
464  // Destructor.  // Destructor.
# Line 333  MainForm::~MainForm() Line 467  MainForm::~MainForm()
467          // Do final processing anyway.          // Do final processing anyway.
468          processServerExit();          processServerExit();
469    
470  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
471          WSACleanup();          WSACleanup();
472  #endif  #endif
473    
474    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
475            if (m_pSigusr1Notifier)
476                    delete m_pSigusr1Notifier;
477            if (m_pSigtermNotifier)
478                    delete m_pSigtermNotifier;
479    #endif
480    
481          // Finally drop any widgets around...          // Finally drop any widgets around...
482          if (m_pDeviceForm)          if (m_pDeviceForm)
483                  delete m_pDeviceForm;                  delete m_pDeviceForm;
# Line 363  MainForm::~MainForm() Line 504  MainForm::~MainForm()
504  #endif  #endif
505    
506          // Pseudo-singleton reference shut-down.          // Pseudo-singleton reference shut-down.
507          g_pMainForm = NULL;          g_pMainForm = nullptr;
508  }  }
509    
510    
# Line 375  void MainForm::setup ( Options *pOptions Line 516  void MainForm::setup ( Options *pOptions
516    
517          // What style do we create these forms?          // What style do we create these forms?
518          Qt::WindowFlags wflags = Qt::Window          Qt::WindowFlags wflags = Qt::Window
 #if QT_VERSION >= 0x040200  
519                  | Qt::CustomizeWindowHint                  | Qt::CustomizeWindowHint
 #endif  
520                  | Qt::WindowTitleHint                  | Qt::WindowTitleHint
521                  | Qt::WindowSystemMenuHint                  | Qt::WindowSystemMenuHint
522                  | Qt::WindowMinMaxButtonsHint;                  | Qt::WindowMinMaxButtonsHint
523                    | Qt::WindowCloseButtonHint;
524          if (m_pOptions->bKeepOnTop)          if (m_pOptions->bKeepOnTop)
525                  wflags |= Qt::Tool;                  wflags |= Qt::Tool;
526    
527          // Some child forms are to be created right now.          // Some child forms are to be created right now.
528          m_pMessages = new Messages(this);          m_pMessages = new Messages(this);
529          m_pDeviceForm = new DeviceForm(this, wflags);          m_pDeviceForm = new DeviceForm(this, wflags);
530  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
531          m_pInstrumentListForm = new InstrumentListForm(this, wflags);          m_pInstrumentListForm = new InstrumentListForm(this, wflags);
532  #else  #else
533          viewInstrumentsAction->setEnabled(false);          m_ui.viewInstrumentsAction->setEnabled(false);
534  #endif  #endif
535    
536          // Setup messages logging appropriately...          // Setup messages logging appropriately...
537          m_pMessages->setLogging(          m_pMessages->setLogging(
538                  m_pOptions->bMessagesLog,                  m_pOptions->bMessagesLog,
539                  m_pOptions->sMessagesLogPath);                  m_pOptions->sMessagesLogPath);
540    
541          // Set message defaults...          // Set message defaults...
542          updateMessagesFont();          updateMessagesFont();
543          updateMessagesLimit();          updateMessagesLimit();
544          updateMessagesCapture();          updateMessagesCapture();
545    
546          // Set the visibility signal.          // Set the visibility signal.
547          QObject::connect(m_pMessages,          QObject::connect(m_pMessages,
548                  SIGNAL(visibilityChanged(bool)),                  SIGNAL(visibilityChanged(bool)),
# Line 425  void MainForm::setup ( Options *pOptions Line 569  void MainForm::setup ( Options *pOptions
569          }          }
570    
571          // Try to restore old window positioning and initial visibility.          // Try to restore old window positioning and initial visibility.
572          m_pOptions->loadWidgetGeometry(this);          m_pOptions->loadWidgetGeometry(this, true);
573          m_pOptions->loadWidgetGeometry(m_pInstrumentListForm);          m_pOptions->loadWidgetGeometry(m_pInstrumentListForm);
574          m_pOptions->loadWidgetGeometry(m_pDeviceForm);          m_pOptions->loadWidgetGeometry(m_pDeviceForm);
575    
# Line 464  bool MainForm::queryClose (void) Line 608  bool MainForm::queryClose (void)
608                                  || m_ui.channelsToolbar->isVisible());                                  || m_ui.channelsToolbar->isVisible());
609                          m_pOptions->bStatusbar = statusBar()->isVisible();                          m_pOptions->bStatusbar = statusBar()->isVisible();
610                          // Save the dock windows state.                          // Save the dock windows state.
                         const QString sDockables = saveState().toBase64().data();  
611                          m_pOptions->settings().setValue("/Layout/DockWindows", saveState());                          m_pOptions->settings().setValue("/Layout/DockWindows", saveState());
612                          // And the children, and the main windows state,.                          // And the children, and the main windows state,.
613                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);
614                          m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);                          m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
615                          m_pOptions->saveWidgetGeometry(this);                          m_pOptions->saveWidgetGeometry(this, true);
616                          // Close popup widgets.                          // Close popup widgets.
617                          if (m_pInstrumentListForm)                          if (m_pInstrumentListForm)
618                                  m_pInstrumentListForm->close();                                  m_pInstrumentListForm->close();
# Line 498  void MainForm::closeEvent ( QCloseEvent Line 641  void MainForm::closeEvent ( QCloseEvent
641  void MainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )  void MainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
642  {  {
643          // Accept external drags only...          // Accept external drags only...
644          if (pDragEnterEvent->source() == NULL          if (pDragEnterEvent->source() == nullptr
645                  && pDragEnterEvent->mimeData()->hasUrls()) {                  && pDragEnterEvent->mimeData()->hasUrls()) {
646                  pDragEnterEvent->accept();                  pDragEnterEvent->accept();
647          } else {          } else {
# Line 507  void MainForm::dragEnterEvent ( QDragEnt Line 650  void MainForm::dragEnterEvent ( QDragEnt
650  }  }
651    
652    
653  void MainForm::dropEvent ( QDropEvent* pDropEvent )  void MainForm::dropEvent ( QDropEvent *pDropEvent )
654  {  {
655          // Accept externally originated drops only...          // Accept externally originated drops only...
656          if (pDropEvent->source())          if (pDropEvent->source())
# Line 518  void MainForm::dropEvent ( QDropEvent* p Line 661  void MainForm::dropEvent ( QDropEvent* p
661                  QListIterator<QUrl> iter(pMimeData->urls());                  QListIterator<QUrl> iter(pMimeData->urls());
662                  while (iter.hasNext()) {                  while (iter.hasNext()) {
663                          const QString& sPath = iter.next().toLocalFile();                          const QString& sPath = iter.next().toLocalFile();
664                          if (Channel::isInstrumentFile(sPath)) {                  //      if (Channel::isDlsInstrumentFile(sPath)) {
665                            if (QFileInfo(sPath).exists()) {
666                                  // Try to create a new channel from instrument file...                                  // Try to create a new channel from instrument file...
667                                  Channel *pChannel = new Channel();                                  Channel *pChannel = new Channel();
668                                  if (pChannel == NULL)                                  if (pChannel == nullptr)
669                                          return;                                          return;
670                                  // Start setting the instrument filename...                                  // Start setting the instrument filename...
671                                  pChannel->setInstrument(sPath, 0);                                  pChannel->setInstrument(sPath, 0);
# Line 552  void MainForm::dropEvent ( QDropEvent* p Line 696  void MainForm::dropEvent ( QDropEvent* p
696    
697    
698  // Custome event handler.  // Custome event handler.
699  void MainForm::customEvent(QEvent* pCustomEvent)  void MainForm::customEvent ( QEvent* pEvent )
700  {  {
701          // For the time being, just pump it to messages.          // For the time being, just pump it to messages.
702          if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {          if (pEvent->type() == QSAMPLER_LSCP_EVENT) {
703                  CustomEvent *pEvent = static_cast<CustomEvent *> (pCustomEvent);                  LscpEvent *pLscpEvent = static_cast<LscpEvent *> (pEvent);
704                  switch (pEvent->event()) {                  switch (pLscpEvent->event()) {
705                          case LSCP_EVENT_CHANNEL_COUNT:                          case LSCP_EVENT_CHANNEL_COUNT:
706                                  updateAllChannelStrips(true);                                  updateAllChannelStrips(true);
707                                  break;                                  break;
708                          case LSCP_EVENT_CHANNEL_INFO: {                          case LSCP_EVENT_CHANNEL_INFO: {
709                                  int iChannelID = pEvent->data().toInt();                                  const int iChannelID = pLscpEvent->data().toInt();
710                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);
711                                  if (pChannelStrip)                                  if (pChannelStrip)
712                                          channelStripChanged(pChannelStrip);                                          channelStripChanged(pChannelStrip);
# Line 575  void MainForm::customEvent(QEvent* pCust Line 719  void MainForm::customEvent(QEvent* pCust
719                                  break;                                  break;
720                          case LSCP_EVENT_MIDI_INPUT_DEVICE_INFO: {                          case LSCP_EVENT_MIDI_INPUT_DEVICE_INFO: {
721                                  if (m_pDeviceForm) m_pDeviceForm->refreshDevices();                                  if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
722                                  const int iDeviceID = pEvent->data().section(' ', 0, 0).toInt();                                  const int iDeviceID = pLscpEvent->data().section(' ', 0, 0).toInt();
723                                  DeviceStatusForm::onDeviceChanged(iDeviceID);                                  DeviceStatusForm::onDeviceChanged(iDeviceID);
724                                  break;                                  break;
725                          }                          }
# Line 585  void MainForm::customEvent(QEvent* pCust Line 729  void MainForm::customEvent(QEvent* pCust
729                          case LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO:                          case LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO:
730                                  if (m_pDeviceForm) m_pDeviceForm->refreshDevices();                                  if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
731                                  break;                                  break;
732  #if CONFIG_EVENT_CHANNEL_MIDI                  #if CONFIG_EVENT_CHANNEL_MIDI
733                          case LSCP_EVENT_CHANNEL_MIDI: {                          case LSCP_EVENT_CHANNEL_MIDI: {
734                                  const int iChannelID = pEvent->data().section(' ', 0, 0).toInt();                                  const int iChannelID = pLscpEvent->data().section(' ', 0, 0).toInt();
735                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);
736                                  if (pChannelStrip)                                  if (pChannelStrip)
737                                          pChannelStrip->midiArrived();                                          pChannelStrip->midiActivityLedOn();
738                                  break;                                  break;
739                          }                          }
740  #endif                  #endif
741  #if CONFIG_EVENT_DEVICE_MIDI                  #if CONFIG_EVENT_DEVICE_MIDI
742                          case LSCP_EVENT_DEVICE_MIDI: {                          case LSCP_EVENT_DEVICE_MIDI: {
743                                  const int iDeviceID = pEvent->data().section(' ', 0, 0).toInt();                                  const int iDeviceID = pLscpEvent->data().section(' ', 0, 0).toInt();
744                                  const int iPortID   = pEvent->data().section(' ', 1, 1).toInt();                                  const int iPortID   = pLscpEvent->data().section(' ', 1, 1).toInt();
745                                  DeviceStatusForm* pDeviceStatusForm =                                  DeviceStatusForm *pDeviceStatusForm
746                                          DeviceStatusForm::getInstance(iDeviceID);                                          = DeviceStatusForm::getInstance(iDeviceID);
747                                  if (pDeviceStatusForm)                                  if (pDeviceStatusForm)
748                                          pDeviceStatusForm->midiArrived(iPortID);                                          pDeviceStatusForm->midiArrived(iPortID);
749                                  break;                                  break;
750                          }                          }
751  #endif                  #endif
752                          default:                          default:
753                                  appendMessagesColor(tr("Notify event: %1 data: %2")                                  appendMessagesColor(tr("LSCP Event: %1 data: %2")
754                                          .arg(::lscp_event_to_text(pEvent->event()))                                          .arg(::lscp_event_to_text(pLscpEvent->event()))
755                                          .arg(pEvent->data()), "#996699");                                          .arg(pLscpEvent->data()), "#996699");
756                  }                  }
757          }          }
758  }  }
759    
760  void MainForm::updateViewMidiDeviceStatusMenu() {  
761    // LADISH Level 1 -- SIGUSR1 signal handler.
762    void MainForm::handle_sigusr1 (void)
763    {
764    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
765    
766            char c;
767    
768            if (::read(g_fdSigusr1[1], &c, sizeof(c)) > 0)
769                    saveSession(false);
770    
771    #endif
772    }
773    
774    
775    void MainForm::handle_sigterm (void)
776    {
777    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
778    
779            char c;
780    
781            if (::read(g_fdSigterm[1], &c, sizeof(c)) > 0)
782                    close();
783    
784    #endif
785    }
786    
787    
788    void MainForm::updateViewMidiDeviceStatusMenu (void)
789    {
790          m_ui.viewMidiDeviceStatusMenu->clear();          m_ui.viewMidiDeviceStatusMenu->clear();
791          const std::map<int, DeviceStatusForm*> statusForms =          const std::map<int, DeviceStatusForm *> statusForms
792                  DeviceStatusForm::getInstances();                  = DeviceStatusForm::getInstances();
793          for (          std::map<int, DeviceStatusForm *>::const_iterator iter
794                  std::map<int, DeviceStatusForm*>::const_iterator iter = statusForms.begin();                  = statusForms.begin();
795                  iter != statusForms.end(); ++iter          for ( ; iter != statusForms.end(); ++iter) {
796          ) {                  DeviceStatusForm *pStatusForm = iter->second;
                 DeviceStatusForm* pForm = iter->second;  
797                  m_ui.viewMidiDeviceStatusMenu->addAction(                  m_ui.viewMidiDeviceStatusMenu->addAction(
798                          pForm->visibleAction()                          pStatusForm->visibleAction());
                 );  
799          }          }
800  }  }
801    
802    
803  // Context menu event handler.  // Context menu event handler.
804  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )
805  {  {
# Line 638  void MainForm::contextMenuEvent( QContex Line 810  void MainForm::contextMenuEvent( QContex
810    
811    
812  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
813  // qsamplerMainForm -- Brainless public property accessors.  // QSampler::MainForm -- Brainless public property accessors.
814    
815  // The global options settings property.  // The global options settings property.
816  Options *MainForm::options (void) const  Options *MainForm::options (void) const
# Line 662  MainForm *MainForm::getInstance (void) Line 834  MainForm *MainForm::getInstance (void)
834    
835    
836  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
837  // qsamplerMainForm -- Session file stuff.  // QSampler::MainForm -- Session file stuff.
838    
839  // Format the displayable session filename.  // Format the displayable session filename.
840  QString MainForm::sessionName ( const QString& sFilename )  QString MainForm::sessionName ( const QString& sFilename )
841  {  {
842          bool bCompletePath = (m_pOptions && m_pOptions->bCompletePath);          const bool bCompletePath = (m_pOptions && m_pOptions->bCompletePath);
843          QString sSessionName = sFilename;          QString sSessionName = sFilename;
844          if (sSessionName.isEmpty())          if (sSessionName.isEmpty())
845                  sSessionName = tr("Untitled") + QString::number(m_iUntitled);                  sSessionName = tr("Untitled") + QString::number(m_iUntitled);
# Line 691  bool MainForm::newSession (void) Line 863  bool MainForm::newSession (void)
863          m_iUntitled++;          m_iUntitled++;
864    
865          // Stabilize form.          // Stabilize form.
866          m_sFilename = QString::null;          m_sFilename = QString();
867          m_iDirtyCount = 0;          m_iDirtyCount = 0;
868          appendMessages(tr("New session: \"%1\".").arg(sessionName(m_sFilename)));          appendMessages(tr("New session: \"%1\".").arg(sessionName(m_sFilename)));
869          stabilizeForm();          stabilizeForm();
# Line 703  bool MainForm::newSession (void) Line 875  bool MainForm::newSession (void)
875  // Open an existing sampler session.  // Open an existing sampler session.
876  bool MainForm::openSession (void)  bool MainForm::openSession (void)
877  {  {
878          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
879                  return false;                  return false;
880    
881          // Ask for the filename to open...          // Ask for the filename to open...
882          QString sFilename = QFileDialog::getOpenFileName(this,          QString sFilename = QFileDialog::getOpenFileName(this,
883                  QSAMPLER_TITLE ": " + tr("Open Session"), // Caption.                  tr("Open Session"),                       // Caption.
884                  m_pOptions->sSessionDir,                  // Start here.                  m_pOptions->sSessionDir,                  // Start here.
885                  tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)                  tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)
886          );          );
# Line 729  bool MainForm::openSession (void) Line 901  bool MainForm::openSession (void)
901  // Save current sampler session with another name.  // Save current sampler session with another name.
902  bool MainForm::saveSession ( bool bPrompt )  bool MainForm::saveSession ( bool bPrompt )
903  {  {
904          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
905                  return false;                  return false;
906    
907          QString sFilename = m_sFilename;          QString sFilename = m_sFilename;
# Line 741  bool MainForm::saveSession ( bool bPromp Line 913  bool MainForm::saveSession ( bool bPromp
913                          sFilename = m_pOptions->sSessionDir;                          sFilename = m_pOptions->sSessionDir;
914                  // Prompt the guy...                  // Prompt the guy...
915                  sFilename = QFileDialog::getSaveFileName(this,                  sFilename = QFileDialog::getSaveFileName(this,
916                          QSAMPLER_TITLE ": " + tr("Save Session"), // Caption.                          tr("Save Session"),                       // Caption.
917                          sFilename,                                // Start here.                          sFilename,                                // Start here.
918                          tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)                          tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)
919                  );                  );
# Line 751  bool MainForm::saveSession ( bool bPromp Line 923  bool MainForm::saveSession ( bool bPromp
923                  // Enforce .lscp extension...                  // Enforce .lscp extension...
924                  if (QFileInfo(sFilename).suffix().isEmpty())                  if (QFileInfo(sFilename).suffix().isEmpty())
925                          sFilename += ".lscp";                          sFilename += ".lscp";
926            #if 0
927                  // Check if already exists...                  // Check if already exists...
928                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
929                          if (QMessageBox::warning(this,                          if (QMessageBox::warning(this,
930                                  QSAMPLER_TITLE ": " + tr("Warning"),                                  tr("Warning"),
931                                  tr("The file already exists:\n\n"                                  tr("The file already exists:\n\n"
932                                  "\"%1\"\n\n"                                  "\"%1\"\n\n"
933                                  "Do you want to replace it?")                                  "Do you want to replace it?")
934                                  .arg(sFilename),                                  .arg(sFilename),
935                                  tr("Replace"), tr("Cancel")) > 0)                                  QMessageBox::Yes | QMessageBox::No)
936                                    == QMessageBox::No)
937                                  return false;                                  return false;
938                  }                  }
939            #endif
940          }          }
941    
942          // Save it right away.          // Save it right away.
# Line 777  bool MainForm::closeSession ( bool bForc Line 952  bool MainForm::closeSession ( bool bForc
952          // Are we dirty enough to prompt it?          // Are we dirty enough to prompt it?
953          if (m_iDirtyCount > 0) {          if (m_iDirtyCount > 0) {
954                  switch (QMessageBox::warning(this,                  switch (QMessageBox::warning(this,
955                          QSAMPLER_TITLE ": " + tr("Warning"),                          tr("Warning"),
956                          tr("The current session has been changed:\n\n"                          tr("The current session has been changed:\n\n"
957                          "\"%1\"\n\n"                          "\"%1\"\n\n"
958                          "Do you want to save the changes?")                          "Do you want to save the changes?")
959                          .arg(sessionName(m_sFilename)),                          .arg(sessionName(m_sFilename)),
960                          tr("Save"), tr("Discard"), tr("Cancel"))) {                          QMessageBox::Save |
961                  case 0:     // Save...                          QMessageBox::Discard |
962                            QMessageBox::Cancel)) {
963                    case QMessageBox::Save:
964                          bClose = saveSession(false);                          bClose = saveSession(false);
965                          // Fall thru....                          // Fall thru....
966                  case 1:     // Discard                  case QMessageBox::Discard:
967                          break;                          break;
968                  default:    // Cancel.                  default:    // Cancel.
969                          bClose = false;                          bClose = false;
# Line 798  bool MainForm::closeSession ( bool bForc Line 975  bool MainForm::closeSession ( bool bForc
975          if (bClose) {          if (bClose) {
976                  // Remove all channel strips from sight...                  // Remove all channel strips from sight...
977                  m_pWorkspace->setUpdatesEnabled(false);                  m_pWorkspace->setUpdatesEnabled(false);
978                  QWidgetList wlist = m_pWorkspace->windowList();                  const QList<QMdiSubWindow *>& wlist
979                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                          = m_pWorkspace->subWindowList();
980                          ChannelStrip *pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
981                            ChannelStrip *pChannelStrip
982                                    = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
983                          if (pChannelStrip) {                          if (pChannelStrip) {
984                                  Channel *pChannel = pChannelStrip->channel();                                  Channel *pChannel = pChannelStrip->channel();
985                                  if (bForce && pChannel)                                  if (bForce && pChannel)
986                                          pChannel->removeChannel();                                          pChannel->removeChannel();
987                                  delete pChannelStrip;                                  delete pChannelStrip;
988                          }                          }
989                            delete pMdiSubWindow;
990                  }                  }
991                  m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
992                  // We're now clean, for sure.                  // We're now clean, for sure.
# Line 820  bool MainForm::closeSession ( bool bForc Line 1000  bool MainForm::closeSession ( bool bForc
1000  // Load a session from specific file path.  // Load a session from specific file path.
1001  bool MainForm::loadSessionFile ( const QString& sFilename )  bool MainForm::loadSessionFile ( const QString& sFilename )
1002  {  {
1003          if (m_pClient == NULL)          if (m_pClient == nullptr)
1004                  return false;                  return false;
1005    
1006          // Open and read from real file.          // Open and read from real file.
# Line 896  bool MainForm::loadSessionFile ( const Q Line 1076  bool MainForm::loadSessionFile ( const Q
1076  // Save current session to specific file path.  // Save current session to specific file path.
1077  bool MainForm::saveSessionFile ( const QString& sFilename )  bool MainForm::saveSessionFile ( const QString& sFilename )
1078  {  {
1079          if (m_pClient == NULL)          if (m_pClient == nullptr)
1080                  return false;                  return false;
1081    
1082          // Check whether server is apparently OK...          // Check whether server is apparently OK...
# Line 918  bool MainForm::saveSessionFile ( const Q Line 1098  bool MainForm::saveSessionFile ( const Q
1098          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1099    
1100          // Write the file.          // Write the file.
1101          int  iErrors = 0;          int iErrors = 0;
1102          QTextStream ts(&file);          QTextStream ts(&file);
1103          ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;          ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;
1104          ts << "# " << tr("Version")          ts << "# " << tr("Version") << ": " CONFIG_BUILD_VERSION << endl;
1105          << ": " QSAMPLER_VERSION << endl;  //      ts << "# " << tr("Build") << ": " CONFIG_BUILD_DATE << endl;
         ts << "# " << tr("Build")  
         << ": " __DATE__ " " __TIME__ << endl;  
1106          ts << "#"  << endl;          ts << "#"  << endl;
1107          ts << "# " << tr("File")          ts << "# " << tr("File")
1108          << ": " << QFileInfo(sFilename).fileName() << endl;          << ": " << QFileInfo(sFilename).fileName() << endl;
# Line 937  bool MainForm::saveSessionFile ( const Q Line 1115  bool MainForm::saveSessionFile ( const Q
1115          // It is assumed that this new kind of device+session file          // It is assumed that this new kind of device+session file
1116          // will be loaded from a complete initialized server...          // will be loaded from a complete initialized server...
1117          int *piDeviceIDs;          int *piDeviceIDs;
1118          int  iDevice;          int  i, iDevice;
1119          ts << "RESET" << endl;          ts << "RESET" << endl;
1120    
1121          // Audio device mapping.          // Audio device mapping.
1122          QMap<int, int> audioDeviceMap;          QMap<int, int> audioDeviceMap; iDevice = 0;
1123          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);
1124          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1125                  ts << endl;                  Device device(Device::Audio, piDeviceIDs[i]);
1126                  Device device(Device::Audio, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1127                    if (device.driverName().toUpper() == "PLUGIN")
1128                            continue;
1129                  // Audio device specification...                  // Audio device specification...
1130                    ts << endl;
1131                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1132                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1133                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
# Line 977  bool MainForm::saveSessionFile ( const Q Line 1158  bool MainForm::saveSessionFile ( const Q
1158                          iPort++;                          iPort++;
1159                  }                  }
1160                  // Audio device index/id mapping.                  // Audio device index/id mapping.
1161                  audioDeviceMap[device.deviceID()] = iDevice;                  audioDeviceMap.insert(device.deviceID(), iDevice++);
1162                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1163                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1164          }          }
1165    
1166          // MIDI device mapping.          // MIDI device mapping.
1167          QMap<int, int> midiDeviceMap;          QMap<int, int> midiDeviceMap; iDevice = 0;
1168          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);
1169          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1170                  ts << endl;                  Device device(Device::Midi, piDeviceIDs[i]);
1171                  Device device(Device::Midi, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1172                    if (device.driverName().toUpper() == "PLUGIN")
1173                            continue;
1174                  // MIDI device specification...                  // MIDI device specification...
1175                    ts << endl;
1176                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1177                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1178                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
# Line 1019  bool MainForm::saveSessionFile ( const Q Line 1203  bool MainForm::saveSessionFile ( const Q
1203                          iPort++;                          iPort++;
1204                  }                  }
1205                  // MIDI device index/id mapping.                  // MIDI device index/id mapping.
1206                  midiDeviceMap[device.deviceID()] = iDevice;                  midiDeviceMap.insert(device.deviceID(), iDevice++);
1207                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1208                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1209          }          }
# Line 1030  bool MainForm::saveSessionFile ( const Q Line 1214  bool MainForm::saveSessionFile ( const Q
1214          QMap<int, int> midiInstrumentMap;          QMap<int, int> midiInstrumentMap;
1215          int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);          int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);
1216          for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {          for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {
1217                  int iMidiMap = piMaps[iMap];                  const int iMidiMap = piMaps[iMap];
1218                  const char *pszMapName                  const char *pszMapName
1219                          = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);                          = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);
1220                  ts << "# " << tr("MIDI instrument map") << " " << iMap;                  ts << "# " << tr("MIDI instrument map") << " " << iMap;
# Line 1082  bool MainForm::saveSessionFile ( const Q Line 1266  bool MainForm::saveSessionFile ( const Q
1266                  }                  }
1267                  ts << endl;                  ts << endl;
1268                  // Check for errors...                  // Check for errors...
1269                  if (pInstrs == NULL && ::lscp_client_get_errno(m_pClient)) {                  if (pInstrs == nullptr && ::lscp_client_get_errno(m_pClient)) {
1270                          appendMessagesClient("lscp_list_midi_instruments");                          appendMessagesClient("lscp_list_midi_instruments");
1271                          iErrors++;                          iErrors++;
1272                  }                  }
1273                  // MIDI strument index/id mapping.                  // MIDI strument index/id mapping.
1274                  midiInstrumentMap[iMidiMap] = iMap;                  midiInstrumentMap.insert(iMidiMap, iMap);
1275          }          }
1276          // Check for errors...          // Check for errors...
1277          if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {          if (piMaps == nullptr && ::lscp_client_get_errno(m_pClient)) {
1278                  appendMessagesClient("lscp_list_midi_instrument_maps");                  appendMessagesClient("lscp_list_midi_instrument_maps");
1279                  iErrors++;                  iErrors++;
1280          }          }
1281  #endif  // CONFIG_MIDI_INSTRUMENT  #endif  // CONFIG_MIDI_INSTRUMENT
1282    
1283          // Sampler channel mapping.          // Sampler channel mapping...
1284          QWidgetList wlist = m_pWorkspace->windowList();          int iChannelID = 0;
1285          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          const QList<QMdiSubWindow *>& wlist
1286                  ChannelStrip* pChannelStrip                  = m_pWorkspace->subWindowList();
1287                          = static_cast<ChannelStrip *> (wlist.at(iChannel));          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
1288                    ChannelStrip *pChannelStrip
1289                            = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
1290                  if (pChannelStrip) {                  if (pChannelStrip) {
1291                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1292                          if (pChannel) {                          if (pChannel) {
1293                                  ts << "# " << tr("Channel") << " " << iChannel << endl;                                  // Avoid "artifial" plug-in devices...
1294                                    const int iAudioDevice = pChannel->audioDevice();
1295                                    if (!audioDeviceMap.contains(iAudioDevice))
1296                                            continue;
1297                                    const int iMidiDevice = pChannel->midiDevice();
1298                                    if (!midiDeviceMap.contains(iMidiDevice))
1299                                            continue;
1300                                    // Go for regular, canonical devices...
1301                                    ts << "# " << tr("Channel") << " " << iChannelID << endl;
1302                                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
1303                                  if (audioDeviceMap.isEmpty()) {                                  if (audioDeviceMap.isEmpty()) {
1304                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannelID
1305                                                  << " " << pChannel->audioDriver() << endl;                                                  << " " << pChannel->audioDriver() << endl;
1306                                  } else {                                  } else {
1307                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannelID
1308                                                  << " " << audioDeviceMap[pChannel->audioDevice()] << endl;                                                  << " " << audioDeviceMap.value(iAudioDevice) << endl;
1309                                  }                                  }
1310                                  if (midiDeviceMap.isEmpty()) {                                  if (midiDeviceMap.isEmpty()) {
1311                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannel                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID
1312                                                  << " " << pChannel->midiDriver() << endl;                                                  << " " << pChannel->midiDriver() << endl;
1313                                  } else {                                  } else {
1314                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannel                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannelID
1315                                                  << " " << midiDeviceMap[pChannel->midiDevice()] << endl;                                                  << " " << midiDeviceMap.value(iMidiDevice) << endl;
1316                                  }                                  }
1317                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID
1318                                          << " " << pChannel->midiPort() << endl;                                          << " " << pChannel->midiPort() << endl;
1319                                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";                                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannelID << " ";
1320                                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)                                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
1321                                          ts << "ALL";                                          ts << "ALL";
1322                                  else                                  else
1323                                          ts << pChannel->midiChannel();                                          ts << pChannel->midiChannel();
1324                                  ts << endl;                                  ts << endl;
1325                                  ts << "LOAD ENGINE " << pChannel->engineName()                                  ts << "LOAD ENGINE " << pChannel->engineName()
1326                                          << " " << iChannel << endl;                                          << " " << iChannelID << endl;
1327                                  if (pChannel->instrumentStatus() < 100) ts << "# ";                                  if (pChannel->instrumentStatus() < 100) ts << "# ";
1328                                  ts << "LOAD INSTRUMENT NON_MODAL '"                                  ts << "LOAD INSTRUMENT NON_MODAL '"
1329                                          << pChannel->instrumentFile() << "' "                                          << pChannel->instrumentFile() << "' "
1330                                          << pChannel->instrumentNr() << " " << iChannel << endl;                                          << pChannel->instrumentNr() << " " << iChannelID << endl;
1331                                  ChannelRoutingMap::ConstIterator audioRoute;                                  ChannelRoutingMap::ConstIterator audioRoute;
1332                                  for (audioRoute = pChannel->audioRouting().begin();                                  for (audioRoute = pChannel->audioRouting().begin();
1333                                                  audioRoute != pChannel->audioRouting().end();                                                  audioRoute != pChannel->audioRouting().end();
1334                                                          ++audioRoute) {                                                          ++audioRoute) {
1335                                          ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannelID
1336                                                  << " " << audioRoute.key()                                                  << " " << audioRoute.key()
1337                                                  << " " << audioRoute.value() << endl;                                                  << " " << audioRoute.value() << endl;
1338                                  }                                  }
1339                                  ts << "SET CHANNEL VOLUME " << iChannel                                  ts << "SET CHANNEL VOLUME " << iChannelID
1340                                          << " " << pChannel->volume() << endl;                                          << " " << pChannel->volume() << endl;
1341                                  if (pChannel->channelMute())                                  if (pChannel->channelMute())
1342                                          ts << "SET CHANNEL MUTE " << iChannel << " 1" << endl;                                          ts << "SET CHANNEL MUTE " << iChannelID << " 1" << endl;
1343                                  if (pChannel->channelSolo())                                  if (pChannel->channelSolo())
1344                                          ts << "SET CHANNEL SOLO " << iChannel << " 1" << endl;                                          ts << "SET CHANNEL SOLO " << iChannelID << " 1" << endl;
1345  #ifdef CONFIG_MIDI_INSTRUMENT                          #ifdef CONFIG_MIDI_INSTRUMENT
1346                                  if (pChannel->midiMap() >= 0) {                                  const int iMidiMap = pChannel->midiMap();
1347                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannel                                  if (midiInstrumentMap.contains(iMidiMap)) {
1348                                                  << " " << midiInstrumentMap[pChannel->midiMap()] << endl;                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannelID
1349                                                    << " " << midiInstrumentMap.value(iMidiMap) << endl;
1350                                  }                                  }
1351  #endif                          #endif
1352  #ifdef CONFIG_FXSEND                          #ifdef CONFIG_FXSEND
                                 int iChannelID = pChannel->channelID();  
1353                                  int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID);                                  int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID);
1354                                  for (int iFxSend = 0;                                  for (int iFxSend = 0;
1355                                                  piFxSends && piFxSends[iFxSend] >= 0;                                                  piFxSends && piFxSends[iFxSend] >= 0;
# Line 1163  bool MainForm::saveSessionFile ( const Q Line 1357  bool MainForm::saveSessionFile ( const Q
1357                                          lscp_fxsend_info_t *pFxSendInfo = ::lscp_get_fxsend_info(                                          lscp_fxsend_info_t *pFxSendInfo = ::lscp_get_fxsend_info(
1358                                                  m_pClient, iChannelID, piFxSends[iFxSend]);                                                  m_pClient, iChannelID, piFxSends[iFxSend]);
1359                                          if (pFxSendInfo) {                                          if (pFxSendInfo) {
1360                                                  ts << "CREATE FX_SEND " << iChannel                                                  ts << "CREATE FX_SEND " << iChannelID
1361                                                          << " " << pFxSendInfo->midi_controller;                                                          << " " << pFxSendInfo->midi_controller;
1362                                                  if (pFxSendInfo->name)                                                  if (pFxSendInfo->name)
1363                                                          ts << " '" << pFxSendInfo->name << "'";                                                          ts << " '" << pFxSendInfo->name << "'";
# Line 1173  bool MainForm::saveSessionFile ( const Q Line 1367  bool MainForm::saveSessionFile ( const Q
1367                                                                  piRouting && piRouting[iAudioSrc] >= 0;                                                                  piRouting && piRouting[iAudioSrc] >= 0;
1368                                                                          iAudioSrc++) {                                                                          iAudioSrc++) {
1369                                                          ts << "SET FX_SEND AUDIO_OUTPUT_CHANNEL "                                                          ts << "SET FX_SEND AUDIO_OUTPUT_CHANNEL "
1370                                                                  << iChannel                                                                  << iChannelID
1371                                                                  << " " << iFxSend                                                                  << " " << iFxSend
1372                                                                  << " " << iAudioSrc                                                                  << " " << iAudioSrc
1373                                                                  << " " << piRouting[iAudioSrc] << endl;                                                                  << " " << piRouting[iAudioSrc] << endl;
1374                                                  }                                                  }
1375  #ifdef CONFIG_FXSEND_LEVEL                                          #ifdef CONFIG_FXSEND_LEVEL
1376                                                  ts << "SET FX_SEND LEVEL " << iChannel                                                  ts << "SET FX_SEND LEVEL " << iChannelID
1377                                                          << " " << iFxSend                                                          << " " << iFxSend
1378                                                          << " " << pFxSendInfo->level << endl;                                                          << " " << pFxSendInfo->level << endl;
1379  #endif                                          #endif
1380                                          }       // Check for errors...                                          }       // Check for errors...
1381                                          else if (::lscp_client_get_errno(m_pClient)) {                                          else if (::lscp_client_get_errno(m_pClient)) {
1382                                                  appendMessagesClient("lscp_get_fxsend_info");                                                  appendMessagesClient("lscp_get_fxsend_info");
1383                                                  iErrors++;                                                  iErrors++;
1384                                          }                                          }
1385                                  }                                  }
1386  #endif                          #endif
1387                                  ts << endl;                                  ts << endl;
1388                                    // Go for next channel...
1389                                    ++iChannelID;
1390                          }                          }
1391                  }                  }
1392                  // Try to keep it snappy :)                  // Try to keep it snappy :)
# Line 1242  void MainForm::sessionDirty (void) Line 1438  void MainForm::sessionDirty (void)
1438    
1439    
1440  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1441  // qsamplerMainForm -- File Action slots.  // QSampler::MainForm -- File Action slots.
1442    
1443  // Create a new sampler session.  // Create a new sampler session.
1444  void MainForm::fileNew (void)  void MainForm::fileNew (void)
# Line 1266  void MainForm::fileOpenRecent (void) Line 1462  void MainForm::fileOpenRecent (void)
1462          // Retrive filename index from action data...          // Retrive filename index from action data...
1463          QAction *pAction = qobject_cast<QAction *> (sender());          QAction *pAction = qobject_cast<QAction *> (sender());
1464          if (pAction && m_pOptions) {          if (pAction && m_pOptions) {
1465                  int iIndex = pAction->data().toInt();                  const int iIndex = pAction->data().toInt();
1466                  if (iIndex >= 0 && iIndex < m_pOptions->recentFiles.count()) {                  if (iIndex >= 0 && iIndex < m_pOptions->recentFiles.count()) {
1467                          QString sFilename = m_pOptions->recentFiles[iIndex];                          QString sFilename = m_pOptions->recentFiles[iIndex];
1468                          // Check if we can safely close the current session...                          // Check if we can safely close the current session...
# Line 1296  void MainForm::fileSaveAs (void) Line 1492  void MainForm::fileSaveAs (void)
1492  // Reset the sampler instance.  // Reset the sampler instance.
1493  void MainForm::fileReset (void)  void MainForm::fileReset (void)
1494  {  {
1495          if (m_pClient == NULL)          if (m_pClient == nullptr)
1496                  return;                  return;
1497    
1498          // Ask user whether he/she want's an internal sampler reset...          // Ask user whether he/she want's an internal sampler reset...
1499          if (QMessageBox::warning(this,          if (m_pOptions && m_pOptions->bConfirmReset) {
1500                  QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sTitle = tr("Warning");
1501                  tr("Resetting the sampler instance will close\n"                  const QString& sText = tr(
1502                  "all device and channel configurations.\n\n"                          "Resetting the sampler instance will close\n"
1503                  "Please note that this operation may cause\n"                          "all device and channel configurations.\n\n"
1504                  "temporary MIDI and Audio disruption.\n\n"                          "Please note that this operation may cause\n"
1505                  "Do you want to reset the sampler engine now?"),                          "temporary MIDI and Audio disruption.\n\n"
1506                  tr("Reset"), tr("Cancel")) > 0)                          "Do you want to reset the sampler engine now?");
1507                  return;          #if 0
1508                    if (QMessageBox::warning(this, sTitle, sText,
1509                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1510                            return;
1511            #else
1512                    QMessageBox mbox(this);
1513                    mbox.setIcon(QMessageBox::Warning);
1514                    mbox.setWindowTitle(sTitle);
1515                    mbox.setText(sText);
1516                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1517                    QCheckBox cbox(tr("Don't ask this again"));
1518                    cbox.setChecked(false);
1519                    cbox.blockSignals(true);
1520                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1521                    if (mbox.exec() == QMessageBox::Cancel)
1522                            return;
1523                    if (cbox.isChecked())
1524                            m_pOptions->bConfirmReset = false;
1525            #endif
1526            }
1527    
1528          // Trye closing the current session, first...          // Trye closing the current session, first...
1529          if (!closeSession(true))          if (!closeSession(true))
# Line 1333  void MainForm::fileReset (void) Line 1548  void MainForm::fileReset (void)
1548  // Restart the client/server instance.  // Restart the client/server instance.
1549  void MainForm::fileRestart (void)  void MainForm::fileRestart (void)
1550  {  {
1551          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1552                  return;                  return;
1553    
1554          bool bRestart = true;          bool bRestart = true;
1555    
1556          // Ask user whether he/she want's a complete restart...          // Ask user whether he/she want's a complete restart...
1557          // (if we're currently up and running)          // (if we're currently up and running)
1558          if (bRestart && m_pClient) {          if (m_pOptions && m_pOptions->bConfirmRestart) {
1559                  bRestart = (QMessageBox::warning(this,                  const QString& sTitle = tr("Warning");
1560                          QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sText = tr(
1561                          tr("New settings will be effective after\n"                          "New settings will be effective after\n"
1562                          "restarting the client/server connection.\n\n"                          "restarting the client/server connection.\n\n"
1563                          "Please note that this operation may cause\n"                          "Please note that this operation may cause\n"
1564                          "temporary MIDI and Audio disruption.\n\n"                          "temporary MIDI and Audio disruption.\n\n"
1565                          "Do you want to restart the connection now?"),                          "Do you want to restart the connection now?");
1566                          tr("Restart"), tr("Cancel")) == 0);          #if 0
1567                    if (QMessageBox::warning(this, sTitle, sText,
1568                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1569                            bRestart = false;
1570            #else
1571                    QMessageBox mbox(this);
1572                    mbox.setIcon(QMessageBox::Warning);
1573                    mbox.setWindowTitle(sTitle);
1574                    mbox.setText(sText);
1575                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1576                    QCheckBox cbox(tr("Don't ask this again"));
1577                    cbox.setChecked(false);
1578                    cbox.blockSignals(true);
1579                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1580                    if (mbox.exec() == QMessageBox::Cancel)
1581                            bRestart = false;
1582                    else
1583                    if (cbox.isChecked())
1584                            m_pOptions->bConfirmRestart = false;
1585            #endif
1586          }          }
1587    
1588          // Are we still for it?          // Are we still for it?
# Line 1370  void MainForm::fileExit (void) Line 1604  void MainForm::fileExit (void)
1604    
1605    
1606  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1607  // qsamplerMainForm -- Edit Action slots.  // QSampler::MainForm -- Edit Action slots.
1608    
1609  // Add a new sampler channel.  // Add a new sampler channel.
1610  void MainForm::editAddChannel (void)  void MainForm::editAddChannel (void)
1611  {  {
1612          if (m_pClient == NULL)          ++m_iDirtySetup;
1613            addChannelStrip();
1614            --m_iDirtySetup;
1615    }
1616    
1617    void MainForm::addChannelStrip (void)
1618    {
1619            if (m_pClient == nullptr)
1620                  return;                  return;
1621    
1622          // Just create the channel instance...          // Just create the channel instance...
1623          Channel *pChannel = new Channel();          Channel *pChannel = new Channel();
1624          if (pChannel == NULL)          if (pChannel == nullptr)
1625                  return;                  return;
1626    
1627          // Before we show it up, may be we'll          // Before we show it up, may be we'll
# Line 1398  void MainForm::editAddChannel (void) Line 1639  void MainForm::editAddChannel (void)
1639          }          }
1640    
1641          // Do we auto-arrange?          // Do we auto-arrange?
1642          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
1643    
1644          // Make that an overall update.          // Make that an overall update.
1645          m_iDirtyCount++;          m_iDirtyCount++;
# Line 1410  void MainForm::editAddChannel (void) Line 1650  void MainForm::editAddChannel (void)
1650  // Remove current sampler channel.  // Remove current sampler channel.
1651  void MainForm::editRemoveChannel (void)  void MainForm::editRemoveChannel (void)
1652  {  {
1653          if (m_pClient == NULL)          ++m_iDirtySetup;
1654            removeChannelStrip();
1655            --m_iDirtySetup;
1656    }
1657    
1658    void MainForm::removeChannelStrip (void)
1659    {
1660            if (m_pClient == nullptr)
1661                  return;                  return;
1662    
1663          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1664          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1665                  return;                  return;
1666    
1667          Channel *pChannel = pChannelStrip->channel();          Channel *pChannel = pChannelStrip->channel();
1668          if (pChannel == NULL)          if (pChannel == nullptr)
1669                  return;                  return;
1670    
1671          // Prompt user if he/she's sure about this...          // Prompt user if he/she's sure about this...
1672          if (m_pOptions && m_pOptions->bConfirmRemove) {          if (m_pOptions && m_pOptions->bConfirmRemove) {
1673                  if (QMessageBox::warning(this,                  const QString& sTitle = tr("Warning");
1674                          QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sText = tr(
1675                          tr("About to remove channel:\n\n"                          "About to remove channel:\n\n"
1676                          "%1\n\n"                          "%1\n\n"
1677                          "Are you sure?")                          "Are you sure?")
1678                          .arg(pChannelStrip->windowTitle()),                          .arg(pChannelStrip->windowTitle());
1679                          tr("OK"), tr("Cancel")) > 0)          #if 0
1680                    if (QMessageBox::warning(this, sTitle, sText,
1681                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1682                            return;
1683            #else
1684                    QMessageBox mbox(this);
1685                    mbox.setIcon(QMessageBox::Warning);
1686                    mbox.setWindowTitle(sTitle);
1687                    mbox.setText(sText);
1688                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1689                    QCheckBox cbox(tr("Don't ask this again"));
1690                    cbox.setChecked(false);
1691                    cbox.blockSignals(true);
1692                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1693                    if (mbox.exec() == QMessageBox::Cancel)
1694                          return;                          return;
1695                    if (cbox.isChecked())
1696                            m_pOptions->bConfirmRemove = false;
1697            #endif
1698          }          }
1699    
1700          // Remove the existing sampler channel.          // Remove the existing sampler channel.
# Line 1438  void MainForm::editRemoveChannel (void) Line 1702  void MainForm::editRemoveChannel (void)
1702                  return;                  return;
1703    
1704          // Just delete the channel strip.          // Just delete the channel strip.
1705          delete pChannelStrip;          destroyChannelStrip(pChannelStrip);
   
         // Do we auto-arrange?  
         if (m_pOptions && m_pOptions->bAutoArrange)  
                 channelsArrange();  
1706    
1707          // We'll be dirty, for sure...          // We'll be dirty, for sure...
1708          m_iDirtyCount++;          m_iDirtyCount++;
# Line 1453  void MainForm::editRemoveChannel (void) Line 1713  void MainForm::editRemoveChannel (void)
1713  // Setup current sampler channel.  // Setup current sampler channel.
1714  void MainForm::editSetupChannel (void)  void MainForm::editSetupChannel (void)
1715  {  {
1716          if (m_pClient == NULL)          if (m_pClient == nullptr)
1717                  return;                  return;
1718    
1719          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1720          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1721                  return;                  return;
1722    
1723          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1468  void MainForm::editSetupChannel (void) Line 1728  void MainForm::editSetupChannel (void)
1728  // Edit current sampler channel.  // Edit current sampler channel.
1729  void MainForm::editEditChannel (void)  void MainForm::editEditChannel (void)
1730  {  {
1731          if (m_pClient == NULL)          if (m_pClient == nullptr)
1732                  return;                  return;
1733    
1734          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1735          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1736                  return;                  return;
1737    
1738          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1483  void MainForm::editEditChannel (void) Line 1743  void MainForm::editEditChannel (void)
1743  // Reset current sampler channel.  // Reset current sampler channel.
1744  void MainForm::editResetChannel (void)  void MainForm::editResetChannel (void)
1745  {  {
1746          if (m_pClient == NULL)          if (m_pClient == nullptr)
1747                  return;                  return;
1748    
1749          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1750          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
1751                  return;                  return;
1752    
1753          // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
# Line 1498  void MainForm::editResetChannel (void) Line 1758  void MainForm::editResetChannel (void)
1758  // Reset all sampler channels.  // Reset all sampler channels.
1759  void MainForm::editResetAllChannels (void)  void MainForm::editResetAllChannels (void)
1760  {  {
1761          if (m_pClient == NULL)          if (m_pClient == nullptr)
1762                  return;                  return;
1763    
1764          // Invoque the channel strip procedure,          // Invoque the channel strip procedure,
1765          // for all channels out there...          // for all channels out there...
1766          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1767          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
1768          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                  = m_pWorkspace->subWindowList();
1769                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
1770                    ChannelStrip *pChannelStrip
1771                            = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
1772                  if (pChannelStrip)                  if (pChannelStrip)
1773                          pChannelStrip->channelReset();                          pChannelStrip->channelReset();
1774          }          }
# Line 1515  void MainForm::editResetAllChannels (voi Line 1777  void MainForm::editResetAllChannels (voi
1777    
1778    
1779  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1780  // qsamplerMainForm -- View Action slots.  // QSampler::MainForm -- View Action slots.
1781    
1782  // Show/hide the main program window menubar.  // Show/hide the main program window menubar.
1783  void MainForm::viewMenubar ( bool bOn )  void MainForm::viewMenubar ( bool bOn )
# Line 1565  void MainForm::viewMessages ( bool bOn ) Line 1827  void MainForm::viewMessages ( bool bOn )
1827  // Show/hide the MIDI instrument list-view form.  // Show/hide the MIDI instrument list-view form.
1828  void MainForm::viewInstruments (void)  void MainForm::viewInstruments (void)
1829  {  {
1830          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1831                  return;                  return;
1832    
1833          if (m_pInstrumentListForm) {          if (m_pInstrumentListForm) {
# Line 1584  void MainForm::viewInstruments (void) Line 1846  void MainForm::viewInstruments (void)
1846  // Show/hide the device configurator form.  // Show/hide the device configurator form.
1847  void MainForm::viewDevices (void)  void MainForm::viewDevices (void)
1848  {  {
1849          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1850                  return;                  return;
1851    
1852          if (m_pDeviceForm) {          if (m_pDeviceForm) {
# Line 1603  void MainForm::viewDevices (void) Line 1865  void MainForm::viewDevices (void)
1865  // Show options dialog.  // Show options dialog.
1866  void MainForm::viewOptions (void)  void MainForm::viewOptions (void)
1867  {  {
1868          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
1869                  return;                  return;
1870    
1871          OptionsForm* pOptionsForm = new OptionsForm(this);          OptionsForm* pOptionsForm = new OptionsForm(this);
1872          if (pOptionsForm) {          if (pOptionsForm) {
1873                  // Check out some initial nullities(tm)...                  // Check out some initial nullities(tm)...
1874                  ChannelStrip* pChannelStrip = activeChannelStrip();                  ChannelStrip *pChannelStrip = activeChannelStrip();
1875                  if (m_pOptions->sDisplayFont.isEmpty() && pChannelStrip)                  if (m_pOptions->sDisplayFont.isEmpty() && pChannelStrip)
1876                          m_pOptions->sDisplayFont = pChannelStrip->displayFont().toString();                          m_pOptions->sDisplayFont = pChannelStrip->displayFont().toString();
1877                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)
1878                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();
1879                  // To track down deferred or immediate changes.                  // To track down deferred or immediate changes.
1880                  QString sOldServerHost      = m_pOptions->sServerHost;                  const QString sOldServerHost       = m_pOptions->sServerHost;
1881                  int     iOldServerPort      = m_pOptions->iServerPort;                  const int     iOldServerPort       = m_pOptions->iServerPort;
1882                  int     iOldServerTimeout   = m_pOptions->iServerTimeout;                  const int     iOldServerTimeout    = m_pOptions->iServerTimeout;
1883                  bool    bOldServerStart     = m_pOptions->bServerStart;                  const bool    bOldServerStart      = m_pOptions->bServerStart;
1884                  QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;                  const QString sOldServerCmdLine    = m_pOptions->sServerCmdLine;
1885                  bool    bOldMessagesLog     = m_pOptions->bMessagesLog;                  const bool    bOldMessagesLog      = m_pOptions->bMessagesLog;
1886                  QString sOldMessagesLogPath = m_pOptions->sMessagesLogPath;                  const QString sOldMessagesLogPath  = m_pOptions->sMessagesLogPath;
1887                  QString sOldDisplayFont     = m_pOptions->sDisplayFont;                  const QString sOldDisplayFont      = m_pOptions->sDisplayFont;
1888                  bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;                  const bool    bOldDisplayEffect    = m_pOptions->bDisplayEffect;
1889                  int     iOldMaxVolume       = m_pOptions->iMaxVolume;                  const int     iOldMaxVolume        = m_pOptions->iMaxVolume;
1890                  QString sOldMessagesFont    = m_pOptions->sMessagesFont;                  const QString sOldMessagesFont     = m_pOptions->sMessagesFont;
1891                  bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;                  const bool    bOldKeepOnTop        = m_pOptions->bKeepOnTop;
1892                  bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;                  const bool    bOldStdoutCapture    = m_pOptions->bStdoutCapture;
1893                  int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;                  const int     bOldMessagesLimit    = m_pOptions->bMessagesLimit;
1894                  int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;                  const int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1895                  bool    bOldCompletePath    = m_pOptions->bCompletePath;                  const bool    bOldCompletePath     = m_pOptions->bCompletePath;
1896                  bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;                  const bool    bOldInstrumentNames  = m_pOptions->bInstrumentNames;
1897                  int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;                  const int     iOldMaxRecentFiles   = m_pOptions->iMaxRecentFiles;
1898                  int     iOldBaseFontSize    = m_pOptions->iBaseFontSize;                  const int     iOldBaseFontSize     = m_pOptions->iBaseFontSize;
1899                    const QString sOldCustomStyleTheme = m_pOptions->sCustomStyleTheme;
1900                    const QString sOldCustomColorTheme = m_pOptions->sCustomColorTheme;
1901                  // Load the current setup settings.                  // Load the current setup settings.
1902                  pOptionsForm->setup(m_pOptions);                  pOptionsForm->setup(m_pOptions);
1903                  // Show the setup dialog...                  // Show the setup dialog...
1904                  if (pOptionsForm->exec()) {                  if (pOptionsForm->exec()) {
1905                          // Warn if something will be only effective on next run.                          // Warn if something will be only effective on next run.
1906                            int iNeedRestart = 0;
1907                          if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||                          if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1908                                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||                                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture)) {
1909                                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||                                  updateMessagesCapture();
1910                                    ++iNeedRestart;
1911                            }
1912                            if (( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1913                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)     ||                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)     ||
1914                                  (iOldBaseFontSize   !=  m_pOptions->iBaseFontSize)) {                                  (iOldBaseFontSize   !=  m_pOptions->iBaseFontSize)) {
1915                                  QMessageBox::information(this,                                  ++iNeedRestart;
1916                                          QSAMPLER_TITLE ": " + tr("Information"),                          }
1917                                          tr("Some settings may be only effective\n"                          // Check whether restart is needed or whether
1918                                          "next time you start this program."), tr("OK"));                          // custom options maybe set up immediately...
1919                                  updateMessagesCapture();                          if (m_pOptions->sCustomStyleTheme != sOldCustomStyleTheme) {
1920                                    if (m_pOptions->sCustomStyleTheme.isEmpty()) {
1921                                            ++iNeedRestart;
1922                                    } else {
1923                                            QApplication::setStyle(
1924                                                    QStyleFactory::create(m_pOptions->sCustomStyleTheme));
1925                                    }
1926                            }
1927                            if (m_pOptions->sCustomColorTheme != sOldCustomColorTheme) {
1928                                    if (m_pOptions->sCustomColorTheme.isEmpty()) {
1929                                            ++iNeedRestart;
1930                                    } else {
1931                                            QPalette pal;
1932                                            if (PaletteForm::namedPalette(
1933                                                            &m_pOptions->settings(), m_pOptions->sCustomColorTheme, pal))
1934                                                    QApplication::setPalette(pal);
1935                                    }
1936                          }                          }
1937                          // Check wheather something immediate has changed.                          // Check wheather something immediate has changed.
1938                          if (( bOldMessagesLog && !m_pOptions->bMessagesLog) ||                          if (( bOldMessagesLog && !m_pOptions->bMessagesLog) ||
# Line 1676  void MainForm::viewOptions (void) Line 1960  void MainForm::viewOptions (void)
1960                                  (!bOldMessagesLimit &&  m_pOptions->bMessagesLimit) ||                                  (!bOldMessagesLimit &&  m_pOptions->bMessagesLimit) ||
1961                                  (iOldMessagesLimitLines !=  m_pOptions->iMessagesLimitLines))                                  (iOldMessagesLimitLines !=  m_pOptions->iMessagesLimitLines))
1962                                  updateMessagesLimit();                                  updateMessagesLimit();
1963                            // Show restart needed message...
1964                            if (iNeedRestart > 0) {
1965                                    QMessageBox::information(this,
1966                                            tr("Information"),
1967                                            tr("Some settings may be only effective\n"
1968                                            "next time you start this program."));
1969                            }
1970                          // And now the main thing, whether we'll do client/server recycling?                          // And now the main thing, whether we'll do client/server recycling?
1971                          if ((sOldServerHost != m_pOptions->sServerHost) ||                          if ((sOldServerHost != m_pOptions->sServerHost) ||
1972                                  (iOldServerPort != m_pOptions->iServerPort) ||                                  (iOldServerPort != m_pOptions->iServerPort) ||
# Line 1696  void MainForm::viewOptions (void) Line 1987  void MainForm::viewOptions (void)
1987    
1988    
1989  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1990  // qsamplerMainForm -- Channels action slots.  // QSampler::MainForm -- Channels action slots.
1991    
1992  // Arrange channel strips.  // Arrange channel strips.
1993  void MainForm::channelsArrange (void)  void MainForm::channelsArrange (void)
1994  {  {
1995          // Full width vertical tiling          // Full width vertical tiling
1996          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
1997                    = m_pWorkspace->subWindowList();
1998          if (wlist.isEmpty())          if (wlist.isEmpty())
1999                  return;                  return;
2000    
2001          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2002          int y = 0;          int y = 0;
2003          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2004                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  pMdiSubWindow->adjustSize();
2005          /*  if (pChannelStrip->testWState(WState_Maximized | WState_Minimized)) {                  const QRect& frameRect
2006                          // Prevent flicker...                          = pMdiSubWindow->frameGeometry();
2007                          pChannelStrip->hide();                  int w = m_pWorkspace->width();
2008                          pChannelStrip->showNormal();                  if (w < frameRect.width())
2009                  }   */                          w = frameRect.width();
2010                  pChannelStrip->adjustSize();                  const int h = frameRect.height();
2011                  int iWidth  = m_pWorkspace->width();                  pMdiSubWindow->setGeometry(0, y, w, h);
2012                  if (iWidth < pChannelStrip->width())                  y += h;
                         iWidth = pChannelStrip->width();  
         //  int iHeight = pChannelStrip->height()  
         //              + pChannelStrip->parentWidget()->baseSize().height();  
                 int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();  
                 pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);  
                 y += iHeight;  
2013          }          }
2014          m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
2015    
# Line 1734  void MainForm::channelsArrange (void) Line 2020  void MainForm::channelsArrange (void)
2020  // Auto-arrange channel strips.  // Auto-arrange channel strips.
2021  void MainForm::channelsAutoArrange ( bool bOn )  void MainForm::channelsAutoArrange ( bool bOn )
2022  {  {
2023          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2024                  return;                  return;
2025    
2026          // Toggle the auto-arrange flag.          // Toggle the auto-arrange flag.
2027          m_pOptions->bAutoArrange = bOn;          m_pOptions->bAutoArrange = bOn;
2028    
2029          // If on, update whole workspace...          // If on, update whole workspace...
2030          if (m_pOptions->bAutoArrange)          channelsArrangeAuto();
2031    }
2032    
2033    
2034    void MainForm::channelsArrangeAuto (void)
2035    {
2036            if (m_pOptions && m_pOptions->bAutoArrange)
2037                  channelsArrange();                  channelsArrange();
2038  }  }
2039    
2040    
2041  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2042  // qsamplerMainForm -- Help Action slots.  // QSampler::MainForm -- Help Action slots.
2043    
2044  // Show information about the Qt toolkit.  // Show information about the Qt toolkit.
2045  void MainForm::helpAboutQt (void)  void MainForm::helpAboutQt (void)
# Line 1759  void MainForm::helpAboutQt (void) Line 2051  void MainForm::helpAboutQt (void)
2051  // Show information about application program.  // Show information about application program.
2052  void MainForm::helpAbout (void)  void MainForm::helpAbout (void)
2053  {  {
2054          // 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";  
2055  #ifdef CONFIG_DEBUG  #ifdef CONFIG_DEBUG
2056          sText += "<small><font color=\"red\">";          list << tr("Debugging option enabled.");
         sText += tr("Debugging option enabled.");  
         sText += "</font></small><br />";  
2057  #endif  #endif
2058  #ifndef CONFIG_LIBGIG  #ifndef CONFIG_LIBGIG
2059          sText += "<small><font color=\"red\">";          list << tr("GIG (libgig) file support disabled.");
         sText += tr("GIG (libgig) file support disabled.");  
         sText += "</font></small><br />";  
2060  #endif  #endif
2061  #ifndef CONFIG_INSTRUMENT_NAME  #ifndef CONFIG_INSTRUMENT_NAME
2062          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 />";  
2063  #endif  #endif
2064  #ifndef CONFIG_MUTE_SOLO  #ifndef CONFIG_MUTE_SOLO
2065          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 />";  
2066  #endif  #endif
2067  #ifndef CONFIG_AUDIO_ROUTING  #ifndef CONFIG_AUDIO_ROUTING
2068          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 />";  
2069  #endif  #endif
2070  #ifndef CONFIG_FXSEND  #ifndef CONFIG_FXSEND
2071          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 />";  
2072  #endif  #endif
2073  #ifndef CONFIG_VOLUME  #ifndef CONFIG_VOLUME
2074          sText += "<small><font color=\"red\">";          list << tr("Global volume support disabled.");
         sText += tr("Global volume support disabled.");  
         sText += "</font></small><br />";  
2075  #endif  #endif
2076  #ifndef CONFIG_MIDI_INSTRUMENT  #ifndef CONFIG_MIDI_INSTRUMENT
2077          sText += "<small><font color=\"red\">";          list << tr("MIDI instrument mapping support disabled.");
         sText += tr("MIDI instrument mapping support disabled.");  
         sText += "</font></small><br />";  
2078  #endif  #endif
2079  #ifndef CONFIG_EDIT_INSTRUMENT  #ifndef CONFIG_EDIT_INSTRUMENT
2080          sText += "<small><font color=\"red\">";          list << tr("Instrument editing support disabled.");
2081          sText += tr("Instrument editing support disabled.");  #endif
2082          sText += "</font></small><br />";  #ifndef CONFIG_EVENT_CHANNEL_MIDI
2083            list << tr("Channel MIDI event support disabled.");
2084  #endif  #endif
2085    #ifndef CONFIG_EVENT_DEVICE_MIDI
2086            list << tr("Device MIDI event support disabled.");
2087    #endif
2088    #ifndef CONFIG_MAX_VOICES
2089            list << tr("Runtime max. voices / disk streams support disabled.");
2090    #endif
2091    
2092            // Stuff the about box text...
2093            QString sText = "<p>\n";
2094            sText += "<b>" QSAMPLER_TITLE " - " + tr(QSAMPLER_SUBTITLE) + "</b><br />\n";
2095            sText += "<br />\n";
2096            sText += tr("Version") + ": <b>" CONFIG_BUILD_VERSION "</b><br />\n";
2097    //      sText += "<small>" + tr("Build") + ": " CONFIG_BUILD_DATE "</small><br />\n";
2098            if (!list.isEmpty()) {
2099                    sText += "<small><font color=\"red\">";
2100                    sText += list.join("<br />\n");
2101                    sText += "</font></small>";
2102            }
2103          sText += "<br />\n";          sText += "<br />\n";
2104          sText += tr("Using") + ": ";          sText += tr("Using") + ": ";
2105          sText += ::lscp_client_package();          sText += ::lscp_client_package();
# Line 1834  void MainForm::helpAbout (void) Line 2124  void MainForm::helpAbout (void)
2124          sText += "</small>";          sText += "</small>";
2125          sText += "</p>\n";          sText += "</p>\n";
2126    
2127          QMessageBox::about(this, tr("About") + " " QSAMPLER_TITLE, sText);          QMessageBox::about(this, tr("About"), sText);
2128  }  }
2129    
2130    
2131  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2132  // qsamplerMainForm -- Main window stabilization.  // QSampler::MainForm -- Main window stabilization.
2133    
2134  void MainForm::stabilizeForm (void)  void MainForm::stabilizeForm (void)
2135  {  {
# Line 1847  void MainForm::stabilizeForm (void) Line 2137  void MainForm::stabilizeForm (void)
2137          QString sSessionName = sessionName(m_sFilename);          QString sSessionName = sessionName(m_sFilename);
2138          if (m_iDirtyCount > 0)          if (m_iDirtyCount > 0)
2139                  sSessionName += " *";                  sSessionName += " *";
2140          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));          setWindowTitle(sSessionName);
2141    
2142          // Update the main menu state...          // Update the main menu state...
2143          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
2144          bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);          const QList<QMdiSubWindow *>& wlist = m_pWorkspace->subWindowList();
2145          bool bHasChannel = (bHasClient && pChannelStrip != NULL);          const bool bHasClient = (m_pOptions != nullptr && m_pClient != nullptr);
2146            const bool bHasChannel = (bHasClient && pChannelStrip != nullptr);
2147            const bool bHasChannels = (bHasClient && wlist.count() > 0);
2148          m_ui.fileNewAction->setEnabled(bHasClient);          m_ui.fileNewAction->setEnabled(bHasClient);
2149          m_ui.fileOpenAction->setEnabled(bHasClient);          m_ui.fileOpenAction->setEnabled(bHasClient);
2150          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
2151          m_ui.fileSaveAsAction->setEnabled(bHasClient);          m_ui.fileSaveAsAction->setEnabled(bHasClient);
2152          m_ui.fileResetAction->setEnabled(bHasClient);          m_ui.fileResetAction->setEnabled(bHasClient);
2153          m_ui.fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);          m_ui.fileRestartAction->setEnabled(bHasClient || m_pServer == nullptr);
2154          m_ui.editAddChannelAction->setEnabled(bHasClient);          m_ui.editAddChannelAction->setEnabled(bHasClient);
2155          m_ui.editRemoveChannelAction->setEnabled(bHasChannel);          m_ui.editRemoveChannelAction->setEnabled(bHasChannel);
2156          m_ui.editSetupChannelAction->setEnabled(bHasChannel);          m_ui.editSetupChannelAction->setEnabled(bHasChannel);
# Line 1868  void MainForm::stabilizeForm (void) Line 2160  void MainForm::stabilizeForm (void)
2160          m_ui.editEditChannelAction->setEnabled(false);          m_ui.editEditChannelAction->setEnabled(false);
2161  #endif  #endif
2162          m_ui.editResetChannelAction->setEnabled(bHasChannel);          m_ui.editResetChannelAction->setEnabled(bHasChannel);
2163          m_ui.editResetAllChannelsAction->setEnabled(bHasChannel);          m_ui.editResetAllChannelsAction->setEnabled(bHasChannels);
2164          m_ui.viewMessagesAction->setChecked(m_pMessages && m_pMessages->isVisible());          m_ui.viewMessagesAction->setChecked(m_pMessages && m_pMessages->isVisible());
2165  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
2166          m_ui.viewInstrumentsAction->setChecked(m_pInstrumentListForm          m_ui.viewInstrumentsAction->setChecked(m_pInstrumentListForm
# Line 1880  void MainForm::stabilizeForm (void) Line 2172  void MainForm::stabilizeForm (void)
2172          m_ui.viewDevicesAction->setChecked(m_pDeviceForm          m_ui.viewDevicesAction->setChecked(m_pDeviceForm
2173                  && m_pDeviceForm->isVisible());                  && m_pDeviceForm->isVisible());
2174          m_ui.viewDevicesAction->setEnabled(bHasClient);          m_ui.viewDevicesAction->setEnabled(bHasClient);
2175          m_ui.channelsArrangeAction->setEnabled(bHasChannel);          m_ui.viewMidiDeviceStatusMenu->setEnabled(
2176                    DeviceStatusForm::getInstances().size() > 0);
2177            m_ui.channelsArrangeAction->setEnabled(bHasChannels);
2178    
2179  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
2180          // Toolbar widgets are also affected...          // Toolbar widgets are also affected...
# Line 1930  void MainForm::volumeChanged ( int iVolu Line 2224  void MainForm::volumeChanged ( int iVolu
2224                  m_pVolumeSpinBox->setValue(iVolume);                  m_pVolumeSpinBox->setValue(iVolume);
2225    
2226          // Do it as commanded...          // Do it as commanded...
2227          float fVolume = 0.01f * float(iVolume);          const float fVolume = 0.01f * float(iVolume);
2228          if (::lscp_set_volume(m_pClient, fVolume) == LSCP_OK)          if (::lscp_set_volume(m_pClient, fVolume) == LSCP_OK)
2229                  appendMessages(QObject::tr("Volume: %1.").arg(fVolume));                  appendMessages(QObject::tr("Volume: %1.").arg(fVolume));
2230          else          else
# Line 1946  void MainForm::volumeChanged ( int iVolu Line 2240  void MainForm::volumeChanged ( int iVolu
2240    
2241    
2242  // Channel change receiver slot.  // Channel change receiver slot.
2243  void MainForm::channelStripChanged(ChannelStrip* pChannelStrip)  void MainForm::channelStripChanged ( ChannelStrip *pChannelStrip )
2244  {  {
2245          // Add this strip to the changed list...          // Add this strip to the changed list...
2246          if (!m_changedStrips.contains(pChannelStrip)) {          if (!m_changedStrips.contains(pChannelStrip)) {
# Line 1965  void MainForm::channelStripChanged(Chann Line 2259  void MainForm::channelStripChanged(Chann
2259  void MainForm::updateSession (void)  void MainForm::updateSession (void)
2260  {  {
2261  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
2262          int iVolume = ::lroundf(100.0f * ::lscp_get_volume(m_pClient));          const int iVolume = ::lroundf(100.0f * ::lscp_get_volume(m_pClient));
2263          m_iVolumeChanging++;          m_iVolumeChanging++;
2264          m_pVolumeSlider->setValue(iVolume);          m_pVolumeSlider->setValue(iVolume);
2265          m_pVolumeSpinBox->setValue(iVolume);          m_pVolumeSpinBox->setValue(iVolume);
# Line 1973  void MainForm::updateSession (void) Line 2267  void MainForm::updateSession (void)
2267  #endif  #endif
2268  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
2269          // FIXME: Make some room for default instrument maps...          // FIXME: Make some room for default instrument maps...
2270          int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);          const int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);
2271          if (iMaps < 0)          if (iMaps < 0)
2272                  appendMessagesClient("lscp_get_midi_instrument_maps");                  appendMessagesClient("lscp_get_midi_instrument_maps");
2273          else if (iMaps < 1) {          else if (iMaps < 1) {
# Line 1987  void MainForm::updateSession (void) Line 2281  void MainForm::updateSession (void)
2281          updateAllChannelStrips(false);          updateAllChannelStrips(false);
2282    
2283          // Do we auto-arrange?          // Do we auto-arrange?
2284          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
2285    
2286          // Remember to refresh devices and instruments...          // Remember to refresh devices and instruments...
2287          if (m_pInstrumentListForm)          if (m_pInstrumentListForm)
# Line 1997  void MainForm::updateSession (void) Line 2290  void MainForm::updateSession (void)
2290                  m_pDeviceForm->refreshDevices();                  m_pDeviceForm->refreshDevices();
2291  }  }
2292    
2293  void MainForm::updateAllChannelStrips(bool bRemoveDeadStrips) {  
2294    void MainForm::updateAllChannelStrips ( bool bRemoveDeadStrips )
2295    {
2296            // Skip if setting up a new channel strip...
2297            if (m_iDirtySetup > 0)
2298                    return;
2299    
2300          // Retrieve the current channel list.          // Retrieve the current channel list.
2301          int *piChannelIDs = ::lscp_list_channels(m_pClient);          int *piChannelIDs = ::lscp_list_channels(m_pClient);
2302          if (piChannelIDs == NULL) {          if (piChannelIDs == nullptr) {
2303                  if (::lscp_client_get_errno(m_pClient)) {                  if (::lscp_client_get_errno(m_pClient)) {
2304                          appendMessagesClient("lscp_list_channels");                          appendMessagesClient("lscp_list_channels");
2305                          appendMessagesError(                          appendMessagesError(
# Line 2009  void MainForm::updateAllChannelStrips(bo Line 2308  void MainForm::updateAllChannelStrips(bo
2308          } else {          } else {
2309                  // Try to (re)create each channel.                  // Try to (re)create each channel.
2310                  m_pWorkspace->setUpdatesEnabled(false);                  m_pWorkspace->setUpdatesEnabled(false);
2311                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {
2312                          // Check if theres already a channel strip for this one...                          // Check if theres already a channel strip for this one...
2313                          if (!channelStrip(piChannelIDs[iChannel]))                          if (!channelStrip(piChannelIDs[iChannel]))
2314                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));
2315                  }                  }
   
2316                  // Do we auto-arrange?                  // Do we auto-arrange?
2317                  if (m_pOptions && m_pOptions->bAutoArrange)                  channelsArrangeAuto();
                         channelsArrange();  
   
                 stabilizeForm();  
   
2318                  // remove dead channel strips                  // remove dead channel strips
2319                  if (bRemoveDeadStrips) {                  if (bRemoveDeadStrips) {
2320                          for (int i = 0; channelStripAt(i); ++i) {                          const QList<QMdiSubWindow *>& wlist
2321                                  ChannelStrip* pChannelStrip = channelStripAt(i);                                  = m_pWorkspace->subWindowList();
2322                                  bool bExists = false;                          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2323                                  for (int j = 0; piChannelIDs[j] >= 0; ++j) {                                  ChannelStrip *pChannelStrip
2324                                          if (!pChannelStrip->channel()) break;                                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2325                                          if (piChannelIDs[j] == pChannelStrip->channel()->channelID()) {                                  if (pChannelStrip) {
2326                                                  // strip exists, don't touch it                                          bool bExists = false;
2327                                                  bExists = true;                                          for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {
2328                                                  break;                                                  Channel *pChannel = pChannelStrip->channel();
2329                                                    if (pChannel == nullptr)
2330                                                            break;
2331                                                    if (piChannelIDs[iChannel] == pChannel->channelID()) {
2332                                                            // strip exists, don't touch it
2333                                                            bExists = true;
2334                                                            break;
2335                                                    }
2336                                          }                                          }
2337                                            if (!bExists)
2338                                                    destroyChannelStrip(pChannelStrip);
2339                                  }                                  }
                                 if (!bExists) destroyChannelStrip(pChannelStrip);  
2340                          }                          }
2341                  }                  }
2342                  m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
2343          }          }
2344    
2345            stabilizeForm();
2346  }  }
2347    
2348    
2349  // Update the recent files list and menu.  // Update the recent files list and menu.
2350  void MainForm::updateRecentFiles ( const QString& sFilename )  void MainForm::updateRecentFiles ( const QString& sFilename )
2351  {  {
2352          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2353                  return;                  return;
2354    
2355          // Remove from list if already there (avoid duplicates)          // Remove from list if already there (avoid duplicates)
2356          int iIndex = m_pOptions->recentFiles.indexOf(sFilename);          const int iIndex = m_pOptions->recentFiles.indexOf(sFilename);
2357          if (iIndex >= 0)          if (iIndex >= 0)
2358                  m_pOptions->recentFiles.removeAt(iIndex);                  m_pOptions->recentFiles.removeAt(iIndex);
2359          // Put it to front...          // Put it to front...
# Line 2059  void MainForm::updateRecentFiles ( const Line 2364  void MainForm::updateRecentFiles ( const
2364  // Update the recent files list and menu.  // Update the recent files list and menu.
2365  void MainForm::updateRecentFilesMenu (void)  void MainForm::updateRecentFilesMenu (void)
2366  {  {
2367          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2368                  return;                  return;
2369    
2370          // Time to keep the list under limits.          // Time to keep the list under limits.
# Line 2087  void MainForm::updateRecentFilesMenu (vo Line 2392  void MainForm::updateRecentFilesMenu (vo
2392  void MainForm::updateInstrumentNames (void)  void MainForm::updateInstrumentNames (void)
2393  {  {
2394          // Full channel list update...          // Full channel list update...
2395          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2396                    = m_pWorkspace->subWindowList();
2397          if (wlist.isEmpty())          if (wlist.isEmpty())
2398                  return;                  return;
2399    
2400          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2401          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2402                  ChannelStrip *pChannelStrip = (ChannelStrip *) wlist.at(iChannel);                  ChannelStrip *pChannelStrip
2403                            = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2404                  if (pChannelStrip)                  if (pChannelStrip)
2405                          pChannelStrip->updateInstrumentName(true);                          pChannelStrip->updateInstrumentName(true);
2406          }          }
# Line 2104  void MainForm::updateInstrumentNames (vo Line 2411  void MainForm::updateInstrumentNames (vo
2411  // Force update of the channels display font.  // Force update of the channels display font.
2412  void MainForm::updateDisplayFont (void)  void MainForm::updateDisplayFont (void)
2413  {  {
2414          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2415                  return;                  return;
2416    
2417          // Check if display font is legal.          // Check if display font is legal.
2418          if (m_pOptions->sDisplayFont.isEmpty())          if (m_pOptions->sDisplayFont.isEmpty())
2419                  return;                  return;
2420    
2421          // Realize it.          // Realize it.
2422          QFont font;          QFont font;
2423          if (!font.fromString(m_pOptions->sDisplayFont))          if (!font.fromString(m_pOptions->sDisplayFont))
2424                  return;                  return;
2425    
2426          // Full channel list update...          // Full channel list update...
2427          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2428                    = m_pWorkspace->subWindowList();
2429          if (wlist.isEmpty())          if (wlist.isEmpty())
2430                  return;                  return;
2431    
2432          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2433          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2434                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  ChannelStrip *pChannelStrip
2435                            = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2436                  if (pChannelStrip)                  if (pChannelStrip)
2437                          pChannelStrip->setDisplayFont(font);                          pChannelStrip->setDisplayFont(font);
2438          }          }
# Line 2134  void MainForm::updateDisplayFont (void) Line 2444  void MainForm::updateDisplayFont (void)
2444  void MainForm::updateDisplayEffect (void)  void MainForm::updateDisplayEffect (void)
2445  {  {
2446          // Full channel list update...          // Full channel list update...
2447          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2448                    = m_pWorkspace->subWindowList();
2449          if (wlist.isEmpty())          if (wlist.isEmpty())
2450                  return;                  return;
2451    
2452          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2453          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2454                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  ChannelStrip *pChannelStrip
2455                            = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2456                  if (pChannelStrip)                  if (pChannelStrip)
2457                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2458          }          }
# Line 2151  void MainForm::updateDisplayEffect (void Line 2463  void MainForm::updateDisplayEffect (void
2463  // Force update of the channels maximum volume setting.  // Force update of the channels maximum volume setting.
2464  void MainForm::updateMaxVolume (void)  void MainForm::updateMaxVolume (void)
2465  {  {
2466          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2467                  return;                  return;
2468    
2469  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
# Line 2162  void MainForm::updateMaxVolume (void) Line 2474  void MainForm::updateMaxVolume (void)
2474  #endif  #endif
2475    
2476          // Full channel list update...          // Full channel list update...
2477          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2478                    = m_pWorkspace->subWindowList();
2479          if (wlist.isEmpty())          if (wlist.isEmpty())
2480                  return;                  return;
2481    
2482          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2483          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2484                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  ChannelStrip *pChannelStrip
2485                            = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2486                  if (pChannelStrip)                  if (pChannelStrip)
2487                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2488          }          }
# Line 2177  void MainForm::updateMaxVolume (void) Line 2491  void MainForm::updateMaxVolume (void)
2491    
2492    
2493  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2494  // qsamplerMainForm -- Messages window form handlers.  // QSampler::MainForm -- Messages window form handlers.
2495    
2496  // Messages output methods.  // Messages output methods.
2497  void MainForm::appendMessages( const QString& s )  void MainForm::appendMessages ( const QString& s )
2498  {  {
2499          if (m_pMessages)          if (m_pMessages)
2500                  m_pMessages->appendMessages(s);                  m_pMessages->appendMessages(s);
# Line 2188  void MainForm::appendMessages( const QSt Line 2502  void MainForm::appendMessages( const QSt
2502          statusBar()->showMessage(s, 3000);          statusBar()->showMessage(s, 3000);
2503  }  }
2504    
2505  void MainForm::appendMessagesColor( const QString& s, const QString& c )  void MainForm::appendMessagesColor ( const QString& s, const QColor& rgb )
2506  {  {
2507          if (m_pMessages)          if (m_pMessages)
2508                  m_pMessages->appendMessagesColor(s, c);                  m_pMessages->appendMessagesColor(s, rgb);
2509    
2510          statusBar()->showMessage(s, 3000);          statusBar()->showMessage(s, 3000);
2511  }  }
2512    
2513  void MainForm::appendMessagesText( const QString& s )  void MainForm::appendMessagesText ( const QString& s )
2514  {  {
2515          if (m_pMessages)          if (m_pMessages)
2516                  m_pMessages->appendMessagesText(s);                  m_pMessages->appendMessagesText(s);
2517  }  }
2518    
2519  void MainForm::appendMessagesError( const QString& s )  void MainForm::appendMessagesError ( const QString& s )
2520  {  {
2521          if (m_pMessages)          if (m_pMessages)
2522                  m_pMessages->show();                  m_pMessages->show();
2523    
2524          appendMessagesColor(s.simplified(), "#ff0000");          appendMessagesColor(s.simplified(), Qt::red);
2525    
2526          // Make it look responsive...:)          // Make it look responsive...:)
2527          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2528    
2529          QMessageBox::critical(this,          if (m_pOptions && m_pOptions->bConfirmError) {
2530                  QSAMPLER_TITLE ": " + tr("Error"), s, tr("Cancel"));                  const QString& sTitle = tr("Error");
2531            #if 0
2532                    QMessageBox::critical(this, sTitle, sText, QMessageBox::Cancel);
2533            #else
2534                    QMessageBox mbox(this);
2535                    mbox.setIcon(QMessageBox::Critical);
2536                    mbox.setWindowTitle(sTitle);
2537                    mbox.setText(s);
2538                    mbox.setStandardButtons(QMessageBox::Cancel);
2539                    QCheckBox cbox(tr("Don't show this again"));
2540                    cbox.setChecked(false);
2541                    cbox.blockSignals(true);
2542                    mbox.addButton(&cbox, QMessageBox::ActionRole);
2543                    if (mbox.exec() && cbox.isChecked())
2544                            m_pOptions->bConfirmError = false;
2545            #endif
2546            }
2547  }  }
2548    
2549    
2550  // This is a special message format, just for client results.  // This is a special message format, just for client results.
2551  void MainForm::appendMessagesClient( const QString& s )  void MainForm::appendMessagesClient( const QString& s )
2552  {  {
2553          if (m_pClient == NULL)          if (m_pClient == nullptr)
2554                  return;                  return;
2555    
2556          appendMessagesColor(s + QString(": %1 (errno=%2)")          appendMessagesColor(s + QString(": %1 (errno=%2)")
# Line 2235  void MainForm::appendMessagesClient( con Line 2565  void MainForm::appendMessagesClient( con
2565  // Force update of the messages font.  // Force update of the messages font.
2566  void MainForm::updateMessagesFont (void)  void MainForm::updateMessagesFont (void)
2567  {  {
2568          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2569                  return;                  return;
2570    
2571          if (m_pMessages && !m_pOptions->sMessagesFont.isEmpty()) {          if (m_pMessages && !m_pOptions->sMessagesFont.isEmpty()) {
# Line 2249  void MainForm::updateMessagesFont (void) Line 2579  void MainForm::updateMessagesFont (void)
2579  // Update messages window line limit.  // Update messages window line limit.
2580  void MainForm::updateMessagesLimit (void)  void MainForm::updateMessagesLimit (void)
2581  {  {
2582          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2583                  return;                  return;
2584    
2585          if (m_pMessages) {          if (m_pMessages) {
# Line 2264  void MainForm::updateMessagesLimit (void Line 2594  void MainForm::updateMessagesLimit (void
2594  // Enablement of the messages capture feature.  // Enablement of the messages capture feature.
2595  void MainForm::updateMessagesCapture (void)  void MainForm::updateMessagesCapture (void)
2596  {  {
2597          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2598                  return;                  return;
2599    
2600          if (m_pMessages)          if (m_pMessages)
# Line 2273  void MainForm::updateMessagesCapture (vo Line 2603  void MainForm::updateMessagesCapture (vo
2603    
2604    
2605  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2606  // qsamplerMainForm -- MDI channel strip management.  // QSampler::MainForm -- MDI channel strip management.
2607    
2608  // The channel strip creation executive.  // The channel strip creation executive.
2609  ChannelStrip* MainForm::createChannelStrip ( Channel *pChannel )  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )
2610  {  {
2611          if (m_pClient == NULL || pChannel == NULL)          if (m_pClient == nullptr || pChannel == nullptr)
2612                  return NULL;                  return nullptr;
2613    
2614          // Add a new channel itema...          // Add a new channel itema...
2615          ChannelStrip *pChannelStrip = new ChannelStrip();          ChannelStrip *pChannelStrip = new ChannelStrip();
2616          if (pChannelStrip == NULL)          if (pChannelStrip == nullptr)
2617                  return NULL;                  return nullptr;
2618    
2619          // Set some initial channel strip options...          // Set some initial channel strip options...
2620          if (m_pOptions) {          if (m_pOptions) {
# Line 2292  ChannelStrip* MainForm::createChannelStr Line 2622  ChannelStrip* MainForm::createChannelStr
2622                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2623                  // We'll need a display font.                  // We'll need a display font.
2624                  QFont font;                  QFont font;
2625                  if (font.fromString(m_pOptions->sDisplayFont))                  if (!m_pOptions->sDisplayFont.isEmpty() &&
2626                            font.fromString(m_pOptions->sDisplayFont))
2627                          pChannelStrip->setDisplayFont(font);                          pChannelStrip->setDisplayFont(font);
2628                  // Maximum allowed volume setting.                  // Maximum allowed volume setting.
2629                  pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                  pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2630          }          }
2631    
2632          // Add it to workspace...          // Add it to workspace...
2633          m_pWorkspace->addWindow(pChannelStrip, Qt::FramelessWindowHint);          QMdiSubWindow *pMdiSubWindow
2634                    = m_pWorkspace->addSubWindow(pChannelStrip,
2635                            Qt::SubWindow | Qt::FramelessWindowHint);
2636            pMdiSubWindow->setAttribute(Qt::WA_DeleteOnClose);
2637    
2638          // Actual channel strip setup...          // Actual channel strip setup...
2639          pChannelStrip->setup(pChannel);          pChannelStrip->setup(pChannel);
2640    
2641          QObject::connect(pChannelStrip,          QObject::connect(pChannelStrip,
2642                  SIGNAL(channelChanged(ChannelStrip*)),                  SIGNAL(channelChanged(ChannelStrip *)),
2643                  SLOT(channelStripChanged(ChannelStrip*)));                  SLOT(channelStripChanged(ChannelStrip *)));
2644    
2645          // Now we show up us to the world.          // Now we show up us to the world.
2646          pChannelStrip->show();          pChannelStrip->show();
# Line 2318  ChannelStrip* MainForm::createChannelStr Line 2652  ChannelStrip* MainForm::createChannelStr
2652          return pChannelStrip;          return pChannelStrip;
2653  }  }
2654    
2655  void MainForm::destroyChannelStrip(ChannelStrip* pChannelStrip) {  
2656    void MainForm::destroyChannelStrip ( ChannelStrip *pChannelStrip )
2657    {
2658            QMdiSubWindow *pMdiSubWindow
2659                    = static_cast<QMdiSubWindow *> (pChannelStrip->parentWidget());
2660            if (pMdiSubWindow == nullptr)
2661                    return;
2662    
2663          // Just delete the channel strip.          // Just delete the channel strip.
2664          delete pChannelStrip;          delete pChannelStrip;
2665            delete pMdiSubWindow;
2666    
2667          // Do we auto-arrange?          // Do we auto-arrange?
2668          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
   
         stabilizeForm();  
2669  }  }
2670    
2671    
2672  // Retrieve the active channel strip.  // Retrieve the active channel strip.
2673  ChannelStrip* MainForm::activeChannelStrip (void)  ChannelStrip *MainForm::activeChannelStrip (void)
2674  {  {
2675          return static_cast<ChannelStrip *> (m_pWorkspace->activeWindow());          QMdiSubWindow *pMdiSubWindow = m_pWorkspace->activeSubWindow();
2676            if (pMdiSubWindow)
2677                    return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2678            else
2679                    return nullptr;
2680  }  }
2681    
2682    
2683  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2684  ChannelStrip* MainForm::channelStripAt ( int iChannel )  ChannelStrip *MainForm::channelStripAt ( int iStrip )
2685  {  {
2686          if (!m_pWorkspace) return NULL;          if (!m_pWorkspace) return nullptr;
2687    
2688          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2689                    = m_pWorkspace->subWindowList();
2690          if (wlist.isEmpty())          if (wlist.isEmpty())
2691                  return NULL;                  return nullptr;
2692    
2693          if (iChannel < 0 || iChannel >= wlist.size())          if (iStrip < 0 || iStrip >= wlist.count())
2694                  return NULL;                  return nullptr;
2695    
2696          return dynamic_cast<ChannelStrip *> (wlist.at(iChannel));          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2697            if (pMdiSubWindow)
2698                    return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2699            else
2700                    return nullptr;
2701  }  }
2702    
2703    
2704  // Retrieve a channel strip by sampler channel id.  // Retrieve a channel strip by sampler channel id.
2705  ChannelStrip* MainForm::channelStrip ( int iChannelID )  ChannelStrip *MainForm::channelStrip ( int iChannelID )
2706  {  {
2707          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2708                    = m_pWorkspace->subWindowList();
2709          if (wlist.isEmpty())          if (wlist.isEmpty())
2710                  return NULL;                  return nullptr;
2711    
2712          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2713                  ChannelStrip* pChannelStrip                  ChannelStrip *pChannelStrip
2714                          = static_cast<ChannelStrip*> (wlist.at(iChannel));                          = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2715                  if (pChannelStrip) {                  if (pChannelStrip) {
2716                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
2717                          if (pChannel && pChannel->channelID() == iChannelID)                          if (pChannel && pChannel->channelID() == iChannelID)
# Line 2370  ChannelStrip* MainForm::channelStrip ( i Line 2720  ChannelStrip* MainForm::channelStrip ( i
2720          }          }
2721    
2722          // Not found.          // Not found.
2723          return NULL;          return nullptr;
2724  }  }
2725    
2726    
# Line 2381  void MainForm::channelsMenuAboutToShow ( Line 2731  void MainForm::channelsMenuAboutToShow (
2731          m_ui.channelsMenu->addAction(m_ui.channelsArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsArrangeAction);
2732          m_ui.channelsMenu->addAction(m_ui.channelsAutoArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsAutoArrangeAction);
2733    
2734          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2735                    = m_pWorkspace->subWindowList();
2736          if (!wlist.isEmpty()) {          if (!wlist.isEmpty()) {
2737                  m_ui.channelsMenu->addSeparator();                  m_ui.channelsMenu->addSeparator();
2738                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                  int iStrip = 0;
2739                          ChannelStrip* pChannelStrip                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2740                                  = static_cast<ChannelStrip*> (wlist.at(iChannel));                          ChannelStrip *pChannelStrip
2741                                    = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2742                          if (pChannelStrip) {                          if (pChannelStrip) {
2743                                  QAction *pAction = m_ui.channelsMenu->addAction(                                  QAction *pAction = m_ui.channelsMenu->addAction(
2744                                          pChannelStrip->windowTitle(),                                          pChannelStrip->windowTitle(),
2745                                          this, SLOT(channelsMenuActivated()));                                          this, SLOT(channelsMenuActivated()));
2746                                  pAction->setCheckable(true);                                  pAction->setCheckable(true);
2747                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);
2748                                  pAction->setData(iChannel);                                  pAction->setData(iStrip);
2749                          }                          }
2750                            ++iStrip;
2751                  }                  }
2752          }          }
2753  }  }
# Line 2405  void MainForm::channelsMenuActivated (vo Line 2758  void MainForm::channelsMenuActivated (vo
2758  {  {
2759          // Retrive channel index from action data...          // Retrive channel index from action data...
2760          QAction *pAction = qobject_cast<QAction *> (sender());          QAction *pAction = qobject_cast<QAction *> (sender());
2761          if (pAction == NULL)          if (pAction == nullptr)
2762                  return;                  return;
2763    
2764          ChannelStrip* pChannelStrip = channelStripAt(pAction->data().toInt());          ChannelStrip *pChannelStrip = channelStripAt(pAction->data().toInt());
2765          if (pChannelStrip) {          if (pChannelStrip) {
2766                  pChannelStrip->showNormal();                  pChannelStrip->showNormal();
2767                  pChannelStrip->setFocus();                  pChannelStrip->setFocus();
# Line 2417  void MainForm::channelsMenuActivated (vo Line 2770  void MainForm::channelsMenuActivated (vo
2770    
2771    
2772  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2773  // qsamplerMainForm -- Timer stuff.  // QSampler::MainForm -- Timer stuff.
2774    
2775  // Set the pseudo-timer delay schedule.  // Set the pseudo-timer delay schedule.
2776  void MainForm::startSchedule ( int iStartDelay )  void MainForm::startSchedule ( int iStartDelay )
# Line 2436  void MainForm::stopSchedule (void) Line 2789  void MainForm::stopSchedule (void)
2789  // Timer slot funtion.  // Timer slot funtion.
2790  void MainForm::timerSlot (void)  void MainForm::timerSlot (void)
2791  {  {
2792          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2793                  return;                  return;
2794    
2795          // 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 2458  void MainForm::timerSlot (void) Line 2811  void MainForm::timerSlot (void)
2811                          ChannelStrip *pChannelStrip = iter.next();                          ChannelStrip *pChannelStrip = iter.next();
2812                          // If successfull, remove from pending list...                          // If successfull, remove from pending list...
2813                          if (pChannelStrip->updateChannelInfo()) {                          if (pChannelStrip->updateChannelInfo()) {
2814                                  int iChannelStrip = m_changedStrips.indexOf(pChannelStrip);                                  const int iChannelStrip = m_changedStrips.indexOf(pChannelStrip);
2815                                  if (iChannelStrip >= 0)                                  if (iChannelStrip >= 0)
2816                                          m_changedStrips.removeAt(iChannelStrip);                                          m_changedStrips.removeAt(iChannelStrip);
2817                          }                          }
# Line 2469  void MainForm::timerSlot (void) Line 2822  void MainForm::timerSlot (void)
2822                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {
2823                                  m_iTimerSlot = 0;                                  m_iTimerSlot = 0;
2824                                  // Update the channel stream usage for each strip...                                  // Update the channel stream usage for each strip...
2825                                  QWidgetList wlist = m_pWorkspace->windowList();                                  const QList<QMdiSubWindow *>& wlist
2826                                  for (int iChannel = 0;                                          = m_pWorkspace->subWindowList();
2827                                                  iChannel < (int) wlist.count(); iChannel++) {                                  foreach (QMdiSubWindow *pMdiSubWindow, wlist) {
2828                                          ChannelStrip* pChannelStrip                                          ChannelStrip *pChannelStrip
2829                                                  = (ChannelStrip*) wlist.at(iChannel);                                                  = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2830                                          if (pChannelStrip && pChannelStrip->isVisible())                                          if (pChannelStrip && pChannelStrip->isVisible())
2831                                                  pChannelStrip->updateChannelUsage();                                                  pChannelStrip->updateChannelUsage();
2832                                  }                                  }
2833                          }                          }
2834                  }                  }
2835    
2836            #if CONFIG_LSCP_CLIENT_CONNECTION_LOST
2837                    // If we lost connection to server: Try to automatically reconnect if we
2838                    // did not start the server.
2839                    //
2840                    // TODO: If we started the server, then we might inform the user that
2841                    // the server probably crashed and asking user ONCE whether we should
2842                    // restart the server.
2843                    if (lscp_client_connection_lost(m_pClient) && !m_pServer)
2844                            startAutoReconnectClient();
2845            #endif // CONFIG_LSCP_CLIENT_CONNECTION_LOST
2846          }          }
2847    
2848          // Register the next timer slot.          // Register the next timer slot.
# Line 2487  void MainForm::timerSlot (void) Line 2851  void MainForm::timerSlot (void)
2851    
2852    
2853  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2854  // qsamplerMainForm -- Server stuff.  // QSampler::MainForm -- Server stuff.
2855    
2856  // Start linuxsampler server...  // Start linuxsampler server...
2857  void MainForm::startServer (void)  void MainForm::startServer (void)
2858  {  {
2859          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
2860                  return;                  return;
2861    
2862          // Aren't already a client, are we?          // Aren't already a client, are we?
# Line 2501  void MainForm::startServer (void) Line 2865  void MainForm::startServer (void)
2865    
2866          // Is the server process instance still here?          // Is the server process instance still here?
2867          if (m_pServer) {          if (m_pServer) {
2868                  switch (QMessageBox::warning(this,                  if (QMessageBox::warning(this,
2869                          QSAMPLER_TITLE ": " + tr("Warning"),                          tr("Warning"),
2870                          tr("Could not start the LinuxSampler server.\n\n"                          tr("Could not start the LinuxSampler server.\n\n"
2871                          "Maybe it is already started."),                          "Maybe it is already started."),
2872                          tr("Stop"), tr("Kill"), tr("Cancel"))) {                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
                 case 0:  
2873                          m_pServer->terminate();                          m_pServer->terminate();
                         break;  
                 case 1:  
2874                          m_pServer->kill();                          m_pServer->kill();
                         break;  
2875                  }                  }
2876                  return;                  return;
2877          }          }
# Line 2525  void MainForm::startServer (void) Line 2885  void MainForm::startServer (void)
2885    
2886          // OK. Let's build the startup process...          // OK. Let's build the startup process...
2887          m_pServer = new QProcess();          m_pServer = new QProcess();
2888          bForceServerStop = true;          m_bForceServerStop = true;
2889    
2890          // Setup stdout/stderr capture...          // Setup stdout/stderr capture...
2891  //      if (m_pOptions->bStdoutCapture) {          m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);
2892  #if QT_VERSION >= 0x040200          QObject::connect(m_pServer,
2893                  m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);                  SIGNAL(readyReadStandardOutput()),
2894  #endif                  SLOT(readServerStdout()));
2895                  QObject::connect(m_pServer,          QObject::connect(m_pServer,
2896                          SIGNAL(readyReadStandardOutput()),                  SIGNAL(readyReadStandardError()),
2897                          SLOT(readServerStdout()));                  SLOT(readServerStdout()));
                 QObject::connect(m_pServer,  
                         SIGNAL(readyReadStandardError()),  
                         SLOT(readServerStdout()));  
 //      }  
2898    
2899          // The unforgiveable signal communication...          // The unforgiveable signal communication...
2900          QObject::connect(m_pServer,          QObject::connect(m_pServer,
# Line 2573  void MainForm::startServer (void) Line 2929  void MainForm::startServer (void)
2929    
2930    
2931  // Stop linuxsampler server...  // Stop linuxsampler server...
2932  void MainForm::stopServer (bool bInteractive)  void MainForm::stopServer ( bool bInteractive )
2933  {  {
2934          // Stop client code.          // Stop client code.
2935          stopClient();          stopClient();
2936    
2937          if (m_pServer && bInteractive) {          if (m_pServer && bInteractive) {
2938                  if (QMessageBox::question(this,                  if (QMessageBox::question(this,
2939                          QSAMPLER_TITLE ": " + tr("The backend's fate ..."),                          tr("The backend's fate ..."),
2940                          tr("You have the option to keep the sampler backend (LinuxSampler)\n"                          tr("You have the option to keep the sampler backend (LinuxSampler)\n"
2941                          "running in the background. The sampler would continue to work\n"                          "running in the background. The sampler would continue to work\n"
2942                          "according to your current sampler session and you could alter the\n"                          "according to your current sampler session and you could alter the\n"
2943                          "sampler session at any time by relaunching QSampler.\n\n"                          "sampler session at any time by relaunching QSampler.\n\n"
2944                          "Do you want LinuxSampler to stop or to keep running in\n"                          "Do you want LinuxSampler to stop?"),
2945                          "the background?"),                          QMessageBox::Yes | QMessageBox::No,
2946                          tr("Stop"), tr("Keep Running")) == 1)                          QMessageBox::Yes) == QMessageBox::No) {
2947                  {                          m_bForceServerStop = false;
                         bForceServerStop = false;  
2948                  }                  }
2949          }          }
2950    
2951            bool bGraceWait = true;
2952    
2953          // And try to stop server.          // And try to stop server.
2954          if (m_pServer && bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2955                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2956                  if (m_pServer->state() == QProcess::Running) {                  if (m_pServer->state() == QProcess::Running) {
2957  #if defined(WIN32)                  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
2958                          // Try harder...                          // Try harder...
2959                          m_pServer->kill();                          m_pServer->kill();
2960  #else                  #else
2961                          // Try softly...                          // Try softly...
2962                          m_pServer->terminate();                          m_pServer->terminate();
2963  #endif                          bool bFinished = m_pServer->waitForFinished(QSAMPLER_TIMER_MSECS * 1000);
2964                            if (bFinished) bGraceWait = false;
2965                    #endif
2966                  }                  }
2967          }       // Do final processing anyway.          }       // Do final processing anyway.
2968          else processServerExit();          else processServerExit();
2969    
2970          // Give it some time to terminate gracefully and stabilize...          // Give it some time to terminate gracefully and stabilize...
2971          QTime t;          if (bGraceWait) {
2972          t.start();                  QElapsedTimer timer;
2973          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                  timer.start();
2974                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  while (timer.elapsed() < QSAMPLER_TIMER_MSECS)
2975                            QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2976            }
2977  }  }
2978    
2979    
# Line 2634  void MainForm::processServerExit (void) Line 2995  void MainForm::processServerExit (void)
2995          if (m_pMessages)          if (m_pMessages)
2996                  m_pMessages->flushStdoutBuffer();                  m_pMessages->flushStdoutBuffer();
2997    
2998          if (m_pServer && bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2999                  if (m_pServer->state() != QProcess::NotRunning) {                  if (m_pServer->state() != QProcess::NotRunning) {
3000                          appendMessages(tr("Server is being forced..."));                          appendMessages(tr("Server is being forced..."));
3001                          // Force final server shutdown...                          // Force final server shutdown...
3002                          m_pServer->kill();                          m_pServer->kill();
3003                          // Give it some time to terminate gracefully and stabilize...                          // Give it some time to terminate gracefully and stabilize...
3004                          QTime t;                          QElapsedTimer timer;
3005                          t.start();                          timer.start();
3006                          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                          while (timer.elapsed() < QSAMPLER_TIMER_MSECS)
3007                                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
3008                  }                  }
3009                  // Force final server shutdown...                  // Force final server shutdown...
# Line 2650  void MainForm::processServerExit (void) Line 3011  void MainForm::processServerExit (void)
3011                          tr("Server was stopped with exit status %1.")                          tr("Server was stopped with exit status %1.")
3012                          .arg(m_pServer->exitStatus()));                          .arg(m_pServer->exitStatus()));
3013                  delete m_pServer;                  delete m_pServer;
3014                  m_pServer = NULL;                  m_pServer = nullptr;
3015          }          }
3016    
3017          // Again, make status visible stable.          // Again, make status visible stable.
# Line 2659  void MainForm::processServerExit (void) Line 3020  void MainForm::processServerExit (void)
3020    
3021    
3022  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
3023  // qsamplerMainForm -- Client stuff.  // QSampler::MainForm -- Client stuff.
3024    
3025  // The LSCP client callback procedure.  // The LSCP client callback procedure.
3026  lscp_status_t qsampler_client_callback ( lscp_client_t */*pClient*/,  lscp_status_t qsampler_client_callback ( lscp_client_t */*pClient*/,
3027          lscp_event_t event, const char *pchData, int cchData, void *pvData )          lscp_event_t event, const char *pchData, int cchData, void *pvData )
3028  {  {
3029          MainForm* pMainForm = (MainForm *) pvData;          MainForm* pMainForm = (MainForm *) pvData;
3030          if (pMainForm == NULL)          if (pMainForm == nullptr)
3031                  return LSCP_FAILED;                  return LSCP_FAILED;
3032    
3033          // ATTN: DO NOT EVER call any GUI code here,          // ATTN: DO NOT EVER call any GUI code here,
3034          // as this is run under some other thread context.          // as this is run under some other thread context.
3035          // A custom event must be posted here...          // A custom event must be posted here...
3036          QApplication::postEvent(pMainForm,          QApplication::postEvent(pMainForm,
3037                  new CustomEvent(event, pchData, cchData));                  new LscpEvent(event, pchData, cchData));
3038    
3039          return LSCP_OK;          return LSCP_OK;
3040  }  }
3041    
3042    
3043  // Start our almighty client...  // Start our almighty client...
3044  bool MainForm::startClient (void)  bool MainForm::startClient (bool bReconnectOnly)
3045  {  {
3046          // Have it a setup?          // Have it a setup?
3047          if (m_pOptions == NULL)          if (m_pOptions == nullptr)
3048                  return false;                  return false;
3049    
3050          // Aren't we already started, are we?          // Aren't we already started, are we?
# Line 2697  bool MainForm::startClient (void) Line 3058  bool MainForm::startClient (void)
3058          m_pClient = ::lscp_client_create(          m_pClient = ::lscp_client_create(
3059                  m_pOptions->sServerHost.toUtf8().constData(),                  m_pOptions->sServerHost.toUtf8().constData(),
3060                  m_pOptions->iServerPort, qsampler_client_callback, this);                  m_pOptions->iServerPort, qsampler_client_callback, this);
3061          if (m_pClient == NULL) {          if (m_pClient == nullptr) {
3062                  // Is this the first try?                  // Is this the first try?
3063                  // maybe we need to start a local server...                  // maybe we need to start a local server...
3064                  if ((m_pServer && m_pServer->state() == QProcess::Running)                  if ((m_pServer && m_pServer->state() == QProcess::Running)
3065                          || !m_pOptions->bServerStart) {                          || !m_pOptions->bServerStart || bReconnectOnly)
3066                          appendMessagesError(                  {
3067                                  tr("Could not connect to server as client.\n\nSorry."));                          // if this method is called from autoReconnectClient()
3068                            // then don't bother user with an error message...
3069                            if (!bReconnectOnly) {
3070                                    appendMessagesError(
3071                                            tr("Could not connect to server as client.\n\nSorry.")
3072                                    );
3073                            }
3074                  } else {                  } else {
3075                          startServer();                          startServer();
3076                  }                  }
# Line 2711  bool MainForm::startClient (void) Line 3078  bool MainForm::startClient (void)
3078                  stabilizeForm();                  stabilizeForm();
3079                  return false;                  return false;
3080          }          }
3081    
3082          // Just set receive timeout value, blindly.          // Just set receive timeout value, blindly.
3083          ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);          ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
3084          appendMessages(          appendMessages(
# Line 2766  bool MainForm::startClient (void) Line 3134  bool MainForm::startClient (void)
3134          if (!m_pOptions->sSessionFile.isEmpty()) {          if (!m_pOptions->sSessionFile.isEmpty()) {
3135                  // Just load the prabably startup session...                  // Just load the prabably startup session...
3136                  if (loadSessionFile(m_pOptions->sSessionFile)) {                  if (loadSessionFile(m_pOptions->sSessionFile)) {
3137                          m_pOptions->sSessionFile = QString::null;                          m_pOptions->sSessionFile = QString();
3138                          return true;                          return true;
3139                  }                  }
3140          }          }
# Line 2782  bool MainForm::startClient (void) Line 3150  bool MainForm::startClient (void)
3150  // Stop client...  // Stop client...
3151  void MainForm::stopClient (void)  void MainForm::stopClient (void)
3152  {  {
3153          if (m_pClient == NULL)          if (m_pClient == nullptr)
3154                  return;                  return;
3155    
3156          // Log prepare here.          // Log prepare here.
# Line 2814  void MainForm::stopClient (void) Line 3182  void MainForm::stopClient (void)
3182          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
3183          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);
3184          ::lscp_client_destroy(m_pClient);          ::lscp_client_destroy(m_pClient);
3185          m_pClient = NULL;          m_pClient = nullptr;
3186    
3187          // Hard-notify instrumnet and device configuration forms,          // Hard-notify instrumnet and device configuration forms,
3188          // if visible, that we're running out...          // if visible, that we're running out...
# Line 2831  void MainForm::stopClient (void) Line 3199  void MainForm::stopClient (void)
3199  }  }
3200    
3201    
3202    void MainForm::startAutoReconnectClient (void)
3203    {
3204            stopClient();
3205            appendMessages(tr("Trying to reconnect..."));
3206            QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(autoReconnectClient()));
3207    }
3208    
3209    
3210    void MainForm::autoReconnectClient (void)
3211    {
3212            const bool bSuccess = startClient(true);
3213            if (!bSuccess)
3214                    QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(autoReconnectClient()));
3215    }
3216    
3217    
3218  // Channel strip activation/selection.  // Channel strip activation/selection.
3219  void MainForm::activateStrip ( QWidget *pWidget )  void MainForm::activateStrip ( QMdiSubWindow *pMdiSubWindow )
3220  {  {
3221          ChannelStrip *pChannelStrip          ChannelStrip *pChannelStrip = nullptr;
3222                  = static_cast<ChannelStrip *> (pWidget);          if (pMdiSubWindow)
3223                    pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
3224          if (pChannelStrip)          if (pChannelStrip)
3225                  pChannelStrip->setSelected(true);                  pChannelStrip->setSelected(true);
3226    
# Line 2843  void MainForm::activateStrip ( QWidget * Line 3228  void MainForm::activateStrip ( QWidget *
3228  }  }
3229    
3230    
3231    // Channel toolbar orientation change.
3232    void MainForm::channelsToolbarOrientation ( Qt::Orientation orientation )
3233    {
3234    #ifdef CONFIG_VOLUME
3235            m_pVolumeSlider->setOrientation(orientation);
3236            if (orientation == Qt::Horizontal) {
3237                    m_pVolumeSlider->setMinimumHeight(24);
3238                    m_pVolumeSlider->setMaximumHeight(32);
3239                    m_pVolumeSlider->setMinimumWidth(120);
3240                    m_pVolumeSlider->setMaximumWidth(640);
3241                    m_pVolumeSpinBox->setMaximumWidth(64);
3242                    m_pVolumeSpinBox->setButtonSymbols(QSpinBox::UpDownArrows);
3243            } else {
3244                    m_pVolumeSlider->setMinimumHeight(120);
3245                    m_pVolumeSlider->setMaximumHeight(480);
3246                    m_pVolumeSlider->setMinimumWidth(24);
3247                    m_pVolumeSlider->setMaximumWidth(32);
3248                    m_pVolumeSpinBox->setMaximumWidth(32);
3249                    m_pVolumeSpinBox->setButtonSymbols(QSpinBox::NoButtons);
3250            }
3251    #endif
3252    }
3253    
3254    
3255  } // namespace QSampler  } // namespace QSampler
3256    
3257    

Legend:
Removed from v.1803  
changed lines
  Added in v.3789

  ViewVC Help
Powered by ViewVC