/[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 1512 by capela, Thu Nov 22 22:17:43 2007 UTC revision 2077 by capela, Wed Mar 31 09:07:30 2010 UTC
# Line 1  Line 1 
1  // qsamplerMainForm.cpp  // qsamplerMainForm.cpp
2  //  //
3  /****************************************************************************  /****************************************************************************
4     Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2010, rncbc aka Rui Nuno Capela. All rights reserved.
5     Copyright (C) 2007, Christian Schoenebeck     Copyright (C) 2007, 2008 Christian Schoenebeck
6    
7     This program is free software; you can redistribute it and/or     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License     modify it under the terms of the GNU General Public License
# Line 20  Line 20 
20    
21  *****************************************************************************/  *****************************************************************************/
22    
23    #include "qsamplerAbout.h"
24  #include "qsamplerMainForm.h"  #include "qsamplerMainForm.h"
25    
 #include "qsamplerAbout.h"  
26  #include "qsamplerOptions.h"  #include "qsamplerOptions.h"
27  #include "qsamplerChannel.h"  #include "qsamplerChannel.h"
28  #include "qsamplerMessages.h"  #include "qsamplerMessages.h"
# Line 33  Line 33 
33  #include "qsamplerInstrumentListForm.h"  #include "qsamplerInstrumentListForm.h"
34  #include "qsamplerDeviceForm.h"  #include "qsamplerDeviceForm.h"
35  #include "qsamplerOptionsForm.h"  #include "qsamplerOptionsForm.h"
36    #include "qsamplerDeviceStatusForm.h"
37    
38  #include <QApplication>  #include <QApplication>
39  #include <QWorkspace>  #include <QWorkspace>
# Line 55  Line 56 
56  #include <QTimer>  #include <QTimer>
57  #include <QDateTime>  #include <QDateTime>
58    
59    #if QT_VERSION < 0x040500
60    namespace Qt {
61    const WindowFlags WindowCloseButtonHint = WindowFlags(0x08000000);
62    #if QT_VERSION < 0x040200
63    const WindowFlags CustomizeWindowHint   = WindowFlags(0x02000000);
64    #endif
65    }
66    #endif
67    
68  #ifdef HAVE_SIGNAL_H  #ifdef HAVE_SIGNAL_H
69  #include <signal.h>  #include <signal.h>
# Line 77  static inline long lroundf ( float x ) Line 86  static inline long lroundf ( float x )
86  }  }
87  #endif  #endif
88    
89    
90    // All winsock apps needs this.
91    #if defined(WIN32)
92    static WSADATA _wsaData;
93    #endif
94    
95    
96    namespace QSampler {
97    
98  // Timer constant stuff.  // Timer constant stuff.
99  #define QSAMPLER_TIMER_MSECS    200  #define QSAMPLER_TIMER_MSECS    200
100    
# Line 87  static inline long lroundf ( float x ) Line 105  static inline long lroundf ( float x )
105  #define QSAMPLER_STATUS_SESSION 3       // Current session modification state.  #define QSAMPLER_STATUS_SESSION 3       // Current session modification state.
106    
107    
108  // All winsock apps needs this.  // Specialties for thread-callback comunication.
109  #if defined(WIN32)  #define QSAMPLER_LSCP_EVENT   QEvent::Type(QEvent::User + 1)
110  static WSADATA _wsaData;  #define QSAMPLER_SAVE_EVENT   QEvent::Type(QEvent::User + 2)
 #endif  
111    
112    
113  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
114  // qsamplerCustomEvent -- specialty for callback comunication.  // LscpEvent -- specialty for LSCP callback comunication.
115    
 #define QSAMPLER_CUSTOM_EVENT   QEvent::Type(QEvent::User + 0)  
116    
117  class qsamplerCustomEvent : public QEvent  class LscpEvent : public QEvent
118  {  {
119  public:  public:
120    
121          // Constructor.          // Constructor.
122          qsamplerCustomEvent(lscp_event_t event, const char *pchData, int cchData)          LscpEvent(lscp_event_t event, const char *pchData, int cchData)
123                  : QEvent(QSAMPLER_CUSTOM_EVENT)                  : QEvent(QSAMPLER_LSCP_EVENT)
124          {          {
125                  m_event = event;                  m_event = event;
126                  m_data  = QString::fromUtf8(pchData, cchData);                  m_data  = QString::fromUtf8(pchData, cchData);
# Line 124  private: Line 140  private:
140    
141    
142  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
143  // qsamplerMainForm -- Main window form implementation.  // LADISH Level 1 support stuff.
144    
145  namespace QSampler {  void qsampler_on_sigusr1 ( int /*signo*/ )
146    {
147            QApplication::postEvent(
148                    MainForm::getInstance(),
149                    new QEvent(QSAMPLER_SAVE_EVENT));
150    }
151    
152    
153    //-------------------------------------------------------------------------
154    // qsamplerMainForm -- Main window form implementation.
155    
156  // Kind of singleton reference.  // Kind of singleton reference.
157  MainForm* MainForm::g_pMainForm = NULL;  MainForm* MainForm::g_pMainForm = NULL;
# Line 162  MainForm::MainForm ( QWidget *pParent ) Line 187  MainForm::MainForm ( QWidget *pParent )
187  #ifdef HAVE_SIGNAL_H  #ifdef HAVE_SIGNAL_H
188          // Set to ignore any fatal "Broken pipe" signals.          // Set to ignore any fatal "Broken pipe" signals.
189          ::signal(SIGPIPE, SIG_IGN);          ::signal(SIGPIPE, SIG_IGN);
190            // LADISH Level 1 suport.
191            ::signal(SIGUSR1, qsampler_on_sigusr1);
192  #endif  #endif
193    
194  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
# Line 171  MainForm::MainForm ( QWidget *pParent ) Line 198  MainForm::MainForm ( QWidget *pParent )
198          // Volume slider...          // Volume slider...
199          m_ui.channelsToolbar->addSeparator();          m_ui.channelsToolbar->addSeparator();
200          m_pVolumeSlider = new QSlider(Qt::Horizontal, m_ui.channelsToolbar);          m_pVolumeSlider = new QSlider(Qt::Horizontal, m_ui.channelsToolbar);
201          m_pVolumeSlider->setTickPosition(QSlider::TicksBelow);          m_pVolumeSlider->setTickPosition(QSlider::TicksBothSides);
202          m_pVolumeSlider->setTickInterval(10);          m_pVolumeSlider->setTickInterval(10);
203          m_pVolumeSlider->setPageStep(10);          m_pVolumeSlider->setPageStep(10);
204          m_pVolumeSlider->setSingleStep(10);          m_pVolumeSlider->setSingleStep(10);
# Line 189  MainForm::MainForm ( QWidget *pParent ) Line 216  MainForm::MainForm ( QWidget *pParent )
216          // Volume spin-box          // Volume spin-box
217          m_ui.channelsToolbar->addSeparator();          m_ui.channelsToolbar->addSeparator();
218          m_pVolumeSpinBox = new QSpinBox(m_ui.channelsToolbar);          m_pVolumeSpinBox = new QSpinBox(m_ui.channelsToolbar);
219            m_pVolumeSpinBox->setMaximumHeight(24);
220          m_pVolumeSpinBox->setSuffix(" %");          m_pVolumeSpinBox->setSuffix(" %");
221          m_pVolumeSpinBox->setMinimum(0);          m_pVolumeSpinBox->setMinimum(0);
222          m_pVolumeSpinBox->setMaximum(100);          m_pVolumeSpinBox->setMaximum(100);
# Line 205  MainForm::MainForm ( QWidget *pParent ) Line 233  MainForm::MainForm ( QWidget *pParent )
233          // Set the activation connection.          // Set the activation connection.
234          QObject::connect(m_pWorkspace,          QObject::connect(m_pWorkspace,
235                  SIGNAL(windowActivated(QWidget *)),                  SIGNAL(windowActivated(QWidget *)),
236                  SLOT(stabilizeForm()));                  SLOT(activateStrip(QWidget *)));
237          // Make it shine :-)          // Make it shine :-)
238          setCentralWidget(m_pWorkspace);          setCentralWidget(m_pWorkspace);
239    
# Line 365  MainForm::~MainForm() Line 393  MainForm::~MainForm()
393    
394    
395  // Make and set a proper setup options step.  // Make and set a proper setup options step.
396  void MainForm::setup ( qsamplerOptions *pOptions )  void MainForm::setup ( Options *pOptions )
397  {  {
398          // We got options?          // We got options?
399          m_pOptions = pOptions;          m_pOptions = pOptions;
400    
401          // What style do we create these forms?          // What style do we create these forms?
402          Qt::WindowFlags wflags = Qt::Window          Qt::WindowFlags wflags = Qt::Window
 #if QT_VERSION >= 0x040200  
403                  | Qt::CustomizeWindowHint                  | Qt::CustomizeWindowHint
 #endif  
404                  | Qt::WindowTitleHint                  | Qt::WindowTitleHint
405                  | Qt::WindowSystemMenuHint                  | Qt::WindowSystemMenuHint
406                  | Qt::WindowMinMaxButtonsHint;                  | Qt::WindowMinMaxButtonsHint
407                    | Qt::WindowCloseButtonHint;
408          if (m_pOptions->bKeepOnTop)          if (m_pOptions->bKeepOnTop)
409                  wflags |= Qt::Tool;                  wflags |= Qt::Tool;
410    
411          // Some child forms are to be created right now.          // Some child forms are to be created right now.
412          m_pMessages = new qsamplerMessages(this);          m_pMessages = new Messages(this);
413          m_pDeviceForm = new DeviceForm(this, wflags);          m_pDeviceForm = new DeviceForm(this, wflags);
414  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
415          m_pInstrumentListForm = new InstrumentListForm(this, wflags);          m_pInstrumentListForm = new InstrumentListForm(this, wflags);
416  #else  #else
417          viewInstrumentsAction->setEnabled(false);          m_ui.viewInstrumentsAction->setEnabled(false);
418  #endif  #endif
419    
420            // Setup messages logging appropriately...
421            m_pMessages->setLogging(
422                    m_pOptions->bMessagesLog,
423                    m_pOptions->sMessagesLogPath);
424    
425          // Set message defaults...          // Set message defaults...
426          updateMessagesFont();          updateMessagesFont();
427          updateMessagesLimit();          updateMessagesLimit();
# Line 418  void MainForm::setup ( qsamplerOptions * Line 452  void MainForm::setup ( qsamplerOptions *
452          }          }
453    
454          // Try to restore old window positioning and initial visibility.          // Try to restore old window positioning and initial visibility.
455          m_pOptions->loadWidgetGeometry(this);          m_pOptions->loadWidgetGeometry(this, true);
456          m_pOptions->loadWidgetGeometry(m_pInstrumentListForm);          m_pOptions->loadWidgetGeometry(m_pInstrumentListForm);
457          m_pOptions->loadWidgetGeometry(m_pDeviceForm);          m_pOptions->loadWidgetGeometry(m_pDeviceForm);
458    
# Line 462  bool MainForm::queryClose (void) Line 496  bool MainForm::queryClose (void)
496                          // And the children, and the main windows state,.                          // And the children, and the main windows state,.
497                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);
498                          m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);                          m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
499                          m_pOptions->saveWidgetGeometry(this);                          m_pOptions->saveWidgetGeometry(this, true);
500                          // Close popup widgets.                          // Close popup widgets.
501                          if (m_pInstrumentListForm)                          if (m_pInstrumentListForm)
502                                  m_pInstrumentListForm->close();                                  m_pInstrumentListForm->close();
503                          if (m_pDeviceForm)                          if (m_pDeviceForm)
504                                  m_pDeviceForm->close();                                  m_pDeviceForm->close();
505                          // Stop client and/or server, gracefully.                          // Stop client and/or server, gracefully.
506                          stopServer();                          stopServer(true /*interactive*/);
507                  }                  }
508          }          }
509    
# Line 479  bool MainForm::queryClose (void) Line 513  bool MainForm::queryClose (void)
513    
514  void MainForm::closeEvent ( QCloseEvent *pCloseEvent )  void MainForm::closeEvent ( QCloseEvent *pCloseEvent )
515  {  {
516          if (queryClose())          if (queryClose()) {
517                    DeviceStatusForm::deleteAllInstances();
518                  pCloseEvent->accept();                  pCloseEvent->accept();
519          else          } else
520                  pCloseEvent->ignore();                  pCloseEvent->ignore();
521  }  }
522    
# Line 510  void MainForm::dropEvent ( QDropEvent* p Line 545  void MainForm::dropEvent ( QDropEvent* p
545                  QListIterator<QUrl> iter(pMimeData->urls());                  QListIterator<QUrl> iter(pMimeData->urls());
546                  while (iter.hasNext()) {                  while (iter.hasNext()) {
547                          const QString& sPath = iter.next().toLocalFile();                          const QString& sPath = iter.next().toLocalFile();
548                          if (qsamplerChannel::isInstrumentFile(sPath)) {                          if (Channel::isInstrumentFile(sPath)) {
549                                  // Try to create a new channel from instrument file...                                  // Try to create a new channel from instrument file...
550                                  qsamplerChannel *pChannel = new qsamplerChannel();                                  Channel *pChannel = new Channel();
551                                  if (pChannel == NULL)                                  if (pChannel == NULL)
552                                          return;                                          return;
553                                  // Start setting the instrument filename...                                  // Start setting the instrument filename...
# Line 544  void MainForm::dropEvent ( QDropEvent* p Line 579  void MainForm::dropEvent ( QDropEvent* p
579    
580    
581  // Custome event handler.  // Custome event handler.
582  void MainForm::customEvent(QEvent* pCustomEvent)  void MainForm::customEvent ( QEvent* pEvent )
583  {  {
584          // For the time being, just pump it to messages.          // For the time being, just pump it to messages.
585          if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {          if (pEvent->type() == QSAMPLER_LSCP_EVENT) {
586                  qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;                  LscpEvent *pLscpEvent = static_cast<LscpEvent *> (pEvent);
587                  if (pEvent->event() == LSCP_EVENT_CHANNEL_INFO) {                  switch (pLscpEvent->event()) {
588                          int iChannelID = pEvent->data().toInt();                          case LSCP_EVENT_CHANNEL_COUNT:
589                          ChannelStrip *pChannelStrip = channelStrip(iChannelID);                                  updateAllChannelStrips(true);
590                          if (pChannelStrip)                                  break;
591                                  channelStripChanged(pChannelStrip);                          case LSCP_EVENT_CHANNEL_INFO: {
592                  } else {                                  int iChannelID = pLscpEvent->data().toInt();
593                          appendMessagesColor(tr("Notify event: %1 data: %2")                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);
594                                  .arg(::lscp_event_to_text(pEvent->event()))                                  if (pChannelStrip)
595                                  .arg(pEvent->data()), "#996699");                                          channelStripChanged(pChannelStrip);
596                  }                                  break;
597                            }
598                            case LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT:
599                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
600                                    DeviceStatusForm::onDevicesChanged();
601                                    updateViewMidiDeviceStatusMenu();
602                                    break;
603                            case LSCP_EVENT_MIDI_INPUT_DEVICE_INFO: {
604                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
605                                    const int iDeviceID = pLscpEvent->data().section(' ', 0, 0).toInt();
606                                    DeviceStatusForm::onDeviceChanged(iDeviceID);
607                                    break;
608                            }
609                            case LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT:
610                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
611                                    break;
612                            case LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO:
613                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
614                                    break;
615                    #if CONFIG_EVENT_CHANNEL_MIDI
616                            case LSCP_EVENT_CHANNEL_MIDI: {
617                                    const int iChannelID = pLscpEvent->data().section(' ', 0, 0).toInt();
618                                    ChannelStrip *pChannelStrip = channelStrip(iChannelID);
619                                    if (pChannelStrip)
620                                            pChannelStrip->midiActivityLedOn();
621                                    break;
622                            }
623                    #endif
624                    #if CONFIG_EVENT_DEVICE_MIDI
625                            case LSCP_EVENT_DEVICE_MIDI: {
626                                    const int iDeviceID = pLscpEvent->data().section(' ', 0, 0).toInt();
627                                    const int iPortID   = pLscpEvent->data().section(' ', 1, 1).toInt();
628                                    DeviceStatusForm *pDeviceStatusForm
629                                            = DeviceStatusForm::getInstance(iDeviceID);
630                                    if (pDeviceStatusForm)
631                                            pDeviceStatusForm->midiArrived(iPortID);
632                                    break;
633                            }
634                    #endif
635                            default:
636                                    appendMessagesColor(tr("LSCP Event: %1 data: %2")
637                                            .arg(::lscp_event_to_text(pLscpEvent->event()))
638                                            .arg(pLscpEvent->data()), "#996699");
639                    }
640            }       // LADISH1 Level 1 support...
641            else if (pEvent->type() == QSAMPLER_SAVE_EVENT)
642                    saveSession(false);
643    }
644    
645    
646    void MainForm::updateViewMidiDeviceStatusMenu (void)
647    {
648            m_ui.viewMidiDeviceStatusMenu->clear();
649            const std::map<int, DeviceStatusForm *> statusForms
650                    = DeviceStatusForm::getInstances();
651            std::map<int, DeviceStatusForm *>::const_iterator iter
652                    = statusForms.begin();
653            for ( ; iter != statusForms.end(); ++iter) {
654                    DeviceStatusForm *pStatusForm = iter->second;
655                    m_ui.viewMidiDeviceStatusMenu->addAction(
656                            pStatusForm->visibleAction());
657          }          }
658  }  }
659    
660    
661  // Context menu event handler.  // Context menu event handler.
662  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )
663  {  {
# Line 575  void MainForm::contextMenuEvent( QContex Line 671  void MainForm::contextMenuEvent( QContex
671  // qsamplerMainForm -- Brainless public property accessors.  // qsamplerMainForm -- Brainless public property accessors.
672    
673  // The global options settings property.  // The global options settings property.
674  qsamplerOptions *MainForm::options (void) const  Options *MainForm::options (void) const
675  {  {
676          return m_pOptions;          return m_pOptions;
677  }  }
# Line 693  bool MainForm::saveSession ( bool bPromp Line 789  bool MainForm::saveSession ( bool bPromp
789                                  "\"%1\"\n\n"                                  "\"%1\"\n\n"
790                                  "Do you want to replace it?")                                  "Do you want to replace it?")
791                                  .arg(sFilename),                                  .arg(sFilename),
792                                  tr("Replace"), tr("Cancel")) > 0)                                  QMessageBox::Yes | QMessageBox::No)
793                                    == QMessageBox::No)
794                                  return false;                                  return false;
795                  }                  }
796          }          }
# Line 716  bool MainForm::closeSession ( bool bForc Line 813  bool MainForm::closeSession ( bool bForc
813                          "\"%1\"\n\n"                          "\"%1\"\n\n"
814                          "Do you want to save the changes?")                          "Do you want to save the changes?")
815                          .arg(sessionName(m_sFilename)),                          .arg(sessionName(m_sFilename)),
816                          tr("Save"), tr("Discard"), tr("Cancel"))) {                          QMessageBox::Save |
817                  case 0:     // Save...                          QMessageBox::Discard |
818                            QMessageBox::Cancel)) {
819                    case QMessageBox::Save:
820                          bClose = saveSession(false);                          bClose = saveSession(false);
821                          // Fall thru....                          // Fall thru....
822                  case 1:     // Discard                  case QMessageBox::Discard:
823                          break;                          break;
824                  default:    // Cancel.                  default:    // Cancel.
825                          bClose = false;                          bClose = false;
# Line 736  bool MainForm::closeSession ( bool bForc Line 835  bool MainForm::closeSession ( bool bForc
835                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
836                          ChannelStrip *pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                          ChannelStrip *pChannelStrip = (ChannelStrip*) wlist.at(iChannel);
837                          if (pChannelStrip) {                          if (pChannelStrip) {
838                                  qsamplerChannel *pChannel = pChannelStrip->channel();                                  Channel *pChannel = pChannelStrip->channel();
839                                  if (bForce && pChannel)                                  if (bForce && pChannel)
840                                          pChannel->removeChannel();                                          pChannel->removeChannel();
841                                  delete pChannelStrip;                                  delete pChannelStrip;
# Line 876  bool MainForm::saveSessionFile ( const Q Line 975  bool MainForm::saveSessionFile ( const Q
975    
976          // Audio device mapping.          // Audio device mapping.
977          QMap<int, int> audioDeviceMap;          QMap<int, int> audioDeviceMap;
978          piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Audio);          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);
979          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
980                  ts << endl;                  ts << endl;
981                  qsamplerDevice device(qsamplerDevice::Audio, piDeviceIDs[iDevice]);                  Device device(Device::Audio, piDeviceIDs[iDevice]);
982                  // Audio device specification...                  // Audio device specification...
983                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
984                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
985                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
986                  qsamplerDeviceParamMap::ConstIterator deviceParam;                  DeviceParamMap::ConstIterator deviceParam;
987                  for (deviceParam = device.params().begin();                  for (deviceParam = device.params().begin();
988                                  deviceParam != device.params().end();                                  deviceParam != device.params().end();
989                                          ++deviceParam) {                                          ++deviceParam) {
990                          const qsamplerDeviceParam& param = deviceParam.value();                          const DeviceParam& param = deviceParam.value();
991                          if (param.value.isEmpty()) ts << "# ";                          if (param.value.isEmpty()) ts << "# ";
992                          ts << " " << deviceParam.key() << "='" << param.value << "'";                          ts << " " << deviceParam.key() << "='" << param.value << "'";
993                  }                  }
994                  ts << endl;                  ts << endl;
995                  // Audio channel parameters...                  // Audio channel parameters...
996                  int iPort = 0;                  int iPort = 0;
997                  QListIterator<qsamplerDevicePort *> iter(device.ports());                  QListIterator<DevicePort *> iter(device.ports());
998                  while (iter.hasNext()) {                  while (iter.hasNext()) {
999                          qsamplerDevicePort *pPort = iter.next();                          DevicePort *pPort = iter.next();
1000                          qsamplerDeviceParamMap::ConstIterator portParam;                          DeviceParamMap::ConstIterator portParam;
1001                          for (portParam = pPort->params().begin();                          for (portParam = pPort->params().begin();
1002                                          portParam != pPort->params().end();                                          portParam != pPort->params().end();
1003                                                  ++portParam) {                                                  ++portParam) {
1004                                  const qsamplerDeviceParam& param = portParam.value();                                  const DeviceParam& param = portParam.value();
1005                                  if (param.fix || param.value.isEmpty()) ts << "# ";                                  if (param.fix || param.value.isEmpty()) ts << "# ";
1006                                  ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice                                  ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice
1007                                          << " " << iPort << " " << portParam.key()                                          << " " << iPort << " " << portParam.key()
# Line 918  bool MainForm::saveSessionFile ( const Q Line 1017  bool MainForm::saveSessionFile ( const Q
1017    
1018          // MIDI device mapping.          // MIDI device mapping.
1019          QMap<int, int> midiDeviceMap;          QMap<int, int> midiDeviceMap;
1020          piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Midi);          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);
1021          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
1022                  ts << endl;                  ts << endl;
1023                  qsamplerDevice device(qsamplerDevice::Midi, piDeviceIDs[iDevice]);                  Device device(Device::Midi, piDeviceIDs[iDevice]);
1024                  // MIDI device specification...                  // MIDI device specification...
1025                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1026                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1027                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
1028                  qsamplerDeviceParamMap::ConstIterator deviceParam;                  DeviceParamMap::ConstIterator deviceParam;
1029                  for (deviceParam = device.params().begin();                  for (deviceParam = device.params().begin();
1030                                  deviceParam != device.params().end();                                  deviceParam != device.params().end();
1031                                          ++deviceParam) {                                          ++deviceParam) {
1032                          const qsamplerDeviceParam& param = deviceParam.value();                          const DeviceParam& param = deviceParam.value();
1033                          if (param.value.isEmpty()) ts << "# ";                          if (param.value.isEmpty()) ts << "# ";
1034                          ts << " " << deviceParam.key() << "='" << param.value << "'";                          ts << " " << deviceParam.key() << "='" << param.value << "'";
1035                  }                  }
1036                  ts << endl;                  ts << endl;
1037                  // MIDI port parameters...                  // MIDI port parameters...
1038                  int iPort = 0;                  int iPort = 0;
1039                  QListIterator<qsamplerDevicePort *> iter(device.ports());                  QListIterator<DevicePort *> iter(device.ports());
1040                  while (iter.hasNext()) {                  while (iter.hasNext()) {
1041                          qsamplerDevicePort *pPort = iter.next();                          DevicePort *pPort = iter.next();
1042                          qsamplerDeviceParamMap::ConstIterator portParam;                          DeviceParamMap::ConstIterator portParam;
1043                          for (portParam = pPort->params().begin();                          for (portParam = pPort->params().begin();
1044                                          portParam != pPort->params().end();                                          portParam != pPort->params().end();
1045                                                  ++portParam) {                                                  ++portParam) {
1046                                  const qsamplerDeviceParam& param = portParam.value();                                  const DeviceParam& param = portParam.value();
1047                                  if (param.fix || param.value.isEmpty()) ts << "# ";                                  if (param.fix || param.value.isEmpty()) ts << "# ";
1048                                  ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice                                  ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice
1049                                  << " " << iPort << " " << portParam.key()                                  << " " << iPort << " " << portParam.key()
# Line 1036  bool MainForm::saveSessionFile ( const Q Line 1135  bool MainForm::saveSessionFile ( const Q
1135                  ChannelStrip* pChannelStrip                  ChannelStrip* pChannelStrip
1136                          = static_cast<ChannelStrip *> (wlist.at(iChannel));                          = static_cast<ChannelStrip *> (wlist.at(iChannel));
1137                  if (pChannelStrip) {                  if (pChannelStrip) {
1138                          qsamplerChannel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1139                          if (pChannel) {                          if (pChannel) {
1140                                  ts << "# " << tr("Channel") << " " << iChannel << endl;                                  ts << "# " << tr("Channel") << " " << iChannel << endl;
1141                                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
# Line 1068  bool MainForm::saveSessionFile ( const Q Line 1167  bool MainForm::saveSessionFile ( const Q
1167                                  ts << "LOAD INSTRUMENT NON_MODAL '"                                  ts << "LOAD INSTRUMENT NON_MODAL '"
1168                                          << pChannel->instrumentFile() << "' "                                          << pChannel->instrumentFile() << "' "
1169                                          << pChannel->instrumentNr() << " " << iChannel << endl;                                          << pChannel->instrumentNr() << " " << iChannel << endl;
1170                                  qsamplerChannelRoutingMap::ConstIterator audioRoute;                                  ChannelRoutingMap::ConstIterator audioRoute;
1171                                  for (audioRoute = pChannel->audioRouting().begin();                                  for (audioRoute = pChannel->audioRouting().begin();
1172                                                  audioRoute != pChannel->audioRouting().end();                                                  audioRoute != pChannel->audioRouting().end();
1173                                                          ++audioRoute) {                                                          ++audioRoute) {
# Line 1241  void MainForm::fileReset (void) Line 1340  void MainForm::fileReset (void)
1340                  "Please note that this operation may cause\n"                  "Please note that this operation may cause\n"
1341                  "temporary MIDI and Audio disruption.\n\n"                  "temporary MIDI and Audio disruption.\n\n"
1342                  "Do you want to reset the sampler engine now?"),                  "Do you want to reset the sampler engine now?"),
1343                  tr("Reset"), tr("Cancel")) > 0)                  QMessageBox::Ok | QMessageBox::Cancel)
1344                    == QMessageBox::Cancel)
1345                  return;                  return;
1346    
1347          // Trye closing the current session, first...          // Trye closing the current session, first...
# Line 1282  void MainForm::fileRestart (void) Line 1382  void MainForm::fileRestart (void)
1382                          "Please note that this operation may cause\n"                          "Please note that this operation may cause\n"
1383                          "temporary MIDI and Audio disruption.\n\n"                          "temporary MIDI and Audio disruption.\n\n"
1384                          "Do you want to restart the connection now?"),                          "Do you want to restart the connection now?"),
1385                          tr("Restart"), tr("Cancel")) == 0);                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok);
1386          }          }
1387    
1388          // Are we still for it?          // Are we still for it?
# Line 1313  void MainForm::editAddChannel (void) Line 1413  void MainForm::editAddChannel (void)
1413                  return;                  return;
1414    
1415          // Just create the channel instance...          // Just create the channel instance...
1416          qsamplerChannel *pChannel = new qsamplerChannel();          Channel *pChannel = new Channel();
1417          if (pChannel == NULL)          if (pChannel == NULL)
1418                  return;                  return;
1419    
# Line 1331  void MainForm::editAddChannel (void) Line 1431  void MainForm::editAddChannel (void)
1431                  return;                  return;
1432          }          }
1433    
1434            // Do we auto-arrange?
1435            if (m_pOptions && m_pOptions->bAutoArrange)
1436                    channelsArrange();
1437    
1438          // Make that an overall update.          // Make that an overall update.
1439          m_iDirtyCount++;          m_iDirtyCount++;
1440          stabilizeForm();          stabilizeForm();
# Line 1347  void MainForm::editRemoveChannel (void) Line 1451  void MainForm::editRemoveChannel (void)
1451          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1452                  return;                  return;
1453    
1454          qsamplerChannel *pChannel = pChannelStrip->channel();          Channel *pChannel = pChannelStrip->channel();
1455          if (pChannel == NULL)          if (pChannel == NULL)
1456                  return;                  return;
1457    
# Line 1359  void MainForm::editRemoveChannel (void) Line 1463  void MainForm::editRemoveChannel (void)
1463                          "%1\n\n"                          "%1\n\n"
1464                          "Are you sure?")                          "Are you sure?")
1465                          .arg(pChannelStrip->windowTitle()),                          .arg(pChannelStrip->windowTitle()),
1466                          tr("OK"), tr("Cancel")) > 0)                          QMessageBox::Ok | QMessageBox::Cancel)
1467                            == QMessageBox::Cancel)
1468                          return;                          return;
1469          }          }
1470    
# Line 1550  void MainForm::viewOptions (void) Line 1655  void MainForm::viewOptions (void)
1655                  int     iOldServerTimeout   = m_pOptions->iServerTimeout;                  int     iOldServerTimeout   = m_pOptions->iServerTimeout;
1656                  bool    bOldServerStart     = m_pOptions->bServerStart;                  bool    bOldServerStart     = m_pOptions->bServerStart;
1657                  QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;                  QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;
1658                    bool    bOldMessagesLog     = m_pOptions->bMessagesLog;
1659                    QString sOldMessagesLogPath = m_pOptions->sMessagesLogPath;
1660                  QString sOldDisplayFont     = m_pOptions->sDisplayFont;                  QString sOldDisplayFont     = m_pOptions->sDisplayFont;
1661                  bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;                  bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1662                  int     iOldMaxVolume       = m_pOptions->iMaxVolume;                  int     iOldMaxVolume       = m_pOptions->iMaxVolume;
# Line 1561  void MainForm::viewOptions (void) Line 1668  void MainForm::viewOptions (void)
1668                  bool    bOldCompletePath    = m_pOptions->bCompletePath;                  bool    bOldCompletePath    = m_pOptions->bCompletePath;
1669                  bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;                  bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1670                  int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;                  int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1671                    int     iOldBaseFontSize    = m_pOptions->iBaseFontSize;
1672                  // Load the current setup settings.                  // Load the current setup settings.
1673                  pOptionsForm->setup(m_pOptions);                  pOptionsForm->setup(m_pOptions);
1674                  // Show the setup dialog...                  // Show the setup dialog...
# Line 1569  void MainForm::viewOptions (void) Line 1677  void MainForm::viewOptions (void)
1677                          if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||                          if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1678                                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||                                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||
1679                                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||                                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1680                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)) {                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)     ||
1681                                    (iOldBaseFontSize   !=  m_pOptions->iBaseFontSize)) {
1682                                  QMessageBox::information(this,                                  QMessageBox::information(this,
1683                                          QSAMPLER_TITLE ": " + tr("Information"),                                          QSAMPLER_TITLE ": " + tr("Information"),
1684                                          tr("Some settings may be only effective\n"                                          tr("Some settings may be only effective\n"
1685                                          "next time you start this program."), tr("OK"));                                          "next time you start this program."));
1686                                  updateMessagesCapture();                                  updateMessagesCapture();
1687                          }                          }
1688                          // Check wheather something immediate has changed.                          // Check wheather something immediate has changed.
1689                            if (( bOldMessagesLog && !m_pOptions->bMessagesLog) ||
1690                                    (!bOldMessagesLog &&  m_pOptions->bMessagesLog) ||
1691                                    (sOldMessagesLogPath != m_pOptions->sMessagesLogPath))
1692                                    m_pMessages->setLogging(
1693                                            m_pOptions->bMessagesLog, m_pOptions->sMessagesLogPath);
1694                          if (( bOldCompletePath && !m_pOptions->bCompletePath) ||                          if (( bOldCompletePath && !m_pOptions->bCompletePath) ||
1695                                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||                                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||
1696                                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))                                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))
# Line 1731  void MainForm::helpAbout (void) Line 1845  void MainForm::helpAbout (void)
1845          sText += tr("Instrument editing support disabled.");          sText += tr("Instrument editing support disabled.");
1846          sText += "</font></small><br />";          sText += "</font></small><br />";
1847  #endif  #endif
1848    #ifndef CONFIG_EVENT_CHANNEL_MIDI
1849            sText += "<small><font color=\"red\">";
1850            sText += tr("Channel MIDI event support disabled.");
1851            sText += "</font></small><br />";
1852    #endif
1853    #ifndef CONFIG_EVENT_DEVICE_MIDI
1854            sText += "<small><font color=\"red\">";
1855            sText += tr("Device MIDI event support disabled.");
1856            sText += "</font></small><br />";
1857    #endif
1858    #ifndef CONFIG_MAX_VOICES
1859            sText += "<small><font color=\"red\">";
1860            sText += tr("Runtime max. voices / disk streams support disabled.");
1861            sText += "</font></small><br />";
1862    #endif
1863          sText += "<br />\n";          sText += "<br />\n";
1864          sText += tr("Using") + ": ";          sText += tr("Using") + ": ";
1865          sText += ::lscp_client_package();          sText += ::lscp_client_package();
# Line 1771  void MainForm::stabilizeForm (void) Line 1900  void MainForm::stabilizeForm (void)
1900          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));
1901    
1902          // Update the main menu state...          // Update the main menu state...
1903          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1904          bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);          bool bHasClient = (m_pOptions != NULL && m_pClient != NULL);
1905          bool bHasChannel = (bHasClient && pChannelStrip != NULL);          bool bHasChannel = (bHasClient && pChannelStrip != NULL);
1906            bool bHasChannels = (bHasClient && m_pWorkspace->windowList().count() > 0);
1907          m_ui.fileNewAction->setEnabled(bHasClient);          m_ui.fileNewAction->setEnabled(bHasClient);
1908          m_ui.fileOpenAction->setEnabled(bHasClient);          m_ui.fileOpenAction->setEnabled(bHasClient);
1909          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
# Line 1789  void MainForm::stabilizeForm (void) Line 1919  void MainForm::stabilizeForm (void)
1919          m_ui.editEditChannelAction->setEnabled(false);          m_ui.editEditChannelAction->setEnabled(false);
1920  #endif  #endif
1921          m_ui.editResetChannelAction->setEnabled(bHasChannel);          m_ui.editResetChannelAction->setEnabled(bHasChannel);
1922          m_ui.editResetAllChannelsAction->setEnabled(bHasChannel);          m_ui.editResetAllChannelsAction->setEnabled(bHasChannels);
1923          m_ui.viewMessagesAction->setChecked(m_pMessages && m_pMessages->isVisible());          m_ui.viewMessagesAction->setChecked(m_pMessages && m_pMessages->isVisible());
1924  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
1925          m_ui.viewInstrumentsAction->setChecked(m_pInstrumentListForm          m_ui.viewInstrumentsAction->setChecked(m_pInstrumentListForm
# Line 1801  void MainForm::stabilizeForm (void) Line 1931  void MainForm::stabilizeForm (void)
1931          m_ui.viewDevicesAction->setChecked(m_pDeviceForm          m_ui.viewDevicesAction->setChecked(m_pDeviceForm
1932                  && m_pDeviceForm->isVisible());                  && m_pDeviceForm->isVisible());
1933          m_ui.viewDevicesAction->setEnabled(bHasClient);          m_ui.viewDevicesAction->setEnabled(bHasClient);
1934          m_ui.channelsArrangeAction->setEnabled(bHasChannel);          m_ui.viewMidiDeviceStatusMenu->setEnabled(
1935                    DeviceStatusForm::getInstances().size() > 0);
1936            m_ui.channelsArrangeAction->setEnabled(bHasChannels);
1937    
1938  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
1939          // Toolbar widgets are also affected...          // Toolbar widgets are also affected...
# Line 1905  void MainForm::updateSession (void) Line 2037  void MainForm::updateSession (void)
2037          }          }
2038  #endif  #endif
2039    
2040            updateAllChannelStrips(false);
2041    
2042            // Do we auto-arrange?
2043            if (m_pOptions && m_pOptions->bAutoArrange)
2044                    channelsArrange();
2045    
2046            // Remember to refresh devices and instruments...
2047            if (m_pInstrumentListForm)
2048                    m_pInstrumentListForm->refreshInstruments();
2049            if (m_pDeviceForm)
2050                    m_pDeviceForm->refreshDevices();
2051    }
2052    
2053    void MainForm::updateAllChannelStrips(bool bRemoveDeadStrips) {
2054          // Retrieve the current channel list.          // Retrieve the current channel list.
2055          int *piChannelIDs = ::lscp_list_channels(m_pClient);          int *piChannelIDs = ::lscp_list_channels(m_pClient);
2056          if (piChannelIDs == NULL) {          if (piChannelIDs == NULL) {
# Line 1919  void MainForm::updateSession (void) Line 2065  void MainForm::updateSession (void)
2065                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {
2066                          // Check if theres already a channel strip for this one...                          // Check if theres already a channel strip for this one...
2067                          if (!channelStrip(piChannelIDs[iChannel]))                          if (!channelStrip(piChannelIDs[iChannel]))
2068                                  createChannelStrip(new qsamplerChannel(piChannelIDs[iChannel]));                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));
2069                  }                  }
                 m_pWorkspace->setUpdatesEnabled(true);  
         }  
