/[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 3508 by capela, Mon Apr 1 22:36:26 2019 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-2019, rncbc aka Rui Nuno Capela. All rights reserved.
5     Copyright (C) 2007, Christian Schoenebeck     Copyright (C) 2007,2008,2015 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__) || defined(_WIN32) || 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_fdSigusr1[2];
113    
114    // Unix SIGUSR1 signal handler.
115    static void qsampler_sigusr1_handler ( int /* signo */ )
116    {
117            char c = 1;
118    
119            (::write(g_fdSigusr1[0], &c, sizeof(c)) > 0);
120    }
121    
122    // File descriptor for SIGTERM notifier.
123    static int g_fdSigterm[2];
124    
125    // Unix SIGTERM signal handler.
126    static void qsampler_sigterm_handler ( int /* signo */ )
127    {
128            char c = 1;
129    
130            (::write(g_fdSigterm[0], &c, sizeof(c)) > 0);
131    }
132    
133    #endif  // HAVE_SIGNAL_H
134    
135    
136    //-------------------------------------------------------------------------
137    // QSampler -- namespace
138    
139    
140    namespace QSampler {
141    
142  // Timer constant stuff.  // Timer constant stuff.
143  #define QSAMPLER_TIMER_MSECS    200  #define QSAMPLER_TIMER_MSECS    200
144    
# Line 87  static inline long lroundf ( float x ) Line 149  static inline long lroundf ( float x )
149  #define QSAMPLER_STATUS_SESSION 3       // Current session modification state.  #define QSAMPLER_STATUS_SESSION 3       // Current session modification state.
150    
151    
152  // All winsock apps needs this.  // Specialties for thread-callback comunication.
153  #if defined(WIN32)  #define QSAMPLER_LSCP_EVENT   QEvent::Type(QEvent::User + 1)
 static WSADATA _wsaData;  
 #endif  
154    
155    
156  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
157  // qsamplerCustomEvent -- specialty for callback comunication.  // QSampler::LscpEvent -- specialty for LSCP callback comunication.
   
 #define QSAMPLER_CUSTOM_EVENT   QEvent::Type(QEvent::User + 0)  
158    
159  class qsamplerCustomEvent : public QEvent  class LscpEvent : public QEvent
160  {  {
161  public:  public:
162    
163          // Constructor.          // Constructor.
164          qsamplerCustomEvent(lscp_event_t event, const char *pchData, int cchData)          LscpEvent(lscp_event_t event, const char *pchData, int cchData)
165                  : QEvent(QSAMPLER_CUSTOM_EVENT)                  : QEvent(QSAMPLER_LSCP_EVENT)
166          {          {
167                  m_event = event;                  m_event = event;
168                  m_data  = QString::fromUtf8(pchData, cchData);                  m_data  = QString::fromUtf8(pchData, cchData);
169          }          }
170    
171          // Accessors.          // Accessors.
172          lscp_event_t event() { return m_event; }          lscp_event_t  event() { return m_event; }
173          QString&     data()  { return m_data;  }          const QString& data() { return m_data;  }
174    
175  private:  private:
176    
# Line 124  private: Line 182  private:
182    
183    
184  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
185  // qsamplerMainForm -- Main window form implementation.  // QSampler::Workspace -- Main window workspace (MDI Area) decl.
186    
187    class Workspace : public QMdiArea
188    {
189    public:
190    
191            Workspace(MainForm *pMainForm) : QMdiArea(pMainForm) {}
192    
193    protected:
194    
195            void resizeEvent(QResizeEvent *)
196            {
197                    MainForm *pMainForm = static_cast<MainForm *> (parentWidget());
198                    if (pMainForm)
199                            pMainForm->channelsArrangeAuto();
200            }
201    };
202    
203  namespace QSampler {  
204    //-------------------------------------------------------------------------
205    // QSampler::MainForm -- Main window form implementation.
206    
207  // Kind of singleton reference.  // Kind of singleton reference.
208  MainForm* MainForm::g_pMainForm = NULL;  MainForm *MainForm::g_pMainForm = NULL;
209    
210  MainForm::MainForm ( QWidget *pParent )  MainForm::MainForm ( QWidget *pParent )
211          : QMainWindow(pParent)          : QMainWindow(pParent)
# Line 149  MainForm::MainForm ( QWidget *pParent ) Line 225  MainForm::MainForm ( QWidget *pParent )
225    
226          // We'll start clean.          // We'll start clean.
227          m_iUntitled   = 0;          m_iUntitled   = 0;
228            m_iDirtySetup = 0;
229          m_iDirtyCount = 0;          m_iDirtyCount = 0;
230    
231          m_pServer = NULL;          m_pServer = NULL;
# Line 159  MainForm::MainForm ( QWidget *pParent ) Line 236  MainForm::MainForm ( QWidget *pParent )
236    
237          m_iTimerSlot = 0;          m_iTimerSlot = 0;
238    
239  #ifdef HAVE_SIGNAL_H  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
240    
241          // Set to ignore any fatal "Broken pipe" signals.          // Set to ignore any fatal "Broken pipe" signals.
242          ::signal(SIGPIPE, SIG_IGN);          ::signal(SIGPIPE, SIG_IGN);
243  #endif  
244            // LADISH Level 1 suport.
245    
246            // Initialize file descriptors for SIGUSR1 socket notifier.
247            ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigusr1);
248            m_pSigusr1Notifier
249                    = new QSocketNotifier(g_fdSigusr1[1], QSocketNotifier::Read, this);
250    
251            QObject::connect(m_pSigusr1Notifier,
252                    SIGNAL(activated(int)),
253                    SLOT(handle_sigusr1()));
254    
255            // Install SIGUSR1 signal handler.
256        struct sigaction sigusr1;
257        sigusr1.sa_handler = qsampler_sigusr1_handler;
258        sigemptyset(&sigusr1.sa_mask);
259        sigusr1.sa_flags = 0;
260        sigusr1.sa_flags |= SA_RESTART;
261        ::sigaction(SIGUSR1, &sigusr1, NULL);
262    
263            // Initialize file descriptors for SIGTERM socket notifier.
264            ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigterm);
265            m_pSigtermNotifier
266                    = new QSocketNotifier(g_fdSigterm[1], QSocketNotifier::Read, this);
267    
268            QObject::connect(m_pSigtermNotifier,
269                    SIGNAL(activated(int)),
270                    SLOT(handle_sigterm()));
271    
272            // Install SIGTERM signal handler.
273            struct sigaction sigterm;
274            sigterm.sa_handler = qsampler_sigterm_handler;
275            ::sigemptyset(&sigterm.sa_mask);
276            sigterm.sa_flags = 0;
277            sigterm.sa_flags |= SA_RESTART;
278            ::sigaction(SIGTERM, &sigterm, NULL);
279            ::sigaction(SIGQUIT, &sigterm, NULL);
280    
281            // Ignore SIGHUP/SIGINT signals.
282            ::signal(SIGHUP, SIG_IGN);
283            ::signal(SIGINT, SIG_IGN);
284    
285    #else   // HAVE_SIGNAL_H
286    
287            m_pSigusr1Notifier = NULL;
288            m_pSigtermNotifier = NULL;
289            
290    #endif  // !HAVE_SIGNAL_H
291    
292  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
293          // Make some extras into the toolbar...          // Make some extras into the toolbar...
# Line 171  MainForm::MainForm ( QWidget *pParent ) Line 296  MainForm::MainForm ( QWidget *pParent )
296          // Volume slider...          // Volume slider...
297          m_ui.channelsToolbar->addSeparator();          m_ui.channelsToolbar->addSeparator();
298          m_pVolumeSlider = new QSlider(Qt::Horizontal, m_ui.channelsToolbar);          m_pVolumeSlider = new QSlider(Qt::Horizontal, m_ui.channelsToolbar);
299          m_pVolumeSlider->setTickPosition(QSlider::TicksBelow);          m_pVolumeSlider->setTickPosition(QSlider::TicksBothSides);
300          m_pVolumeSlider->setTickInterval(10);          m_pVolumeSlider->setTickInterval(10);
301          m_pVolumeSlider->setPageStep(10);          m_pVolumeSlider->setPageStep(10);
302          m_pVolumeSlider->setSingleStep(10);          m_pVolumeSlider->setSingleStep(10);
# Line 183  MainForm::MainForm ( QWidget *pParent ) Line 308  MainForm::MainForm ( QWidget *pParent )
308          QObject::connect(m_pVolumeSlider,          QObject::connect(m_pVolumeSlider,
309                  SIGNAL(valueChanged(int)),                  SIGNAL(valueChanged(int)),
310                  SLOT(volumeChanged(int)));                  SLOT(volumeChanged(int)));
         //m_ui.channelsToolbar->setHorizontallyStretchable(true);  
         //m_ui.channelsToolbar->setStretchableWidget(m_pVolumeSlider);  
311          m_ui.channelsToolbar->addWidget(m_pVolumeSlider);          m_ui.channelsToolbar->addWidget(m_pVolumeSlider);
312          // Volume spin-box          // Volume spin-box
313          m_ui.channelsToolbar->addSeparator();          m_ui.channelsToolbar->addSeparator();
# Line 200  MainForm::MainForm ( QWidget *pParent ) Line 323  MainForm::MainForm ( QWidget *pParent )
323  #endif  #endif
324    
325          // Make it an MDI workspace.          // Make it an MDI workspace.
326          m_pWorkspace = new QWorkspace(this);          m_pWorkspace = new Workspace(this);
327          m_pWorkspace->setScrollBarsEnabled(true);          m_pWorkspace->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
328            m_pWorkspace->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
329          // Set the activation connection.          // Set the activation connection.
330          QObject::connect(m_pWorkspace,          QObject::connect(m_pWorkspace,
331                  SIGNAL(windowActivated(QWidget *)),                  SIGNAL(subWindowActivated(QMdiSubWindow *)),
332                  SLOT(stabilizeForm()));                  SLOT(activateStrip(QMdiSubWindow *)));
333          // Make it shine :-)          // Make it shine :-)
334          setCentralWidget(m_pWorkspace);          setCentralWidget(m_pWorkspace);
335    
# Line 234  MainForm::MainForm ( QWidget *pParent ) Line 358  MainForm::MainForm ( QWidget *pParent )
358          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
359          statusBar()->addWidget(pLabel);          statusBar()->addWidget(pLabel);
360    
361  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
362          WSAStartup(MAKEWORD(1, 1), &_wsaData);          WSAStartup(MAKEWORD(1, 1), &_wsaData);
363  #endif  #endif
364    
365            // Some actions surely need those
366            // shortcuts firmly attached...
367            addAction(m_ui.viewMenubarAction);
368            addAction(m_ui.viewToolbarAction);
369    
370          QObject::connect(m_ui.fileNewAction,          QObject::connect(m_ui.fileNewAction,
371                  SIGNAL(triggered()),                  SIGNAL(triggered()),
372                  SLOT(fileNew()));                  SLOT(fileNew()));
# Line 317  MainForm::MainForm ( QWidget *pParent ) Line 446  MainForm::MainForm ( QWidget *pParent )
446          QObject::connect(m_ui.channelsMenu,          QObject::connect(m_ui.channelsMenu,
447                  SIGNAL(aboutToShow()),                  SIGNAL(aboutToShow()),
448                  SLOT(channelsMenuAboutToShow()));                  SLOT(channelsMenuAboutToShow()));
449    #ifdef CONFIG_VOLUME
450            QObject::connect(m_ui.channelsToolbar,
451                    SIGNAL(orientationChanged(Qt::Orientation)),
452                    SLOT(channelsToolbarOrientation(Qt::Orientation)));
453    #endif
454  }  }
455    
456  // Destructor.  // Destructor.
# Line 325  MainForm::~MainForm() Line 459  MainForm::~MainForm()
459          // Do final processing anyway.          // Do final processing anyway.
460          processServerExit();          processServerExit();
461    
462  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
463          WSACleanup();          WSACleanup();
464  #endif  #endif
465    
466    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
467            if (m_pSigusr1Notifier)
468                    delete m_pSigusr1Notifier;
469            if (m_pSigtermNotifier)
470                    delete m_pSigtermNotifier;
471    #endif
472    
473          // Finally drop any widgets around...          // Finally drop any widgets around...
474          if (m_pDeviceForm)          if (m_pDeviceForm)
475                  delete m_pDeviceForm;                  delete m_pDeviceForm;
# Line 360  MainForm::~MainForm() Line 501  MainForm::~MainForm()
501    
502    
503  // Make and set a proper setup options step.  // Make and set a proper setup options step.
504  void MainForm::setup ( qsamplerOptions *pOptions )  void MainForm::setup ( Options *pOptions )
505  {  {
506          // We got options?          // We got options?
507          m_pOptions = pOptions;          m_pOptions = pOptions;
508    
509          // What style do we create these forms?          // What style do we create these forms?
510          Qt::WindowFlags wflags = Qt::Window          Qt::WindowFlags wflags = Qt::Window
 #if QT_VERSION >= 0x040200  
511                  | Qt::CustomizeWindowHint                  | Qt::CustomizeWindowHint
 #endif  
512                  | Qt::WindowTitleHint                  | Qt::WindowTitleHint
513                  | Qt::WindowSystemMenuHint                  | Qt::WindowSystemMenuHint
514                  | Qt::WindowMinMaxButtonsHint;                  | Qt::WindowMinMaxButtonsHint
515                    | Qt::WindowCloseButtonHint;
516          if (m_pOptions->bKeepOnTop)          if (m_pOptions->bKeepOnTop)
517                  wflags |= Qt::Tool;                  wflags |= Qt::Tool;
518    
519          // Some child forms are to be created right now.          // Some child forms are to be created right now.
520          m_pMessages = new qsamplerMessages(this);          m_pMessages = new Messages(this);
521          m_pDeviceForm = new DeviceForm(this, wflags);          m_pDeviceForm = new DeviceForm(this, wflags);
522  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
523          m_pInstrumentListForm = new InstrumentListForm(this, wflags);          m_pInstrumentListForm = new InstrumentListForm(this, wflags);
524  #else  #else
525          viewInstrumentsAction->setEnabled(false);          m_ui.viewInstrumentsAction->setEnabled(false);
526  #endif  #endif
527    
528            // Setup messages logging appropriately...
529            m_pMessages->setLogging(
530                    m_pOptions->bMessagesLog,
531                    m_pOptions->sMessagesLogPath);
532    
533          // Set message defaults...          // Set message defaults...
534          updateMessagesFont();          updateMessagesFont();
535          updateMessagesLimit();          updateMessagesLimit();
536          updateMessagesCapture();          updateMessagesCapture();
537    
538          // Set the visibility signal.          // Set the visibility signal.
539          QObject::connect(m_pMessages,          QObject::connect(m_pMessages,
540                  SIGNAL(visibilityChanged(bool)),                  SIGNAL(visibilityChanged(bool)),
# Line 413  void MainForm::setup ( qsamplerOptions * Line 561  void MainForm::setup ( qsamplerOptions *
561          }          }
562    
563          // Try to restore old window positioning and initial visibility.          // Try to restore old window positioning and initial visibility.
564          m_pOptions->loadWidgetGeometry(this);          m_pOptions->loadWidgetGeometry(this, true);
565          m_pOptions->loadWidgetGeometry(m_pInstrumentListForm);          m_pOptions->loadWidgetGeometry(m_pInstrumentListForm);
566          m_pOptions->loadWidgetGeometry(m_pDeviceForm);          m_pOptions->loadWidgetGeometry(m_pDeviceForm);
567    
# Line 452  bool MainForm::queryClose (void) Line 600  bool MainForm::queryClose (void)
600                                  || m_ui.channelsToolbar->isVisible());                                  || m_ui.channelsToolbar->isVisible());
601                          m_pOptions->bStatusbar = statusBar()->isVisible();                          m_pOptions->bStatusbar = statusBar()->isVisible();
602                          // Save the dock windows state.                          // Save the dock windows state.
                         const QString sDockables = saveState().toBase64().data();  
