/[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 1515 by capela, Fri Nov 23 18:15:33 2007 UTC revision 2387 by capela, Sat Dec 29 00:21:11 2012 UTC
# Line 1  Line 1 
1  // qsamplerMainForm.cpp  // qsamplerMainForm.cpp
2  //  //
3  /****************************************************************************  /****************************************************************************
4     Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2012, rncbc aka Rui Nuno Capela. All rights reserved.
5     Copyright (C) 2007, Christian Schoenebeck     Copyright (C) 2007, 2008 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 33  Line 33 
33  #include "qsamplerInstrumentListForm.h"  #include "qsamplerInstrumentListForm.h"
34  #include "qsamplerDeviceForm.h"  #include "qsamplerDeviceForm.h"
35  #include "qsamplerOptionsForm.h"  #include "qsamplerOptionsForm.h"
36    #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 55  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    #if QT_VERSION < 0x040200
69    const WindowFlags CustomizeWindowHint   = WindowFlags(0x02000000);
70    #endif
71    }
72    #endif
73    
74  #ifdef HAVE_SIGNAL_H  #ifdef HAVE_SIGNAL_H
75  #include <signal.h>  #include <signal.h>
# Line 77  static inline long lroundf ( float x ) Line 92  static inline long lroundf ( float x )
92  }  }
93  #endif  #endif
94    
95    
96    // All winsock apps needs this.
97    #if defined(WIN32)
98    static WSADATA _wsaData;
99    #endif
100    
101    
102    //-------------------------------------------------------------------------
103    // LADISH Level 1 support stuff.
104    
105    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
106    
107    #include <QSocketNotifier>
108    
109    #include <sys/types.h>
110    #include <sys/socket.h>
111    
112    #include <signal.h>
113    
114    // File descriptor for SIGUSR1 notifier.
115    static int g_fdUsr1[2];
116    
117    // Unix SIGUSR1 signal handler.
118    static void qsampler_sigusr1_handler ( int /* signo */ )
119    {
120            char c = 1;
121    
122            (::write(g_fdUsr1[0], &c, sizeof(c)) > 0);
123    }
124    
125    #endif  // HAVE_SIGNAL_H
126    
127    
128    //-------------------------------------------------------------------------
129    // qsampler -- namespace
130    
131    
132    namespace QSampler {
133    
134  // Timer constant stuff.  // Timer constant stuff.
135  #define QSAMPLER_TIMER_MSECS    200  #define QSAMPLER_TIMER_MSECS    200
136    
# Line 87  static inline long lroundf ( float x ) Line 141  static inline long lroundf ( float x )
141  #define QSAMPLER_STATUS_SESSION 3       // Current session modification state.  #define QSAMPLER_STATUS_SESSION 3       // Current session modification state.
142    
143    
144  // All winsock apps needs this.  // Specialties for thread-callback comunication.
145  #if defined(WIN32)  #define QSAMPLER_LSCP_EVENT   QEvent::Type(QEvent::User + 1)
 static WSADATA _wsaData;  
 #endif  
146    
147    
148  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
149  // qsamplerCustomEvent -- specialty for callback comunication.  // LscpEvent -- specialty for LSCP callback comunication.
150    
 #define QSAMPLER_CUSTOM_EVENT   QEvent::Type(QEvent::User + 0)  
151    
152  class qsamplerCustomEvent : public QEvent  class LscpEvent : public QEvent
153  {  {
154  public:  public:
155    
156          // Constructor.          // Constructor.
157          qsamplerCustomEvent(lscp_event_t event, const char *pchData, int cchData)          LscpEvent(lscp_event_t event, const char *pchData, int cchData)
158                  : QEvent(QSAMPLER_CUSTOM_EVENT)                  : QEvent(QSAMPLER_LSCP_EVENT)
159          {          {
160                  m_event = event;                  m_event = event;
161                  m_data  = QString::fromUtf8(pchData, cchData);                  m_data  = QString::fromUtf8(pchData, cchData);
# Line 126  private: Line 177  private:
177  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
178  // qsamplerMainForm -- Main window form implementation.  // qsamplerMainForm -- Main window form implementation.
179    
 namespace QSampler {  
   
180  // Kind of singleton reference.  // Kind of singleton reference.
181  MainForm* MainForm::g_pMainForm = NULL;  MainForm* MainForm::g_pMainForm = NULL;
182    
# Line 159  MainForm::MainForm ( QWidget *pParent ) Line 208  MainForm::MainForm ( QWidget *pParent )
208    
209          m_iTimerSlot = 0;          m_iTimerSlot = 0;
210    
211  #ifdef HAVE_SIGNAL_H  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
212    
213          // Set to ignore any fatal "Broken pipe" signals.          // Set to ignore any fatal "Broken pipe" signals.
214          ::signal(SIGPIPE, SIG_IGN);          ::signal(SIGPIPE, SIG_IGN);
215  #endif  
216            // LADISH Level 1 suport.
217    
218            // Initialize file descriptors for SIGUSR1 socket notifier.
219            ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdUsr1);
220            m_pUsr1Notifier
221                    = new QSocketNotifier(g_fdUsr1[1], QSocketNotifier::Read, this);
222    
223            QObject::connect(m_pUsr1Notifier,
224                    SIGNAL(activated(int)),
225                    SLOT(handle_sigusr1()));
226    
227            // Install SIGUSR1 signal handler.
228        struct sigaction usr1;
229        usr1.sa_handler = qsampler_sigusr1_handler;
230        sigemptyset(&usr1.sa_mask);
231        usr1.sa_flags = 0;
232        usr1.sa_flags |= SA_RESTART;
233        ::sigaction(SIGUSR1, &usr1, NULL);
234    
235    #else   // HAVE_SIGNAL_H
236    
237            m_pUsr1Notifier = NULL;
238            
239    #endif  // !HAVE_SIGNAL_H
240    
241  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
242          // Make some extras into the toolbar...          // Make some extras into the toolbar...
# Line 201  MainForm::MainForm ( QWidget *pParent ) Line 275  MainForm::MainForm ( QWidget *pParent )
275  #endif  #endif
276    
277          // Make it an MDI workspace.          // Make it an MDI workspace.
278          m_pWorkspace = new QWorkspace(this);          m_pWorkspace = new QMdiArea(this);
         m_pWorkspace->setScrollBarsEnabled(true);  
279          // Set the activation connection.          // Set the activation connection.
280          QObject::connect(m_pWorkspace,          QObject::connect(m_pWorkspace,
281                  SIGNAL(windowActivated(QWidget *)),                  SIGNAL(subWindowActivated(QMdiSubWindow *)),
282                  SLOT(activateStrip(QWidget *)));                  SLOT(activateStrip(QMdiSubWindow *)));
283          // Make it shine :-)          // Make it shine :-)
284          setCentralWidget(m_pWorkspace);          setCentralWidget(m_pWorkspace);
285    
# Line 335  MainForm::~MainForm() Line 408  MainForm::~MainForm()
408          WSACleanup();          WSACleanup();
409  #endif  #endif
410    
411    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
412            if (m_pUsr1Notifier)
413                    delete m_pUsr1Notifier;
414    #endif
415    
416          // Finally drop any widgets around...          // Finally drop any widgets around...
417          if (m_pDeviceForm)          if (m_pDeviceForm)
418                  delete m_pDeviceForm;                  delete m_pDeviceForm;
# Line 366  MainForm::~MainForm() Line 444  MainForm::~MainForm()
444    
445    
446  // Make and set a proper setup options step.  // Make and set a proper setup options step.
447  void MainForm::setup ( qsamplerOptions *pOptions )  void MainForm::setup ( Options *pOptions )
448  {  {
449          // We got options?          // We got options?
450          m_pOptions = pOptions;          m_pOptions = pOptions;
451    
452          // What style do we create these forms?          // What style do we create these forms?
453          Qt::WindowFlags wflags = Qt::Window          Qt::WindowFlags wflags = Qt::Window
 #if QT_VERSION >= 0x040200  
454                  | Qt::CustomizeWindowHint                  | Qt::CustomizeWindowHint
 #endif  
455                  | Qt::WindowTitleHint                  | Qt::WindowTitleHint
456                  | Qt::WindowSystemMenuHint                  | Qt::WindowSystemMenuHint
457                  | Qt::WindowMinMaxButtonsHint;                  | Qt::WindowMinMaxButtonsHint
458                    | Qt::WindowCloseButtonHint;
459          if (m_pOptions->bKeepOnTop)          if (m_pOptions->bKeepOnTop)
460                  wflags |= Qt::Tool;                  wflags |= Qt::Tool;
461    
462          // Some child forms are to be created right now.          // Some child forms are to be created right now.
463          m_pMessages = new qsamplerMessages(this);          m_pMessages = new Messages(this);
464          m_pDeviceForm = new DeviceForm(this, wflags);          m_pDeviceForm = new DeviceForm(this, wflags);
465  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
466          m_pInstrumentListForm = new InstrumentListForm(this, wflags);          m_pInstrumentListForm = new InstrumentListForm(this, wflags);
467  #else  #else
468          viewInstrumentsAction->setEnabled(false);          m_ui.viewInstrumentsAction->setEnabled(false);
469  #endif  #endif
470    
471            // Setup messages logging appropriately...
472            m_pMessages->setLogging(
473                    m_pOptions->bMessagesLog,
474                    m_pOptions->sMessagesLogPath);
475    
476          // Set message defaults...          // Set message defaults...
477          updateMessagesFont();          updateMessagesFont();
478          updateMessagesLimit();          updateMessagesLimit();
# Line 419  void MainForm::setup ( qsamplerOptions * Line 503  void MainForm::setup ( qsamplerOptions *
503          }          }
504    
505          // Try to restore old window positioning and initial visibility.          // Try to restore old window positioning and initial visibility.
506          m_pOptions->loadWidgetGeometry(this);          m_pOptions->loadWidgetGeometry(this, true);
507          m_pOptions->loadWidgetGeometry(m_pInstrumentListForm);          m_pOptions->loadWidgetGeometry(m_pInstrumentListForm);
508          m_pOptions->loadWidgetGeometry(m_pDeviceForm);          m_pOptions->loadWidgetGeometry(m_pDeviceForm);
509    
# Line 463  bool MainForm::queryClose (void) Line 547  bool MainForm::queryClose (void)
547                          // And the children, and the main windows state,.                          // And the children, and the main windows state,.
548                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);
549                          m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);                          m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
550                          m_pOptions->saveWidgetGeometry(this);                          m_pOptions->saveWidgetGeometry(this, true);
551                          // Close popup widgets.                          // Close popup widgets.
552                          if (m_pInstrumentListForm)                          if (m_pInstrumentListForm)
553                                  m_pInstrumentListForm->close();                                  m_pInstrumentListForm->close();
554                          if (m_pDeviceForm)                          if (m_pDeviceForm)
555                                  m_pDeviceForm->close();                                  m_pDeviceForm->close();
556                          // Stop client and/or server, gracefully.                          // Stop client and/or server, gracefully.
557                          stopServer();                          stopServer(true /*interactive*/);
558                  }                  }
559          }          }
560    
# Line 480  bool MainForm::queryClose (void) Line 564  bool MainForm::queryClose (void)
564    
565  void MainForm::closeEvent ( QCloseEvent *pCloseEvent )  void MainForm::closeEvent ( QCloseEvent *pCloseEvent )
566  {  {
567          if (queryClose())          if (queryClose()) {
568                    DeviceStatusForm::deleteAllInstances();
569                  pCloseEvent->accept();                  pCloseEvent->accept();
570          else          } else
571                  pCloseEvent->ignore();                  pCloseEvent->ignore();
572  }  }
573    
# Line 511  void MainForm::dropEvent ( QDropEvent* p Line 596  void MainForm::dropEvent ( QDropEvent* p
596                  QListIterator<QUrl> iter(pMimeData->urls());                  QListIterator<QUrl> iter(pMimeData->urls());
597                  while (iter.hasNext()) {                  while (iter.hasNext()) {
598                          const QString& sPath = iter.next().toLocalFile();                          const QString& sPath = iter.next().toLocalFile();
599                          if (qsamplerChannel::isInstrumentFile(sPath)) {                  //      if (Channel::isDlsInstrumentFile(sPath)) {
600                            if (QFileInfo(sPath).exists()) {
601                                  // Try to create a new channel from instrument file...                                  // Try to create a new channel from instrument file...
602                                  qsamplerChannel *pChannel = new qsamplerChannel();                                  Channel *pChannel = new Channel();
603                                  if (pChannel == NULL)                                  if (pChannel == NULL)
604                                          return;                                          return;
605                                  // Start setting the instrument filename...                                  // Start setting the instrument filename...
# Line 545  void MainForm::dropEvent ( QDropEvent* p Line 631  void MainForm::dropEvent ( QDropEvent* p
631    
632    
633  // Custome event handler.  // Custome event handler.
634  void MainForm::customEvent(QEvent* pCustomEvent)  void MainForm::customEvent ( QEvent* pEvent )
635  {  {
636          // For the time being, just pump it to messages.          // For the time being, just pump it to messages.
637          if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {          if (pEvent->type() == QSAMPLER_LSCP_EVENT) {
638                  qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;                  LscpEvent *pLscpEvent = static_cast<LscpEvent *> (pEvent);
639                  if (pEvent->event() == LSCP_EVENT_CHANNEL_INFO) {                  switch (pLscpEvent->event()) {
640                          int iChannelID = pEvent->data().toInt();                          case LSCP_EVENT_CHANNEL_COUNT:
641                          ChannelStrip *pChannelStrip = channelStrip(iChannelID);                                  updateAllChannelStrips(true);
642                          if (pChannelStrip)                                  break;
643                                  channelStripChanged(pChannelStrip);                          case LSCP_EVENT_CHANNEL_INFO: {
644                  } else {                                  int iChannelID = pLscpEvent->data().toInt();
645                          appendMessagesColor(tr("Notify event: %1 data: %2")                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);
646                                  .arg(::lscp_event_to_text(pEvent->event()))                                  if (pChannelStrip)
647                                  .arg(pEvent->data()), "#996699");                                          channelStripChanged(pChannelStrip);
648                                    break;
649                            }
650                            case LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT:
651                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
652                                    DeviceStatusForm::onDevicesChanged();
653                                    updateViewMidiDeviceStatusMenu();
654                                    break;
655                            case LSCP_EVENT_MIDI_INPUT_DEVICE_INFO: {
656                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
657                                    const int iDeviceID = pLscpEvent->data().section(' ', 0, 0).toInt();
658                                    DeviceStatusForm::onDeviceChanged(iDeviceID);
659                                    break;
660                            }
661                            case LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT:
662                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
663                                    break;
664                            case LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO:
665                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
666                                    break;
667                    #if CONFIG_EVENT_CHANNEL_MIDI
668                            case LSCP_EVENT_CHANNEL_MIDI: {
669                                    const int iChannelID = pLscpEvent->data().section(' ', 0, 0).toInt();
670                                    ChannelStrip *pChannelStrip = channelStrip(iChannelID);
671                                    if (pChannelStrip)
672                                            pChannelStrip->midiActivityLedOn();
673                                    break;
674                            }
675                    #endif
676                    #if CONFIG_EVENT_DEVICE_MIDI
677                            case LSCP_EVENT_DEVICE_MIDI: {
678                                    const int iDeviceID = pLscpEvent->data().section(' ', 0, 0).toInt();
679                                    const int iPortID   = pLscpEvent->data().section(' ', 1, 1).toInt();
680                                    DeviceStatusForm *pDeviceStatusForm
681                                            = DeviceStatusForm::getInstance(iDeviceID);
682                                    if (pDeviceStatusForm)
683                                            pDeviceStatusForm->midiArrived(iPortID);
684                                    break;
685                            }
686                    #endif
687                            default:
688                                    appendMessagesColor(tr("LSCP Event: %1 data: %2")
689                                            .arg(::lscp_event_to_text(pLscpEvent->event()))
690                                            .arg(pLscpEvent->data()), "#996699");
691                  }                  }
692          }          }
693  }  }
694    
695    
696    // LADISH Level 1 -- SIGUSR1 signal handler.
697    void MainForm::handle_sigusr1 (void)
698    {
699    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
700    
701            char c;
702    
703            if (::read(g_fdUsr1[1], &c, sizeof(c)) > 0)
704                    saveSession(false);
705    
706    #endif
707    }
708    
709    
710    void MainForm::updateViewMidiDeviceStatusMenu (void)
711    {
712            m_ui.viewMidiDeviceStatusMenu->clear();
713            const std::map<int, DeviceStatusForm *> statusForms
714                    = DeviceStatusForm::getInstances();
715            std::map<int, DeviceStatusForm *>::const_iterator iter
716                    = statusForms.begin();
717            for ( ; iter != statusForms.end(); ++iter) {
718                    DeviceStatusForm *pStatusForm = iter->second;
719                    m_ui.viewMidiDeviceStatusMenu->addAction(
720                            pStatusForm->visibleAction());
721            }
722    }
723    
724    
725  // Context menu event handler.  // Context menu event handler.
726  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )
727  {  {
# Line 576  void MainForm::contextMenuEvent( QContex Line 735  void MainForm::contextMenuEvent( QContex
735  // qsamplerMainForm -- Brainless public property accessors.  // qsamplerMainForm -- Brainless public property accessors.
736    
737  // The global options settings property.  // The global options settings property.
738  qsamplerOptions *MainForm::options (void) const  Options *MainForm::options (void) const
739  {  {
740          return m_pOptions;          return m_pOptions;
741  }  }
# Line 694  bool MainForm::saveSession ( bool bPromp Line 853  bool MainForm::saveSession ( bool bPromp
853                                  "\"%1\"\n\n"                                  "\"%1\"\n\n"
854                                  "Do you want to replace it?")                                  "Do you want to replace it?")
855                                  .arg(sFilename),                                  .arg(sFilename),
856                                  tr("Replace"), tr("Cancel")) > 0)                                  QMessageBox::Yes | QMessageBox::No)
857                                    == QMessageBox::No)
858                                  return false;                                  return false;
859                  }                  }
860          }          }
# Line 717  bool MainForm::closeSession ( bool bForc Line 877  bool MainForm::closeSession ( bool bForc
877                          "\"%1\"\n\n"                          "\"%1\"\n\n"
878                          "Do you want to save the changes?")                          "Do you want to save the changes?")
879                          .arg(sessionName(m_sFilename)),                          .arg(sessionName(m_sFilename)),
880                          tr("Save"), tr("Discard"), tr("Cancel"))) {                          QMessageBox::Save |
881                  case 0:     // Save...                          QMessageBox::Discard |
882                            QMessageBox::Cancel)) {
883                    case QMessageBox::Save:
884                          bClose = saveSession(false);                          bClose = saveSession(false);
885                          // Fall thru....                          // Fall thru....
886                  case 1:     // Discard                  case QMessageBox::Discard:
887                          break;                          break;
888                  default:    // Cancel.                  default:    // Cancel.
889                          bClose = false;                          bClose = false;
# Line 733  bool MainForm::closeSession ( bool bForc Line 895  bool MainForm::closeSession ( bool bForc
895          if (bClose) {          if (bClose) {
896                  // Remove all channel strips from sight...                  // Remove all channel strips from sight...
897                  m_pWorkspace->setUpdatesEnabled(false);                  m_pWorkspace->setUpdatesEnabled(false);
898                  QWidgetList wlist = m_pWorkspace->windowList();                  QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
899                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                  for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {
900                          ChannelStrip *pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                          ChannelStrip *pChannelStrip = NULL;
901                            QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);
902                            if (pMdiSubWindow)
903                                    pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
904                          if (pChannelStrip) {                          if (pChannelStrip) {
905                                  qsamplerChannel *pChannel = pChannelStrip->channel();                                  Channel *pChannel = pChannelStrip->channel();
906                                  if (bForce && pChannel)                                  if (bForce && pChannel)
907                                          pChannel->removeChannel();                                          pChannel->removeChannel();
908                                  delete pChannelStrip;                                  delete pChannelStrip;
# Line 877  bool MainForm::saveSessionFile ( const Q Line 1042  bool MainForm::saveSessionFile ( const Q
1042    
1043          // Audio device mapping.          // Audio device mapping.
1044          QMap<int, int> audioDeviceMap;          QMap<int, int> audioDeviceMap;
1045          piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Audio);          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);
1046          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
1047                  ts << endl;                  ts << endl;
1048                  qsamplerDevice device(qsamplerDevice::Audio, piDeviceIDs[iDevice]);                  Device device(Device::Audio, piDeviceIDs[iDevice]);
1049                  // Audio device specification...                  // Audio device specification...
1050                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1051                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1052                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
1053                  qsamplerDeviceParamMap::ConstIterator deviceParam;                  DeviceParamMap::ConstIterator deviceParam;
1054                  for (deviceParam = device.params().begin();                  for (deviceParam = device.params().begin();
1055                                  deviceParam != device.params().end();                                  deviceParam != device.params().end();
1056                                          ++deviceParam) {                                          ++deviceParam) {
1057                          const qsamplerDeviceParam& param = deviceParam.value();                          const DeviceParam& param = deviceParam.value();
1058                          if (param.value.isEmpty()) ts << "# ";                          if (param.value.isEmpty()) ts << "# ";
1059                          ts << " " << deviceParam.key() << "='" << param.value << "'";                          ts << " " << deviceParam.key() << "='" << param.value << "'";
1060                  }                  }
1061                  ts << endl;                  ts << endl;
1062                  // Audio channel parameters...                  // Audio channel parameters...
1063                  int iPort = 0;                  int iPort = 0;
1064                  QListIterator<qsamplerDevicePort *> iter(device.ports());                  QListIterator<DevicePort *> iter(device.ports());
1065                  while (iter.hasNext()) {                  while (iter.hasNext()) {
1066                          qsamplerDevicePort *pPort = iter.next();                          DevicePort *pPort = iter.next();
1067                          qsamplerDeviceParamMap::ConstIterator portParam;                          DeviceParamMap::ConstIterator portParam;
1068                          for (portParam = pPort->params().begin();                          for (portParam = pPort->params().begin();
1069                                          portParam != pPort->params().end();                                          portParam != pPort->params().end();
1070                                                  ++portParam) {                                                  ++portParam) {
1071                                  const qsamplerDeviceParam& param = portParam.value();                                  const DeviceParam& param = portParam.value();
1072                                  if (param.fix || param.value.isEmpty()) ts << "# ";                                  if (param.fix || param.value.isEmpty()) ts << "# ";
1073                                  ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice                                  ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice
1074                                          << " " << iPort << " " << portParam.key()                                          << " " << iPort << " " << portParam.key()
# Line 919  bool MainForm::saveSessionFile ( const Q Line 1084  bool MainForm::saveSessionFile ( const Q
1084    
1085          // MIDI device mapping.          // MIDI device mapping.
1086          QMap<int, int> midiDeviceMap;          QMap<int, int> midiDeviceMap;
1087          piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Midi);          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);
1088          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
1089                  ts << endl;                  ts << endl;
1090                  qsamplerDevice device(qsamplerDevice::Midi, piDeviceIDs[iDevice]);                  Device device(Device::Midi, piDeviceIDs[iDevice]);
1091                  // MIDI device specification...                  // MIDI device specification...
1092                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1093                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1094                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
1095                  qsamplerDeviceParamMap::ConstIterator deviceParam;                  DeviceParamMap::ConstIterator deviceParam;
1096                  for (deviceParam = device.params().begin();                  for (deviceParam = device.params().begin();
1097                                  deviceParam != device.params().end();                                  deviceParam != device.params().end();
1098                                          ++deviceParam) {                                          ++deviceParam) {
1099                          const qsamplerDeviceParam& param = deviceParam.value();                          const DeviceParam& param = deviceParam.value();
1100                          if (param.value.isEmpty()) ts << "# ";                          if (param.value.isEmpty()) ts << "# ";
1101                          ts << " " << deviceParam.key() << "='" << param.value << "'";                          ts << " " << deviceParam.key() << "='" << param.value << "'";
1102                  }                  }
1103                  ts << endl;                  ts << endl;
1104                  // MIDI port parameters...                  // MIDI port parameters...
1105                  int iPort = 0;                  int iPort = 0;
1106                  QListIterator<qsamplerDevicePort *> iter(device.ports());                  QListIterator<DevicePort *> iter(device.ports());
1107                  while (iter.hasNext()) {                  while (iter.hasNext()) {
1108                          qsamplerDevicePort *pPort = iter.next();                          DevicePort *pPort = iter.next();
1109                          qsamplerDeviceParamMap::ConstIterator portParam;                          DeviceParamMap::ConstIterator portParam;
1110                          for (portParam = pPort->params().begin();                          for (portParam = pPort->params().begin();
1111                                          portParam != pPort->params().end();                                          portParam != pPort->params().end();
1112                                                  ++portParam) {                                                  ++portParam) {
1113                                  const qsamplerDeviceParam& param = portParam.value();                                  const DeviceParam& param = portParam.value();
1114                                  if (param.fix || param.value.isEmpty()) ts << "# ";                                  if (param.fix || param.value.isEmpty()) ts << "# ";
1115                                  ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice                                  ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice
1116                                  << " " << iPort << " " << portParam.key()                                  << " " << iPort << " " << portParam.key()
# Line 1032  bool MainForm::saveSessionFile ( const Q Line 1197  bool MainForm::saveSessionFile ( const Q
1197  #endif  // CONFIG_MIDI_INSTRUMENT  #endif  // CONFIG_MIDI_INSTRUMENT
1198    
1199          // Sampler channel mapping.          // Sampler channel mapping.
1200          QWidgetList wlist = m_pWorkspace->windowList();          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
1201          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {
1202                  ChannelStrip* pChannelStrip                  ChannelStrip *pChannelStrip = NULL;
1203                          = static_cast<ChannelStrip *> (wlist.at(iChannel));                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);
1204                    if (pMdiSubWindow)
1205                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
1206                  if (pChannelStrip) {                  if (pChannelStrip) {
1207                          qsamplerChannel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1208                          if (pChannel) {                          if (pChannel) {
1209                                  ts << "# " << tr("Channel") << " " << iChannel << endl;                                  ts << "# " << tr("Channel") << " " << iChannel << endl;
1210                                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
# Line 1069  bool MainForm::saveSessionFile ( const Q Line 1236  bool MainForm::saveSessionFile ( const Q
1236                                  ts << "LOAD INSTRUMENT NON_MODAL '"                                  ts << "LOAD INSTRUMENT NON_MODAL '"
1237                                          << pChannel->instrumentFile() << "' "                                          << pChannel->instrumentFile() << "' "
1238                                          << pChannel->instrumentNr() << " " << iChannel << endl;                                          << pChannel->instrumentNr() << " " << iChannel << endl;
1239                                  qsamplerChannelRoutingMap::ConstIterator audioRoute;                                  ChannelRoutingMap::ConstIterator audioRoute;
1240                                  for (audioRoute = pChannel->audioRouting().begin();                                  for (audioRoute = pChannel->audioRouting().begin();
1241                                                  audioRoute != pChannel->audioRouting().end();                                                  audioRoute != pChannel->audioRouting().end();
1242                                                          ++audioRoute) {                                                          ++audioRoute) {
# Line 1242  void MainForm::fileReset (void) Line 1409  void MainForm::fileReset (void)
1409                  "Please note that this operation may cause\n"                  "Please note that this operation may cause\n"
1410                  "temporary MIDI and Audio disruption.\n\n"                  "temporary MIDI and Audio disruption.\n\n"
1411                  "Do you want to reset the sampler engine now?"),                  "Do you want to reset the sampler engine now?"),
1412                  tr("Reset"), tr("Cancel")) > 0)                  QMessageBox::Ok | QMessageBox::Cancel)
1413                    == QMessageBox::Cancel)
1414                  return;                  return;
1415    
1416          // Trye closing the current session, first...          // Trye closing the current session, first...
# Line 1283  void MainForm::fileRestart (void) Line 1451  void MainForm::fileRestart (void)
1451                          "Please note that this operation may cause\n"                          "Please note that this operation may cause\n"
1452                          "temporary MIDI and Audio disruption.\n\n"                          "temporary MIDI and Audio disruption.\n\n"
1453                          "Do you want to restart the connection now?"),                          "Do you want to restart the connection now?"),
1454                          tr("Restart"), tr("Cancel")) == 0);                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok);
1455          }          }
1456    
1457          // Are we still for it?          // Are we still for it?
# Line 1314  void MainForm::editAddChannel (void) Line 1482  void MainForm::editAddChannel (void)
1482                  return;                  return;
1483    
1484          // Just create the channel instance...          // Just create the channel instance...
1485          qsamplerChannel *pChannel = new qsamplerChannel();          Channel *pChannel = new Channel();
1486          if (pChannel == NULL)          if (pChannel == NULL)
1487                  return;                  return;
1488    
# Line 1348  void MainForm::editRemoveChannel (void) Line 1516  void MainForm::editRemoveChannel (void)
1516          if (m_pClient == NULL)          if (m_pClient == NULL)
1517                  return;                  return;
1518    
1519          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1520          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1521                  return;                  return;
1522    
1523          qsamplerChannel *pChannel = pChannelStrip->channel();          Channel *pChannel = pChannelStrip->channel();
1524          if (pChannel == NULL)          if (pChannel == NULL)
1525                  return;                  return;
1526    
# Line 1364  void MainForm::editRemoveChannel (void) Line 1532  void MainForm::editRemoveChannel (void)
1532                          "%1\n\n"                          "%1\n\n"
1533                          "Are you sure?")                          "Are you sure?")
1534                          .arg(pChannelStrip->windowTitle()),                          .arg(pChannelStrip->windowTitle()),
1535                          tr("OK"), tr("Cancel")) > 0)                          QMessageBox::Ok | QMessageBox::Cancel)
1536                            == QMessageBox::Cancel)
1537                          return;                          return;
1538          }          }
1539    
# Line 1391  void MainForm::editSetupChannel (void) Line 1560  void MainForm::editSetupChannel (void)
1560          if (m_pClient == NULL)          if (m_pClient == NULL)
1561                  return;                  return;
1562    
1563          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1564          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1565                  return;                  return;
1566    
# Line 1406  void MainForm::editEditChannel (void) Line 1575  void MainForm::editEditChannel (void)
1575          if (m_pClient == NULL)          if (m_pClient == NULL)
1576                  return;                  return;
1577    
1578          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1579          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1580                  return;                  return;
1581    
# Line 1421  void MainForm::editResetChannel (void) Line 1590  void MainForm::editResetChannel (void)
1590          if (m_pClient == NULL)          if (m_pClient == NULL)
1591                  return;                  return;
1592    
1593          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1594          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1595                  return;                  return;
1596    
# Line 1439  void MainForm::editResetAllChannels (voi Line 1608  void MainForm::editResetAllChannels (voi
1608          // Invoque the channel strip procedure,          // Invoque the channel strip procedure,
1609          // for all channels out there...          // for all channels out there...
1610          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1611          QWidgetList wlist = m_pWorkspace->windowList();          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
1612          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {
1613                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  ChannelStrip *pChannelStrip = NULL;
1614                    QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);
1615                    if (pMdiSubWindow)
1616                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
1617                  if (pChannelStrip)                  if (pChannelStrip)
1618                          pChannelStrip->channelReset();                          pChannelStrip->channelReset();
1619          }          }
# Line 1544  void MainForm::viewOptions (void) Line 1716  void MainForm::viewOptions (void)
1716          OptionsForm* pOptionsForm = new OptionsForm(this);          OptionsForm* pOptionsForm = new OptionsForm(this);
1717          if (pOptionsForm) {          if (pOptionsForm) {
1718                  // Check out some initial nullities(tm)...                  // Check out some initial nullities(tm)...
1719                  ChannelStrip* pChannelStrip = activeChannelStrip();                  ChannelStrip *pChannelStrip = activeChannelStrip();
1720                  if (m_pOptions->sDisplayFont.isEmpty() && pChannelStrip)                  if (m_pOptions->sDisplayFont.isEmpty() && pChannelStrip)
1721                          m_pOptions->sDisplayFont = pChannelStrip->displayFont().toString();                          m_pOptions->sDisplayFont = pChannelStrip->displayFont().toString();
1722                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)
# Line 1555  void MainForm::viewOptions (void) Line 1727  void MainForm::viewOptions (void)
1727                  int     iOldServerTimeout   = m_pOptions->iServerTimeout;                  int     iOldServerTimeout   = m_pOptions->iServerTimeout;
1728                  bool    bOldServerStart     = m_pOptions->bServerStart;                  bool    bOldServerStart     = m_pOptions->bServerStart;
1729                  QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;                  QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;
1730                    bool    bOldMessagesLog     = m_pOptions->bMessagesLog;
1731                    QString sOldMessagesLogPath = m_pOptions->sMessagesLogPath;
1732                  QString sOldDisplayFont     = m_pOptions->sDisplayFont;                  QString sOldDisplayFont     = m_pOptions->sDisplayFont;
1733                  bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;                  bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1734                  int     iOldMaxVolume       = m_pOptions->iMaxVolume;                  int     iOldMaxVolume       = m_pOptions->iMaxVolume;
# Line 1566  void MainForm::viewOptions (void) Line 1740  void MainForm::viewOptions (void)
1740                  bool    bOldCompletePath    = m_pOptions->bCompletePath;                  bool    bOldCompletePath    = m_pOptions->bCompletePath;
1741                  bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;                  bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1742                  int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;                  int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1743                    int     iOldBaseFontSize    = m_pOptions->iBaseFontSize;
1744                  // Load the current setup settings.                  // Load the current setup settings.
1745                  pOptionsForm->setup(m_pOptions);                  pOptionsForm->setup(m_pOptions);
1746                  // Show the setup dialog...                  // Show the setup dialog...
# Line 1574  void MainForm::viewOptions (void) Line 1749  void MainForm::viewOptions (void)
1749                          if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||                          if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1750                                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||                                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||
1751                                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||                                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1752                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)) {                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)     ||
1753                                    (iOldBaseFontSize   !=  m_pOptions->iBaseFontSize)) {
1754                                  QMessageBox::information(this,                                  QMessageBox::information(this,
1755                                          QSAMPLER_TITLE ": " + tr("Information"),                                          QSAMPLER_TITLE ": " + tr("Information"),
1756                                          tr("Some settings may be only effective\n"                                          tr("Some settings may be only effective\n"
1757                                          "next time you start this program."), tr("OK"));                                          "next time you start this program."));
1758                                  updateMessagesCapture();                                  updateMessagesCapture();
1759                          }                          }
1760                          // Check wheather something immediate has changed.                          // Check wheather something immediate has changed.
1761                            if (( bOldMessagesLog && !m_pOptions->bMessagesLog) ||
1762                                    (!bOldMessagesLog &&  m_pOptions->bMessagesLog) ||
1763                                    (sOldMessagesLogPath != m_pOptions->sMessagesLogPath))
1764                                    m_pMessages->setLogging(
1765                                            m_pOptions->bMessagesLog, m_pOptions->sMessagesLogPath);
1766                          if (( bOldCompletePath && !m_pOptions->bCompletePath) ||                          if (( bOldCompletePath && !m_pOptions->bCompletePath) ||
1767                                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||                                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||
1768                                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))                                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))
# Line 1628  void MainForm::viewOptions (void) Line 1809  void MainForm::viewOptions (void)
1809  void MainForm::channelsArrange (void)  void MainForm::channelsArrange (void)
1810  {  {
1811          // Full width vertical tiling          // Full width vertical tiling
1812          QWidgetList wlist = m_pWorkspace->windowList();          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
1813          if (wlist.isEmpty())          if (wlist.isEmpty())
1814                  return;                  return;
1815    
1816          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1817          int y = 0;          int y = 0;
1818          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {
1819                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  ChannelStrip *pChannelStrip = NULL;
1820          /*  if (pChannelStrip->testWState(WState_Maximized | WState_Minimized)) {                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);
1821                          // Prevent flicker...                  if (pMdiSubWindow)
1822                          pChannelStrip->hide();                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
1823                          pChannelStrip->showNormal();                  if (pChannelStrip) {
1824                  }   */                  /*  if (pChannelStrip->testWState(WState_Maximized | WState_Minimized)) {
1825                  pChannelStrip->adjustSize();                                  // Prevent flicker...
1826                  int iWidth  = m_pWorkspace->width();                                  pChannelStrip->hide();
1827                  if (iWidth < pChannelStrip->width())                                  pChannelStrip->showNormal();
1828                          iWidth = pChannelStrip->width();                          }   */
1829          //  int iHeight = pChannelStrip->height()                          pChannelStrip->adjustSize();
1830          //              + pChannelStrip->parentWidget()->baseSize().height();                          int iWidth  = m_pWorkspace->width();
1831                  int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();                          if (iWidth < pChannelStrip->width())
1832                  pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);                                  iWidth = pChannelStrip->width();
1833                  y += iHeight;                  //  int iHeight = pChannelStrip->height()
1834                    //              + pChannelStrip->parentWidget()->baseSize().height();
1835                            int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
1836                            pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
1837                            y += iHeight;
1838                    }
1839          }          }
1840          m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
1841    
# Line 1736  void MainForm::helpAbout (void) Line 1922  void MainForm::helpAbout (void)
1922          sText += tr("Instrument editing support disabled.");          sText += tr("Instrument editing support disabled.");
1923          sText += "</font></small><br />";          sText += "</font></small><br />";
1924  #endif  #endif
1925    #ifndef CONFIG_EVENT_CHANNEL_MIDI
1926            sText += "<small><font color=\"red\">";
1927            sText += tr("Channel MIDI event support disabled.");
1928            sText += "</font></small><br />";
1929    #endif
1930    #ifndef CONFIG_EVENT_DEVICE_MIDI
1931            sText += "<small><font color=\"red\">";
1932            sText += tr("Device MIDI event support disabled.");
1933            sText += "</font></small><br />";
1934    #endif
1935    #ifndef CONFIG_MAX_VOICES
1936            sText += "<small><font color=\"red\">";
1937            sText += tr("Runtime max. voices / disk streams support disabled.");
1938            sText += "</font></small><br />";
1939    #endif
1940          sText += "<br />\n";          sText += "<br />\n";
1941          sText += tr("Using") + ": ";          sText += tr("Using") + ": ";
1942          sText += ::lscp_client_package();          sText += ::lscp_client_package();
# Line 1776  void MainForm::stabilizeForm (void) Line 1977  void MainForm::stabilizeForm (void)
1977          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));
1978    
1979          // Update the main menu state...          // Update the main menu state...
1980          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1981          bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);          bool bHasClient = (m_pOptions != NULL && m_pClient != NULL);
1982          bool bHasChannel = (bHasClient && pChannelStrip != NULL);          bool bHasChannel = (bHasClient && pChannelStrip != NULL);
1983            bool bHasChannels = (bHasClient && m_pWorkspace->subWindowList().count() > 0);
1984          m_ui.fileNewAction->setEnabled(bHasClient);          m_ui.fileNewAction->setEnabled(bHasClient);
1985          m_ui.fileOpenAction->setEnabled(bHasClient);          m_ui.fileOpenAction->setEnabled(bHasClient);
1986          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
# Line 1794  void MainForm::stabilizeForm (void) Line 1996  void MainForm::stabilizeForm (void)
1996          m_ui.editEditChannelAction->setEnabled(false);          m_ui.editEditChannelAction->setEnabled(false);
1997  #endif  #endif
1998          m_ui.editResetChannelAction->setEnabled(bHasChannel);          m_ui.editResetChannelAction->setEnabled(bHasChannel);
1999          m_ui.editResetAllChannelsAction->setEnabled(bHasChannel);          m_ui.editResetAllChannelsAction->setEnabled(bHasChannels);
2000          m_ui.viewMessagesAction->setChecked(m_pMessages && m_pMessages->isVisible());          m_ui.viewMessagesAction->setChecked(m_pMessages && m_pMessages->isVisible());
2001  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
2002          m_ui.viewInstrumentsAction->setChecked(m_pInstrumentListForm          m_ui.viewInstrumentsAction->setChecked(m_pInstrumentListForm
# Line 1806  void MainForm::stabilizeForm (void) Line 2008  void MainForm::stabilizeForm (void)
2008          m_ui.viewDevicesAction->setChecked(m_pDeviceForm          m_ui.viewDevicesAction->setChecked(m_pDeviceForm
2009                  && m_pDeviceForm->isVisible());                  && m_pDeviceForm->isVisible());
2010          m_ui.viewDevicesAction->setEnabled(bHasClient);          m_ui.viewDevicesAction->setEnabled(bHasClient);
2011          m_ui.channelsArrangeAction->setEnabled(bHasChannel);          m_ui.viewMidiDeviceStatusMenu->setEnabled(
2012                    DeviceStatusForm::getInstances().size() > 0);
2013            m_ui.channelsArrangeAction->setEnabled(bHasChannels);
2014    
2015  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
2016          // Toolbar widgets are also affected...          // Toolbar widgets are also affected...
# Line 1872  void MainForm::volumeChanged ( int iVolu Line 2076  void MainForm::volumeChanged ( int iVolu
2076    
2077    
2078  // Channel change receiver slot.  // Channel change receiver slot.
2079  void MainForm::channelStripChanged(ChannelStrip* pChannelStrip)  void MainForm::channelStripChanged ( ChannelStrip *pChannelStrip )
2080  {  {
2081          // Add this strip to the changed list...          // Add this strip to the changed list...
2082          if (!m_changedStrips.contains(pChannelStrip)) {          if (!m_changedStrips.contains(pChannelStrip)) {
# Line 1910  void MainForm::updateSession (void) Line 2114  void MainForm::updateSession (void)
2114          }          }
2115  #endif  #endif
2116    
2117            updateAllChannelStrips(false);
2118    
2119            // Do we auto-arrange?
2120            if (m_pOptions && m_pOptions->bAutoArrange)
2121                    channelsArrange();
2122    
2123            // Remember to refresh devices and instruments...
2124            if (m_pInstrumentListForm)
2125                    m_pInstrumentListForm->refreshInstruments();
2126            if (m_pDeviceForm)
2127                    m_pDeviceForm->refreshDevices();
2128    }
2129    
2130    
2131    void MainForm::updateAllChannelStrips ( bool bRemoveDeadStrips )
2132    {
2133          // Retrieve the current channel list.          // Retrieve the current channel list.
2134          int *piChannelIDs = ::lscp_list_channels(m_pClient);          int *piChannelIDs = ::lscp_list_channels(m_pClient);
2135          if (piChannelIDs == NULL) {          if (piChannelIDs == NULL) {
# Line 1921  void MainForm::updateSession (void) Line 2141  void MainForm::updateSession (void)
2141          } else {          } else {
2142                  // Try to (re)create each channel.                  // Try to (re)create each channel.
2143                  m_pWorkspace->setUpdatesEnabled(false);                  m_pWorkspace->setUpdatesEnabled(false);
2144                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {
2145                          // Check if theres already a channel strip for this one...                          // Check if theres already a channel strip for this one...
2146                          if (!channelStrip(piChannelIDs[iChannel]))                          if (!channelStrip(piChannelIDs[iChannel]))
2147                                  createChannelStrip(new qsamplerChannel(piChannelIDs[iChannel]));                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));
2148                    }
2149                    // Do we auto-arrange?
2150                    if (m_pOptions && m_pOptions->bAutoArrange)
2151                            channelsArrange();
2152                    // remove dead channel strips
2153                    if (bRemoveDeadStrips) {
2154                            QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
2155                            for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {
2156                                    ChannelStrip *pChannelStrip = NULL;
2157                                    QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);
2158                                    if (pMdiSubWindow)
2159                                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2160                                    if (pChannelStrip) {
2161                                            bool bExists = false;
2162                                            for (int j = 0; piChannelIDs[j] >= 0; ++j) {
2163                                                    if (!pChannelStrip->channel())
2164                                                            break;
2165                                                    if (piChannelIDs[j] == pChannelStrip->channel()->channelID()) {
2166                                                            // strip exists, don't touch it
2167                                                            bExists = true;
2168                                                            break;
2169                                                    }
2170                                            }
2171                                            if (!bExists)
2172                                                    destroyChannelStrip(pChannelStrip);
2173                                    }
2174                            }
2175                  }                  }
2176                  m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
2177          }          }
2178    
2179          // Do we auto-arrange?          stabilizeForm();
         if (m_pOptions && m_pOptions->bAutoArrange)  
                 channelsArrange();  
   
         // Remember to refresh devices and instruments...  
         if (m_pInstrumentListForm)  
                 m_pInstrumentListForm->refreshInstruments();  
         if (m_pDeviceForm)  
                 m_pDeviceForm->refreshDevices();  
