/[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 1702 by schoenebeck, Sun Feb 17 13:53:00 2008 UTC
# Line 2  Line 2 
2  //  //
3  /****************************************************************************  /****************************************************************************
4     Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2007, 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 77  static inline long lroundf ( float x ) Line 78  static inline long lroundf ( float x )
78  }  }
79  #endif  #endif
80    
81    
82    // All winsock apps needs this.
83    #if defined(WIN32)
84    static WSADATA _wsaData;
85    #endif
86    
87    
88    namespace QSampler {
89    
90  // Timer constant stuff.  // Timer constant stuff.
91  #define QSAMPLER_TIMER_MSECS    200  #define QSAMPLER_TIMER_MSECS    200
92    
# Line 87  static inline long lroundf ( float x ) Line 97  static inline long lroundf ( float x )
97  #define QSAMPLER_STATUS_SESSION 3       // Current session modification state.  #define QSAMPLER_STATUS_SESSION 3       // Current session modification state.
98    
99    
 // All winsock apps needs this.  
 #if defined(WIN32)  
 static WSADATA _wsaData;  
 #endif  
   
   
100  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
101  // qsamplerCustomEvent -- specialty for callback comunication.  // CustomEvent -- specialty for callback comunication.
102    
103  #define QSAMPLER_CUSTOM_EVENT   QEvent::Type(QEvent::User + 0)  #define QSAMPLER_CUSTOM_EVENT   QEvent::Type(QEvent::User + 0)
104    
105  class qsamplerCustomEvent : public QEvent  class CustomEvent : public QEvent
106  {  {
107  public:  public:
108    
109          // Constructor.          // Constructor.
110          qsamplerCustomEvent(lscp_event_t event, const char *pchData, int cchData)          CustomEvent(lscp_event_t event, const char *pchData, int cchData)
111                  : QEvent(QSAMPLER_CUSTOM_EVENT)                  : QEvent(QSAMPLER_CUSTOM_EVENT)
112          {          {
113                  m_event = event;                  m_event = event;
# Line 126  private: Line 130  private:
130  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
131  // qsamplerMainForm -- Main window form implementation.  // qsamplerMainForm -- Main window form implementation.
132    
 namespace QSampler {  
   
133  // Kind of singleton reference.  // Kind of singleton reference.
134  MainForm* MainForm::g_pMainForm = NULL;  MainForm* MainForm::g_pMainForm = NULL;
135    
# Line 366  MainForm::~MainForm() Line 368  MainForm::~MainForm()
368    
369    
370  // Make and set a proper setup options step.  // Make and set a proper setup options step.
371  void MainForm::setup ( qsamplerOptions *pOptions )  void MainForm::setup ( Options *pOptions )
372  {  {
373          // We got options?          // We got options?
374          m_pOptions = pOptions;          m_pOptions = pOptions;
# Line 382  void MainForm::setup ( qsamplerOptions * Line 384  void MainForm::setup ( qsamplerOptions *
384          if (m_pOptions->bKeepOnTop)          if (m_pOptions->bKeepOnTop)
385                  wflags |= Qt::Tool;                  wflags |= Qt::Tool;
386          // Some child forms are to be created right now.          // Some child forms are to be created right now.
387          m_pMessages = new qsamplerMessages(this);          m_pMessages = new Messages(this);
388          m_pDeviceForm = new DeviceForm(this, wflags);          m_pDeviceForm = new DeviceForm(this, wflags);
389  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
390          m_pInstrumentListForm = new InstrumentListForm(this, wflags);          m_pInstrumentListForm = new InstrumentListForm(this, wflags);
# Line 470  bool MainForm::queryClose (void) Line 472  bool MainForm::queryClose (void)
472                          if (m_pDeviceForm)                          if (m_pDeviceForm)
473                                  m_pDeviceForm->close();                                  m_pDeviceForm->close();
474                          // Stop client and/or server, gracefully.                          // Stop client and/or server, gracefully.
475                          stopServer();                          stopServer(true /*interactive*/);
476                  }                  }
477          }          }
478    
# Line 480  bool MainForm::queryClose (void) Line 482  bool MainForm::queryClose (void)
482    
483  void MainForm::closeEvent ( QCloseEvent *pCloseEvent )  void MainForm::closeEvent ( QCloseEvent *pCloseEvent )
484  {  {
485          if (queryClose())          if (queryClose()) {
486                    DeviceStatusForm::deleteAllInstances();
487                  pCloseEvent->accept();                  pCloseEvent->accept();
488          else          } else
489                  pCloseEvent->ignore();                  pCloseEvent->ignore();
490  }  }
491    
# Line 511  void MainForm::dropEvent ( QDropEvent* p Line 514  void MainForm::dropEvent ( QDropEvent* p
514                  QListIterator<QUrl> iter(pMimeData->urls());                  QListIterator<QUrl> iter(pMimeData->urls());
515                  while (iter.hasNext()) {                  while (iter.hasNext()) {
516                          const QString& sPath = iter.next().toLocalFile();                          const QString& sPath = iter.next().toLocalFile();
517                          if (qsamplerChannel::isInstrumentFile(sPath)) {                          if (Channel::isInstrumentFile(sPath)) {
518                                  // Try to create a new channel from instrument file...                                  // Try to create a new channel from instrument file...
519                                  qsamplerChannel *pChannel = new qsamplerChannel();                                  Channel *pChannel = new Channel();
520                                  if (pChannel == NULL)                                  if (pChannel == NULL)
521                                          return;                                          return;
522                                  // Start setting the instrument filename...                                  // Start setting the instrument filename...
# Line 549  void MainForm::customEvent(QEvent* pCust Line 552  void MainForm::customEvent(QEvent* pCust
552  {  {
553          // For the time being, just pump it to messages.          // For the time being, just pump it to messages.
554          if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {          if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {
555                  qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;                  CustomEvent *pEvent = static_cast<CustomEvent *> (pCustomEvent);
556                  if (pEvent->event() == LSCP_EVENT_CHANNEL_INFO) {                  switch (pEvent->event()) {
557                          int iChannelID = pEvent->data().toInt();                          case LSCP_EVENT_CHANNEL_COUNT:
558                          ChannelStrip *pChannelStrip = channelStrip(iChannelID);                                  updateAllChannelStrips(true);
559                          if (pChannelStrip)                                  break;
560                                  channelStripChanged(pChannelStrip);                          case LSCP_EVENT_CHANNEL_INFO: {
561                  } else {                                  int iChannelID = pEvent->data().toInt();
562                          appendMessagesColor(tr("Notify event: %1 data: %2")                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);
563                                  .arg(::lscp_event_to_text(pEvent->event()))                                  if (pChannelStrip)
564                                  .arg(pEvent->data()), "#996699");                                          channelStripChanged(pChannelStrip);
565                                    break;
566                            }
567                            case LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT:
568                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
569                                    DeviceStatusForm::onDevicesChanged();
570                                    updateViewMidiDeviceStatusMenu();
571                                    break;
572                            case LSCP_EVENT_MIDI_INPUT_DEVICE_INFO: {
573                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
574                                    const int iDeviceID = pEvent->data().section(' ', 0, 0).toInt();
575                                    DeviceStatusForm::onDeviceChanged(iDeviceID);
576                                    break;
577                            }
578                            case LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT:
579                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
580                                    break;
581                            case LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO:
582                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
583                                    break;
584    #if CONFIG_LSCP_CHANNEL_MIDI
585                            case LSCP_EVENT_CHANNEL_MIDI: {
586                                    const int iChannelID = pEvent->data().section(' ', 0, 0).toInt();
587                                    ChannelStrip *pChannelStrip = channelStrip(iChannelID);
588                                    if (pChannelStrip)
589                                            pChannelStrip->midiArrived();
590                                    break;
591                            }
592    #endif
593    #if CONFIG_LSCP_DEVICE_MIDI
594                            case LSCP_EVENT_DEVICE_MIDI: {
595                                    const int iDeviceID = pEvent->data().section(' ', 0, 0).toInt();
596                                    const int iPortID   = pEvent->data().section(' ', 1, 1).toInt();
597                                    DeviceStatusForm* pDeviceStatusForm =
598                                            DeviceStatusForm::getInstance(iDeviceID);
599                                    if (pDeviceStatusForm)
600                                            pDeviceStatusForm->midiArrived(iPortID);
601                                    break;
602                            }
603    #endif
604                            default:
605                                    appendMessagesColor(tr("Notify event: %1 data: %2")
606                                            .arg(::lscp_event_to_text(pEvent->event()))
607                                            .arg(pEvent->data()), "#996699");
608                  }                  }
609          }          }
610  }  }
611    
612    void MainForm::updateViewMidiDeviceStatusMenu() {
613            m_ui.viewMidiDeviceStatusMenu->clear();
614            const std::map<int, DeviceStatusForm*> statusForms =
615                    DeviceStatusForm::getInstances();
616            for (
617                    std::map<int, DeviceStatusForm*>::const_iterator iter = statusForms.begin();
618                    iter != statusForms.end(); ++iter
619            ) {
620                    DeviceStatusForm* pForm = iter->second;
621                    m_ui.viewMidiDeviceStatusMenu->addAction(
622                            pForm->visibleAction()
623                    );
624            }
625    }
626    
627  // Context menu event handler.  // Context menu event handler.
628  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )
629  {  {
# Line 576  void MainForm::contextMenuEvent( QContex Line 637  void MainForm::contextMenuEvent( QContex
637  // qsamplerMainForm -- Brainless public property accessors.  // qsamplerMainForm -- Brainless public property accessors.
638    
639  // The global options settings property.  // The global options settings property.
640  qsamplerOptions *MainForm::options (void) const  Options *MainForm::options (void) const
641  {  {
642          return m_pOptions;          return m_pOptions;
643  }  }
# Line 737  bool MainForm::closeSession ( bool bForc Line 798  bool MainForm::closeSession ( bool bForc
798                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
799                          ChannelStrip *pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                          ChannelStrip *pChannelStrip = (ChannelStrip*) wlist.at(iChannel);
800                          if (pChannelStrip) {                          if (pChannelStrip) {
801                                  qsamplerChannel *pChannel = pChannelStrip->channel();                                  Channel *pChannel = pChannelStrip->channel();
802                                  if (bForce && pChannel)                                  if (bForce && pChannel)
803                                          pChannel->removeChannel();                                          pChannel->removeChannel();
804                                  delete pChannelStrip;                                  delete pChannelStrip;
# Line 877  bool MainForm::saveSessionFile ( const Q Line 938  bool MainForm::saveSessionFile ( const Q
938    
939          // Audio device mapping.          // Audio device mapping.
940          QMap<int, int> audioDeviceMap;          QMap<int, int> audioDeviceMap;
941          piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Audio);          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);
942          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
943                  ts << endl;                  ts << endl;
944                  qsamplerDevice device(qsamplerDevice::Audio, piDeviceIDs[iDevice]);                  Device device(Device::Audio, piDeviceIDs[iDevice]);
945                  // Audio device specification...                  // Audio device specification...
946                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
947                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
948                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
949                  qsamplerDeviceParamMap::ConstIterator deviceParam;                  DeviceParamMap::ConstIterator deviceParam;
950                  for (deviceParam = device.params().begin();                  for (deviceParam = device.params().begin();
951                                  deviceParam != device.params().end();                                  deviceParam != device.params().end();
952                                          ++deviceParam) {                                          ++deviceParam) {
953                          const qsamplerDeviceParam& param = deviceParam.value();                          const DeviceParam& param = deviceParam.value();
954                          if (param.value.isEmpty()) ts << "# ";                          if (param.value.isEmpty()) ts << "# ";
955                          ts << " " << deviceParam.key() << "='" << param.value << "'";                          ts << " " << deviceParam.key() << "='" << param.value << "'";
956                  }                  }
957                  ts << endl;                  ts << endl;
958                  // Audio channel parameters...                  // Audio channel parameters...
959                  int iPort = 0;                  int iPort = 0;
960                  QListIterator<qsamplerDevicePort *> iter(device.ports());                  QListIterator<DevicePort *> iter(device.ports());
961                  while (iter.hasNext()) {                  while (iter.hasNext()) {
962                          qsamplerDevicePort *pPort = iter.next();                          DevicePort *pPort = iter.next();
963                          qsamplerDeviceParamMap::ConstIterator portParam;                          DeviceParamMap::ConstIterator portParam;
964                          for (portParam = pPort->params().begin();                          for (portParam = pPort->params().begin();
965                                          portParam != pPort->params().end();                                          portParam != pPort->params().end();
966                                                  ++portParam) {                                                  ++portParam) {
967                                  const qsamplerDeviceParam& param = portParam.value();                                  const DeviceParam& param = portParam.value();
968                                  if (param.fix || param.value.isEmpty()) ts << "# ";                                  if (param.fix || param.value.isEmpty()) ts << "# ";
969                                  ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice                                  ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice
970                                          << " " << iPort << " " << portParam.key()                                          << " " << iPort << " " << portParam.key()
# Line 919  bool MainForm::saveSessionFile ( const Q Line 980  bool MainForm::saveSessionFile ( const Q
980    
981          // MIDI device mapping.          // MIDI device mapping.
982          QMap<int, int> midiDeviceMap;          QMap<int, int> midiDeviceMap;
983          piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Midi);          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);
984          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
985                  ts << endl;                  ts << endl;
986                  qsamplerDevice device(qsamplerDevice::Midi, piDeviceIDs[iDevice]);                  Device device(Device::Midi, piDeviceIDs[iDevice]);
987                  // MIDI device specification...                  // MIDI device specification...
988                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
989                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
990                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
991                  qsamplerDeviceParamMap::ConstIterator deviceParam;                  DeviceParamMap::ConstIterator deviceParam;
992                  for (deviceParam = device.params().begin();                  for (deviceParam = device.params().begin();
993                                  deviceParam != device.params().end();                                  deviceParam != device.params().end();
994                                          ++deviceParam) {                                          ++deviceParam) {
995                          const qsamplerDeviceParam& param = deviceParam.value();                          const DeviceParam& param = deviceParam.value();
996                          if (param.value.isEmpty()) ts << "# ";                          if (param.value.isEmpty()) ts << "# ";
997                          ts << " " << deviceParam.key() << "='" << param.value << "'";                          ts << " " << deviceParam.key() << "='" << param.value << "'";
998                  }                  }
999                  ts << endl;                  ts << endl;
1000                  // MIDI port parameters...                  // MIDI port parameters...
1001                  int iPort = 0;                  int iPort = 0;
1002                  QListIterator<qsamplerDevicePort *> iter(device.ports());                  QListIterator<DevicePort *> iter(device.ports());
1003                  while (iter.hasNext()) {                  while (iter.hasNext()) {
1004                          qsamplerDevicePort *pPort = iter.next();                          DevicePort *pPort = iter.next();
1005                          qsamplerDeviceParamMap::ConstIterator portParam;                          DeviceParamMap::ConstIterator portParam;
1006                          for (portParam = pPort->params().begin();                          for (portParam = pPort->params().begin();
1007                                          portParam != pPort->params().end();                                          portParam != pPort->params().end();
1008                                                  ++portParam) {                                                  ++portParam) {
1009                                  const qsamplerDeviceParam& param = portParam.value();                                  const DeviceParam& param = portParam.value();
1010                                  if (param.fix || param.value.isEmpty()) ts << "# ";                                  if (param.fix || param.value.isEmpty()) ts << "# ";
1011                                  ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice                                  ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice
1012                                  << " " << iPort << " " << portParam.key()                                  << " " << iPort << " " << portParam.key()
# Line 1037  bool MainForm::saveSessionFile ( const Q Line 1098  bool MainForm::saveSessionFile ( const Q
1098                  ChannelStrip* pChannelStrip                  ChannelStrip* pChannelStrip
1099                          = static_cast<ChannelStrip *> (wlist.at(iChannel));                          = static_cast<ChannelStrip *> (wlist.at(iChannel));
1100                  if (pChannelStrip) {                  if (pChannelStrip) {
1101                          qsamplerChannel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1102                          if (pChannel) {                          if (pChannel) {
1103                                  ts << "# " << tr("Channel") << " " << iChannel << endl;                                  ts << "# " << tr("Channel") << " " << iChannel << endl;
1104                                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
# Line 1069  bool MainForm::saveSessionFile ( const Q Line 1130  bool MainForm::saveSessionFile ( const Q
1130                                  ts << "LOAD INSTRUMENT NON_MODAL '"                                  ts << "LOAD INSTRUMENT NON_MODAL '"
1131                                          << pChannel->instrumentFile() << "' "                                          << pChannel->instrumentFile() << "' "
1132                                          << pChannel->instrumentNr() << " " << iChannel << endl;                                          << pChannel->instrumentNr() << " " << iChannel << endl;
1133                                  qsamplerChannelRoutingMap::ConstIterator audioRoute;                                  ChannelRoutingMap::ConstIterator audioRoute;
1134                                  for (audioRoute = pChannel->audioRouting().begin();                                  for (audioRoute = pChannel->audioRouting().begin();
1135                                                  audioRoute != pChannel->audioRouting().end();                                                  audioRoute != pChannel->audioRouting().end();
1136                                                          ++audioRoute) {                                                          ++audioRoute) {
# Line 1314  void MainForm::editAddChannel (void) Line 1375  void MainForm::editAddChannel (void)
1375                  return;                  return;
1376    
1377          // Just create the channel instance...          // Just create the channel instance...
1378          qsamplerChannel *pChannel = new qsamplerChannel();          Channel *pChannel = new Channel();
1379          if (pChannel == NULL)          if (pChannel == NULL)
1380                  return;                  return;
1381    
# Line 1352  void MainForm::editRemoveChannel (void) Line 1413  void MainForm::editRemoveChannel (void)
1413          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1414                  return;                  return;
1415    
1416          qsamplerChannel *pChannel = pChannelStrip->channel();          Channel *pChannel = pChannelStrip->channel();
1417          if (pChannel == NULL)          if (pChannel == NULL)
1418                  return;                  return;
1419    
# Line 1910  void MainForm::updateSession (void) Line 1971  void MainForm::updateSession (void)
1971          }          }
1972  #endif  #endif
1973    
1974            updateAllChannelStrips(false);
1975    
1976            // Do we auto-arrange?
1977            if (m_pOptions && m_pOptions->bAutoArrange)
1978                    channelsArrange();
1979    
1980            // Remember to refresh devices and instruments...
1981            if (m_pInstrumentListForm)
1982                    m_pInstrumentListForm->refreshInstruments();
1983            if (m_pDeviceForm)
1984                    m_pDeviceForm->refreshDevices();
1985    }
1986    
1987    void MainForm::updateAllChannelStrips(bool bRemoveDeadStrips) {
1988          // Retrieve the current channel list.          // Retrieve the current channel list.
1989          int *piChannelIDs = ::lscp_list_channels(m_pClient);          int *piChannelIDs = ::lscp_list_channels(m_pClient);
1990          if (piChannelIDs == NULL) {          if (piChannelIDs == NULL) {
# Line 1924  void MainForm::updateSession (void) Line 1999  void MainForm::updateSession (void)
1999                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {
2000                          // Check if theres already a channel strip for this one...                          // Check if theres already a channel strip for this one...
2001                          if (!channelStrip(piChannelIDs[iChannel]))                          if (!channelStrip(piChannelIDs[iChannel]))
2002                                  createChannelStrip(new qsamplerChannel(piChannelIDs[iChannel]));                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));
2003                  }                  }
                 m_pWorkspace->setUpdatesEnabled(true);  
         }  
2004    
2005          // Do we auto-arrange?                  // Do we auto-arrange?
2006          if (m_pOptions && m_pOptions->bAutoArrange)                  if (m_pOptions && m_pOptions->bAutoArrange)
2007                  channelsArrange();                          channelsArrange();
2008    
2009          // Remember to refresh devices and instruments...                  stabilizeForm();
         if (m_pInstrumentListForm)  
                 m_pInstrumentListForm->refreshInstruments();  
         if (m_pDeviceForm)  
                 m_pDeviceForm->refreshDevices();  
 }  
2010    
2011                    // remove dead channel strips
2012                    if (bRemoveDeadStrips) {
2013                            for (int i = 0; channelStripAt(i); ++i) {
2014                                    ChannelStrip* pChannelStrip = channelStripAt(i);
2015                                    bool bExists = false;
2016                                    for (int j = 0; piChannelIDs[j] >= 0; ++j) {
2017                                            if (!pChannelStrip->channel()) break;
2018                                            if (piChannelIDs[j] == pChannelStrip->channel()->channelID()) {
2019                                                    // strip exists, don't touch it
2020                                                    bExists = true;
2021                                                    break;
2022                                            }
2023                                    }
2024                                    if (!bExists) destroyChannelStrip(pChannelStrip);
2025                            }
2026                    }
2027                    m_pWorkspace->setUpdatesEnabled(true);
2028            }
2029    }
2030    
2031  // Update the recent files list and menu.  // Update the recent files list and menu.
2032  void MainForm::updateRecentFiles ( const QString& sFilename )  void MainForm::updateRecentFiles ( const QString& sFilename )
# Line 2176  void MainForm::updateMessagesCapture (vo Line 2263  void MainForm::updateMessagesCapture (vo
2263  // qsamplerMainForm -- MDI channel strip management.  // qsamplerMainForm -- MDI channel strip management.
2264    
2265  // The channel strip creation executive.  // The channel strip creation executive.
2266  ChannelStrip* MainForm::createChannelStrip ( qsamplerChannel *pChannel )  ChannelStrip* MainForm::createChannelStrip ( Channel *pChannel )
2267  {  {
2268          if (m_pClient == NULL || pChannel == NULL)          if (m_pClient == NULL || pChannel == NULL)
2269                  return NULL;                  return NULL;
# Line 2218  ChannelStrip* MainForm::createChannelStr Line 2305  ChannelStrip* MainForm::createChannelStr
2305          return pChannelStrip;          return pChannelStrip;
2306  }  }
2307    
2308    void MainForm::destroyChannelStrip(ChannelStrip* pChannelStrip) {
2309            // Just delete the channel strip.
2310            delete pChannelStrip;
2311    
2312            // Do we auto-arrange?
2313            if (m_pOptions && m_pOptions->bAutoArrange)
2314                    channelsArrange();
2315    
2316            stabilizeForm();
2317    }
2318    
2319  // Retrieve the active channel strip.  // Retrieve the active channel strip.
2320  ChannelStrip* MainForm::activeChannelStrip (void)  ChannelStrip* MainForm::activeChannelStrip (void)
# Line 2229  ChannelStrip* MainForm::activeChannelStr Line 2326  ChannelStrip* MainForm::activeChannelStr
2326  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2327  ChannelStrip* MainForm::channelStripAt ( int iChannel )  ChannelStrip* MainForm::channelStripAt ( int iChannel )
2328  {  {
2329            if (!m_pWorkspace) return NULL;
2330    
2331          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
2332          if (wlist.isEmpty())          if (wlist.isEmpty())
2333                  return NULL;                  return NULL;
2334    
2335          return static_cast<ChannelStrip *> (wlist.at(iChannel));          if (iChannel < 0 || iChannel >= wlist.size())
2336                    return NULL;
2337    
2338            return dynamic_cast<ChannelStrip *> (wlist.at(iChannel));
2339  }  }
2340    
2341    
# Line 2248  ChannelStrip* MainForm::channelStrip ( i Line 2350  ChannelStrip* MainForm::channelStrip ( i
2350                  ChannelStrip* pChannelStrip                  ChannelStrip* pChannelStrip
2351                          = static_cast<ChannelStrip*> (wlist.at(iChannel));                          = static_cast<ChannelStrip*> (wlist.at(iChannel));
2352                  if (pChannelStrip) {                  if (pChannelStrip) {
2353                          qsamplerChannel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
2354                          if (pChannel && pChannel->channelID() == iChannelID)                          if (pChannel && pChannel->channelID() == iChannelID)
2355                                  return pChannelStrip;                                  return pChannelStrip;
2356                  }                  }
# Line 2389  void MainForm::startServer (void) Line 2491  void MainForm::startServer (void)
2491                  switch (QMessageBox::warning(this,                  switch (QMessageBox::warning(this,
2492                          QSAMPLER_TITLE ": " + tr("Warning"),                          QSAMPLER_TITLE ": " + tr("Warning"),
2493                          tr("Could not start the LinuxSampler server.\n\n"                          tr("Could not start the LinuxSampler server.\n\n"
2494                          "Maybe it ss already started."),                          "Maybe it is already started."),
2495                          tr("Stop"), tr("Kill"), tr("Cancel"))) {                          tr("Stop"), tr("Kill"), tr("Cancel"))) {
2496                  case 0:                  case 0:
2497                          m_pServer->terminate();                          m_pServer->terminate();
# Line 2409  void MainForm::startServer (void) Line 2511  void MainForm::startServer (void)
2511                  return;                  return;
2512    
2513          // OK. Let's build the startup process...          // OK. Let's build the startup process...
2514          m_pServer = new QProcess(this);          m_pServer = new QProcess();
2515            bForceServerStop = true;
2516    
2517          // Setup stdout/stderr capture...          // Setup stdout/stderr capture...
2518  //      if (m_pOptions->bStdoutCapture) {  //      if (m_pOptions->bStdoutCapture) {
2519                  //m_pServer->setProcessChannelMode(  #if QT_VERSION >= 0x040200
2520                  //      QProcess::StandardOutput);                  m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);
2521    #endif
2522                  QObject::connect(m_pServer,                  QObject::connect(m_pServer,
2523                          SIGNAL(readyReadStandardOutput()),                          SIGNAL(readyReadStandardOutput()),
2524                          SLOT(readServerStdout()));                          SLOT(readServerStdout()));
# Line 2425  void MainForm::startServer (void) Line 2529  void MainForm::startServer (void)
2529    
2530          // The unforgiveable signal communication...          // The unforgiveable signal communication...
2531          QObject::connect(m_pServer,          QObject::connect(m_pServer,
2532                  SIGNAL(finished(int,QProcess::ExitStatus)),                  SIGNAL(finished(int, QProcess::ExitStatus)),
2533                  SLOT(processServerExit()));                  SLOT(processServerExit()));
2534    
2535          // Build process arguments...          // Build process arguments...
# Line 2456  void MainForm::startServer (void) Line 2560  void MainForm::startServer (void)
2560    
2561    
2562  // Stop linuxsampler server...  // Stop linuxsampler server...
2563  void MainForm::stopServer (void)  void MainForm::stopServer (bool bInteractive)
2564  {  {
2565          // Stop client code.          // Stop client code.
2566          stopClient();          stopClient();
2567    
2568            if (m_pServer && bInteractive) {
2569                    if (QMessageBox::question(this,
2570                            QSAMPLER_TITLE ": " + tr("The backend's fate ..."),
2571                            tr("You have the option to keep the sampler backend (LinuxSampler)\n"
2572                            "running in the background. The sampler would continue to work\n"
2573                            "according to your current sampler session and you could alter the\n"
2574                            "sampler session at any time by relaunching QSampler.\n\n"
2575                            "Do you want LinuxSampler to stop or to keep running in\n"
2576                            "the background?"),
2577                            tr("Stop"), tr("Keep Running")) == 1)
2578                    {
2579                            bForceServerStop = false;
2580                    }
2581            }
2582    
2583          // And try to stop server.          // And try to stop server.
2584          if (m_pServer) {          if (m_pServer && bForceServerStop) {
2585                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2586                  if (m_pServer->state() == QProcess::Running)                  if (m_pServer->state() == QProcess::Running) {
2587    #if defined(WIN32)
2588                            // Try harder...
2589                            m_pServer->kill();
2590    #else
2591                            // Try softly...
2592                          m_pServer->terminate();                          m_pServer->terminate();
2593          }  #endif
2594                    }
2595            }       // Do final processing anyway.
2596            else processServerExit();
2597    
2598          // Give it some time to terminate gracefully and stabilize...          // Give it some time to terminate gracefully and stabilize...
2599          QTime t;          QTime t;
2600          t.start();          t.start();
2601          while (t.elapsed() < QSAMPLER_TIMER_MSECS)          while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2602                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
   
         // Do final processing anyway.  
         processServerExit();  
2603  }  }
2604    
2605    
# Line 2497  void MainForm::processServerExit (void) Line 2621  void MainForm::processServerExit (void)
2621          if (m_pMessages)          if (m_pMessages)
2622                  m_pMessages->flushStdoutBuffer();                  m_pMessages->flushStdoutBuffer();
2623    
2624          if (m_pServer) {          if (m_pServer && bForceServerStop) {
2625                    if (m_pServer->state() != QProcess::NotRunning) {
2626                            appendMessages(tr("Server is being forced..."));
2627                            // Force final server shutdown...
2628                            m_pServer->kill();
2629                            // Give it some time to terminate gracefully and stabilize...
2630                            QTime t;
2631                            t.start();
2632                            while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2633                                    QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2634                    }
2635                  // Force final server shutdown...                  // Force final server shutdown...
2636                  appendMessages(                  appendMessages(
2637                          tr("Server was stopped with exit status %1.")                          tr("Server was stopped with exit status %1.")
2638                          .arg(m_pServer->exitStatus()));                          .arg(m_pServer->exitStatus()));
                 m_pServer->terminate();  
                 if (!m_pServer->waitForFinished(2000))  
                         m_pServer->kill();  
                 // Destroy it.  
2639                  delete m_pServer;                  delete m_pServer;
2640                  m_pServer = NULL;                  m_pServer = NULL;
2641          }          }
# Line 2530  lscp_status_t qsampler_client_callback ( Line 2660  lscp_status_t qsampler_client_callback (
2660          // as this is run under some other thread context.          // as this is run under some other thread context.
2661          // A custom event must be posted here...          // A custom event must be posted here...
2662          QApplication::postEvent(pMainForm,          QApplication::postEvent(pMainForm,
2663                  new qsamplerCustomEvent(event, pchData, cchData));                  new CustomEvent(event, pchData, cchData));
2664    
2665          return LSCP_OK;          return LSCP_OK;
2666  }  }
# Line 2575  bool MainForm::startClient (void) Line 2705  bool MainForm::startClient (void)
2705                  .arg(::lscp_client_get_timeout(m_pClient)));                  .arg(::lscp_client_get_timeout(m_pClient)));
2706    
2707          // Subscribe to channel info change notifications...          // Subscribe to channel info change notifications...
2708            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT) != LSCP_OK)
2709                    appendMessagesClient("lscp_client_subscribe(CHANNEL_COUNT)");
2710          if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)          if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)
2711                  appendMessagesClient("lscp_client_subscribe");                  appendMessagesClient("lscp_client_subscribe(CHANNEL_INFO)");
2712    
2713            DeviceStatusForm::onDevicesChanged(); // initialize
2714            updateViewMidiDeviceStatusMenu();
2715            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT) != LSCP_OK)
2716                    appendMessagesClient("lscp_client_subscribe(MIDI_INPUT_DEVICE_COUNT)");
2717            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO) != LSCP_OK)
2718                    appendMessagesClient("lscp_client_subscribe(MIDI_INPUT_DEVICE_INFO)");
2719            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT) != LSCP_OK)
2720                    appendMessagesClient("lscp_client_subscribe(AUDIO_OUTPUT_DEVICE_COUNT)");
2721            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO) != LSCP_OK)
2722                    appendMessagesClient("lscp_client_subscribe(AUDIO_OUTPUT_DEVICE_INFO)");
2723    
2724    #if CONFIG_LSCP_CHANNEL_MIDI
2725            // Subscribe to channel MIDI data notifications...
2726            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_MIDI) != LSCP_OK)
2727                    appendMessagesClient("lscp_client_subscribe(CHANNEL_MIDI)");
2728    #endif
2729    
2730    #if CONFIG_LSCP_DEVICE_MIDI
2731            // Subscribe to channel MIDI data notifications...
2732            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_DEVICE_MIDI) != LSCP_OK)
2733                    appendMessagesClient("lscp_client_subscribe(DEVICE_MIDI)");
2734    #endif
2735    
2736          // We may stop scheduling around.          // We may stop scheduling around.
2737          stopSchedule();          stopSchedule();
# Line 2630  void MainForm::stopClient (void) Line 2785  void MainForm::stopClient (void)
2785          closeSession(false);          closeSession(false);
2786    
2787          // Close us as a client...          // Close us as a client...
2788    #if CONFIG_LSCP_DEVICE_MIDI
2789            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_DEVICE_MIDI);
2790    #endif
2791    #if CONFIG_LSCP_CHANNEL_MIDI
2792            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_MIDI);
2793    #endif
2794            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO);
2795            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT);
2796            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO);
2797            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT);
2798          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
2799            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);
2800          ::lscp_client_destroy(m_pClient);          ::lscp_client_destroy(m_pClient);
2801          m_pClient = NULL;          m_pClient = NULL;
2802    

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

  ViewVC Help
Powered by ViewVC