/[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 1509 by capela, Thu Nov 22 11:10:44 2007 UTC revision 2459 by capela, Mon Jul 8 10:06:57 2013 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-2013, 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 <QMdiArea>
39    #include <QMdiSubWindow>
40    
41  #include <QApplication>  #include <QApplication>
 #include <QWorkspace>  
42  #include <QProcess>  #include <QProcess>
43  #include <QMessageBox>  #include <QMessageBox>
44    
# Line 55  Line 58 
58  #include <QTimer>  #include <QTimer>
59  #include <QDateTime>  #include <QDateTime>
60    
61    #if QT_VERSION >= 0x050000
62    #include <QMimeData>
63    #endif
64    
65    #if QT_VERSION < 0x040500
66    namespace Qt {
67    const WindowFlags WindowCloseButtonHint = WindowFlags(0x08000000);
68    }
69    #endif
70    
71  #ifdef HAVE_SIGNAL_H  #ifdef HAVE_SIGNAL_H
72  #include <signal.h>  #include <signal.h>
# Line 77  static inline long lroundf ( float x ) Line 89  static inline long lroundf ( float x )
89  }  }
90  #endif  #endif
91    
92    
93    // All winsock apps needs this.
94    #if defined(WIN32)
95    static WSADATA _wsaData;
96    #endif
97    
98    
99    //-------------------------------------------------------------------------
100    // LADISH Level 1 support stuff.
101    
102    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
103    
104    #include <QSocketNotifier>
105    
106    #include <sys/types.h>
107    #include <sys/socket.h>
108    
109    #include <signal.h>
110    
111    // File descriptor for SIGUSR1 notifier.
112    static int g_fdUsr1[2];
113    
114    // Unix SIGUSR1 signal handler.
115    static void qsampler_sigusr1_handler ( int /* signo */ )
116    {
117            char c = 1;
118    
119            (::write(g_fdUsr1[0], &c, sizeof(c)) > 0);
120    }
121    
122    #endif  // HAVE_SIGNAL_H
123    
124    
125    //-------------------------------------------------------------------------
126    // qsampler -- namespace
127    
128    
129    namespace QSampler {
130    
131  // Timer constant stuff.  // Timer constant stuff.
132  #define QSAMPLER_TIMER_MSECS    200  #define QSAMPLER_TIMER_MSECS    200
133    
# Line 87  static inline long lroundf ( float x ) Line 138  static inline long lroundf ( float x )
138  #define QSAMPLER_STATUS_SESSION 3       // Current session modification state.  #define QSAMPLER_STATUS_SESSION 3       // Current session modification state.
139    
140    
141  // All winsock apps needs this.  // Specialties for thread-callback comunication.
142  #if defined(WIN32)  #define QSAMPLER_LSCP_EVENT   QEvent::Type(QEvent::User + 1)
 static WSADATA _wsaData;  
 #endif  
143    
144    
145  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
146  // qsamplerCustomEvent -- specialty for callback comunication.  // LscpEvent -- specialty for LSCP callback comunication.
147    
 #define QSAMPLER_CUSTOM_EVENT   QEvent::Type(QEvent::User + 0)  
148    
149  class qsamplerCustomEvent : public QEvent  class LscpEvent : public QEvent
150  {  {
151  public:  public:
152    
153          // Constructor.          // Constructor.
154          qsamplerCustomEvent(lscp_event_t event, const char *pchData, int cchData)          LscpEvent(lscp_event_t event, const char *pchData, int cchData)
155                  : QEvent(QSAMPLER_CUSTOM_EVENT)                  : QEvent(QSAMPLER_LSCP_EVENT)
156          {          {
157                  m_event = event;                  m_event = event;
158                  m_data  = QString::fromUtf8(pchData, cchData);                  m_data  = QString::fromUtf8(pchData, cchData);
# Line 126  private: Line 174  private:
174  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
175  // qsamplerMainForm -- Main window form implementation.  // qsamplerMainForm -- Main window form implementation.
176    
 namespace QSampler {  
   
177  // Kind of singleton reference.  // Kind of singleton reference.
178  MainForm* MainForm::g_pMainForm = NULL;  MainForm* MainForm::g_pMainForm = NULL;
179    
# Line 159  MainForm::MainForm ( QWidget *pParent ) Line 205  MainForm::MainForm ( QWidget *pParent )
205    
206          m_iTimerSlot = 0;          m_iTimerSlot = 0;
207    
208  #ifdef HAVE_SIGNAL_H  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
209    
210          // Set to ignore any fatal "Broken pipe" signals.          // Set to ignore any fatal "Broken pipe" signals.
211          ::signal(SIGPIPE, SIG_IGN);          ::signal(SIGPIPE, SIG_IGN);
212  #endif  
213            // LADISH Level 1 suport.
214    
215            // Initialize file descriptors for SIGUSR1 socket notifier.
216            ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdUsr1);
217            m_pUsr1Notifier
218                    = new QSocketNotifier(g_fdUsr1[1], QSocketNotifier::Read, this);
219    
220            QObject::connect(m_pUsr1Notifier,
221                    SIGNAL(activated(int)),
222                    SLOT(handle_sigusr1()));
223    
224            // Install SIGUSR1 signal handler.
225        struct sigaction usr1;
226        usr1.sa_handler = qsampler_sigusr1_handler;
227        sigemptyset(&usr1.sa_mask);
228        usr1.sa_flags = 0;
229        usr1.sa_flags |= SA_RESTART;
230        ::sigaction(SIGUSR1, &usr1, NULL);
231    
232    #else   // HAVE_SIGNAL_H
233    
234            m_pUsr1Notifier = NULL;
235            
236    #endif  // !HAVE_SIGNAL_H
237    
238  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
239          // Make some extras into the toolbar...          // Make some extras into the toolbar...
# Line 171  MainForm::MainForm ( QWidget *pParent ) Line 242  MainForm::MainForm ( QWidget *pParent )
242          // Volume slider...          // Volume slider...
243          m_ui.channelsToolbar->addSeparator();          m_ui.channelsToolbar->addSeparator();
244          m_pVolumeSlider = new QSlider(Qt::Horizontal, m_ui.channelsToolbar);          m_pVolumeSlider = new QSlider(Qt::Horizontal, m_ui.channelsToolbar);
245          m_pVolumeSlider->setTickPosition(QSlider::TicksBelow);          m_pVolumeSlider->setTickPosition(QSlider::TicksBothSides);
246          m_pVolumeSlider->setTickInterval(10);          m_pVolumeSlider->setTickInterval(10);
247          m_pVolumeSlider->setPageStep(10);          m_pVolumeSlider->setPageStep(10);
248          m_pVolumeSlider->setSingleStep(10);          m_pVolumeSlider->setSingleStep(10);
# Line 189  MainForm::MainForm ( QWidget *pParent ) Line 260  MainForm::MainForm ( QWidget *pParent )
260          // Volume spin-box          // Volume spin-box
261          m_ui.channelsToolbar->addSeparator();          m_ui.channelsToolbar->addSeparator();
262          m_pVolumeSpinBox = new QSpinBox(m_ui.channelsToolbar);          m_pVolumeSpinBox = new QSpinBox(m_ui.channelsToolbar);
263            m_pVolumeSpinBox->setMaximumHeight(24);
264          m_pVolumeSpinBox->setSuffix(" %");          m_pVolumeSpinBox->setSuffix(" %");
265          m_pVolumeSpinBox->setMinimum(0);          m_pVolumeSpinBox->setMinimum(0);
266          m_pVolumeSpinBox->setMaximum(100);          m_pVolumeSpinBox->setMaximum(100);
# Line 200  MainForm::MainForm ( QWidget *pParent ) Line 272  MainForm::MainForm ( QWidget *pParent )
272  #endif  #endif
273    
274          // Make it an MDI workspace.          // Make it an MDI workspace.
275          m_pWorkspace = new QWorkspace(this);          m_pWorkspace = new QMdiArea(this);
276          m_pWorkspace->setScrollBarsEnabled(true);          m_pWorkspace->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
277            m_pWorkspace->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
278          // Set the activation connection.          // Set the activation connection.
279          QObject::connect(m_pWorkspace,          QObject::connect(m_pWorkspace,
280                  SIGNAL(windowActivated(QWidget *)),                  SIGNAL(subWindowActivated(QMdiSubWindow *)),
281                  SLOT(stabilizeForm()));                  SLOT(activateStrip(QMdiSubWindow *)));
282          // Make it shine :-)          // Make it shine :-)
283          setCentralWidget(m_pWorkspace);          setCentralWidget(m_pWorkspace);
284    
# Line 238  MainForm::MainForm ( QWidget *pParent ) Line 311  MainForm::MainForm ( QWidget *pParent )
311          WSAStartup(MAKEWORD(1, 1), &_wsaData);          WSAStartup(MAKEWORD(1, 1), &_wsaData);
312  #endif  #endif
313    
314            // Some actions surely need those
315            // shortcuts firmly attached...
316            addAction(m_ui.viewMenubarAction);
317            addAction(m_ui.viewToolbarAction);
318    
319          QObject::connect(m_ui.fileNewAction,          QObject::connect(m_ui.fileNewAction,
320                  SIGNAL(triggered()),                  SIGNAL(triggered()),
321                  SLOT(fileNew()));                  SLOT(fileNew()));
# Line 329  MainForm::~MainForm() Line 407  MainForm::~MainForm()
407          WSACleanup();          WSACleanup();
408  #endif  #endif
409    
410    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
411            if (m_pUsr1Notifier)
412                    delete m_pUsr1Notifier;
413    #endif
414    
415          // Finally drop any widgets around...          // Finally drop any widgets around...
416          if (m_pDeviceForm)          if (m_pDeviceForm)
417                  delete m_pDeviceForm;                  delete m_pDeviceForm;
# Line 360  MainForm::~MainForm() Line 443  MainForm::~MainForm()
443    
444    
445  // Make and set a proper setup options step.  // Make and set a proper setup options step.
446  void MainForm::setup ( qsamplerOptions *pOptions )  void MainForm::setup ( Options *pOptions )
447  {  {
448          // We got options?          // We got options?
449          m_pOptions = pOptions;          m_pOptions = pOptions;
450    
451          // What style do we create these forms?          // What style do we create these forms?
452          Qt::WindowFlags wflags = Qt::Window          Qt::WindowFlags wflags = Qt::Window
 #if QT_VERSION >= 0x040200  
453                  | Qt::CustomizeWindowHint                  | Qt::CustomizeWindowHint
 #endif  
454                  | Qt::WindowTitleHint                  | Qt::WindowTitleHint
455                  | Qt::WindowSystemMenuHint                  | Qt::WindowSystemMenuHint
456                  | Qt::WindowMinMaxButtonsHint;                  | Qt::WindowMinMaxButtonsHint
457                    | Qt::WindowCloseButtonHint;
458          if (m_pOptions->bKeepOnTop)          if (m_pOptions->bKeepOnTop)
459                  wflags |= Qt::Tool;                  wflags |= Qt::Tool;
460    
461          // Some child forms are to be created right now.          // Some child forms are to be created right now.
462          m_pMessages = new qsamplerMessages(this);          m_pMessages = new Messages(this);
463          m_pDeviceForm = new DeviceForm(this, wflags);          m_pDeviceForm = new DeviceForm(this, wflags);
464  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
465          m_pInstrumentListForm = new InstrumentListForm(this, wflags);          m_pInstrumentListForm = new InstrumentListForm(this, wflags);
466  #else  #else
467          viewInstrumentsAction->setEnabled(false);          m_ui.viewInstrumentsAction->setEnabled(false);
468  #endif  #endif
469    
470            // Setup messages logging appropriately...
471            m_pMessages->setLogging(
472                    m_pOptions->bMessagesLog,
473                    m_pOptions->sMessagesLogPath);
474    
475          // Set message defaults...          // Set message defaults...
476          updateMessagesFont();          updateMessagesFont();
477          updateMessagesLimit();          updateMessagesLimit();
# Line 413  void MainForm::setup ( qsamplerOptions * Line 502  void MainForm::setup ( qsamplerOptions *
502          }          }
503    
504          // Try to restore old window positioning and initial visibility.          // Try to restore old window positioning and initial visibility.
505          m_pOptions->loadWidgetGeometry(this);          m_pOptions->loadWidgetGeometry(this, true);
506          m_pOptions->loadWidgetGeometry(m_pInstrumentListForm);          m_pOptions->loadWidgetGeometry(m_pInstrumentListForm);
507          m_pOptions->loadWidgetGeometry(m_pDeviceForm);          m_pOptions->loadWidgetGeometry(m_pDeviceForm);
508    
# Line 457  bool MainForm::queryClose (void) Line 546  bool MainForm::queryClose (void)
546                          // And the children, and the main windows state,.                          // And the children, and the main windows state,.
547                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);
548                          m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);                          m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
549                          m_pOptions->saveWidgetGeometry(this);                          m_pOptions->saveWidgetGeometry(this, true);
550                          // Close popup widgets.                          // Close popup widgets.
551                          if (m_pInstrumentListForm)                          if (m_pInstrumentListForm)
552                                  m_pInstrumentListForm->close();                                  m_pInstrumentListForm->close();
553                          if (m_pDeviceForm)                          if (m_pDeviceForm)
554                                  m_pDeviceForm->close();                                  m_pDeviceForm->close();
555                          // Stop client and/or server, gracefully.                          // Stop client and/or server, gracefully.
556                          stopServer();                          stopServer(true /*interactive*/);
557                  }                  }
558          }          }
559    
# Line 474  bool MainForm::queryClose (void) Line 563  bool MainForm::queryClose (void)
563    
564  void MainForm::closeEvent ( QCloseEvent *pCloseEvent )  void MainForm::closeEvent ( QCloseEvent *pCloseEvent )
565  {  {
566          if (queryClose())          if (queryClose()) {
567                    DeviceStatusForm::deleteAllInstances();
568                  pCloseEvent->accept();                  pCloseEvent->accept();
569          else          } else
570                  pCloseEvent->ignore();                  pCloseEvent->ignore();
571  }  }
572    
# Line 505  void MainForm::dropEvent ( QDropEvent* p Line 595  void MainForm::dropEvent ( QDropEvent* p
595                  QListIterator<QUrl> iter(pMimeData->urls());                  QListIterator<QUrl> iter(pMimeData->urls());
596                  while (iter.hasNext()) {                  while (iter.hasNext()) {
597                          const QString& sPath = iter.next().toLocalFile();                          const QString& sPath = iter.next().toLocalFile();
598                          if (qsamplerChannel::isInstrumentFile(sPath)) {                  //      if (Channel::isDlsInstrumentFile(sPath)) {
599                            if (QFileInfo(sPath).exists()) {
600                                  // Try to create a new channel from instrument file...                                  // Try to create a new channel from instrument file...
601                                  qsamplerChannel *pChannel = new qsamplerChannel();                                  Channel *pChannel = new Channel();
602                                  if (pChannel == NULL)                                  if (pChannel == NULL)
603                                          return;                                          return;
604                                  // Start setting the instrument filename...                                  // Start setting the instrument filename...
# Line 539  void MainForm::dropEvent ( QDropEvent* p Line 630  void MainForm::dropEvent ( QDropEvent* p
630    
631    
632  // Custome event handler.  // Custome event handler.
633  void MainForm::customEvent(QEvent* pCustomEvent)  void MainForm::customEvent ( QEvent* pEvent )
634  {  {
635          // For the time being, just pump it to messages.          // For the time being, just pump it to messages.
636          if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {          if (pEvent->type() == QSAMPLER_LSCP_EVENT) {
637                  qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;                  LscpEvent *pLscpEvent = static_cast<LscpEvent *> (pEvent);
638                  if (pEvent->event() == LSCP_EVENT_CHANNEL_INFO) {                  switch (pLscpEvent->event()) {
639                          int iChannelID = pEvent->data().toInt();                          case LSCP_EVENT_CHANNEL_COUNT:
640                          ChannelStrip *pChannelStrip = channelStrip(iChannelID);                                  updateAllChannelStrips(true);
641                          if (pChannelStrip)                                  break;
642                                  channelStripChanged(pChannelStrip);                          case LSCP_EVENT_CHANNEL_INFO: {
643                  } else {                                  int iChannelID = pLscpEvent->data().toInt();
644                          appendMessagesColor(tr("Notify event: %1 data: %2")                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);
645                                  .arg(::lscp_event_to_text(pEvent->event()))                                  if (pChannelStrip)
646                                  .arg(pEvent->data()), "#996699");                                          channelStripChanged(pChannelStrip);
647                                    break;
648                            }
649                            case LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT:
650                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
651                                    DeviceStatusForm::onDevicesChanged();
652                                    updateViewMidiDeviceStatusMenu();
653                                    break;
654                            case LSCP_EVENT_MIDI_INPUT_DEVICE_INFO: {
655                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
656                                    const int iDeviceID = pLscpEvent->data().section(' ', 0, 0).toInt();
657                                    DeviceStatusForm::onDeviceChanged(iDeviceID);
658                                    break;
659                            }
660                            case LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT:
661                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
662                                    break;
663                            case LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO:
664                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
665                                    break;
666                    #if CONFIG_EVENT_CHANNEL_MIDI
667                            case LSCP_EVENT_CHANNEL_MIDI: {
668                                    const int iChannelID = pLscpEvent->data().section(' ', 0, 0).toInt();
669                                    ChannelStrip *pChannelStrip = channelStrip(iChannelID);
670                                    if (pChannelStrip)
671                                            pChannelStrip->midiActivityLedOn();
672                                    break;
673                            }
674                    #endif
675                    #if CONFIG_EVENT_DEVICE_MIDI
676                            case LSCP_EVENT_DEVICE_MIDI: {
677                                    const int iDeviceID = pLscpEvent->data().section(' ', 0, 0).toInt();
678                                    const int iPortID   = pLscpEvent->data().section(' ', 1, 1).toInt();
679                                    DeviceStatusForm *pDeviceStatusForm
680                                            = DeviceStatusForm::getInstance(iDeviceID);
681                                    if (pDeviceStatusForm)
682                                            pDeviceStatusForm->midiArrived(iPortID);
683                                    break;
684                            }
685                    #endif
686                            default:
687                                    appendMessagesColor(tr("LSCP Event: %1 data: %2")
688                                            .arg(::lscp_event_to_text(pLscpEvent->event()))
689                                            .arg(pLscpEvent->data()), "#996699");
690                  }                  }
691          }          }
692  }  }
693    
694    
695    // LADISH Level 1 -- SIGUSR1 signal handler.
696    void MainForm::handle_sigusr1 (void)
697    {
698    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
699    
700            char c;
701    
702            if (::read(g_fdUsr1[1], &c, sizeof(c)) > 0)
703                    saveSession(false);
704    
705    #endif
706    }
707    
708    
709    void MainForm::updateViewMidiDeviceStatusMenu (void)
710    {
711            m_ui.viewMidiDeviceStatusMenu->clear();
712            const std::map<int, DeviceStatusForm *> statusForms
713                    = DeviceStatusForm::getInstances();
714            std::map<int, DeviceStatusForm *>::const_iterator iter
715                    = statusForms.begin();
716            for ( ; iter != statusForms.end(); ++iter) {
717                    DeviceStatusForm *pStatusForm = iter->second;
718                    m_ui.viewMidiDeviceStatusMenu->addAction(
719                            pStatusForm->visibleAction());
720            }
721    }
722    
723    
724  // Context menu event handler.  // Context menu event handler.
725  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )
726  {  {
# Line 570  void MainForm::contextMenuEvent( QContex Line 734  void MainForm::contextMenuEvent( QContex
734  // qsamplerMainForm -- Brainless public property accessors.  // qsamplerMainForm -- Brainless public property accessors.
735    
736  // The global options settings property.  // The global options settings property.
737  qsamplerOptions *MainForm::options (void) const  Options *MainForm::options (void) const
738  {  {
739          return m_pOptions;          return m_pOptions;
740  }  }
# Line 688  bool MainForm::saveSession ( bool bPromp Line 852  bool MainForm::saveSession ( bool bPromp
852                                  "\"%1\"\n\n"                                  "\"%1\"\n\n"
853                                  "Do you want to replace it?")                                  "Do you want to replace it?")
854                                  .arg(sFilename),                                  .arg(sFilename),
855                                  tr("Replace"), tr("Cancel")) > 0)                                  QMessageBox::Yes | QMessageBox::No)
856                                    == QMessageBox::No)
857                                  return false;                                  return false;
858                  }                  }
859          }          }
# Line 711  bool MainForm::closeSession ( bool bForc Line 876  bool MainForm::closeSession ( bool bForc
876                          "\"%1\"\n\n"                          "\"%1\"\n\n"
877                          "Do you want to save the changes?")                          "Do you want to save the changes?")
878                          .arg(sessionName(m_sFilename)),                          .arg(sessionName(m_sFilename)),
879                          tr("Save"), tr("Discard"), tr("Cancel"))) {                          QMessageBox::Save |
880                  case 0:     // Save...                          QMessageBox::Discard |
881                            QMessageBox::Cancel)) {
882                    case QMessageBox::Save:
883                          bClose = saveSession(false);                          bClose = saveSession(false);
884                          // Fall thru....                          // Fall thru....
885                  case 1:     // Discard                  case QMessageBox::Discard:
886                          break;                          break;
887                  default:    // Cancel.                  default:    // Cancel.
888                          bClose = false;                          bClose = false;
# Line 727  bool MainForm::closeSession ( bool bForc Line 894  bool MainForm::closeSession ( bool bForc
894          if (bClose) {          if (bClose) {
895                  // Remove all channel strips from sight...                  // Remove all channel strips from sight...
896                  m_pWorkspace->setUpdatesEnabled(false);                  m_pWorkspace->setUpdatesEnabled(false);
897                  QWidgetList wlist = m_pWorkspace->windowList();                  QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
898                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                  for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {
899                          ChannelStrip *pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                          ChannelStrip *pChannelStrip = NULL;
900                            QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);
901                            if (pMdiSubWindow)
902                                    pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
903                          if (pChannelStrip) {                          if (pChannelStrip) {
904                                  qsamplerChannel *pChannel = pChannelStrip->channel();                                  Channel *pChannel = pChannelStrip->channel();
905                                  if (bForce && pChannel)                                  if (bForce && pChannel)
906                                          pChannel->removeChannel();                                          pChannel->removeChannel();
907                                  delete pChannelStrip;                                  delete pChannelStrip;
908                          }                          }
909                            if (pMdiSubWindow)
910                                    delete pMdiSubWindow;
911                  }                  }
912                  m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
913                  // We're now clean, for sure.                  // We're now clean, for sure.
# Line 871  bool MainForm::saveSessionFile ( const Q Line 1043  bool MainForm::saveSessionFile ( const Q
1043    
1044          // Audio device mapping.          // Audio device mapping.
1045          QMap<int, int> audioDeviceMap;          QMap<int, int> audioDeviceMap;
1046          piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Audio);          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);
1047          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
1048                  ts << endl;                  ts << endl;
1049                  qsamplerDevice device(qsamplerDevice::Audio, piDeviceIDs[iDevice]);                  Device device(Device::Audio, piDeviceIDs[iDevice]);
1050                  // Audio device specification...                  // Audio device specification...
1051                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1052                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1053                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
1054                  qsamplerDeviceParamMap::ConstIterator deviceParam;                  DeviceParamMap::ConstIterator deviceParam;
1055                  for (deviceParam = device.params().begin();                  for (deviceParam = device.params().begin();
1056                                  deviceParam != device.params().end();                                  deviceParam != device.params().end();
1057                                          ++deviceParam) {                                          ++deviceParam) {
1058                          const qsamplerDeviceParam& param = deviceParam.value();                          const DeviceParam& param = deviceParam.value();
1059                          if (param.value.isEmpty()) ts << "# ";                          if (param.value.isEmpty()) ts << "# ";
1060                          ts << " " << deviceParam.key() << "='" << param.value << "'";                          ts << " " << deviceParam.key() << "='" << param.value << "'";
1061                  }                  }
1062                  ts << endl;                  ts << endl;
1063                  // Audio channel parameters...                  // Audio channel parameters...
1064                  int iPort = 0;                  int iPort = 0;
1065                  QListIterator<qsamplerDevicePort *> iter(device.ports());                  QListIterator<DevicePort *> iter(device.ports());
1066                  while (iter.hasNext()) {                  while (iter.hasNext()) {
1067                          qsamplerDevicePort *pPort = iter.next();                          DevicePort *pPort = iter.next();
1068                          qsamplerDeviceParamMap::ConstIterator portParam;                          DeviceParamMap::ConstIterator portParam;
1069                          for (portParam = pPort->params().begin();                          for (portParam = pPort->params().begin();
1070                                          portParam != pPort->params().end();                                          portParam != pPort->params().end();
1071                                                  ++portParam) {                                                  ++portParam) {
1072                                  const qsamplerDeviceParam& param = portParam.value();                                  const DeviceParam& param = portParam.value();
1073                                  if (param.fix || param.value.isEmpty()) ts << "# ";                                  if (param.fix || param.value.isEmpty()) ts << "# ";
1074                                  ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice                                  ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice
1075                                          << " " << iPort << " " << portParam.key()                                          << " " << iPort << " " << portParam.key()
# Line 913  bool MainForm::saveSessionFile ( const Q Line 1085  bool MainForm::saveSessionFile ( const Q
1085    
1086          // MIDI device mapping.          // MIDI device mapping.
1087          QMap<int, int> midiDeviceMap;          QMap<int, int> midiDeviceMap;
1088          piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Midi);          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);
1089          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
1090                  ts << endl;                  ts << endl;
1091                  qsamplerDevice device(qsamplerDevice::Midi, piDeviceIDs[iDevice]);                  Device device(Device::Midi, piDeviceIDs[iDevice]);
1092                  // MIDI device specification...                  // MIDI device specification...
1093                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1094                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1095                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
1096                  qsamplerDeviceParamMap::ConstIterator deviceParam;                  DeviceParamMap::ConstIterator deviceParam;
1097                  for (deviceParam = device.params().begin();                  for (deviceParam = device.params().begin();
1098                                  deviceParam != device.params().end();                                  deviceParam != device.params().end();
1099                                          ++deviceParam) {                                          ++deviceParam) {
1100                          const qsamplerDeviceParam& param = deviceParam.value();                          const DeviceParam& param = deviceParam.value();
1101                          if (param.value.isEmpty()) ts << "# ";                          if (param.value.isEmpty()) ts << "# ";
1102                          ts << " " << deviceParam.key() << "='" << param.value << "'";                          ts << " " << deviceParam.key() << "='" << param.value << "'";
1103                  }                  }
1104                  ts << endl;                  ts << endl;
1105                  // MIDI port parameters...                  // MIDI port parameters...
1106                  int iPort = 0;                  int iPort = 0;
1107                  QListIterator<qsamplerDevicePort *> iter(device.ports());                  QListIterator<DevicePort *> iter(device.ports());
1108                  while (iter.hasNext()) {                  while (iter.hasNext()) {
1109                          qsamplerDevicePort *pPort = iter.next();                          DevicePort *pPort = iter.next();
1110                          qsamplerDeviceParamMap::ConstIterator portParam;                          DeviceParamMap::ConstIterator portParam;
1111                          for (portParam = pPort->params().begin();                          for (portParam = pPort->params().begin();
1112                                          portParam != pPort->params().end();                                          portParam != pPort->params().end();
1113                                                  ++portParam) {                                                  ++portParam) {
1114                                  const qsamplerDeviceParam& param = portParam.value();                                  const DeviceParam& param = portParam.value();
1115                                  if (param.fix || param.value.isEmpty()) ts << "# ";                                  if (param.fix || param.value.isEmpty()) ts << "# ";
1116                                  ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice                                  ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice
1117                                  << " " << iPort << " " << portParam.key()                                  << " " << iPort << " " << portParam.key()
# Line 1026  bool MainForm::saveSessionFile ( const Q Line 1198  bool MainForm::saveSessionFile ( const Q
1198  #endif  // CONFIG_MIDI_INSTRUMENT  #endif  // CONFIG_MIDI_INSTRUMENT
1199    
1200          // Sampler channel mapping.          // Sampler channel mapping.
1201          QWidgetList wlist = m_pWorkspace->windowList();          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
1202          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {
1203                  ChannelStrip* pChannelStrip                  ChannelStrip *pChannelStrip = NULL;
1204                          = static_cast<ChannelStrip *> (wlist.at(iChannel));                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);
1205                    if (pMdiSubWindow)
1206                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
1207                  if (pChannelStrip) {                  if (pChannelStrip) {
1208                          qsamplerChannel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1209                          if (pChannel) {                          if (pChannel) {
1210                                  ts << "# " << tr("Channel") << " " << iChannel << endl;                                  ts << "# " << tr("Channel") << " " << iChannel << endl;
1211                                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
# Line 1063  bool MainForm::saveSessionFile ( const Q Line 1237  bool MainForm::saveSessionFile ( const Q
1237                                  ts << "LOAD INSTRUMENT NON_MODAL '"                                  ts << "LOAD INSTRUMENT NON_MODAL '"
1238                                          << pChannel->instrumentFile() << "' "                                          << pChannel->instrumentFile() << "' "
1239                                          << pChannel->instrumentNr() << " " << iChannel << endl;                                          << pChannel->instrumentNr() << " " << iChannel << endl;
1240                                  qsamplerChannelRoutingMap::ConstIterator audioRoute;                                  ChannelRoutingMap::ConstIterator audioRoute;
1241                                  for (audioRoute = pChannel->audioRouting().begin();                                  for (audioRoute = pChannel->audioRouting().begin();
1242                                                  audioRoute != pChannel->audioRouting().end();                                                  audioRoute != pChannel->audioRouting().end();
1243                                                          ++audioRoute) {                                                          ++audioRoute) {
# Line 1077  bool MainForm::saveSessionFile ( const Q Line 1251  bool MainForm::saveSessionFile ( const Q
1251                                          ts << "SET CHANNEL MUTE " << iChannel << " 1" << endl;                                          ts << "SET CHANNEL MUTE " << iChannel << " 1" << endl;
1252                                  if (pChannel->channelSolo())                                  if (pChannel->channelSolo())
1253                                          ts << "SET CHANNEL SOLO " << iChannel << " 1" << endl;                                          ts << "SET CHANNEL SOLO " << iChannel << " 1" << endl;
1254  #ifdef CONFIG_MIDI_INSTRUMENT                          #ifdef CONFIG_MIDI_INSTRUMENT
1255                                  if (pChannel->midiMap() >= 0) {                                  if (pChannel->midiMap() >= 0) {
1256                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannel                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannel
1257                                                  << " " << midiInstrumentMap[pChannel->midiMap()] << endl;                                                  << " " << midiInstrumentMap[pChannel->midiMap()] << endl;
1258                                  }                                  }
1259  #endif                          #endif
1260  #ifdef CONFIG_FXSEND                          #ifdef CONFIG_FXSEND
1261                                  int iChannelID = pChannel->channelID();                                  int iChannelID = pChannel->channelID();
1262                                  int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID);                                  int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID);
1263                                  for (int iFxSend = 0;                                  for (int iFxSend = 0;
# Line 1107  bool MainForm::saveSessionFile ( const Q Line 1281  bool MainForm::saveSessionFile ( const Q
1281                                                                  << " " << iAudioSrc                                                                  << " " << iAudioSrc
1282                                                                  << " " << piRouting[iAudioSrc] << endl;                                                                  << " " << piRouting[iAudioSrc] << endl;
1283                                                  }                                                  }
1284  #ifdef CONFIG_FXSEND_LEVEL                                          #ifdef CONFIG_FXSEND_LEVEL
1285                                                  ts << "SET FX_SEND LEVEL " << iChannel                                                  ts << "SET FX_SEND LEVEL " << iChannel
1286                                                          << " " << iFxSend                                                          << " " << iFxSend
1287                                                          << " " << pFxSendInfo->level << endl;                                                          << " " << pFxSendInfo->level << endl;
1288  #endif                                          #endif
1289                                          }       // Check for errors...                                          }       // Check for errors...
1290                                          else if (::lscp_client_get_errno(m_pClient)) {                                          else if (::lscp_client_get_errno(m_pClient)) {
1291                                                  appendMessagesClient("lscp_get_fxsend_info");                                                  appendMessagesClient("lscp_get_fxsend_info");
1292                                                  iErrors++;                                                  iErrors++;
1293                                          }                                          }
1294                                  }                                  }
1295  #endif                          #endif
1296                                  ts << endl;                                  ts << endl;
1297                          }                          }
1298                  }                  }
# Line 1236  void MainForm::fileReset (void) Line 1410  void MainForm::fileReset (void)
1410                  "Please note that this operation may cause\n"                  "Please note that this operation may cause\n"
1411                  "temporary MIDI and Audio disruption.\n\n"                  "temporary MIDI and Audio disruption.\n\n"
1412                  "Do you want to reset the sampler engine now?"),                  "Do you want to reset the sampler engine now?"),
1413                  tr("Reset"), tr("Cancel")) > 0)                  QMessageBox::Ok | QMessageBox::Cancel)
1414                    == QMessageBox::Cancel)
1415                  return;                  return;
1416    
1417          // Trye closing the current session, first...          // Trye closing the current session, first...
# Line 1277  void MainForm::fileRestart (void) Line 1452  void MainForm::fileRestart (void)
1452                          "Please note that this operation may cause\n"                          "Please note that this operation may cause\n"
1453                          "temporary MIDI and Audio disruption.\n\n"                          "temporary MIDI and Audio disruption.\n\n"
1454                          "Do you want to restart the connection now?"),                          "Do you want to restart the connection now?"),
1455                          tr("Restart"), tr("Cancel")) == 0);                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok);
1456          }          }
1457    
1458          // Are we still for it?          // Are we still for it?
# Line 1308  void MainForm::editAddChannel (void) Line 1483  void MainForm::editAddChannel (void)
1483                  return;                  return;
1484    
1485          // Just create the channel instance...          // Just create the channel instance...
1486          qsamplerChannel *pChannel = new qsamplerChannel();          Channel *pChannel = new Channel();
1487          if (pChannel == NULL)          if (pChannel == NULL)
1488                  return;                  return;
1489    
# Line 1326  void MainForm::editAddChannel (void) Line 1501  void MainForm::editAddChannel (void)
1501                  return;                  return;
1502          }          }
1503    
1504            // Do we auto-arrange?
1505            if (m_pOptions && m_pOptions->bAutoArrange)
1506                    channelsArrange();
1507    
1508          // Make that an overall update.          // Make that an overall update.
1509          m_iDirtyCount++;          m_iDirtyCount++;
1510          stabilizeForm();          stabilizeForm();
# Line 1338  void MainForm::editRemoveChannel (void) Line 1517  void MainForm::editRemoveChannel (void)
1517          if (m_pClient == NULL)          if (m_pClient == NULL)
1518                  return;                  return;
1519    
1520          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1521          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1522                  return;                  return;
1523    
1524          qsamplerChannel *pChannel = pChannelStrip->channel();          Channel *pChannel = pChannelStrip->channel();
1525          if (pChannel == NULL)          if (pChannel == NULL)
1526                  return;                  return;
1527    
# Line 1354  void MainForm::editRemoveChannel (void) Line 1533  void MainForm::editRemoveChannel (void)
1533                          "%1\n\n"                          "%1\n\n"
1534                          "Are you sure?")                          "Are you sure?")
1535                          .arg(pChannelStrip->windowTitle()),                          .arg(pChannelStrip->windowTitle()),
1536                          tr("OK"), tr("Cancel")) > 0)                          QMessageBox::Ok | QMessageBox::Cancel)
1537                            == QMessageBox::Cancel)
1538                          return;                          return;
1539          }          }
1540    
# Line 1362  void MainForm::editRemoveChannel (void) Line 1542  void MainForm::editRemoveChannel (void)
1542          if (!pChannel->removeChannel())          if (!pChannel->removeChannel())
1543                  return;                  return;
1544    
         // Just delete the channel strip.  
         delete pChannelStrip;  
   
         // Do we auto-arrange?  
         if (m_pOptions && m_pOptions->bAutoArrange)  
                 channelsArrange();  
   
