/[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 1840 by capela, Thu Feb 19 11:44:57 2009 UTC revision 3358 by capela, Wed Oct 18 08:57:21 2017 UTC
# Line 1  Line 1 
1  // qsamplerMainForm.cpp  // qsamplerMainForm.cpp
2  //  //
3  /****************************************************************************  /****************************************************************************
4     Copyright (C) 2004-2009, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2017, rncbc aka Rui Nuno Capela. All rights reserved.
5     Copyright (C) 2007, 2008 Christian Schoenebeck     Copyright (C) 2007,2008,2015 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 <QMdiArea>
39    #include <QMdiSubWindow>
40    
41  #include <QApplication>  #include <QApplication>
 #include <QWorkspace>  
42  #include <QProcess>  #include <QProcess>
43  #include <QMessageBox>  #include <QMessageBox>
44    
# Line 56  Line 58 
58  #include <QTimer>  #include <QTimer>
59  #include <QDateTime>  #include <QDateTime>
60    
61    #if QT_VERSION >= 0x050000
62    #include <QMimeData>
63    #endif
64    
65    #if QT_VERSION < 0x040500
66    namespace Qt {
67    const WindowFlags WindowCloseButtonHint = WindowFlags(0x08000000);
68    }
69    #endif
70    
71  #ifdef HAVE_SIGNAL_H  #ifdef HAVE_SIGNAL_H
72  #include <signal.h>  #include <signal.h>
# Line 80  static inline long lroundf ( float x ) Line 91  static inline long lroundf ( float x )
91    
92    
93  // All winsock apps needs this.  // All winsock apps needs this.
94  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
95  static WSADATA _wsaData;  static WSADATA _wsaData;
96  #endif  #endif
97    
98    
99    //-------------------------------------------------------------------------
100    // LADISH Level 1 support stuff.
101    
102    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
103    
104    #include <QSocketNotifier>
105    
106    #include <sys/types.h>
107    #include <sys/socket.h>
108    
109    #include <signal.h>
110    
111    // File descriptor for SIGUSR1 notifier.
112    static int g_fdUsr1[2];
113    
114    // Unix SIGUSR1 signal handler.
115    static void qsampler_sigusr1_handler ( int /* signo */ )
116    {
117            char c = 1;
118    
119            (::write(g_fdUsr1[0], &c, sizeof(c)) > 0);
120    }
121    
122    #endif  // HAVE_SIGNAL_H
123    
124    
125    //-------------------------------------------------------------------------
126    // QSampler -- namespace
127    
128    
129  namespace QSampler {  namespace QSampler {
130    
131  // Timer constant stuff.  // Timer constant stuff.
# Line 97  namespace QSampler { Line 138  namespace QSampler {
138  #define QSAMPLER_STATUS_SESSION 3       // Current session modification state.  #define QSAMPLER_STATUS_SESSION 3       // Current session modification state.
139    
140    
141  //-------------------------------------------------------------------------  // Specialties for thread-callback comunication.
142  // CustomEvent -- specialty for callback comunication.  #define QSAMPLER_LSCP_EVENT   QEvent::Type(QEvent::User + 1)
143    
 #define QSAMPLER_CUSTOM_EVENT   QEvent::Type(QEvent::User + 0)  
144    
145  class CustomEvent : public QEvent  //-------------------------------------------------------------------------
146    // QSampler::LscpEvent -- specialty for LSCP callback comunication.
147    
148    class LscpEvent : public QEvent
149  {  {
150  public:  public:
151    
152          // Constructor.          // Constructor.
153          CustomEvent(lscp_event_t event, const char *pchData, int cchData)          LscpEvent(lscp_event_t event, const char *pchData, int cchData)
154                  : QEvent(QSAMPLER_CUSTOM_EVENT)                  : QEvent(QSAMPLER_LSCP_EVENT)
155          {          {
156                  m_event = event;                  m_event = event;
157                  m_data  = QString::fromUtf8(pchData, cchData);                  m_data  = QString::fromUtf8(pchData, cchData);
158          }          }
159    
160          // Accessors.          // Accessors.
161          lscp_event_t event() { return m_event; }          lscp_event_t  event() { return m_event; }
162          QString&     data()  { return m_data;  }          const QString& data() { return m_data;  }
163    
164  private:  private:
165    
# Line 128  private: Line 171  private:
171    
172    
173  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
174  // qsamplerMainForm -- Main window form implementation.  // QSampler::Workspace -- Main window workspace (MDI Area) decl.
175    
176    class Workspace : public QMdiArea
177    {
178    public:
179    
180            Workspace(MainForm *pMainForm) : QMdiArea(pMainForm) {}
181    
182    protected:
183    
184            void resizeEvent(QResizeEvent *)
185            {
186                    MainForm *pMainForm = static_cast<MainForm *> (parentWidget());
187                    if (pMainForm)
188                            pMainForm->channelsArrangeAuto();
189            }
190    };
191    
192    
193    //-------------------------------------------------------------------------
194    // QSampler::MainForm -- Main window form implementation.
195    
196  // Kind of singleton reference.  // Kind of singleton reference.
197  MainForm* MainForm::g_pMainForm = NULL;  MainForm *MainForm::g_pMainForm = NULL;
198    
199  MainForm::MainForm ( QWidget *pParent )  MainForm::MainForm ( QWidget *pParent )
200          : QMainWindow(pParent)          : QMainWindow(pParent)
# Line 151  MainForm::MainForm ( QWidget *pParent ) Line 214  MainForm::MainForm ( QWidget *pParent )
214    
215          // We'll start clean.          // We'll start clean.
216          m_iUntitled   = 0;          m_iUntitled   = 0;
217            m_iDirtySetup = 0;
218          m_iDirtyCount = 0;          m_iDirtyCount = 0;
219    
220          m_pServer = NULL;          m_pServer = NULL;
# Line 161  MainForm::MainForm ( QWidget *pParent ) Line 225  MainForm::MainForm ( QWidget *pParent )
225    
226          m_iTimerSlot = 0;          m_iTimerSlot = 0;
227    
228  #ifdef HAVE_SIGNAL_H  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
229    
230          // Set to ignore any fatal "Broken pipe" signals.          // Set to ignore any fatal "Broken pipe" signals.
231          ::signal(SIGPIPE, SIG_IGN);          ::signal(SIGPIPE, SIG_IGN);
232  #endif  
233            // LADISH Level 1 suport.
234    
235            // Initialize file descriptors for SIGUSR1 socket notifier.
236            ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdUsr1);
237            m_pUsr1Notifier
238                    = new QSocketNotifier(g_fdUsr1[1], QSocketNotifier::Read, this);
239    
240            QObject::connect(m_pUsr1Notifier,
241                    SIGNAL(activated(int)),
242                    SLOT(handle_sigusr1()));
243    
244            // Install SIGUSR1 signal handler.
245        struct sigaction usr1;
246        usr1.sa_handler = qsampler_sigusr1_handler;
247        sigemptyset(&usr1.sa_mask);
248        usr1.sa_flags = 0;
249        usr1.sa_flags |= SA_RESTART;
250        ::sigaction(SIGUSR1, &usr1, NULL);
251    
252    #else   // HAVE_SIGNAL_H
253    
254            m_pUsr1Notifier = NULL;
255            
256    #endif  // !HAVE_SIGNAL_H
257    
258  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
259          // Make some extras into the toolbar...          // Make some extras into the toolbar...
# Line 185  MainForm::MainForm ( QWidget *pParent ) Line 274  MainForm::MainForm ( QWidget *pParent )
274          QObject::connect(m_pVolumeSlider,          QObject::connect(m_pVolumeSlider,
275                  SIGNAL(valueChanged(int)),                  SIGNAL(valueChanged(int)),
276                  SLOT(volumeChanged(int)));                  SLOT(volumeChanged(int)));
         //m_ui.channelsToolbar->setHorizontallyStretchable(true);  
         //m_ui.channelsToolbar->setStretchableWidget(m_pVolumeSlider);  
277          m_ui.channelsToolbar->addWidget(m_pVolumeSlider);          m_ui.channelsToolbar->addWidget(m_pVolumeSlider);
278          // Volume spin-box          // Volume spin-box
279          m_ui.channelsToolbar->addSeparator();          m_ui.channelsToolbar->addSeparator();
280          m_pVolumeSpinBox = new QSpinBox(m_ui.channelsToolbar);          m_pVolumeSpinBox = new QSpinBox(m_ui.channelsToolbar);
         m_pVolumeSpinBox->setMaximumHeight(24);  
281          m_pVolumeSpinBox->setSuffix(" %");          m_pVolumeSpinBox->setSuffix(" %");
282          m_pVolumeSpinBox->setMinimum(0);          m_pVolumeSpinBox->setMinimum(0);
283          m_pVolumeSpinBox->setMaximum(100);          m_pVolumeSpinBox->setMaximum(100);
# Line 203  MainForm::MainForm ( QWidget *pParent ) Line 289  MainForm::MainForm ( QWidget *pParent )
289  #endif  #endif
290    
291          // Make it an MDI workspace.          // Make it an MDI workspace.
292          m_pWorkspace = new QWorkspace(this);          m_pWorkspace = new Workspace(this);
293          m_pWorkspace->setScrollBarsEnabled(true);          m_pWorkspace->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
294            m_pWorkspace->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
295          // Set the activation connection.          // Set the activation connection.
296          QObject::connect(m_pWorkspace,          QObject::connect(m_pWorkspace,
297                  SIGNAL(windowActivated(QWidget *)),                  SIGNAL(subWindowActivated(QMdiSubWindow *)),
298                  SLOT(activateStrip(QWidget *)));                  SLOT(activateStrip(QMdiSubWindow *)));
299          // Make it shine :-)          // Make it shine :-)
300          setCentralWidget(m_pWorkspace);          setCentralWidget(m_pWorkspace);
301    
# Line 237  MainForm::MainForm ( QWidget *pParent ) Line 324  MainForm::MainForm ( QWidget *pParent )
324          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
325          statusBar()->addWidget(pLabel);          statusBar()->addWidget(pLabel);
326    
327  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
328          WSAStartup(MAKEWORD(1, 1), &_wsaData);          WSAStartup(MAKEWORD(1, 1), &_wsaData);
329  #endif  #endif
330    
# Line 325  MainForm::MainForm ( QWidget *pParent ) Line 412  MainForm::MainForm ( QWidget *pParent )
412          QObject::connect(m_ui.channelsMenu,          QObject::connect(m_ui.channelsMenu,
413                  SIGNAL(aboutToShow()),                  SIGNAL(aboutToShow()),
414                  SLOT(channelsMenuAboutToShow()));                  SLOT(channelsMenuAboutToShow()));
415    #ifdef CONFIG_VOLUME
416            QObject::connect(m_ui.channelsToolbar,
417                    SIGNAL(orientationChanged(Qt::Orientation)),
418                    SLOT(channelsToolbarOrientation(Qt::Orientation)));
419    #endif
420  }  }
421    
422  // Destructor.  // Destructor.
# Line 333  MainForm::~MainForm() Line 425  MainForm::~MainForm()
425          // Do final processing anyway.          // Do final processing anyway.
426          processServerExit();          processServerExit();
427    
428  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
429          WSACleanup();          WSACleanup();
430  #endif  #endif
431    
432    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
433            if (m_pUsr1Notifier)
434                    delete m_pUsr1Notifier;
435    #endif
436    
437          // Finally drop any widgets around...          // Finally drop any widgets around...
438          if (m_pDeviceForm)          if (m_pDeviceForm)
439                  delete m_pDeviceForm;                  delete m_pDeviceForm;
# Line 375  void MainForm::setup ( Options *pOptions Line 472  void MainForm::setup ( Options *pOptions
472    
473          // What style do we create these forms?          // What style do we create these forms?
474          Qt::WindowFlags wflags = Qt::Window          Qt::WindowFlags wflags = Qt::Window
 #if QT_VERSION >= 0x040200  
475                  | Qt::CustomizeWindowHint                  | Qt::CustomizeWindowHint
 #endif  
476                  | Qt::WindowTitleHint                  | Qt::WindowTitleHint
477                  | Qt::WindowSystemMenuHint                  | Qt::WindowSystemMenuHint
478                  | Qt::WindowMinMaxButtonsHint;                  | Qt::WindowMinMaxButtonsHint
479                    | Qt::WindowCloseButtonHint;
480          if (m_pOptions->bKeepOnTop)          if (m_pOptions->bKeepOnTop)
481                  wflags |= Qt::Tool;                  wflags |= Qt::Tool;
482    
483          // Some child forms are to be created right now.          // Some child forms are to be created right now.
484          m_pMessages = new Messages(this);          m_pMessages = new Messages(this);
485          m_pDeviceForm = new DeviceForm(this, wflags);          m_pDeviceForm = new DeviceForm(this, wflags);
486  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
487          m_pInstrumentListForm = new InstrumentListForm(this, wflags);          m_pInstrumentListForm = new InstrumentListForm(this, wflags);
488  #else  #else
489          viewInstrumentsAction->setEnabled(false);          m_ui.viewInstrumentsAction->setEnabled(false);
490  #endif  #endif
491    
492          // Setup messages logging appropriately...          // Setup messages logging appropriately...
493          m_pMessages->setLogging(          m_pMessages->setLogging(
494                  m_pOptions->bMessagesLog,                  m_pOptions->bMessagesLog,
495                  m_pOptions->sMessagesLogPath);                  m_pOptions->sMessagesLogPath);
496    
497          // Set message defaults...          // Set message defaults...
498          updateMessagesFont();          updateMessagesFont();
499          updateMessagesLimit();          updateMessagesLimit();
500          updateMessagesCapture();          updateMessagesCapture();
501    
502          // Set the visibility signal.          // Set the visibility signal.
503          QObject::connect(m_pMessages,          QObject::connect(m_pMessages,
504                  SIGNAL(visibilityChanged(bool)),                  SIGNAL(visibilityChanged(bool)),
# Line 425  void MainForm::setup ( Options *pOptions Line 525  void MainForm::setup ( Options *pOptions
525          }          }
526    
527          // Try to restore old window positioning and initial visibility.          // Try to restore old window positioning and initial visibility.
528          m_pOptions->loadWidgetGeometry(this);          m_pOptions->loadWidgetGeometry(this, true);
529          m_pOptions->loadWidgetGeometry(m_pInstrumentListForm);          m_pOptions->loadWidgetGeometry(m_pInstrumentListForm);
530          m_pOptions->loadWidgetGeometry(m_pDeviceForm);          m_pOptions->loadWidgetGeometry(m_pDeviceForm);
531    
# Line 464  bool MainForm::queryClose (void) Line 564  bool MainForm::queryClose (void)
564                                  || m_ui.channelsToolbar->isVisible());                                  || m_ui.channelsToolbar->isVisible());
565                          m_pOptions->bStatusbar = statusBar()->isVisible();                          m_pOptions->bStatusbar = statusBar()->isVisible();
566                          // Save the dock windows state.                          // Save the dock windows state.
                         const QString sDockables = saveState().toBase64().data();  