603                          m_pOptions->settings().setValue("/Layout/DockWindows", saveState());                          m_pOptions->settings().setValue("/Layout/DockWindows", saveState());
604                          // And the children, and the main windows state,.                          // And the children, and the main windows state,.
605                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);
606                          m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);                          m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
607                          m_pOptions->saveWidgetGeometry(this);                          m_pOptions->saveWidgetGeometry(this, true);
608                          // Close popup widgets.                          // Close popup widgets.
609                          if (m_pInstrumentListForm)                          if (m_pInstrumentListForm)
610                                  m_pInstrumentListForm->close();                                  m_pInstrumentListForm->close();
611                          if (m_pDeviceForm)                          if (m_pDeviceForm)
612                                  m_pDeviceForm->close();                                  m_pDeviceForm->close();
613                          // Stop client and/or server, gracefully.                          // Stop client and/or server, gracefully.
614                          stopServer();                          stopServer(true /*interactive*/);
615                  }                  }
616          }          }
617    
# Line 474  bool MainForm::queryClose (void) Line 621  bool MainForm::queryClose (void)
621    
622  void MainForm::closeEvent ( QCloseEvent *pCloseEvent )  void MainForm::closeEvent ( QCloseEvent *pCloseEvent )
623  {  {
624          if (queryClose())          if (queryClose()) {
625                    DeviceStatusForm::deleteAllInstances();
626                  pCloseEvent->accept();                  pCloseEvent->accept();
627          else          } else
628                  pCloseEvent->ignore();                  pCloseEvent->ignore();
629  }  }
630    
# Line 494  void MainForm::dragEnterEvent ( QDragEnt Line 642  void MainForm::dragEnterEvent ( QDragEnt
642  }  }
643    
644    
645  void MainForm::dropEvent ( QDropEvent* pDropEvent )  void MainForm::dropEvent ( QDropEvent *pDropEvent )
646  {  {
647          // Accept externally originated drops only...          // Accept externally originated drops only...
648          if (pDropEvent->source())          if (pDropEvent->source())
# Line 505  void MainForm::dropEvent ( QDropEvent* p Line 653  void MainForm::dropEvent ( QDropEvent* p
653                  QListIterator<QUrl> iter(pMimeData->urls());                  QListIterator<QUrl> iter(pMimeData->urls());
654                  while (iter.hasNext()) {                  while (iter.hasNext()) {
655                          const QString& sPath = iter.next().toLocalFile();                          const QString& sPath = iter.next().toLocalFile();
656                          if (qsamplerChannel::isInstrumentFile(sPath)) {                  //      if (Channel::isDlsInstrumentFile(sPath)) {
657                            if (QFileInfo(sPath).exists()) {
658                                  // Try to create a new channel from instrument file...                                  // Try to create a new channel from instrument file...
659                                  qsamplerChannel *pChannel = new qsamplerChannel();                                  Channel *pChannel = new Channel();
660                                  if (pChannel == NULL)                                  if (pChannel == NULL)
661                                          return;                                          return;
662                                  // Start setting the instrument filename...                                  // Start setting the instrument filename...
# Line 539  void MainForm::dropEvent ( QDropEvent* p Line 688  void MainForm::dropEvent ( QDropEvent* p
688    
689    
690  // Custome event handler.  // Custome event handler.
691  void MainForm::customEvent(QEvent* pCustomEvent)  void MainForm::customEvent ( QEvent* pEvent )
692  {  {
693          // For the time being, just pump it to messages.          // For the time being, just pump it to messages.
694          if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {          if (pEvent->type() == QSAMPLER_LSCP_EVENT) {
695                  qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;                  LscpEvent *pLscpEvent = static_cast<LscpEvent *> (pEvent);
696                  if (pEvent->event() == LSCP_EVENT_CHANNEL_INFO) {                  switch (pLscpEvent->event()) {
697                          int iChannelID = pEvent->data().toInt();                          case LSCP_EVENT_CHANNEL_COUNT:
698                          ChannelStrip *pChannelStrip = channelStrip(iChannelID);                                  updateAllChannelStrips(true);
699                          if (pChannelStrip)                                  break;
700                                  channelStripChanged(pChannelStrip);                          case LSCP_EVENT_CHANNEL_INFO: {
701                  } else {                                  const int iChannelID = pLscpEvent->data().toInt();
702                          appendMessagesColor(tr("Notify event: %1 data: %2")                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);
703                                  .arg(::lscp_event_to_text(pEvent->event()))                                  if (pChannelStrip)
704                                  .arg(pEvent->data()), "#996699");                                          channelStripChanged(pChannelStrip);
705                                    break;
706                            }
707                            case LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT:
708                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
709                                    DeviceStatusForm::onDevicesChanged();
710                                    updateViewMidiDeviceStatusMenu();
711                                    break;
712                            case LSCP_EVENT_MIDI_INPUT_DEVICE_INFO: {
713                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
714                                    const int iDeviceID = pLscpEvent->data().section(' ', 0, 0).toInt();
715                                    DeviceStatusForm::onDeviceChanged(iDeviceID);
716                                    break;
717                            }
718                            case LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT:
719                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
720                                    break;
721                            case LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO:
722                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
723                                    break;
724                    #if CONFIG_EVENT_CHANNEL_MIDI
725                            case LSCP_EVENT_CHANNEL_MIDI: {
726                                    const int iChannelID = pLscpEvent->data().section(' ', 0, 0).toInt();
727                                    ChannelStrip *pChannelStrip = channelStrip(iChannelID);
728                                    if (pChannelStrip)
729                                            pChannelStrip->midiActivityLedOn();
730                                    break;
731                            }
732                    #endif
733                    #if CONFIG_EVENT_DEVICE_MIDI
734                            case LSCP_EVENT_DEVICE_MIDI: {
735                                    const int iDeviceID = pLscpEvent->data().section(' ', 0, 0).toInt();
736                                    const int iPortID   = pLscpEvent->data().section(' ', 1, 1).toInt();
737                                    DeviceStatusForm *pDeviceStatusForm
738                                            = DeviceStatusForm::getInstance(iDeviceID);
739                                    if (pDeviceStatusForm)
740                                            pDeviceStatusForm->midiArrived(iPortID);
741                                    break;
742                            }
743                    #endif
744                            default:
745                                    appendMessagesColor(tr("LSCP Event: %1 data: %2")
746                                            .arg(::lscp_event_to_text(pLscpEvent->event()))
747                                            .arg(pLscpEvent->data()), "#996699");
748                  }                  }
749          }          }
750  }  }
751    
752    
753    // LADISH Level 1 -- SIGUSR1 signal handler.
754    void MainForm::handle_sigusr1 (void)
755    {
756    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
757    
758            char c;
759    
760            if (::read(g_fdSigusr1[1], &c, sizeof(c)) > 0)
761                    saveSession(false);
762    
763    #endif
764    }
765    
766    
767    void MainForm::handle_sigterm (void)
768    {
769    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
770    
771            char c;
772    
773            if (::read(g_fdSigterm[1], &c, sizeof(c)) > 0)
774                    close();
775    
776    #endif
777    }
778    
779    
780    void MainForm::updateViewMidiDeviceStatusMenu (void)
781    {
782            m_ui.viewMidiDeviceStatusMenu->clear();
783            const std::map<int, DeviceStatusForm *> statusForms
784                    = DeviceStatusForm::getInstances();
785            std::map<int, DeviceStatusForm *>::const_iterator iter
786                    = statusForms.begin();
787            for ( ; iter != statusForms.end(); ++iter) {
788                    DeviceStatusForm *pStatusForm = iter->second;
789                    m_ui.viewMidiDeviceStatusMenu->addAction(
790                            pStatusForm->visibleAction());
791            }
792    }
793    
794    
795  // Context menu event handler.  // Context menu event handler.
796  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )
797  {  {
# Line 567  void MainForm::contextMenuEvent( QContex Line 802  void MainForm::contextMenuEvent( QContex
802    
803    
804  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
805  // qsamplerMainForm -- Brainless public property accessors.  // QSampler::MainForm -- Brainless public property accessors.
806    
807  // The global options settings property.  // The global options settings property.
808  qsamplerOptions *MainForm::options (void) const  Options *MainForm::options (void) const
809  {  {
810          return m_pOptions;          return m_pOptions;
811  }  }
# Line 591  MainForm *MainForm::getInstance (void) Line 826  MainForm *MainForm::getInstance (void)
826    
827    
828  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
829  // qsamplerMainForm -- Session file stuff.  // QSampler::MainForm -- Session file stuff.
830    
831  // Format the displayable session filename.  // Format the displayable session filename.
832  QString MainForm::sessionName ( const QString& sFilename )  QString MainForm::sessionName ( const QString& sFilename )
833  {  {
834          bool bCompletePath = (m_pOptions && m_pOptions->bCompletePath);          const bool bCompletePath = (m_pOptions && m_pOptions->bCompletePath);
835          QString sSessionName = sFilename;          QString sSessionName = sFilename;
836          if (sSessionName.isEmpty())          if (sSessionName.isEmpty())
837                  sSessionName = tr("Untitled") + QString::number(m_iUntitled);                  sSessionName = tr("Untitled") + QString::number(m_iUntitled);
# Line 680  bool MainForm::saveSession ( bool bPromp Line 915  bool MainForm::saveSession ( bool bPromp
915                  // Enforce .lscp extension...                  // Enforce .lscp extension...
916                  if (QFileInfo(sFilename).suffix().isEmpty())                  if (QFileInfo(sFilename).suffix().isEmpty())
917                          sFilename += ".lscp";                          sFilename += ".lscp";
918            #if 0
919                  // Check if already exists...                  // Check if already exists...
920                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
921                          if (QMessageBox::warning(this,                          if (QMessageBox::warning(this,
# Line 688  bool MainForm::saveSession ( bool bPromp Line 924  bool MainForm::saveSession ( bool bPromp
924                                  "\"%1\"\n\n"                                  "\"%1\"\n\n"
925                                  "Do you want to replace it?")                                  "Do you want to replace it?")
926                                  .arg(sFilename),                                  .arg(sFilename),
927                                  tr("Replace"), tr("Cancel")) > 0)                                  QMessageBox::Yes | QMessageBox::No)
928                                    == QMessageBox::No)
929                                  return false;                                  return false;
930                  }                  }
931            #endif
932          }          }
933    
934          // Save it right away.          // Save it right away.
# Line 711  bool MainForm::closeSession ( bool bForc Line 949  bool MainForm::closeSession ( bool bForc
949                          "\"%1\"\n\n"                          "\"%1\"\n\n"
950                          "Do you want to save the changes?")                          "Do you want to save the changes?")
951                          .arg(sessionName(m_sFilename)),                          .arg(sessionName(m_sFilename)),
952                          tr("Save"), tr("Discard"), tr("Cancel"))) {                          QMessageBox::Save |
953                  case 0:     // Save...                          QMessageBox::Discard |
954                            QMessageBox::Cancel)) {
955                    case QMessageBox::Save:
956                          bClose = saveSession(false);                          bClose = saveSession(false);
957                          // Fall thru....                          // Fall thru....
958                  case 1:     // Discard                  case QMessageBox::Discard:
959                          break;                          break;
960                  default:    // Cancel.                  default:    // Cancel.
961                          bClose = false;                          bClose = false;
# Line 727  bool MainForm::closeSession ( bool bForc Line 967  bool MainForm::closeSession ( bool bForc
967          if (bClose) {          if (bClose) {
968                  // Remove all channel strips from sight...                  // Remove all channel strips from sight...
969                  m_pWorkspace->setUpdatesEnabled(false);                  m_pWorkspace->setUpdatesEnabled(false);
970                  QWidgetList wlist = m_pWorkspace->windowList();                  const QList<QMdiSubWindow *>& wlist
971                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                          = m_pWorkspace->subWindowList();
972                          ChannelStrip *pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  const int iStripCount = wlist.count();
973                    for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
974                            ChannelStrip *pChannelStrip = NULL;
975                            QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
976                            if (pMdiSubWindow)
977                                    pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
978                          if (pChannelStrip) {                          if (pChannelStrip) {
979                                  qsamplerChannel *pChannel = pChannelStrip->channel();                                  Channel *pChannel = pChannelStrip->channel();
980                                  if (bForce && pChannel)                                  if (bForce && pChannel)
981                                          pChannel->removeChannel();                                          pChannel->removeChannel();
982                                  delete pChannelStrip;                                  delete pChannelStrip;
983                          }                          }
984                            if (pMdiSubWindow)
985                                    delete pMdiSubWindow;
986                  }                  }
987                  m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
988                  // We're now clean, for sure.                  // We're now clean, for sure.
# Line 847  bool MainForm::saveSessionFile ( const Q Line 1094  bool MainForm::saveSessionFile ( const Q
1094          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1095    
1096          // Write the file.          // Write the file.
1097          int  iErrors = 0;          int iErrors = 0;
1098          QTextStream ts(&file);          QTextStream ts(&file);
1099          ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;          ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;
1100          ts << "# " << tr("Version")          ts << "# " << tr("Version") << ": " CONFIG_BUILD_VERSION << endl;
1101          << ": " QSAMPLER_VERSION << endl;  //      ts << "# " << tr("Build") << ": " CONFIG_BUILD_DATE << endl;
         ts << "# " << tr("Build")  
         << ": " __DATE__ " " __TIME__ << endl;  
1102          ts << "#"  << endl;          ts << "#"  << endl;
1103          ts << "# " << tr("File")          ts << "# " << tr("File")
1104          << ": " << QFileInfo(sFilename).fileName() << endl;          << ": " << QFileInfo(sFilename).fileName() << endl;
# Line 866  bool MainForm::saveSessionFile ( const Q Line 1111  bool MainForm::saveSessionFile ( const Q
1111          // It is assumed that this new kind of device+session file          // It is assumed that this new kind of device+session file
1112          // will be loaded from a complete initialized server...          // will be loaded from a complete initialized server...
1113          int *piDeviceIDs;          int *piDeviceIDs;
1114          int  iDevice;          int  i, iDevice;
1115          ts << "RESET" << endl;          ts << "RESET" << endl;
1116    
1117          // Audio device mapping.          // Audio device mapping.
1118          QMap<int, int> audioDeviceMap;          QMap<int, int> audioDeviceMap; iDevice = 0;
1119          piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Audio);          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);
1120          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1121                  ts << endl;                  Device device(Device::Audio, piDeviceIDs[i]);
1122                  qsamplerDevice device(qsamplerDevice::Audio, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1123                    if (device.driverName().toUpper() == "PLUGIN")
1124                            continue;
1125                  // Audio device specification...                  // Audio device specification...
1126                    ts << endl;
1127                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1128                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1129                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
1130                  qsamplerDeviceParamMap::ConstIterator deviceParam;                  DeviceParamMap::ConstIterator deviceParam;
1131                  for (deviceParam = device.params().begin();                  for (deviceParam = device.params().begin();
1132                                  deviceParam != device.params().end();                                  deviceParam != device.params().end();
1133                                          ++deviceParam) {                                          ++deviceParam) {
1134                          const qsamplerDeviceParam& param = deviceParam.value();                          const DeviceParam& param = deviceParam.value();
1135                          if (param.value.isEmpty()) ts << "# ";                          if (param.value.isEmpty()) ts << "# ";
1136                          ts << " " << deviceParam.key() << "='" << param.value << "'";                          ts << " " << deviceParam.key() << "='" << param.value << "'";
1137                  }                  }
1138                  ts << endl;                  ts << endl;
1139                  // Audio channel parameters...                  // Audio channel parameters...
1140                  int iPort = 0;                  int iPort = 0;
1141                  QListIterator<qsamplerDevicePort *> iter(device.ports());                  QListIterator<DevicePort *> iter(device.ports());
1142                  while (iter.hasNext()) {                  while (iter.hasNext()) {
1143                          qsamplerDevicePort *pPort = iter.next();                          DevicePort *pPort = iter.next();
1144                          qsamplerDeviceParamMap::ConstIterator portParam;                          DeviceParamMap::ConstIterator portParam;
1145                          for (portParam = pPort->params().begin();                          for (portParam = pPort->params().begin();
1146                                          portParam != pPort->params().end();                                          portParam != pPort->params().end();
1147                                                  ++portParam) {                                                  ++portParam) {
1148                                  const qsamplerDeviceParam& param = portParam.value();                                  const DeviceParam& param = portParam.value();
1149                                  if (param.fix || param.value.isEmpty()) ts << "# ";                                  if (param.fix || param.value.isEmpty()) ts << "# ";
1150                                  ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice                                  ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice
1151                                          << " " << iPort << " " << portParam.key()                                          << " " << iPort << " " << portParam.key()
# Line 906  bool MainForm::saveSessionFile ( const Q Line 1154  bool MainForm::saveSessionFile ( const Q
1154                          iPort++;                          iPort++;
1155                  }                  }
1156                  // Audio device index/id mapping.                  // Audio device index/id mapping.
1157                  audioDeviceMap[device.deviceID()] = iDevice;                  audioDeviceMap.insert(device.deviceID(), iDevice++);
1158                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1159                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1160          }          }
1161    
1162          // MIDI device mapping.          // MIDI device mapping.
1163          QMap<int, int> midiDeviceMap;          QMap<int, int> midiDeviceMap; iDevice = 0;
1164          piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Midi);          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);
1165          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1166                  ts << endl;                  Device device(Device::Midi, piDeviceIDs[i]);
1167                  qsamplerDevice device(qsamplerDevice::Midi, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1168                    if (device.driverName().toUpper() == "PLUGIN")
1169                            continue;
1170                  // MIDI device specification...                  // MIDI device specification...
1171                    ts << endl;
1172                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1173                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1174                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
1175                  qsamplerDeviceParamMap::ConstIterator deviceParam;                  DeviceParamMap::ConstIterator deviceParam;
1176                  for (deviceParam = device.params().begin();                  for (deviceParam = device.params().begin();
1177                                  deviceParam != device.params().end();                                  deviceParam != device.params().end();
1178                                          ++deviceParam) {                                          ++deviceParam) {
1179                          const qsamplerDeviceParam& param = deviceParam.value();                          const DeviceParam& param = deviceParam.value();
1180                          if (param.value.isEmpty()) ts << "# ";                          if (param.value.isEmpty()) ts << "# ";
1181                          ts << " " << deviceParam.key() << "='" << param.value << "'";                          ts << " " << deviceParam.key() << "='" << param.value << "'";
1182                  }                  }
1183                  ts << endl;                  ts << endl;
1184                  // MIDI port parameters...                  // MIDI port parameters...
1185                  int iPort = 0;                  int iPort = 0;
1186                  QListIterator<qsamplerDevicePort *> iter(device.ports());                  QListIterator<DevicePort *> iter(device.ports());
1187                  while (iter.hasNext()) {                  while (iter.hasNext()) {
1188                          qsamplerDevicePort *pPort = iter.next();                          DevicePort *pPort = iter.next();
1189                          qsamplerDeviceParamMap::ConstIterator portParam;                          DeviceParamMap::ConstIterator portParam;
1190                          for (portParam = pPort->params().begin();                          for (portParam = pPort->params().begin();
1191                                          portParam != pPort->params().end();                                          portParam != pPort->params().end();
1192                                                  ++portParam) {                                                  ++portParam) {
1193                                  const qsamplerDeviceParam& param = portParam.value();                                  const DeviceParam& param = portParam.value();
1194                                  if (param.fix || param.value.isEmpty()) ts << "# ";                                  if (param.fix || param.value.isEmpty()) ts << "# ";
1195                                  ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice                                  ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice
1196                                  << " " << iPort << " " << portParam.key()                                  << " " << iPort << " " << portParam.key()
# Line 948  bool MainForm::saveSessionFile ( const Q Line 1199  bool MainForm::saveSessionFile ( const Q
1199                          iPort++;                          iPort++;
1200                  }                  }
1201                  // MIDI device index/id mapping.                  // MIDI device index/id mapping.
1202                  midiDeviceMap[device.deviceID()] = iDevice;                  midiDeviceMap.insert(device.deviceID(), iDevice++);
1203                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1204                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1205          }          }
# Line 959  bool MainForm::saveSessionFile ( const Q Line 1210  bool MainForm::saveSessionFile ( const Q
1210          QMap<int, int> midiInstrumentMap;          QMap<int, int> midiInstrumentMap;
1211          int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);          int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);
1212          for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {          for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {
1213                  int iMidiMap = piMaps[iMap];                  const int iMidiMap = piMaps[iMap];
1214                  const char *pszMapName                  const char *pszMapName
1215                          = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);                          = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);
1216                  ts << "# " << tr("MIDI instrument map") << " " << iMap;                  ts << "# " << tr("MIDI instrument map") << " " << iMap;
# Line 1016  bool MainForm::saveSessionFile ( const Q Line 1267  bool MainForm::saveSessionFile ( const Q
1267                          iErrors++;                          iErrors++;
1268                  }                  }
1269                  // MIDI strument index/id mapping.                  // MIDI strument index/id mapping.
1270                  midiInstrumentMap[iMidiMap] = iMap;                  midiInstrumentMap.insert(iMidiMap, iMap);
1271          }          }
1272          // Check for errors...          // Check for errors...
1273          if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {          if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {
# Line 1025  bool MainForm::saveSessionFile ( const Q Line 1276  bool MainForm::saveSessionFile ( const Q
1276          }          }
1277  #endif  // CONFIG_MIDI_INSTRUMENT  #endif  // CONFIG_MIDI_INSTRUMENT
1278    
1279          // Sampler channel mapping.          // Sampler channel mapping...
1280          QWidgetList wlist = m_pWorkspace->windowList();          int iChannelID = 0;
1281          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          const QList<QMdiSubWindow *>& wlist
1282                  ChannelStrip* pChannelStrip                  = m_pWorkspace->subWindowList();
1283                          = static_cast<ChannelStrip *> (wlist.at(iChannel));          const int iStripCount = wlist.count();
1284            for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
1285                    ChannelStrip *pChannelStrip = NULL;
1286                    QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
1287                    if (pMdiSubWindow)
1288                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
1289                  if (pChannelStrip) {                  if (pChannelStrip) {
1290                          qsamplerChannel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1291                          if (pChannel) {                          if (pChannel) {
1292                                  ts << "# " << tr("Channel") << " " << iChannel << endl;                                  // Avoid "artifial" plug-in devices...
1293                                    const int iAudioDevice = pChannel->audioDevice();
1294                                    if (!audioDeviceMap.contains(iAudioDevice))
1295                                            continue;
1296                                    const int iMidiDevice = pChannel->midiDevice();
1297                                    if (!midiDeviceMap.contains(iMidiDevice))
1298                                            continue;
1299                                    // Go for regular, canonical devices...
1300                                    ts << "# " << tr("Channel") << " " << iChannelID << endl;
1301                                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
1302                                  if (audioDeviceMap.isEmpty()) {                                  if (audioDeviceMap.isEmpty()) {
1303                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannelID
1304                                                  << " " << pChannel->audioDriver() << endl;                                                  << " " << pChannel->audioDriver() << endl;
1305                                  } else {                                  } else {
1306                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannelID
1307                                                  << " " << audioDeviceMap[pChannel->audioDevice()] << endl;                                                  << " " << audioDeviceMap.value(iAudioDevice) << endl;
1308                                  }                                  }
1309                                  if (midiDeviceMap.isEmpty()) {                                  if (midiDeviceMap.isEmpty()) {
1310                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannel                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID
1311                                                  << " " << pChannel->midiDriver() << endl;                                                  << " " << pChannel->midiDriver() << endl;
1312                                  } else {                                  } else {
1313                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannel                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannelID
1314                                                  << " " << midiDeviceMap[pChannel->midiDevice()] << endl;                                                  << " " << midiDeviceMap.value(iMidiDevice) << endl;
1315                                  }                                  }
1316                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID
1317                                          << " " << pChannel->midiPort() << endl;                                          << " " << pChannel->midiPort() << endl;
1318                                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";                                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannelID << " ";
1319                                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)                                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
1320                                          ts << "ALL";                                          ts << "ALL";
1321                                  else                                  else
1322                                          ts << pChannel->midiChannel();                                          ts << pChannel->midiChannel();
1323                                  ts << endl;                                  ts << endl;
1324                                  ts << "LOAD ENGINE " << pChannel->engineName()                                  ts << "LOAD ENGINE " << pChannel->engineName()
1325                                          << " " << iChannel << endl;                                          << " " << iChannelID << endl;
1326                                  if (pChannel->instrumentStatus() < 100) ts << "# ";                                  if (pChannel->instrumentStatus() < 100) ts << "# ";
1327                                  ts << "LOAD INSTRUMENT NON_MODAL '"                                  ts << "LOAD INSTRUMENT NON_MODAL '"
1328                                          << pChannel->instrumentFile() << "' "                                          << pChannel->instrumentFile() << "' "
1329                                          << pChannel->instrumentNr() << " " << iChannel << endl;                                          << pChannel->instrumentNr() << " " << iChannelID << endl;
1330                                  qsamplerChannelRoutingMap::ConstIterator audioRoute;                                  ChannelRoutingMap::ConstIterator audioRoute;
1331                                  for (audioRoute = pChannel->audioRouting().begin();                                  for (audioRoute = pChannel->audioRouting().begin();
1332                                                  audioRoute != pChannel->audioRouting().end();                                                  audioRoute != pChannel->audioRouting().end();
1333                                                          ++audioRoute) {                                                          ++audioRoute) {
1334                                          ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannelID
1335                                                  << " " << audioRoute.key()                                                  << " " << audioRoute.key()
1336                                                  << " " << audioRoute.value() << endl;                                                  << " " << audioRoute.value() << endl;
1337                                  }                                  }
1338                                  ts << "SET CHANNEL VOLUME " << iChannel                                  ts << "SET CHANNEL VOLUME " << iChannelID
1339                                          << " " << pChannel->volume() << endl;                                          << " " << pChannel->volume() << endl;
1340                                  if (pChannel->channelMute())                                  if (pChannel->channelMute())
1341                                          ts << "SET CHANNEL MUTE " << iChannel << " 1" << endl;                                          ts << "SET CHANNEL MUTE " << iChannelID << " 1" << endl;
1342                                  if (pChannel->channelSolo())                                  if (pChannel->channelSolo())
1343                                          ts << "SET CHANNEL SOLO " << iChannel << " 1" << endl;                                          ts << "SET CHANNEL SOLO " << iChannelID << " 1" << endl;
1344  #ifdef CONFIG_MIDI_INSTRUMENT                          #ifdef CONFIG_MIDI_INSTRUMENT
1345                                  if (pChannel->midiMap() >= 0) {                                  const int iMidiMap = pChannel->midiMap();
1346                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannel                                  if (midiInstrumentMap.contains(iMidiMap)) {
1347                                                  << " " << midiInstrumentMap[pChannel->midiMap()] << endl;                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannelID
1348                                                    << " " << midiInstrumentMap.value(iMidiMap) << endl;
1349                                  }                                  }
1350  #endif                          #endif
1351  #ifdef CONFIG_FXSEND                          #ifdef CONFIG_FXSEND
                                 int iChannelID = pChannel->channelID();  
1352                                  int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID);                                  int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID);
1353                                  for (int iFxSend = 0;                                  for (int iFxSend = 0;
1354                                                  piFxSends && piFxSends[iFxSend] >= 0;                                                  piFxSends && piFxSends[iFxSend] >= 0;
# Line 1092  bool MainForm::saveSessionFile ( const Q Line 1356  bool MainForm::saveSessionFile ( const Q
1356                                          lscp_fxsend_info_t *pFxSendInfo = ::lscp_get_fxsend_info(                                          lscp_fxsend_info_t *pFxSendInfo = ::lscp_get_fxsend_info(
1357                                                  m_pClient, iChannelID, piFxSends[iFxSend]);                                                  m_pClient, iChannelID, piFxSends[iFxSend]);
1358                                          if (pFxSendInfo) {                                          if (pFxSendInfo) {
1359                                                  ts << "CREATE FX_SEND " << iChannel                                                  ts << "CREATE FX_SEND " << iChannelID
1360                                                          << " " << pFxSendInfo->midi_controller;                                                          << " " << pFxSendInfo->midi_controller;
1361                                                  if (pFxSendInfo->name)                                                  if (pFxSendInfo->name)
1362                                                          ts << " '" << pFxSendInfo->name << "'";                                                          ts << " '" << pFxSendInfo->name << "'";
# Line 1102  bool MainForm::saveSessionFile ( const Q Line 1366  bool MainForm::saveSessionFile ( const Q
1366                                                                  piRouting && piRouting[iAudioSrc] >= 0;                                                                  piRouting && piRouting[iAudioSrc] >= 0;
1367                                                                          iAudioSrc++) {                                                                          iAudioSrc++) {
1368                                                          ts << "SET FX_SEND AUDIO_OUTPUT_CHANNEL "                                                          ts << "SET FX_SEND AUDIO_OUTPUT_CHANNEL "
1369                                                                  << iChannel                                                                  << iChannelID
1370                                                                  << " " << iFxSend                                                                  << " " << iFxSend
1371                                                                  << " " << iAudioSrc                                                                  << " " << iAudioSrc
1372                                                                  << " " << piRouting[iAudioSrc] << endl;                                                                  << " " << piRouting[iAudioSrc] << endl;
1373                                                  }                                                  }
1374  #ifdef CONFIG_FXSEND_LEVEL                                          #ifdef CONFIG_FXSEND_LEVEL
1375                                                  ts << "SET FX_SEND LEVEL " << iChannel                                                  ts << "SET FX_SEND LEVEL " << iChannelID
1376                                                          << " " << iFxSend                                                          << " " << iFxSend
1377                                                          << " " << pFxSendInfo->level << endl;                                                          << " " << pFxSendInfo->level << endl;
1378  #endif                                          #endif
1379                                          }       // Check for errors...                                          }       // Check for errors...
1380                                          else if (::lscp_client_get_errno(m_pClient)) {                                          else if (::lscp_client_get_errno(m_pClient)) {
1381                                                  appendMessagesClient("lscp_get_fxsend_info");                                                  appendMessagesClient("lscp_get_fxsend_info");
1382                                                  iErrors++;                                                  iErrors++;
1383                                          }                                          }
1384                                  }                                  }
1385  #endif                          #endif
1386                                  ts << endl;                                  ts << endl;
1387                                    // Go for next channel...
1388                                    ++iChannelID;
1389                          }                          }
1390                  }                  }
1391                  // Try to keep it snappy :)                  // Try to keep it snappy :)
# Line 1171  void MainForm::sessionDirty (void) Line 1437  void MainForm::sessionDirty (void)
1437    
1438    
1439  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1440  // qsamplerMainForm -- File Action slots.  // QSampler::MainForm -- File Action slots.
1441    
1442  // Create a new sampler session.  // Create a new sampler session.
1443  void MainForm::fileNew (void)  void MainForm::fileNew (void)
# Line 1195  void MainForm::fileOpenRecent (void) Line 1461  void MainForm::fileOpenRecent (void)
1461          // Retrive filename index from action data...          // Retrive filename index from action data...
1462          QAction *pAction = qobject_cast<QAction *> (sender());          QAction *pAction = qobject_cast<QAction *> (sender());
1463          if (pAction && m_pOptions) {          if (pAction && m_pOptions) {
1464                  int iIndex = pAction->data().toInt();                  const int iIndex = pAction->data().toInt();
1465                  if (iIndex >= 0 && iIndex < m_pOptions->recentFiles.count()) {                  if (iIndex >= 0 && iIndex < m_pOptions->recentFiles.count()) {
1466                          QString sFilename = m_pOptions->recentFiles[iIndex];                          QString sFilename = m_pOptions->recentFiles[iIndex];
1467                          // Check if we can safely close the current session...                          // Check if we can safely close the current session...
# Line 1229  void MainForm::fileReset (void) Line 1495  void MainForm::fileReset (void)
1495                  return;                  return;
1496    
1497          // Ask user whether he/she want's an internal sampler reset...          // Ask user whether he/she want's an internal sampler reset...
1498          if (QMessageBox::warning(this,          if (m_pOptions && m_pOptions->bConfirmReset) {
1499                  QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");
1500                  tr("Resetting the sampler instance will close\n"                  const QString& sText = tr(
1501                  "all device and channel configurations.\n\n"                          "Resetting the sampler instance will close\n"
1502                  "Please note that this operation may cause\n"                          "all device and channel configurations.\n\n"
1503                  "temporary MIDI and Audio disruption.\n\n"                          "Please note that this operation may cause\n"
1504                  "Do you want to reset the sampler engine now?"),                          "temporary MIDI and Audio disruption.\n\n"
1505                  tr("Reset"), tr("Cancel")) > 0)                          "Do you want to reset the sampler engine now?");
1506                  return;          #if 0
1507                    if (QMessageBox::warning(this, sTitle, sText,
1508                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1509                            return;
1510            #else
1511                    QMessageBox mbox(this);
1512                    mbox.setIcon(QMessageBox::Warning);
1513                    mbox.setWindowTitle(sTitle);
1514                    mbox.setText(sText);
1515                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1516                    QCheckBox cbox(tr("Don't ask this again"));
1517                    cbox.setChecked(false);
1518                    cbox.blockSignals(true);
1519                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1520                    if (mbox.exec() == QMessageBox::Cancel)
1521                            return;
1522                    if (cbox.isChecked())
1523                            m_pOptions->bConfirmReset = false;
1524            #endif
1525            }
1526    
1527          // Trye closing the current session, first...          // Trye closing the current session, first...
1528          if (!closeSession(true))          if (!closeSession(true))
# Line 1269  void MainForm::fileRestart (void) Line 1554  void MainForm::fileRestart (void)
1554    
1555          // Ask user whether he/she want's a complete restart...          // Ask user whether he/she want's a complete restart...
1556          // (if we're currently up and running)          // (if we're currently up and running)
1557          if (bRestart && m_pClient) {          if (m_pOptions && m_pOptions->bConfirmRestart) {
1558                  bRestart = (QMessageBox::warning(this,                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");
1559                          QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sText = tr(
1560                          tr("New settings will be effective after\n"                          "New settings will be effective after\n"
1561                          "restarting the client/server connection.\n\n"                          "restarting the client/server connection.\n\n"
1562                          "Please note that this operation may cause\n"                          "Please note that this operation may cause\n"
1563                          "temporary MIDI and Audio disruption.\n\n"                          "temporary MIDI and Audio disruption.\n\n"
1564                          "Do you want to restart the connection now?"),                          "Do you want to restart the connection now?");
1565                          tr("Restart"), tr("Cancel")) == 0);          #if 0
1566                    if (QMessageBox::warning(this, sTitle, sText,
1567                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1568                            bRestart = false;
1569            #else
1570                    QMessageBox mbox(this);
1571                    mbox.setIcon(QMessageBox::Warning);
1572                    mbox.setWindowTitle(sTitle);
1573                    mbox.setText(sText);
1574                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1575                    QCheckBox cbox(tr("Don't ask this again"));
1576                    cbox.setChecked(false);
1577                    cbox.blockSignals(true);
1578                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1579                    if (mbox.exec() == QMessageBox::Cancel)
1580                            bRestart = false;
1581                    else
1582                    if (cbox.isChecked())
1583                            m_pOptions->bConfirmRestart = false;
1584            #endif
1585          }          }
1586    
1587          // Are we still for it?          // Are we still for it?
# Line 1299  void MainForm::fileExit (void) Line 1603  void MainForm::fileExit (void)
1603    
1604    
1605  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1606  // qsamplerMainForm -- Edit Action slots.  // QSampler::MainForm -- Edit Action slots.
1607    
1608  // Add a new sampler channel.  // Add a new sampler channel.
1609  void MainForm::editAddChannel (void)  void MainForm::editAddChannel (void)
1610  {  {
1611            ++m_iDirtySetup;
1612            addChannelStrip();
1613            --m_iDirtySetup;
1614    }
1615    
1616    void MainForm::addChannelStrip (void)
1617    {
1618          if (m_pClient == NULL)          if (m_pClient == NULL)
1619                  return;                  return;
1620    
1621          // Just create the channel instance...          // Just create the channel instance...
1622          qsamplerChannel *pChannel = new qsamplerChannel();          Channel *pChannel = new Channel();
1623          if (pChannel == NULL)          if (pChannel == NULL)
1624                  return;                  return;
1625    
# Line 1326  void MainForm::editAddChannel (void) Line 1637  void MainForm::editAddChannel (void)
1637                  return;                  return;
1638          }          }
1639    
1640            // Do we auto-arrange?
1641            channelsArrangeAuto();
1642    
1643          // Make that an overall update.          // Make that an overall update.
1644          m_iDirtyCount++;          m_iDirtyCount++;
1645          stabilizeForm();          stabilizeForm();
# Line 1335  void MainForm::editAddChannel (void) Line 1649  void MainForm::editAddChannel (void)
1649  // Remove current sampler channel.  // Remove current sampler channel.
1650  void MainForm::editRemoveChannel (void)  void MainForm::editRemoveChannel (void)
1651  {  {
1652            ++m_iDirtySetup;
1653            removeChannelStrip();
1654            --m_iDirtySetup;
1655    }
1656    
1657    void MainForm::removeChannelStrip (void)
1658    {
1659          if (m_pClient == NULL)          if (m_pClient == NULL)
1660                  return;                  return;
1661    
1662          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1663          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1664                  return;                  return;
1665    
1666          qsamplerChannel *pChannel = pChannelStrip->channel();          Channel *pChannel = pChannelStrip->channel();
1667          if (pChannel == NULL)          if (pChannel == NULL)
1668                  return;                  return;
1669    
1670          // Prompt user if he/she's sure about this...          // Prompt user if he/she's sure about this...
1671          if (m_pOptions && m_pOptions->bConfirmRemove) {          if (m_pOptions && m_pOptions->bConfirmRemove) {
1672                  if (QMessageBox::warning(this,                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");
1673                          QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sText = tr(
1674                          tr("About to remove channel:\n\n"                          "About to remove channel:\n\n"
1675                          "%1\n\n"                          "%1\n\n"
1676                          "Are you sure?")                          "Are you sure?")
1677                          .arg(pChannelStrip->windowTitle()),                          .arg(pChannelStrip->windowTitle());
1678                          tr("OK"), tr("Cancel")) > 0)          #if 0
1679                    if (QMessageBox::warning(this, sTitle, sText,
1680                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1681                            return;
1682            #else
1683                    QMessageBox mbox(this);
1684                    mbox.setIcon(QMessageBox::Warning);
1685                    mbox.setWindowTitle(sTitle);
1686                    mbox.setText(sText);
1687                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1688                    QCheckBox cbox(tr("Don't ask this again"));
1689                    cbox.setChecked(false);
1690                    cbox.blockSignals(true);
1691                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1692                    if (mbox.exec() == QMessageBox::Cancel)
1693                          return;                          return;
1694                    if (cbox.isChecked())
1695                            m_pOptions->bConfirmRemove = false;
1696            #endif
1697          }          }
1698    
1699          // Remove the existing sampler channel.          // Remove the existing sampler channel.
# Line 1363  void MainForm::editRemoveChannel (void) Line 1701  void MainForm::editRemoveChannel (void)
1701                  return;                  return;
1702    
1703          // Just delete the channel strip.          // Just delete the channel strip.
1704          delete pChannelStrip;          destroyChannelStrip(pChannelStrip);
   
         // Do we auto-arrange?  
         if (m_pOptions && m_pOptions->bAutoArrange)  
                 channelsArrange();  
1705    
1706          // We'll be dirty, for sure...          // We'll be dirty, for sure...
1707          m_iDirtyCount++;          m_iDirtyCount++;
# Line 1381  void MainForm::editSetupChannel (void) Line 1715  void MainForm::editSetupChannel (void)
1715          if (m_pClient == NULL)          if (m_pClient == NULL)
1716                  return;                  return;
1717    
1718          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1719          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1720                  return;                  return;
1721    
# Line 1396  void MainForm::editEditChannel (void) Line 1730  void MainForm::editEditChannel (void)
1730          if (m_pClient == NULL)          if (m_pClient == NULL)
1731                  return;                  return;
1732    
1733          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1734          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1735                  return;                  return;
1736    
# Line 1411  void MainForm::editResetChannel (void) Line 1745  void MainForm::editResetChannel (void)
1745          if (m_pClient == NULL)          if (m_pClient == NULL)
1746                  return;                  return;
1747    
1748          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1749          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1750                  return;                  return;
1751    
# Line 1429  void MainForm::editResetAllChannels (voi Line 1763  void MainForm::editResetAllChannels (voi
1763          // Invoque the channel strip procedure,          // Invoque the channel strip procedure,
1764          // for all channels out there...          // for all channels out there...
1765          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1766          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
1767          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                  = m_pWorkspace->subWindowList();
1768                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);          const int iStripCount = wlist.count();
1769            for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
1770                    ChannelStrip *pChannelStrip = NULL;
1771                    QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
1772                    if (pMdiSubWindow)
1773                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
1774                  if (pChannelStrip)                  if (pChannelStrip)
1775                          pChannelStrip->channelReset();                          pChannelStrip->channelReset();
1776          }          }
# Line 1440  void MainForm::editResetAllChannels (voi Line 1779  void MainForm::editResetAllChannels (voi
1779    
1780    
1781  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1782  // qsamplerMainForm -- View Action slots.  // QSampler::MainForm -- View Action slots.
1783    
1784  // Show/hide the main program window menubar.  // Show/hide the main program window menubar.
1785  void MainForm::viewMenubar ( bool bOn )  void MainForm::viewMenubar ( bool bOn )
# Line 1534  void MainForm::viewOptions (void) Line 1873  void MainForm::viewOptions (void)
1873          OptionsForm* pOptionsForm = new OptionsForm(this);          OptionsForm* pOptionsForm = new OptionsForm(this);
1874          if (pOptionsForm) {          if (pOptionsForm) {
1875                  // Check out some initial nullities(tm)...                  // Check out some initial nullities(tm)...
1876                  ChannelStrip* pChannelStrip = activeChannelStrip();                  ChannelStrip *pChannelStrip = activeChannelStrip();
1877                  if (m_pOptions->sDisplayFont.isEmpty() && pChannelStrip)                  if (m_pOptions->sDisplayFont.isEmpty() && pChannelStrip)
1878                          m_pOptions->sDisplayFont = pChannelStrip->displayFont().toString();                          m_pOptions->sDisplayFont = pChannelStrip->displayFont().toString();
1879                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)
1880                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();
1881                  // To track down deferred or immediate changes.                  // To track down deferred or immediate changes.
1882                  QString sOldServerHost      = m_pOptions->sServerHost;                  const QString sOldServerHost      = m_pOptions->sServerHost;
1883                  int     iOldServerPort      = m_pOptions->iServerPort;                  const int     iOldServerPort      = m_pOptions->iServerPort;
1884                  int     iOldServerTimeout   = m_pOptions->iServerTimeout;                  const int     iOldServerTimeout   = m_pOptions->iServerTimeout;
1885                  bool    bOldServerStart     = m_pOptions->bServerStart;                  const bool    bOldServerStart     = m_pOptions->bServerStart;
1886                  QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;                  const QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;
1887                  QString sOldDisplayFont     = m_pOptions->sDisplayFont;                  const bool    bOldMessagesLog     = m_pOptions->bMessagesLog;
1888                  bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;                  const QString sOldMessagesLogPath = m_pOptions->sMessagesLogPath;
1889                  int     iOldMaxVolume       = m_pOptions->iMaxVolume;                  const QString sOldDisplayFont     = m_pOptions->sDisplayFont;
1890                  QString sOldMessagesFont    = m_pOptions->sMessagesFont;                  const bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1891                  bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;                  const int     iOldMaxVolume       = m_pOptions->iMaxVolume;
1892                  bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;                  const QString sOldMessagesFont    = m_pOptions->sMessagesFont;
1893                  int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;                  const bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;
1894                  int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;                  const bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;
1895                  bool    bOldCompletePath    = m_pOptions->bCompletePath;                  const int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;
1896                  bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;                  const int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1897                  int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;                  const bool    bOldCompletePath    = m_pOptions->bCompletePath;
1898                    const bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1899                    const int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1900                    const int     iOldBaseFontSize    = m_pOptions->iBaseFontSize;
1901                  // Load the current setup settings.                  // Load the current setup settings.
1902                  pOptionsForm->setup(m_pOptions);                  pOptionsForm->setup(m_pOptions);
1903                  // Show the setup dialog...                  // Show the setup dialog...
# Line 1564  void MainForm::viewOptions (void) Line 1906  void MainForm::viewOptions (void)
1906                          if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||                          if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1907                                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||                                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||
1908                                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||                                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1909                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)) {                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)     ||
1910                                    (iOldBaseFontSize   !=  m_pOptions->iBaseFontSize)) {
1911                                  QMessageBox::information(this,                                  QMessageBox::information(this,
1912                                          QSAMPLER_TITLE ": " + tr("Information"),                                          QSAMPLER_TITLE ": " + tr("Information"),
1913                                          tr("Some settings may be only effective\n"                                          tr("Some settings may be only effective\n"
1914                                          "next time you start this program."), tr("OK"));                                          "next time you start this program."));
1915                                  updateMessagesCapture();                                  updateMessagesCapture();
1916                          }                          }
1917                          // Check wheather something immediate has changed.                          // Check wheather something immediate has changed.
1918                            if (( bOldMessagesLog && !m_pOptions->bMessagesLog) ||
1919                                    (!bOldMessagesLog &&  m_pOptions->bMessagesLog) ||
1920                                    (sOldMessagesLogPath != m_pOptions->sMessagesLogPath))
1921                                    m_pMessages->setLogging(
1922                                            m_pOptions->bMessagesLog, m_pOptions->sMessagesLogPath);
1923                          if (( bOldCompletePath && !m_pOptions->bCompletePath) ||                          if (( bOldCompletePath && !m_pOptions->bCompletePath) ||
1924                                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||                                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||
1925                                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))                                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))
# Line 1612  void MainForm::viewOptions (void) Line 1960  void MainForm::viewOptions (void)
1960    
1961    
1962  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1963  // qsamplerMainForm -- Channels action slots.  // QSampler::MainForm -- Channels action slots.
1964    
1965  // Arrange channel strips.  // Arrange channel strips.
1966  void MainForm::channelsArrange (void)  void MainForm::channelsArrange (void)
1967  {  {
1968          // Full width vertical tiling          // Full width vertical tiling
1969          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
1970                    = m_pWorkspace->subWindowList();
1971          if (wlist.isEmpty())          if (wlist.isEmpty())
1972                  return;                  return;
1973    
1974          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1975          int y = 0;          int y = 0;
1976          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          const int iStripCount = wlist.count();
1977                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
1978          /*  if (pChannelStrip->testWState(WState_Maximized | WState_Minimized)) {                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
1979                          // Prevent flicker...                  if (pMdiSubWindow) {
1980                          pChannelStrip->hide();                          pMdiSubWindow->adjustSize();
1981                          pChannelStrip->showNormal();                          int iWidth = m_pWorkspace->width();
1982                  }   */                          if (iWidth < pMdiSubWindow->width())
1983                  pChannelStrip->adjustSize();                                  iWidth = pMdiSubWindow->width();
1984                  int iWidth  = m_pWorkspace->width();                          const int iHeight = pMdiSubWindow->frameGeometry().height();
1985                  if (iWidth < pChannelStrip->width())                          pMdiSubWindow->setGeometry(0, y, iWidth, iHeight);
1986                          iWidth = pChannelStrip->width();                          y += iHeight;
1987          //  int iHeight = pChannelStrip->height()                  }
         //              + pChannelStrip->parentWidget()->baseSize().height();  
                 int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();  
                 pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);  
                 y += iHeight;  
1988          }          }
1989          m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
1990    
# Line 1657  void MainForm::channelsAutoArrange ( boo Line 2002  void MainForm::channelsAutoArrange ( boo
2002          m_pOptions->bAutoArrange = bOn;          m_pOptions->bAutoArrange = bOn;
2003    
2004          // If on, update whole workspace...          // If on, update whole workspace...
2005          if (m_pOptions->bAutoArrange)          channelsArrangeAuto();
2006    }
2007    
2008    
2009    void MainForm::channelsArrangeAuto (void)
2010    {
2011            if (m_pOptions && m_pOptions->bAutoArrange)
2012                  channelsArrange();                  channelsArrange();
2013  }  }
2014    
2015    
2016  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2017  // qsamplerMainForm -- Help Action slots.  // QSampler::MainForm -- Help Action slots.
2018    
2019  // Show information about the Qt toolkit.  // Show information about the Qt toolkit.
2020  void MainForm::helpAboutQt (void)  void MainForm::helpAboutQt (void)
# Line 1675  void MainForm::helpAboutQt (void) Line 2026  void MainForm::helpAboutQt (void)
2026  // Show information about application program.  // Show information about application program.
2027  void MainForm::helpAbout (void)  void MainForm::helpAbout (void)
2028  {  {
2029          // Stuff the about box text...          QStringList list;
         QString sText = "<p>\n";  
         sText += "<b>" QSAMPLER_TITLE " - " + tr(QSAMPLER_SUBTITLE) + "</b><br />\n";  
         sText += "<br />\n";  
         sText += tr("Version") + ": <b>" QSAMPLER_VERSION "</b><br />\n";  
         sText += "<small>" + tr("Build") + ": " __DATE__ " " __TIME__ "</small><br />\n";  
2030  #ifdef CONFIG_DEBUG  #ifdef CONFIG_DEBUG
2031          sText += "<small><font color=\"red\">";          list << tr("Debugging option enabled.");
         sText += tr("Debugging option enabled.");  
         sText += "</font></small><br />";  
2032  #endif  #endif
2033  #ifndef CONFIG_LIBGIG  #ifndef CONFIG_LIBGIG
2034          sText += "<small><font color=\"red\">";          list << tr("GIG (libgig) file support disabled.");
         sText += tr("GIG (libgig) file support disabled.");  
         sText += "</font></small><br />";  
2035  #endif  #endif
2036  #ifndef CONFIG_INSTRUMENT_NAME  #ifndef CONFIG_INSTRUMENT_NAME
2037          sText += "<small><font color=\"red\">";          list << tr("LSCP (liblscp) instrument_name support disabled.");
         sText += tr("LSCP (liblscp) instrument_name support disabled.");  
         sText += "</font></small><br />";  
2038  #endif  #endif
2039  #ifndef CONFIG_MUTE_SOLO  #ifndef CONFIG_MUTE_SOLO
2040          sText += "<small><font color=\"red\">";          list << tr("Sampler channel Mute/Solo support disabled.");
         sText += tr("Sampler channel Mute/Solo support disabled.");  
         sText += "</font></small><br />";  
2041  #endif  #endif
2042  #ifndef CONFIG_AUDIO_ROUTING  #ifndef CONFIG_AUDIO_ROUTING
2043          sText += "<small><font color=\"red\">";          list << tr("LSCP (liblscp) audio_routing support disabled.");
         sText += tr("LSCP (liblscp) audio_routing support disabled.");  
         sText += "</font></small><br />";  
2044  #endif  #endif
2045  #ifndef CONFIG_FXSEND  #ifndef CONFIG_FXSEND
2046          sText += "<small><font color=\"red\">";          list << tr("Sampler channel Effect Sends support disabled.");
         sText += tr("Sampler channel Effect Sends support disabled.");  
         sText += "</font></small><br />";  
2047  #endif  #endif
2048  #ifndef CONFIG_VOLUME  #ifndef CONFIG_VOLUME
2049          sText += "<small><font color=\"red\">";          list << tr("Global volume support disabled.");
         sText += tr("Global volume support disabled.");  
         sText += "</font></small><br />";  
2050  #endif  #endif
2051  #ifndef CONFIG_MIDI_INSTRUMENT  #ifndef CONFIG_MIDI_INSTRUMENT
2052          sText += "<small><font color=\"red\">";          list << tr("MIDI instrument mapping support disabled.");
         sText += tr("MIDI instrument mapping support disabled.");  
         sText += "</font></small><br />";  
2053  #endif  #endif
2054  #ifndef CONFIG_EDIT_INSTRUMENT  #ifndef CONFIG_EDIT_INSTRUMENT
2055          sText += "<small><font color=\"red\">";          list << tr("Instrument editing support disabled.");
2056          sText += tr("Instrument editing support disabled.");  #endif
2057          sText += "</font></small><br />";  #ifndef CONFIG_EVENT_CHANNEL_MIDI
2058            list << tr("Channel MIDI event support disabled.");
2059    #endif
2060    #ifndef CONFIG_EVENT_DEVICE_MIDI
2061            list << tr("Device MIDI event support disabled.");
2062  #endif  #endif
2063    #ifndef CONFIG_MAX_VOICES
2064            list << tr("Runtime max. voices / disk streams support disabled.");
2065    #endif
2066    
2067            // Stuff the about box text...
2068            QString sText = "<p>\n";
2069            sText += "<b>" QSAMPLER_TITLE " - " + tr(QSAMPLER_SUBTITLE) + "</b><br />\n";
2070            sText += "<br />\n";
2071            sText += tr("Version") + ": <b>" CONFIG_BUILD_VERSION "</b><br />\n";
2072    //      sText += "<small>" + tr("Build") + ": " CONFIG_BUILD_DATE "</small><br />\n";
2073            if (!list.isEmpty()) {
2074                    sText += "<small><font color=\"red\">";
2075                    sText += list.join("<br />\n");
2076                    sText += "</font></small>";
2077            }
2078          sText += "<br />\n";          sText += "<br />\n";
2079          sText += tr("Using") + ": ";          sText += tr("Using") + ": ";
2080          sText += ::lscp_client_package();          sText += ::lscp_client_package();
# Line 1755  void MainForm::helpAbout (void) Line 2104  void MainForm::helpAbout (void)
2104    
2105    
2106  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2107  // qsamplerMainForm -- Main window stabilization.  // QSampler::MainForm -- Main window stabilization.
2108    
2109  void MainForm::stabilizeForm (void)  void MainForm::stabilizeForm (void)
2110  {  {
# Line 1766  void MainForm::stabilizeForm (void) Line 2115  void MainForm::stabilizeForm (void)
2115          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));
2116    
2117          // Update the main menu state...          // Update the main menu state...
2118          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
2119          bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);          const QList<QMdiSubWindow *>& wlist = m_pWorkspace->subWindowList();
2120          bool bHasChannel = (bHasClient && pChannelStrip != NULL);          const bool bHasClient = (m_pOptions != NULL && m_pClient != NULL);
2121            const bool bHasChannel = (bHasClient && pChannelStrip != NULL);
2122            const bool bHasChannels = (bHasClient && wlist.count() > 0);
2123          m_ui.fileNewAction->setEnabled(bHasClient);          m_ui.fileNewAction->setEnabled(bHasClient);
2124          m_ui.fileOpenAction->setEnabled(bHasClient);          m_ui.fileOpenAction->setEnabled(bHasClient);
2125          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
# Line 1784  void MainForm::stabilizeForm (void) Line 2135  void MainForm::stabilizeForm (void)
2135          m_ui.editEditChannelAction->setEnabled(false);          m_ui.editEditChannelAction->setEnabled(false);
2136  #endif  #endif
2137          m_ui.editResetChannelAction->setEnabled(bHasChannel);          m_ui.editResetChannelAction->setEnabled(bHasChannel);
2138          m_ui.editResetAllChannelsAction->setEnabled(bHasChannel);          m_ui.editResetAllChannelsAction->setEnabled(bHasChannels);
2139          m_ui.viewMessagesAction->setChecked(m_pMessages && m_pMessages->isVisible());          m_ui.viewMessagesAction->setChecked(m_pMessages && m_pMessages->isVisible());
2140  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
2141          m_ui.viewInstrumentsAction->setChecked(m_pInstrumentListForm          m_ui.viewInstrumentsAction->setChecked(m_pInstrumentListForm
# Line 1796  void MainForm::stabilizeForm (void) Line 2147  void MainForm::stabilizeForm (void)
2147          m_ui.viewDevicesAction->setChecked(m_pDeviceForm          m_ui.viewDevicesAction->setChecked(m_pDeviceForm
2148                  && m_pDeviceForm->isVisible());                  && m_pDeviceForm->isVisible());
2149          m_ui.viewDevicesAction->setEnabled(bHasClient);          m_ui.viewDevicesAction->setEnabled(bHasClient);
2150          m_ui.channelsArrangeAction->setEnabled(bHasChannel);          m_ui.viewMidiDeviceStatusMenu->setEnabled(
2151                    DeviceStatusForm::getInstances().size() > 0);
2152            m_ui.channelsArrangeAction->setEnabled(bHasChannels);
2153    
2154  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
2155          // Toolbar widgets are also affected...          // Toolbar widgets are also affected...
# Line 1846  void MainForm::volumeChanged ( int iVolu Line 2199  void MainForm::volumeChanged ( int iVolu
2199                  m_pVolumeSpinBox->setValue(iVolume);                  m_pVolumeSpinBox->setValue(iVolume);
2200    
2201          // Do it as commanded...          // Do it as commanded...
2202          float fVolume = 0.01f * float(iVolume);          const float fVolume = 0.01f * float(iVolume);
2203          if (::lscp_set_volume(m_pClient, fVolume) == LSCP_OK)          if (::lscp_set_volume(m_pClient, fVolume) == LSCP_OK)
2204                  appendMessages(QObject::tr("Volume: %1.").arg(fVolume));                  appendMessages(QObject::tr("Volume: %1.").arg(fVolume));
2205          else          else
# Line 1862  void MainForm::volumeChanged ( int iVolu Line 2215  void MainForm::volumeChanged ( int iVolu
2215    
2216    
2217  // Channel change receiver slot.  // Channel change receiver slot.
2218  void MainForm::channelStripChanged(ChannelStrip* pChannelStrip)  void MainForm::channelStripChanged ( ChannelStrip *pChannelStrip )
2219  {  {
2220          // Add this strip to the changed list...          // Add this strip to the changed list...
2221          if (!m_changedStrips.contains(pChannelStrip)) {          if (!m_changedStrips.contains(pChannelStrip)) {
# Line 1881  void MainForm::channelStripChanged(Chann Line 2234  void MainForm::channelStripChanged(Chann
2234  void MainForm::updateSession (void)  void MainForm::updateSession (void)
2235  {  {
2236  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
2237          int iVolume = ::lroundf(100.0f * ::lscp_get_volume(m_pClient));          const int iVolume = ::lroundf(100.0f * ::lscp_get_volume(m_pClient));
2238          m_iVolumeChanging++;          m_iVolumeChanging++;
2239          m_pVolumeSlider->setValue(iVolume);          m_pVolumeSlider->setValue(iVolume);
2240          m_pVolumeSpinBox->setValue(iVolume);          m_pVolumeSpinBox->setValue(iVolume);
# Line 1889  void MainForm::updateSession (void) Line 2242  void MainForm::updateSession (void)
2242  #endif  #endif
2243  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
2244          // FIXME: Make some room for default instrument maps...          // FIXME: Make some room for default instrument maps...
2245          int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);          const int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);
2246          if (iMaps < 0)          if (iMaps < 0)
2247                  appendMessagesClient("lscp_get_midi_instrument_maps");                  appendMessagesClient("lscp_get_midi_instrument_maps");
2248          else if (iMaps < 1) {          else if (iMaps < 1) {
# Line 1900  void MainForm::updateSession (void) Line 2253  void MainForm::updateSession (void)
2253          }          }
2254  #endif  #endif
2255    
2256            updateAllChannelStrips(false);
2257    
2258            // Do we auto-arrange?
2259            channelsArrangeAuto();
2260    
2261            // Remember to refresh devices and instruments...
2262            if (m_pInstrumentListForm)
2263                    m_pInstrumentListForm->refreshInstruments();
2264            if (m_pDeviceForm)
2265                    m_pDeviceForm->refreshDevices();
2266    }
2267    
2268    
2269    void MainForm::updateAllChannelStrips ( bool bRemoveDeadStrips )
2270    {
2271            // Skip if setting up a new channel strip...
2272            if (m_iDirtySetup > 0)
2273                    return;
2274    
2275          // Retrieve the current channel list.          // Retrieve the current channel list.
2276          int *piChannelIDs = ::lscp_list_channels(m_pClient);          int *piChannelIDs = ::lscp_list_channels(m_pClient);
2277          if (piChannelIDs == NULL) {          if (piChannelIDs == NULL) {
# Line 1911  void MainForm::updateSession (void) Line 2283  void MainForm::updateSession (void)
2283          } else {          } else {
2284                  // Try to (re)create each channel.                  // Try to (re)create each channel.
2285                  m_pWorkspace->setUpdatesEnabled(false);                  m_pWorkspace->setUpdatesEnabled(false);
2286                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {
2287                          // Check if theres already a channel strip for this one...                          // Check if theres already a channel strip for this one...
2288                          if (!channelStrip(piChannelIDs[iChannel]))                          if (!channelStrip(piChannelIDs[iChannel]))
2289                                  createChannelStrip(new qsamplerChannel(piChannelIDs[iChannel]));                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));
2290                    }
2291                    // Do we auto-arrange?
2292                    channelsArrangeAuto();
2293                    // remove dead channel strips
2294                    if (bRemoveDeadStrips) {
2295                            const QList<QMdiSubWindow *>& wlist
2296                                    = m_pWorkspace->subWindowList();
2297                            const int iStripCount = wlist.count();
2298                            for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2299                                    ChannelStrip *pChannelStrip = NULL;
2300                                    QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2301                                    if (pMdiSubWindow)
2302                                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2303                                    if (pChannelStrip) {
2304                                            bool bExists = false;
2305                                            for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {
2306                                                    Channel *pChannel = pChannelStrip->channel();
2307                                                    if (pChannel == NULL)
2308                                                            break;
2309                                                    if (piChannelIDs[iChannel] == pChannel->channelID()) {
2310                                                            // strip exists, don't touch it
2311                                                            bExists = true;
2312                                                            break;
2313                                                    }
2314                                            }
2315                                            if (!bExists)
2316                                                    destroyChannelStrip(pChannelStrip);
2317                                    }
2318                            }
2319                  }                  }
2320                  m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
2321          }          }
2322    
2323          // 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();  
2324  }  }
2325    
2326    
# Line 1938  void MainForm::updateRecentFiles ( const Line 2331  void MainForm::updateRecentFiles ( const
2331                  return;                  return;
2332    
2333          // Remove from list if already there (avoid duplicates)          // Remove from list if already there (avoid duplicates)
2334          int iIndex = m_pOptions->recentFiles.indexOf(sFilename);          const int iIndex = m_pOptions->recentFiles.indexOf(sFilename);
2335          if (iIndex >= 0)          if (iIndex >= 0)
2336                  m_pOptions->recentFiles.removeAt(iIndex);                  m_pOptions->recentFiles.removeAt(iIndex);
2337          // Put it to front...          // Put it to front...
# Line 1977  void MainForm::updateRecentFilesMenu (vo Line 2370  void MainForm::updateRecentFilesMenu (vo
2370  void MainForm::updateInstrumentNames (void)  void MainForm::updateInstrumentNames (void)
2371  {  {
2372          // Full channel list update...          // Full channel list update...
2373          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2374                    = m_pWorkspace->subWindowList();
2375          if (wlist.isEmpty())          if (wlist.isEmpty())
2376                  return;                  return;
2377    
2378          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2379          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          const int iStripCount = wlist.count();
2380                  ChannelStrip *pChannelStrip = (ChannelStrip *) wlist.at(iChannel);          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2381                    ChannelStrip *pChannelStrip = NULL;
2382                    QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2383                    if (pMdiSubWindow)
2384                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2385                  if (pChannelStrip)                  if (pChannelStrip)
2386                          pChannelStrip->updateInstrumentName(true);                          pChannelStrip->updateInstrumentName(true);
2387          }          }
# Line 2000  void MainForm::updateDisplayFont (void) Line 2398  void MainForm::updateDisplayFont (void)
2398          // Check if display font is legal.          // Check if display font is legal.
2399          if (m_pOptions->sDisplayFont.isEmpty())          if (m_pOptions->sDisplayFont.isEmpty())
2400                  return;                  return;
2401    
2402          // Realize it.          // Realize it.
2403          QFont font;          QFont font;
2404          if (!font.fromString(m_pOptions->sDisplayFont))          if (!font.fromString(m_pOptions->sDisplayFont))
2405                  return;                  return;
2406    
2407          // Full channel list update...          // Full channel list update...
2408          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2409                    = m_pWorkspace->subWindowList();
2410          if (wlist.isEmpty())          if (wlist.isEmpty())
2411                  return;                  return;
2412    
2413          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2414          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          const int iStripCount = wlist.count();
2415                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2416                    ChannelStrip *pChannelStrip = NULL;
2417                    QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2418                    if (pMdiSubWindow)
2419                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2420                  if (pChannelStrip)                  if (pChannelStrip)
2421                          pChannelStrip->setDisplayFont(font);                          pChannelStrip->setDisplayFont(font);
2422          }          }
# Line 2024  void MainForm::updateDisplayFont (void) Line 2428  void MainForm::updateDisplayFont (void)
2428  void MainForm::updateDisplayEffect (void)  void MainForm::updateDisplayEffect (void)
2429  {  {
2430          // Full channel list update...          // Full channel list update...
2431          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2432                    = m_pWorkspace->subWindowList();
2433          if (wlist.isEmpty())          if (wlist.isEmpty())
2434                  return;                  return;
2435    
2436          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2437          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          const int iStripCount = wlist.count();
2438                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2439                    ChannelStrip *pChannelStrip = NULL;
2440                    QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2441                    if (pMdiSubWindow)
2442                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2443                  if (pChannelStrip)                  if (pChannelStrip)
2444                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2445          }          }
# Line 2052  void MainForm::updateMaxVolume (void) Line 2461  void MainForm::updateMaxVolume (void)
2461  #endif  #endif
2462    
2463          // Full channel list update...          // Full channel list update...
2464          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2465                    = m_pWorkspace->subWindowList();
2466          if (wlist.isEmpty())          if (wlist.isEmpty())
2467                  return;                  return;
2468    
2469          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2470          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          const int iStripCount = wlist.count();
2471                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2472                    ChannelStrip *pChannelStrip = NULL;
2473                    QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2474                    if (pMdiSubWindow)
2475                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2476                  if (pChannelStrip)                  if (pChannelStrip)
2477                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2478          }          }
# Line 2067  void MainForm::updateMaxVolume (void) Line 2481  void MainForm::updateMaxVolume (void)
2481    
2482    
2483  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2484  // qsamplerMainForm -- Messages window form handlers.  // QSampler::MainForm -- Messages window form handlers.
2485    
2486  // Messages output methods.  // Messages output methods.
2487  void MainForm::appendMessages( const QString& s )  void MainForm::appendMessages( const QString& s )
# Line 2092  void MainForm::appendMessagesText( const Line 2506  void MainForm::appendMessagesText( const
2506                  m_pMessages->appendMessagesText(s);                  m_pMessages->appendMessagesText(s);
2507  }  }
2508    
2509  void MainForm::appendMessagesError( const QString& s )  void MainForm::appendMessagesError( const QString& sText )
2510  {  {
2511          if (m_pMessages)          if (m_pMessages)
2512                  m_pMessages->show();                  m_pMessages->show();
2513    
2514          appendMessagesColor(s.simplified(), "#ff0000");          appendMessagesColor(sText.simplified(), "#ff0000");
2515    
2516          // Make it look responsive...:)          // Make it look responsive...:)
2517          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2518    
2519          QMessageBox::critical(this,          if (m_pOptions && m_pOptions->bConfirmError) {
2520                  QSAMPLER_TITLE ": " + tr("Error"), s, tr("Cancel"));                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Error");
2521            #if 0
2522                    QMessageBox::critical(this, sTitle, sText, QMessageBox::Cancel);
2523            #else
2524                    QMessageBox mbox(this);
2525                    mbox.setIcon(QMessageBox::Critical);
2526                    mbox.setWindowTitle(sTitle);
2527                    mbox.setText(sText);
2528                    mbox.setStandardButtons(QMessageBox::Cancel);
2529                    QCheckBox cbox(tr("Don't show this again"));
2530                    cbox.setChecked(false);
2531                    cbox.blockSignals(true);
2532                    mbox.addButton(&cbox, QMessageBox::ActionRole);
2533                    if (mbox.exec() && cbox.isChecked())
2534                            m_pOptions->bConfirmError = false;
2535            #endif
2536            }
2537  }  }
2538    
2539    
# Line 2163  void MainForm::updateMessagesCapture (vo Line 2593  void MainForm::updateMessagesCapture (vo
2593    
2594    
2595  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2596  // qsamplerMainForm -- MDI channel strip management.  // QSampler::MainForm -- MDI channel strip management.
2597    
2598  // The channel strip creation executive.  // The channel strip creation executive.
2599  ChannelStrip* MainForm::createChannelStrip(qsamplerChannel* pChannel)  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )
2600  {  {
2601          if (m_pClient == NULL || pChannel == NULL)          if (m_pClient == NULL || pChannel == NULL)
2602                  return NULL;                  return NULL;
2603    
         // 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();  
                         }  
                 }  
         }  
   
