/[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 1513 by capela, Fri Nov 23 09:32:06 2007 UTC revision 1699 by schoenebeck, Sun Feb 17 10:46:17 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 171  MainForm::MainForm ( QWidget *pParent ) Line 173  MainForm::MainForm ( QWidget *pParent )
173          // Volume slider...          // Volume slider...
174          m_ui.channelsToolbar->addSeparator();          m_ui.channelsToolbar->addSeparator();
175          m_pVolumeSlider = new QSlider(Qt::Horizontal, m_ui.channelsToolbar);          m_pVolumeSlider = new QSlider(Qt::Horizontal, m_ui.channelsToolbar);
176          m_pVolumeSlider->setTickPosition(QSlider::TicksBelow);          m_pVolumeSlider->setTickPosition(QSlider::TicksBothSides);
177          m_pVolumeSlider->setTickInterval(10);          m_pVolumeSlider->setTickInterval(10);
178          m_pVolumeSlider->setPageStep(10);          m_pVolumeSlider->setPageStep(10);
179          m_pVolumeSlider->setSingleStep(10);          m_pVolumeSlider->setSingleStep(10);
# Line 189  MainForm::MainForm ( QWidget *pParent ) Line 191  MainForm::MainForm ( QWidget *pParent )
191          // Volume spin-box          // Volume spin-box
192          m_ui.channelsToolbar->addSeparator();          m_ui.channelsToolbar->addSeparator();
193          m_pVolumeSpinBox = new QSpinBox(m_ui.channelsToolbar);          m_pVolumeSpinBox = new QSpinBox(m_ui.channelsToolbar);
194            m_pVolumeSpinBox->setMaximumHeight(24);
195          m_pVolumeSpinBox->setSuffix(" %");          m_pVolumeSpinBox->setSuffix(" %");
196          m_pVolumeSpinBox->setMinimum(0);          m_pVolumeSpinBox->setMinimum(0);
197          m_pVolumeSpinBox->setMaximum(100);          m_pVolumeSpinBox->setMaximum(100);
# Line 205  MainForm::MainForm ( QWidget *pParent ) Line 208  MainForm::MainForm ( QWidget *pParent )
208          // Set the activation connection.          // Set the activation connection.
209          QObject::connect(m_pWorkspace,          QObject::connect(m_pWorkspace,
210                  SIGNAL(windowActivated(QWidget *)),                  SIGNAL(windowActivated(QWidget *)),
211                  SLOT(stabilizeForm()));                  SLOT(activateStrip(QWidget *)));
212          // Make it shine :-)          // Make it shine :-)
213          setCentralWidget(m_pWorkspace);          setCentralWidget(m_pWorkspace);
214    
# Line 365  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 381  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 469  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 479  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 510  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 548  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_INFO: {
558                          ChannelStrip *pChannelStrip = channelStrip(iChannelID);                                  int iChannelID = pEvent->data().toInt();
559                          if (pChannelStrip)                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);
560                                  channelStripChanged(pChannelStrip);                                  if (pChannelStrip)
561                  } else {                                          channelStripChanged(pChannelStrip);
562                          appendMessagesColor(tr("Notify event: %1 data: %2")                                  break;
563                                  .arg(::lscp_event_to_text(pEvent->event()))                          }
564                                  .arg(pEvent->data()), "#996699");                          case LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT:
565                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
566                                    DeviceStatusForm::onDevicesChanged();
567                                    updateViewMidiDeviceStatusMenu();
568                                    break;
569                            case LSCP_EVENT_MIDI_INPUT_DEVICE_INFO: {
570                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
571                                    const int iDeviceID = pEvent->data().section(' ', 0, 0).toInt();
572                                    DeviceStatusForm::onDeviceChanged(iDeviceID);
573                                    break;
574                            }
575    #if CONFIG_LSCP_CHANNEL_MIDI
576                            case LSCP_EVENT_CHANNEL_MIDI: {
577                                    const int iChannelID = pEvent->data().section(' ', 0, 0).toInt();
578                                    ChannelStrip *pChannelStrip = channelStrip(iChannelID);
579                                    if (pChannelStrip)
580                                            pChannelStrip->midiArrived();
581                                    break;
582                            }
583    #endif
584    #if CONFIG_LSCP_DEVICE_MIDI
585                            case LSCP_EVENT_DEVICE_MIDI: {
586                                    const int iDeviceID = pEvent->data().section(' ', 0, 0).toInt();
587                                    const int iPortID   = pEvent->data().section(' ', 1, 1).toInt();
588                                    DeviceStatusForm* pDeviceStatusForm =
589                                            DeviceStatusForm::getInstance(iDeviceID);
590                                    if (pDeviceStatusForm)
591                                            pDeviceStatusForm->midiArrived(iPortID);
592                                    break;
593                            }
594    #endif
595                            default:
596                                    appendMessagesColor(tr("Notify event: %1 data: %2")
597                                            .arg(::lscp_event_to_text(pEvent->event()))
598                                            .arg(pEvent->data()), "#996699");
599                  }                  }
600          }          }
601  }  }
602    
603    void MainForm::updateViewMidiDeviceStatusMenu() {
604            m_ui.viewMidiDeviceStatusMenu->clear();
605            const std::map<int, DeviceStatusForm*> statusForms =
606                    DeviceStatusForm::getInstances();
607            for (
608                    std::map<int, DeviceStatusForm*>::const_iterator iter = statusForms.begin();
609                    iter != statusForms.end(); ++iter
610            ) {
611                    DeviceStatusForm* pForm = iter->second;
612                    m_ui.viewMidiDeviceStatusMenu->addAction(
613                            pForm->visibleAction()
614                    );
615            }
616    }
617    
618  // Context menu event handler.  // Context menu event handler.
619  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )
620  {  {
# Line 575  void MainForm::contextMenuEvent( QContex Line 628  void MainForm::contextMenuEvent( QContex
628  // qsamplerMainForm -- Brainless public property accessors.  // qsamplerMainForm -- Brainless public property accessors.
629    
630  // The global options settings property.  // The global options settings property.
631  qsamplerOptions *MainForm::options (void) const  Options *MainForm::options (void) const
632  {  {
633          return m_pOptions;          return m_pOptions;
634  }  }
# Line 736  bool MainForm::closeSession ( bool bForc Line 789  bool MainForm::closeSession ( bool bForc
789                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
790                          ChannelStrip *pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                          ChannelStrip *pChannelStrip = (ChannelStrip*) wlist.at(iChannel);
791                          if (pChannelStrip) {                          if (pChannelStrip) {
792                                  qsamplerChannel *pChannel = pChannelStrip->channel();                                  Channel *pChannel = pChannelStrip->channel();
793                                  if (bForce && pChannel)                                  if (bForce && pChannel)
794                                          pChannel->removeChannel();                                          pChannel->removeChannel();
795                                  delete pChannelStrip;                                  delete pChannelStrip;
# Line 876  bool MainForm::saveSessionFile ( const Q Line 929  bool MainForm::saveSessionFile ( const Q
929    
930          // Audio device mapping.          // Audio device mapping.
931          QMap<int, int> audioDeviceMap;          QMap<int, int> audioDeviceMap;
932          piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Audio);          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);
933          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
934                  ts << endl;                  ts << endl;
935                  qsamplerDevice device(qsamplerDevice::Audio, piDeviceIDs[iDevice]);                  Device device(Device::Audio, piDeviceIDs[iDevice]);
936                  // Audio device specification...                  // Audio device specification...
937                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
938                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
939                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
940                  qsamplerDeviceParamMap::ConstIterator deviceParam;                  DeviceParamMap::ConstIterator deviceParam;
941                  for (deviceParam = device.params().begin();                  for (deviceParam = device.params().begin();
942                                  deviceParam != device.params().end();                                  deviceParam != device.params().end();
943                                          ++deviceParam) {                                          ++deviceParam) {
944                          const qsamplerDeviceParam& param = deviceParam.value();                          const DeviceParam& param = deviceParam.value();
945                          if (param.value.isEmpty()) ts << "# ";                          if (param.value.isEmpty()) ts << "# ";
946                          ts << " " << deviceParam.key() << "='" << param.value << "'";                          ts << " " << deviceParam.key() << "='" << param.value << "'";
947                  }                  }
948                  ts << endl;                  ts << endl;
949                  // Audio channel parameters...                  // Audio channel parameters...
950                  int iPort = 0;                  int iPort = 0;
951                  QListIterator<qsamplerDevicePort *> iter(device.ports());                  QListIterator<DevicePort *> iter(device.ports());
952                  while (iter.hasNext()) {                  while (iter.hasNext()) {
953                          qsamplerDevicePort *pPort = iter.next();                          DevicePort *pPort = iter.next();
954                          qsamplerDeviceParamMap::ConstIterator portParam;                          DeviceParamMap::ConstIterator portParam;
955                          for (portParam = pPort->params().begin();                          for (portParam = pPort->params().begin();
956                                          portParam != pPort->params().end();                                          portParam != pPort->params().end();
957                                                  ++portParam) {                                                  ++portParam) {
958                                  const qsamplerDeviceParam& param = portParam.value();                                  const DeviceParam& param = portParam.value();
959                                  if (param.fix || param.value.isEmpty()) ts << "# ";                                  if (param.fix || param.value.isEmpty()) ts << "# ";
960                                  ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice                                  ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice
961                                          << " " << iPort << " " << portParam.key()                                          << " " << iPort << " " << portParam.key()
# Line 918  bool MainForm::saveSessionFile ( const Q Line 971  bool MainForm::saveSessionFile ( const Q
971    
972          // MIDI device mapping.          // MIDI device mapping.
973          QMap<int, int> midiDeviceMap;          QMap<int, int> midiDeviceMap;
974          piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Midi);          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);
975          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
976                  ts << endl;                  ts << endl;
977                  qsamplerDevice device(qsamplerDevice::Midi, piDeviceIDs[iDevice]);                  Device device(Device::Midi, piDeviceIDs[iDevice]);
978                  // MIDI device specification...                  // MIDI device specification...
979                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
980                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
981                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
982                  qsamplerDeviceParamMap::ConstIterator deviceParam;                  DeviceParamMap::ConstIterator deviceParam;
983                  for (deviceParam = device.params().begin();                  for (deviceParam = device.params().begin();
984                                  deviceParam != device.params().end();                                  deviceParam != device.params().end();
985                                          ++deviceParam) {                                          ++deviceParam) {
986                          const qsamplerDeviceParam& param = deviceParam.value();                          const DeviceParam& param = deviceParam.value();
987                          if (param.value.isEmpty()) ts << "# ";                          if (param.value.isEmpty()) ts << "# ";
988                          ts << " " << deviceParam.key() << "='" << param.value << "'";                          ts << " " << deviceParam.key() << "='" << param.value << "'";
989                  }                  }
990                  ts << endl;                  ts << endl;
991                  // MIDI port parameters...                  // MIDI port parameters...
992                  int iPort = 0;                  int iPort = 0;
993                  QListIterator<qsamplerDevicePort *> iter(device.ports());                  QListIterator<DevicePort *> iter(device.ports());
994                  while (iter.hasNext()) {                  while (iter.hasNext()) {
995                          qsamplerDevicePort *pPort = iter.next();                          DevicePort *pPort = iter.next();
996                          qsamplerDeviceParamMap::ConstIterator portParam;                          DeviceParamMap::ConstIterator portParam;
997                          for (portParam = pPort->params().begin();                          for (portParam = pPort->params().begin();
998                                          portParam != pPort->params().end();                                          portParam != pPort->params().end();
999                                                  ++portParam) {                                                  ++portParam) {
1000                                  const qsamplerDeviceParam& param = portParam.value();                                  const DeviceParam& param = portParam.value();
1001                                  if (param.fix || param.value.isEmpty()) ts << "# ";                                  if (param.fix || param.value.isEmpty()) ts << "# ";
1002                                  ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice                                  ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice
1003                                  << " " << iPort << " " << portParam.key()                                  << " " << iPort << " " << portParam.key()
# Line 1036  bool MainForm::saveSessionFile ( const Q Line 1089  bool MainForm::saveSessionFile ( const Q
1089                  ChannelStrip* pChannelStrip                  ChannelStrip* pChannelStrip
1090                          = static_cast<ChannelStrip *> (wlist.at(iChannel));                          = static_cast<ChannelStrip *> (wlist.at(iChannel));
1091                  if (pChannelStrip) {                  if (pChannelStrip) {
1092                          qsamplerChannel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1093                          if (pChannel) {                          if (pChannel) {
1094                                  ts << "# " << tr("Channel") << " " << iChannel << endl;                                  ts << "# " << tr("Channel") << " " << iChannel << endl;
1095                                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
# Line 1068  bool MainForm::saveSessionFile ( const Q Line 1121  bool MainForm::saveSessionFile ( const Q
1121                                  ts << "LOAD INSTRUMENT NON_MODAL '"                                  ts << "LOAD INSTRUMENT NON_MODAL '"
1122                                          << pChannel->instrumentFile() << "' "                                          << pChannel->instrumentFile() << "' "
1123                                          << pChannel->instrumentNr() << " " << iChannel << endl;                                          << pChannel->instrumentNr() << " " << iChannel << endl;
1124                                  qsamplerChannelRoutingMap::ConstIterator audioRoute;                                  ChannelRoutingMap::ConstIterator audioRoute;
1125                                  for (audioRoute = pChannel->audioRouting().begin();                                  for (audioRoute = pChannel->audioRouting().begin();
1126                                                  audioRoute != pChannel->audioRouting().end();                                                  audioRoute != pChannel->audioRouting().end();
1127                                                          ++audioRoute) {                                                          ++audioRoute) {
# Line 1313  void MainForm::editAddChannel (void) Line 1366  void MainForm::editAddChannel (void)
1366                  return;                  return;
1367    
1368          // Just create the channel instance...          // Just create the channel instance...
1369          qsamplerChannel *pChannel = new qsamplerChannel();          Channel *pChannel = new Channel();
1370          if (pChannel == NULL)          if (pChannel == NULL)
1371                  return;                  return;
1372    
# Line 1331  void MainForm::editAddChannel (void) Line 1384  void MainForm::editAddChannel (void)
1384                  return;                  return;
1385          }          }
1386    
1387            // Do we auto-arrange?
1388            if (m_pOptions && m_pOptions->bAutoArrange)
1389                    channelsArrange();
1390    
1391          // Make that an overall update.          // Make that an overall update.
1392          m_iDirtyCount++;          m_iDirtyCount++;
1393          stabilizeForm();          stabilizeForm();
# Line 1347  void MainForm::editRemoveChannel (void) Line 1404  void MainForm::editRemoveChannel (void)
1404          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1405                  return;                  return;
1406    
1407          qsamplerChannel *pChannel = pChannelStrip->channel();          Channel *pChannel = pChannelStrip->channel();
1408          if (pChannel == NULL)          if (pChannel == NULL)
1409                  return;                  return;
1410    
# Line 1919  void MainForm::updateSession (void) Line 1976  void MainForm::updateSession (void)
1976                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {
1977                          // Check if theres already a channel strip for this one...                          // Check if theres already a channel strip for this one...
1978                          if (!channelStrip(piChannelIDs[iChannel]))                          if (!channelStrip(piChannelIDs[iChannel]))
1979                                  createChannelStrip(new qsamplerChannel(piChannelIDs[iChannel]));                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));
1980                  }                  }
1981                  m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
1982          }          }
# Line 2171  void MainForm::updateMessagesCapture (vo Line 2228  void MainForm::updateMessagesCapture (vo
2228  // qsamplerMainForm -- MDI channel strip management.  // qsamplerMainForm -- MDI channel strip management.
2229    
2230  // The channel strip creation executive.  // The channel strip creation executive.
2231  ChannelStrip* MainForm::createChannelStrip(qsamplerChannel* pChannel)  ChannelStrip* MainForm::createChannelStrip ( Channel *pChannel )
2232  {  {
2233          if (m_pClient == NULL || pChannel == NULL)          if (m_pClient == NULL || pChannel == NULL)
2234                  return NULL;                  return NULL;
2235    
         // Prepare for auto-arrange?  
         ChannelStrip* pChannelStrip = NULL;  
         int y = 0;  
         if (m_pOptions && m_pOptions->bAutoArrange) {  
                 QWidgetList wlist = m_pWorkspace->windowList();  
                 for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {  
                         pChannelStrip = static_cast<ChannelStrip *> (wlist.at(iChannel));  
                         if (pChannelStrip) {  
                         //  y += pChannelStrip->height()  
                         //              + pChannelStrip->parentWidget()->baseSize().height();  
                                 y += pChannelStrip->parentWidget()->frameGeometry().height();  
                         }  
                 }  
         }  
   
2236          // Add a new channel itema...          // Add a new channel itema...
2237          pChannelStrip = new ChannelStrip();          ChannelStrip *pChannelStrip = new ChannelStrip();
2238          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
2239                  return NULL;                  return NULL;
2240    
2241          m_pWorkspace->addWindow(pChannelStrip, Qt::FramelessWindowHint);          // Set some initial channel strip options...
   
         // Actual channel strip setup...  
         pChannelStrip->setup(pChannel);  
         QObject::connect(pChannelStrip,  
                 SIGNAL(channelChanged(ChannelStrip*)),  
                 SLOT(channelStripChanged(ChannelStrip*)));  
         // Set some initial aesthetic options...  
2242          if (m_pOptions) {          if (m_pOptions) {
2243                  // Background display effect...                  // Background display effect...
2244                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
# Line 2215  ChannelStrip* MainForm::createChannelStr Line 2250  ChannelStrip* MainForm::createChannelStr
2250                  pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                  pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2251          }          }
2252    
2253            // Add it to workspace...
2254            m_pWorkspace->addWindow(pChannelStrip, Qt::FramelessWindowHint);
2255    
2256            // Actual channel strip setup...
2257            pChannelStrip->setup(pChannel);
2258    
2259            QObject::connect(pChannelStrip,
2260                    SIGNAL(channelChanged(ChannelStrip*)),
2261                    SLOT(channelStripChanged(ChannelStrip*)));
2262    
2263          // Now we show up us to the world.          // Now we show up us to the world.
2264          pChannelStrip->show();          pChannelStrip->show();
         // Only then, we'll auto-arrange...  
         if (m_pOptions && m_pOptions->bAutoArrange) {  
                 int iWidth  = m_pWorkspace->width();  
         //  int iHeight = pChannel->height()  
         //              + pChannel->parentWidget()->baseSize().height();  
                 int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();  
                 pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);  
         }  
2265    
2266          // This is pretty new, so we'll watch for it closely.          // This is pretty new, so we'll watch for it closely.
2267          channelStripChanged(pChannelStrip);          channelStripChanged(pChannelStrip);
# Line 2263  ChannelStrip* MainForm::channelStrip ( i Line 2300  ChannelStrip* MainForm::channelStrip ( i
2300                  ChannelStrip* pChannelStrip                  ChannelStrip* pChannelStrip
2301                          = static_cast<ChannelStrip*> (wlist.at(iChannel));                          = static_cast<ChannelStrip*> (wlist.at(iChannel));
2302                  if (pChannelStrip) {                  if (pChannelStrip) {
2303                          qsamplerChannel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
2304                          if (pChannel && pChannel->channelID() == iChannelID)                          if (pChannel && pChannel->channelID() == iChannelID)
2305                                  return pChannelStrip;                                  return pChannelStrip;
2306                  }                  }
# Line 2404  void MainForm::startServer (void) Line 2441  void MainForm::startServer (void)
2441                  switch (QMessageBox::warning(this,                  switch (QMessageBox::warning(this,
2442                          QSAMPLER_TITLE ": " + tr("Warning"),                          QSAMPLER_TITLE ": " + tr("Warning"),
2443                          tr("Could not start the LinuxSampler server.\n\n"                          tr("Could not start the LinuxSampler server.\n\n"
2444                          "Maybe it ss already started."),                          "Maybe it is already started."),
2445                          tr("Stop"), tr("Kill"), tr("Cancel"))) {                          tr("Stop"), tr("Kill"), tr("Cancel"))) {
2446                  case 0:                  case 0:
2447                          m_pServer->terminate();                          m_pServer->terminate();
# Line 2424  void MainForm::startServer (void) Line 2461  void MainForm::startServer (void)
2461                  return;                  return;
2462    
2463          // OK. Let's build the startup process...          // OK. Let's build the startup process...
2464          m_pServer = new QProcess(this);          m_pServer = new QProcess();
2465            bForceServerStop = true;
2466    
2467          // Setup stdout/stderr capture...          // Setup stdout/stderr capture...
2468  //      if (m_pOptions->bStdoutCapture) {  //      if (m_pOptions->bStdoutCapture) {
2469                  //m_pServer->setProcessChannelMode(  #if QT_VERSION >= 0x040200
2470                  //      QProcess::StandardOutput);                  m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);
2471    #endif
2472                  QObject::connect(m_pServer,                  QObject::connect(m_pServer,
2473                          SIGNAL(readyReadStandardOutput()),                          SIGNAL(readyReadStandardOutput()),
2474                          SLOT(readServerStdout()));                          SLOT(readServerStdout()));
# Line 2440  void MainForm::startServer (void) Line 2479  void MainForm::startServer (void)
2479    
2480          // The unforgiveable signal communication...          // The unforgiveable signal communication...
2481          QObject::connect(m_pServer,          QObject::connect(m_pServer,
2482                  SIGNAL(finished(int,QProcess::ExitStatus)),                  SIGNAL(finished(int, QProcess::ExitStatus)),
2483                  SLOT(processServerExit()));                  SLOT(processServerExit()));
2484    
2485          // Build process arguments...          // Build process arguments...
# Line 2471  void MainForm::startServer (void) Line 2510  void MainForm::startServer (void)
2510    
2511    
2512  // Stop linuxsampler server...  // Stop linuxsampler server...
2513  void MainForm::stopServer (void)  void MainForm::stopServer (bool bInteractive)
2514  {  {
2515          // Stop client code.          // Stop client code.
2516          stopClient();          stopClient();
2517    
2518            if (m_pServer && bInteractive) {
2519                    if (QMessageBox::question(this,
2520                            QSAMPLER_TITLE ": " + tr("The backend's fate ..."),
2521                            tr("You have the option to keep the sampler backend (LinuxSampler)\n"
2522                            "running in the background. The sampler would continue to work\n"
2523                            "according to your current sampler session and you could alter the\n"
2524                            "sampler session at any time by relaunching QSampler.\n\n"
2525                            "Do you want LinuxSampler to stop or to keep running in\n"
2526                            "the background?"),
2527                            tr("Stop"), tr("Keep Running")) == 1)
2528                    {
2529                            bForceServerStop = false;
2530                    }
2531            }
2532    
2533          // And try to stop server.          // And try to stop server.
2534          if (m_pServer) {          if (m_pServer && bForceServerStop) {
2535                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2536                  if (m_pServer->state() == QProcess::Running)                  if (m_pServer->state() == QProcess::Running) {
2537    #if defined(WIN32)
2538                            // Try harder...
2539                            m_pServer->kill();
2540    #else
2541                            // Try softly...
2542                          m_pServer->terminate();                          m_pServer->terminate();
2543          }  #endif
2544                    }
2545            }       // Do final processing anyway.
2546            else processServerExit();
2547    
2548          // Give it some time to terminate gracefully and stabilize...          // Give it some time to terminate gracefully and stabilize...
2549          QTime t;          QTime t;
2550          t.start();          t.start();
2551          while (t.elapsed() < QSAMPLER_TIMER_MSECS)          while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2552                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
   
         // Do final processing anyway.  
         processServerExit();  
2553  }  }
2554    
2555    
# Line 2512  void MainForm::processServerExit (void) Line 2571  void MainForm::processServerExit (void)
2571          if (m_pMessages)          if (m_pMessages)
2572                  m_pMessages->flushStdoutBuffer();                  m_pMessages->flushStdoutBuffer();
2573    
2574          if (m_pServer) {          if (m_pServer && bForceServerStop) {
2575                    if (m_pServer->state() != QProcess::NotRunning) {
2576                            appendMessages(tr("Server is being forced..."));
2577                            // Force final server shutdown...
2578                            m_pServer->kill();
2579                            // Give it some time to terminate gracefully and stabilize...
2580                            QTime t;
2581                            t.start();
2582                            while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2583                                    QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2584                    }
2585                  // Force final server shutdown...                  // Force final server shutdown...
2586                  appendMessages(                  appendMessages(
2587                          tr("Server was stopped with exit status %1.")                          tr("Server was stopped with exit status %1.")
2588                          .arg(m_pServer->exitStatus()));                          .arg(m_pServer->exitStatus()));
                 m_pServer->terminate();  
                 if (!m_pServer->waitForFinished(2000))  
                         m_pServer->kill();  
                 // Destroy it.  
2589                  delete m_pServer;                  delete m_pServer;
2590                  m_pServer = NULL;                  m_pServer = NULL;
2591          }          }
# Line 2545  lscp_status_t qsampler_client_callback ( Line 2610  lscp_status_t qsampler_client_callback (
2610          // as this is run under some other thread context.          // as this is run under some other thread context.
2611          // A custom event must be posted here...          // A custom event must be posted here...
2612          QApplication::postEvent(pMainForm,          QApplication::postEvent(pMainForm,
2613                  new qsamplerCustomEvent(event, pchData, cchData));                  new CustomEvent(event, pchData, cchData));
2614    
2615          return LSCP_OK;          return LSCP_OK;
2616  }  }
# Line 2591  bool MainForm::startClient (void) Line 2656  bool MainForm::startClient (void)
2656    
2657          // Subscribe to channel info change notifications...          // Subscribe to channel info change notifications...
2658          if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)          if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)
2659                  appendMessagesClient("lscp_client_subscribe");                  appendMessagesClient("lscp_client_subscribe(CHANNEL_INFO)");
2660    
2661            DeviceStatusForm::onDevicesChanged(); // initialize
2662            updateViewMidiDeviceStatusMenu();
2663            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT) != LSCP_OK)
2664                    appendMessagesClient("lscp_client_subscribe(MIDI_INPUT_DEVICE_COUNT)");
2665            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO) != LSCP_OK)
2666                    appendMessagesClient("lscp_client_subscribe(MIDI_INPUT_DEVICE_INFO)");
2667    
2668    #if CONFIG_LSCP_CHANNEL_MIDI
2669            // Subscribe to channel MIDI data notifications...
2670            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_MIDI) != LSCP_OK)
2671                    appendMessagesClient("lscp_client_subscribe(CHANNEL_MIDI)");
2672    #endif
2673    
2674    #if CONFIG_LSCP_DEVICE_MIDI
2675            // Subscribe to channel MIDI data notifications...
2676            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_DEVICE_MIDI) != LSCP_OK)
2677                    appendMessagesClient("lscp_client_subscribe(DEVICE_MIDI)");
2678    #endif
2679    
2680          // We may stop scheduling around.          // We may stop scheduling around.
2681          stopSchedule();          stopSchedule();
# Line 2645  void MainForm::stopClient (void) Line 2729  void MainForm::stopClient (void)
2729          closeSession(false);          closeSession(false);
2730    
2731          // Close us as a client...          // Close us as a client...
2732    #if CONFIG_LSCP_DEVICE_MIDI
2733            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_DEVICE_MIDI);
2734    #endif
2735    #if CONFIG_LSCP_CHANNEL_MIDI
2736            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_MIDI);
2737    #endif
2738            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO);
2739            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT);
2740          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
2741          ::lscp_client_destroy(m_pClient);          ::lscp_client_destroy(m_pClient);
2742          m_pClient = NULL;          m_pClient = NULL;
# Line 2663  void MainForm::stopClient (void) Line 2755  void MainForm::stopClient (void)
2755          stabilizeForm();          stabilizeForm();
2756  }  }
2757    
2758    
2759    // Channel strip activation/selection.
2760    void MainForm::activateStrip ( QWidget *pWidget )
2761    {
2762            ChannelStrip *pChannelStrip
2763                    = static_cast<ChannelStrip *> (pWidget);
2764            if (pChannelStrip)
2765                    pChannelStrip->setSelected(true);
2766    
2767            stabilizeForm();
2768    }
2769    
2770    
2771  } // namespace QSampler  } // namespace QSampler
2772    
2773    

Legend:
Removed from v.1513  
changed lines
  Added in v.1699

  ViewVC Help
Powered by ViewVC