2070    
2071          // Do we auto-arrange?                  // Do we auto-arrange?
2072          if (m_pOptions && m_pOptions->bAutoArrange)                  if (m_pOptions && m_pOptions->bAutoArrange)
2073                  channelsArrange();                          channelsArrange();
2074    
2075          // Remember to refresh devices and instruments...                  stabilizeForm();
         if (m_pInstrumentListForm)  
                 m_pInstrumentListForm->refreshInstruments();  
         if (m_pDeviceForm)  
                 m_pDeviceForm->refreshDevices();  
 }  
2076    
2077                    // remove dead channel strips
2078                    if (bRemoveDeadStrips) {
2079                            for (int i = 0; channelStripAt(i); ++i) {
2080                                    ChannelStrip* pChannelStrip = channelStripAt(i);
2081                                    bool bExists = false;
2082                                    for (int j = 0; piChannelIDs[j] >= 0; ++j) {
2083                                            if (!pChannelStrip->channel()) break;
2084                                            if (piChannelIDs[j] == pChannelStrip->channel()->channelID()) {
2085                                                    // strip exists, don't touch it
2086                                                    bExists = true;
2087                                                    break;
2088                                            }
2089                                    }
2090                                    if (!bExists) destroyChannelStrip(pChannelStrip);
2091                            }
2092                    }
2093                    m_pWorkspace->setUpdatesEnabled(true);
2094            }
2095    }
2096    
2097  // Update the recent files list and menu.  // Update the recent files list and menu.
2098  void MainForm::updateRecentFiles ( const QString& sFilename )  void MainForm::updateRecentFiles ( const QString& sFilename )
# Line 2108  void MainForm::appendMessagesError( cons Line 2266  void MainForm::appendMessagesError( cons
2266          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2267    
2268          QMessageBox::critical(this,          QMessageBox::critical(this,
2269                  QSAMPLER_TITLE ": " + tr("Error"), s, tr("Cancel"));                  QSAMPLER_TITLE ": " + tr("Error"), s, QMessageBox::Cancel);
2270  }  }
2271    
2272    
# Line 2171  void MainForm::updateMessagesCapture (vo Line 2329  void MainForm::updateMessagesCapture (vo
2329  // qsamplerMainForm -- MDI channel strip management.  // qsamplerMainForm -- MDI channel strip management.
2330    
2331  // The channel strip creation executive.  // The channel strip creation executive.
2332  ChannelStrip* MainForm::createChannelStrip(qsamplerChannel* pChannel)  ChannelStrip* MainForm::createChannelStrip ( Channel *pChannel )
2333  {  {
2334          if (m_pClient == NULL || pChannel == NULL)          if (m_pClient == NULL || pChannel == NULL)
2335                  return NULL;                  return NULL;
2336    
         // 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();  
                         }  
                 }  
         }  
   