2604          // Add a new channel itema...          // Add a new channel itema...
2605          pChannelStrip = new ChannelStrip();          ChannelStrip *pChannelStrip = new ChannelStrip();
2606          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
2607                  return NULL;                  return NULL;
2608    
2609          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...  
2610          if (m_pOptions) {          if (m_pOptions) {
2611                  // Background display effect...                  // Background display effect...
2612                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2613                  // We'll need a display font.                  // We'll need a display font.
2614                  QFont font;                  QFont font;
2615                  if (font.fromString(m_pOptions->sDisplayFont))                  if (!m_pOptions->sDisplayFont.isEmpty() &&
2616                            font.fromString(m_pOptions->sDisplayFont))
2617                          pChannelStrip->setDisplayFont(font);                          pChannelStrip->setDisplayFont(font);
2618                  // Maximum allowed volume setting.                  // Maximum allowed volume setting.
2619                  pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                  pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2620          }          }
2621    
2622            // Add it to workspace...
2623            m_pWorkspace->addSubWindow(pChannelStrip,
2624                    Qt::SubWindow | Qt::FramelessWindowHint);
2625    
2626            // Actual channel strip setup...
2627            pChannelStrip->setup(pChannel);
2628    
2629            QObject::connect(pChannelStrip,
2630                    SIGNAL(channelChanged(ChannelStrip *)),
2631                    SLOT(channelStripChanged(ChannelStrip *)));
2632    
2633          // Now we show up us to the world.          // Now we show up us to the world.
2634          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);  
         }  
