/[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 1738 by capela, Wed May 14 15:24:22 2008 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-2008, 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);
391  #else  #else
392          viewInstrumentsAction->setEnabled(false);          viewInstrumentsAction->setEnabled(false);
393  #endif  #endif
394            // Setup appropriately...
395            m_pMessages->setLogging(m_pOptions->bMessagesLog, m_pOptions->sMessagesLogPath);
396          // Set message defaults...          // Set message defaults...
397          updateMessagesFont();          updateMessagesFont();
398          updateMessagesLimit();          updateMessagesLimit();
# Line 470  bool MainForm::queryClose (void) Line 474  bool MainForm::queryClose (void)
474                          if (m_pDeviceForm)                          if (m_pDeviceForm)
475                                  m_pDeviceForm->close();                                  m_pDeviceForm->close();
476                          // Stop client and/or server, gracefully.                          // Stop client and/or server, gracefully.
477                          stopServer();                          stopServer(true /*interactive*/);
478                  }                  }
479          }          }
480    
# Line 480  bool MainForm::queryClose (void) Line 484  bool MainForm::queryClose (void)
484    
485  void MainForm::closeEvent ( QCloseEvent *pCloseEvent )  void MainForm::closeEvent ( QCloseEvent *pCloseEvent )
486  {  {
487          if (queryClose())          if (queryClose()) {
488                    DeviceStatusForm::deleteAllInstances();
489                  pCloseEvent->accept();                  pCloseEvent->accept();
490          else          } else
491                  pCloseEvent->ignore();                  pCloseEvent->ignore();
492  }  }
493    
# Line 511  void MainForm::dropEvent ( QDropEvent* p Line 516  void MainForm::dropEvent ( QDropEvent* p
516                  QListIterator<QUrl> iter(pMimeData->urls());                  QListIterator<QUrl> iter(pMimeData->urls());
517                  while (iter.hasNext()) {                  while (iter.hasNext()) {
518                          const QString& sPath = iter.next().toLocalFile();                          const QString& sPath = iter.next().toLocalFile();
519                          if (qsamplerChannel::isInstrumentFile(sPath)) {                          if (Channel::isInstrumentFile(sPath)) {
520                                  // Try to create a new channel from instrument file...                                  // Try to create a new channel from instrument file...
521                                  qsamplerChannel *pChannel = new qsamplerChannel();                                  Channel *pChannel = new Channel();
522                                  if (pChannel == NULL)                                  if (pChannel == NULL)
523                                          return;                                          return;
524                                  // Start setting the instrument filename...                                  // Start setting the instrument filename...
# Line 549  void MainForm::customEvent(QEvent* pCust Line 554  void MainForm::customEvent(QEvent* pCust
554  {  {
555          // For the time being, just pump it to messages.          // For the time being, just pump it to messages.
556          if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {          if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {
557                  qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;                  CustomEvent *pEvent = static_cast<CustomEvent *> (pCustomEvent);
558                  if (pEvent->event() == LSCP_EVENT_CHANNEL_INFO) {                  switch (pEvent->event()) {
559                          int iChannelID = pEvent->data().toInt();                          case LSCP_EVENT_CHANNEL_COUNT:
560                          ChannelStrip *pChannelStrip = channelStrip(iChannelID);                                  updateAllChannelStrips(true);
561                          if (pChannelStrip)                                  break;
562                                  channelStripChanged(pChannelStrip);                          case LSCP_EVENT_CHANNEL_INFO: {
563                  } else {                                  int iChannelID = pEvent->data().toInt();
564                          appendMessagesColor(tr("Notify event: %1 data: %2")                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);
565                                  .arg(::lscp_event_to_text(pEvent->event()))                                  if (pChannelStrip)
566                                  .arg(pEvent->data()), "#996699");                                          channelStripChanged(pChannelStrip);
567                                    break;
568                            }
569                            case LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT:
570                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
571                                    DeviceStatusForm::onDevicesChanged();
572                                    updateViewMidiDeviceStatusMenu();
573                                    break;
574                            case LSCP_EVENT_MIDI_INPUT_DEVICE_INFO: {
575                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
576                                    const int iDeviceID = pEvent->data().section(' ', 0, 0).toInt();
577                                    DeviceStatusForm::onDeviceChanged(iDeviceID);
578                                    break;
579                            }
580                            case LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT:
581                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
582                                    break;
583                            case LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO:
584                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
585                                    break;
586    #if CONFIG_EVENT_CHANNEL_MIDI
587                            case LSCP_EVENT_CHANNEL_MIDI: {
588                                    const int iChannelID = pEvent->data().section(' ', 0, 0).toInt();
589                                    ChannelStrip *pChannelStrip = channelStrip(iChannelID);
590                                    if (pChannelStrip)
591                                            pChannelStrip->midiArrived();
592                                    break;
593                            }
594    #endif
595    #if CONFIG_EVENT_DEVICE_MIDI
596                            case LSCP_EVENT_DEVICE_MIDI: {
597                                    const int iDeviceID = pEvent->data().section(' ', 0, 0).toInt();
598                                    const int iPortID   = pEvent->data().section(' ', 1, 1).toInt();
599                                    DeviceStatusForm* pDeviceStatusForm =
600                                            DeviceStatusForm::getInstance(iDeviceID);
601                                    if (pDeviceStatusForm)
602                                            pDeviceStatusForm->midiArrived(iPortID);
603                                    break;
604                            }
605    #endif
606                            default:
607                                    appendMessagesColor(tr("Notify event: %1 data: %2")
608                                            .arg(::lscp_event_to_text(pEvent->event()))
609                                            .arg(pEvent->data()), "#996699");
610                  }                  }
611          }          }
612  }  }
613    
614    void MainForm::updateViewMidiDeviceStatusMenu() {
615            m_ui.viewMidiDeviceStatusMenu->clear();
616            const std::map<int, DeviceStatusForm*> statusForms =
617                    DeviceStatusForm::getInstances();
618            for (
619                    std::map<int, DeviceStatusForm*>::const_iterator iter = statusForms.begin();
620                    iter != statusForms.end(); ++iter
621            ) {
622                    DeviceStatusForm* pForm = iter->second;
623                    m_ui.viewMidiDeviceStatusMenu->addAction(
624                            pForm->visibleAction()
625                    );
626            }
627    }
628    
629  // Context menu event handler.  // Context menu event handler.
630  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )
631  {  {
# Line 576  void MainForm::contextMenuEvent( QContex Line 639  void MainForm::contextMenuEvent( QContex
639  // qsamplerMainForm -- Brainless public property accessors.  // qsamplerMainForm -- Brainless public property accessors.
640    
641  // The global options settings property.  // The global options settings property.
642  qsamplerOptions *MainForm::options (void) const  Options *MainForm::options (void) const
643  {  {
644          return m_pOptions;          return m_pOptions;
645  }  }
# Line 737  bool MainForm::closeSession ( bool bForc Line 800  bool MainForm::closeSession ( bool bForc
800                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
801                          ChannelStrip *pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                          ChannelStrip *pChannelStrip = (ChannelStrip*) wlist.at(iChannel);
802                          if (pChannelStrip) {                          if (pChannelStrip) {
803                                  qsamplerChannel *pChannel = pChannelStrip->channel();                                  Channel *pChannel = pChannelStrip->channel();
804                                  if (bForce && pChannel)                                  if (bForce && pChannel)
805                                          pChannel->removeChannel();                                          pChannel->removeChannel();
806                                  delete pChannelStrip;                                  delete pChannelStrip;
# Line 877  bool MainForm::saveSessionFile ( const Q Line 940  bool MainForm::saveSessionFile ( const Q
940    
941          // Audio device mapping.          // Audio device mapping.
942          QMap<int, int> audioDeviceMap;          QMap<int, int> audioDeviceMap;
943          piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Audio);          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);
944          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
945                  ts << endl;                  ts << endl;
946                  qsamplerDevice device(qsamplerDevice::Audio, piDeviceIDs[iDevice]);                  Device device(Device::Audio, piDeviceIDs[iDevice]);
947                  // Audio device specification...                  // Audio device specification...
948                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
949                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
950                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
951                  qsamplerDeviceParamMap::ConstIterator deviceParam;                  DeviceParamMap::ConstIterator deviceParam;
952                  for (deviceParam = device.params().begin();                  for (deviceParam = device.params().begin();
953                                  deviceParam != device.params().end();                                  deviceParam != device.params().end();
954                                          ++deviceParam) {                                          ++deviceParam) {
955                          const qsamplerDeviceParam& param = deviceParam.value();                          const DeviceParam& param = deviceParam.value();
956                          if (param.value.isEmpty()) ts << "# ";                          if (param.value.isEmpty()) ts << "# ";
957                          ts << " " << deviceParam.key() << "='" << param.value << "'";                          ts << " " << deviceParam.key() << "='" << param.value << "'";
958                  }                  }
959                  ts << endl;                  ts << endl;
960                  // Audio channel parameters...                  // Audio channel parameters...
961                  int iPort = 0;                  int iPort = 0;
962                  QListIterator<qsamplerDevicePort *> iter(device.ports());                  QListIterator<DevicePort *> iter(device.ports());
963                  while (iter.hasNext()) {                  while (iter.hasNext()) {
964                          qsamplerDevicePort *pPort = iter.next();                          DevicePort *pPort = iter.next();
965                          qsamplerDeviceParamMap::ConstIterator portParam;                          DeviceParamMap::ConstIterator portParam;
966                          for (portParam = pPort->params().begin();                          for (portParam = pPort->params().begin();
967                                          portParam != pPort->params().end();                                          portParam != pPort->params().end();
968                                                  ++portParam) {                                                  ++portParam) {
969                                  const qsamplerDeviceParam& param = portParam.value();                                  const DeviceParam& param = portParam.value();
970                                  if (param.fix || param.value.isEmpty()) ts << "# ";                                  if (param.fix || param.value.isEmpty()) ts << "# ";
971                                  ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice                                  ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice
972                                          << " " << iPort << " " << portParam.key()                                          << " " << iPort << " " << portParam.key()
# Line 919  bool MainForm::saveSessionFile ( const Q Line 982  bool MainForm::saveSessionFile ( const Q
982    
983          // MIDI device mapping.          // MIDI device mapping.
984          QMap<int, int> midiDeviceMap;          QMap<int, int> midiDeviceMap;
985          piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Midi);          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);
986          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
987                  ts << endl;                  ts << endl;
988                  qsamplerDevice device(qsamplerDevice::Midi, piDeviceIDs[iDevice]);                  Device device(Device::Midi, piDeviceIDs[iDevice]);
989                  // MIDI device specification...                  // MIDI device specification...
990                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
991                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
992                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
993                  qsamplerDeviceParamMap::ConstIterator deviceParam;                  DeviceParamMap::ConstIterator deviceParam;
994                  for (deviceParam = device.params().begin();                  for (deviceParam = device.params().begin();
995                                  deviceParam != device.params().end();                                  deviceParam != device.params().end();
996                                          ++deviceParam) {                                          ++deviceParam) {
997                          const qsamplerDeviceParam& param = deviceParam.value();                          const DeviceParam& param = deviceParam.value();
998                          if (param.value.isEmpty()) ts << "# ";                          if (param.value.isEmpty()) ts << "# ";
999                          ts << " " << deviceParam.key() << "='" << param.value << "'";                          ts << " " << deviceParam.key() << "='" << param.value << "'";
1000                  }                  }
1001                  ts << endl;                  ts << endl;
1002                  // MIDI port parameters...                  // MIDI port parameters...
1003                  int iPort = 0;                  int iPort = 0;
1004                  QListIterator<qsamplerDevicePort *> iter(device.ports());                  QListIterator<DevicePort *> iter(device.ports());
1005                  while (iter.hasNext()) {                  while (iter.hasNext()) {
1006                          qsamplerDevicePort *pPort = iter.next();                          DevicePort *pPort = iter.next();
1007                          qsamplerDeviceParamMap::ConstIterator portParam;                          DeviceParamMap::ConstIterator portParam;
1008                          for (portParam = pPort->params().begin();                          for (portParam = pPort->params().begin();
1009                                          portParam != pPort->params().end();                                          portParam != pPort->params().end();
1010                                                  ++portParam) {                                                  ++portParam) {
1011                                  const qsamplerDeviceParam& param = portParam.value();                                  const DeviceParam& param = portParam.value();
1012                                  if (param.fix || param.value.isEmpty()) ts << "# ";                                  if (param.fix || param.value.isEmpty()) ts << "# ";
1013                                  ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice                                  ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice
1014                                  << " " << iPort << " " << portParam.key()                                  << " " << iPort << " " << portParam.key()
# Line 1037  bool MainForm::saveSessionFile ( const Q Line 1100  bool MainForm::saveSessionFile ( const Q
1100                  ChannelStrip* pChannelStrip                  ChannelStrip* pChannelStrip
1101                          = static_cast<ChannelStrip *> (wlist.at(iChannel));                          = static_cast<ChannelStrip *> (wlist.at(iChannel));
1102                  if (pChannelStrip) {                  if (pChannelStrip) {
1103                          qsamplerChannel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1104                          if (pChannel) {                          if (pChannel) {
1105                                  ts << "# " << tr("Channel") << " " << iChannel << endl;                                  ts << "# " << tr("Channel") << " " << iChannel << endl;
1106                                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
# Line 1069  bool MainForm::saveSessionFile ( const Q Line 1132  bool MainForm::saveSessionFile ( const Q
1132                                  ts << "LOAD INSTRUMENT NON_MODAL '"                                  ts << "LOAD INSTRUMENT NON_MODAL '"
1133                                          << pChannel->instrumentFile() << "' "                                          << pChannel->instrumentFile() << "' "
1134                                          << pChannel->instrumentNr() << " " << iChannel << endl;                                          << pChannel->instrumentNr() << " " << iChannel << endl;
1135                                  qsamplerChannelRoutingMap::ConstIterator audioRoute;                                  ChannelRoutingMap::ConstIterator audioRoute;
1136                                  for (audioRoute = pChannel->audioRouting().begin();                                  for (audioRoute = pChannel->audioRouting().begin();
1137                                                  audioRoute != pChannel->audioRouting().end();                                                  audioRoute != pChannel->audioRouting().end();
1138                                                          ++audioRoute) {                                                          ++audioRoute) {
# Line 1314  void MainForm::editAddChannel (void) Line 1377  void MainForm::editAddChannel (void)
1377                  return;                  return;
1378    
1379          // Just create the channel instance...          // Just create the channel instance...
1380          qsamplerChannel *pChannel = new qsamplerChannel();          Channel *pChannel = new Channel();
1381          if (pChannel == NULL)          if (pChannel == NULL)
1382                  return;                  return;
1383    
# Line 1352  void MainForm::editRemoveChannel (void) Line 1415  void MainForm::editRemoveChannel (void)
1415          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1416                  return;                  return;
1417    
1418          qsamplerChannel *pChannel = pChannelStrip->channel();          Channel *pChannel = pChannelStrip->channel();
1419          if (pChannel == NULL)          if (pChannel == NULL)
1420                  return;                  return;
1421    
# Line 1555  void MainForm::viewOptions (void) Line 1618  void MainForm::viewOptions (void)
1618                  int     iOldServerTimeout   = m_pOptions->iServerTimeout;                  int     iOldServerTimeout   = m_pOptions->iServerTimeout;
1619                  bool    bOldServerStart     = m_pOptions->bServerStart;                  bool    bOldServerStart     = m_pOptions->bServerStart;
1620                  QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;                  QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;
1621                    bool    bOldMessagesLog     = m_pOptions->bMessagesLog;
1622                    QString sOldMessagesLogPath = m_pOptions->sMessagesLogPath;
1623                  QString sOldDisplayFont     = m_pOptions->sDisplayFont;                  QString sOldDisplayFont     = m_pOptions->sDisplayFont;
1624                  bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;                  bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1625                  int     iOldMaxVolume       = m_pOptions->iMaxVolume;                  int     iOldMaxVolume       = m_pOptions->iMaxVolume;
# Line 1582  void MainForm::viewOptions (void) Line 1647  void MainForm::viewOptions (void)
1647                                  updateMessagesCapture();                                  updateMessagesCapture();
1648                          }                          }
1649                          // Check wheather something immediate has changed.                          // Check wheather something immediate has changed.
1650                            if (( bOldMessagesLog && !m_pOptions->bMessagesLog) ||
1651                                    (!bOldMessagesLog &&  m_pOptions->bMessagesLog) ||
1652                                    (sOldMessagesLogPath != m_pOptions->sMessagesLogPath))
1653                                    m_pMessages->setLogging(
1654                                            m_pOptions->bMessagesLog, m_pOptions->sMessagesLogPath);
1655                          if (( bOldCompletePath && !m_pOptions->bCompletePath) ||                          if (( bOldCompletePath && !m_pOptions->bCompletePath) ||
1656                                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||                                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||
1657                                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))                                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))
# Line 1910  void MainForm::updateSession (void) Line 1980  void MainForm::updateSession (void)
1980          }          }
1981  #endif  #endif
1982    
1983            updateAllChannelStrips(false);
1984    
1985            // Do we auto-arrange?
1986            if (m_pOptions && m_pOptions->bAutoArrange)
1987                    channelsArrange();
1988    
1989            // Remember to refresh devices and instruments...
1990            if (m_pInstrumentListForm)
1991                    m_pInstrumentListForm->refreshInstruments();
1992            if (m_pDeviceForm)
1993                    m_pDeviceForm->refreshDevices();
1994    }
1995    
1996    void MainForm::updateAllChannelStrips(bool bRemoveDeadStrips) {
1997          // Retrieve the current channel list.          // Retrieve the current channel list.
1998          int *piChannelIDs = ::lscp_list_channels(m_pClient);          int *piChannelIDs = ::lscp_list_channels(m_pClient);
1999          if (piChannelIDs == NULL) {          if (piChannelIDs == NULL) {
# Line 1924  void MainForm::updateSession (void) Line 2008  void MainForm::updateSession (void)
2008                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {
2009                          // Check if theres already a channel strip for this one...                          // Check if theres already a channel strip for this one...
2010                          if (!channelStrip(piChannelIDs[iChannel]))                          if (!channelStrip(piChannelIDs[iChannel]))
2011                                  createChannelStrip(new qsamplerChannel(piChannelIDs[iChannel]));                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));
2012                  }                  }
                 m_pWorkspace->setUpdatesEnabled(true);  
         }  
2013    
2014          // Do we auto-arrange?                  // Do we auto-arrange?
2015          if (m_pOptions && m_pOptions->bAutoArrange)                  if (m_pOptions && m_pOptions->bAutoArrange)
2016                  channelsArrange();                          channelsArrange();
2017    
2018          // Remember to refresh devices and instruments...                  stabilizeForm();
         if (m_pInstrumentListForm)  
                 m_pInstrumentListForm->refreshInstruments();  
         if (m_pDeviceForm)  
                 m_pDeviceForm->refreshDevices();  
 }  
2019    
2020                    // remove dead channel strips
2021                    if (bRemoveDeadStrips) {
2022                            for (int i = 0; channelStripAt(i); ++i) {
2023                                    ChannelStrip* pChannelStrip = channelStripAt(i);
2024                                    bool bExists = false;
2025                                    for (int j = 0; piChannelIDs[j] >= 0; ++j) {
2026                                            if (!pChannelStrip->channel()) break;
2027                                            if (piChannelIDs[j] == pChannelStrip->channel()->channelID()) {
2028                                                    // strip exists, don't touch it
2029                                                    bExists = true;
2030                                                    break;
2031                                            }
2032                                    }
2033                                    if (!bExists) destroyChannelStrip(pChannelStrip);
2034                            }
2035                    }
2036                    m_pWorkspace->setUpdatesEnabled(true);
2037            }
2038    }
2039    
2040  // Update the recent files list and menu.  // Update the recent files list and menu.
2041  void MainForm::updateRecentFiles ( const QString& sFilename )  void MainForm::updateRecentFiles ( const QString& sFilename )
# Line 2176  void MainForm::updateMessagesCapture (vo Line 2272  void MainForm::updateMessagesCapture (vo
2272  // qsamplerMainForm -- MDI channel strip management.  // qsamplerMainForm -- MDI channel strip management.
2273    
2274  // The channel strip creation executive.  // The channel strip creation executive.
2275  ChannelStrip* MainForm::createChannelStrip ( qsamplerChannel *pChannel )  ChannelStrip* MainForm::createChannelStrip ( Channel *pChannel )
2276  {  {
2277          if (m_pClient == NULL || pChannel == NULL)          if (m_pClient == NULL || pChannel == NULL)
2278                  return NULL;                  return NULL;
# Line 2218  ChannelStrip* MainForm::createChannelStr Line 2314  ChannelStrip* MainForm::createChannelStr
2314          return pChannelStrip;          return pChannelStrip;
2315  }  }
2316    
2317    void MainForm::destroyChannelStrip(ChannelStrip* pChannelStrip) {
2318            // Just delete the channel strip.
2319            delete pChannelStrip;
2320    
2321            // Do we auto-arrange?
2322            if (m_pOptions && m_pOptions->bAutoArrange)
2323                    channelsArrange();
2324    
2325            stabilizeForm();
2326    }
2327    
2328  // Retrieve the active channel strip.  // Retrieve the active channel strip.
2329  ChannelStrip* MainForm::activeChannelStrip (void)  ChannelStrip* MainForm::activeChannelStrip (void)
# Line 2229  ChannelStrip* MainForm::activeChannelStr Line 2335  ChannelStrip* MainForm::activeChannelStr
2335  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2336  ChannelStrip* MainForm::channelStripAt ( int iChannel )  ChannelStrip* MainForm::channelStripAt ( int iChannel )
2337  {  {
2338            if (!m_pWorkspace) return NULL;
2339    
2340          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
2341          if (wlist.isEmpty())          if (wlist.isEmpty())
2342                  return NULL;                  return NULL;
2343    
2344          return static_cast<ChannelStrip *> (wlist.at(iChannel));          if (iChannel < 0 || iChannel >= wlist.size())
2345                    return NULL;
2346    
2347            return dynamic_cast<ChannelStrip *> (wlist.at(iChannel));
2348  }  }
2349    
2350    
# Line 2248  ChannelStrip* MainForm::channelStrip ( i Line 2359  ChannelStrip* MainForm::channelStrip ( i
2359                  ChannelStrip* pChannelStrip                  ChannelStrip* pChannelStrip
2360                          = static_cast<ChannelStrip*> (wlist.at(iChannel));                          = static_cast<ChannelStrip*> (wlist.at(iChannel));
2361                  if (pChannelStrip) {                  if (pChannelStrip) {
2362                          qsamplerChannel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
2363                          if (pChannel && pChannel->channelID() == iChannelID)                          if (pChannel && pChannel->channelID() == iChannelID)
2364                                  return pChannelStrip;                                  return pChannelStrip;
2365                  }                  }
# Line 2389  void MainForm::startServer (void) Line 2500  void MainForm::startServer (void)
2500                  switch (QMessageBox::warning(this,                  switch (QMessageBox::warning(this,
2501                          QSAMPLER_TITLE ": " + tr("Warning"),                          QSAMPLER_TITLE ": " + tr("Warning"),
2502                          tr("Could not start the LinuxSampler server.\n\n"                          tr("Could not start the LinuxSampler server.\n\n"
2503                          "Maybe it ss already started."),                          "Maybe it is already started."),
2504                          tr("Stop"), tr("Kill"), tr("Cancel"))) {                          tr("Stop"), tr("Kill"), tr("Cancel"))) {
2505                  case 0:                  case 0:
2506                          m_pServer->terminate();                          m_pServer->terminate();
# Line 2409  void MainForm::startServer (void) Line 2520  void MainForm::startServer (void)
2520                  return;                  return;
2521    
2522          // OK. Let's build the startup process...          // OK. Let's build the startup process...
2523          m_pServer = new QProcess(this);          m_pServer = new QProcess();
2524            bForceServerStop = true;
2525    
2526          // Setup stdout/stderr capture...          // Setup stdout/stderr capture...
2527  //      if (m_pOptions->bStdoutCapture) {  //      if (m_pOptions->bStdoutCapture) {
2528                  //m_pServer->setProcessChannelMode(  #if QT_VERSION >= 0x040200
2529                  //      QProcess::StandardOutput);                  m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);
2530    #endif
2531                  QObject::connect(m_pServer,                  QObject::connect(m_pServer,
2532                          SIGNAL(readyReadStandardOutput()),                          SIGNAL(readyReadStandardOutput()),
2533                          SLOT(readServerStdout()));                          SLOT(readServerStdout()));
# Line 2425  void MainForm::startServer (void) Line 2538  void MainForm::startServer (void)
2538    
2539          // The unforgiveable signal communication...          // The unforgiveable signal communication...
2540          QObject::connect(m_pServer,          QObject::connect(m_pServer,
2541                  SIGNAL(finished(int,QProcess::ExitStatus)),                  SIGNAL(finished(int, QProcess::ExitStatus)),
2542                  SLOT(processServerExit()));                  SLOT(processServerExit()));
2543    
2544          // Build process arguments...          // Build process arguments...
# Line 2456  void MainForm::startServer (void) Line 2569  void MainForm::startServer (void)
2569    
2570    
2571  // Stop linuxsampler server...  // Stop linuxsampler server...
2572  void MainForm::stopServer (void)  void MainForm::stopServer (bool bInteractive)
2573  {  {
2574          // Stop client code.          // Stop client code.
2575          stopClient();          stopClient();
2576    
2577            if (m_pServer && bInteractive) {
2578                    if (QMessageBox::question(this,
2579                            QSAMPLER_TITLE ": " + tr("The backend's fate ..."),
2580                            tr("You have the option to keep the sampler backend (LinuxSampler)\n"
2581                            "running in the background. The sampler would continue to work\n"
2582                            "according to your current sampler session and you could alter the\n"
2583                            "sampler session at any time by relaunching QSampler.\n\n"
2584                            "Do you want LinuxSampler to stop or to keep running in\n"
2585                            "the background?"),
2586                            tr("Stop"), tr("Keep Running")) == 1)
2587                    {
2588                            bForceServerStop = false;
2589                    }
2590            }
2591    
2592          // And try to stop server.          // And try to stop server.
2593          if (m_pServer) {          if (m_pServer && bForceServerStop) {
2594                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2595                  if (m_pServer->state() == QProcess::Running)                  if (m_pServer->state() == QProcess::Running) {
2596    #if defined(WIN32)
2597                            // Try harder...
2598                            m_pServer->kill();
2599    #else
2600                            // Try softly...
2601                          m_pServer->terminate();                          m_pServer->terminate();
2602          }  #endif
2603                    }
2604            }       // Do final processing anyway.
2605            else processServerExit();
2606    
2607          // Give it some time to terminate gracefully and stabilize...          // Give it some time to terminate gracefully and stabilize...
2608          QTime t;          QTime t;
2609          t.start();          t.start();
2610          while (t.elapsed() < QSAMPLER_TIMER_MSECS)          while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2611                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
   
         // Do final processing anyway.  
         processServerExit();  
2612  }  }
2613    
2614    
# Line 2497  void MainForm::processServerExit (void) Line 2630  void MainForm::processServerExit (void)
2630          if (m_pMessages)          if (m_pMessages)
2631                  m_pMessages->flushStdoutBuffer();                  m_pMessages->flushStdoutBuffer();
2632    
2633          if (m_pServer) {          if (m_pServer && bForceServerStop) {
2634                    if (m_pServer->state() != QProcess::NotRunning) {
2635                            appendMessages(tr("Server is being forced..."));
2636                            // Force final server shutdown...
2637                            m_pServer->kill();
2638                            // Give it some time to terminate gracefully and stabilize...
2639                            QTime t;
2640                            t.start();
2641                            while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2642                                    QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2643                    }
2644                  // Force final server shutdown...                  // Force final server shutdown...
2645                  appendMessages(                  appendMessages(
2646                          tr("Server was stopped with exit status %1.")                          tr("Server was stopped with exit status %1.")
2647                          .arg(m_pServer->exitStatus()));                          .arg(m_pServer->exitStatus()));
                 m_pServer->terminate();  
                 if (!m_pServer->waitForFinished(2000))  
                         m_pServer->kill();  
                 // Destroy it.  
2648                  delete m_pServer;                  delete m_pServer;
2649                  m_pServer = NULL;                  m_pServer = NULL;
2650          }          }
# Line 2530  lscp_status_t qsampler_client_callback ( Line 2669  lscp_status_t qsampler_client_callback (
2669          // as this is run under some other thread context.          // as this is run under some other thread context.
2670          // A custom event must be posted here...          // A custom event must be posted here...
2671          QApplication::postEvent(pMainForm,          QApplication::postEvent(pMainForm,
2672                  new qsamplerCustomEvent(event, pchData, cchData));                  new CustomEvent(event, pchData, cchData));
2673    
2674          return LSCP_OK;          return LSCP_OK;
2675  }  }
# Line 2575  bool MainForm::startClient (void) Line 2714  bool MainForm::startClient (void)
2714                  .arg(::lscp_client_get_timeout(m_pClient)));                  .arg(::lscp_client_get_timeout(m_pClient)));
2715    
2716          // Subscribe to channel info change notifications...          // Subscribe to channel info change notifications...
2717            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT) != LSCP_OK)
2718                    appendMessagesClient("lscp_client_subscribe(CHANNEL_COUNT)");
2719          if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)          if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)
2720                  appendMessagesClient("lscp_client_subscribe");                  appendMessagesClient("lscp_client_subscribe(CHANNEL_INFO)");
2721    
2722            DeviceStatusForm::onDevicesChanged(); // initialize
2723            updateViewMidiDeviceStatusMenu();
2724            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT) != LSCP_OK)
2725                    appendMessagesClient("lscp_client_subscribe(MIDI_INPUT_DEVICE_COUNT)");
2726            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO) != LSCP_OK)
2727                    appendMessagesClient("lscp_client_subscribe(MIDI_INPUT_DEVICE_INFO)");
2728            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT) != LSCP_OK)
2729                    appendMessagesClient("lscp_client_subscribe(AUDIO_OUTPUT_DEVICE_COUNT)");
2730            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO) != LSCP_OK)
2731                    appendMessagesClient("lscp_client_subscribe(AUDIO_OUTPUT_DEVICE_INFO)");
2732    
2733    #if CONFIG_EVENT_CHANNEL_MIDI
2734            // Subscribe to channel MIDI data notifications...
2735            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_MIDI) != LSCP_OK)
2736                    appendMessagesClient("lscp_client_subscribe(CHANNEL_MIDI)");
2737    #endif
2738    
2739    #if CONFIG_EVENT_DEVICE_MIDI
2740            // Subscribe to channel MIDI data notifications...
2741            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_DEVICE_MIDI) != LSCP_OK)
2742                    appendMessagesClient("lscp_client_subscribe(DEVICE_MIDI)");
2743    #endif
2744    
2745          // We may stop scheduling around.          // We may stop scheduling around.
2746          stopSchedule();          stopSchedule();
# Line 2630  void MainForm::stopClient (void) Line 2794  void MainForm::stopClient (void)
2794          closeSession(false);          closeSession(false);
2795    
2796          // Close us as a client...          // Close us as a client...
2797    #if CONFIG_EVENT_DEVICE_MIDI
2798            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_DEVICE_MIDI);
2799    #endif
2800    #if CONFIG_EVENT_CHANNEL_MIDI
2801            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_MIDI);
2802    #endif
2803            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO);
2804            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT);
2805            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO);
2806            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT);
2807          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
2808            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);
2809          ::lscp_client_destroy(m_pClient);          ::lscp_client_destroy(m_pClient);
2810          m_pClient = NULL;          m_pClient = NULL;
2811    

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

  ViewVC Help
Powered by ViewVC