2180  }  }
2181    
2182    
# Line 1987  void MainForm::updateRecentFilesMenu (vo Line 2226  void MainForm::updateRecentFilesMenu (vo
2226  void MainForm::updateInstrumentNames (void)  void MainForm::updateInstrumentNames (void)
2227  {  {
2228          // Full channel list update...          // Full channel list update...
2229          QWidgetList wlist = m_pWorkspace->windowList();          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
2230          if (wlist.isEmpty())          if (wlist.isEmpty())
2231                  return;                  return;
2232    
2233          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2234          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {
2235                  ChannelStrip *pChannelStrip = (ChannelStrip *) wlist.at(iChannel);                  ChannelStrip *pChannelStrip = (ChannelStrip *) wlist.at(iChannel);
2236                  if (pChannelStrip)                  if (pChannelStrip)
2237                          pChannelStrip->updateInstrumentName(true);                          pChannelStrip->updateInstrumentName(true);
# Line 2016  void MainForm::updateDisplayFont (void) Line 2255  void MainForm::updateDisplayFont (void)
2255                  return;                  return;
2256    
2257          // Full channel list update...          // Full channel list update...
2258          QWidgetList wlist = m_pWorkspace->windowList();          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
2259          if (wlist.isEmpty())          if (wlist.isEmpty())
2260                  return;                  return;
2261    
2262          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2263          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {
2264                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  ChannelStrip *pChannelStrip = NULL;
2265                    QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);
2266                    if (pMdiSubWindow)
2267                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2268                  if (pChannelStrip)                  if (pChannelStrip)
2269                          pChannelStrip->setDisplayFont(font);                          pChannelStrip->setDisplayFont(font);
2270          }          }
# Line 2034  void MainForm::updateDisplayFont (void) Line 2276  void MainForm::updateDisplayFont (void)
2276  void MainForm::updateDisplayEffect (void)  void MainForm::updateDisplayEffect (void)
2277  {  {
2278          // Full channel list update...          // Full channel list update...
2279          QWidgetList wlist = m_pWorkspace->windowList();          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
2280          if (wlist.isEmpty())          if (wlist.isEmpty())
2281                  return;                  return;
2282    
2283          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2284          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {
2285                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  ChannelStrip *pChannelStrip = NULL;
2286                    QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);
2287                    if (pMdiSubWindow)
2288                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2289                  if (pChannelStrip)                  if (pChannelStrip)
2290                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2291          }          }
# Line 2062  void MainForm::updateMaxVolume (void) Line 2307  void MainForm::updateMaxVolume (void)
2307  #endif  #endif
2308    
2309          // Full channel list update...          // Full channel list update...
2310          QWidgetList wlist = m_pWorkspace->windowList();          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
2311          if (wlist.isEmpty())          if (wlist.isEmpty())
2312                  return;                  return;
2313    
2314          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2315          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {
2316                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  ChannelStrip *pChannelStrip = NULL;
2317                    QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);
2318                    if (pMdiSubWindow)
2319                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2320                  if (pChannelStrip)                  if (pChannelStrip)
2321                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2322          }          }
# Line 2113  void MainForm::appendMessagesError( cons Line 2361  void MainForm::appendMessagesError( cons
2361          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2362    
2363          QMessageBox::critical(this,          QMessageBox::critical(this,
2364                  QSAMPLER_TITLE ": " + tr("Error"), s, tr("Cancel"));                  QSAMPLER_TITLE ": " + tr("Error"), s, QMessageBox::Cancel);
2365  }  }
2366    
2367    
# Line 2176  void MainForm::updateMessagesCapture (vo Line 2424  void MainForm::updateMessagesCapture (vo
2424  // qsamplerMainForm -- MDI channel strip management.  // qsamplerMainForm -- MDI channel strip management.
2425    
2426  // The channel strip creation executive.  // The channel strip creation executive.
2427  ChannelStrip* MainForm::createChannelStrip ( qsamplerChannel *pChannel )  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )
2428  {  {
2429          if (m_pClient == NULL || pChannel == NULL)          if (m_pClient == NULL || pChannel == NULL)
2430                  return NULL;                  return NULL;
# Line 2199  ChannelStrip* MainForm::createChannelStr Line 2447  ChannelStrip* MainForm::createChannelStr
2447          }          }
2448    
2449          // Add it to workspace...          // Add it to workspace...
2450          m_pWorkspace->addWindow(pChannelStrip, Qt::FramelessWindowHint);          m_pWorkspace->addSubWindow(pChannelStrip, Qt::FramelessWindowHint);
2451    
2452          // Actual channel strip setup...          // Actual channel strip setup...
2453          pChannelStrip->setup(pChannel);          pChannelStrip->setup(pChannel);
2454    
2455          QObject::connect(pChannelStrip,          QObject::connect(pChannelStrip,
2456                  SIGNAL(channelChanged(ChannelStrip*)),                  SIGNAL(channelChanged(ChannelStrip *)),
2457                  SLOT(channelStripChanged(ChannelStrip*)));                  SLOT(channelStripChanged(ChannelStrip *)));
2458    
2459          // Now we show up us to the world.          // Now we show up us to the world.
2460          pChannelStrip->show();          pChannelStrip->show();
# Line 2219  ChannelStrip* MainForm::createChannelStr Line 2467  ChannelStrip* MainForm::createChannelStr
2467  }  }
2468    
2469    
2470    void MainForm::destroyChannelStrip ( ChannelStrip *pChannelStrip )
2471    {
2472            // Just delete the channel strip.
2473            delete pChannelStrip;
2474    
2475            // Do we auto-arrange?
2476            if (m_pOptions && m_pOptions->bAutoArrange)
2477                    channelsArrange();
2478    
2479            stabilizeForm();
2480    }
2481    
2482    
2483  // Retrieve the active channel strip.  // Retrieve the active channel strip.
2484  ChannelStrip* MainForm::activeChannelStrip (void)  ChannelStrip *MainForm::activeChannelStrip (void)
2485  {  {
2486          return static_cast<ChannelStrip *> (m_pWorkspace->activeWindow());          QMdiSubWindow *pMdiSubWindow = m_pWorkspace->activeSubWindow();
2487            if (pMdiSubWindow)
2488                    return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2489            else
2490                    return NULL;
2491  }  }
2492    
2493    
2494  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2495  ChannelStrip* MainForm::channelStripAt ( int iChannel )  ChannelStrip *MainForm::channelStripAt ( int iChannel )
2496  {  {
2497          QWidgetList wlist = m_pWorkspace->windowList();          if (!m_pWorkspace) return NULL;
2498    
2499            QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
2500          if (wlist.isEmpty())          if (wlist.isEmpty())
2501                  return NULL;                  return NULL;
2502    
2503          return static_cast<ChannelStrip *> (wlist.at(iChannel));          if (iChannel < 0 || iChannel >= wlist.size())
2504                    return NULL;
2505    
2506            QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);
2507            if (pMdiSubWindow)
2508                    return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2509            else
2510                    return NULL;
2511  }  }
2512    
2513    
2514  // Retrieve a channel strip by sampler channel id.  // Retrieve a channel strip by sampler channel id.
2515  ChannelStrip* MainForm::channelStrip ( int iChannelID )  ChannelStrip *MainForm::channelStrip ( int iChannelID )
2516  {  {
2517          QWidgetList wlist = m_pWorkspace->windowList();          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
2518          if (wlist.isEmpty())          if (wlist.isEmpty())
2519                  return NULL;                  return NULL;
2520    
2521          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {
2522                  ChannelStrip* pChannelStrip                  ChannelStrip *pChannelStrip = NULL;
2523                          = static_cast<ChannelStrip*> (wlist.at(iChannel));                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);
2524                    if (pMdiSubWindow)
2525                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2526                  if (pChannelStrip) {                  if (pChannelStrip) {
2527                          qsamplerChannel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
2528                          if (pChannel && pChannel->channelID() == iChannelID)                          if (pChannel && pChannel->channelID() == iChannelID)
2529                                  return pChannelStrip;                                  return pChannelStrip;
2530                  }                  }
# Line 2266  void MainForm::channelsMenuAboutToShow ( Line 2542  void MainForm::channelsMenuAboutToShow (
2542          m_ui.channelsMenu->addAction(m_ui.channelsArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsArrangeAction);
2543          m_ui.channelsMenu->addAction(m_ui.channelsAutoArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsAutoArrangeAction);
2544    
2545          QWidgetList wlist = m_pWorkspace->windowList();          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
2546          if (!wlist.isEmpty()) {          if (!wlist.isEmpty()) {
2547                  m_ui.channelsMenu->addSeparator();                  m_ui.channelsMenu->addSeparator();
2548                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                  for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {
2549                          ChannelStrip* pChannelStrip                          ChannelStrip *pChannelStrip = NULL;
2550                                  = static_cast<ChannelStrip*> (wlist.at(iChannel));                          QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);
2551                            if (pMdiSubWindow)
2552                                    pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2553                          if (pChannelStrip) {                          if (pChannelStrip) {
2554                                  QAction *pAction = m_ui.channelsMenu->addAction(                                  QAction *pAction = m_ui.channelsMenu->addAction(
2555                                          pChannelStrip->windowTitle(),                                          pChannelStrip->windowTitle(),
# Line 2293  void MainForm::channelsMenuActivated (vo Line 2571  void MainForm::channelsMenuActivated (vo
2571          if (pAction == NULL)          if (pAction == NULL)
2572                  return;                  return;
2573    
2574          ChannelStrip* pChannelStrip = channelStripAt(pAction->data().toInt());          ChannelStrip *pChannelStrip = channelStripAt(pAction->data().toInt());
2575          if (pChannelStrip) {          if (pChannelStrip) {
2576                  pChannelStrip->showNormal();                  pChannelStrip->showNormal();
2577                  pChannelStrip->setFocus();                  pChannelStrip->setFocus();
# Line 2354  void MainForm::timerSlot (void) Line 2632  void MainForm::timerSlot (void)
2632                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {
2633                                  m_iTimerSlot = 0;                                  m_iTimerSlot = 0;
2634                                  // Update the channel stream usage for each strip...                                  // Update the channel stream usage for each strip...
2635                                  QWidgetList wlist = m_pWorkspace->windowList();                                  QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
2636                                  for (int iChannel = 0;                                  for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {
2637                                                  iChannel < (int) wlist.count(); iChannel++) {                                          ChannelStrip *pChannelStrip = NULL;
2638                                          ChannelStrip* pChannelStrip                                          QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);
2639                                                  = (ChannelStrip*) wlist.at(iChannel);                                          if (pMdiSubWindow)
2640                                                    pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2641                                          if (pChannelStrip && pChannelStrip->isVisible())                                          if (pChannelStrip && pChannelStrip->isVisible())
2642                                                  pChannelStrip->updateChannelUsage();                                                  pChannelStrip->updateChannelUsage();
2643                                  }                                  }
# Line 2386  void MainForm::startServer (void) Line 2665  void MainForm::startServer (void)
2665    
2666          // Is the server process instance still here?          // Is the server process instance still here?
2667          if (m_pServer) {          if (m_pServer) {
2668                  switch (QMessageBox::warning(this,                  if (QMessageBox::warning(this,
2669                          QSAMPLER_TITLE ": " + tr("Warning"),                          QSAMPLER_TITLE ": " + tr("Warning"),
2670                          tr("Could not start the LinuxSampler server.\n\n"                          tr("Could not start the LinuxSampler server.\n\n"
2671                          "Maybe it ss already started."),                          "Maybe it is already started."),
2672                          tr("Stop"), tr("Kill"), tr("Cancel"))) {                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
                 case 0:  
2673                          m_pServer->terminate();                          m_pServer->terminate();
                         break;  
                 case 1:  
2674                          m_pServer->kill();                          m_pServer->kill();
                         break;  
2675                  }                  }
2676                  return;                  return;
2677          }          }
# Line 2409  void MainForm::startServer (void) Line 2684  void MainForm::startServer (void)
2684                  return;                  return;
2685    
2686          // OK. Let's build the startup process...          // OK. Let's build the startup process...
2687          m_pServer = new QProcess(this);          m_pServer = new QProcess();
2688            bForceServerStop = true;
2689    
2690          // Setup stdout/stderr capture...          // Setup stdout/stderr capture...
2691  //      if (m_pOptions->bStdoutCapture) {  //      if (m_pOptions->bStdoutCapture) {
2692                  //m_pServer->setProcessChannelMode(  #if QT_VERSION >= 0x040200
2693                  //      QProcess::StandardOutput);                  m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);
2694    #endif
2695                  QObject::connect(m_pServer,                  QObject::connect(m_pServer,
2696                          SIGNAL(readyReadStandardOutput()),                          SIGNAL(readyReadStandardOutput()),
2697                          SLOT(readServerStdout()));                          SLOT(readServerStdout()));
# Line 2425  void MainForm::startServer (void) Line 2702  void MainForm::startServer (void)
2702    
2703          // The unforgiveable signal communication...          // The unforgiveable signal communication...
2704          QObject::connect(m_pServer,          QObject::connect(m_pServer,
2705                  SIGNAL(finished(int,QProcess::ExitStatus)),                  SIGNAL(finished(int, QProcess::ExitStatus)),
2706                  SLOT(processServerExit()));                  SLOT(processServerExit()));
2707    
2708          // Build process arguments...          // Build process arguments...
# Line 2456  void MainForm::startServer (void) Line 2733  void MainForm::startServer (void)
2733    
2734    
2735  // Stop linuxsampler server...  // Stop linuxsampler server...
2736  void MainForm::stopServer (void)  void MainForm::stopServer (bool bInteractive)
2737  {  {
2738          // Stop client code.          // Stop client code.
2739          stopClient();          stopClient();
2740    
2741            if (m_pServer && bInteractive) {
2742                    if (QMessageBox::question(this,
2743                            QSAMPLER_TITLE ": " + tr("The backend's fate ..."),
2744                            tr("You have the option to keep the sampler backend (LinuxSampler)\n"
2745                            "running in the background. The sampler would continue to work\n"
2746                            "according to your current sampler session and you could alter the\n"
2747                            "sampler session at any time by relaunching QSampler.\n\n"
2748                            "Do you want LinuxSampler to stop?"),
2749                            QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
2750                    {
2751                            bForceServerStop = false;
2752                    }
2753            }
2754    
2755          // And try to stop server.          // And try to stop server.
2756          if (m_pServer) {          if (m_pServer && bForceServerStop) {
2757                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2758                  if (m_pServer->state() == QProcess::Running)                  if (m_pServer->state() == QProcess::Running) {
2759    #if defined(WIN32)
2760                            // Try harder...
2761                            m_pServer->kill();
2762    #else
2763                            // Try softly...
2764                          m_pServer->terminate();                          m_pServer->terminate();
2765          }  #endif
2766                    }
2767            }       // Do final processing anyway.
2768            else processServerExit();
2769    
2770          // Give it some time to terminate gracefully and stabilize...          // Give it some time to terminate gracefully and stabilize...
2771          QTime t;          QTime t;
2772          t.start();          t.start();
2773          while (t.elapsed() < QSAMPLER_TIMER_MSECS)          while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2774                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
   
         // Do final processing anyway.  
         processServerExit();  
2775  }  }
2776    
2777    
# Line 2497  void MainForm::processServerExit (void) Line 2793  void MainForm::processServerExit (void)
2793          if (m_pMessages)          if (m_pMessages)
2794                  m_pMessages->flushStdoutBuffer();                  m_pMessages->flushStdoutBuffer();
2795    
2796          if (m_pServer) {          if (m_pServer && bForceServerStop) {
2797                    if (m_pServer->state() != QProcess::NotRunning) {
2798                            appendMessages(tr("Server is being forced..."));
2799                            // Force final server shutdown...
2800                            m_pServer->kill();
2801                            // Give it some time to terminate gracefully and stabilize...
2802                            QTime t;
2803                            t.start();
2804                            while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2805                                    QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2806                    }
2807                  // Force final server shutdown...                  // Force final server shutdown...
2808                  appendMessages(                  appendMessages(
2809                          tr("Server was stopped with exit status %1.")                          tr("Server was stopped with exit status %1.")
2810                          .arg(m_pServer->exitStatus()));                          .arg(m_pServer->exitStatus()));
                 m_pServer->terminate();  
                 if (!m_pServer->waitForFinished(2000))  
                         m_pServer->kill();  
                 // Destroy it.  
2811                  delete m_pServer;                  delete m_pServer;
2812                  m_pServer = NULL;                  m_pServer = NULL;
2813          }          }
# Line 2530  lscp_status_t qsampler_client_callback ( Line 2832  lscp_status_t qsampler_client_callback (
2832          // as this is run under some other thread context.          // as this is run under some other thread context.
2833          // A custom event must be posted here...          // A custom event must be posted here...
2834          QApplication::postEvent(pMainForm,          QApplication::postEvent(pMainForm,
2835                  new qsamplerCustomEvent(event, pchData, cchData));                  new LscpEvent(event, pchData, cchData));
2836    
2837          return LSCP_OK;          return LSCP_OK;
2838  }  }
# Line 2575  bool MainForm::startClient (void) Line 2877  bool MainForm::startClient (void)
2877                  .arg(::lscp_client_get_timeout(m_pClient)));                  .arg(::lscp_client_get_timeout(m_pClient)));
2878    
2879          // Subscribe to channel info change notifications...          // Subscribe to channel info change notifications...
2880            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT) != LSCP_OK)
2881                    appendMessagesClient("lscp_client_subscribe(CHANNEL_COUNT)");
2882          if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)          if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)
2883                  appendMessagesClient("lscp_client_subscribe");                  appendMessagesClient("lscp_client_subscribe(CHANNEL_INFO)");
2884    
2885            DeviceStatusForm::onDevicesChanged(); // initialize
2886            updateViewMidiDeviceStatusMenu();
2887            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT) != LSCP_OK)
2888                    appendMessagesClient("lscp_client_subscribe(MIDI_INPUT_DEVICE_COUNT)");
2889            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO) != LSCP_OK)
2890                    appendMessagesClient("lscp_client_subscribe(MIDI_INPUT_DEVICE_INFO)");
2891            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT) != LSCP_OK)
2892                    appendMessagesClient("lscp_client_subscribe(AUDIO_OUTPUT_DEVICE_COUNT)");
2893            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO) != LSCP_OK)
2894                    appendMessagesClient("lscp_client_subscribe(AUDIO_OUTPUT_DEVICE_INFO)");
2895    
2896    #if CONFIG_EVENT_CHANNEL_MIDI
2897            // Subscribe to channel MIDI data notifications...
2898            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_MIDI) != LSCP_OK)
2899                    appendMessagesClient("lscp_client_subscribe(CHANNEL_MIDI)");
2900    #endif
2901    
2902    #if CONFIG_EVENT_DEVICE_MIDI
2903            // Subscribe to channel MIDI data notifications...
2904            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_DEVICE_MIDI) != LSCP_OK)
2905                    appendMessagesClient("lscp_client_subscribe(DEVICE_MIDI)");
2906    #endif
2907    
2908          // We may stop scheduling around.          // We may stop scheduling around.
2909          stopSchedule();          stopSchedule();
# Line 2603  bool MainForm::startClient (void) Line 2930  bool MainForm::startClient (void)
2930                  }                  }
2931          }          }
2932    
2933            // send the current / loaded fine tuning settings to the sampler
2934            m_pOptions->sendFineTuningSettings();
2935    
2936          // Make a new session          // Make a new session
2937          return newSession();          return newSession();
2938  }  }
# Line 2630  void MainForm::stopClient (void) Line 2960  void MainForm::stopClient (void)
2960          closeSession(false);          closeSession(false);
2961    
2962          // Close us as a client...          // Close us as a client...
2963    #if CONFIG_EVENT_DEVICE_MIDI
2964            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_DEVICE_MIDI);
2965    #endif
2966    #if CONFIG_EVENT_CHANNEL_MIDI
2967            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_MIDI);
2968    #endif
2969            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO);
2970            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT);
2971            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO);
2972            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT);
2973          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
2974            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);
2975          ::lscp_client_destroy(m_pClient);          ::lscp_client_destroy(m_pClient);
2976          m_pClient = NULL;          m_pClient = NULL;
2977    
# Line 2650  void MainForm::stopClient (void) Line 2991  void MainForm::stopClient (void)
2991    
2992    
2993  // Channel strip activation/selection.  // Channel strip activation/selection.
2994  void MainForm::activateStrip ( QWidget *pWidget )  void MainForm::activateStrip ( QMdiSubWindow *pMdiSubWindow )
2995  {  {
2996          ChannelStrip *pChannelStrip          ChannelStrip *pChannelStrip = NULL;
2997                  = static_cast<ChannelStrip *> (pWidget);          if (pMdiSubWindow)
2998                    pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2999          if (pChannelStrip)          if (pChannelStrip)
3000                  pChannelStrip->setSelected(true);                  pChannelStrip->setSelected(true);
3001    

Legend:
Removed from v.1515  
changed lines
  Added in v.2387

  ViewVC Help
Powered by ViewVC