1545          // We'll be dirty, for sure...          // We'll be dirty, for sure...
1546          m_iDirtyCount++;          m_iDirtyCount++;
1547          stabilizeForm();  
1548            // Just delete the channel strip.
1549            destroyChannelStrip(pChannelStrip);
1550  }  }
1551    
1552    
# Line 1381  void MainForm::editSetupChannel (void) Line 1556  void MainForm::editSetupChannel (void)
1556          if (m_pClient == NULL)          if (m_pClient == NULL)
1557                  return;                  return;
1558    
1559          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1560          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1561                  return;                  return;
1562    
# Line 1396  void MainForm::editEditChannel (void) Line 1571  void MainForm::editEditChannel (void)
1571          if (m_pClient == NULL)          if (m_pClient == NULL)
1572                  return;                  return;
1573    
1574          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1575          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1576                  return;                  return;
1577    
# Line 1411  void MainForm::editResetChannel (void) Line 1586  void MainForm::editResetChannel (void)
1586          if (m_pClient == NULL)          if (m_pClient == NULL)
1587                  return;                  return;
1588    
1589          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1590          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1591                  return;                  return;
1592    
# Line 1429  void MainForm::editResetAllChannels (voi Line 1604  void MainForm::editResetAllChannels (voi
1604          // Invoque the channel strip procedure,          // Invoque the channel strip procedure,
1605          // for all channels out there...          // for all channels out there...
1606          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1607          QWidgetList wlist = m_pWorkspace->windowList();          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
1608          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {
1609                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  ChannelStrip *pChannelStrip = NULL;
1610                    QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);
1611                    if (pMdiSubWindow)
1612                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
1613                  if (pChannelStrip)                  if (pChannelStrip)
1614                          pChannelStrip->channelReset();                          pChannelStrip->channelReset();
1615          }          }
# Line 1534  void MainForm::viewOptions (void) Line 1712  void MainForm::viewOptions (void)
1712          OptionsForm* pOptionsForm = new OptionsForm(this);          OptionsForm* pOptionsForm = new OptionsForm(this);
1713          if (pOptionsForm) {          if (pOptionsForm) {
1714                  // Check out some initial nullities(tm)...                  // Check out some initial nullities(tm)...
1715                  ChannelStrip* pChannelStrip = activeChannelStrip();                  ChannelStrip *pChannelStrip = activeChannelStrip();
1716                  if (m_pOptions->sDisplayFont.isEmpty() && pChannelStrip)                  if (m_pOptions->sDisplayFont.isEmpty() && pChannelStrip)
1717                          m_pOptions->sDisplayFont = pChannelStrip->displayFont().toString();                          m_pOptions->sDisplayFont = pChannelStrip->displayFont().toString();
1718                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)
# Line 1545  void MainForm::viewOptions (void) Line 1723  void MainForm::viewOptions (void)
1723                  int     iOldServerTimeout   = m_pOptions->iServerTimeout;                  int     iOldServerTimeout   = m_pOptions->iServerTimeout;
1724                  bool    bOldServerStart     = m_pOptions->bServerStart;                  bool    bOldServerStart     = m_pOptions->bServerStart;
1725                  QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;                  QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;
1726                    bool    bOldMessagesLog     = m_pOptions->bMessagesLog;
1727                    QString sOldMessagesLogPath = m_pOptions->sMessagesLogPath;
1728                  QString sOldDisplayFont     = m_pOptions->sDisplayFont;                  QString sOldDisplayFont     = m_pOptions->sDisplayFont;
1729                  bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;                  bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1730                  int     iOldMaxVolume       = m_pOptions->iMaxVolume;                  int     iOldMaxVolume       = m_pOptions->iMaxVolume;
# Line 1556  void MainForm::viewOptions (void) Line 1736  void MainForm::viewOptions (void)
1736                  bool    bOldCompletePath    = m_pOptions->bCompletePath;                  bool    bOldCompletePath    = m_pOptions->bCompletePath;
1737                  bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;                  bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1738                  int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;                  int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1739                    int     iOldBaseFontSize    = m_pOptions->iBaseFontSize;
1740                  // Load the current setup settings.                  // Load the current setup settings.
1741                  pOptionsForm->setup(m_pOptions);                  pOptionsForm->setup(m_pOptions);
1742                  // Show the setup dialog...                  // Show the setup dialog...
# Line 1564  void MainForm::viewOptions (void) Line 1745  void MainForm::viewOptions (void)
1745                          if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||                          if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1746                                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||                                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||
1747                                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||                                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1748                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)) {                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)     ||
1749                                    (iOldBaseFontSize   !=  m_pOptions->iBaseFontSize)) {
1750                                  QMessageBox::information(this,                                  QMessageBox::information(this,
1751                                          QSAMPLER_TITLE ": " + tr("Information"),                                          QSAMPLER_TITLE ": " + tr("Information"),
1752                                          tr("Some settings may be only effective\n"                                          tr("Some settings may be only effective\n"
1753                                          "next time you start this program."), tr("OK"));                                          "next time you start this program."));
1754                                  updateMessagesCapture();                                  updateMessagesCapture();
1755                          }                          }
1756                          // Check wheather something immediate has changed.                          // Check wheather something immediate has changed.
1757                            if (( bOldMessagesLog && !m_pOptions->bMessagesLog) ||
1758                                    (!bOldMessagesLog &&  m_pOptions->bMessagesLog) ||
1759                                    (sOldMessagesLogPath != m_pOptions->sMessagesLogPath))
1760                                    m_pMessages->setLogging(
1761                                            m_pOptions->bMessagesLog, m_pOptions->sMessagesLogPath);
1762                          if (( bOldCompletePath && !m_pOptions->bCompletePath) ||                          if (( bOldCompletePath && !m_pOptions->bCompletePath) ||
1763                                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||                                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||
1764                                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))                                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))
# Line 1618  void MainForm::viewOptions (void) Line 1805  void MainForm::viewOptions (void)
1805  void MainForm::channelsArrange (void)  void MainForm::channelsArrange (void)
1806  {  {
1807          // Full width vertical tiling          // Full width vertical tiling
1808          QWidgetList wlist = m_pWorkspace->windowList();          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
1809          if (wlist.isEmpty())          if (wlist.isEmpty())
1810                  return;                  return;
1811    
1812          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1813          int y = 0;          int y = 0;
1814          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {
1815                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  ChannelStrip *pChannelStrip = NULL;
1816          /*  if (pChannelStrip->testWState(WState_Maximized | WState_Minimized)) {                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);
1817                          // Prevent flicker...                  if (pMdiSubWindow)
1818                          pChannelStrip->hide();                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
1819                          pChannelStrip->showNormal();                  if (pChannelStrip) {
1820                  }   */                  /*  if (pChannelStrip->testWState(WState_Maximized | WState_Minimized)) {
1821                  pChannelStrip->adjustSize();                                  // Prevent flicker...
1822                  int iWidth  = m_pWorkspace->width();                                  pChannelStrip->hide();
1823                  if (iWidth < pChannelStrip->width())                                  pChannelStrip->showNormal();
1824                          iWidth = pChannelStrip->width();                          }   */
1825          //  int iHeight = pChannelStrip->height()                          pChannelStrip->adjustSize();
1826          //              + pChannelStrip->parentWidget()->baseSize().height();                          int iWidth  = m_pWorkspace->width();
1827                  int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();                          if (iWidth < pChannelStrip->width())
1828                  pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);                                  iWidth = pChannelStrip->width();
1829                  y += iHeight;                  //  int iHeight = pChannelStrip->height()
1830                    //              + pChannelStrip->parentWidget()->baseSize().height();
1831                            int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
1832                            pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
1833                            y += iHeight;
1834                    }
1835          }          }
1836          m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
1837    
# Line 1726  void MainForm::helpAbout (void) Line 1918  void MainForm::helpAbout (void)
1918          sText += tr("Instrument editing support disabled.");          sText += tr("Instrument editing support disabled.");
1919          sText += "</font></small><br />";          sText += "</font></small><br />";
1920  #endif  #endif
1921    #ifndef CONFIG_EVENT_CHANNEL_MIDI
1922            sText += "<small><font color=\"red\">";
1923            sText += tr("Channel MIDI event support disabled.");
1924            sText += "</font></small><br />";
1925    #endif
1926    #ifndef CONFIG_EVENT_DEVICE_MIDI
1927            sText += "<small><font color=\"red\">";
1928            sText += tr("Device MIDI event support disabled.");
1929            sText += "</font></small><br />";
1930    #endif
1931    #ifndef CONFIG_MAX_VOICES
1932            sText += "<small><font color=\"red\">";
1933            sText += tr("Runtime max. voices / disk streams support disabled.");
1934            sText += "</font></small><br />";
1935    #endif
1936          sText += "<br />\n";          sText += "<br />\n";
1937          sText += tr("Using") + ": ";          sText += tr("Using") + ": ";
1938          sText += ::lscp_client_package();          sText += ::lscp_client_package();
# Line 1766  void MainForm::stabilizeForm (void) Line 1973  void MainForm::stabilizeForm (void)
1973          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));
1974    
1975          // Update the main menu state...          // Update the main menu state...
1976          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1977          bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);          bool bHasClient = (m_pOptions != NULL && m_pClient != NULL);
1978          bool bHasChannel = (bHasClient && pChannelStrip != NULL);          bool bHasChannel = (bHasClient && pChannelStrip != NULL);
1979            bool bHasChannels = (bHasClient && m_pWorkspace->subWindowList().count() > 0);
1980          m_ui.fileNewAction->setEnabled(bHasClient);          m_ui.fileNewAction->setEnabled(bHasClient);
1981          m_ui.fileOpenAction->setEnabled(bHasClient);          m_ui.fileOpenAction->setEnabled(bHasClient);
1982          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
# Line 1784  void MainForm::stabilizeForm (void) Line 1992  void MainForm::stabilizeForm (void)
1992          m_ui.editEditChannelAction->setEnabled(false);          m_ui.editEditChannelAction->setEnabled(false);
1993  #endif  #endif
1994          m_ui.editResetChannelAction->setEnabled(bHasChannel);          m_ui.editResetChannelAction->setEnabled(bHasChannel);
1995          m_ui.editResetAllChannelsAction->setEnabled(bHasChannel);          m_ui.editResetAllChannelsAction->setEnabled(bHasChannels);
1996          m_ui.viewMessagesAction->setChecked(m_pMessages && m_pMessages->isVisible());          m_ui.viewMessagesAction->setChecked(m_pMessages && m_pMessages->isVisible());
1997  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
1998          m_ui.viewInstrumentsAction->setChecked(m_pInstrumentListForm          m_ui.viewInstrumentsAction->setChecked(m_pInstrumentListForm
# Line 1796  void MainForm::stabilizeForm (void) Line 2004  void MainForm::stabilizeForm (void)
2004          m_ui.viewDevicesAction->setChecked(m_pDeviceForm          m_ui.viewDevicesAction->setChecked(m_pDeviceForm
2005                  && m_pDeviceForm->isVisible());                  && m_pDeviceForm->isVisible());
2006          m_ui.viewDevicesAction->setEnabled(bHasClient);          m_ui.viewDevicesAction->setEnabled(bHasClient);
2007          m_ui.channelsArrangeAction->setEnabled(bHasChannel);          m_ui.viewMidiDeviceStatusMenu->setEnabled(
2008                    DeviceStatusForm::getInstances().size() > 0);
2009            m_ui.channelsArrangeAction->setEnabled(bHasChannels);
2010    
2011  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
2012          // Toolbar widgets are also affected...          // Toolbar widgets are also affected...
# Line 1862  void MainForm::volumeChanged ( int iVolu Line 2072  void MainForm::volumeChanged ( int iVolu
2072    
2073    
2074  // Channel change receiver slot.  // Channel change receiver slot.
2075  void MainForm::channelStripChanged(ChannelStrip* pChannelStrip)  void MainForm::channelStripChanged ( ChannelStrip *pChannelStrip )
2076  {  {
2077          // Add this strip to the changed list...          // Add this strip to the changed list...
2078          if (!m_changedStrips.contains(pChannelStrip)) {          if (!m_changedStrips.contains(pChannelStrip)) {
# Line 1900  void MainForm::updateSession (void) Line 2110  void MainForm::updateSession (void)
2110          }          }
2111  #endif  #endif
2112    
2113            updateAllChannelStrips(false);
2114    
2115            // Do we auto-arrange?
2116            if (m_pOptions && m_pOptions->bAutoArrange)
2117                    channelsArrange();
2118    
2119            // Remember to refresh devices and instruments...
2120            if (m_pInstrumentListForm)
2121                    m_pInstrumentListForm->refreshInstruments();
2122            if (m_pDeviceForm)
2123                    m_pDeviceForm->refreshDevices();
2124    }
2125    
2126    
2127    void MainForm::updateAllChannelStrips ( bool bRemoveDeadStrips )
2128    {
2129          // Retrieve the current channel list.          // Retrieve the current channel list.
2130          int *piChannelIDs = ::lscp_list_channels(m_pClient);          int *piChannelIDs = ::lscp_list_channels(m_pClient);
2131          if (piChannelIDs == NULL) {          if (piChannelIDs == NULL) {
# Line 1911  void MainForm::updateSession (void) Line 2137  void MainForm::updateSession (void)
2137          } else {          } else {
2138                  // Try to (re)create each channel.                  // Try to (re)create each channel.
2139                  m_pWorkspace->setUpdatesEnabled(false);                  m_pWorkspace->setUpdatesEnabled(false);
2140                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {
2141                          // Check if theres already a channel strip for this one...                          // Check if theres already a channel strip for this one...
2142                          if (!channelStrip(piChannelIDs[iChannel]))                          if (!channelStrip(piChannelIDs[iChannel]))
2143                                  createChannelStrip(new qsamplerChannel(piChannelIDs[iChannel]));                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));
2144                    }
2145                    // Do we auto-arrange?
2146                    if (m_pOptions && m_pOptions->bAutoArrange)
2147                            channelsArrange();
2148                    // remove dead channel strips
2149                    if (bRemoveDeadStrips) {
2150                            QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
2151                            for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {
2152                                    ChannelStrip *pChannelStrip = NULL;
2153                                    QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);
2154                                    if (pMdiSubWindow)
2155                                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2156                                    if (pChannelStrip) {
2157                                            bool bExists = false;
2158                                            for (int j = 0; piChannelIDs[j] >= 0; ++j) {
2159                                                    if (!pChannelStrip->channel())
2160                                                            break;
2161                                                    if (piChannelIDs[j] == pChannelStrip->channel()->channelID()) {
2162                                                            // strip exists, don't touch it
2163                                                            bExists = true;
2164                                                            break;
2165                                                    }
2166                                            }
2167                                            if (!bExists)
2168                                                    destroyChannelStrip(pChannelStrip);
2169                                    }
2170                            }
2171                  }                  }
2172                  m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
2173          }          }
2174    
2175          // Do we auto-arrange?          stabilizeForm();
         if (m_pOptions && m_pOptions->bAutoArrange)  
                 channelsArrange();  
   
         // Remember to refresh devices and instruments...  
         if (m_pInstrumentListForm)  
                 m_pInstrumentListForm->refreshInstruments();  
         if (m_pDeviceForm)  
                 m_pDeviceForm->refreshDevices();  