567                          m_pOptions->settings().setValue("/Layout/DockWindows", saveState());                          m_pOptions->settings().setValue("/Layout/DockWindows", saveState());
568                          // And the children, and the main windows state,.                          // And the children, and the main windows state,.
569                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);
570                          m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);                          m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
571                          m_pOptions->saveWidgetGeometry(this);                          m_pOptions->saveWidgetGeometry(this, true);
572                          // Close popup widgets.                          // Close popup widgets.
573                          if (m_pInstrumentListForm)                          if (m_pInstrumentListForm)
574                                  m_pInstrumentListForm->close();                                  m_pInstrumentListForm->close();
# Line 507  void MainForm::dragEnterEvent ( QDragEnt Line 606  void MainForm::dragEnterEvent ( QDragEnt
606  }  }
607    
608    
609  void MainForm::dropEvent ( QDropEvent* pDropEvent )  void MainForm::dropEvent ( QDropEvent *pDropEvent )
610  {  {
611          // Accept externally originated drops only...          // Accept externally originated drops only...
612          if (pDropEvent->source())          if (pDropEvent->source())
# Line 518  void MainForm::dropEvent ( QDropEvent* p Line 617  void MainForm::dropEvent ( QDropEvent* p
617                  QListIterator<QUrl> iter(pMimeData->urls());                  QListIterator<QUrl> iter(pMimeData->urls());
618                  while (iter.hasNext()) {                  while (iter.hasNext()) {
619                          const QString& sPath = iter.next().toLocalFile();                          const QString& sPath = iter.next().toLocalFile();
620                          if (Channel::isInstrumentFile(sPath)) {                  //      if (Channel::isDlsInstrumentFile(sPath)) {
621                            if (QFileInfo(sPath).exists()) {
622                                  // Try to create a new channel from instrument file...                                  // Try to create a new channel from instrument file...
623                                  Channel *pChannel = new Channel();                                  Channel *pChannel = new Channel();
624                                  if (pChannel == NULL)                                  if (pChannel == NULL)
# Line 552  void MainForm::dropEvent ( QDropEvent* p Line 652  void MainForm::dropEvent ( QDropEvent* p
652    
653    
654  // Custome event handler.  // Custome event handler.
655  void MainForm::customEvent(QEvent* pCustomEvent)  void MainForm::customEvent ( QEvent* pEvent )
656  {  {
657          // For the time being, just pump it to messages.          // For the time being, just pump it to messages.
658          if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {          if (pEvent->type() == QSAMPLER_LSCP_EVENT) {
659                  CustomEvent *pEvent = static_cast<CustomEvent *> (pCustomEvent);                  LscpEvent *pLscpEvent = static_cast<LscpEvent *> (pEvent);
660                  switch (pEvent->event()) {                  switch (pLscpEvent->event()) {
661                          case LSCP_EVENT_CHANNEL_COUNT:                          case LSCP_EVENT_CHANNEL_COUNT:
662                                  updateAllChannelStrips(true);                                  updateAllChannelStrips(true);
663                                  break;                                  break;
664                          case LSCP_EVENT_CHANNEL_INFO: {                          case LSCP_EVENT_CHANNEL_INFO: {
665                                  int iChannelID = pEvent->data().toInt();                                  const int iChannelID = pLscpEvent->data().toInt();
666                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);
667                                  if (pChannelStrip)                                  if (pChannelStrip)
668                                          channelStripChanged(pChannelStrip);                                          channelStripChanged(pChannelStrip);
# Line 575  void MainForm::customEvent(QEvent* pCust Line 675  void MainForm::customEvent(QEvent* pCust
675                                  break;                                  break;
676                          case LSCP_EVENT_MIDI_INPUT_DEVICE_INFO: {                          case LSCP_EVENT_MIDI_INPUT_DEVICE_INFO: {
677                                  if (m_pDeviceForm) m_pDeviceForm->refreshDevices();                                  if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
678                                  const int iDeviceID = pEvent->data().section(' ', 0, 0).toInt();                                  const int iDeviceID = pLscpEvent->data().section(' ', 0, 0).toInt();
679                                  DeviceStatusForm::onDeviceChanged(iDeviceID);                                  DeviceStatusForm::onDeviceChanged(iDeviceID);
680                                  break;                                  break;
681                          }                          }
# Line 585  void MainForm::customEvent(QEvent* pCust Line 685  void MainForm::customEvent(QEvent* pCust
685                          case LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO:                          case LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO:
686                                  if (m_pDeviceForm) m_pDeviceForm->refreshDevices();                                  if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
687                                  break;                                  break;
688  #if CONFIG_EVENT_CHANNEL_MIDI                  #if CONFIG_EVENT_CHANNEL_MIDI
689                          case LSCP_EVENT_CHANNEL_MIDI: {                          case LSCP_EVENT_CHANNEL_MIDI: {
690                                  const int iChannelID = pEvent->data().section(' ', 0, 0).toInt();                                  const int iChannelID = pLscpEvent->data().section(' ', 0, 0).toInt();
691                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);
692                                  if (pChannelStrip)                                  if (pChannelStrip)
693                                          pChannelStrip->midiArrived();                                          pChannelStrip->midiActivityLedOn();
694                                  break;                                  break;
695                          }                          }
696  #endif                  #endif
697  #if CONFIG_EVENT_DEVICE_MIDI                  #if CONFIG_EVENT_DEVICE_MIDI
698                          case LSCP_EVENT_DEVICE_MIDI: {                          case LSCP_EVENT_DEVICE_MIDI: {
699                                  const int iDeviceID = pEvent->data().section(' ', 0, 0).toInt();                                  const int iDeviceID = pLscpEvent->data().section(' ', 0, 0).toInt();
700                                  const int iPortID   = pEvent->data().section(' ', 1, 1).toInt();                                  const int iPortID   = pLscpEvent->data().section(' ', 1, 1).toInt();
701                                  DeviceStatusForm* pDeviceStatusForm =                                  DeviceStatusForm *pDeviceStatusForm
702                                          DeviceStatusForm::getInstance(iDeviceID);                                          = DeviceStatusForm::getInstance(iDeviceID);
703                                  if (pDeviceStatusForm)                                  if (pDeviceStatusForm)
704                                          pDeviceStatusForm->midiArrived(iPortID);                                          pDeviceStatusForm->midiArrived(iPortID);
705                                  break;                                  break;
706                          }                          }
707  #endif                  #endif
708                          default:                          default:
709                                  appendMessagesColor(tr("Notify event: %1 data: %2")                                  appendMessagesColor(tr("LSCP Event: %1 data: %2")
710                                          .arg(::lscp_event_to_text(pEvent->event()))                                          .arg(::lscp_event_to_text(pLscpEvent->event()))
711                                          .arg(pEvent->data()), "#996699");                                          .arg(pLscpEvent->data()), "#996699");
712                  }                  }
713          }          }
714  }  }
715    
716  void MainForm::updateViewMidiDeviceStatusMenu() {  
717    // LADISH Level 1 -- SIGUSR1 signal handler.
718    void MainForm::handle_sigusr1 (void)
719    {
720    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
721    
722            char c;
723    
724            if (::read(g_fdUsr1[1], &c, sizeof(c)) > 0)
725                    saveSession(false);
726    
727    #endif
728    }
729    
730    
731    void MainForm::updateViewMidiDeviceStatusMenu (void)
732    {
733          m_ui.viewMidiDeviceStatusMenu->clear();          m_ui.viewMidiDeviceStatusMenu->clear();
734          const std::map<int, DeviceStatusForm*> statusForms =          const std::map<int, DeviceStatusForm *> statusForms
735                  DeviceStatusForm::getInstances();                  = DeviceStatusForm::getInstances();
736          for (          std::map<int, DeviceStatusForm *>::const_iterator iter
737                  std::map<int, DeviceStatusForm*>::const_iterator iter = statusForms.begin();                  = statusForms.begin();
738                  iter != statusForms.end(); ++iter          for ( ; iter != statusForms.end(); ++iter) {
739          ) {                  DeviceStatusForm *pStatusForm = iter->second;
                 DeviceStatusForm* pForm = iter->second;  
740                  m_ui.viewMidiDeviceStatusMenu->addAction(                  m_ui.viewMidiDeviceStatusMenu->addAction(
741                          pForm->visibleAction()                          pStatusForm->visibleAction());
                 );  
742          }          }
743  }  }
744    
745    
746  // Context menu event handler.  // Context menu event handler.
747  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )
748  {  {
# Line 638  void MainForm::contextMenuEvent( QContex Line 753  void MainForm::contextMenuEvent( QContex
753    
754    
755  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
756  // qsamplerMainForm -- Brainless public property accessors.  // QSampler::MainForm -- Brainless public property accessors.
757    
758  // The global options settings property.  // The global options settings property.
759  Options *MainForm::options (void) const  Options *MainForm::options (void) const
# Line 662  MainForm *MainForm::getInstance (void) Line 777  MainForm *MainForm::getInstance (void)
777    
778    
779  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
780  // qsamplerMainForm -- Session file stuff.  // QSampler::MainForm -- Session file stuff.
781    
782  // Format the displayable session filename.  // Format the displayable session filename.
783  QString MainForm::sessionName ( const QString& sFilename )  QString MainForm::sessionName ( const QString& sFilename )
784  {  {
785          bool bCompletePath = (m_pOptions && m_pOptions->bCompletePath);          const bool bCompletePath = (m_pOptions && m_pOptions->bCompletePath);
786          QString sSessionName = sFilename;          QString sSessionName = sFilename;
787          if (sSessionName.isEmpty())          if (sSessionName.isEmpty())
788                  sSessionName = tr("Untitled") + QString::number(m_iUntitled);                  sSessionName = tr("Untitled") + QString::number(m_iUntitled);
# Line 801  bool MainForm::closeSession ( bool bForc Line 916  bool MainForm::closeSession ( bool bForc
916          if (bClose) {          if (bClose) {
917                  // Remove all channel strips from sight...                  // Remove all channel strips from sight...
918                  m_pWorkspace->setUpdatesEnabled(false);                  m_pWorkspace->setUpdatesEnabled(false);
919                  QWidgetList wlist = m_pWorkspace->windowList();                  const QList<QMdiSubWindow *>& wlist
920                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                          = m_pWorkspace->subWindowList();
921                          ChannelStrip *pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  const int iStripCount = wlist.count();
922                    for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
923                            ChannelStrip *pChannelStrip = NULL;
924                            QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
925                            if (pMdiSubWindow)
926                                    pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
927                          if (pChannelStrip) {                          if (pChannelStrip) {
928                                  Channel *pChannel = pChannelStrip->channel();                                  Channel *pChannel = pChannelStrip->channel();
929                                  if (bForce && pChannel)                                  if (bForce && pChannel)
930                                          pChannel->removeChannel();                                          pChannel->removeChannel();
931                                  delete pChannelStrip;                                  delete pChannelStrip;
932                          }                          }
933                            if (pMdiSubWindow)
934                                    delete pMdiSubWindow;
935                  }                  }
936                  m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
937                  // We're now clean, for sure.                  // We're now clean, for sure.
# Line 921  bool MainForm::saveSessionFile ( const Q Line 1043  bool MainForm::saveSessionFile ( const Q
1043          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1044    
1045          // Write the file.          // Write the file.
1046          int  iErrors = 0;          int iErrors = 0;
1047          QTextStream ts(&file);          QTextStream ts(&file);
1048          ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;          ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;
1049          ts << "# " << tr("Version")          ts << "# " << tr("Version") << ": " CONFIG_BUILD_VERSION << endl;
1050          << ": " QSAMPLER_VERSION << endl;  //      ts << "# " << tr("Build") << ": " CONFIG_BUILD_DATE << endl;
         ts << "# " << tr("Build")  
         << ": " __DATE__ " " __TIME__ << endl;  
1051          ts << "#"  << endl;          ts << "#"  << endl;
1052          ts << "# " << tr("File")          ts << "# " << tr("File")
1053          << ": " << QFileInfo(sFilename).fileName() << endl;          << ": " << QFileInfo(sFilename).fileName() << endl;
# Line 1033  bool MainForm::saveSessionFile ( const Q Line 1153  bool MainForm::saveSessionFile ( const Q
1153          QMap<int, int> midiInstrumentMap;          QMap<int, int> midiInstrumentMap;
1154          int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);          int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);
1155          for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {          for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {
1156                  int iMidiMap = piMaps[iMap];                  const int iMidiMap = piMaps[iMap];
1157                  const char *pszMapName                  const char *pszMapName
1158                          = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);                          = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);
1159                  ts << "# " << tr("MIDI instrument map") << " " << iMap;                  ts << "# " << tr("MIDI instrument map") << " " << iMap;
# Line 1100  bool MainForm::saveSessionFile ( const Q Line 1220  bool MainForm::saveSessionFile ( const Q
1220  #endif  // CONFIG_MIDI_INSTRUMENT  #endif  // CONFIG_MIDI_INSTRUMENT
1221    
1222          // Sampler channel mapping.          // Sampler channel mapping.
1223          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
1224          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                  = m_pWorkspace->subWindowList();
1225                  ChannelStrip* pChannelStrip          const int iStripCount = wlist.count();
1226                          = static_cast<ChannelStrip *> (wlist.at(iChannel));          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
1227                    ChannelStrip *pChannelStrip = NULL;
1228                    QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
1229                    if (pMdiSubWindow)
1230                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
1231                  if (pChannelStrip) {                  if (pChannelStrip) {
1232                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1233                          if (pChannel) {                          if (pChannel) {
1234                                  ts << "# " << tr("Channel") << " " << iChannel << endl;                                  const int iChannelID = pChannel->channelID();
1235                                    ts << "# " << tr("Channel") << " " << iChannelID << endl;
1236                                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
1237                                  if (audioDeviceMap.isEmpty()) {                                  if (audioDeviceMap.isEmpty()) {
1238                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannelID
1239                                                  << " " << pChannel->audioDriver() << endl;                                                  << " " << pChannel->audioDriver() << endl;
1240                                  } else {                                  } else {
1241                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannelID
1242                                                  << " " << audioDeviceMap[pChannel->audioDevice()] << endl;                                                  << " " << audioDeviceMap[pChannel->audioDevice()] << endl;
1243                                  }                                  }
1244                                  if (midiDeviceMap.isEmpty()) {                                  if (midiDeviceMap.isEmpty()) {
1245                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannel                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID
1246                                                  << " " << pChannel->midiDriver() << endl;                                                  << " " << pChannel->midiDriver() << endl;
1247                                  } else {                                  } else {
1248                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannel                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannelID
1249                                                  << " " << midiDeviceMap[pChannel->midiDevice()] << endl;                                                  << " " << midiDeviceMap[pChannel->midiDevice()] << endl;
1250                                  }                                  }
1251                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID
1252                                          << " " << pChannel->midiPort() << endl;                                          << " " << pChannel->midiPort() << endl;
1253                                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";                                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannelID << " ";
1254                                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)                                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
1255                                          ts << "ALL";                                          ts << "ALL";
1256                                  else                                  else
1257                                          ts << pChannel->midiChannel();                                          ts << pChannel->midiChannel();
1258                                  ts << endl;                                  ts << endl;
1259                                  ts << "LOAD ENGINE " << pChannel->engineName()                                  ts << "LOAD ENGINE " << pChannel->engineName()
1260                                          << " " << iChannel << endl;                                          << " " << iChannelID << endl;
1261                                  if (pChannel->instrumentStatus() < 100) ts << "# ";                                  if (pChannel->instrumentStatus() < 100) ts << "# ";
1262                                  ts << "LOAD INSTRUMENT NON_MODAL '"                                  ts << "LOAD INSTRUMENT NON_MODAL '"
1263                                          << pChannel->instrumentFile() << "' "                                          << pChannel->instrumentFile() << "' "
1264                                          << pChannel->instrumentNr() << " " << iChannel << endl;                                          << pChannel->instrumentNr() << " " << iChannelID << endl;
1265                                  ChannelRoutingMap::ConstIterator audioRoute;                                  ChannelRoutingMap::ConstIterator audioRoute;
1266                                  for (audioRoute = pChannel->audioRouting().begin();                                  for (audioRoute = pChannel->audioRouting().begin();
1267                                                  audioRoute != pChannel->audioRouting().end();                                                  audioRoute != pChannel->audioRouting().end();
1268                                                          ++audioRoute) {                                                          ++audioRoute) {
1269                                          ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannelID
1270                                                  << " " << audioRoute.key()                                                  << " " << audioRoute.key()
1271                                                  << " " << audioRoute.value() << endl;                                                  << " " << audioRoute.value() << endl;
1272                                  }                                  }
1273                                  ts << "SET CHANNEL VOLUME " << iChannel                                  ts << "SET CHANNEL VOLUME " << iChannelID
1274                                          << " " << pChannel->volume() << endl;                                          << " " << pChannel->volume() << endl;
1275                                  if (pChannel->channelMute())                                  if (pChannel->channelMute())
1276                                          ts << "SET CHANNEL MUTE " << iChannel << " 1" << endl;                                          ts << "SET CHANNEL MUTE " << iChannelID << " 1" << endl;
1277                                  if (pChannel->channelSolo())                                  if (pChannel->channelSolo())
1278                                          ts << "SET CHANNEL SOLO " << iChannel << " 1" << endl;                                          ts << "SET CHANNEL SOLO " << iChannelID << " 1" << endl;
1279  #ifdef CONFIG_MIDI_INSTRUMENT                          #ifdef CONFIG_MIDI_INSTRUMENT
1280                                  if (pChannel->midiMap() >= 0) {                                  if (pChannel->midiMap() >= 0) {
1281                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannel                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannelID
1282                                                  << " " << midiInstrumentMap[pChannel->midiMap()] << endl;                                                  << " " << midiInstrumentMap[pChannel->midiMap()] << endl;
1283                                  }                                  }
1284  #endif                          #endif
1285  #ifdef CONFIG_FXSEND                          #ifdef CONFIG_FXSEND
                                 int iChannelID = pChannel->channelID();  
1286                                  int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID);                                  int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID);
1287                                  for (int iFxSend = 0;                                  for (int iFxSend = 0;
1288                                                  piFxSends && piFxSends[iFxSend] >= 0;                                                  piFxSends && piFxSends[iFxSend] >= 0;
# Line 1166  bool MainForm::saveSessionFile ( const Q Line 1290  bool MainForm::saveSessionFile ( const Q
1290                                          lscp_fxsend_info_t *pFxSendInfo = ::lscp_get_fxsend_info(                                          lscp_fxsend_info_t *pFxSendInfo = ::lscp_get_fxsend_info(
1291                                                  m_pClient, iChannelID, piFxSends[iFxSend]);                                                  m_pClient, iChannelID, piFxSends[iFxSend]);
1292                                          if (pFxSendInfo) {                                          if (pFxSendInfo) {
1293                                                  ts << "CREATE FX_SEND " << iChannel                                                  ts << "CREATE FX_SEND " << iChannelID
1294                                                          << " " << pFxSendInfo->midi_controller;                                                          << " " << pFxSendInfo->midi_controller;
1295                                                  if (pFxSendInfo->name)                                                  if (pFxSendInfo->name)
1296                                                          ts << " '" << pFxSendInfo->name << "'";                                                          ts << " '" << pFxSendInfo->name << "'";
# Line 1176  bool MainForm::saveSessionFile ( const Q Line 1300  bool MainForm::saveSessionFile ( const Q
1300                                                                  piRouting && piRouting[iAudioSrc] >= 0;                                                                  piRouting && piRouting[iAudioSrc] >= 0;
1301                                                                          iAudioSrc++) {                                                                          iAudioSrc++) {
1302                                                          ts << "SET FX_SEND AUDIO_OUTPUT_CHANNEL "                                                          ts << "SET FX_SEND AUDIO_OUTPUT_CHANNEL "
1303                                                                  << iChannel                                                                  << iChannelID
1304                                                                  << " " << iFxSend                                                                  << " " << iFxSend
1305                                                                  << " " << iAudioSrc                                                                  << " " << iAudioSrc
1306                                                                  << " " << piRouting[iAudioSrc] << endl;                                                                  << " " << piRouting[iAudioSrc] << endl;
1307                                                  }                                                  }
1308  #ifdef CONFIG_FXSEND_LEVEL                                          #ifdef CONFIG_FXSEND_LEVEL
1309                                                  ts << "SET FX_SEND LEVEL " << iChannel                                                  ts << "SET FX_SEND LEVEL " << iChannelID
1310                                                          << " " << iFxSend                                                          << " " << iFxSend
1311                                                          << " " << pFxSendInfo->level << endl;                                                          << " " << pFxSendInfo->level << endl;
1312  #endif                                          #endif
1313                                          }       // Check for errors...                                          }       // Check for errors...
1314                                          else if (::lscp_client_get_errno(m_pClient)) {                                          else if (::lscp_client_get_errno(m_pClient)) {
1315                                                  appendMessagesClient("lscp_get_fxsend_info");                                                  appendMessagesClient("lscp_get_fxsend_info");
1316                                                  iErrors++;                                                  iErrors++;
1317                                          }                                          }
1318                                  }                                  }
1319  #endif                          #endif
1320                                  ts << endl;                                  ts << endl;
1321                          }                          }
1322                  }                  }
# Line 1245  void MainForm::sessionDirty (void) Line 1369  void MainForm::sessionDirty (void)
1369    
1370    
1371  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1372  // qsamplerMainForm -- File Action slots.  // QSampler::MainForm -- File Action slots.
1373    
1374  // Create a new sampler session.  // Create a new sampler session.
1375  void MainForm::fileNew (void)  void MainForm::fileNew (void)
# Line 1269  void MainForm::fileOpenRecent (void) Line 1393  void MainForm::fileOpenRecent (void)
1393          // Retrive filename index from action data...          // Retrive filename index from action data...
1394          QAction *pAction = qobject_cast<QAction *> (sender());          QAction *pAction = qobject_cast<QAction *> (sender());
1395          if (pAction && m_pOptions) {          if (pAction && m_pOptions) {
1396                  int iIndex = pAction->data().toInt();                  const int iIndex = pAction->data().toInt();
1397                  if (iIndex >= 0 && iIndex < m_pOptions->recentFiles.count()) {                  if (iIndex >= 0 && iIndex < m_pOptions->recentFiles.count()) {
1398                          QString sFilename = m_pOptions->recentFiles[iIndex];                          QString sFilename = m_pOptions->recentFiles[iIndex];
1399                          // Check if we can safely close the current session...                          // Check if we can safely close the current session...
# Line 1303  void MainForm::fileReset (void) Line 1427  void MainForm::fileReset (void)
1427                  return;                  return;
1428    
1429          // Ask user whether he/she want's an internal sampler reset...          // Ask user whether he/she want's an internal sampler reset...
1430          if (QMessageBox::warning(this,          if (m_pOptions && m_pOptions->bConfirmReset) {
1431                  QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");
1432                  tr("Resetting the sampler instance will close\n"                  const QString& sText = tr(
1433                  "all device and channel configurations.\n\n"                          "Resetting the sampler instance will close\n"
1434                  "Please note that this operation may cause\n"                          "all device and channel configurations.\n\n"
1435                  "temporary MIDI and Audio disruption.\n\n"                          "Please note that this operation may cause\n"
1436                  "Do you want to reset the sampler engine now?"),                          "temporary MIDI and Audio disruption.\n\n"
1437                  QMessageBox::Ok | QMessageBox::Cancel)                          "Do you want to reset the sampler engine now?");
1438                  == QMessageBox::Cancel)          #if 0
1439                  return;                  if (QMessageBox::warning(this, sTitle, sText,
1440                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1441                            return;
1442            #else
1443                    QMessageBox mbox(this);
1444                    mbox.setIcon(QMessageBox::Warning);
1445                    mbox.setWindowTitle(sTitle);
1446                    mbox.setText(sText);
1447                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1448                    QCheckBox cbox(tr("Don't ask this again"));
1449                    cbox.setChecked(false);
1450                    cbox.blockSignals(true);
1451                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1452                    if (mbox.exec() == QMessageBox::Cancel)
1453                            return;
1454                    if (cbox.isChecked())
1455                            m_pOptions->bConfirmReset = false;
1456            #endif
1457            }
1458    
1459          // Trye closing the current session, first...          // Trye closing the current session, first...
1460          if (!closeSession(true))          if (!closeSession(true))
# Line 1344  void MainForm::fileRestart (void) Line 1486  void MainForm::fileRestart (void)
1486    
1487          // Ask user whether he/she want's a complete restart...          // Ask user whether he/she want's a complete restart...
1488          // (if we're currently up and running)          // (if we're currently up and running)
1489          if (bRestart && m_pClient) {          if (m_pOptions && m_pOptions->bConfirmRestart) {
1490                  bRestart = (QMessageBox::warning(this,                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");
1491                          QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sText = tr(
1492                          tr("New settings will be effective after\n"                          "New settings will be effective after\n"
1493                          "restarting the client/server connection.\n\n"                          "restarting the client/server connection.\n\n"
1494                          "Please note that this operation may cause\n"                          "Please note that this operation may cause\n"
1495                          "temporary MIDI and Audio disruption.\n\n"                          "temporary MIDI and Audio disruption.\n\n"
1496                          "Do you want to restart the connection now?"),                          "Do you want to restart the connection now?");
1497                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok);          #if 0
1498                    if (QMessageBox::warning(this, sTitle, sText,
1499                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1500                            bRestart = false;
1501            #else
1502                    QMessageBox mbox(this);
1503                    mbox.setIcon(QMessageBox::Warning);
1504                    mbox.setWindowTitle(sTitle);
1505                    mbox.setText(sText);
1506                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1507                    QCheckBox cbox(tr("Don't ask this again"));
1508                    cbox.setChecked(false);
1509                    cbox.blockSignals(true);
1510                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1511                    if (mbox.exec() == QMessageBox::Cancel)
1512                            bRestart = false;
1513                    else
1514                    if (cbox.isChecked())
1515                            m_pOptions->bConfirmRestart = false;
1516            #endif
1517          }          }
1518    
1519          // Are we still for it?          // Are we still for it?
# Line 1374  void MainForm::fileExit (void) Line 1535  void MainForm::fileExit (void)
1535    
1536    
1537  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1538  // qsamplerMainForm -- Edit Action slots.  // QSampler::MainForm -- Edit Action slots.
1539    
1540  // Add a new sampler channel.  // Add a new sampler channel.
1541  void MainForm::editAddChannel (void)  void MainForm::editAddChannel (void)
1542  {  {
1543            ++m_iDirtySetup;
1544            addChannelStrip();
1545            --m_iDirtySetup;
1546    }
1547    
1548    void MainForm::addChannelStrip (void)
1549    {
1550          if (m_pClient == NULL)          if (m_pClient == NULL)
1551                  return;                  return;
1552    
# Line 1402  void MainForm::editAddChannel (void) Line 1570  void MainForm::editAddChannel (void)
1570          }          }
1571    
1572          // Do we auto-arrange?          // Do we auto-arrange?
1573          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
1574    
1575          // Make that an overall update.          // Make that an overall update.
1576          m_iDirtyCount++;          m_iDirtyCount++;
# Line 1414  void MainForm::editAddChannel (void) Line 1581  void MainForm::editAddChannel (void)
1581  // Remove current sampler channel.  // Remove current sampler channel.
1582  void MainForm::editRemoveChannel (void)  void MainForm::editRemoveChannel (void)
1583  {  {
1584            ++m_iDirtySetup;
1585            removeChannelStrip();
1586            --m_iDirtySetup;
1587    }
1588    
1589    void MainForm::removeChannelStrip (void)
1590    {
1591          if (m_pClient == NULL)          if (m_pClient == NULL)
1592                  return;                  return;
1593    
1594          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1595          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1596                  return;                  return;
1597    
# Line 1427  void MainForm::editRemoveChannel (void) Line 1601  void MainForm::editRemoveChannel (void)
1601    
1602          // Prompt user if he/she's sure about this...          // Prompt user if he/she's sure about this...
1603          if (m_pOptions && m_pOptions->bConfirmRemove) {          if (m_pOptions && m_pOptions->bConfirmRemove) {
1604                  if (QMessageBox::warning(this,                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");
1605                          QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sText = tr(
1606                          tr("About to remove channel:\n\n"                          "About to remove channel:\n\n"
1607                          "%1\n\n"                          "%1\n\n"
1608                          "Are you sure?")                          "Are you sure?")
1609                          .arg(pChannelStrip->windowTitle()),                          .arg(pChannelStrip->windowTitle());
1610                          QMessageBox::Ok | QMessageBox::Cancel)          #if 0
1611                          == QMessageBox::Cancel)                  if (QMessageBox::warning(this, sTitle, sText,
1612                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1613                          return;                          return;
1614            #else
1615                    QMessageBox mbox(this);
1616                    mbox.setIcon(QMessageBox::Warning);
1617                    mbox.setWindowTitle(sTitle);
1618                    mbox.setText(sText);
1619                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1620                    QCheckBox cbox(tr("Don't ask this again"));
1621                    cbox.setChecked(false);
1622                    cbox.blockSignals(true);
1623                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1624                    if (mbox.exec() == QMessageBox::Cancel)
1625                            return;
1626                    if (cbox.isChecked())
1627                            m_pOptions->bConfirmRemove = false;
1628            #endif
1629          }          }
1630    
1631          // Remove the existing sampler channel.          // Remove the existing sampler channel.
# Line 1443  void MainForm::editRemoveChannel (void) Line 1633  void MainForm::editRemoveChannel (void)
1633                  return;                  return;
1634    
1635          // Just delete the channel strip.          // Just delete the channel strip.
1636          delete pChannelStrip;          destroyChannelStrip(pChannelStrip);
   
         // Do we auto-arrange?  
         if (m_pOptions && m_pOptions->bAutoArrange)  
                 channelsArrange();  
1637    
1638          // We'll be dirty, for sure...          // We'll be dirty, for sure...
1639          m_iDirtyCount++;          m_iDirtyCount++;
# Line 1461  void MainForm::editSetupChannel (void) Line 1647  void MainForm::editSetupChannel (void)
1647          if (m_pClient == NULL)          if (m_pClient == NULL)
1648                  return;                  return;
1649    
1650          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1651          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1652                  return;                  return;
1653    
# Line 1476  void MainForm::editEditChannel (void) Line 1662  void MainForm::editEditChannel (void)
1662          if (m_pClient == NULL)          if (m_pClient == NULL)
1663                  return;                  return;
1664    
1665          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1666          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1667                  return;                  return;
1668    
# Line 1491  void MainForm::editResetChannel (void) Line 1677  void MainForm::editResetChannel (void)
1677          if (m_pClient == NULL)          if (m_pClient == NULL)
1678                  return;                  return;
1679    
1680          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1681          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1682                  return;                  return;
1683    
# Line 1509  void MainForm::editResetAllChannels (voi Line 1695  void MainForm::editResetAllChannels (voi
1695          // Invoque the channel strip procedure,          // Invoque the channel strip procedure,
1696          // for all channels out there...          // for all channels out there...
1697          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1698          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
1699          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                  = m_pWorkspace->subWindowList();
1700                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);          const int iStripCount = wlist.count();
1701            for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
1702                    ChannelStrip *pChannelStrip = NULL;
1703                    QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
1704                    if (pMdiSubWindow)
1705                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
1706                  if (pChannelStrip)                  if (pChannelStrip)
1707                          pChannelStrip->channelReset();                          pChannelStrip->channelReset();
1708          }          }
# Line 1520  void MainForm::editResetAllChannels (voi Line 1711  void MainForm::editResetAllChannels (voi
1711    
1712    
1713  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1714  // qsamplerMainForm -- View Action slots.  // QSampler::MainForm -- View Action slots.
1715    
1716  // Show/hide the main program window menubar.  // Show/hide the main program window menubar.
1717  void MainForm::viewMenubar ( bool bOn )  void MainForm::viewMenubar ( bool bOn )
# Line 1614  void MainForm::viewOptions (void) Line 1805  void MainForm::viewOptions (void)
1805          OptionsForm* pOptionsForm = new OptionsForm(this);          OptionsForm* pOptionsForm = new OptionsForm(this);
1806          if (pOptionsForm) {          if (pOptionsForm) {
1807                  // Check out some initial nullities(tm)...                  // Check out some initial nullities(tm)...
1808                  ChannelStrip* pChannelStrip = activeChannelStrip();                  ChannelStrip *pChannelStrip = activeChannelStrip();
1809                  if (m_pOptions->sDisplayFont.isEmpty() && pChannelStrip)                  if (m_pOptions->sDisplayFont.isEmpty() && pChannelStrip)
1810                          m_pOptions->sDisplayFont = pChannelStrip->displayFont().toString();                          m_pOptions->sDisplayFont = pChannelStrip->displayFont().toString();
1811                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)
1812                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();
1813                  // To track down deferred or immediate changes.                  // To track down deferred or immediate changes.
1814                  QString sOldServerHost      = m_pOptions->sServerHost;                  const QString sOldServerHost      = m_pOptions->sServerHost;
1815                  int     iOldServerPort      = m_pOptions->iServerPort;                  const int     iOldServerPort      = m_pOptions->iServerPort;
1816                  int     iOldServerTimeout   = m_pOptions->iServerTimeout;                  const int     iOldServerTimeout   = m_pOptions->iServerTimeout;
1817                  bool    bOldServerStart     = m_pOptions->bServerStart;                  const bool    bOldServerStart     = m_pOptions->bServerStart;
1818                  QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;                  const QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;
1819                  bool    bOldMessagesLog     = m_pOptions->bMessagesLog;                  const bool    bOldMessagesLog     = m_pOptions->bMessagesLog;
1820                  QString sOldMessagesLogPath = m_pOptions->sMessagesLogPath;                  const QString sOldMessagesLogPath = m_pOptions->sMessagesLogPath;
1821                  QString sOldDisplayFont     = m_pOptions->sDisplayFont;                  const QString sOldDisplayFont     = m_pOptions->sDisplayFont;
1822                  bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;                  const bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1823                  int     iOldMaxVolume       = m_pOptions->iMaxVolume;                  const int     iOldMaxVolume       = m_pOptions->iMaxVolume;
1824                  QString sOldMessagesFont    = m_pOptions->sMessagesFont;                  const QString sOldMessagesFont    = m_pOptions->sMessagesFont;
1825                  bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;                  const bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;
1826                  bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;                  const bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;
1827                  int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;                  const int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;
1828                  int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;                  const int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1829                  bool    bOldCompletePath    = m_pOptions->bCompletePath;                  const bool    bOldCompletePath    = m_pOptions->bCompletePath;
1830                  bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;                  const bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1831                  int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;                  const int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1832                  int     iOldBaseFontSize    = m_pOptions->iBaseFontSize;                  const int     iOldBaseFontSize    = m_pOptions->iBaseFontSize;
1833                  // Load the current setup settings.                  // Load the current setup settings.
1834                  pOptionsForm->setup(m_pOptions);                  pOptionsForm->setup(m_pOptions);
1835                  // Show the setup dialog...                  // Show the setup dialog...
# Line 1701  void MainForm::viewOptions (void) Line 1892  void MainForm::viewOptions (void)
1892    
1893    
1894  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1895  // qsamplerMainForm -- Channels action slots.  // QSampler::MainForm -- Channels action slots.
1896    
1897  // Arrange channel strips.  // Arrange channel strips.
1898  void MainForm::channelsArrange (void)  void MainForm::channelsArrange (void)
1899  {  {
1900          // Full width vertical tiling          // Full width vertical tiling
1901          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
1902                    = m_pWorkspace->subWindowList();
1903          if (wlist.isEmpty())          if (wlist.isEmpty())
1904                  return;                  return;
1905    
1906          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1907          int y = 0;          int y = 0;
1908          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          const int iStripCount = wlist.count();
1909                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
1910          /*  if (pChannelStrip->testWState(WState_Maximized | WState_Minimized)) {                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
1911                          // Prevent flicker...                  if (pMdiSubWindow) {
1912                          pChannelStrip->hide();                          pMdiSubWindow->adjustSize();
1913                          pChannelStrip->showNormal();                          int iWidth = m_pWorkspace->width();
1914                  }   */                          if (iWidth < pMdiSubWindow->width())
1915                  pChannelStrip->adjustSize();                                  iWidth = pMdiSubWindow->width();
1916                  int iWidth  = m_pWorkspace->width();                          const int iHeight = pMdiSubWindow->frameGeometry().height();
1917                  if (iWidth < pChannelStrip->width())                          pMdiSubWindow->setGeometry(0, y, iWidth, iHeight);
1918                          iWidth = pChannelStrip->width();                          y += iHeight;
1919          //  int iHeight = pChannelStrip->height()                  }
         //              + pChannelStrip->parentWidget()->baseSize().height();  
                 int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();  
                 pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);  
                 y += iHeight;  
1920          }          }
1921          m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
1922    
# Line 1746  void MainForm::channelsAutoArrange ( boo Line 1934  void MainForm::channelsAutoArrange ( boo
1934          m_pOptions->bAutoArrange = bOn;          m_pOptions->bAutoArrange = bOn;
1935    
1936          // If on, update whole workspace...          // If on, update whole workspace...
1937          if (m_pOptions->bAutoArrange)          channelsArrangeAuto();
1938    }
1939    
1940    
1941    void MainForm::channelsArrangeAuto (void)
1942    {
1943            if (m_pOptions && m_pOptions->bAutoArrange)
1944                  channelsArrange();                  channelsArrange();
1945  }  }
1946    
1947    
1948  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1949  // qsamplerMainForm -- Help Action slots.  // QSampler::MainForm -- Help Action slots.
1950    
1951  // Show information about the Qt toolkit.  // Show information about the Qt toolkit.
1952  void MainForm::helpAboutQt (void)  void MainForm::helpAboutQt (void)
# Line 1764  void MainForm::helpAboutQt (void) Line 1958  void MainForm::helpAboutQt (void)
1958  // Show information about application program.  // Show information about application program.
1959  void MainForm::helpAbout (void)  void MainForm::helpAbout (void)
1960  {  {
1961          // 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";  
1962  #ifdef CONFIG_DEBUG  #ifdef CONFIG_DEBUG
1963          sText += "<small><font color=\"red\">";          list << tr("Debugging option enabled.");
         sText += tr("Debugging option enabled.");  
         sText += "</font></small><br />";  
1964  #endif  #endif
1965  #ifndef CONFIG_LIBGIG  #ifndef CONFIG_LIBGIG
1966          sText += "<small><font color=\"red\">";          list << tr("GIG (libgig) file support disabled.");
         sText += tr("GIG (libgig) file support disabled.");  
         sText += "</font></small><br />";  
1967  #endif  #endif
1968  #ifndef CONFIG_INSTRUMENT_NAME  #ifndef CONFIG_INSTRUMENT_NAME
1969          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 />";  
1970  #endif  #endif
1971  #ifndef CONFIG_MUTE_SOLO  #ifndef CONFIG_MUTE_SOLO
1972          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 />";  
1973  #endif  #endif
1974  #ifndef CONFIG_AUDIO_ROUTING  #ifndef CONFIG_AUDIO_ROUTING
1975          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 />";  
1976  #endif  #endif
1977  #ifndef CONFIG_FXSEND  #ifndef CONFIG_FXSEND
1978          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 />";  
1979  #endif  #endif
1980  #ifndef CONFIG_VOLUME  #ifndef CONFIG_VOLUME
1981          sText += "<small><font color=\"red\">";          list << tr("Global volume support disabled.");
         sText += tr("Global volume support disabled.");  
         sText += "</font></small><br />";  
1982  #endif  #endif
1983  #ifndef CONFIG_MIDI_INSTRUMENT  #ifndef CONFIG_MIDI_INSTRUMENT
1984          sText += "<small><font color=\"red\">";          list << tr("MIDI instrument mapping support disabled.");
         sText += tr("MIDI instrument mapping support disabled.");  
         sText += "</font></small><br />";  
1985  #endif  #endif
1986  #ifndef CONFIG_EDIT_INSTRUMENT  #ifndef CONFIG_EDIT_INSTRUMENT
1987          sText += "<small><font color=\"red\">";          list << tr("Instrument editing support disabled.");
         sText += tr("Instrument editing support disabled.");  
         sText += "</font></small><br />";  
1988  #endif  #endif
1989  #ifndef CONFIG_EVENT_CHANNEL_MIDI  #ifndef CONFIG_EVENT_CHANNEL_MIDI
1990          sText += "<small><font color=\"red\">";          list << tr("Channel MIDI event support disabled.");
         sText += tr("Channel MIDI event support disabled.");  
         sText += "</font></small><br />";  
1991  #endif  #endif
1992  #ifndef CONFIG_EVENT_DEVICE_MIDI  #ifndef CONFIG_EVENT_DEVICE_MIDI
1993          sText += "<small><font color=\"red\">";          list << tr("Device MIDI event support disabled.");
         sText += tr("Device MIDI event support disabled.");  
         sText += "</font></small><br />";  
1994  #endif  #endif
1995  #ifndef CONFIG_MAX_VOICES  #ifndef CONFIG_MAX_VOICES
1996          sText += "<small><font color=\"red\">";          list << tr("Runtime max. voices / disk streams support disabled.");
         sText += tr("Runtime max. voices / disk streams support disabled.");  
         sText += "</font></small><br />";  
1997  #endif  #endif
1998    
1999            // Stuff the about box text...
2000            QString sText = "<p>\n";
2001            sText += "<b>" QSAMPLER_TITLE " - " + tr(QSAMPLER_SUBTITLE) + "</b><br />\n";
2002            sText += "<br />\n";
2003            sText += tr("Version") + ": <b>" CONFIG_BUILD_VERSION "</b><br />\n";
2004    //      sText += "<small>" + tr("Build") + ": " CONFIG_BUILD_DATE "</small><br />\n";
2005            if (!list.isEmpty()) {
2006                    sText += "<small><font color=\"red\">";
2007                    sText += list.join("<br />\n");
2008                    sText += "</font></small>";
2009            }
2010          sText += "<br />\n";          sText += "<br />\n";
2011          sText += tr("Using") + ": ";          sText += tr("Using") + ": ";
2012          sText += ::lscp_client_package();          sText += ::lscp_client_package();
# Line 1859  void MainForm::helpAbout (void) Line 2036  void MainForm::helpAbout (void)
2036    
2037    
2038  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2039  // qsamplerMainForm -- Main window stabilization.  // QSampler::MainForm -- Main window stabilization.
2040    
2041  void MainForm::stabilizeForm (void)  void MainForm::stabilizeForm (void)
2042  {  {
# Line 1870  void MainForm::stabilizeForm (void) Line 2047  void MainForm::stabilizeForm (void)
2047          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));
2048    
2049          // Update the main menu state...          // Update the main menu state...
2050          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
2051          bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);          const QList<QMdiSubWindow *>& wlist = m_pWorkspace->subWindowList();
2052          bool bHasChannel = (bHasClient && pChannelStrip != NULL);          const bool bHasClient = (m_pOptions != NULL && m_pClient != NULL);
2053            const bool bHasChannel = (bHasClient && pChannelStrip != NULL);
2054            const bool bHasChannels = (bHasClient && wlist.count() > 0);
2055          m_ui.fileNewAction->setEnabled(bHasClient);          m_ui.fileNewAction->setEnabled(bHasClient);
2056          m_ui.fileOpenAction->setEnabled(bHasClient);          m_ui.fileOpenAction->setEnabled(bHasClient);
2057          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
# Line 1888  void MainForm::stabilizeForm (void) Line 2067  void MainForm::stabilizeForm (void)
2067          m_ui.editEditChannelAction->setEnabled(false);          m_ui.editEditChannelAction->setEnabled(false);
2068  #endif  #endif
2069          m_ui.editResetChannelAction->setEnabled(bHasChannel);          m_ui.editResetChannelAction->setEnabled(bHasChannel);
2070          m_ui.editResetAllChannelsAction->setEnabled(bHasChannel);          m_ui.editResetAllChannelsAction->setEnabled(bHasChannels);
2071          m_ui.viewMessagesAction->setChecked(m_pMessages && m_pMessages->isVisible());          m_ui.viewMessagesAction->setChecked(m_pMessages && m_pMessages->isVisible());
2072  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
2073          m_ui.viewInstrumentsAction->setChecked(m_pInstrumentListForm          m_ui.viewInstrumentsAction->setChecked(m_pInstrumentListForm
# Line 1900  void MainForm::stabilizeForm (void) Line 2079  void MainForm::stabilizeForm (void)
2079          m_ui.viewDevicesAction->setChecked(m_pDeviceForm          m_ui.viewDevicesAction->setChecked(m_pDeviceForm
2080                  && m_pDeviceForm->isVisible());                  && m_pDeviceForm->isVisible());
2081          m_ui.viewDevicesAction->setEnabled(bHasClient);          m_ui.viewDevicesAction->setEnabled(bHasClient);
2082          m_ui.channelsArrangeAction->setEnabled(bHasChannel);          m_ui.viewMidiDeviceStatusMenu->setEnabled(
2083                    DeviceStatusForm::getInstances().size() > 0);
2084            m_ui.channelsArrangeAction->setEnabled(bHasChannels);
2085    
2086  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
2087          // Toolbar widgets are also affected...          // Toolbar widgets are also affected...
# Line 1950  void MainForm::volumeChanged ( int iVolu Line 2131  void MainForm::volumeChanged ( int iVolu
2131                  m_pVolumeSpinBox->setValue(iVolume);                  m_pVolumeSpinBox->setValue(iVolume);
2132    
2133          // Do it as commanded...          // Do it as commanded...
2134          float fVolume = 0.01f * float(iVolume);          const float fVolume = 0.01f * float(iVolume);
2135          if (::lscp_set_volume(m_pClient, fVolume) == LSCP_OK)          if (::lscp_set_volume(m_pClient, fVolume) == LSCP_OK)
2136                  appendMessages(QObject::tr("Volume: %1.").arg(fVolume));                  appendMessages(QObject::tr("Volume: %1.").arg(fVolume));
2137          else          else
# Line 1966  void MainForm::volumeChanged ( int iVolu Line 2147  void MainForm::volumeChanged ( int iVolu
2147    
2148    
2149  // Channel change receiver slot.  // Channel change receiver slot.
2150  void MainForm::channelStripChanged(ChannelStrip* pChannelStrip)  void MainForm::channelStripChanged ( ChannelStrip *pChannelStrip )
2151  {  {
2152          // Add this strip to the changed list...          // Add this strip to the changed list...
2153          if (!m_changedStrips.contains(pChannelStrip)) {          if (!m_changedStrips.contains(pChannelStrip)) {
# Line 1985  void MainForm::channelStripChanged(Chann Line 2166  void MainForm::channelStripChanged(Chann
2166  void MainForm::updateSession (void)  void MainForm::updateSession (void)
2167  {  {
2168  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
2169          int iVolume = ::lroundf(100.0f * ::lscp_get_volume(m_pClient));          const int iVolume = ::lroundf(100.0f * ::lscp_get_volume(m_pClient));
2170          m_iVolumeChanging++;          m_iVolumeChanging++;
2171          m_pVolumeSlider->setValue(iVolume);          m_pVolumeSlider->setValue(iVolume);
2172          m_pVolumeSpinBox->setValue(iVolume);          m_pVolumeSpinBox->setValue(iVolume);
# Line 1993  void MainForm::updateSession (void) Line 2174  void MainForm::updateSession (void)
2174  #endif  #endif
2175  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
2176          // FIXME: Make some room for default instrument maps...          // FIXME: Make some room for default instrument maps...
2177          int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);          const int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);
2178          if (iMaps < 0)          if (iMaps < 0)
2179                  appendMessagesClient("lscp_get_midi_instrument_maps");                  appendMessagesClient("lscp_get_midi_instrument_maps");
2180          else if (iMaps < 1) {          else if (iMaps < 1) {
# Line 2007  void MainForm::updateSession (void) Line 2188  void MainForm::updateSession (void)
2188          updateAllChannelStrips(false);          updateAllChannelStrips(false);
2189    
2190          // Do we auto-arrange?          // Do we auto-arrange?
2191          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
2192    
2193          // Remember to refresh devices and instruments...          // Remember to refresh devices and instruments...
2194          if (m_pInstrumentListForm)          if (m_pInstrumentListForm)
# Line 2017  void MainForm::updateSession (void) Line 2197  void MainForm::updateSession (void)
2197                  m_pDeviceForm->refreshDevices();                  m_pDeviceForm->refreshDevices();
2198  }  }
2199    
2200  void MainForm::updateAllChannelStrips(bool bRemoveDeadStrips) {  
2201    void MainForm::updateAllChannelStrips ( bool bRemoveDeadStrips )
2202    {
2203            // Skip if setting up a new channel strip...
2204            if (m_iDirtySetup > 0)
2205                    return;
2206    
2207          // Retrieve the current channel list.          // Retrieve the current channel list.
2208          int *piChannelIDs = ::lscp_list_channels(m_pClient);          int *piChannelIDs = ::lscp_list_channels(m_pClient);
2209          if (piChannelIDs == NULL) {          if (piChannelIDs == NULL) {
# Line 2029  void MainForm::updateAllChannelStrips(bo Line 2215  void MainForm::updateAllChannelStrips(bo
2215          } else {          } else {
2216                  // Try to (re)create each channel.                  // Try to (re)create each channel.
2217                  m_pWorkspace->setUpdatesEnabled(false);                  m_pWorkspace->setUpdatesEnabled(false);
2218                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {
2219                          // Check if theres already a channel strip for this one...                          // Check if theres already a channel strip for this one...
2220                          if (!channelStrip(piChannelIDs[iChannel]))                          if (!channelStrip(piChannelIDs[iChannel]))
2221                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));
2222                  }                  }
   
2223                  // Do we auto-arrange?                  // Do we auto-arrange?
2224                  if (m_pOptions && m_pOptions->bAutoArrange)                  channelsArrangeAuto();
                         channelsArrange();  
   
                 stabilizeForm();  
   
2225                  // remove dead channel strips                  // remove dead channel strips
2226                  if (bRemoveDeadStrips) {                  if (bRemoveDeadStrips) {
2227                          for (int i = 0; channelStripAt(i); ++i) {                          const QList<QMdiSubWindow *>& wlist
2228                                  ChannelStrip* pChannelStrip = channelStripAt(i);                                  = m_pWorkspace->subWindowList();
2229                                  bool bExists = false;                          const int iStripCount = wlist.count();
2230                                  for (int j = 0; piChannelIDs[j] >= 0; ++j) {                          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2231                                          if (!pChannelStrip->channel()) break;                                  ChannelStrip *pChannelStrip = NULL;
2232                                          if (piChannelIDs[j] == pChannelStrip->channel()->channelID()) {                                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2233                                                  // strip exists, don't touch it                                  if (pMdiSubWindow)
2234                                                  bExists = true;                                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2235                                                  break;                                  if (pChannelStrip) {
2236                                            bool bExists = false;
2237                                            for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {
2238                                                    Channel *pChannel = pChannelStrip->channel();
2239                                                    if (pChannel == NULL)
2240                                                            break;
2241                                                    if (piChannelIDs[iChannel] == pChannel->channelID()) {
2242                                                            // strip exists, don't touch it
2243                                                            bExists = true;
2244                                                            break;
2245                                                    }
2246                                          }                                          }
2247                                            if (!bExists)
2248                                                    destroyChannelStrip(pChannelStrip);
2249                                  }                                  }
                                 if (!bExists) destroyChannelStrip(pChannelStrip);  
2250                          }                          }
2251                  }                  }
2252                  m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
2253          }          }
2254    
2255            stabilizeForm();
2256  }  }
2257    
2258    
2259  // Update the recent files list and menu.  // Update the recent files list and menu.
2260  void MainForm::updateRecentFiles ( const QString& sFilename )  void MainForm::updateRecentFiles ( const QString& sFilename )
2261  {  {
# Line 2068  void MainForm::updateRecentFiles ( const Line 2263  void MainForm::updateRecentFiles ( const
2263                  return;                  return;
2264    
2265          // Remove from list if already there (avoid duplicates)          // Remove from list if already there (avoid duplicates)
2266          int iIndex = m_pOptions->recentFiles.indexOf(sFilename);          const int iIndex = m_pOptions->recentFiles.indexOf(sFilename);
2267          if (iIndex >= 0)          if (iIndex >= 0)
2268                  m_pOptions->recentFiles.removeAt(iIndex);                  m_pOptions->recentFiles.removeAt(iIndex);
2269          // Put it to front...          // Put it to front...
# Line 2107  void MainForm::updateRecentFilesMenu (vo Line 2302  void MainForm::updateRecentFilesMenu (vo
2302  void MainForm::updateInstrumentNames (void)  void MainForm::updateInstrumentNames (void)
2303  {  {
2304          // Full channel list update...          // Full channel list update...
2305          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2306                    = m_pWorkspace->subWindowList();
2307          if (wlist.isEmpty())          if (wlist.isEmpty())
2308                  return;                  return;
2309    
2310          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2311          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          const int iStripCount = wlist.count();
2312                  ChannelStrip *pChannelStrip = (ChannelStrip *) wlist.at(iChannel);          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2313                    ChannelStrip *pChannelStrip = NULL;
2314                    QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2315                    if (pMdiSubWindow)
2316                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2317                  if (pChannelStrip)                  if (pChannelStrip)
2318                          pChannelStrip->updateInstrumentName(true);                          pChannelStrip->updateInstrumentName(true);
2319          }          }
# Line 2130  void MainForm::updateDisplayFont (void) Line 2330  void MainForm::updateDisplayFont (void)
2330          // Check if display font is legal.          // Check if display font is legal.
2331          if (m_pOptions->sDisplayFont.isEmpty())          if (m_pOptions->sDisplayFont.isEmpty())
2332                  return;                  return;
2333    
2334          // Realize it.          // Realize it.
2335          QFont font;          QFont font;
2336          if (!font.fromString(m_pOptions->sDisplayFont))          if (!font.fromString(m_pOptions->sDisplayFont))
2337                  return;                  return;
2338    
2339          // Full channel list update...          // Full channel list update...
2340          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2341                    = m_pWorkspace->subWindowList();
2342          if (wlist.isEmpty())          if (wlist.isEmpty())
2343                  return;                  return;
2344    
2345          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2346          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          const int iStripCount = wlist.count();
2347                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2348                    ChannelStrip *pChannelStrip = NULL;
2349                    QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2350                    if (pMdiSubWindow)
2351                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2352                  if (pChannelStrip)                  if (pChannelStrip)
2353                          pChannelStrip->setDisplayFont(font);                          pChannelStrip->setDisplayFont(font);
2354          }          }
# Line 2154  void MainForm::updateDisplayFont (void) Line 2360  void MainForm::updateDisplayFont (void)
2360  void MainForm::updateDisplayEffect (void)  void MainForm::updateDisplayEffect (void)
2361  {  {
2362          // Full channel list update...          // Full channel list update...
2363          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2364                    = m_pWorkspace->subWindowList();
2365          if (wlist.isEmpty())          if (wlist.isEmpty())
2366                  return;                  return;
2367    
2368          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2369          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          const int iStripCount = wlist.count();
2370                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2371                    ChannelStrip *pChannelStrip = NULL;
2372                    QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2373                    if (pMdiSubWindow)
2374                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2375                  if (pChannelStrip)                  if (pChannelStrip)
2376                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2377          }          }
# Line 2182  void MainForm::updateMaxVolume (void) Line 2393  void MainForm::updateMaxVolume (void)
2393  #endif  #endif
2394    
2395          // Full channel list update...          // Full channel list update...
2396          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2397                    = m_pWorkspace->subWindowList();
2398          if (wlist.isEmpty())          if (wlist.isEmpty())
2399                  return;                  return;
2400    
2401          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2402          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          const int iStripCount = wlist.count();
2403                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2404                    ChannelStrip *pChannelStrip = NULL;
2405                    QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2406                    if (pMdiSubWindow)
2407                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2408                  if (pChannelStrip)                  if (pChannelStrip)
2409                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2410          }          }
# Line 2197  void MainForm::updateMaxVolume (void) Line 2413  void MainForm::updateMaxVolume (void)
2413    
2414    
2415  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2416  // qsamplerMainForm -- Messages window form handlers.  // QSampler::MainForm -- Messages window form handlers.
2417    
2418  // Messages output methods.  // Messages output methods.
2419  void MainForm::appendMessages( const QString& s )  void MainForm::appendMessages( const QString& s )
# Line 2222  void MainForm::appendMessagesText( const Line 2438  void MainForm::appendMessagesText( const
2438                  m_pMessages->appendMessagesText(s);                  m_pMessages->appendMessagesText(s);
2439  }  }
2440    
2441  void MainForm::appendMessagesError( const QString& s )  void MainForm::appendMessagesError( const QString& sText )
2442  {  {
2443          if (m_pMessages)          if (m_pMessages)
2444                  m_pMessages->show();                  m_pMessages->show();
2445    
2446          appendMessagesColor(s.simplified(), "#ff0000");          appendMessagesColor(sText.simplified(), "#ff0000");
2447    
2448          // Make it look responsive...:)          // Make it look responsive...:)
2449          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2450    
2451          QMessageBox::critical(this,          if (m_pOptions && m_pOptions->bConfirmError) {
2452                  QSAMPLER_TITLE ": " + tr("Error"), s, QMessageBox::Cancel);                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Error");
2453            #if 0
2454                    QMessageBox::critical(this, sTitle, sText, QMessageBox::Cancel);
2455            #else
2456                    QMessageBox mbox(this);
2457                    mbox.setIcon(QMessageBox::Critical);
2458                    mbox.setWindowTitle(sTitle);
2459                    mbox.setText(sText);
2460                    mbox.setStandardButtons(QMessageBox::Cancel);
2461                    QCheckBox cbox(tr("Don't show this again"));
2462                    cbox.setChecked(false);
2463                    cbox.blockSignals(true);
2464                    mbox.addButton(&cbox, QMessageBox::ActionRole);
2465                    if (mbox.exec() && cbox.isChecked())
2466                            m_pOptions->bConfirmError = false;
2467            #endif
2468            }
2469  }  }
2470    
2471    
# Line 2293  void MainForm::updateMessagesCapture (vo Line 2525  void MainForm::updateMessagesCapture (vo
2525    
2526    
2527  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2528  // qsamplerMainForm -- MDI channel strip management.  // QSampler::MainForm -- MDI channel strip management.
2529    
2530  // The channel strip creation executive.  // The channel strip creation executive.
2531  ChannelStrip* MainForm::createChannelStrip ( Channel *pChannel )  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )
2532  {  {
2533          if (m_pClient == NULL || pChannel == NULL)          if (m_pClient == NULL || pChannel == NULL)
2534                  return NULL;                  return NULL;
# Line 2312  ChannelStrip* MainForm::createChannelStr Line 2544  ChannelStrip* MainForm::createChannelStr
2544                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2545                  // We'll need a display font.                  // We'll need a display font.
2546                  QFont font;                  QFont font;
2547                  if (font.fromString(m_pOptions->sDisplayFont))                  if (!m_pOptions->sDisplayFont.isEmpty() &&
2548                            font.fromString(m_pOptions->sDisplayFont))
2549                          pChannelStrip->setDisplayFont(font);                          pChannelStrip->setDisplayFont(font);
2550                  // Maximum allowed volume setting.                  // Maximum allowed volume setting.
2551                  pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                  pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2552          }          }
2553    
2554          // Add it to workspace...          // Add it to workspace...
2555          m_pWorkspace->addWindow(pChannelStrip, Qt::FramelessWindowHint);          m_pWorkspace->addSubWindow(pChannelStrip,
2556                    Qt::SubWindow | Qt::FramelessWindowHint);
2557    
2558          // Actual channel strip setup...          // Actual channel strip setup...
2559          pChannelStrip->setup(pChannel);          pChannelStrip->setup(pChannel);
2560    
2561          QObject::connect(pChannelStrip,          QObject::connect(pChannelStrip,
2562                  SIGNAL(channelChanged(ChannelStrip*)),                  SIGNAL(channelChanged(ChannelStrip *)),
2563                  SLOT(channelStripChanged(ChannelStrip*)));                  SLOT(channelStripChanged(ChannelStrip *)));
2564    
2565          // Now we show up us to the world.          // Now we show up us to the world.
2566          pChannelStrip->show();          pChannelStrip->show();
# Line 2338  ChannelStrip* MainForm::createChannelStr Line 2572  ChannelStrip* MainForm::createChannelStr
2572          return pChannelStrip;          return pChannelStrip;
2573  }  }
2574    
2575  void MainForm::destroyChannelStrip(ChannelStrip* pChannelStrip) {  
2576    void MainForm::destroyChannelStrip ( ChannelStrip *pChannelStrip )
2577    {
2578            QMdiSubWindow *pMdiSubWindow
2579                    = static_cast<QMdiSubWindow *> (pChannelStrip->parentWidget());
2580            if (pMdiSubWindow == NULL)
2581                    return;
2582    
2583          // Just delete the channel strip.          // Just delete the channel strip.
2584          delete pChannelStrip;          delete pChannelStrip;
2585            delete pMdiSubWindow;
2586    
2587          // Do we auto-arrange?          // Do we auto-arrange?
2588          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
   
         stabilizeForm();  
2589  }  }
2590    
2591    
2592  // Retrieve the active channel strip.  // Retrieve the active channel strip.
2593  ChannelStrip* MainForm::activeChannelStrip (void)  ChannelStrip *MainForm::activeChannelStrip (void)
2594  {  {
2595          return static_cast<ChannelStrip *> (m_pWorkspace->activeWindow());          QMdiSubWindow *pMdiSubWindow = m_pWorkspace->activeSubWindow();
2596            if (pMdiSubWindow)
2597                    return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2598            else
2599                    return NULL;
2600  }  }
2601    
2602    
2603  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2604  ChannelStrip* MainForm::channelStripAt ( int iChannel )  ChannelStrip *MainForm::channelStripAt ( int iStrip )
2605  {  {
2606          if (!m_pWorkspace) return NULL;          if (!m_pWorkspace) return NULL;
2607    
2608          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2609                    = m_pWorkspace->subWindowList();
2610          if (wlist.isEmpty())          if (wlist.isEmpty())
2611                  return NULL;                  return NULL;
2612    
2613          if (iChannel < 0 || iChannel >= wlist.size())          if (iStrip < 0 || iStrip >= wlist.count())
2614                  return NULL;                  return NULL;
2615    
2616          return dynamic_cast<ChannelStrip *> (wlist.at(iChannel));          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2617            if (pMdiSubWindow)
2618                    return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2619            else
2620                    return NULL;
2621  }  }
2622    
2623    
2624  // Retrieve a channel strip by sampler channel id.  // Retrieve a channel strip by sampler channel id.
2625  ChannelStrip* MainForm::channelStrip ( int iChannelID )  ChannelStrip *MainForm::channelStrip ( int iChannelID )
2626  {  {
2627          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2628                    = m_pWorkspace->subWindowList();
2629          if (wlist.isEmpty())          if (wlist.isEmpty())
2630                  return NULL;                  return NULL;
2631    
2632          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          const int iStripCount = wlist.count();
2633                  ChannelStrip* pChannelStrip          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2634                          = static_cast<ChannelStrip*> (wlist.at(iChannel));                  ChannelStrip *pChannelStrip = NULL;
2635                    QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2636                    if (pMdiSubWindow)
2637                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2638                  if (pChannelStrip) {                  if (pChannelStrip) {
2639                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
2640                          if (pChannel && pChannel->channelID() == iChannelID)                          if (pChannel && pChannel->channelID() == iChannelID)
# Line 2401  void MainForm::channelsMenuAboutToShow ( Line 2654  void MainForm::channelsMenuAboutToShow (
2654          m_ui.channelsMenu->addAction(m_ui.channelsArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsArrangeAction);
2655          m_ui.channelsMenu->addAction(m_ui.channelsAutoArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsAutoArrangeAction);
2656    
2657          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2658                    = m_pWorkspace->subWindowList();
2659          if (!wlist.isEmpty()) {          if (!wlist.isEmpty()) {
2660                  m_ui.channelsMenu->addSeparator();                  m_ui.channelsMenu->addSeparator();
2661                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                  const int iStripCount = wlist.count();
2662                          ChannelStrip* pChannelStrip                  for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2663                                  = static_cast<ChannelStrip*> (wlist.at(iChannel));                          ChannelStrip *pChannelStrip = NULL;
2664                            QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2665                            if (pMdiSubWindow)
2666                                    pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2667                          if (pChannelStrip) {                          if (pChannelStrip) {
2668                                  QAction *pAction = m_ui.channelsMenu->addAction(                                  QAction *pAction = m_ui.channelsMenu->addAction(
2669                                          pChannelStrip->windowTitle(),                                          pChannelStrip->windowTitle(),
2670                                          this, SLOT(channelsMenuActivated()));                                          this, SLOT(channelsMenuActivated()));
2671                                  pAction->setCheckable(true);                                  pAction->setCheckable(true);
2672                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);
2673                                  pAction->setData(iChannel);                                  pAction->setData(iStrip);
2674                          }                          }
2675                  }                  }
2676          }          }
# Line 2428  void MainForm::channelsMenuActivated (vo Line 2685  void MainForm::channelsMenuActivated (vo
2685          if (pAction == NULL)          if (pAction == NULL)
2686                  return;                  return;
2687    
2688          ChannelStrip* pChannelStrip = channelStripAt(pAction->data().toInt());          ChannelStrip *pChannelStrip = channelStripAt(pAction->data().toInt());
2689          if (pChannelStrip) {          if (pChannelStrip) {
2690                  pChannelStrip->showNormal();                  pChannelStrip->showNormal();
2691                  pChannelStrip->setFocus();                  pChannelStrip->setFocus();
# Line 2437  void MainForm::channelsMenuActivated (vo Line 2694  void MainForm::channelsMenuActivated (vo
2694    
2695    
2696  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2697  // qsamplerMainForm -- Timer stuff.  // QSampler::MainForm -- Timer stuff.
2698    
2699  // Set the pseudo-timer delay schedule.  // Set the pseudo-timer delay schedule.
2700  void MainForm::startSchedule ( int iStartDelay )  void MainForm::startSchedule ( int iStartDelay )
# Line 2478  void MainForm::timerSlot (void) Line 2735  void MainForm::timerSlot (void)
2735                          ChannelStrip *pChannelStrip = iter.next();                          ChannelStrip *pChannelStrip = iter.next();
2736                          // If successfull, remove from pending list...                          // If successfull, remove from pending list...
2737                          if (pChannelStrip->updateChannelInfo()) {                          if (pChannelStrip->updateChannelInfo()) {
2738                                  int iChannelStrip = m_changedStrips.indexOf(pChannelStrip);                                  const int iChannelStrip = m_changedStrips.indexOf(pChannelStrip);
2739                                  if (iChannelStrip >= 0)                                  if (iChannelStrip >= 0)
2740                                          m_changedStrips.removeAt(iChannelStrip);                                          m_changedStrips.removeAt(iChannelStrip);
2741                          }                          }
# Line 2489  void MainForm::timerSlot (void) Line 2746  void MainForm::timerSlot (void)
2746                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {
2747                                  m_iTimerSlot = 0;                                  m_iTimerSlot = 0;
2748                                  // Update the channel stream usage for each strip...                                  // Update the channel stream usage for each strip...
2749                                  QWidgetList wlist = m_pWorkspace->windowList();                                  const QList<QMdiSubWindow *>& wlist
2750                                  for (int iChannel = 0;                                          = m_pWorkspace->subWindowList();
2751                                                  iChannel < (int) wlist.count(); iChannel++) {                                  const int iStripCount = wlist.count();
2752                                          ChannelStrip* pChannelStrip                                  for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2753                                                  = (ChannelStrip*) wlist.at(iChannel);                                          ChannelStrip *pChannelStrip = NULL;
2754                                            QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2755                                            if (pMdiSubWindow)
2756                                                    pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2757                                          if (pChannelStrip && pChannelStrip->isVisible())                                          if (pChannelStrip && pChannelStrip->isVisible())
2758                                                  pChannelStrip->updateChannelUsage();                                                  pChannelStrip->updateChannelUsage();
2759                                  }                                  }
# Line 2507  void MainForm::timerSlot (void) Line 2767  void MainForm::timerSlot (void)
2767    
2768    
2769  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2770  // qsamplerMainForm -- Server stuff.  // QSampler::MainForm -- Server stuff.
2771    
2772  // Start linuxsampler server...  // Start linuxsampler server...
2773  void MainForm::startServer (void)  void MainForm::startServer (void)
# Line 2541  void MainForm::startServer (void) Line 2801  void MainForm::startServer (void)
2801    
2802          // OK. Let's build the startup process...          // OK. Let's build the startup process...
2803          m_pServer = new QProcess();          m_pServer = new QProcess();
2804          bForceServerStop = true;          m_bForceServerStop = true;
2805    
2806          // Setup stdout/stderr capture...          // Setup stdout/stderr capture...
2807  //      if (m_pOptions->bStdoutCapture) {          m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);
2808  #if QT_VERSION >= 0x040200          QObject::connect(m_pServer,
2809                  m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);                  SIGNAL(readyReadStandardOutput()),
2810  #endif                  SLOT(readServerStdout()));
2811                  QObject::connect(m_pServer,          QObject::connect(m_pServer,
2812                          SIGNAL(readyReadStandardOutput()),                  SIGNAL(readyReadStandardError()),
2813                          SLOT(readServerStdout()));                  SLOT(readServerStdout()));
                 QObject::connect(m_pServer,  
                         SIGNAL(readyReadStandardError()),  
                         SLOT(readServerStdout()));  
 //      }  
2814    
2815          // The unforgiveable signal communication...          // The unforgiveable signal communication...
2816          QObject::connect(m_pServer,          QObject::connect(m_pServer,
# Line 2589  void MainForm::startServer (void) Line 2845  void MainForm::startServer (void)
2845    
2846    
2847  // Stop linuxsampler server...  // Stop linuxsampler server...
2848  void MainForm::stopServer (bool bInteractive)  void MainForm::stopServer ( bool bInteractive )
2849  {  {
2850          // Stop client code.          // Stop client code.
2851          stopClient();          stopClient();
# Line 2601  void MainForm::stopServer (bool bInterac Line 2857  void MainForm::stopServer (bool bInterac
2857                          "running in the background. The sampler would continue to work\n"                          "running in the background. The sampler would continue to work\n"
2858                          "according to your current sampler session and you could alter the\n"                          "according to your current sampler session and you could alter the\n"
2859                          "sampler session at any time by relaunching QSampler.\n\n"                          "sampler session at any time by relaunching QSampler.\n\n"
2860                          "Do you want LinuxSampler to stop or to keep running in\n"                          "Do you want LinuxSampler to stop?"),
2861                          "the background?"),                          QMessageBox::Yes | QMessageBox::No,
2862                          QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)                          QMessageBox::Yes) == QMessageBox::No) {
2863                  {                          m_bForceServerStop = false;
                         bForceServerStop = false;  
2864                  }                  }
2865          }          }
2866    
2867          // And try to stop server.          // And try to stop server.
2868          if (m_pServer && bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2869                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2870                  if (m_pServer->state() == QProcess::Running) {                  if (m_pServer->state() == QProcess::Running) {
2871  #if defined(WIN32)                  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
2872                          // Try harder...                          // Try harder...
2873                          m_pServer->kill();                          m_pServer->kill();
2874  #else                  #else
2875                          // Try softly...                          // Try softly...
2876                          m_pServer->terminate();                          m_pServer->terminate();
2877  #endif                  #endif
2878                  }                  }
2879          }       // Do final processing anyway.          }       // Do final processing anyway.
2880          else processServerExit();          else processServerExit();
# Line 2650  void MainForm::processServerExit (void) Line 2905  void MainForm::processServerExit (void)
2905          if (m_pMessages)          if (m_pMessages)
2906                  m_pMessages->flushStdoutBuffer();                  m_pMessages->flushStdoutBuffer();
2907    
2908          if (m_pServer && bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2909                  if (m_pServer->state() != QProcess::NotRunning) {                  if (m_pServer->state() != QProcess::NotRunning) {
2910                          appendMessages(tr("Server is being forced..."));                          appendMessages(tr("Server is being forced..."));
2911                          // Force final server shutdown...                          // Force final server shutdown...
# Line 2675  void MainForm::processServerExit (void) Line 2930  void MainForm::processServerExit (void)
2930    
2931    
2932  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2933  // qsamplerMainForm -- Client stuff.  // QSampler::MainForm -- Client stuff.
2934    
2935  // The LSCP client callback procedure.  // The LSCP client callback procedure.
2936  lscp_status_t qsampler_client_callback ( lscp_client_t */*pClient*/,  lscp_status_t qsampler_client_callback ( lscp_client_t */*pClient*/,
# Line 2689  lscp_status_t qsampler_client_callback ( Line 2944  lscp_status_t qsampler_client_callback (
2944          // as this is run under some other thread context.          // as this is run under some other thread context.
2945          // A custom event must be posted here...          // A custom event must be posted here...
2946          QApplication::postEvent(pMainForm,          QApplication::postEvent(pMainForm,
2947                  new CustomEvent(event, pchData, cchData));                  new LscpEvent(event, pchData, cchData));
2948    
2949          return LSCP_OK;          return LSCP_OK;
2950  }  }
# Line 2727  bool MainForm::startClient (void) Line 2982  bool MainForm::startClient (void)
2982                  stabilizeForm();                  stabilizeForm();
2983                  return false;                  return false;
2984          }          }
2985    
2986          // Just set receive timeout value, blindly.          // Just set receive timeout value, blindly.
2987          ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);          ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
2988          appendMessages(          appendMessages(
# Line 2848  void MainForm::stopClient (void) Line 3104  void MainForm::stopClient (void)
3104    
3105    
3106  // Channel strip activation/selection.  // Channel strip activation/selection.
3107  void MainForm::activateStrip ( QWidget *pWidget )  void MainForm::activateStrip ( QMdiSubWindow *pMdiSubWindow )
3108  {  {
3109          ChannelStrip *pChannelStrip          ChannelStrip *pChannelStrip = NULL;
3110                  = static_cast<ChannelStrip *> (pWidget);          if (pMdiSubWindow)
3111                    pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
3112          if (pChannelStrip)          if (pChannelStrip)
3113                  pChannelStrip->setSelected(true);                  pChannelStrip->setSelected(true);
3114    
# Line 2859  void MainForm::activateStrip ( QWidget * Line 3116  void MainForm::activateStrip ( QWidget *
3116  }  }
3117    
3118    
3119    // Channel toolbar orientation change.
3120    void MainForm::channelsToolbarOrientation ( Qt::Orientation orientation )
3121    {
3122    #ifdef CONFIG_VOLUME
3123            m_pVolumeSlider->setOrientation(orientation);
3124            if (orientation == Qt::Horizontal) {
3125                    m_pVolumeSlider->setMinimumHeight(24);
3126                    m_pVolumeSlider->setMaximumHeight(32);
3127                    m_pVolumeSlider->setMinimumWidth(120);
3128                    m_pVolumeSlider->setMaximumWidth(640);
3129                    m_pVolumeSpinBox->setMaximumWidth(64);
3130                    m_pVolumeSpinBox->setButtonSymbols(QSpinBox::UpDownArrows);
3131            } else {
3132                    m_pVolumeSlider->setMinimumHeight(120);
3133                    m_pVolumeSlider->setMaximumHeight(480);
3134                    m_pVolumeSlider->setMinimumWidth(24);
3135                    m_pVolumeSlider->setMaximumWidth(32);
3136                    m_pVolumeSpinBox->setMaximumWidth(32);
3137                    m_pVolumeSpinBox->setButtonSymbols(QSpinBox::NoButtons);
3138            }
3139    #endif
3140    }
3141    
3142    
3143  } // namespace QSampler  } // namespace QSampler
3144    
3145    

Legend:
Removed from v.1840  
changed lines
  Added in v.3358

  ViewVC Help
Powered by ViewVC