/[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 1815 by capela, Mon Dec 22 10:04:59 2008 UTC revision 3437 by capela, Mon Dec 3 16:30:53 2018 UTC
# Line 1  Line 1 
1  // qsamplerMainForm.cpp  // qsamplerMainForm.cpp
2  //  //
3  /****************************************************************************  /****************************************************************************
4     Copyright (C) 2004-2008, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2018, 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    
144    
145  #define QSAMPLER_CUSTOM_EVENT   QEvent::Type(QEvent::User + 0)  //-------------------------------------------------------------------------
146    // QSampler::LscpEvent -- specialty for LSCP callback comunication.
147    
148  class CustomEvent : public QEvent  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 751  bool MainForm::saveSession ( bool bPromp Line 866  bool MainForm::saveSession ( bool bPromp
866                  // Enforce .lscp extension...                  // Enforce .lscp extension...
867                  if (QFileInfo(sFilename).suffix().isEmpty())                  if (QFileInfo(sFilename).suffix().isEmpty())
868                          sFilename += ".lscp";                          sFilename += ".lscp";
869            #if 0
870                  // Check if already exists...                  // Check if already exists...
871                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
872                          if (QMessageBox::warning(this,                          if (QMessageBox::warning(this,
# Line 759  bool MainForm::saveSession ( bool bPromp Line 875  bool MainForm::saveSession ( bool bPromp
875                                  "\"%1\"\n\n"                                  "\"%1\"\n\n"
876                                  "Do you want to replace it?")                                  "Do you want to replace it?")
877                                  .arg(sFilename),                                  .arg(sFilename),
878                                  tr("Replace"), tr("Cancel")) > 0)                                  QMessageBox::Yes | QMessageBox::No)
879                                    == QMessageBox::No)
880                                  return false;                                  return false;
881                  }                  }
882            #endif
883          }          }
884    
885          // Save it right away.          // Save it right away.
# Line 782  bool MainForm::closeSession ( bool bForc Line 900  bool MainForm::closeSession ( bool bForc
900                          "\"%1\"\n\n"                          "\"%1\"\n\n"
901                          "Do you want to save the changes?")                          "Do you want to save the changes?")
902                          .arg(sessionName(m_sFilename)),                          .arg(sessionName(m_sFilename)),
903                          tr("Save"), tr("Discard"), tr("Cancel"))) {                          QMessageBox::Save |
904                  case 0:     // Save...                          QMessageBox::Discard |
905                            QMessageBox::Cancel)) {
906                    case QMessageBox::Save:
907                          bClose = saveSession(false);                          bClose = saveSession(false);
908                          // Fall thru....                          // Fall thru....
909                  case 1:     // Discard                  case QMessageBox::Discard:
910                          break;                          break;
911                  default:    // Cancel.                  default:    // Cancel.
912                          bClose = false;                          bClose = false;
# Line 798  bool MainForm::closeSession ( bool bForc Line 918  bool MainForm::closeSession ( bool bForc
918          if (bClose) {          if (bClose) {
919                  // Remove all channel strips from sight...                  // Remove all channel strips from sight...
920                  m_pWorkspace->setUpdatesEnabled(false);                  m_pWorkspace->setUpdatesEnabled(false);
921                  QWidgetList wlist = m_pWorkspace->windowList();                  const QList<QMdiSubWindow *>& wlist
922                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                          = m_pWorkspace->subWindowList();
923                          ChannelStrip *pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  const int iStripCount = wlist.count();
924                    for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
925                            ChannelStrip *pChannelStrip = NULL;
926                            QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
927                            if (pMdiSubWindow)
928                                    pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
929                          if (pChannelStrip) {                          if (pChannelStrip) {
930                                  Channel *pChannel = pChannelStrip->channel();                                  Channel *pChannel = pChannelStrip->channel();
931                                  if (bForce && pChannel)                                  if (bForce && pChannel)
932                                          pChannel->removeChannel();                                          pChannel->removeChannel();
933                                  delete pChannelStrip;                                  delete pChannelStrip;
934                          }                          }
935                            if (pMdiSubWindow)
936                                    delete pMdiSubWindow;
937                  }                  }
938                  m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
939                  // We're now clean, for sure.                  // We're now clean, for sure.
# Line 918  bool MainForm::saveSessionFile ( const Q Line 1045  bool MainForm::saveSessionFile ( const Q
1045          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1046    
1047          // Write the file.          // Write the file.
1048          int  iErrors = 0;          int iErrors = 0;
1049          QTextStream ts(&file);          QTextStream ts(&file);
1050          ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;          ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;
1051          ts << "# " << tr("Version")          ts << "# " << tr("Version") << ": " CONFIG_BUILD_VERSION << endl;
1052          << ": " QSAMPLER_VERSION << endl;  //      ts << "# " << tr("Build") << ": " CONFIG_BUILD_DATE << endl;
         ts << "# " << tr("Build")  
         << ": " __DATE__ " " __TIME__ << endl;  
1053          ts << "#"  << endl;          ts << "#"  << endl;
1054          ts << "# " << tr("File")          ts << "# " << tr("File")
1055          << ": " << QFileInfo(sFilename).fileName() << endl;          << ": " << QFileInfo(sFilename).fileName() << endl;
# Line 937  bool MainForm::saveSessionFile ( const Q Line 1062  bool MainForm::saveSessionFile ( const Q
1062          // It is assumed that this new kind of device+session file          // It is assumed that this new kind of device+session file
1063          // will be loaded from a complete initialized server...          // will be loaded from a complete initialized server...
1064          int *piDeviceIDs;          int *piDeviceIDs;
1065          int  iDevice;          int  i, iDevice;
1066          ts << "RESET" << endl;          ts << "RESET" << endl;
1067    
1068          // Audio device mapping.          // Audio device mapping.
1069          QMap<int, int> audioDeviceMap;          QMap<int, int> audioDeviceMap; iDevice = 0;
1070          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);
1071          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1072                  ts << endl;                  Device device(Device::Audio, piDeviceIDs[i]);
1073                  Device device(Device::Audio, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1074                    if (device.driverName().toUpper() == "PLUGIN")
1075                            continue;
1076                  // Audio device specification...                  // Audio device specification...
1077                    ts << endl;
1078                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1079                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1080                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
# Line 977  bool MainForm::saveSessionFile ( const Q Line 1105  bool MainForm::saveSessionFile ( const Q
1105                          iPort++;                          iPort++;
1106                  }                  }
1107                  // Audio device index/id mapping.                  // Audio device index/id mapping.
1108                  audioDeviceMap[device.deviceID()] = iDevice;                  audioDeviceMap.insert(device.deviceID(), iDevice++);
1109                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1110                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1111          }          }
1112    
1113          // MIDI device mapping.          // MIDI device mapping.
1114          QMap<int, int> midiDeviceMap;          QMap<int, int> midiDeviceMap; iDevice = 0;
1115          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);
1116          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1117                  ts << endl;                  Device device(Device::Midi, piDeviceIDs[i]);
1118                  Device device(Device::Midi, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1119                    if (device.driverName().toUpper() == "PLUGIN")
1120                            continue;
1121                  // MIDI device specification...                  // MIDI device specification...
1122                    ts << endl;
1123                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1124                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1125                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
# Line 1019  bool MainForm::saveSessionFile ( const Q Line 1150  bool MainForm::saveSessionFile ( const Q
1150                          iPort++;                          iPort++;
1151                  }                  }
1152                  // MIDI device index/id mapping.                  // MIDI device index/id mapping.
1153                  midiDeviceMap[device.deviceID()] = iDevice;                  midiDeviceMap.insert(device.deviceID(), iDevice++);
1154                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1155                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1156          }          }
# Line 1030  bool MainForm::saveSessionFile ( const Q Line 1161  bool MainForm::saveSessionFile ( const Q
1161          QMap<int, int> midiInstrumentMap;          QMap<int, int> midiInstrumentMap;
1162          int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);          int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);
1163          for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {          for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {
1164                  int iMidiMap = piMaps[iMap];                  const int iMidiMap = piMaps[iMap];
1165                  const char *pszMapName                  const char *pszMapName
1166                          = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);                          = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);
1167                  ts << "# " << tr("MIDI instrument map") << " " << iMap;                  ts << "# " << tr("MIDI instrument map") << " " << iMap;
# Line 1087  bool MainForm::saveSessionFile ( const Q Line 1218  bool MainForm::saveSessionFile ( const Q
1218                          iErrors++;                          iErrors++;
1219                  }                  }
1220                  // MIDI strument index/id mapping.                  // MIDI strument index/id mapping.
1221                  midiInstrumentMap[iMidiMap] = iMap;                  midiInstrumentMap.insert(iMidiMap, iMap);
1222          }          }
1223          // Check for errors...          // Check for errors...
1224          if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {          if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {
# Line 1096  bool MainForm::saveSessionFile ( const Q Line 1227  bool MainForm::saveSessionFile ( const Q
1227          }          }
1228  #endif  // CONFIG_MIDI_INSTRUMENT  #endif  // CONFIG_MIDI_INSTRUMENT
1229    
1230          // Sampler channel mapping.          // Sampler channel mapping...
1231          QWidgetList wlist = m_pWorkspace->windowList();          int iChannelID = 0;
1232          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          const QList<QMdiSubWindow *>& wlist
1233                  ChannelStrip* pChannelStrip                  = m_pWorkspace->subWindowList();
1234                          = static_cast<ChannelStrip *> (wlist.at(iChannel));          const int iStripCount = wlist.count();
1235            for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
1236                    ChannelStrip *pChannelStrip = NULL;
1237                    QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
1238                    if (pMdiSubWindow)
1239                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
1240                  if (pChannelStrip) {                  if (pChannelStrip) {
1241                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1242                          if (pChannel) {                          if (pChannel) {
1243                                  ts << "# " << tr("Channel") << " " << iChannel << endl;                                  // Avoid "artifial" plug-in devices...
1244                                    const int iAudioDevice = pChannel->audioDevice();
1245                                    if (!audioDeviceMap.contains(iAudioDevice))
1246                                            continue;
1247                                    const int iMidiDevice = pChannel->midiDevice();
1248                                    if (!midiDeviceMap.contains(iMidiDevice))
1249                                            continue;
1250                                    // Go for regular, canonical devices...
1251                                    ts << "# " << tr("Channel") << " " << iChannelID << endl;
1252                                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
1253                                  if (audioDeviceMap.isEmpty()) {                                  if (audioDeviceMap.isEmpty()) {
1254                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannelID
1255                                                  << " " << pChannel->audioDriver() << endl;                                                  << " " << pChannel->audioDriver() << endl;
1256                                  } else {                                  } else {
1257                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannelID
1258                                                  << " " << audioDeviceMap[pChannel->audioDevice()] << endl;                                                  << " " << audioDeviceMap.value(iAudioDevice) << endl;
1259                                  }                                  }
1260                                  if (midiDeviceMap.isEmpty()) {                                  if (midiDeviceMap.isEmpty()) {
1261                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannel                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID
1262                                                  << " " << pChannel->midiDriver() << endl;                                                  << " " << pChannel->midiDriver() << endl;
1263                                  } else {                                  } else {
1264                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannel                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannelID
1265                                                  << " " << midiDeviceMap[pChannel->midiDevice()] << endl;                                                  << " " << midiDeviceMap.value(iMidiDevice) << endl;
1266                                  }                                  }
1267                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID
1268                                          << " " << pChannel->midiPort() << endl;                                          << " " << pChannel->midiPort() << endl;
1269                                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";                                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannelID << " ";
1270                                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)                                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
1271                                          ts << "ALL";                                          ts << "ALL";
1272                                  else                                  else
1273                                          ts << pChannel->midiChannel();                                          ts << pChannel->midiChannel();
1274                                  ts << endl;                                  ts << endl;
1275                                  ts << "LOAD ENGINE " << pChannel->engineName()                                  ts << "LOAD ENGINE " << pChannel->engineName()
1276                                          << " " << iChannel << endl;                                          << " " << iChannelID << endl;
1277                                  if (pChannel->instrumentStatus() < 100) ts << "# ";                                  if (pChannel->instrumentStatus() < 100) ts << "# ";
1278                                  ts << "LOAD INSTRUMENT NON_MODAL '"                                  ts << "LOAD INSTRUMENT NON_MODAL '"
1279                                          << pChannel->instrumentFile() << "' "                                          << pChannel->instrumentFile() << "' "
1280                                          << pChannel->instrumentNr() << " " << iChannel << endl;                                          << pChannel->instrumentNr() << " " << iChannelID << endl;
1281                                  ChannelRoutingMap::ConstIterator audioRoute;                                  ChannelRoutingMap::ConstIterator audioRoute;
1282                                  for (audioRoute = pChannel->audioRouting().begin();                                  for (audioRoute = pChannel->audioRouting().begin();
1283                                                  audioRoute != pChannel->audioRouting().end();                                                  audioRoute != pChannel->audioRouting().end();
1284                                                          ++audioRoute) {                                                          ++audioRoute) {
1285                                          ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannelID
1286                                                  << " " << audioRoute.key()                                                  << " " << audioRoute.key()
1287                                                  << " " << audioRoute.value() << endl;                                                  << " " << audioRoute.value() << endl;
1288                                  }                                  }
1289                                  ts << "SET CHANNEL VOLUME " << iChannel                                  ts << "SET CHANNEL VOLUME " << iChannelID
1290                                          << " " << pChannel->volume() << endl;                                          << " " << pChannel->volume() << endl;
1291                                  if (pChannel->channelMute())                                  if (pChannel->channelMute())
1292                                          ts << "SET CHANNEL MUTE " << iChannel << " 1" << endl;                                          ts << "SET CHANNEL MUTE " << iChannelID << " 1" << endl;
1293                                  if (pChannel->channelSolo())                                  if (pChannel->channelSolo())
1294                                          ts << "SET CHANNEL SOLO " << iChannel << " 1" << endl;                                          ts << "SET CHANNEL SOLO " << iChannelID << " 1" << endl;
1295  #ifdef CONFIG_MIDI_INSTRUMENT                          #ifdef CONFIG_MIDI_INSTRUMENT
1296                                  if (pChannel->midiMap() >= 0) {                                  const int iMidiMap = pChannel->midiMap();
1297                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannel                                  if (midiInstrumentMap.contains(iMidiMap)) {
1298                                                  << " " << midiInstrumentMap[pChannel->midiMap()] << endl;                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannelID
1299                                                    << " " << midiInstrumentMap.value(iMidiMap) << endl;
1300                                  }                                  }
1301  #endif                          #endif
1302  #ifdef CONFIG_FXSEND                          #ifdef CONFIG_FXSEND
                                 int iChannelID = pChannel->channelID();  
1303                                  int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID);                                  int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID);
1304                                  for (int iFxSend = 0;                                  for (int iFxSend = 0;
1305                                                  piFxSends && piFxSends[iFxSend] >= 0;                                                  piFxSends && piFxSends[iFxSend] >= 0;
# Line 1163  bool MainForm::saveSessionFile ( const Q Line 1307  bool MainForm::saveSessionFile ( const Q
1307                                          lscp_fxsend_info_t *pFxSendInfo = ::lscp_get_fxsend_info(                                          lscp_fxsend_info_t *pFxSendInfo = ::lscp_get_fxsend_info(
1308                                                  m_pClient, iChannelID, piFxSends[iFxSend]);                                                  m_pClient, iChannelID, piFxSends[iFxSend]);
1309                                          if (pFxSendInfo) {                                          if (pFxSendInfo) {
1310                                                  ts << "CREATE FX_SEND " << iChannel                                                  ts << "CREATE FX_SEND " << iChannelID
1311                                                          << " " << pFxSendInfo->midi_controller;                                                          << " " << pFxSendInfo->midi_controller;
1312                                                  if (pFxSendInfo->name)                                                  if (pFxSendInfo->name)
1313                                                          ts << " '" << pFxSendInfo->name << "'";                                                          ts << " '" << pFxSendInfo->name << "'";
# Line 1173  bool MainForm::saveSessionFile ( const Q Line 1317  bool MainForm::saveSessionFile ( const Q
1317                                                                  piRouting && piRouting[iAudioSrc] >= 0;                                                                  piRouting && piRouting[iAudioSrc] >= 0;
1318                                                                          iAudioSrc++) {                                                                          iAudioSrc++) {
1319                                                          ts << "SET FX_SEND AUDIO_OUTPUT_CHANNEL "                                                          ts << "SET FX_SEND AUDIO_OUTPUT_CHANNEL "
1320                                                                  << iChannel                                                                  << iChannelID
1321                                                                  << " " << iFxSend                                                                  << " " << iFxSend
1322                                                                  << " " << iAudioSrc                                                                  << " " << iAudioSrc
1323                                                                  << " " << piRouting[iAudioSrc] << endl;                                                                  << " " << piRouting[iAudioSrc] << endl;
1324                                                  }                                                  }
1325  #ifdef CONFIG_FXSEND_LEVEL                                          #ifdef CONFIG_FXSEND_LEVEL
1326                                                  ts << "SET FX_SEND LEVEL " << iChannel                                                  ts << "SET FX_SEND LEVEL " << iChannelID
1327                                                          << " " << iFxSend                                                          << " " << iFxSend
1328                                                          << " " << pFxSendInfo->level << endl;                                                          << " " << pFxSendInfo->level << endl;
1329  #endif                                          #endif
1330                                          }       // Check for errors...                                          }       // Check for errors...
1331                                          else if (::lscp_client_get_errno(m_pClient)) {                                          else if (::lscp_client_get_errno(m_pClient)) {
1332                                                  appendMessagesClient("lscp_get_fxsend_info");                                                  appendMessagesClient("lscp_get_fxsend_info");
1333                                                  iErrors++;                                                  iErrors++;
1334                                          }                                          }
1335                                  }                                  }
1336  #endif                          #endif
1337                                  ts << endl;                                  ts << endl;
1338                                    // Go for next channel...
1339                                    ++iChannelID;
1340                          }                          }
1341                  }                  }
1342                  // Try to keep it snappy :)                  // Try to keep it snappy :)
# Line 1242  void MainForm::sessionDirty (void) Line 1388  void MainForm::sessionDirty (void)
1388    
1389    
1390  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1391  // qsamplerMainForm -- File Action slots.  // QSampler::MainForm -- File Action slots.
1392    
1393  // Create a new sampler session.  // Create a new sampler session.
1394  void MainForm::fileNew (void)  void MainForm::fileNew (void)
# Line 1266  void MainForm::fileOpenRecent (void) Line 1412  void MainForm::fileOpenRecent (void)
1412          // Retrive filename index from action data...          // Retrive filename index from action data...
1413          QAction *pAction = qobject_cast<QAction *> (sender());          QAction *pAction = qobject_cast<QAction *> (sender());
1414          if (pAction && m_pOptions) {          if (pAction && m_pOptions) {
1415                  int iIndex = pAction->data().toInt();                  const int iIndex = pAction->data().toInt();
1416                  if (iIndex >= 0 && iIndex < m_pOptions->recentFiles.count()) {                  if (iIndex >= 0 && iIndex < m_pOptions->recentFiles.count()) {
1417                          QString sFilename = m_pOptions->recentFiles[iIndex];                          QString sFilename = m_pOptions->recentFiles[iIndex];
1418                          // Check if we can safely close the current session...                          // Check if we can safely close the current session...
# Line 1300  void MainForm::fileReset (void) Line 1446  void MainForm::fileReset (void)
1446                  return;                  return;
1447    
1448          // Ask user whether he/she want's an internal sampler reset...          // Ask user whether he/she want's an internal sampler reset...
1449          if (QMessageBox::warning(this,          if (m_pOptions && m_pOptions->bConfirmReset) {
1450                  QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");
1451                  tr("Resetting the sampler instance will close\n"                  const QString& sText = tr(
1452                  "all device and channel configurations.\n\n"                          "Resetting the sampler instance will close\n"
1453                  "Please note that this operation may cause\n"                          "all device and channel configurations.\n\n"
1454                  "temporary MIDI and Audio disruption.\n\n"                          "Please note that this operation may cause\n"
1455                  "Do you want to reset the sampler engine now?"),                          "temporary MIDI and Audio disruption.\n\n"
1456                  tr("Reset"), tr("Cancel")) > 0)                          "Do you want to reset the sampler engine now?");
1457                  return;          #if 0
1458                    if (QMessageBox::warning(this, sTitle, sText,
1459                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1460                            return;
1461            #else
1462                    QMessageBox mbox(this);
1463                    mbox.setIcon(QMessageBox::Warning);
1464                    mbox.setWindowTitle(sTitle);
1465                    mbox.setText(sText);
1466                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1467                    QCheckBox cbox(tr("Don't ask this again"));
1468                    cbox.setChecked(false);
1469                    cbox.blockSignals(true);
1470                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1471                    if (mbox.exec() == QMessageBox::Cancel)
1472                            return;
1473                    if (cbox.isChecked())
1474                            m_pOptions->bConfirmReset = false;
1475            #endif
1476            }
1477    
1478          // Trye closing the current session, first...          // Trye closing the current session, first...
1479          if (!closeSession(true))          if (!closeSession(true))
# Line 1340  void MainForm::fileRestart (void) Line 1505  void MainForm::fileRestart (void)
1505    
1506          // Ask user whether he/she want's a complete restart...          // Ask user whether he/she want's a complete restart...
1507          // (if we're currently up and running)          // (if we're currently up and running)
1508          if (bRestart && m_pClient) {          if (m_pOptions && m_pOptions->bConfirmRestart) {
1509                  bRestart = (QMessageBox::warning(this,                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");
1510                          QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sText = tr(
1511                          tr("New settings will be effective after\n"                          "New settings will be effective after\n"
1512                          "restarting the client/server connection.\n\n"                          "restarting the client/server connection.\n\n"
1513                          "Please note that this operation may cause\n"                          "Please note that this operation may cause\n"
1514                          "temporary MIDI and Audio disruption.\n\n"                          "temporary MIDI and Audio disruption.\n\n"
1515                          "Do you want to restart the connection now?"),                          "Do you want to restart the connection now?");
1516                          tr("Restart"), tr("Cancel")) == 0);          #if 0
1517                    if (QMessageBox::warning(this, sTitle, sText,
1518                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1519                            bRestart = false;
1520            #else
1521                    QMessageBox mbox(this);
1522                    mbox.setIcon(QMessageBox::Warning);
1523                    mbox.setWindowTitle(sTitle);
1524                    mbox.setText(sText);
1525                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1526                    QCheckBox cbox(tr("Don't ask this again"));
1527                    cbox.setChecked(false);
1528                    cbox.blockSignals(true);
1529                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1530                    if (mbox.exec() == QMessageBox::Cancel)
1531                            bRestart = false;
1532                    else
1533                    if (cbox.isChecked())
1534                            m_pOptions->bConfirmRestart = false;
1535            #endif
1536          }          }
1537    
1538          // Are we still for it?          // Are we still for it?
# Line 1370  void MainForm::fileExit (void) Line 1554  void MainForm::fileExit (void)
1554    
1555    
1556  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1557  // qsamplerMainForm -- Edit Action slots.  // QSampler::MainForm -- Edit Action slots.
1558    
1559  // Add a new sampler channel.  // Add a new sampler channel.
1560  void MainForm::editAddChannel (void)  void MainForm::editAddChannel (void)
1561  {  {
1562            ++m_iDirtySetup;
1563            addChannelStrip();
1564            --m_iDirtySetup;
1565    }
1566    
1567    void MainForm::addChannelStrip (void)
1568    {
1569          if (m_pClient == NULL)          if (m_pClient == NULL)
1570                  return;                  return;
1571    
# Line 1398  void MainForm::editAddChannel (void) Line 1589  void MainForm::editAddChannel (void)
1589          }          }
1590    
1591          // Do we auto-arrange?          // Do we auto-arrange?
1592          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
1593    
1594          // Make that an overall update.          // Make that an overall update.
1595          m_iDirtyCount++;          m_iDirtyCount++;
# Line 1410  void MainForm::editAddChannel (void) Line 1600  void MainForm::editAddChannel (void)
1600  // Remove current sampler channel.  // Remove current sampler channel.
1601  void MainForm::editRemoveChannel (void)  void MainForm::editRemoveChannel (void)
1602  {  {
1603            ++m_iDirtySetup;
1604            removeChannelStrip();
1605            --m_iDirtySetup;
1606    }
1607    
1608    void MainForm::removeChannelStrip (void)
1609    {
1610          if (m_pClient == NULL)          if (m_pClient == NULL)
1611                  return;                  return;
1612    
1613          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1614          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1615                  return;                  return;
1616    
# Line 1423  void MainForm::editRemoveChannel (void) Line 1620  void MainForm::editRemoveChannel (void)
1620    
1621          // Prompt user if he/she's sure about this...          // Prompt user if he/she's sure about this...
1622          if (m_pOptions && m_pOptions->bConfirmRemove) {          if (m_pOptions && m_pOptions->bConfirmRemove) {
1623                  if (QMessageBox::warning(this,                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");
1624                          QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sText = tr(
1625                          tr("About to remove channel:\n\n"                          "About to remove channel:\n\n"
1626                          "%1\n\n"                          "%1\n\n"
1627                          "Are you sure?")                          "Are you sure?")
1628                          .arg(pChannelStrip->windowTitle()),                          .arg(pChannelStrip->windowTitle());
1629                          tr("OK"), tr("Cancel")) > 0)          #if 0
1630                    if (QMessageBox::warning(this, sTitle, sText,
1631                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1632                          return;                          return;
1633            #else
1634                    QMessageBox mbox(this);
1635                    mbox.setIcon(QMessageBox::Warning);
1636                    mbox.setWindowTitle(sTitle);
1637                    mbox.setText(sText);
1638                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1639                    QCheckBox cbox(tr("Don't ask this again"));
1640                    cbox.setChecked(false);
1641                    cbox.blockSignals(true);
1642                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1643                    if (mbox.exec() == QMessageBox::Cancel)
1644                            return;
1645                    if (cbox.isChecked())
1646                            m_pOptions->bConfirmRemove = false;
1647            #endif
1648          }          }
1649    
1650          // Remove the existing sampler channel.          // Remove the existing sampler channel.
# Line 1438  void MainForm::editRemoveChannel (void) Line 1652  void MainForm::editRemoveChannel (void)
1652                  return;                  return;
1653    
1654          // Just delete the channel strip.          // Just delete the channel strip.
1655          delete pChannelStrip;          destroyChannelStrip(pChannelStrip);
   
         // Do we auto-arrange?  
         if (m_pOptions && m_pOptions->bAutoArrange)  
                 channelsArrange();  
1656    
1657          // We'll be dirty, for sure...          // We'll be dirty, for sure...
1658          m_iDirtyCount++;          m_iDirtyCount++;
# Line 1456  void MainForm::editSetupChannel (void) Line 1666  void MainForm::editSetupChannel (void)
1666          if (m_pClient == NULL)          if (m_pClient == NULL)
1667                  return;                  return;
1668    
1669          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1670          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1671                  return;                  return;
1672    
# Line 1471  void MainForm::editEditChannel (void) Line 1681  void MainForm::editEditChannel (void)
1681          if (m_pClient == NULL)          if (m_pClient == NULL)
1682                  return;                  return;
1683    
1684          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1685          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1686                  return;                  return;
1687    
# Line 1486  void MainForm::editResetChannel (void) Line 1696  void MainForm::editResetChannel (void)
1696          if (m_pClient == NULL)          if (m_pClient == NULL)
1697                  return;                  return;
1698    
1699          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1700          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1701                  return;                  return;
1702    
# Line 1504  void MainForm::editResetAllChannels (voi Line 1714  void MainForm::editResetAllChannels (voi
1714          // Invoque the channel strip procedure,          // Invoque the channel strip procedure,
1715          // for all channels out there...          // for all channels out there...
1716          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1717          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
1718          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                  = m_pWorkspace->subWindowList();
1719                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);          const int iStripCount = wlist.count();
1720            for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
1721                    ChannelStrip *pChannelStrip = NULL;
1722                    QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
1723                    if (pMdiSubWindow)
1724                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
1725                  if (pChannelStrip)                  if (pChannelStrip)
1726                          pChannelStrip->channelReset();                          pChannelStrip->channelReset();
1727          }          }
# Line 1515  void MainForm::editResetAllChannels (voi Line 1730  void MainForm::editResetAllChannels (voi
1730    
1731    
1732  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1733  // qsamplerMainForm -- View Action slots.  // QSampler::MainForm -- View Action slots.
1734    
1735  // Show/hide the main program window menubar.  // Show/hide the main program window menubar.
1736  void MainForm::viewMenubar ( bool bOn )  void MainForm::viewMenubar ( bool bOn )
# Line 1609  void MainForm::viewOptions (void) Line 1824  void MainForm::viewOptions (void)
1824          OptionsForm* pOptionsForm = new OptionsForm(this);          OptionsForm* pOptionsForm = new OptionsForm(this);
1825          if (pOptionsForm) {          if (pOptionsForm) {
1826                  // Check out some initial nullities(tm)...                  // Check out some initial nullities(tm)...
1827                  ChannelStrip* pChannelStrip = activeChannelStrip();                  ChannelStrip *pChannelStrip = activeChannelStrip();
1828                  if (m_pOptions->sDisplayFont.isEmpty() && pChannelStrip)                  if (m_pOptions->sDisplayFont.isEmpty() && pChannelStrip)
1829                          m_pOptions->sDisplayFont = pChannelStrip->displayFont().toString();                          m_pOptions->sDisplayFont = pChannelStrip->displayFont().toString();
1830                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)
1831                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();
1832                  // To track down deferred or immediate changes.                  // To track down deferred or immediate changes.
1833                  QString sOldServerHost      = m_pOptions->sServerHost;                  const QString sOldServerHost      = m_pOptions->sServerHost;
1834                  int     iOldServerPort      = m_pOptions->iServerPort;                  const int     iOldServerPort      = m_pOptions->iServerPort;
1835                  int     iOldServerTimeout   = m_pOptions->iServerTimeout;                  const int     iOldServerTimeout   = m_pOptions->iServerTimeout;
1836                  bool    bOldServerStart     = m_pOptions->bServerStart;                  const bool    bOldServerStart     = m_pOptions->bServerStart;
1837                  QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;                  const QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;
1838                  bool    bOldMessagesLog     = m_pOptions->bMessagesLog;                  const bool    bOldMessagesLog     = m_pOptions->bMessagesLog;
1839                  QString sOldMessagesLogPath = m_pOptions->sMessagesLogPath;                  const QString sOldMessagesLogPath = m_pOptions->sMessagesLogPath;
1840                  QString sOldDisplayFont     = m_pOptions->sDisplayFont;                  const QString sOldDisplayFont     = m_pOptions->sDisplayFont;
1841                  bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;                  const bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1842                  int     iOldMaxVolume       = m_pOptions->iMaxVolume;                  const int     iOldMaxVolume       = m_pOptions->iMaxVolume;
1843                  QString sOldMessagesFont    = m_pOptions->sMessagesFont;                  const QString sOldMessagesFont    = m_pOptions->sMessagesFont;
1844                  bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;                  const bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;
1845                  bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;                  const bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;
1846                  int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;                  const int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;
1847                  int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;                  const int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1848                  bool    bOldCompletePath    = m_pOptions->bCompletePath;                  const bool    bOldCompletePath    = m_pOptions->bCompletePath;
1849                  bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;                  const bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1850                  int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;                  const int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1851                  int     iOldBaseFontSize    = m_pOptions->iBaseFontSize;                  const int     iOldBaseFontSize    = m_pOptions->iBaseFontSize;
1852                  // Load the current setup settings.                  // Load the current setup settings.
1853                  pOptionsForm->setup(m_pOptions);                  pOptionsForm->setup(m_pOptions);
1854                  // Show the setup dialog...                  // Show the setup dialog...
# Line 1647  void MainForm::viewOptions (void) Line 1862  void MainForm::viewOptions (void)
1862                                  QMessageBox::information(this,                                  QMessageBox::information(this,
1863                                          QSAMPLER_TITLE ": " + tr("Information"),                                          QSAMPLER_TITLE ": " + tr("Information"),
1864                                          tr("Some settings may be only effective\n"                                          tr("Some settings may be only effective\n"
1865                                          "next time you start this program."), tr("OK"));                                          "next time you start this program."));
1866                                  updateMessagesCapture();                                  updateMessagesCapture();
1867                          }                          }
1868                          // Check wheather something immediate has changed.                          // Check wheather something immediate has changed.
# Line 1696  void MainForm::viewOptions (void) Line 1911  void MainForm::viewOptions (void)
1911    
1912    
1913  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1914  // qsamplerMainForm -- Channels action slots.  // QSampler::MainForm -- Channels action slots.
1915    
1916  // Arrange channel strips.  // Arrange channel strips.
1917  void MainForm::channelsArrange (void)  void MainForm::channelsArrange (void)
1918  {  {
1919          // Full width vertical tiling          // Full width vertical tiling
1920          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
1921                    = m_pWorkspace->subWindowList();
1922          if (wlist.isEmpty())          if (wlist.isEmpty())
1923                  return;                  return;
1924    
1925          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1926          int y = 0;          int y = 0;
1927          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          const int iStripCount = wlist.count();
1928                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
1929          /*  if (pChannelStrip->testWState(WState_Maximized | WState_Minimized)) {                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
1930                          // Prevent flicker...                  if (pMdiSubWindow) {
1931                          pChannelStrip->hide();                          pMdiSubWindow->adjustSize();
1932                          pChannelStrip->showNormal();                          int iWidth = m_pWorkspace->width();
1933                  }   */                          if (iWidth < pMdiSubWindow->width())
1934                  pChannelStrip->adjustSize();                                  iWidth = pMdiSubWindow->width();
1935                  int iWidth  = m_pWorkspace->width();                          const int iHeight = pMdiSubWindow->frameGeometry().height();
1936                  if (iWidth < pChannelStrip->width())                          pMdiSubWindow->setGeometry(0, y, iWidth, iHeight);
1937                          iWidth = pChannelStrip->width();                          y += iHeight;
1938          //  int iHeight = pChannelStrip->height()                  }
         //              + pChannelStrip->parentWidget()->baseSize().height();  
                 int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();  
                 pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);  
                 y += iHeight;  