2176  }  }
2177    
2178    
# Line 1977  void MainForm::updateRecentFilesMenu (vo Line 2222  void MainForm::updateRecentFilesMenu (vo
2222  void MainForm::updateInstrumentNames (void)  void MainForm::updateInstrumentNames (void)
2223  {  {
2224          // Full channel list update...          // Full channel list update...
2225          QWidgetList wlist = m_pWorkspace->windowList();          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
2226          if (wlist.isEmpty())          if (wlist.isEmpty())
2227                  return;                  return;
2228    
2229          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2230          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {
2231                  ChannelStrip *pChannelStrip = (ChannelStrip *) wlist.at(iChannel);                  ChannelStrip *pChannelStrip = (ChannelStrip *) wlist.at(iChannel);
2232                  if (pChannelStrip)                  if (pChannelStrip)
2233                          pChannelStrip->updateInstrumentName(true);                          pChannelStrip->updateInstrumentName(true);
# Line 2006  void MainForm::updateDisplayFont (void) Line 2251  void MainForm::updateDisplayFont (void)
2251                  return;                  return;
2252    
2253          // Full channel list update...          // Full channel list update...
2254          QWidgetList wlist = m_pWorkspace->windowList();          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
2255          if (wlist.isEmpty())          if (wlist.isEmpty())
2256                  return;                  return;
2257    
2258          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2259          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {
2260                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  ChannelStrip *pChannelStrip = NULL;
2261                    QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);
2262                    if (pMdiSubWindow)
2263                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2264                  if (pChannelStrip)                  if (pChannelStrip)
2265                          pChannelStrip->setDisplayFont(font);                          pChannelStrip->setDisplayFont(font);
2266          }          }
# Line 2024  void MainForm::updateDisplayFont (void) Line 2272  void MainForm::updateDisplayFont (void)
2272  void MainForm::updateDisplayEffect (void)  void MainForm::updateDisplayEffect (void)
2273  {  {
2274          // Full channel list update...          // Full channel list update...
2275          QWidgetList wlist = m_pWorkspace->windowList();          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
2276          if (wlist.isEmpty())          if (wlist.isEmpty())
2277                  return;                  return;
2278    
2279          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2280          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {
2281                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  ChannelStrip *pChannelStrip = NULL;
2282                    QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);
2283                    if (pMdiSubWindow)
2284                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2285                  if (pChannelStrip)                  if (pChannelStrip)
2286                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2287          }          }
# Line 2052  void MainForm::updateMaxVolume (void) Line 2303  void MainForm::updateMaxVolume (void)
2303  #endif  #endif
2304    
2305          // Full channel list update...          // Full channel list update...
2306          QWidgetList wlist = m_pWorkspace->windowList();          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
2307          if (wlist.isEmpty())          if (wlist.isEmpty())
2308                  return;                  return;
2309    
2310          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2311          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {
2312                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  ChannelStrip *pChannelStrip = NULL;
2313                    QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);
2314                    if (pMdiSubWindow)
2315                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2316                  if (pChannelStrip)                  if (pChannelStrip)
2317                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2318          }          }
# Line 2103  void MainForm::appendMessagesError( cons Line 2357  void MainForm::appendMessagesError( cons
2357          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2358    
2359          QMessageBox::critical(this,          QMessageBox::critical(this,
2360                  QSAMPLER_TITLE ": " + tr("Error"), s, tr("Cancel"));                  QSAMPLER_TITLE ": " + tr("Error"), s, QMessageBox::Cancel);
2361  }  }
2362    
2363    
# Line 2166  void MainForm::updateMessagesCapture (vo Line 2420  void MainForm::updateMessagesCapture (vo
2420  // qsamplerMainForm -- MDI channel strip management.  // qsamplerMainForm -- MDI channel strip management.
2421    
2422  // The channel strip creation executive.  // The channel strip creation executive.
2423  ChannelStrip* MainForm::createChannelStrip(qsamplerChannel* pChannel)  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )
2424  {  {
2425          if (m_pClient == NULL || pChannel == NULL)          if (m_pClient == NULL || pChannel == NULL)
2426                  return NULL;                  return NULL;
2427    
         // 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();  
                         }  
                 }  
         }  
   
