/[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 2038 by capela, Thu Jan 7 18:42:26 2010 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-2010, 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 <QApplication>  #include <QApplication>
39  #include <QWorkspace>  #include <QWorkspace>
# Line 55  Line 56 
56  #include <QTimer>  #include <QTimer>
57  #include <QDateTime>  #include <QDateTime>
58    
59    #if QT_VERSION < 0x040500
60    namespace Qt {
61    const WindowFlags WindowCloseButtonHint = WindowFlags(0x08000000);
62    #if QT_VERSION < 0x040200
63    const WindowFlags CustomizeWindowHint   = WindowFlags(0x02000000);
64    #endif
65    }
66    #endif
67    
68  #ifdef HAVE_SIGNAL_H  #ifdef HAVE_SIGNAL_H
69  #include <signal.h>  #include <signal.h>
# Line 77  static inline long lroundf ( float x ) Line 86  static inline long lroundf ( float x )
86  }  }
87  #endif  #endif
88    
89    
90    // All winsock apps needs this.
91    #if defined(WIN32)
92    static WSADATA _wsaData;
93    #endif
94    
95    
96    namespace QSampler {
97    
98  // Timer constant stuff.  // Timer constant stuff.
99  #define QSAMPLER_TIMER_MSECS    200  #define QSAMPLER_TIMER_MSECS    200
100    
# Line 87  static inline long lroundf ( float x ) Line 105  static inline long lroundf ( float x )
105  #define QSAMPLER_STATUS_SESSION 3       // Current session modification state.  #define QSAMPLER_STATUS_SESSION 3       // Current session modification state.
106    
107    
 // All winsock apps needs this.  
 #if defined(WIN32)  
 static WSADATA _wsaData;  
 #endif  
   
   
108  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
109  // qsamplerCustomEvent -- specialty for callback comunication.  // CustomEvent -- specialty for callback comunication.
110    
111  #define QSAMPLER_CUSTOM_EVENT   QEvent::Type(QEvent::User + 0)  #define QSAMPLER_CUSTOM_EVENT   QEvent::Type(QEvent::User + 0)
112    
113  class qsamplerCustomEvent : public QEvent  class CustomEvent : public QEvent
114  {  {
115  public:  public:
116    
117          // Constructor.          // Constructor.
118          qsamplerCustomEvent(lscp_event_t event, const char *pchData, int cchData)          CustomEvent(lscp_event_t event, const char *pchData, int cchData)
119                  : QEvent(QSAMPLER_CUSTOM_EVENT)                  : QEvent(QSAMPLER_CUSTOM_EVENT)
120          {          {
121                  m_event = event;                  m_event = event;
# Line 126  private: Line 138  private:
138  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
139  // qsamplerMainForm -- Main window form implementation.  // qsamplerMainForm -- Main window form implementation.
140    
 namespace QSampler {  
   
141  // Kind of singleton reference.  // Kind of singleton reference.
142  MainForm* MainForm::g_pMainForm = NULL;  MainForm* MainForm::g_pMainForm = NULL;
143    
# Line 366  MainForm::~MainForm() Line 376  MainForm::~MainForm()
376    
377    
378  // Make and set a proper setup options step.  // Make and set a proper setup options step.
379  void MainForm::setup ( qsamplerOptions *pOptions )  void MainForm::setup ( Options *pOptions )
380  {  {
381          // We got options?          // We got options?
382          m_pOptions = pOptions;          m_pOptions = pOptions;
383    
384          // What style do we create these forms?          // What style do we create these forms?
385          Qt::WindowFlags wflags = Qt::Window          Qt::WindowFlags wflags = Qt::Window
 #if QT_VERSION >= 0x040200  
386                  | Qt::CustomizeWindowHint                  | Qt::CustomizeWindowHint
 #endif  
387                  | Qt::WindowTitleHint                  | Qt::WindowTitleHint
388                  | Qt::WindowSystemMenuHint                  | Qt::WindowSystemMenuHint
389                  | Qt::WindowMinMaxButtonsHint;                  | Qt::WindowMinMaxButtonsHint
390                    | Qt::WindowCloseButtonHint;
391          if (m_pOptions->bKeepOnTop)          if (m_pOptions->bKeepOnTop)
392                  wflags |= Qt::Tool;                  wflags |= Qt::Tool;
393    
394          // Some child forms are to be created right now.          // Some child forms are to be created right now.
395          m_pMessages = new qsamplerMessages(this);          m_pMessages = new Messages(this);
396          m_pDeviceForm = new DeviceForm(this, wflags);          m_pDeviceForm = new DeviceForm(this, wflags);
397  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
398          m_pInstrumentListForm = new InstrumentListForm(this, wflags);          m_pInstrumentListForm = new InstrumentListForm(this, wflags);
399  #else  #else
400          viewInstrumentsAction->setEnabled(false);          m_ui.viewInstrumentsAction->setEnabled(false);
401  #endif  #endif
402    
403            // Setup messages logging appropriately...
404            m_pMessages->setLogging(
405                    m_pOptions->bMessagesLog,
406                    m_pOptions->sMessagesLogPath);
407    
408          // Set message defaults...          // Set message defaults...
409          updateMessagesFont();          updateMessagesFont();
410          updateMessagesLimit();          updateMessagesLimit();
# Line 470  bool MainForm::queryClose (void) Line 486  bool MainForm::queryClose (void)
486                          if (m_pDeviceForm)                          if (m_pDeviceForm)
487                                  m_pDeviceForm->close();                                  m_pDeviceForm->close();
488                          // Stop client and/or server, gracefully.                          // Stop client and/or server, gracefully.
489                          stopServer();                          stopServer(true /*interactive*/);
490                  }                  }
491          }          }
492    
# Line 480  bool MainForm::queryClose (void) Line 496  bool MainForm::queryClose (void)
496    
497  void MainForm::closeEvent ( QCloseEvent *pCloseEvent )  void MainForm::closeEvent ( QCloseEvent *pCloseEvent )
498  {  {
499          if (queryClose())          if (queryClose()) {
500                    DeviceStatusForm::deleteAllInstances();
501                  pCloseEvent->accept();                  pCloseEvent->accept();
502          else          } else
503                  pCloseEvent->ignore();                  pCloseEvent->ignore();
504  }  }
505    
# Line 511  void MainForm::dropEvent ( QDropEvent* p Line 528  void MainForm::dropEvent ( QDropEvent* p
528                  QListIterator<QUrl> iter(pMimeData->urls());                  QListIterator<QUrl> iter(pMimeData->urls());
529                  while (iter.hasNext()) {                  while (iter.hasNext()) {
530                          const QString& sPath = iter.next().toLocalFile();                          const QString& sPath = iter.next().toLocalFile();
531                          if (qsamplerChannel::isInstrumentFile(sPath)) {                          if (Channel::isInstrumentFile(sPath)) {
532                                  // Try to create a new channel from instrument file...                                  // Try to create a new channel from instrument file...
533                                  qsamplerChannel *pChannel = new qsamplerChannel();                                  Channel *pChannel = new Channel();
534                                  if (pChannel == NULL)                                  if (pChannel == NULL)
535                                          return;                                          return;
536                                  // Start setting the instrument filename...                                  // Start setting the instrument filename...
# Line 549  void MainForm::customEvent(QEvent* pCust Line 566  void MainForm::customEvent(QEvent* pCust
566  {  {
567          // For the time being, just pump it to messages.          // For the time being, just pump it to messages.
568          if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {          if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {
569                  qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;                  CustomEvent *pEvent = static_cast<CustomEvent *> (pCustomEvent);
570                  if (pEvent->event() == LSCP_EVENT_CHANNEL_INFO) {                  switch (pEvent->event()) {
571                          int iChannelID = pEvent->data().toInt();                          case LSCP_EVENT_CHANNEL_COUNT:
572                          ChannelStrip *pChannelStrip = channelStrip(iChannelID);                                  updateAllChannelStrips(true);
573                          if (pChannelStrip)                                  break;
574                                  channelStripChanged(pChannelStrip);                          case LSCP_EVENT_CHANNEL_INFO: {
575                  } else {                                  int iChannelID = pEvent->data().toInt();
576                          appendMessagesColor(tr("Notify event: %1 data: %2")                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);
577                                  .arg(::lscp_event_to_text(pEvent->event()))                                  if (pChannelStrip)
578                                  .arg(pEvent->data()), "#996699");                                          channelStripChanged(pChannelStrip);
579                                    break;
580                            }
581                            case LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT:
582                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
583                                    DeviceStatusForm::onDevicesChanged();
584                                    updateViewMidiDeviceStatusMenu();
585                                    break;
586                            case LSCP_EVENT_MIDI_INPUT_DEVICE_INFO: {
587                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
588                                    const int iDeviceID = pEvent->data().section(' ', 0, 0).toInt();
589                                    DeviceStatusForm::onDeviceChanged(iDeviceID);
590                                    break;
591                            }
592                            case LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT:
593                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
594                                    break;
595                            case LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO:
596                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
597                                    break;
598                    #if CONFIG_EVENT_CHANNEL_MIDI
599                            case LSCP_EVENT_CHANNEL_MIDI: {
600                                    const int iChannelID = pEvent->data().section(' ', 0, 0).toInt();
601                                    ChannelStrip *pChannelStrip = channelStrip(iChannelID);
602                                    if (pChannelStrip)
603                                            pChannelStrip->midiActivityLedOn();
604                                    break;
605                            }
606                    #endif
607                    #if CONFIG_EVENT_DEVICE_MIDI
608                            case LSCP_EVENT_DEVICE_MIDI: {
609                                    const int iDeviceID = pEvent->data().section(' ', 0, 0).toInt();
610                                    const int iPortID   = pEvent->data().section(' ', 1, 1).toInt();
611                                    DeviceStatusForm *pDeviceStatusForm
612                                            = DeviceStatusForm::getInstance(iDeviceID);
613                                    if (pDeviceStatusForm)
614                                            pDeviceStatusForm->midiArrived(iPortID);
615                                    break;
616                            }
617                    #endif
618                            default:
619                                    appendMessagesColor(tr("Notify event: %1 data: %2")
620                                            .arg(::lscp_event_to_text(pEvent->event()))
621                                            .arg(pEvent->data()), "#996699");
622                  }                  }
623          }          }
624  }  }
625    
626    
627    void MainForm::updateViewMidiDeviceStatusMenu (void)
628    {
629            m_ui.viewMidiDeviceStatusMenu->clear();
630            const std::map<int, DeviceStatusForm *> statusForms
631                    = DeviceStatusForm::getInstances();
632            std::map<int, DeviceStatusForm *>::const_iterator iter
633                    = statusForms.begin();
634            for ( ; iter != statusForms.end(); ++iter) {
635                    DeviceStatusForm *pStatusForm = iter->second;
636                    m_ui.viewMidiDeviceStatusMenu->addAction(
637                            pStatusForm->visibleAction());
638            }
639    }
640    
641    
642  // Context menu event handler.  // Context menu event handler.
643  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )
644  {  {
# Line 576  void MainForm::contextMenuEvent( QContex Line 652  void MainForm::contextMenuEvent( QContex
652  // qsamplerMainForm -- Brainless public property accessors.  // qsamplerMainForm -- Brainless public property accessors.
653    
654  // The global options settings property.  // The global options settings property.
655  qsamplerOptions *MainForm::options (void) const  Options *MainForm::options (void) const
656  {  {
657          return m_pOptions;          return m_pOptions;
658  }  }
# Line 694  bool MainForm::saveSession ( bool bPromp Line 770  bool MainForm::saveSession ( bool bPromp
770                                  "\"%1\"\n\n"                                  "\"%1\"\n\n"
771                                  "Do you want to replace it?")                                  "Do you want to replace it?")
772                                  .arg(sFilename),                                  .arg(sFilename),
773                                  tr("Replace"), tr("Cancel")) > 0)                                  QMessageBox::Yes | QMessageBox::No)
774                                    == QMessageBox::No)
775                                  return false;                                  return false;
776                  }                  }
777          }          }
# Line 717  bool MainForm::closeSession ( bool bForc Line 794  bool MainForm::closeSession ( bool bForc
794                          "\"%1\"\n\n"                          "\"%1\"\n\n"
795                          "Do you want to save the changes?")                          "Do you want to save the changes?")
796                          .arg(sessionName(m_sFilename)),                          .arg(sessionName(m_sFilename)),
797                          tr("Save"), tr("Discard"), tr("Cancel"))) {                          QMessageBox::Save |
798                  case 0:     // Save...                          QMessageBox::Discard |
799                            QMessageBox::Cancel)) {
800                    case QMessageBox::Save:
801                          bClose = saveSession(false);                          bClose = saveSession(false);
802                          // Fall thru....                          // Fall thru....
803                  case 1:     // Discard                  case QMessageBox::Discard:
804                          break;                          break;
805                  default:    // Cancel.                  default:    // Cancel.
806                          bClose = false;                          bClose = false;
# Line 737  bool MainForm::closeSession ( bool bForc Line 816  bool MainForm::closeSession ( bool bForc
816                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
817                          ChannelStrip *pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                          ChannelStrip *pChannelStrip = (ChannelStrip*) wlist.at(iChannel);
818                          if (pChannelStrip) {                          if (pChannelStrip) {
819                                  qsamplerChannel *pChannel = pChannelStrip->channel();                                  Channel *pChannel = pChannelStrip->channel();
820                                  if (bForce && pChannel)                                  if (bForce && pChannel)
821                                          pChannel->removeChannel();                                          pChannel->removeChannel();
822                                  delete pChannelStrip;                                  delete pChannelStrip;
# Line 877  bool MainForm::saveSessionFile ( const Q Line 956  bool MainForm::saveSessionFile ( const Q
956    
957          // Audio device mapping.          // Audio device mapping.
958          QMap<int, int> audioDeviceMap;          QMap<int, int> audioDeviceMap;
959          piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Audio);          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);
960          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
961                  ts << endl;                  ts << endl;
962                  qsamplerDevice device(qsamplerDevice::Audio, piDeviceIDs[iDevice]);                  Device device(Device::Audio, piDeviceIDs[iDevice]);
963                  // Audio device specification...                  // Audio device specification...
964                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
965                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
966                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
967                  qsamplerDeviceParamMap::ConstIterator deviceParam;                  DeviceParamMap::ConstIterator deviceParam;
968                  for (deviceParam = device.params().begin();                  for (deviceParam = device.params().begin();
969                                  deviceParam != device.params().end();                                  deviceParam != device.params().end();
970                                          ++deviceParam) {                                          ++deviceParam) {
971                          const qsamplerDeviceParam& param = deviceParam.value();                          const DeviceParam& param = deviceParam.value();
972                          if (param.value.isEmpty()) ts << "# ";                          if (param.value.isEmpty()) ts << "# ";
973                          ts << " " << deviceParam.key() << "='" << param.value << "'";                          ts << " " << deviceParam.key() << "='" << param.value << "'";
974                  }                  }
975                  ts << endl;                  ts << endl;
976                  // Audio channel parameters...                  // Audio channel parameters...
977                  int iPort = 0;                  int iPort = 0;
978                  QListIterator<qsamplerDevicePort *> iter(device.ports());                  QListIterator<DevicePort *> iter(device.ports());
979                  while (iter.hasNext()) {                  while (iter.hasNext()) {
980                          qsamplerDevicePort *pPort = iter.next();                          DevicePort *pPort = iter.next();
981                          qsamplerDeviceParamMap::ConstIterator portParam;                          DeviceParamMap::ConstIterator portParam;
982                          for (portParam = pPort->params().begin();                          for (portParam = pPort->params().begin();
983                                          portParam != pPort->params().end();                                          portParam != pPort->params().end();
984                                                  ++portParam) {                                                  ++portParam) {
985                                  const qsamplerDeviceParam& param = portParam.value();                                  const DeviceParam& param = portParam.value();
986                                  if (param.fix || param.value.isEmpty()) ts << "# ";                                  if (param.fix || param.value.isEmpty()) ts << "# ";
987                                  ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice                                  ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice
988                                          << " " << iPort << " " << portParam.key()                                          << " " << iPort << " " << portParam.key()
# Line 919  bool MainForm::saveSessionFile ( const Q Line 998  bool MainForm::saveSessionFile ( const Q
998    
999          // MIDI device mapping.          // MIDI device mapping.
1000          QMap<int, int> midiDeviceMap;          QMap<int, int> midiDeviceMap;
1001          piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Midi);          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);
1002          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
1003                  ts << endl;                  ts << endl;
1004                  qsamplerDevice device(qsamplerDevice::Midi, piDeviceIDs[iDevice]);                  Device device(Device::Midi, piDeviceIDs[iDevice]);
1005                  // MIDI device specification...                  // MIDI device specification...
1006                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1007                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1008                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
1009                  qsamplerDeviceParamMap::ConstIterator deviceParam;                  DeviceParamMap::ConstIterator deviceParam;
1010                  for (deviceParam = device.params().begin();                  for (deviceParam = device.params().begin();
1011                                  deviceParam != device.params().end();                                  deviceParam != device.params().end();
1012                                          ++deviceParam) {                                          ++deviceParam) {
1013                          const qsamplerDeviceParam& param = deviceParam.value();                          const DeviceParam& param = deviceParam.value();
1014                          if (param.value.isEmpty()) ts << "# ";                          if (param.value.isEmpty()) ts << "# ";
1015                          ts << " " << deviceParam.key() << "='" << param.value << "'";                          ts << " " << deviceParam.key() << "='" << param.value << "'";
1016                  }                  }
1017                  ts << endl;                  ts << endl;
1018                  // MIDI port parameters...                  // MIDI port parameters...
1019                  int iPort = 0;                  int iPort = 0;
1020                  QListIterator<qsamplerDevicePort *> iter(device.ports());                  QListIterator<DevicePort *> iter(device.ports());
1021                  while (iter.hasNext()) {                  while (iter.hasNext()) {
1022                          qsamplerDevicePort *pPort = iter.next();                          DevicePort *pPort = iter.next();
1023                          qsamplerDeviceParamMap::ConstIterator portParam;                          DeviceParamMap::ConstIterator portParam;
1024                          for (portParam = pPort->params().begin();                          for (portParam = pPort->params().begin();
1025                                          portParam != pPort->params().end();                                          portParam != pPort->params().end();
1026                                                  ++portParam) {                                                  ++portParam) {
1027                                  const qsamplerDeviceParam& param = portParam.value();                                  const DeviceParam& param = portParam.value();
1028                                  if (param.fix || param.value.isEmpty()) ts << "# ";                                  if (param.fix || param.value.isEmpty()) ts << "# ";
1029                                  ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice                                  ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice
1030                                  << " " << iPort << " " << portParam.key()                                  << " " << iPort << " " << portParam.key()
# Line 1037  bool MainForm::saveSessionFile ( const Q Line 1116  bool MainForm::saveSessionFile ( const Q
1116                  ChannelStrip* pChannelStrip                  ChannelStrip* pChannelStrip
1117                          = static_cast<ChannelStrip *> (wlist.at(iChannel));                          = static_cast<ChannelStrip *> (wlist.at(iChannel));
1118                  if (pChannelStrip) {                  if (pChannelStrip) {
1119                          qsamplerChannel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1120                          if (pChannel) {                          if (pChannel) {
1121                                  ts << "# " << tr("Channel") << " " << iChannel << endl;                                  ts << "# " << tr("Channel") << " " << iChannel << endl;
1122                                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
# Line 1069  bool MainForm::saveSessionFile ( const Q Line 1148  bool MainForm::saveSessionFile ( const Q
1148                                  ts << "LOAD INSTRUMENT NON_MODAL '"                                  ts << "LOAD INSTRUMENT NON_MODAL '"
1149                                          << pChannel->instrumentFile() << "' "                                          << pChannel->instrumentFile() << "' "
1150                                          << pChannel->instrumentNr() << " " << iChannel << endl;                                          << pChannel->instrumentNr() << " " << iChannel << endl;
1151                                  qsamplerChannelRoutingMap::ConstIterator audioRoute;                                  ChannelRoutingMap::ConstIterator audioRoute;
1152                                  for (audioRoute = pChannel->audioRouting().begin();                                  for (audioRoute = pChannel->audioRouting().begin();
1153                                                  audioRoute != pChannel->audioRouting().end();                                                  audioRoute != pChannel->audioRouting().end();
1154                                                          ++audioRoute) {                                                          ++audioRoute) {
# Line 1242  void MainForm::fileReset (void) Line 1321  void MainForm::fileReset (void)
1321                  "Please note that this operation may cause\n"                  "Please note that this operation may cause\n"
1322                  "temporary MIDI and Audio disruption.\n\n"                  "temporary MIDI and Audio disruption.\n\n"
1323                  "Do you want to reset the sampler engine now?"),                  "Do you want to reset the sampler engine now?"),
1324                  tr("Reset"), tr("Cancel")) > 0)                  QMessageBox::Ok | QMessageBox::Cancel)
1325                    == QMessageBox::Cancel)
1326                  return;                  return;
1327    
1328          // Trye closing the current session, first...          // Trye closing the current session, first...
# Line 1283  void MainForm::fileRestart (void) Line 1363  void MainForm::fileRestart (void)
1363                          "Please note that this operation may cause\n"                          "Please note that this operation may cause\n"
1364                          "temporary MIDI and Audio disruption.\n\n"                          "temporary MIDI and Audio disruption.\n\n"
1365                          "Do you want to restart the connection now?"),                          "Do you want to restart the connection now?"),
1366                          tr("Restart"), tr("Cancel")) == 0);                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok);
1367          }          }
1368    
1369          // Are we still for it?          // Are we still for it?
# Line 1314  void MainForm::editAddChannel (void) Line 1394  void MainForm::editAddChannel (void)
1394                  return;                  return;
1395    
1396          // Just create the channel instance...          // Just create the channel instance...
1397          qsamplerChannel *pChannel = new qsamplerChannel();          Channel *pChannel = new Channel();
1398          if (pChannel == NULL)          if (pChannel == NULL)
1399                  return;                  return;
1400    
# Line 1352  void MainForm::editRemoveChannel (void) Line 1432  void MainForm::editRemoveChannel (void)
1432          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1433                  return;                  return;
1434    
1435          qsamplerChannel *pChannel = pChannelStrip->channel();          Channel *pChannel = pChannelStrip->channel();
1436          if (pChannel == NULL)          if (pChannel == NULL)
1437                  return;                  return;
1438    
# Line 1364  void MainForm::editRemoveChannel (void) Line 1444  void MainForm::editRemoveChannel (void)
1444                          "%1\n\n"                          "%1\n\n"
1445                          "Are you sure?")                          "Are you sure?")
1446                          .arg(pChannelStrip->windowTitle()),                          .arg(pChannelStrip->windowTitle()),
1447                          tr("OK"), tr("Cancel")) > 0)                          QMessageBox::Ok | QMessageBox::Cancel)
1448                            == QMessageBox::Cancel)
1449                          return;                          return;
1450          }          }
1451    
# Line 1555  void MainForm::viewOptions (void) Line 1636  void MainForm::viewOptions (void)
1636                  int     iOldServerTimeout   = m_pOptions->iServerTimeout;                  int     iOldServerTimeout   = m_pOptions->iServerTimeout;
1637                  bool    bOldServerStart     = m_pOptions->bServerStart;                  bool    bOldServerStart     = m_pOptions->bServerStart;
1638                  QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;                  QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;
1639                    bool    bOldMessagesLog     = m_pOptions->bMessagesLog;
1640                    QString sOldMessagesLogPath = m_pOptions->sMessagesLogPath;
1641                  QString sOldDisplayFont     = m_pOptions->sDisplayFont;                  QString sOldDisplayFont     = m_pOptions->sDisplayFont;
1642                  bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;                  bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1643                  int     iOldMaxVolume       = m_pOptions->iMaxVolume;                  int     iOldMaxVolume       = m_pOptions->iMaxVolume;
# Line 1566  void MainForm::viewOptions (void) Line 1649  void MainForm::viewOptions (void)
1649                  bool    bOldCompletePath    = m_pOptions->bCompletePath;                  bool    bOldCompletePath    = m_pOptions->bCompletePath;
1650                  bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;                  bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1651                  int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;                  int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1652                    int     iOldBaseFontSize    = m_pOptions->iBaseFontSize;
1653                  // Load the current setup settings.                  // Load the current setup settings.
1654                  pOptionsForm->setup(m_pOptions);                  pOptionsForm->setup(m_pOptions);
1655                  // Show the setup dialog...                  // Show the setup dialog...
# Line 1574  void MainForm::viewOptions (void) Line 1658  void MainForm::viewOptions (void)
1658                          if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||                          if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1659                                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||                                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||
1660                                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||                                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1661                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)) {                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)     ||
1662                                    (iOldBaseFontSize   !=  m_pOptions->iBaseFontSize)) {
1663                                  QMessageBox::information(this,                                  QMessageBox::information(this,
1664                                          QSAMPLER_TITLE ": " + tr("Information"),                                          QSAMPLER_TITLE ": " + tr("Information"),
1665                                          tr("Some settings may be only effective\n"                                          tr("Some settings may be only effective\n"
1666                                          "next time you start this program."), tr("OK"));                                          "next time you start this program."));
1667                                  updateMessagesCapture();                                  updateMessagesCapture();
1668                          }                          }
1669                          // Check wheather something immediate has changed.                          // Check wheather something immediate has changed.
1670                            if (( bOldMessagesLog && !m_pOptions->bMessagesLog) ||
1671                                    (!bOldMessagesLog &&  m_pOptions->bMessagesLog) ||
1672                                    (sOldMessagesLogPath != m_pOptions->sMessagesLogPath))
1673                                    m_pMessages->setLogging(
1674                                            m_pOptions->bMessagesLog, m_pOptions->sMessagesLogPath);
1675                          if (( bOldCompletePath && !m_pOptions->bCompletePath) ||                          if (( bOldCompletePath && !m_pOptions->bCompletePath) ||
1676                                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||                                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||
1677                                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))                                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))
# Line 1736  void MainForm::helpAbout (void) Line 1826  void MainForm::helpAbout (void)
1826          sText += tr("Instrument editing support disabled.");          sText += tr("Instrument editing support disabled.");
1827          sText += "</font></small><br />";          sText += "</font></small><br />";
1828  #endif  #endif
1829    #ifndef CONFIG_EVENT_CHANNEL_MIDI
1830            sText += "<small><font color=\"red\">";
1831            sText += tr("Channel MIDI event support disabled.");
1832            sText += "</font></small><br />";
1833    #endif
1834    #ifndef CONFIG_EVENT_DEVICE_MIDI
1835            sText += "<small><font color=\"red\">";
1836            sText += tr("Device MIDI event support disabled.");
1837            sText += "</font></small><br />";
1838    #endif
1839    #ifndef CONFIG_MAX_VOICES
1840            sText += "<small><font color=\"red\">";
1841            sText += tr("Runtime max. voices / disk streams support disabled.");
1842            sText += "</font></small><br />";
1843    #endif
1844          sText += "<br />\n";          sText += "<br />\n";
1845          sText += tr("Using") + ": ";          sText += tr("Using") + ": ";
1846          sText += ::lscp_client_package();          sText += ::lscp_client_package();
# Line 1776  void MainForm::stabilizeForm (void) Line 1881  void MainForm::stabilizeForm (void)
1881          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));
1882    
1883          // Update the main menu state...          // Update the main menu state...
1884          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1885          bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);          bool bHasClient = (m_pOptions != NULL && m_pClient != NULL);
1886          bool bHasChannel = (bHasClient && pChannelStrip != NULL);          bool bHasChannel = (bHasClient && pChannelStrip != NULL);
1887            bool bHasChannels = (bHasClient && m_pWorkspace->windowList().count() > 0);
1888          m_ui.fileNewAction->setEnabled(bHasClient);          m_ui.fileNewAction->setEnabled(bHasClient);
1889          m_ui.fileOpenAction->setEnabled(bHasClient);          m_ui.fileOpenAction->setEnabled(bHasClient);
1890          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
# Line 1794  void MainForm::stabilizeForm (void) Line 1900  void MainForm::stabilizeForm (void)
1900          m_ui.editEditChannelAction->setEnabled(false);          m_ui.editEditChannelAction->setEnabled(false);
1901  #endif  #endif
1902          m_ui.editResetChannelAction->setEnabled(bHasChannel);          m_ui.editResetChannelAction->setEnabled(bHasChannel);
1903          m_ui.editResetAllChannelsAction->setEnabled(bHasChannel);          m_ui.editResetAllChannelsAction->setEnabled(bHasChannels);
1904          m_ui.viewMessagesAction->setChecked(m_pMessages && m_pMessages->isVisible());          m_ui.viewMessagesAction->setChecked(m_pMessages && m_pMessages->isVisible());
1905  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
1906          m_ui.viewInstrumentsAction->setChecked(m_pInstrumentListForm          m_ui.viewInstrumentsAction->setChecked(m_pInstrumentListForm
# Line 1806  void MainForm::stabilizeForm (void) Line 1912  void MainForm::stabilizeForm (void)
1912          m_ui.viewDevicesAction->setChecked(m_pDeviceForm          m_ui.viewDevicesAction->setChecked(m_pDeviceForm
1913                  && m_pDeviceForm->isVisible());                  && m_pDeviceForm->isVisible());
1914          m_ui.viewDevicesAction->setEnabled(bHasClient);          m_ui.viewDevicesAction->setEnabled(bHasClient);
1915          m_ui.channelsArrangeAction->setEnabled(bHasChannel);          m_ui.viewMidiDeviceStatusMenu->setEnabled(
1916                    DeviceStatusForm::getInstances().size() > 0);
1917            m_ui.channelsArrangeAction->setEnabled(bHasChannels);
1918    
1919  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
1920          // Toolbar widgets are also affected...          // Toolbar widgets are also affected...
# Line 1910  void MainForm::updateSession (void) Line 2018  void MainForm::updateSession (void)
2018          }          }
2019  #endif  #endif
2020    
2021            updateAllChannelStrips(false);
2022    
2023            // Do we auto-arrange?
2024            if (m_pOptions && m_pOptions->bAutoArrange)
2025                    channelsArrange();
2026    
2027            // Remember to refresh devices and instruments...
2028            if (m_pInstrumentListForm)
2029                    m_pInstrumentListForm->refreshInstruments();
2030            if (m_pDeviceForm)
2031                    m_pDeviceForm->refreshDevices();
2032    }
2033    
2034    void MainForm::updateAllChannelStrips(bool bRemoveDeadStrips) {
2035          // Retrieve the current channel list.          // Retrieve the current channel list.
2036          int *piChannelIDs = ::lscp_list_channels(m_pClient);          int *piChannelIDs = ::lscp_list_channels(m_pClient);
2037          if (piChannelIDs == NULL) {          if (piChannelIDs == NULL) {
# Line 1924  void MainForm::updateSession (void) Line 2046  void MainForm::updateSession (void)
2046                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {
2047                          // Check if theres already a channel strip for this one...                          // Check if theres already a channel strip for this one...
2048                          if (!channelStrip(piChannelIDs[iChannel]))                          if (!channelStrip(piChannelIDs[iChannel]))
2049                                  createChannelStrip(new qsamplerChannel(piChannelIDs[iChannel]));                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));
2050                  }                  }
                 m_pWorkspace->setUpdatesEnabled(true);  
         }  