1939          }          }
1940          m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
1941    
# Line 1741  void MainForm::channelsAutoArrange ( boo Line 1953  void MainForm::channelsAutoArrange ( boo
1953          m_pOptions->bAutoArrange = bOn;          m_pOptions->bAutoArrange = bOn;
1954    
1955          // If on, update whole workspace...          // If on, update whole workspace...
1956          if (m_pOptions->bAutoArrange)          channelsArrangeAuto();
1957    }
1958    
1959    
1960    void MainForm::channelsArrangeAuto (void)
1961    {
1962            if (m_pOptions && m_pOptions->bAutoArrange)
1963                  channelsArrange();                  channelsArrange();
1964  }  }
1965    
1966    
1967  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1968  // qsamplerMainForm -- Help Action slots.  // QSampler::MainForm -- Help Action slots.
1969    
1970  // Show information about the Qt toolkit.  // Show information about the Qt toolkit.
1971  void MainForm::helpAboutQt (void)  void MainForm::helpAboutQt (void)
# Line 1759  void MainForm::helpAboutQt (void) Line 1977  void MainForm::helpAboutQt (void)
1977  // Show information about application program.  // Show information about application program.
1978  void MainForm::helpAbout (void)  void MainForm::helpAbout (void)
1979  {  {
1980          // 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";  
1981  #ifdef CONFIG_DEBUG  #ifdef CONFIG_DEBUG
1982          sText += "<small><font color=\"red\">";          list << tr("Debugging option enabled.");
         sText += tr("Debugging option enabled.");  
         sText += "</font></small><br />";  
1983  #endif  #endif
1984  #ifndef CONFIG_LIBGIG  #ifndef CONFIG_LIBGIG
1985          sText += "<small><font color=\"red\">";          list << tr("GIG (libgig) file support disabled.");
         sText += tr("GIG (libgig) file support disabled.");  
         sText += "</font></small><br />";  
1986  #endif  #endif
1987  #ifndef CONFIG_INSTRUMENT_NAME  #ifndef CONFIG_INSTRUMENT_NAME
1988          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 />";  
1989  #endif  #endif
1990  #ifndef CONFIG_MUTE_SOLO  #ifndef CONFIG_MUTE_SOLO
1991          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 />";  
1992  #endif  #endif
1993  #ifndef CONFIG_AUDIO_ROUTING  #ifndef CONFIG_AUDIO_ROUTING
1994          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 />";  
1995  #endif  #endif
1996  #ifndef CONFIG_FXSEND  #ifndef CONFIG_FXSEND
1997          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 />";  
1998  #endif  #endif
1999  #ifndef CONFIG_VOLUME  #ifndef CONFIG_VOLUME
2000          sText += "<small><font color=\"red\">";          list << tr("Global volume support disabled.");
         sText += tr("Global volume support disabled.");  
         sText += "</font></small><br />";  
2001  #endif  #endif
2002  #ifndef CONFIG_MIDI_INSTRUMENT  #ifndef CONFIG_MIDI_INSTRUMENT
2003          sText += "<small><font color=\"red\">";          list << tr("MIDI instrument mapping support disabled.");
         sText += tr("MIDI instrument mapping support disabled.");  
         sText += "</font></small><br />";  
2004  #endif  #endif
2005  #ifndef CONFIG_EDIT_INSTRUMENT  #ifndef CONFIG_EDIT_INSTRUMENT
2006          sText += "<small><font color=\"red\">";          list << tr("Instrument editing support disabled.");
         sText += tr("Instrument editing support disabled.");  
         sText += "</font></small><br />";  
2007  #endif  #endif
2008  #ifndef CONFIG_EVENT_CHANNEL_MIDI  #ifndef CONFIG_EVENT_CHANNEL_MIDI
2009          sText += "<small><font color=\"red\">";          list << tr("Channel MIDI event support disabled.");
         sText += tr("Channel MIDI event support disabled.");  
         sText += "</font></small><br />";  
2010  #endif  #endif
2011  #ifndef CONFIG_EVENT_DEVICE_MIDI  #ifndef CONFIG_EVENT_DEVICE_MIDI
2012          sText += "<small><font color=\"red\">";          list << tr("Device MIDI event support disabled.");
         sText += tr("Device MIDI event support disabled.");  
         sText += "</font></small><br />";  
2013  #endif  #endif
2014  #ifndef CONFIG_MAX_VOICES  #ifndef CONFIG_MAX_VOICES
2015          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 />";  
2016  #endif  #endif
2017    
2018            // Stuff the about box text...
2019            QString sText = "<p>\n";
2020            sText += "<b>" QSAMPLER_TITLE " - " + tr(QSAMPLER_SUBTITLE) + "</b><br />\n";
2021            sText += "<br />\n";
2022            sText += tr("Version") + ": <b>" CONFIG_BUILD_VERSION "</b><br />\n";
2023    //      sText += "<small>" + tr("Build") + ": " CONFIG_BUILD_DATE "</small><br />\n";
2024            if (!list.isEmpty()) {
2025                    sText += "<small><font color=\"red\">";
2026                    sText += list.join("<br />\n");
2027                    sText += "</font></small>";
2028            }
2029          sText += "<br />\n";          sText += "<br />\n";
2030          sText += tr("Using") + ": ";          sText += tr("Using") + ": ";
2031          sText += ::lscp_client_package();          sText += ::lscp_client_package();
# Line 1854  void MainForm::helpAbout (void) Line 2055  void MainForm::helpAbout (void)
2055    
2056    
2057  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2058  // qsamplerMainForm -- Main window stabilization.  // QSampler::MainForm -- Main window stabilization.
2059    
2060  void MainForm::stabilizeForm (void)  void MainForm::stabilizeForm (void)
2061  {  {
# Line 1865  void MainForm::stabilizeForm (void) Line 2066  void MainForm::stabilizeForm (void)
2066          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));
2067    
2068          // Update the main menu state...          // Update the main menu state...
2069          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
2070          bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);          const QList<QMdiSubWindow *>& wlist = m_pWorkspace->subWindowList();
2071          bool bHasChannel = (bHasClient && pChannelStrip != NULL);          const bool bHasClient = (m_pOptions != NULL && m_pClient != NULL);
2072            const bool bHasChannel = (bHasClient && pChannelStrip != NULL);
2073            const bool bHasChannels = (bHasClient && wlist.count() > 0);
2074          m_ui.fileNewAction->setEnabled(bHasClient);          m_ui.fileNewAction->setEnabled(bHasClient);
2075          m_ui.fileOpenAction->setEnabled(bHasClient);          m_ui.fileOpenAction->setEnabled(bHasClient);
2076          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
# Line 1883  void MainForm::stabilizeForm (void) Line 2086  void MainForm::stabilizeForm (void)
2086          m_ui.editEditChannelAction->setEnabled(false);          m_ui.editEditChannelAction->setEnabled(false);
2087  #endif  #endif
2088          m_ui.editResetChannelAction->setEnabled(bHasChannel);          m_ui.editResetChannelAction->setEnabled(bHasChannel);
2089          m_ui.editResetAllChannelsAction->setEnabled(bHasChannel);          m_ui.editResetAllChannelsAction->setEnabled(bHasChannels);
2090          m_ui.viewMessagesAction->setChecked(m_pMessages && m_pMessages->isVisible());          m_ui.viewMessagesAction->setChecked(m_pMessages && m_pMessages->isVisible());
2091  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
2092          m_ui.viewInstrumentsAction->setChecked(m_pInstrumentListForm          m_ui.viewInstrumentsAction->setChecked(m_pInstrumentListForm
# Line 1895  void MainForm::stabilizeForm (void) Line 2098  void MainForm::stabilizeForm (void)
2098          m_ui.viewDevicesAction->setChecked(m_pDeviceForm          m_ui.viewDevicesAction->setChecked(m_pDeviceForm
2099                  && m_pDeviceForm->isVisible());                  && m_pDeviceForm->isVisible());
2100          m_ui.viewDevicesAction->setEnabled(bHasClient);          m_ui.viewDevicesAction->setEnabled(bHasClient);
2101          m_ui.channelsArrangeAction->setEnabled(bHasChannel);          m_ui.viewMidiDeviceStatusMenu->setEnabled(
2102                    DeviceStatusForm::getInstances().size() > 0);
2103            m_ui.channelsArrangeAction->setEnabled(bHasChannels);
2104    
2105  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
2106          // Toolbar widgets are also affected...          // Toolbar widgets are also affected...
# Line 1945  void MainForm::volumeChanged ( int iVolu Line 2150  void MainForm::volumeChanged ( int iVolu
2150                  m_pVolumeSpinBox->setValue(iVolume);                  m_pVolumeSpinBox->setValue(iVolume);
2151    
2152          // Do it as commanded...          // Do it as commanded...
2153          float fVolume = 0.01f * float(iVolume);          const float fVolume = 0.01f * float(iVolume);
2154          if (::lscp_set_volume(m_pClient, fVolume) == LSCP_OK)          if (::lscp_set_volume(m_pClient, fVolume) == LSCP_OK)
2155                  appendMessages(QObject::tr("Volume: %1.").arg(fVolume));                  appendMessages(QObject::tr("Volume: %1.").arg(fVolume));
2156          else          else
# Line 1961  void MainForm::volumeChanged ( int iVolu Line 2166  void MainForm::volumeChanged ( int iVolu
2166    
2167    
2168  // Channel change receiver slot.  // Channel change receiver slot.
2169  void MainForm::channelStripChanged(ChannelStrip* pChannelStrip)  void MainForm::channelStripChanged ( ChannelStrip *pChannelStrip )
2170  {  {
2171          // Add this strip to the changed list...          // Add this strip to the changed list...
2172          if (!m_changedStrips.contains(pChannelStrip)) {          if (!m_changedStrips.contains(pChannelStrip)) {
# Line 1980  void MainForm::channelStripChanged(Chann Line 2185  void MainForm::channelStripChanged(Chann
2185  void MainForm::updateSession (void)  void MainForm::updateSession (void)
2186  {  {
2187  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
2188          int iVolume = ::lroundf(100.0f * ::lscp_get_volume(m_pClient));          const int iVolume = ::lroundf(100.0f * ::lscp_get_volume(m_pClient));
2189          m_iVolumeChanging++;          m_iVolumeChanging++;
2190          m_pVolumeSlider->setValue(iVolume);          m_pVolumeSlider->setValue(iVolume);
2191          m_pVolumeSpinBox->setValue(iVolume);          m_pVolumeSpinBox->setValue(iVolume);
# Line 1988  void MainForm::updateSession (void) Line 2193  void MainForm::updateSession (void)
2193  #endif  #endif
2194  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
2195          // FIXME: Make some room for default instrument maps...          // FIXME: Make some room for default instrument maps...
2196          int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);          const int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);
2197          if (iMaps < 0)          if (iMaps < 0)
2198                  appendMessagesClient("lscp_get_midi_instrument_maps");                  appendMessagesClient("lscp_get_midi_instrument_maps");
2199          else if (iMaps < 1) {          else if (iMaps < 1) {
# Line 2002  void MainForm::updateSession (void) Line 2207  void MainForm::updateSession (void)
2207          updateAllChannelStrips(false);          updateAllChannelStrips(false);
2208    
2209          // Do we auto-arrange?          // Do we auto-arrange?
2210          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
2211    
2212          // Remember to refresh devices and instruments...          // Remember to refresh devices and instruments...
2213          if (m_pInstrumentListForm)          if (m_pInstrumentListForm)
# Line 2012  void MainForm::updateSession (void) Line 2216  void MainForm::updateSession (void)
2216                  m_pDeviceForm->refreshDevices();                  m_pDeviceForm->refreshDevices();
2217  }  }
2218    
2219  void MainForm::updateAllChannelStrips(bool bRemoveDeadStrips) {  
2220    void MainForm::updateAllChannelStrips ( bool bRemoveDeadStrips )
2221    {
2222            // Skip if setting up a new channel strip...
2223            if (m_iDirtySetup > 0)
2224                    return;
2225    
2226          // Retrieve the current channel list.          // Retrieve the current channel list.
2227          int *piChannelIDs = ::lscp_list_channels(m_pClient);          int *piChannelIDs = ::lscp_list_channels(m_pClient);
2228          if (piChannelIDs == NULL) {          if (piChannelIDs == NULL) {
# Line 2024  void MainForm::updateAllChannelStrips(bo Line 2234  void MainForm::updateAllChannelStrips(bo
2234          } else {          } else {
2235                  // Try to (re)create each channel.                  // Try to (re)create each channel.
2236                  m_pWorkspace->setUpdatesEnabled(false);                  m_pWorkspace->setUpdatesEnabled(false);
2237                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {
2238                          // Check if theres already a channel strip for this one...                          // Check if theres already a channel strip for this one...
2239                          if (!channelStrip(piChannelIDs[iChannel]))                          if (!channelStrip(piChannelIDs[iChannel]))
2240                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));
2241                  }                  }
   
2242                  // Do we auto-arrange?                  // Do we auto-arrange?
2243                  if (m_pOptions && m_pOptions->bAutoArrange)                  channelsArrangeAuto();
                         channelsArrange();  
   
                 stabilizeForm();  
   
2244                  // remove dead channel strips                  // remove dead channel strips
2245                  if (bRemoveDeadStrips) {                  if (bRemoveDeadStrips) {
2246                          for (int i = 0; channelStripAt(i); ++i) {                          const QList<QMdiSubWindow *>& wlist
2247                                  ChannelStrip* pChannelStrip = channelStripAt(i);                                  = m_pWorkspace->subWindowList();
2248                                  bool bExists = false;                          const int iStripCount = wlist.count();
2249                                  for (int j = 0; piChannelIDs[j] >= 0; ++j) {                          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2250                                          if (!pChannelStrip->channel()) break;                                  ChannelStrip *pChannelStrip = NULL;
2251                                          if (piChannelIDs[j] == pChannelStrip->channel()->channelID()) {                                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2252                                                  // strip exists, don't touch it                                  if (pMdiSubWindow)
2253                                                  bExists = true;                                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2254                                                  break;                                  if (pChannelStrip) {
2255                                            bool bExists = false;
2256                                            for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {
2257                                                    Channel *pChannel = pChannelStrip->channel();
2258                                                    if (pChannel == NULL)
2259                                                            break;
2260                                                    if (piChannelIDs[iChannel] == pChannel->channelID()) {
2261                                                            // strip exists, don't touch it
2262                                                            bExists = true;
2263                                                            break;
2264                                                    }
2265                                          }                                          }
2266                                            if (!bExists)
2267                                                    destroyChannelStrip(pChannelStrip);
2268                                  }                                  }
                                 if (!bExists) destroyChannelStrip(pChannelStrip);  
2269                          }                          }
2270                  }                  }
2271                  m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
2272          }          }
2273    
2274            stabilizeForm();
2275  }  }
2276    
2277    
2278  // Update the recent files list and menu.  // Update the recent files list and menu.
2279  void MainForm::updateRecentFiles ( const QString& sFilename )  void MainForm::updateRecentFiles ( const QString& sFilename )
2280  {  {
# Line 2063  void MainForm::updateRecentFiles ( const Line 2282  void MainForm::updateRecentFiles ( const
2282                  return;                  return;
2283    
2284          // Remove from list if already there (avoid duplicates)          // Remove from list if already there (avoid duplicates)
2285          int iIndex = m_pOptions->recentFiles.indexOf(sFilename);          const int iIndex = m_pOptions->recentFiles.indexOf(sFilename);
2286          if (iIndex >= 0)          if (iIndex >= 0)
2287                  m_pOptions->recentFiles.removeAt(iIndex);                  m_pOptions->recentFiles.removeAt(iIndex);
2288          // Put it to front...          // Put it to front...
# Line 2102  void MainForm::updateRecentFilesMenu (vo Line 2321  void MainForm::updateRecentFilesMenu (vo
2321  void MainForm::updateInstrumentNames (void)  void MainForm::updateInstrumentNames (void)
2322  {  {
2323          // Full channel list update...          // Full channel list update...
2324          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2325                    = m_pWorkspace->subWindowList();
2326          if (wlist.isEmpty())          if (wlist.isEmpty())
2327                  return;                  return;
2328    
2329          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2330          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          const int iStripCount = wlist.count();
2331                  ChannelStrip *pChannelStrip = (ChannelStrip *) wlist.at(iChannel);          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2332                    ChannelStrip *pChannelStrip = NULL;
2333                    QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2334                    if (pMdiSubWindow)
2335                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2336                  if (pChannelStrip)                  if (pChannelStrip)
2337                          pChannelStrip->updateInstrumentName(true);                          pChannelStrip->updateInstrumentName(true);
2338          }          }
# Line 2125  void MainForm::updateDisplayFont (void) Line 2349  void MainForm::updateDisplayFont (void)
2349          // Check if display font is legal.          // Check if display font is legal.
2350          if (m_pOptions->sDisplayFont.isEmpty())          if (m_pOptions->sDisplayFont.isEmpty())
2351                  return;                  return;
2352    
2353          // Realize it.          // Realize it.
2354          QFont font;          QFont font;
2355          if (!font.fromString(m_pOptions->sDisplayFont))          if (!font.fromString(m_pOptions->sDisplayFont))
2356                  return;                  return;
2357    
2358          // Full channel list update...          // Full channel list update...
2359          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2360                    = m_pWorkspace->subWindowList();
2361          if (wlist.isEmpty())          if (wlist.isEmpty())
2362                  return;                  return;
2363    
2364          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2365          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          const int iStripCount = wlist.count();
2366                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2367                    ChannelStrip *pChannelStrip = NULL;
2368                    QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2369                    if (pMdiSubWindow)
2370                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2371                  if (pChannelStrip)                  if (pChannelStrip)
2372                          pChannelStrip->setDisplayFont(font);                          pChannelStrip->setDisplayFont(font);
2373          }          }
# Line 2149  void MainForm::updateDisplayFont (void) Line 2379  void MainForm::updateDisplayFont (void)
2379  void MainForm::updateDisplayEffect (void)  void MainForm::updateDisplayEffect (void)
2380  {  {
2381          // Full channel list update...          // Full channel list update...
2382          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2383                    = m_pWorkspace->subWindowList();
2384          if (wlist.isEmpty())          if (wlist.isEmpty())
2385                  return;                  return;
2386    
2387          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2388          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          const int iStripCount = wlist.count();
2389                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2390                    ChannelStrip *pChannelStrip = NULL;
2391                    QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2392                    if (pMdiSubWindow)
2393                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2394                  if (pChannelStrip)                  if (pChannelStrip)
2395                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2396          }          }
# Line 2177  void MainForm::updateMaxVolume (void) Line 2412  void MainForm::updateMaxVolume (void)
2412  #endif  #endif
2413    
2414          // Full channel list update...          // Full channel list update...
2415          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2416                    = m_pWorkspace->subWindowList();
2417          if (wlist.isEmpty())          if (wlist.isEmpty())
2418                  return;                  return;
2419    
2420          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2421          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          const int iStripCount = wlist.count();
2422                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2423                    ChannelStrip *pChannelStrip = NULL;
2424                    QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2425                    if (pMdiSubWindow)
2426                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2427                  if (pChannelStrip)                  if (pChannelStrip)
2428                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2429          }          }
# Line 2192  void MainForm::updateMaxVolume (void) Line 2432  void MainForm::updateMaxVolume (void)
2432    
2433    
2434  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2435  // qsamplerMainForm -- Messages window form handlers.  // QSampler::MainForm -- Messages window form handlers.
2436    
2437  // Messages output methods.  // Messages output methods.
2438  void MainForm::appendMessages( const QString& s )  void MainForm::appendMessages( const QString& s )
# Line 2217  void MainForm::appendMessagesText( const Line 2457  void MainForm::appendMessagesText( const
2457                  m_pMessages->appendMessagesText(s);                  m_pMessages->appendMessagesText(s);
2458  }  }
2459    
2460  void MainForm::appendMessagesError( const QString& s )  void MainForm::appendMessagesError( const QString& sText )
2461  {  {
2462          if (m_pMessages)          if (m_pMessages)
2463                  m_pMessages->show();                  m_pMessages->show();
2464    
2465          appendMessagesColor(s.simplified(), "#ff0000");          appendMessagesColor(sText.simplified(), "#ff0000");
2466    
2467          // Make it look responsive...:)          // Make it look responsive...:)
2468          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2469    
2470          QMessageBox::critical(this,          if (m_pOptions && m_pOptions->bConfirmError) {
2471                  QSAMPLER_TITLE ": " + tr("Error"), s, tr("Cancel"));                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Error");
2472            #if 0
2473                    QMessageBox::critical(this, sTitle, sText, QMessageBox::Cancel);
2474            #else
2475                    QMessageBox mbox(this);
2476                    mbox.setIcon(QMessageBox::Critical);
2477                    mbox.setWindowTitle(sTitle);
2478                    mbox.setText(sText);
2479                    mbox.setStandardButtons(QMessageBox::Cancel);
2480                    QCheckBox cbox(tr("Don't show this again"));
2481                    cbox.setChecked(false);
2482                    cbox.blockSignals(true);
2483                    mbox.addButton(&cbox, QMessageBox::ActionRole);
2484                    if (mbox.exec() && cbox.isChecked())
2485                            m_pOptions->bConfirmError = false;
2486            #endif
2487            }
2488  }  }
2489    
2490    
# Line 2288  void MainForm::updateMessagesCapture (vo Line 2544  void MainForm::updateMessagesCapture (vo
2544    
2545    
2546  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2547  // qsamplerMainForm -- MDI channel strip management.  // QSampler::MainForm -- MDI channel strip management.
2548    
2549  // The channel strip creation executive.  // The channel strip creation executive.
2550  ChannelStrip* MainForm::createChannelStrip ( Channel *pChannel )  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )
2551  {  {
2552          if (m_pClient == NULL || pChannel == NULL)          if (m_pClient == NULL || pChannel == NULL)
2553                  return NULL;                  return NULL;
# Line 2307  ChannelStrip* MainForm::createChannelStr Line 2563  ChannelStrip* MainForm::createChannelStr
2563                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2564                  // We'll need a display font.                  // We'll need a display font.
2565                  QFont font;                  QFont font;
2566                  if (font.fromString(m_pOptions->sDisplayFont))                  if (!m_pOptions->sDisplayFont.isEmpty() &&
2567                            font.fromString(m_pOptions->sDisplayFont))
2568                          pChannelStrip->setDisplayFont(font);                          pChannelStrip->setDisplayFont(font);
2569                  // Maximum allowed volume setting.                  // Maximum allowed volume setting.
2570                  pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                  pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2571          }          }
2572    
2573          // Add it to workspace...          // Add it to workspace...
2574          m_pWorkspace->addWindow(pChannelStrip, Qt::FramelessWindowHint);          m_pWorkspace->addSubWindow(pChannelStrip,
2575                    Qt::SubWindow | Qt::FramelessWindowHint);
2576    
2577          // Actual channel strip setup...          // Actual channel strip setup...
2578          pChannelStrip->setup(pChannel);          pChannelStrip->setup(pChannel);
2579    
2580          QObject::connect(pChannelStrip,          QObject::connect(pChannelStrip,
2581                  SIGNAL(channelChanged(ChannelStrip*)),                  SIGNAL(channelChanged(ChannelStrip *)),
2582                  SLOT(channelStripChanged(ChannelStrip*)));                  SLOT(channelStripChanged(ChannelStrip *)));
2583    
2584          // Now we show up us to the world.          // Now we show up us to the world.
2585          pChannelStrip->show();          pChannelStrip->show();
# Line 2333  ChannelStrip* MainForm::createChannelStr Line 2591  ChannelStrip* MainForm::createChannelStr
2591          return pChannelStrip;          return pChannelStrip;
2592  }  }
2593    
2594  void MainForm::destroyChannelStrip(ChannelStrip* pChannelStrip) {  
2595    void MainForm::destroyChannelStrip ( ChannelStrip *pChannelStrip )
2596    {
2597            QMdiSubWindow *pMdiSubWindow
2598                    = static_cast<QMdiSubWindow *> (pChannelStrip->parentWidget());
2599            if (pMdiSubWindow == NULL)
2600                    return;
2601    
2602          // Just delete the channel strip.          // Just delete the channel strip.
2603          delete pChannelStrip;          delete pChannelStrip;
2604            delete pMdiSubWindow;
2605    
2606          // Do we auto-arrange?          // Do we auto-arrange?
2607          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
   
         stabilizeForm();  
2608  }  }
2609    
2610    
2611  // Retrieve the active channel strip.  // Retrieve the active channel strip.
2612  ChannelStrip* MainForm::activeChannelStrip (void)  ChannelStrip *MainForm::activeChannelStrip (void)
2613  {  {
2614          return static_cast<ChannelStrip *> (m_pWorkspace->activeWindow());          QMdiSubWindow *pMdiSubWindow = m_pWorkspace->activeSubWindow();
2615            if (pMdiSubWindow)
2616                    return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2617            else
2618                    return NULL;
2619  }  }
2620    
2621    
2622  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2623  ChannelStrip* MainForm::channelStripAt ( int iChannel )  ChannelStrip *MainForm::channelStripAt ( int iStrip )
2624  {  {
2625          if (!m_pWorkspace) return NULL;          if (!m_pWorkspace) return NULL;
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          if (iChannel < 0 || iChannel >= wlist.size())          if (iStrip < 0 || iStrip >= wlist.count())
2633                  return NULL;                  return NULL;
2634    
2635          return dynamic_cast<ChannelStrip *> (wlist.at(iChannel));          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2636            if (pMdiSubWindow)
2637                    return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2638            else
2639                    return NULL;
2640  }  }
2641    
2642    
2643  // Retrieve a channel strip by sampler channel id.  // Retrieve a channel strip by sampler channel id.
2644  ChannelStrip* MainForm::channelStrip ( int iChannelID )  ChannelStrip *MainForm::channelStrip ( int iChannelID )
2645  {  {
2646          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2647                    = m_pWorkspace->subWindowList();
2648          if (wlist.isEmpty())          if (wlist.isEmpty())
2649                  return NULL;                  return NULL;
2650    
2651          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          const int iStripCount = wlist.count();
2652                  ChannelStrip* pChannelStrip          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2653                          = static_cast<ChannelStrip*> (wlist.at(iChannel));                  ChannelStrip *pChannelStrip = NULL;
2654                    QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2655                    if (pMdiSubWindow)
2656                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2657                  if (pChannelStrip) {                  if (pChannelStrip) {
2658                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
2659                          if (pChannel && pChannel->channelID() == iChannelID)                          if (pChannel && pChannel->channelID() == iChannelID)
# Line 2396  void MainForm::channelsMenuAboutToShow ( Line 2673  void MainForm::channelsMenuAboutToShow (
2673          m_ui.channelsMenu->addAction(m_ui.channelsArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsArrangeAction);
2674          m_ui.channelsMenu->addAction(m_ui.channelsAutoArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsAutoArrangeAction);
2675    
2676          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2677                    = m_pWorkspace->subWindowList();
2678          if (!wlist.isEmpty()) {          if (!wlist.isEmpty()) {
2679                  m_ui.channelsMenu->addSeparator();                  m_ui.channelsMenu->addSeparator();
2680                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                  const int iStripCount = wlist.count();
2681                          ChannelStrip* pChannelStrip                  for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2682                                  = static_cast<ChannelStrip*> (wlist.at(iChannel));                          ChannelStrip *pChannelStrip = NULL;
2683                            QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2684                            if (pMdiSubWindow)
2685                                    pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2686                          if (pChannelStrip) {                          if (pChannelStrip) {
2687                                  QAction *pAction = m_ui.channelsMenu->addAction(                                  QAction *pAction = m_ui.channelsMenu->addAction(
2688                                          pChannelStrip->windowTitle(),                                          pChannelStrip->windowTitle(),
2689                                          this, SLOT(channelsMenuActivated()));                                          this, SLOT(channelsMenuActivated()));
2690                                  pAction->setCheckable(true);                                  pAction->setCheckable(true);
2691                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);
2692                                  pAction->setData(iChannel);                                  pAction->setData(iStrip);
2693                          }                          }
2694                  }                  }
2695          }          }
# Line 2423  void MainForm::channelsMenuActivated (vo Line 2704  void MainForm::channelsMenuActivated (vo
2704          if (pAction == NULL)          if (pAction == NULL)
2705                  return;                  return;
2706    
2707          ChannelStrip* pChannelStrip = channelStripAt(pAction->data().toInt());          ChannelStrip *pChannelStrip = channelStripAt(pAction->data().toInt());
2708          if (pChannelStrip) {          if (pChannelStrip) {
2709                  pChannelStrip->showNormal();                  pChannelStrip->showNormal();
2710                  pChannelStrip->setFocus();                  pChannelStrip->setFocus();
# Line 2432  void MainForm::channelsMenuActivated (vo Line 2713  void MainForm::channelsMenuActivated (vo
2713    
2714    
2715  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2716  // qsamplerMainForm -- Timer stuff.  // QSampler::MainForm -- Timer stuff.
2717    
2718  // Set the pseudo-timer delay schedule.  // Set the pseudo-timer delay schedule.
2719  void MainForm::startSchedule ( int iStartDelay )  void MainForm::startSchedule ( int iStartDelay )
# Line 2473  void MainForm::timerSlot (void) Line 2754  void MainForm::timerSlot (void)
2754                          ChannelStrip *pChannelStrip = iter.next();                          ChannelStrip *pChannelStrip = iter.next();
2755                          // If successfull, remove from pending list...                          // If successfull, remove from pending list...
2756                          if (pChannelStrip->updateChannelInfo()) {                          if (pChannelStrip->updateChannelInfo()) {
2757                                  int iChannelStrip = m_changedStrips.indexOf(pChannelStrip);                                  const int iChannelStrip = m_changedStrips.indexOf(pChannelStrip);
2758                                  if (iChannelStrip >= 0)                                  if (iChannelStrip >= 0)
2759                                          m_changedStrips.removeAt(iChannelStrip);                                          m_changedStrips.removeAt(iChannelStrip);
2760                          }                          }
# Line 2484  void MainForm::timerSlot (void) Line 2765  void MainForm::timerSlot (void)
2765                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {
2766                                  m_iTimerSlot = 0;                                  m_iTimerSlot = 0;
2767                                  // Update the channel stream usage for each strip...                                  // Update the channel stream usage for each strip...
2768                                  QWidgetList wlist = m_pWorkspace->windowList();                                  const QList<QMdiSubWindow *>& wlist
2769                                  for (int iChannel = 0;                                          = m_pWorkspace->subWindowList();
2770                                                  iChannel < (int) wlist.count(); iChannel++) {                                  const int iStripCount = wlist.count();
2771                                          ChannelStrip* pChannelStrip                                  for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2772                                                  = (ChannelStrip*) wlist.at(iChannel);                                          ChannelStrip *pChannelStrip = NULL;
2773                                            QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2774                                            if (pMdiSubWindow)
2775                                                    pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2776                                          if (pChannelStrip && pChannelStrip->isVisible())                                          if (pChannelStrip && pChannelStrip->isVisible())
2777                                                  pChannelStrip->updateChannelUsage();                                                  pChannelStrip->updateChannelUsage();
2778                                  }                                  }
# Line 2502  void MainForm::timerSlot (void) Line 2786  void MainForm::timerSlot (void)
2786    
2787    
2788  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2789  // qsamplerMainForm -- Server stuff.  // QSampler::MainForm -- Server stuff.
2790    
2791  // Start linuxsampler server...  // Start linuxsampler server...
2792  void MainForm::startServer (void)  void MainForm::startServer (void)
# Line 2516  void MainForm::startServer (void) Line 2800  void MainForm::startServer (void)
2800    
2801          // Is the server process instance still here?          // Is the server process instance still here?
2802          if (m_pServer) {          if (m_pServer) {
2803                  switch (QMessageBox::warning(this,                  if (QMessageBox::warning(this,
2804                          QSAMPLER_TITLE ": " + tr("Warning"),                          QSAMPLER_TITLE ": " + tr("Warning"),
2805                          tr("Could not start the LinuxSampler server.\n\n"                          tr("Could not start the LinuxSampler server.\n\n"
2806                          "Maybe it is already started."),                          "Maybe it is already started."),
2807                          tr("Stop"), tr("Kill"), tr("Cancel"))) {                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
                 case 0:  
2808                          m_pServer->terminate();                          m_pServer->terminate();
                         break;  
                 case 1:  
2809                          m_pServer->kill();                          m_pServer->kill();
                         break;  
2810                  }                  }
2811                  return;                  return;
2812          }          }
# Line 2540  void MainForm::startServer (void) Line 2820  void MainForm::startServer (void)
2820    
2821          // OK. Let's build the startup process...          // OK. Let's build the startup process...
2822          m_pServer = new QProcess();          m_pServer = new QProcess();
2823          bForceServerStop = true;          m_bForceServerStop = true;
2824    
2825          // Setup stdout/stderr capture...          // Setup stdout/stderr capture...
2826  //      if (m_pOptions->bStdoutCapture) {          m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);
2827  #if QT_VERSION >= 0x040200          QObject::connect(m_pServer,
2828                  m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);                  SIGNAL(readyReadStandardOutput()),
2829  #endif                  SLOT(readServerStdout()));
2830                  QObject::connect(m_pServer,          QObject::connect(m_pServer,
2831                          SIGNAL(readyReadStandardOutput()),                  SIGNAL(readyReadStandardError()),
2832                          SLOT(readServerStdout()));                  SLOT(readServerStdout()));
                 QObject::connect(m_pServer,  
                         SIGNAL(readyReadStandardError()),  
                         SLOT(readServerStdout()));  
 //      }  
2833    
2834          // The unforgiveable signal communication...          // The unforgiveable signal communication...
2835          QObject::connect(m_pServer,          QObject::connect(m_pServer,
# Line 2588  void MainForm::startServer (void) Line 2864  void MainForm::startServer (void)
2864    
2865    
2866  // Stop linuxsampler server...  // Stop linuxsampler server...
2867  void MainForm::stopServer (bool bInteractive)  void MainForm::stopServer ( bool bInteractive )
2868  {  {
2869          // Stop client code.          // Stop client code.
2870          stopClient();          stopClient();
# Line 2600  void MainForm::stopServer (bool bInterac Line 2876  void MainForm::stopServer (bool bInterac
2876                          "running in the background. The sampler would continue to work\n"                          "running in the background. The sampler would continue to work\n"
2877                          "according to your current sampler session and you could alter the\n"                          "according to your current sampler session and you could alter the\n"
2878                          "sampler session at any time by relaunching QSampler.\n\n"                          "sampler session at any time by relaunching QSampler.\n\n"
2879                          "Do you want LinuxSampler to stop or to keep running in\n"                          "Do you want LinuxSampler to stop?"),
2880                          "the background?"),                          QMessageBox::Yes | QMessageBox::No,
2881                          tr("Stop"), tr("Keep Running")) == 1)                          QMessageBox::Yes) == QMessageBox::No) {
2882                  {                          m_bForceServerStop = false;
                         bForceServerStop = false;  
2883                  }                  }
2884          }          }
2885    
2886            bool bGraceWait = true;
2887    
2888          // And try to stop server.          // And try to stop server.
2889          if (m_pServer && bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2890                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2891                  if (m_pServer->state() == QProcess::Running) {                  if (m_pServer->state() == QProcess::Running) {
2892  #if defined(WIN32)                  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
2893                          // Try harder...                          // Try harder...
2894                          m_pServer->kill();                          m_pServer->kill();
2895  #else                  #else
2896                          // Try softly...                          // Try softly...
2897                          m_pServer->terminate();                          m_pServer->terminate();
2898  #endif                          bool bFinished = m_pServer->waitForFinished(QSAMPLER_TIMER_MSECS * 1000);
2899                            if (bFinished) bGraceWait = false;
2900                    #endif
2901                  }                  }
2902          }       // Do final processing anyway.          }       // Do final processing anyway.
2903          else processServerExit();          else processServerExit();
2904    
2905          // Give it some time to terminate gracefully and stabilize...          // Give it some time to terminate gracefully and stabilize...
2906          QTime t;          if (bGraceWait) {
2907          t.start();                  QTime t;
2908          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                  t.start();
2909                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2910                            QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2911            }
2912  }  }
2913    
2914    
# Line 2649  void MainForm::processServerExit (void) Line 2930  void MainForm::processServerExit (void)
2930          if (m_pMessages)          if (m_pMessages)
2931                  m_pMessages->flushStdoutBuffer();                  m_pMessages->flushStdoutBuffer();
2932    
2933          if (m_pServer && bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2934                  if (m_pServer->state() != QProcess::NotRunning) {                  if (m_pServer->state() != QProcess::NotRunning) {
2935                          appendMessages(tr("Server is being forced..."));                          appendMessages(tr("Server is being forced..."));
2936                          // Force final server shutdown...                          // Force final server shutdown...
# Line 2674  void MainForm::processServerExit (void) Line 2955  void MainForm::processServerExit (void)
2955    
2956    
2957  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2958  // qsamplerMainForm -- Client stuff.  // QSampler::MainForm -- Client stuff.
2959    
2960  // The LSCP client callback procedure.  // The LSCP client callback procedure.
2961  lscp_status_t qsampler_client_callback ( lscp_client_t */*pClient*/,  lscp_status_t qsampler_client_callback ( lscp_client_t */*pClient*/,
# Line 2688  lscp_status_t qsampler_client_callback ( Line 2969  lscp_status_t qsampler_client_callback (
2969          // as this is run under some other thread context.          // as this is run under some other thread context.
2970          // A custom event must be posted here...          // A custom event must be posted here...
2971          QApplication::postEvent(pMainForm,          QApplication::postEvent(pMainForm,
2972                  new CustomEvent(event, pchData, cchData));                  new LscpEvent(event, pchData, cchData));
2973    
2974          return LSCP_OK;          return LSCP_OK;
2975  }  }
# Line 2726  bool MainForm::startClient (void) Line 3007  bool MainForm::startClient (void)
3007                  stabilizeForm();                  stabilizeForm();
3008                  return false;                  return false;
3009          }          }
3010    
3011          // Just set receive timeout value, blindly.          // Just set receive timeout value, blindly.
3012          ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);          ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
3013          appendMessages(          appendMessages(
# Line 2847  void MainForm::stopClient (void) Line 3129  void MainForm::stopClient (void)
3129    
3130    
3131  // Channel strip activation/selection.  // Channel strip activation/selection.
3132  void MainForm::activateStrip ( QWidget *pWidget )  void MainForm::activateStrip ( QMdiSubWindow *pMdiSubWindow )
3133  {  {
3134          ChannelStrip *pChannelStrip          ChannelStrip *pChannelStrip = NULL;
3135                  = static_cast<ChannelStrip *> (pWidget);          if (pMdiSubWindow)
3136                    pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
3137          if (pChannelStrip)          if (pChannelStrip)
3138                  pChannelStrip->setSelected(true);                  pChannelStrip->setSelected(true);
3139    
# Line 2858  void MainForm::activateStrip ( QWidget * Line 3141  void MainForm::activateStrip ( QWidget *
3141  }  }
3142    
3143    
3144    // Channel toolbar orientation change.
3145    void MainForm::channelsToolbarOrientation ( Qt::Orientation orientation )
3146    {
3147    #ifdef CONFIG_VOLUME
3148            m_pVolumeSlider->setOrientation(orientation);
3149            if (orientation == Qt::Horizontal) {
3150                    m_pVolumeSlider->setMinimumHeight(24);
3151                    m_pVolumeSlider->setMaximumHeight(32);
3152                    m_pVolumeSlider->setMinimumWidth(120);
3153                    m_pVolumeSlider->setMaximumWidth(640);
3154                    m_pVolumeSpinBox->setMaximumWidth(64);
3155                    m_pVolumeSpinBox->setButtonSymbols(QSpinBox::UpDownArrows);
3156            } else {
3157                    m_pVolumeSlider->setMinimumHeight(120);
3158                    m_pVolumeSlider->setMaximumHeight(480);
3159                    m_pVolumeSlider->setMinimumWidth(24);
3160                    m_pVolumeSlider->setMaximumWidth(32);
3161                    m_pVolumeSpinBox->setMaximumWidth(32);
3162                    m_pVolumeSpinBox->setButtonSymbols(QSpinBox::NoButtons);
3163            }
3164    #endif
3165    }
3166    
3167    
3168  } // namespace QSampler  } // namespace QSampler
3169    
3170    

Legend:
Removed from v.1815  
changed lines
  Added in v.3437

  ViewVC Help
Powered by ViewVC