2428          // Add a new channel itema...          // Add a new channel itema...
2429          pChannelStrip = new ChannelStrip();          ChannelStrip *pChannelStrip = new ChannelStrip();
2430          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
2431                  return NULL;                  return NULL;
2432    
2433          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...  
2434          if (m_pOptions) {          if (m_pOptions) {
2435                  // Background display effect...                  // Background display effect...
2436                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
# Line 2210  ChannelStrip* MainForm::createChannelStr Line 2442  ChannelStrip* MainForm::createChannelStr
2442                  pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                  pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2443          }          }
2444    
2445            // Add it to workspace...
2446            m_pWorkspace->addSubWindow(pChannelStrip,
2447                    Qt::SubWindow | Qt::FramelessWindowHint);
2448    
2449            // Actual channel strip setup...
2450            pChannelStrip->setup(pChannel);
2451    
2452            QObject::connect(pChannelStrip,
2453                    SIGNAL(channelChanged(ChannelStrip *)),
2454                    SLOT(channelStripChanged(ChannelStrip *)));
2455    
2456          // Now we show up us to the world.          // Now we show up us to the world.
2457          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);  
         }  
2458    
2459          // This is pretty new, so we'll watch for it closely.          // This is pretty new, so we'll watch for it closely.
2460          channelStripChanged(pChannelStrip);          channelStripChanged(pChannelStrip);
# Line 2229  ChannelStrip* MainForm::createChannelStr Line 2464  ChannelStrip* MainForm::createChannelStr
2464  }  }
2465    
2466    
2467    void MainForm::destroyChannelStrip ( ChannelStrip *pChannelStrip )
2468    {
2469            QMdiSubWindow *pMdiSubWindow
2470                    = static_cast<QMdiSubWindow *> (pChannelStrip->parentWidget());
2471            if (pMdiSubWindow == NULL)
2472                    return;
2473    
2474            // Just delete the channel strip.
2475            delete pChannelStrip;
2476            delete pMdiSubWindow;
2477    
2478            // Do we auto-arrange?
2479            if (m_pOptions && m_pOptions->bAutoArrange)
2480                    channelsArrange();
2481    
2482            stabilizeForm();
2483    }
2484    
2485    
2486  // Retrieve the active channel strip.  // Retrieve the active channel strip.
2487  ChannelStrip* MainForm::activeChannelStrip (void)  ChannelStrip *MainForm::activeChannelStrip (void)
2488  {  {
2489          return static_cast<ChannelStrip *> (m_pWorkspace->activeWindow());          QMdiSubWindow *pMdiSubWindow = m_pWorkspace->activeSubWindow();
2490            if (pMdiSubWindow)
2491                    return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2492            else
2493                    return NULL;
2494  }  }
2495    
2496    
2497  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2498  ChannelStrip* MainForm::channelStripAt ( int iChannel )  ChannelStrip *MainForm::channelStripAt ( int iChannel )
2499  {  {
2500          QWidgetList wlist = m_pWorkspace->windowList();          if (!m_pWorkspace) return NULL;
2501    
2502            QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
2503          if (wlist.isEmpty())          if (wlist.isEmpty())
2504                  return NULL;                  return NULL;
2505    
2506          return static_cast<ChannelStrip *> (wlist.at(iChannel));          if (iChannel < 0 || iChannel >= wlist.size())
2507                    return NULL;
2508    
2509            QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);
2510            if (pMdiSubWindow)
2511                    return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2512            else
2513                    return NULL;
2514  }  }
2515    
2516    
2517  // Retrieve a channel strip by sampler channel id.  // Retrieve a channel strip by sampler channel id.
2518  ChannelStrip* MainForm::channelStrip ( int iChannelID )  ChannelStrip *MainForm::channelStrip ( int iChannelID )
2519  {  {
2520          QWidgetList wlist = m_pWorkspace->windowList();          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
2521          if (wlist.isEmpty())          if (wlist.isEmpty())
2522                  return NULL;                  return NULL;
2523    
2524          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {
2525                  ChannelStrip* pChannelStrip                  ChannelStrip *pChannelStrip = NULL;
2526                          = static_cast<ChannelStrip*> (wlist.at(iChannel));                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);
2527                    if (pMdiSubWindow)
2528                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2529                  if (pChannelStrip) {                  if (pChannelStrip) {
2530                          qsamplerChannel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
2531                          if (pChannel && pChannel->channelID() == iChannelID)                          if (pChannel && pChannel->channelID() == iChannelID)
2532                                  return pChannelStrip;                                  return pChannelStrip;
2533                  }                  }
# Line 2276  void MainForm::channelsMenuAboutToShow ( Line 2545  void MainForm::channelsMenuAboutToShow (
2545          m_ui.channelsMenu->addAction(m_ui.channelsArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsArrangeAction);
2546          m_ui.channelsMenu->addAction(m_ui.channelsAutoArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsAutoArrangeAction);
2547    
2548          QWidgetList wlist = m_pWorkspace->windowList();          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
2549          if (!wlist.isEmpty()) {          if (!wlist.isEmpty()) {
2550                  m_ui.channelsMenu->addSeparator();                  m_ui.channelsMenu->addSeparator();
2551                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                  for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {
2552                          ChannelStrip* pChannelStrip                          ChannelStrip *pChannelStrip = NULL;
2553                                  = static_cast<ChannelStrip*> (wlist.at(iChannel));                          QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);
2554                            if (pMdiSubWindow)
2555                                    pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2556                          if (pChannelStrip) {                          if (pChannelStrip) {
2557                                  QAction *pAction = m_ui.channelsMenu->addAction(                                  QAction *pAction = m_ui.channelsMenu->addAction(
2558                                          pChannelStrip->windowTitle(),                                          pChannelStrip->windowTitle(),
# Line 2303  void MainForm::channelsMenuActivated (vo Line 2574  void MainForm::channelsMenuActivated (vo
2574          if (pAction == NULL)          if (pAction == NULL)
2575                  return;                  return;
2576    
2577          ChannelStrip* pChannelStrip = channelStripAt(pAction->data().toInt());          ChannelStrip *pChannelStrip = channelStripAt(pAction->data().toInt());
2578          if (pChannelStrip) {          if (pChannelStrip) {
2579                  pChannelStrip->showNormal();                  pChannelStrip->showNormal();
2580                  pChannelStrip->setFocus();                  pChannelStrip->setFocus();
# Line 2364  void MainForm::timerSlot (void) Line 2635  void MainForm::timerSlot (void)
2635                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {
2636                                  m_iTimerSlot = 0;                                  m_iTimerSlot = 0;
2637                                  // Update the channel stream usage for each strip...                                  // Update the channel stream usage for each strip...
2638                                  QWidgetList wlist = m_pWorkspace->windowList();                                  QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();
2639                                  for (int iChannel = 0;                                  for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {
2640                                                  iChannel < (int) wlist.count(); iChannel++) {                                          ChannelStrip *pChannelStrip = NULL;
2641                                          ChannelStrip* pChannelStrip                                          QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);
2642                                                  = (ChannelStrip*) wlist.at(iChannel);                                          if (pMdiSubWindow)
2643                                                    pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2644                                          if (pChannelStrip && pChannelStrip->isVisible())                                          if (pChannelStrip && pChannelStrip->isVisible())
2645                                                  pChannelStrip->updateChannelUsage();                                                  pChannelStrip->updateChannelUsage();
2646                                  }                                  }
# Line 2396  void MainForm::startServer (void) Line 2668  void MainForm::startServer (void)
2668    
2669          // Is the server process instance still here?          // Is the server process instance still here?
2670          if (m_pServer) {          if (m_pServer) {
2671                  switch (QMessageBox::warning(this,                  if (QMessageBox::warning(this,
2672                          QSAMPLER_TITLE ": " + tr("Warning"),                          QSAMPLER_TITLE ": " + tr("Warning"),
2673                          tr("Could not start the LinuxSampler server.\n\n"                          tr("Could not start the LinuxSampler server.\n\n"
2674                          "Maybe it ss already started."),                          "Maybe it is already started."),
2675                          tr("Stop"), tr("Kill"), tr("Cancel"))) {                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
                 case 0:  
2676                          m_pServer->terminate();                          m_pServer->terminate();
                         break;  
                 case 1:  
2677                          m_pServer->kill();                          m_pServer->kill();
                         break;  
2678                  }                  }
2679                  return;                  return;
2680          }          }
# Line 2419  void MainForm::startServer (void) Line 2687  void MainForm::startServer (void)
2687                  return;                  return;
2688    
2689          // OK. Let's build the startup process...          // OK. Let's build the startup process...
2690          m_pServer = new QProcess(this);          m_pServer = new QProcess();
2691            bForceServerStop = true;
2692    
2693          // Setup stdout/stderr capture...          // Setup stdout/stderr capture...
2694  //      if (m_pOptions->bStdoutCapture) {  //      if (m_pOptions->bStdoutCapture) {
2695                  //m_pServer->setProcessChannelMode(                  m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);
                 //      QProcess::StandardOutput);  
2696                  QObject::connect(m_pServer,                  QObject::connect(m_pServer,
2697                          SIGNAL(readyReadStandardOutput()),                          SIGNAL(readyReadStandardOutput()),
2698                          SLOT(readServerStdout()));                          SLOT(readServerStdout()));
# Line 2435  void MainForm::startServer (void) Line 2703  void MainForm::startServer (void)
2703    
2704          // The unforgiveable signal communication...          // The unforgiveable signal communication...
2705          QObject::connect(m_pServer,          QObject::connect(m_pServer,
2706                  SIGNAL(finished(int,QProcess::ExitStatus)),                  SIGNAL(finished(int, QProcess::ExitStatus)),
2707                  SLOT(processServerExit()));                  SLOT(processServerExit()));
2708    
2709          // Build process arguments...          // Build process arguments...
# Line 2466  void MainForm::startServer (void) Line 2734  void MainForm::startServer (void)
2734    
2735    
2736  // Stop linuxsampler server...  // Stop linuxsampler server...
2737  void MainForm::stopServer (void)  void MainForm::stopServer (bool bInteractive)
2738  {  {
2739          // Stop client code.          // Stop client code.
2740          stopClient();          stopClient();
2741    
2742            if (m_pServer && bInteractive) {
2743                    if (QMessageBox::question(this,
2744                            QSAMPLER_TITLE ": " + tr("The backend's fate ..."),
2745                            tr("You have the option to keep the sampler backend (LinuxSampler)\n"
2746                            "running in the background. The sampler would continue to work\n"
2747                            "according to your current sampler session and you could alter the\n"
2748                            "sampler session at any time by relaunching QSampler.\n\n"
2749                            "Do you want LinuxSampler to stop?"),
2750                            QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
2751                    {
2752                            bForceServerStop = false;
2753                    }
2754            }
2755    
2756          // And try to stop server.          // And try to stop server.
2757          if (m_pServer) {          if (m_pServer && bForceServerStop) {
2758                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2759                  if (m_pServer->state() == QProcess::Running)                  if (m_pServer->state() == QProcess::Running) {
2760                    #if defined(WIN32)
2761                            // Try harder...
2762                            m_pServer->kill();
2763                    #else
2764                            // Try softly...
2765                          m_pServer->terminate();                          m_pServer->terminate();
2766          }                  #endif
2767                    }
2768            }       // Do final processing anyway.
2769            else processServerExit();
2770    
2771          // Give it some time to terminate gracefully and stabilize...          // Give it some time to terminate gracefully and stabilize...
2772          QTime t;          QTime t;
2773          t.start();          t.start();
2774          while (t.elapsed() < QSAMPLER_TIMER_MSECS)          while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2775                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
   
         // Do final processing anyway.  
         processServerExit();  
2776  }  }
2777    
2778    
# Line 2507  void MainForm::processServerExit (void) Line 2794  void MainForm::processServerExit (void)
2794          if (m_pMessages)          if (m_pMessages)
2795                  m_pMessages->flushStdoutBuffer();                  m_pMessages->flushStdoutBuffer();
2796    
2797          if (m_pServer) {          if (m_pServer && bForceServerStop) {
2798                    if (m_pServer->state() != QProcess::NotRunning) {
2799                            appendMessages(tr("Server is being forced..."));
2800                            // Force final server shutdown...
2801                            m_pServer->kill();
2802                            // Give it some time to terminate gracefully and stabilize...
2803                            QTime t;
2804                            t.start();
2805                            while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2806                                    QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2807                    }
2808                  // Force final server shutdown...                  // Force final server shutdown...
2809                  appendMessages(                  appendMessages(
2810                          tr("Server was stopped with exit status %1.")                          tr("Server was stopped with exit status %1.")
2811                          .arg(m_pServer->exitStatus()));                          .arg(m_pServer->exitStatus()));
                 m_pServer->terminate();  
                 if (!m_pServer->waitForFinished(2000))  
                         m_pServer->kill();  
                 // Destroy it.  
2812                  delete m_pServer;                  delete m_pServer;
2813                  m_pServer = NULL;                  m_pServer = NULL;
2814          }          }
# Line 2540  lscp_status_t qsampler_client_callback ( Line 2833  lscp_status_t qsampler_client_callback (
2833          // as this is run under some other thread context.          // as this is run under some other thread context.
2834          // A custom event must be posted here...          // A custom event must be posted here...
2835          QApplication::postEvent(pMainForm,          QApplication::postEvent(pMainForm,
2836                  new qsamplerCustomEvent(event, pchData, cchData));                  new LscpEvent(event, pchData, cchData));
2837    
2838          return LSCP_OK;          return LSCP_OK;
2839  }  }
# Line 2585  bool MainForm::startClient (void) Line 2878  bool MainForm::startClient (void)
2878                  .arg(::lscp_client_get_timeout(m_pClient)));                  .arg(::lscp_client_get_timeout(m_pClient)));
2879    
2880          // Subscribe to channel info change notifications...          // Subscribe to channel info change notifications...
2881            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT) != LSCP_OK)
2882                    appendMessagesClient("lscp_client_subscribe(CHANNEL_COUNT)");
2883          if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)          if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)
2884                  appendMessagesClient("lscp_client_subscribe");                  appendMessagesClient("lscp_client_subscribe(CHANNEL_INFO)");
2885    
2886            DeviceStatusForm::onDevicesChanged(); // initialize
2887            updateViewMidiDeviceStatusMenu();
2888            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT) != LSCP_OK)
2889                    appendMessagesClient("lscp_client_subscribe(MIDI_INPUT_DEVICE_COUNT)");
2890            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO) != LSCP_OK)
2891                    appendMessagesClient("lscp_client_subscribe(MIDI_INPUT_DEVICE_INFO)");
2892            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT) != LSCP_OK)
2893                    appendMessagesClient("lscp_client_subscribe(AUDIO_OUTPUT_DEVICE_COUNT)");
2894            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO) != LSCP_OK)
2895                    appendMessagesClient("lscp_client_subscribe(AUDIO_OUTPUT_DEVICE_INFO)");
2896    
2897    #if CONFIG_EVENT_CHANNEL_MIDI
2898            // Subscribe to channel MIDI data notifications...
2899            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_MIDI) != LSCP_OK)
2900                    appendMessagesClient("lscp_client_subscribe(CHANNEL_MIDI)");
2901    #endif
2902    
2903    #if CONFIG_EVENT_DEVICE_MIDI
2904            // Subscribe to channel MIDI data notifications...
2905            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_DEVICE_MIDI) != LSCP_OK)
2906                    appendMessagesClient("lscp_client_subscribe(DEVICE_MIDI)");
2907    #endif
2908    
2909          // We may stop scheduling around.          // We may stop scheduling around.
2910          stopSchedule();          stopSchedule();
# Line 2613  bool MainForm::startClient (void) Line 2931  bool MainForm::startClient (void)
2931                  }                  }
2932          }          }
2933    
2934            // send the current / loaded fine tuning settings to the sampler
2935            m_pOptions->sendFineTuningSettings();
2936    
2937          // Make a new session          // Make a new session
2938          return newSession();          return newSession();
2939  }  }
# Line 2640  void MainForm::stopClient (void) Line 2961  void MainForm::stopClient (void)
2961          closeSession(false);          closeSession(false);
2962    
2963          // Close us as a client...          // Close us as a client...
2964    #if CONFIG_EVENT_DEVICE_MIDI
2965            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_DEVICE_MIDI);
2966    #endif
2967    #if CONFIG_EVENT_CHANNEL_MIDI
2968            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_MIDI);
2969    #endif
2970            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO);
2971            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT);
2972            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO);
2973            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT);
2974          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
2975            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);
2976          ::lscp_client_destroy(m_pClient);          ::lscp_client_destroy(m_pClient);
2977          m_pClient = NULL;          m_pClient = NULL;
2978    
# Line 2658  void MainForm::stopClient (void) Line 2990  void MainForm::stopClient (void)
2990          stabilizeForm();          stabilizeForm();
2991  }  }
2992    
2993    
2994    // Channel strip activation/selection.
2995    void MainForm::activateStrip ( QMdiSubWindow *pMdiSubWindow )
2996    {
2997            ChannelStrip *pChannelStrip = NULL;
2998            if (pMdiSubWindow)
2999                    pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
3000            if (pChannelStrip)
3001                    pChannelStrip->setSelected(true);
3002    
3003            stabilizeForm();
3004    }
3005    
3006    
3007  } // namespace QSampler  } // namespace QSampler
3008    
3009    

Legend:
Removed from v.1509  
changed lines
  Added in v.2459

  ViewVC Help
Powered by ViewVC