2051    
2052          // Do we auto-arrange?                  // Do we auto-arrange?
2053          if (m_pOptions && m_pOptions->bAutoArrange)                  if (m_pOptions && m_pOptions->bAutoArrange)
2054                  channelsArrange();                          channelsArrange();
2055    
2056          // Remember to refresh devices and instruments...                  stabilizeForm();
         if (m_pInstrumentListForm)  
                 m_pInstrumentListForm->refreshInstruments();  
         if (m_pDeviceForm)  
                 m_pDeviceForm->refreshDevices();  
 }  
2057    
2058                    // remove dead channel strips
2059                    if (bRemoveDeadStrips) {
2060                            for (int i = 0; channelStripAt(i); ++i) {
2061                                    ChannelStrip* pChannelStrip = channelStripAt(i);
2062                                    bool bExists = false;
2063                                    for (int j = 0; piChannelIDs[j] >= 0; ++j) {
2064                                            if (!pChannelStrip->channel()) break;
2065                                            if (piChannelIDs[j] == pChannelStrip->channel()->channelID()) {
2066                                                    // strip exists, don't touch it
2067                                                    bExists = true;
2068                                                    break;
2069                                            }
2070                                    }
2071                                    if (!bExists) destroyChannelStrip(pChannelStrip);
2072                            }
2073                    }
2074                    m_pWorkspace->setUpdatesEnabled(true);
2075            }
2076    }
2077    
2078  // Update the recent files list and menu.  // Update the recent files list and menu.
2079  void MainForm::updateRecentFiles ( const QString& sFilename )  void MainForm::updateRecentFiles ( const QString& sFilename )
# Line 2113  void MainForm::appendMessagesError( cons Line 2247  void MainForm::appendMessagesError( cons
2247          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2248    
2249          QMessageBox::critical(this,          QMessageBox::critical(this,
2250                  QSAMPLER_TITLE ": " + tr("Error"), s, tr("Cancel"));                  QSAMPLER_TITLE ": " + tr("Error"), s, QMessageBox::Cancel);
2251  }  }
2252    
2253    
# Line 2176  void MainForm::updateMessagesCapture (vo Line 2310  void MainForm::updateMessagesCapture (vo
2310  // qsamplerMainForm -- MDI channel strip management.  // qsamplerMainForm -- MDI channel strip management.
2311    
2312  // The channel strip creation executive.  // The channel strip creation executive.
2313  ChannelStrip* MainForm::createChannelStrip ( qsamplerChannel *pChannel )  ChannelStrip* MainForm::createChannelStrip ( Channel *pChannel )
2314  {  {
2315          if (m_pClient == NULL || pChannel == NULL)          if (m_pClient == NULL || pChannel == NULL)
2316                  return NULL;                  return NULL;
# Line 2218  ChannelStrip* MainForm::createChannelStr Line 2352  ChannelStrip* MainForm::createChannelStr
2352          return pChannelStrip;          return pChannelStrip;
2353  }  }
2354    
2355    void MainForm::destroyChannelStrip(ChannelStrip* pChannelStrip) {
2356            // Just delete the channel strip.
2357            delete pChannelStrip;
2358    
2359            // Do we auto-arrange?
2360            if (m_pOptions && m_pOptions->bAutoArrange)
2361                    channelsArrange();
2362    
2363            stabilizeForm();
2364    }
2365    
2366  // Retrieve the active channel strip.  // Retrieve the active channel strip.
2367  ChannelStrip* MainForm::activeChannelStrip (void)  ChannelStrip* MainForm::activeChannelStrip (void)
# Line 2229  ChannelStrip* MainForm::activeChannelStr Line 2373  ChannelStrip* MainForm::activeChannelStr
2373  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2374  ChannelStrip* MainForm::channelStripAt ( int iChannel )  ChannelStrip* MainForm::channelStripAt ( int iChannel )
2375  {  {
2376            if (!m_pWorkspace) return NULL;
2377    
2378          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
2379          if (wlist.isEmpty())          if (wlist.isEmpty())
2380                  return NULL;                  return NULL;
2381    
2382          return static_cast<ChannelStrip *> (wlist.at(iChannel));          if (iChannel < 0 || iChannel >= wlist.size())
2383                    return NULL;
2384    
2385            return dynamic_cast<ChannelStrip *> (wlist.at(iChannel));
2386  }  }
2387    
2388    
# Line 2248  ChannelStrip* MainForm::channelStrip ( i Line 2397  ChannelStrip* MainForm::channelStrip ( i
2397                  ChannelStrip* pChannelStrip                  ChannelStrip* pChannelStrip
2398                          = static_cast<ChannelStrip*> (wlist.at(iChannel));                          = static_cast<ChannelStrip*> (wlist.at(iChannel));
2399                  if (pChannelStrip) {                  if (pChannelStrip) {
2400                          qsamplerChannel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
2401                          if (pChannel && pChannel->channelID() == iChannelID)                          if (pChannel && pChannel->channelID() == iChannelID)
2402                                  return pChannelStrip;                                  return pChannelStrip;
2403                  }                  }
# Line 2386  void MainForm::startServer (void) Line 2535  void MainForm::startServer (void)
2535    
2536          // Is the server process instance still here?          // Is the server process instance still here?
2537          if (m_pServer) {          if (m_pServer) {
2538                  switch (QMessageBox::warning(this,                  if (QMessageBox::warning(this,
2539                          QSAMPLER_TITLE ": " + tr("Warning"),                          QSAMPLER_TITLE ": " + tr("Warning"),
2540                          tr("Could not start the LinuxSampler server.\n\n"                          tr("Could not start the LinuxSampler server.\n\n"
2541                          "Maybe it ss already started."),                          "Maybe it is already started."),
2542                          tr("Stop"), tr("Kill"), tr("Cancel"))) {                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
                 case 0:  
2543                          m_pServer->terminate();                          m_pServer->terminate();
                         break;  
                 case 1:  
2544                          m_pServer->kill();                          m_pServer->kill();
                         break;  
2545                  }                  }
2546                  return;                  return;
2547          }          }
# Line 2409  void MainForm::startServer (void) Line 2554  void MainForm::startServer (void)
2554                  return;                  return;
2555    
2556          // OK. Let's build the startup process...          // OK. Let's build the startup process...
2557          m_pServer = new QProcess(this);          m_pServer = new QProcess();
2558            bForceServerStop = true;
2559    
2560          // Setup stdout/stderr capture...          // Setup stdout/stderr capture...
2561  //      if (m_pOptions->bStdoutCapture) {  //      if (m_pOptions->bStdoutCapture) {
2562                  //m_pServer->setProcessChannelMode(  #if QT_VERSION >= 0x040200
2563                  //      QProcess::StandardOutput);                  m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);
2564    #endif
2565                  QObject::connect(m_pServer,                  QObject::connect(m_pServer,
2566                          SIGNAL(readyReadStandardOutput()),                          SIGNAL(readyReadStandardOutput()),
2567                          SLOT(readServerStdout()));                          SLOT(readServerStdout()));
# Line 2425  void MainForm::startServer (void) Line 2572  void MainForm::startServer (void)
2572    
2573          // The unforgiveable signal communication...          // The unforgiveable signal communication...
2574          QObject::connect(m_pServer,          QObject::connect(m_pServer,
2575                  SIGNAL(finished(int,QProcess::ExitStatus)),                  SIGNAL(finished(int, QProcess::ExitStatus)),
2576                  SLOT(processServerExit()));                  SLOT(processServerExit()));
2577    
2578          // Build process arguments...          // Build process arguments...
# Line 2456  void MainForm::startServer (void) Line 2603  void MainForm::startServer (void)
2603    
2604    
2605  // Stop linuxsampler server...  // Stop linuxsampler server...
2606  void MainForm::stopServer (void)  void MainForm::stopServer (bool bInteractive)
2607  {  {
2608          // Stop client code.          // Stop client code.
2609          stopClient();          stopClient();
2610    
2611            if (m_pServer && bInteractive) {
2612                    if (QMessageBox::question(this,
2613                            QSAMPLER_TITLE ": " + tr("The backend's fate ..."),
2614                            tr("You have the option to keep the sampler backend (LinuxSampler)\n"
2615                            "running in the background. The sampler would continue to work\n"
2616                            "according to your current sampler session and you could alter the\n"
2617                            "sampler session at any time by relaunching QSampler.\n\n"
2618                            "Do you want LinuxSampler to stop?"),
2619                            QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
2620                    {
2621                            bForceServerStop = false;
2622                    }
2623            }
2624    
2625          // And try to stop server.          // And try to stop server.
2626          if (m_pServer) {          if (m_pServer && bForceServerStop) {
2627                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2628                  if (m_pServer->state() == QProcess::Running)                  if (m_pServer->state() == QProcess::Running) {
2629    #if defined(WIN32)
2630                            // Try harder...
2631                            m_pServer->kill();
2632    #else
2633                            // Try softly...
2634                          m_pServer->terminate();                          m_pServer->terminate();
2635          }  #endif
2636                    }
2637            }       // Do final processing anyway.
2638            else processServerExit();
2639    
2640          // Give it some time to terminate gracefully and stabilize...          // Give it some time to terminate gracefully and stabilize...
2641          QTime t;          QTime t;
2642          t.start();          t.start();
2643          while (t.elapsed() < QSAMPLER_TIMER_MSECS)          while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2644                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
   
         // Do final processing anyway.  
         processServerExit();  
2645  }  }
2646    
2647    
# Line 2497  void MainForm::processServerExit (void) Line 2663  void MainForm::processServerExit (void)
2663          if (m_pMessages)          if (m_pMessages)
2664                  m_pMessages->flushStdoutBuffer();                  m_pMessages->flushStdoutBuffer();
2665    
2666          if (m_pServer) {          if (m_pServer && bForceServerStop) {
2667                    if (m_pServer->state() != QProcess::NotRunning) {
2668                            appendMessages(tr("Server is being forced..."));
2669                            // Force final server shutdown...
2670                            m_pServer->kill();
2671                            // Give it some time to terminate gracefully and stabilize...
2672                            QTime t;
2673                            t.start();
2674                            while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2675                                    QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2676                    }
2677                  // Force final server shutdown...                  // Force final server shutdown...
2678                  appendMessages(                  appendMessages(
2679                          tr("Server was stopped with exit status %1.")                          tr("Server was stopped with exit status %1.")
2680                          .arg(m_pServer->exitStatus()));                          .arg(m_pServer->exitStatus()));
                 m_pServer->terminate();  
                 if (!m_pServer->waitForFinished(2000))  
                         m_pServer->kill();  
                 // Destroy it.  
2681                  delete m_pServer;                  delete m_pServer;
2682                  m_pServer = NULL;                  m_pServer = NULL;
2683          }          }
# Line 2530  lscp_status_t qsampler_client_callback ( Line 2702  lscp_status_t qsampler_client_callback (
2702          // as this is run under some other thread context.          // as this is run under some other thread context.
2703          // A custom event must be posted here...          // A custom event must be posted here...
2704          QApplication::postEvent(pMainForm,          QApplication::postEvent(pMainForm,
2705                  new qsamplerCustomEvent(event, pchData, cchData));                  new CustomEvent(event, pchData, cchData));
2706    
2707          return LSCP_OK;          return LSCP_OK;
2708  }  }
# Line 2575  bool MainForm::startClient (void) Line 2747  bool MainForm::startClient (void)
2747                  .arg(::lscp_client_get_timeout(m_pClient)));                  .arg(::lscp_client_get_timeout(m_pClient)));
2748    
2749          // Subscribe to channel info change notifications...          // Subscribe to channel info change notifications...
2750            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT) != LSCP_OK)
2751                    appendMessagesClient("lscp_client_subscribe(CHANNEL_COUNT)");
2752          if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)          if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)
2753                  appendMessagesClient("lscp_client_subscribe");                  appendMessagesClient("lscp_client_subscribe(CHANNEL_INFO)");
2754    
2755            DeviceStatusForm::onDevicesChanged(); // initialize
2756            updateViewMidiDeviceStatusMenu();
2757            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT) != LSCP_OK)
2758                    appendMessagesClient("lscp_client_subscribe(MIDI_INPUT_DEVICE_COUNT)");
2759            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO) != LSCP_OK)
2760                    appendMessagesClient("lscp_client_subscribe(MIDI_INPUT_DEVICE_INFO)");
2761            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT) != LSCP_OK)
2762                    appendMessagesClient("lscp_client_subscribe(AUDIO_OUTPUT_DEVICE_COUNT)");
2763            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO) != LSCP_OK)
2764                    appendMessagesClient("lscp_client_subscribe(AUDIO_OUTPUT_DEVICE_INFO)");
2765    
2766    #if CONFIG_EVENT_CHANNEL_MIDI
2767            // Subscribe to channel MIDI data notifications...
2768            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_MIDI) != LSCP_OK)
2769                    appendMessagesClient("lscp_client_subscribe(CHANNEL_MIDI)");
2770    #endif
2771    
2772    #if CONFIG_EVENT_DEVICE_MIDI
2773            // Subscribe to channel MIDI data notifications...
2774            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_DEVICE_MIDI) != LSCP_OK)
2775                    appendMessagesClient("lscp_client_subscribe(DEVICE_MIDI)");
2776    #endif
2777    
2778          // We may stop scheduling around.          // We may stop scheduling around.
2779          stopSchedule();          stopSchedule();
# Line 2603  bool MainForm::startClient (void) Line 2800  bool MainForm::startClient (void)
2800                  }                  }
2801          }          }
2802    
2803            // send the current / loaded fine tuning settings to the sampler
2804            m_pOptions->sendFineTuningSettings();
2805    
2806          // Make a new session          // Make a new session
2807          return newSession();          return newSession();
2808  }  }
# Line 2630  void MainForm::stopClient (void) Line 2830  void MainForm::stopClient (void)
2830          closeSession(false);          closeSession(false);
2831    
2832          // Close us as a client...          // Close us as a client...
2833    #if CONFIG_EVENT_DEVICE_MIDI
2834            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_DEVICE_MIDI);
2835    #endif
2836    #if CONFIG_EVENT_CHANNEL_MIDI
2837            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_MIDI);
2838    #endif
2839            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO);
2840            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT);
2841            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO);
2842            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT);
2843          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
2844            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);
2845          ::lscp_client_destroy(m_pClient);          ::lscp_client_destroy(m_pClient);
2846          m_pClient = NULL;          m_pClient = NULL;
2847    

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

  ViewVC Help
Powered by ViewVC