2635    
2636          // This is pretty new, so we'll watch for it closely.          // This is pretty new, so we'll watch for it closely.
2637          channelStripChanged(pChannelStrip);          channelStripChanged(pChannelStrip);
# Line 2229  ChannelStrip* MainForm::createChannelStr Line 2641  ChannelStrip* MainForm::createChannelStr
2641  }  }
2642    
2643    
2644    void MainForm::destroyChannelStrip ( ChannelStrip *pChannelStrip )
2645    {
2646            QMdiSubWindow *pMdiSubWindow
2647                    = static_cast<QMdiSubWindow *> (pChannelStrip->parentWidget());
2648            if (pMdiSubWindow == NULL)
2649                    return;
2650    
2651            // Just delete the channel strip.
2652            delete pChannelStrip;
2653            delete pMdiSubWindow;
2654    
2655            // Do we auto-arrange?
2656            channelsArrangeAuto();
2657    }
2658    
2659    
2660  // Retrieve the active channel strip.  // Retrieve the active channel strip.
2661  ChannelStrip* MainForm::activeChannelStrip (void)  ChannelStrip *MainForm::activeChannelStrip (void)
2662  {  {
2663          return static_cast<ChannelStrip *> (m_pWorkspace->activeWindow());          QMdiSubWindow *pMdiSubWindow = m_pWorkspace->activeSubWindow();
2664            if (pMdiSubWindow)
2665                    return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2666            else
2667                    return NULL;
2668  }  }
2669    
2670    
2671  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2672  ChannelStrip* MainForm::channelStripAt ( int iChannel )  ChannelStrip *MainForm::channelStripAt ( int iStrip )
2673  {  {
2674          QWidgetList wlist = m_pWorkspace->windowList();          if (!m_pWorkspace) return NULL;
2675    
2676            const QList<QMdiSubWindow *>& wlist
2677                    = m_pWorkspace->subWindowList();
2678          if (wlist.isEmpty())          if (wlist.isEmpty())
2679                  return NULL;                  return NULL;
2680    
2681          return static_cast<ChannelStrip *> (wlist.at(iChannel));          if (iStrip < 0 || iStrip >= wlist.count())
2682                    return NULL;
2683    
2684            QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2685            if (pMdiSubWindow)
2686                    return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2687            else
2688                    return NULL;
2689  }  }
2690    
2691    
2692  // Retrieve a channel strip by sampler channel id.  // Retrieve a channel strip by sampler channel id.
2693  ChannelStrip* MainForm::channelStrip ( int iChannelID )  ChannelStrip *MainForm::channelStrip ( int iChannelID )
2694  {  {
2695          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2696                    = m_pWorkspace->subWindowList();
2697          if (wlist.isEmpty())          if (wlist.isEmpty())
2698                  return NULL;                  return NULL;
2699    
2700          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          const int iStripCount = wlist.count();
2701                  ChannelStrip* pChannelStrip          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2702                          = static_cast<ChannelStrip*> (wlist.at(iChannel));                  ChannelStrip *pChannelStrip = NULL;
2703                    QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2704                    if (pMdiSubWindow)
2705                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2706                  if (pChannelStrip) {                  if (pChannelStrip) {
2707                          qsamplerChannel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
2708                          if (pChannel && pChannel->channelID() == iChannelID)                          if (pChannel && pChannel->channelID() == iChannelID)
2709                                  return pChannelStrip;                                  return pChannelStrip;
2710                  }                  }
# Line 2276  void MainForm::channelsMenuAboutToShow ( Line 2722  void MainForm::channelsMenuAboutToShow (
2722          m_ui.channelsMenu->addAction(m_ui.channelsArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsArrangeAction);
2723          m_ui.channelsMenu->addAction(m_ui.channelsAutoArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsAutoArrangeAction);
2724    
2725          QWidgetList wlist = m_pWorkspace->windowList();          const QList<QMdiSubWindow *>& wlist
2726                    = m_pWorkspace->subWindowList();
2727          if (!wlist.isEmpty()) {          if (!wlist.isEmpty()) {
2728                  m_ui.channelsMenu->addSeparator();                  m_ui.channelsMenu->addSeparator();
2729                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                  const int iStripCount = wlist.count();
2730                          ChannelStrip* pChannelStrip                  for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2731                                  = static_cast<ChannelStrip*> (wlist.at(iChannel));                          ChannelStrip *pChannelStrip = NULL;
2732                            QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2733                            if (pMdiSubWindow)
2734                                    pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2735                          if (pChannelStrip) {                          if (pChannelStrip) {
2736                                  QAction *pAction = m_ui.channelsMenu->addAction(                                  QAction *pAction = m_ui.channelsMenu->addAction(
2737                                          pChannelStrip->windowTitle(),                                          pChannelStrip->windowTitle(),
2738                                          this, SLOT(channelsMenuActivated()));                                          this, SLOT(channelsMenuActivated()));
2739                                  pAction->setCheckable(true);                                  pAction->setCheckable(true);
2740                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);
2741                                  pAction->setData(iChannel);                                  pAction->setData(iStrip);
2742                          }                          }
2743                  }                  }
2744          }          }
# Line 2303  void MainForm::channelsMenuActivated (vo Line 2753  void MainForm::channelsMenuActivated (vo
2753          if (pAction == NULL)          if (pAction == NULL)
2754                  return;                  return;
2755    
2756          ChannelStrip* pChannelStrip = channelStripAt(pAction->data().toInt());          ChannelStrip *pChannelStrip = channelStripAt(pAction->data().toInt());
2757          if (pChannelStrip) {          if (pChannelStrip) {
2758                  pChannelStrip->showNormal();                  pChannelStrip->showNormal();
2759                  pChannelStrip->setFocus();                  pChannelStrip->setFocus();
# Line 2312  void MainForm::channelsMenuActivated (vo Line 2762  void MainForm::channelsMenuActivated (vo
2762    
2763    
2764  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2765  // qsamplerMainForm -- Timer stuff.  // QSampler::MainForm -- Timer stuff.
2766    
2767  // Set the pseudo-timer delay schedule.  // Set the pseudo-timer delay schedule.
2768  void MainForm::startSchedule ( int iStartDelay )  void MainForm::startSchedule ( int iStartDelay )
# Line 2353  void MainForm::timerSlot (void) Line 2803  void MainForm::timerSlot (void)
2803                          ChannelStrip *pChannelStrip = iter.next();                          ChannelStrip *pChannelStrip = iter.next();
2804                          // If successfull, remove from pending list...                          // If successfull, remove from pending list...
2805                          if (pChannelStrip->updateChannelInfo()) {                          if (pChannelStrip->updateChannelInfo()) {
2806                                  int iChannelStrip = m_changedStrips.indexOf(pChannelStrip);                                  const int iChannelStrip = m_changedStrips.indexOf(pChannelStrip);
2807                                  if (iChannelStrip >= 0)                                  if (iChannelStrip >= 0)
2808                                          m_changedStrips.removeAt(iChannelStrip);                                          m_changedStrips.removeAt(iChannelStrip);
2809                          }                          }
# Line 2364  void MainForm::timerSlot (void) Line 2814  void MainForm::timerSlot (void)
2814                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {
2815                                  m_iTimerSlot = 0;                                  m_iTimerSlot = 0;
2816                                  // Update the channel stream usage for each strip...                                  // Update the channel stream usage for each strip...
2817                                  QWidgetList wlist = m_pWorkspace->windowList();                                  const QList<QMdiSubWindow *>& wlist
2818                                  for (int iChannel = 0;                                          = m_pWorkspace->subWindowList();
2819                                                  iChannel < (int) wlist.count(); iChannel++) {                                  const int iStripCount = wlist.count();
2820                                          ChannelStrip* pChannelStrip                                  for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2821                                                  = (ChannelStrip*) wlist.at(iChannel);                                          ChannelStrip *pChannelStrip = NULL;
2822                                            QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2823                                            if (pMdiSubWindow)
2824                                                    pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2825                                          if (pChannelStrip && pChannelStrip->isVisible())                                          if (pChannelStrip && pChannelStrip->isVisible())
2826                                                  pChannelStrip->updateChannelUsage();                                                  pChannelStrip->updateChannelUsage();
2827                                  }                                  }
# Line 2382  void MainForm::timerSlot (void) Line 2835  void MainForm::timerSlot (void)
2835    
2836    
2837  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2838  // qsamplerMainForm -- Server stuff.  // QSampler::MainForm -- Server stuff.
2839    
2840  // Start linuxsampler server...  // Start linuxsampler server...
2841  void MainForm::startServer (void)  void MainForm::startServer (void)
# Line 2396  void MainForm::startServer (void) Line 2849  void MainForm::startServer (void)
2849    
2850          // Is the server process instance still here?          // Is the server process instance still here?
2851          if (m_pServer) {          if (m_pServer) {
2852                  switch (QMessageBox::warning(this,                  if (QMessageBox::warning(this,
2853                          QSAMPLER_TITLE ": " + tr("Warning"),                          QSAMPLER_TITLE ": " + tr("Warning"),
2854                          tr("Could not start the LinuxSampler server.\n\n"                          tr("Could not start the LinuxSampler server.\n\n"
2855                          "Maybe it ss already started."),                          "Maybe it is already started."),
2856                          tr("Stop"), tr("Kill"), tr("Cancel"))) {                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
                 case 0:  
2857                          m_pServer->terminate();                          m_pServer->terminate();
                         break;  
                 case 1:  
2858                          m_pServer->kill();                          m_pServer->kill();
                         break;  
2859                  }                  }
2860                  return;                  return;
2861          }          }
# Line 2419  void MainForm::startServer (void) Line 2868  void MainForm::startServer (void)
2868                  return;                  return;
2869    
2870          // OK. Let's build the startup process...          // OK. Let's build the startup process...
2871          m_pServer = new QProcess(this);          m_pServer = new QProcess();
2872            m_bForceServerStop = true;
2873    
2874          // Setup stdout/stderr capture...          // Setup stdout/stderr capture...
2875  //      if (m_pOptions->bStdoutCapture) {          m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);
2876                  //m_pServer->setProcessChannelMode(          QObject::connect(m_pServer,
2877                  //      QProcess::StandardOutput);                  SIGNAL(readyReadStandardOutput()),
2878                  QObject::connect(m_pServer,                  SLOT(readServerStdout()));
2879                          SIGNAL(readyReadStandardOutput()),          QObject::connect(m_pServer,
2880                          SLOT(readServerStdout()));                  SIGNAL(readyReadStandardError()),
2881                  QObject::connect(m_pServer,                  SLOT(readServerStdout()));
                         SIGNAL(readyReadStandardError()),  
                         SLOT(readServerStdout()));  
 //      }  
2882    
2883          // The unforgiveable signal communication...          // The unforgiveable signal communication...
2884          QObject::connect(m_pServer,          QObject::connect(m_pServer,
2885                  SIGNAL(finished(int,QProcess::ExitStatus)),                  SIGNAL(finished(int, QProcess::ExitStatus)),
2886                  SLOT(processServerExit()));                  SLOT(processServerExit()));
2887    
2888          // Build process arguments...          // Build process arguments...
# Line 2466  void MainForm::startServer (void) Line 2913  void MainForm::startServer (void)
2913    
2914    
2915  // Stop linuxsampler server...  // Stop linuxsampler server...
2916  void MainForm::stopServer (void)  void MainForm::stopServer ( bool bInteractive )
2917  {  {
2918          // Stop client code.          // Stop client code.
2919          stopClient();          stopClient();
2920    
2921            if (m_pServer && bInteractive) {
2922                    if (QMessageBox::question(this,
2923                            QSAMPLER_TITLE ": " + tr("The backend's fate ..."),
2924                            tr("You have the option to keep the sampler backend (LinuxSampler)\n"
2925                            "running in the background. The sampler would continue to work\n"
2926                            "according to your current sampler session and you could alter the\n"
2927                            "sampler session at any time by relaunching QSampler.\n\n"
2928                            "Do you want LinuxSampler to stop?"),
2929                            QMessageBox::Yes | QMessageBox::No,
2930                            QMessageBox::Yes) == QMessageBox::No) {
2931                            m_bForceServerStop = false;
2932                    }
2933            }
2934    
2935            bool bGraceWait = true;
2936    
2937          // And try to stop server.          // And try to stop server.
2938          if (m_pServer) {          if (m_pServer && m_bForceServerStop) {
2939                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2940                  if (m_pServer->state() == QProcess::Running)                  if (m_pServer->state() == QProcess::Running) {
2941                    #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
2942                            // Try harder...
2943                            m_pServer->kill();
2944                    #else
2945                            // Try softly...
2946                          m_pServer->terminate();                          m_pServer->terminate();
2947          }                          bool bFinished = m_pServer->waitForFinished(QSAMPLER_TIMER_MSECS * 1000);
2948                            if (bFinished) bGraceWait = false;
2949                    #endif
2950                    }
2951            }       // Do final processing anyway.
2952            else processServerExit();
2953    
2954          // Give it some time to terminate gracefully and stabilize...          // Give it some time to terminate gracefully and stabilize...
2955          QTime t;          if (bGraceWait) {
2956          t.start();                  QTime t;
2957          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                  t.start();
2958                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2959                            QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2960          // Do final processing anyway.          }
         processServerExit();  
2961  }  }
2962    
2963    
# Line 2507  void MainForm::processServerExit (void) Line 2979  void MainForm::processServerExit (void)
2979          if (m_pMessages)          if (m_pMessages)
2980                  m_pMessages->flushStdoutBuffer();                  m_pMessages->flushStdoutBuffer();
2981    
2982          if (m_pServer) {          if (m_pServer && m_bForceServerStop) {
2983                    if (m_pServer->state() != QProcess::NotRunning) {
2984                            appendMessages(tr("Server is being forced..."));
2985                            // Force final server shutdown...
2986                            m_pServer->kill();
2987                            // Give it some time to terminate gracefully and stabilize...
2988                            QTime t;
2989                            t.start();
2990                            while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2991                                    QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2992                    }
2993                  // Force final server shutdown...                  // Force final server shutdown...
2994                  appendMessages(                  appendMessages(
2995                          tr("Server was stopped with exit status %1.")                          tr("Server was stopped with exit status %1.")
2996                          .arg(m_pServer->exitStatus()));                          .arg(m_pServer->exitStatus()));
                 m_pServer->terminate();  
                 if (!m_pServer->waitForFinished(2000))  
                         m_pServer->kill();  
                 // Destroy it.  
2997                  delete m_pServer;                  delete m_pServer;
2998                  m_pServer = NULL;                  m_pServer = NULL;
2999          }          }
# Line 2526  void MainForm::processServerExit (void) Line 3004  void MainForm::processServerExit (void)
3004    
3005    
3006  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
3007  // qsamplerMainForm -- Client stuff.  // QSampler::MainForm -- Client stuff.
3008    
3009  // The LSCP client callback procedure.  // The LSCP client callback procedure.
3010  lscp_status_t qsampler_client_callback ( lscp_client_t */*pClient*/,  lscp_status_t qsampler_client_callback ( lscp_client_t */*pClient*/,
# Line 2540  lscp_status_t qsampler_client_callback ( Line 3018  lscp_status_t qsampler_client_callback (
3018          // as this is run under some other thread context.          // as this is run under some other thread context.
3019          // A custom event must be posted here...          // A custom event must be posted here...
3020          QApplication::postEvent(pMainForm,          QApplication::postEvent(pMainForm,
3021                  new qsamplerCustomEvent(event, pchData, cchData));                  new LscpEvent(event, pchData, cchData));
3022    
3023          return LSCP_OK;          return LSCP_OK;
3024  }  }
# Line 2578  bool MainForm::startClient (void) Line 3056  bool MainForm::startClient (void)
3056                  stabilizeForm();                  stabilizeForm();
3057                  return false;                  return false;
3058          }          }
3059    
3060          // Just set receive timeout value, blindly.          // Just set receive timeout value, blindly.
3061          ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);          ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
3062          appendMessages(          appendMessages(
# Line 2585  bool MainForm::startClient (void) Line 3064  bool MainForm::startClient (void)
3064                  .arg(::lscp_client_get_timeout(m_pClient)));                  .arg(::lscp_client_get_timeout(m_pClient)));
3065    
3066          // Subscribe to channel info change notifications...          // Subscribe to channel info change notifications...
3067            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT) != LSCP_OK)
3068                    appendMessagesClient("lscp_client_subscribe(CHANNEL_COUNT)");
3069          if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)          if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)
3070                  appendMessagesClient("lscp_client_subscribe");                  appendMessagesClient("lscp_client_subscribe(CHANNEL_INFO)");
3071    
3072            DeviceStatusForm::onDevicesChanged(); // initialize
3073            updateViewMidiDeviceStatusMenu();
3074            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT) != LSCP_OK)
3075                    appendMessagesClient("lscp_client_subscribe(MIDI_INPUT_DEVICE_COUNT)");
3076            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO) != LSCP_OK)
3077                    appendMessagesClient("lscp_client_subscribe(MIDI_INPUT_DEVICE_INFO)");
3078            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT) != LSCP_OK)
3079                    appendMessagesClient("lscp_client_subscribe(AUDIO_OUTPUT_DEVICE_COUNT)");
3080            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO) != LSCP_OK)
3081                    appendMessagesClient("lscp_client_subscribe(AUDIO_OUTPUT_DEVICE_INFO)");
3082    
3083    #if CONFIG_EVENT_CHANNEL_MIDI
3084            // Subscribe to channel MIDI data notifications...
3085            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_MIDI) != LSCP_OK)
3086                    appendMessagesClient("lscp_client_subscribe(CHANNEL_MIDI)");
3087    #endif
3088    
3089    #if CONFIG_EVENT_DEVICE_MIDI
3090            // Subscribe to channel MIDI data notifications...
3091            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_DEVICE_MIDI) != LSCP_OK)
3092                    appendMessagesClient("lscp_client_subscribe(DEVICE_MIDI)");
3093    #endif
3094    
3095          // We may stop scheduling around.          // We may stop scheduling around.
3096          stopSchedule();          stopSchedule();
# Line 2613  bool MainForm::startClient (void) Line 3117  bool MainForm::startClient (void)
3117                  }                  }
3118          }          }
3119    
3120            // send the current / loaded fine tuning settings to the sampler
3121            m_pOptions->sendFineTuningSettings();
3122    
3123          // Make a new session          // Make a new session
3124          return newSession();          return newSession();
3125  }  }
# Line 2640  void MainForm::stopClient (void) Line 3147  void MainForm::stopClient (void)
3147          closeSession(false);          closeSession(false);
3148    
3149          // Close us as a client...          // Close us as a client...
3150    #if CONFIG_EVENT_DEVICE_MIDI
3151            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_DEVICE_MIDI);
3152    #endif
3153    #if CONFIG_EVENT_CHANNEL_MIDI
3154            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_MIDI);
3155    #endif
3156            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO);
3157            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT);
3158            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO);
3159            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT);
3160          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
3161            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);
3162          ::lscp_client_destroy(m_pClient);          ::lscp_client_destroy(m_pClient);
3163          m_pClient = NULL;          m_pClient = NULL;
3164    
# Line 2658  void MainForm::stopClient (void) Line 3176  void MainForm::stopClient (void)
3176          stabilizeForm();          stabilizeForm();
3177  }  }
3178    
3179    
3180    // Channel strip activation/selection.
3181    void MainForm::activateStrip ( QMdiSubWindow *pMdiSubWindow )
3182    {
3183            ChannelStrip *pChannelStrip = NULL;
3184            if (pMdiSubWindow)
3185                    pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
3186            if (pChannelStrip)
3187                    pChannelStrip->setSelected(true);
3188    
3189            stabilizeForm();
3190    }
3191    
3192    
3193    // Channel toolbar orientation change.
3194    void MainForm::channelsToolbarOrientation ( Qt::Orientation orientation )
3195    {
3196    #ifdef CONFIG_VOLUME
3197            m_pVolumeSlider->setOrientation(orientation);
3198            if (orientation == Qt::Horizontal) {
3199                    m_pVolumeSlider->setMinimumHeight(24);
3200                    m_pVolumeSlider->setMaximumHeight(32);
3201                    m_pVolumeSlider->setMinimumWidth(120);
3202                    m_pVolumeSlider->setMaximumWidth(640);
3203                    m_pVolumeSpinBox->setMaximumWidth(64);
3204                    m_pVolumeSpinBox->setButtonSymbols(QSpinBox::UpDownArrows);
3205            } else {
3206                    m_pVolumeSlider->setMinimumHeight(120);
3207                    m_pVolumeSlider->setMaximumHeight(480);
3208                    m_pVolumeSlider->setMinimumWidth(24);
3209                    m_pVolumeSlider->setMaximumWidth(32);
3210                    m_pVolumeSpinBox->setMaximumWidth(32);
3211                    m_pVolumeSpinBox->setButtonSymbols(QSpinBox::NoButtons);
3212            }
3213    #endif
3214    }
3215    
3216    
3217  } // namespace QSampler  } // namespace QSampler
3218    
3219    

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

  ViewVC Help
Powered by ViewVC