2337          // Add a new channel itema...          // Add a new channel itema...
2338          pChannelStrip = new ChannelStrip();          ChannelStrip *pChannelStrip = new ChannelStrip();
2339          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
2340                  return NULL;                  return NULL;
2341    
2342          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...  
2343          if (m_pOptions) {          if (m_pOptions) {
2344                  // Background display effect...                  // Background display effect...
2345                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
# Line 2215  ChannelStrip* MainForm::createChannelStr Line 2351  ChannelStrip* MainForm::createChannelStr
2351                  pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                  pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2352          }          }
2353    
2354            // Add it to workspace...
2355            m_pWorkspace->addWindow(pChannelStrip, Qt::FramelessWindowHint);
2356    
2357            // Actual channel strip setup...
2358            pChannelStrip->setup(pChannel);
2359    
2360            QObject::connect(pChannelStrip,
2361                    SIGNAL(channelChanged(ChannelStrip*)),
2362                    SLOT(channelStripChanged(ChannelStrip*)));
2363    
2364          // Now we show up us to the world.          // Now we show up us to the world.
2365          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);  
         }  
2366    
2367          // This is pretty new, so we'll watch for it closely.          // This is pretty new, so we'll watch for it closely.
2368          channelStripChanged(pChannelStrip);          channelStripChanged(pChannelStrip);
# Line 2233  ChannelStrip* MainForm::createChannelStr Line 2371  ChannelStrip* MainForm::createChannelStr
2371          return pChannelStrip;          return pChannelStrip;
2372  }  }
2373    
2374    void MainForm::destroyChannelStrip(ChannelStrip* pChannelStrip) {
2375            // Just delete the channel strip.
2376            delete pChannelStrip;
2377    
2378            // Do we auto-arrange?
2379            if (m_pOptions && m_pOptions->bAutoArrange)
2380                    channelsArrange();
2381    
2382            stabilizeForm();
2383    }
2384    
2385  // Retrieve the active channel strip.  // Retrieve the active channel strip.
2386  ChannelStrip* MainForm::activeChannelStrip (void)  ChannelStrip* MainForm::activeChannelStrip (void)
# Line 2244  ChannelStrip* MainForm::activeChannelStr Line 2392  ChannelStrip* MainForm::activeChannelStr
2392  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2393  ChannelStrip* MainForm::channelStripAt ( int iChannel )  ChannelStrip* MainForm::channelStripAt ( int iChannel )
2394  {  {
2395            if (!m_pWorkspace) return NULL;
2396    
2397          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
2398          if (wlist.isEmpty())          if (wlist.isEmpty())
2399                  return NULL;                  return NULL;
2400    
2401          return static_cast<ChannelStrip *> (wlist.at(iChannel));          if (iChannel < 0 || iChannel >= wlist.size())
2402                    return NULL;
2403    
2404            return dynamic_cast<ChannelStrip *> (wlist.at(iChannel));
2405  }  }
2406    
2407    
# Line 2263  ChannelStrip* MainForm::channelStrip ( i Line 2416  ChannelStrip* MainForm::channelStrip ( i
2416                  ChannelStrip* pChannelStrip                  ChannelStrip* pChannelStrip
2417                          = static_cast<ChannelStrip*> (wlist.at(iChannel));                          = static_cast<ChannelStrip*> (wlist.at(iChannel));
2418                  if (pChannelStrip) {                  if (pChannelStrip) {
2419                          qsamplerChannel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
2420                          if (pChannel && pChannel->channelID() == iChannelID)                          if (pChannel && pChannel->channelID() == iChannelID)
2421                                  return pChannelStrip;                                  return pChannelStrip;
2422                  }                  }
# Line 2401  void MainForm::startServer (void) Line 2554  void MainForm::startServer (void)
2554    
2555          // Is the server process instance still here?          // Is the server process instance still here?
2556          if (m_pServer) {          if (m_pServer) {
2557                  switch (QMessageBox::warning(this,                  if (QMessageBox::warning(this,
2558                          QSAMPLER_TITLE ": " + tr("Warning"),                          QSAMPLER_TITLE ": " + tr("Warning"),
2559                          tr("Could not start the LinuxSampler server.\n\n"                          tr("Could not start the LinuxSampler server.\n\n"
2560                          "Maybe it ss already started."),                          "Maybe it is already started."),
2561                          tr("Stop"), tr("Kill"), tr("Cancel"))) {                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
                 case 0:  
2562                          m_pServer->terminate();                          m_pServer->terminate();
                         break;  
                 case 1:  
2563                          m_pServer->kill();                          m_pServer->kill();
                         break;  
2564                  }                  }
2565                  return;                  return;
2566          }          }
# Line 2424  void MainForm::startServer (void) Line 2573  void MainForm::startServer (void)
2573                  return;                  return;
2574    
2575          // OK. Let's build the startup process...          // OK. Let's build the startup process...
2576          m_pServer = new QProcess(this);          m_pServer = new QProcess();
2577            bForceServerStop = true;
2578    
2579          // Setup stdout/stderr capture...          // Setup stdout/stderr capture...
2580  //      if (m_pOptions->bStdoutCapture) {  //      if (m_pOptions->bStdoutCapture) {
2581                  //m_pServer->setProcessChannelMode(  #if QT_VERSION >= 0x040200
2582                  //      QProcess::StandardOutput);                  m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);
2583    #endif
2584                  QObject::connect(m_pServer,                  QObject::connect(m_pServer,
2585                          SIGNAL(readyReadStandardOutput()),                          SIGNAL(readyReadStandardOutput()),
2586                          SLOT(readServerStdout()));                          SLOT(readServerStdout()));
# Line 2440  void MainForm::startServer (void) Line 2591  void MainForm::startServer (void)
2591    
2592          // The unforgiveable signal communication...          // The unforgiveable signal communication...
2593          QObject::connect(m_pServer,          QObject::connect(m_pServer,
2594                  SIGNAL(finished(int,QProcess::ExitStatus)),                  SIGNAL(finished(int, QProcess::ExitStatus)),
2595                  SLOT(processServerExit()));                  SLOT(processServerExit()));
2596    
2597          // Build process arguments...          // Build process arguments...
# Line 2471  void MainForm::startServer (void) Line 2622  void MainForm::startServer (void)
2622    
2623    
2624  // Stop linuxsampler server...  // Stop linuxsampler server...
2625  void MainForm::stopServer (void)  void MainForm::stopServer (bool bInteractive)
2626  {  {
2627          // Stop client code.          // Stop client code.
2628          stopClient();          stopClient();
2629    
2630            if (m_pServer && bInteractive) {
2631                    if (QMessageBox::question(this,
2632                            QSAMPLER_TITLE ": " + tr("The backend's fate ..."),
2633                            tr("You have the option to keep the sampler backend (LinuxSampler)\n"
2634                            "running in the background. The sampler would continue to work\n"
2635                            "according to your current sampler session and you could alter the\n"
2636                            "sampler session at any time by relaunching QSampler.\n\n"
2637                            "Do you want LinuxSampler to stop?"),
2638                            QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
2639                    {
2640                            bForceServerStop = false;
2641                    }
2642            }
2643    
2644          // And try to stop server.          // And try to stop server.
2645          if (m_pServer) {          if (m_pServer && bForceServerStop) {
2646                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2647                  if (m_pServer->state() == QProcess::Running)                  if (m_pServer->state() == QProcess::Running) {
2648    #if defined(WIN32)
2649                            // Try harder...
2650                            m_pServer->kill();
2651    #else
2652                            // Try softly...
2653                          m_pServer->terminate();                          m_pServer->terminate();
2654          }  #endif
2655                    }
2656            }       // Do final processing anyway.
2657            else processServerExit();
2658    
2659          // Give it some time to terminate gracefully and stabilize...          // Give it some time to terminate gracefully and stabilize...
2660          QTime t;          QTime t;
2661          t.start();          t.start();
2662          while (t.elapsed() < QSAMPLER_TIMER_MSECS)          while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2663                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
   
         // Do final processing anyway.  
         processServerExit();  
2664  }  }
2665    
2666    
# Line 2512  void MainForm::processServerExit (void) Line 2682  void MainForm::processServerExit (void)
2682          if (m_pMessages)          if (m_pMessages)
2683                  m_pMessages->flushStdoutBuffer();                  m_pMessages->flushStdoutBuffer();
2684    
2685          if (m_pServer) {          if (m_pServer && bForceServerStop) {
2686                    if (m_pServer->state() != QProcess::NotRunning) {
2687                            appendMessages(tr("Server is being forced..."));
2688                            // Force final server shutdown...
2689                            m_pServer->kill();
2690                            // Give it some time to terminate gracefully and stabilize...
2691                            QTime t;
2692                            t.start();
2693                            while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2694                                    QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2695                    }
2696                  // Force final server shutdown...                  // Force final server shutdown...
2697                  appendMessages(                  appendMessages(
2698                          tr("Server was stopped with exit status %1.")                          tr("Server was stopped with exit status %1.")
2699                          .arg(m_pServer->exitStatus()));                          .arg(m_pServer->exitStatus()));
                 m_pServer->terminate();  
                 if (!m_pServer->waitForFinished(2000))  
                         m_pServer->kill();  
                 // Destroy it.  
2700                  delete m_pServer;                  delete m_pServer;
2701                  m_pServer = NULL;                  m_pServer = NULL;
2702          }          }
# Line 2545  lscp_status_t qsampler_client_callback ( Line 2721  lscp_status_t qsampler_client_callback (
2721          // as this is run under some other thread context.          // as this is run under some other thread context.
2722          // A custom event must be posted here...          // A custom event must be posted here...
2723          QApplication::postEvent(pMainForm,          QApplication::postEvent(pMainForm,
2724                  new qsamplerCustomEvent(event, pchData, cchData));                  new LscpEvent(event, pchData, cchData));
2725    
2726          return LSCP_OK;          return LSCP_OK;
2727  }  }
# Line 2590  bool MainForm::startClient (void) Line 2766  bool MainForm::startClient (void)
2766                  .arg(::lscp_client_get_timeout(m_pClient)));                  .arg(::lscp_client_get_timeout(m_pClient)));
2767    
2768          // Subscribe to channel info change notifications...          // Subscribe to channel info change notifications...
2769            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT) != LSCP_OK)
2770                    appendMessagesClient("lscp_client_subscribe(CHANNEL_COUNT)");
2771          if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)          if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)
2772                  appendMessagesClient("lscp_client_subscribe");                  appendMessagesClient("lscp_client_subscribe(CHANNEL_INFO)");
2773    
2774            DeviceStatusForm::onDevicesChanged(); // initialize
2775            updateViewMidiDeviceStatusMenu();
2776            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT) != LSCP_OK)
2777                    appendMessagesClient("lscp_client_subscribe(MIDI_INPUT_DEVICE_COUNT)");
2778            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO) != LSCP_OK)
2779                    appendMessagesClient("lscp_client_subscribe(MIDI_INPUT_DEVICE_INFO)");
2780            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT) != LSCP_OK)
2781                    appendMessagesClient("lscp_client_subscribe(AUDIO_OUTPUT_DEVICE_COUNT)");
2782            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO) != LSCP_OK)
2783                    appendMessagesClient("lscp_client_subscribe(AUDIO_OUTPUT_DEVICE_INFO)");
2784    
2785    #if CONFIG_EVENT_CHANNEL_MIDI
2786            // Subscribe to channel MIDI data notifications...
2787            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_MIDI) != LSCP_OK)
2788                    appendMessagesClient("lscp_client_subscribe(CHANNEL_MIDI)");
2789    #endif
2790    
2791    #if CONFIG_EVENT_DEVICE_MIDI
2792            // Subscribe to channel MIDI data notifications...
2793            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_DEVICE_MIDI) != LSCP_OK)
2794                    appendMessagesClient("lscp_client_subscribe(DEVICE_MIDI)");
2795    #endif
2796    
2797          // We may stop scheduling around.          // We may stop scheduling around.
2798          stopSchedule();          stopSchedule();
# Line 2618  bool MainForm::startClient (void) Line 2819  bool MainForm::startClient (void)
2819                  }                  }
2820          }          }
2821    
2822            // send the current / loaded fine tuning settings to the sampler
2823            m_pOptions->sendFineTuningSettings();
2824    
2825          // Make a new session          // Make a new session
2826          return newSession();          return newSession();
2827  }  }
# Line 2645  void MainForm::stopClient (void) Line 2849  void MainForm::stopClient (void)
2849          closeSession(false);          closeSession(false);
2850    
2851          // Close us as a client...          // Close us as a client...
2852    #if CONFIG_EVENT_DEVICE_MIDI
2853            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_DEVICE_MIDI);
2854    #endif
2855    #if CONFIG_EVENT_CHANNEL_MIDI
2856            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_MIDI);
2857    #endif
2858            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO);
2859            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT);
2860            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO);
2861            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT);
2862          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
2863            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);
2864          ::lscp_client_destroy(m_pClient);          ::lscp_client_destroy(m_pClient);
2865          m_pClient = NULL;          m_pClient = NULL;
2866    
# Line 2663  void MainForm::stopClient (void) Line 2878  void MainForm::stopClient (void)
2878          stabilizeForm();          stabilizeForm();
2879  }  }
2880    
2881    
2882    // Channel strip activation/selection.
2883    void MainForm::activateStrip ( QWidget *pWidget )
2884    {
2885            ChannelStrip *pChannelStrip
2886                    = static_cast<ChannelStrip *> (pWidget);
2887            if (pChannelStrip)
2888                    pChannelStrip->setSelected(true);
2889    
2890            stabilizeForm();
2891    }
2892    
2893    
2894  } // namespace QSampler  } // namespace QSampler
2895    
2896    

Legend:
Removed from v.1512  
changed lines
  Added in v.2077

  ViewVC Help
Powered by ViewVC