/[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 2717 by schoenebeck, Wed Jan 21 13:19:51 2015 UTC revision 3509 by capela, Tue Apr 2 17:55:00 2019 UTC
# Line 1  Line 1 
1  // qsamplerMainForm.cpp  // qsamplerMainForm.cpp
2  //  //
3  /****************************************************************************  /****************************************************************************
4     Copyright (C) 2004-2014, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2019, rncbc aka Rui Nuno Capela. All rights reserved.
5     Copyright (C) 2007, 2008 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 68  const WindowFlags WindowCloseButtonHint Line 68  const WindowFlags WindowCloseButtonHint
68  }  }
69  #endif  #endif
70    
 #ifdef HAVE_SIGNAL_H  
 #include <signal.h>  
 #endif  
   
71  #ifdef CONFIG_LIBGIG  #ifdef CONFIG_LIBGIG
72  #include <gig.h>  #include <gig.h>
73  #endif  #endif
# Line 91  static inline long lroundf ( float x ) Line 87  static inline long lroundf ( float x )
87    
88    
89  // All winsock apps needs this.  // All winsock apps needs this.
90  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
91  static WSADATA _wsaData;  static WSADATA _wsaData;
92  #endif  #endif
93    
# Line 109  static WSADATA _wsaData; Line 105  static WSADATA _wsaData;
105  #include <signal.h>  #include <signal.h>
106    
107  // File descriptor for SIGUSR1 notifier.  // File descriptor for SIGUSR1 notifier.
108  static int g_fdUsr1[2];  static int g_fdSigusr1[2];
109    
110  // Unix SIGUSR1 signal handler.  // Unix SIGUSR1 signal handler.
111  static void qsampler_sigusr1_handler ( int /* signo */ )  static void qsampler_sigusr1_handler ( int /* signo */ )
112  {  {
113          char c = 1;          char c = 1;
114    
115          (::write(g_fdUsr1[0], &c, sizeof(c)) > 0);          (::write(g_fdSigusr1[0], &c, sizeof(c)) > 0);
116    }
117    
118    // File descriptor for SIGTERM notifier.
119    static int g_fdSigterm[2];
120    
121    // Unix SIGTERM signal handler.
122    static void qsampler_sigterm_handler ( int /* signo */ )
123    {
124            char c = 1;
125    
126            (::write(g_fdSigterm[0], &c, sizeof(c)) > 0);
127  }  }
128    
129  #endif  // HAVE_SIGNAL_H  #endif  // HAVE_SIGNAL_H
130    
131    
132  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
133  // qsampler -- namespace  // QSampler -- namespace
134    
135    
136  namespace QSampler {  namespace QSampler {
# Line 143  namespace QSampler { Line 150  namespace QSampler {
150    
151    
152  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
153  // LscpEvent -- specialty for LSCP callback comunication.  // QSampler::LscpEvent -- specialty for LSCP callback comunication.
   
154    
155  class LscpEvent : public QEvent  class LscpEvent : public QEvent
156  {  {
# Line 159  public: Line 165  public:
165          }          }
166    
167          // Accessors.          // Accessors.
168          lscp_event_t event() { return m_event; }          lscp_event_t  event() { return m_event; }
169          QString&     data()  { return m_data;  }          const QString& data() { return m_data;  }
170    
171  private:  private:
172    
# Line 172  private: Line 178  private:
178    
179    
180  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
181  // qsamplerMainForm -- Main window form implementation.  // QSampler::Workspace -- Main window workspace (MDI Area) decl.
182    
183    class Workspace : public QMdiArea
184    {
185    public:
186    
187            Workspace(MainForm *pMainForm) : QMdiArea(pMainForm) {}
188    
189    protected:
190    
191            void resizeEvent(QResizeEvent *)
192            {
193                    MainForm *pMainForm = static_cast<MainForm *> (parentWidget());
194                    if (pMainForm)
195                            pMainForm->channelsArrangeAuto();
196            }
197    };
198    
199    
200    //-------------------------------------------------------------------------
201    // QSampler::MainForm -- Main window form implementation.
202    
203  // Kind of singleton reference.  // Kind of singleton reference.
204  MainForm* MainForm::g_pMainForm = NULL;  MainForm *MainForm::g_pMainForm = NULL;
205    
206  MainForm::MainForm ( QWidget *pParent )  MainForm::MainForm ( QWidget *pParent )
207          : QMainWindow(pParent)          : QMainWindow(pParent)
# Line 195  MainForm::MainForm ( QWidget *pParent ) Line 221  MainForm::MainForm ( QWidget *pParent )
221    
222          // We'll start clean.          // We'll start clean.
223          m_iUntitled   = 0;          m_iUntitled   = 0;
224            m_iDirtySetup = 0;
225          m_iDirtyCount = 0;          m_iDirtyCount = 0;
226    
227          m_pServer = NULL;          m_pServer = NULL;
# Line 213  MainForm::MainForm ( QWidget *pParent ) Line 240  MainForm::MainForm ( QWidget *pParent )
240          // LADISH Level 1 suport.          // LADISH Level 1 suport.
241    
242          // Initialize file descriptors for SIGUSR1 socket notifier.          // Initialize file descriptors for SIGUSR1 socket notifier.
243          ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdUsr1);          ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigusr1);
244          m_pUsr1Notifier          m_pSigusr1Notifier
245                  = new QSocketNotifier(g_fdUsr1[1], QSocketNotifier::Read, this);                  = new QSocketNotifier(g_fdSigusr1[1], QSocketNotifier::Read, this);
246    
247          QObject::connect(m_pUsr1Notifier,          QObject::connect(m_pSigusr1Notifier,
248                  SIGNAL(activated(int)),                  SIGNAL(activated(int)),
249                  SLOT(handle_sigusr1()));                  SLOT(handle_sigusr1()));
250    
251          // Install SIGUSR1 signal handler.          // Install SIGUSR1 signal handler.
252      struct sigaction usr1;      struct sigaction sigusr1;
253      usr1.sa_handler = qsampler_sigusr1_handler;      sigusr1.sa_handler = qsampler_sigusr1_handler;
254      sigemptyset(&usr1.sa_mask);      sigemptyset(&sigusr1.sa_mask);
255      usr1.sa_flags = 0;      sigusr1.sa_flags = 0;
256      usr1.sa_flags |= SA_RESTART;      sigusr1.sa_flags |= SA_RESTART;
257      ::sigaction(SIGUSR1, &usr1, NULL);      ::sigaction(SIGUSR1, &sigusr1, NULL);
258    
259            // Initialize file descriptors for SIGTERM socket notifier.
260            ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigterm);
261            m_pSigtermNotifier
262                    = new QSocketNotifier(g_fdSigterm[1], QSocketNotifier::Read, this);
263    
264            QObject::connect(m_pSigtermNotifier,
265                    SIGNAL(activated(int)),
266                    SLOT(handle_sigterm()));
267    
268            // Install SIGTERM signal handler.
269            struct sigaction sigterm;
270            sigterm.sa_handler = qsampler_sigterm_handler;
271            ::sigemptyset(&sigterm.sa_mask);
272            sigterm.sa_flags = 0;
273            sigterm.sa_flags |= SA_RESTART;
274            ::sigaction(SIGTERM, &sigterm, NULL);
275            ::sigaction(SIGQUIT, &sigterm, NULL);
276    
277            // Ignore SIGHUP/SIGINT signals.
278            ::signal(SIGHUP, SIG_IGN);
279            ::signal(SIGINT, SIG_IGN);
280    
281  #else   // HAVE_SIGNAL_H  #else   // HAVE_SIGNAL_H
282    
283          m_pUsr1Notifier = NULL;          m_pSigusr1Notifier = NULL;
284            m_pSigtermNotifier = NULL;
285                    
286  #endif  // !HAVE_SIGNAL_H  #endif  // !HAVE_SIGNAL_H
287    
# Line 269  MainForm::MainForm ( QWidget *pParent ) Line 319  MainForm::MainForm ( QWidget *pParent )
319  #endif  #endif
320    
321          // Make it an MDI workspace.          // Make it an MDI workspace.
322          m_pWorkspace = new QMdiArea(this);          m_pWorkspace = new Workspace(this);
323          m_pWorkspace->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);          m_pWorkspace->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
324          m_pWorkspace->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);          m_pWorkspace->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
325          // Set the activation connection.          // Set the activation connection.
# Line 304  MainForm::MainForm ( QWidget *pParent ) Line 354  MainForm::MainForm ( QWidget *pParent )
354          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
355          statusBar()->addWidget(pLabel);          statusBar()->addWidget(pLabel);
356    
357  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
358          WSAStartup(MAKEWORD(1, 1), &_wsaData);          WSAStartup(MAKEWORD(1, 1), &_wsaData);
359  #endif  #endif
360    
# Line 405  MainForm::~MainForm() Line 455  MainForm::~MainForm()
455          // Do final processing anyway.          // Do final processing anyway.
456          processServerExit();          processServerExit();
457    
458  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
459          WSACleanup();          WSACleanup();
460  #endif  #endif
461    
462  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
463          if (m_pUsr1Notifier)          if (m_pSigusr1Notifier)
464                  delete m_pUsr1Notifier;                  delete m_pSigusr1Notifier;
465            if (m_pSigtermNotifier)
466                    delete m_pSigtermNotifier;
467  #endif  #endif
468    
469          // Finally drop any widgets around...          // Finally drop any widgets around...
# Line 478  void MainForm::setup ( Options *pOptions Line 530  void MainForm::setup ( Options *pOptions
530          updateMessagesFont();          updateMessagesFont();
531          updateMessagesLimit();          updateMessagesLimit();
532          updateMessagesCapture();          updateMessagesCapture();
533    
534          // Set the visibility signal.          // Set the visibility signal.
535          QObject::connect(m_pMessages,          QObject::connect(m_pMessages,
536                  SIGNAL(visibilityChanged(bool)),                  SIGNAL(visibilityChanged(bool)),
# Line 543  bool MainForm::queryClose (void) Line 596  bool MainForm::queryClose (void)
596                                  || m_ui.channelsToolbar->isVisible());                                  || m_ui.channelsToolbar->isVisible());
597                          m_pOptions->bStatusbar = statusBar()->isVisible();                          m_pOptions->bStatusbar = statusBar()->isVisible();
598                          // Save the dock windows state.                          // Save the dock windows state.
                         const QString sDockables = saveState().toBase64().data();  
599                          m_pOptions->settings().setValue("/Layout/DockWindows", saveState());                          m_pOptions->settings().setValue("/Layout/DockWindows", saveState());
600                          // And the children, and the main windows state,.                          // And the children, and the main windows state,.
601                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);
# Line 586  void MainForm::dragEnterEvent ( QDragEnt Line 638  void MainForm::dragEnterEvent ( QDragEnt
638  }  }
639    
640    
641  void MainForm::dropEvent ( QDropEvent* pDropEvent )  void MainForm::dropEvent ( QDropEvent *pDropEvent )
642  {  {
643          // Accept externally originated drops only...          // Accept externally originated drops only...
644          if (pDropEvent->source())          if (pDropEvent->source())
# Line 642  void MainForm::customEvent ( QEvent* pEv Line 694  void MainForm::customEvent ( QEvent* pEv
694                                  updateAllChannelStrips(true);                                  updateAllChannelStrips(true);
695                                  break;                                  break;
696                          case LSCP_EVENT_CHANNEL_INFO: {                          case LSCP_EVENT_CHANNEL_INFO: {
697                                  int iChannelID = pLscpEvent->data().toInt();                                  const int iChannelID = pLscpEvent->data().toInt();
698                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);
699                                  if (pChannelStrip)                                  if (pChannelStrip)
700                                          channelStripChanged(pChannelStrip);                                          channelStripChanged(pChannelStrip);
# Line 701  void MainForm::handle_sigusr1 (void) Line 753  void MainForm::handle_sigusr1 (void)
753    
754          char c;          char c;
755    
756          if (::read(g_fdUsr1[1], &c, sizeof(c)) > 0)          if (::read(g_fdSigusr1[1], &c, sizeof(c)) > 0)
757                  saveSession(false);                  saveSession(false);
758    
759  #endif  #endif
760  }  }
761    
762    
763    void MainForm::handle_sigterm (void)
764    {
765    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
766    
767            char c;
768    
769            if (::read(g_fdSigterm[1], &c, sizeof(c)) > 0)
770                    close();
771    
772    #endif
773    }
774    
775    
776  void MainForm::updateViewMidiDeviceStatusMenu (void)  void MainForm::updateViewMidiDeviceStatusMenu (void)
777  {  {
778          m_ui.viewMidiDeviceStatusMenu->clear();          m_ui.viewMidiDeviceStatusMenu->clear();
# Line 733  void MainForm::contextMenuEvent( QContex Line 798  void MainForm::contextMenuEvent( QContex
798    
799    
800  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
801  // qsamplerMainForm -- Brainless public property accessors.  // QSampler::MainForm -- Brainless public property accessors.
802    
803  // The global options settings property.  // The global options settings property.
804  Options *MainForm::options (void) const  Options *MainForm::options (void) const
# Line 757  MainForm *MainForm::getInstance (void) Line 822  MainForm *MainForm::getInstance (void)
822    
823    
824  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
825  // qsamplerMainForm -- Session file stuff.  // QSampler::MainForm -- Session file stuff.
826    
827  // Format the displayable session filename.  // Format the displayable session filename.
828  QString MainForm::sessionName ( const QString& sFilename )  QString MainForm::sessionName ( const QString& sFilename )
829  {  {
830          bool bCompletePath = (m_pOptions && m_pOptions->bCompletePath);          const bool bCompletePath = (m_pOptions && m_pOptions->bCompletePath);
831          QString sSessionName = sFilename;          QString sSessionName = sFilename;
832          if (sSessionName.isEmpty())          if (sSessionName.isEmpty())
833                  sSessionName = tr("Untitled") + QString::number(m_iUntitled);                  sSessionName = tr("Untitled") + QString::number(m_iUntitled);
# Line 846  bool MainForm::saveSession ( bool bPromp Line 911  bool MainForm::saveSession ( bool bPromp
911                  // Enforce .lscp extension...                  // Enforce .lscp extension...
912                  if (QFileInfo(sFilename).suffix().isEmpty())                  if (QFileInfo(sFilename).suffix().isEmpty())
913                          sFilename += ".lscp";                          sFilename += ".lscp";
914            #if 0
915                  // Check if already exists...                  // Check if already exists...
916                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
917                          if (QMessageBox::warning(this,                          if (QMessageBox::warning(this,
# Line 858  bool MainForm::saveSession ( bool bPromp Line 924  bool MainForm::saveSession ( bool bPromp
924                                  == QMessageBox::No)                                  == QMessageBox::No)
925                                  return false;                                  return false;
926                  }                  }
927            #endif
928          }          }
929    
930          // Save it right away.          // Save it right away.
# Line 896  bool MainForm::closeSession ( bool bForc Line 963  bool MainForm::closeSession ( bool bForc
963          if (bClose) {          if (bClose) {
964                  // Remove all channel strips from sight...                  // Remove all channel strips from sight...
965                  m_pWorkspace->setUpdatesEnabled(false);                  m_pWorkspace->setUpdatesEnabled(false);
966                  QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();                  const QList<QMdiSubWindow *>& wlist
967                  for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {                          = m_pWorkspace->subWindowList();
968                    const int iStripCount = wlist.count();
969                    for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
970                          ChannelStrip *pChannelStrip = NULL;                          ChannelStrip *pChannelStrip = NULL;
971                          QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
972                          if (pMdiSubWindow)                          if (pMdiSubWindow)
973                                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
974                          if (pChannelStrip) {                          if (pChannelStrip) {
# Line 1021  bool MainForm::saveSessionFile ( const Q Line 1090  bool MainForm::saveSessionFile ( const Q
1090          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1091    
1092          // Write the file.          // Write the file.
1093          int  iErrors = 0;          int iErrors = 0;
1094          QTextStream ts(&file);          QTextStream ts(&file);
1095          ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;          ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;
1096          ts << "# " << tr("Version")          ts << "# " << tr("Version") << ": " CONFIG_BUILD_VERSION << endl;
1097          << ": " QSAMPLER_VERSION << endl;  //      ts << "# " << tr("Build") << ": " CONFIG_BUILD_DATE << endl;
         ts << "# " << tr("Build")  
         << ": " __DATE__ " " __TIME__ << endl;  
1098          ts << "#"  << endl;          ts << "#"  << endl;
1099          ts << "# " << tr("File")          ts << "# " << tr("File")
1100          << ": " << QFileInfo(sFilename).fileName() << endl;          << ": " << QFileInfo(sFilename).fileName() << endl;
# Line 1040  bool MainForm::saveSessionFile ( const Q Line 1107  bool MainForm::saveSessionFile ( const Q
1107          // It is assumed that this new kind of device+session file          // It is assumed that this new kind of device+session file
1108          // will be loaded from a complete initialized server...          // will be loaded from a complete initialized server...
1109          int *piDeviceIDs;          int *piDeviceIDs;
1110          int  iDevice;          int  i, iDevice;
1111          ts << "RESET" << endl;          ts << "RESET" << endl;
1112    
1113          // Audio device mapping.          // Audio device mapping.
1114          QMap<int, int> audioDeviceMap;          QMap<int, int> audioDeviceMap; iDevice = 0;
1115          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);
1116          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1117                  ts << endl;                  Device device(Device::Audio, piDeviceIDs[i]);
1118                  Device device(Device::Audio, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1119                    if (device.driverName().toUpper() == "PLUGIN")
1120                            continue;
1121                  // Audio device specification...                  // Audio device specification...
1122                    ts << endl;
1123                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1124                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1125                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
# Line 1080  bool MainForm::saveSessionFile ( const Q Line 1150  bool MainForm::saveSessionFile ( const Q
1150                          iPort++;                          iPort++;
1151                  }                  }
1152                  // Audio device index/id mapping.                  // Audio device index/id mapping.
1153                  audioDeviceMap[device.deviceID()] = iDevice;                  audioDeviceMap.insert(device.deviceID(), iDevice++);
1154                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1155                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1156          }          }
1157    
1158          // MIDI device mapping.          // MIDI device mapping.
1159          QMap<int, int> midiDeviceMap;          QMap<int, int> midiDeviceMap; iDevice = 0;
1160          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);
1161          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1162                  ts << endl;                  Device device(Device::Midi, piDeviceIDs[i]);
1163                  Device device(Device::Midi, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1164                    if (device.driverName().toUpper() == "PLUGIN")
1165                            continue;
1166                  // MIDI device specification...                  // MIDI device specification...
1167                    ts << endl;
1168                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1169                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1170                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
# Line 1122  bool MainForm::saveSessionFile ( const Q Line 1195  bool MainForm::saveSessionFile ( const Q
1195                          iPort++;                          iPort++;
1196                  }                  }
1197                  // MIDI device index/id mapping.                  // MIDI device index/id mapping.
1198                  midiDeviceMap[device.deviceID()] = iDevice;                  midiDeviceMap.insert(device.deviceID(), iDevice++);
1199                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1200                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1201          }          }
# Line 1133  bool MainForm::saveSessionFile ( const Q Line 1206  bool MainForm::saveSessionFile ( const Q
1206          QMap<int, int> midiInstrumentMap;          QMap<int, int> midiInstrumentMap;
1207          int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);          int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);
1208          for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {          for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {
1209                  int iMidiMap = piMaps[iMap];                  const int iMidiMap = piMaps[iMap];
1210                  const char *pszMapName                  const char *pszMapName
1211                          = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);                          = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);
1212                  ts << "# " << tr("MIDI instrument map") << " " << iMap;                  ts << "# " << tr("MIDI instrument map") << " " << iMap;
# Line 1190  bool MainForm::saveSessionFile ( const Q Line 1263  bool MainForm::saveSessionFile ( const Q
1263                          iErrors++;                          iErrors++;
1264                  }                  }
1265                  // MIDI strument index/id mapping.                  // MIDI strument index/id mapping.
1266                  midiInstrumentMap[iMidiMap] = iMap;                  midiInstrumentMap.insert(iMidiMap, iMap);
1267          }          }
1268          // Check for errors...          // Check for errors...
1269          if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {          if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {
# Line 1199  bool MainForm::saveSessionFile ( const Q Line 1272  bool MainForm::saveSessionFile ( const Q
1272          }          }
1273  #endif  // CONFIG_MIDI_INSTRUMENT  #endif  // CONFIG_MIDI_INSTRUMENT
1274    
1275          // Sampler channel mapping.          // Sampler channel mapping...
1276          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          int iChannelID = 0;
1277          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          const QList<QMdiSubWindow *>& wlist
1278                    = m_pWorkspace->subWindowList();
1279            const int iStripCount = wlist.count();
1280            for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
1281                  ChannelStrip *pChannelStrip = NULL;                  ChannelStrip *pChannelStrip = NULL;
1282                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
1283                  if (pMdiSubWindow)                  if (pMdiSubWindow)
1284                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
1285                  if (pChannelStrip) {                  if (pChannelStrip) {
1286                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1287                          if (pChannel) {                          if (pChannel) {
1288                                  ts << "# " << tr("Channel") << " " << iChannel << endl;                                  // Avoid "artifial" plug-in devices...
1289                                    const int iAudioDevice = pChannel->audioDevice();
1290                                    if (!audioDeviceMap.contains(iAudioDevice))
1291                                            continue;
1292                                    const int iMidiDevice = pChannel->midiDevice();
1293                                    if (!midiDeviceMap.contains(iMidiDevice))
1294                                            continue;
1295                                    // Go for regular, canonical devices...
1296                                    ts << "# " << tr("Channel") << " " << iChannelID << endl;
1297                                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
1298                                  if (audioDeviceMap.isEmpty()) {                                  if (audioDeviceMap.isEmpty()) {
1299                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannelID
1300                                                  << " " << pChannel->audioDriver() << endl;                                                  << " " << pChannel->audioDriver() << endl;
1301                                  } else {                                  } else {
1302                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannelID
1303                                                  << " " << audioDeviceMap[pChannel->audioDevice()] << endl;                                                  << " " << audioDeviceMap.value(iAudioDevice) << endl;
1304                                  }                                  }
1305                                  if (midiDeviceMap.isEmpty()) {                                  if (midiDeviceMap.isEmpty()) {
1306                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannel                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID
1307                                                  << " " << pChannel->midiDriver() << endl;                                                  << " " << pChannel->midiDriver() << endl;
1308                                  } else {                                  } else {
1309                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannel                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannelID
1310                                                  << " " << midiDeviceMap[pChannel->midiDevice()] << endl;                                                  << " " << midiDeviceMap.value(iMidiDevice) << endl;
1311                                  }                                  }
1312                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID
1313                                          << " " << pChannel->midiPort() << endl;                                          << " " << pChannel->midiPort() << endl;
1314                                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";                                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannelID << " ";
1315                                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)                                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
1316                                          ts << "ALL";                                          ts << "ALL";
1317                                  else                                  else
1318                                          ts << pChannel->midiChannel();                                          ts << pChannel->midiChannel();
1319                                  ts << endl;                                  ts << endl;
1320                                  ts << "LOAD ENGINE " << pChannel->engineName()                                  ts << "LOAD ENGINE " << pChannel->engineName()
1321                                          << " " << iChannel << endl;                                          << " " << iChannelID << endl;
1322                                  if (pChannel->instrumentStatus() < 100) ts << "# ";                                  if (pChannel->instrumentStatus() < 100) ts << "# ";
1323                                  ts << "LOAD INSTRUMENT NON_MODAL '"                                  ts << "LOAD INSTRUMENT NON_MODAL '"
1324                                          << pChannel->instrumentFile() << "' "                                          << pChannel->instrumentFile() << "' "
1325                                          << pChannel->instrumentNr() << " " << iChannel << endl;                                          << pChannel->instrumentNr() << " " << iChannelID << endl;
1326                                  ChannelRoutingMap::ConstIterator audioRoute;                                  ChannelRoutingMap::ConstIterator audioRoute;
1327                                  for (audioRoute = pChannel->audioRouting().begin();                                  for (audioRoute = pChannel->audioRouting().begin();
1328                                                  audioRoute != pChannel->audioRouting().end();                                                  audioRoute != pChannel->audioRouting().end();
1329                                                          ++audioRoute) {                                                          ++audioRoute) {
1330                                          ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannelID
1331                                                  << " " << audioRoute.key()                                                  << " " << audioRoute.key()
1332                                                  << " " << audioRoute.value() << endl;                                                  << " " << audioRoute.value() << endl;
1333                                  }                                  }
1334                                  ts << "SET CHANNEL VOLUME " << iChannel                                  ts << "SET CHANNEL VOLUME " << iChannelID
1335                                          << " " << pChannel->volume() << endl;                                          << " " << pChannel->volume() << endl;
1336                                  if (pChannel->channelMute())                                  if (pChannel->channelMute())
1337                                          ts << "SET CHANNEL MUTE " << iChannel << " 1" << endl;                                          ts << "SET CHANNEL MUTE " << iChannelID << " 1" << endl;
1338                                  if (pChannel->channelSolo())                                  if (pChannel->channelSolo())
1339                                          ts << "SET CHANNEL SOLO " << iChannel << " 1" << endl;                                          ts << "SET CHANNEL SOLO " << iChannelID << " 1" << endl;
1340                          #ifdef CONFIG_MIDI_INSTRUMENT                          #ifdef CONFIG_MIDI_INSTRUMENT
1341                                  if (pChannel->midiMap() >= 0) {                                  const int iMidiMap = pChannel->midiMap();
1342                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannel                                  if (midiInstrumentMap.contains(iMidiMap)) {
1343                                                  << " " << midiInstrumentMap[pChannel->midiMap()] << endl;                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannelID
1344                                                    << " " << midiInstrumentMap.value(iMidiMap) << endl;
1345                                  }                                  }
1346                          #endif                          #endif
1347                          #ifdef CONFIG_FXSEND                          #ifdef CONFIG_FXSEND
                                 int iChannelID = pChannel->channelID();  
1348                                  int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID);                                  int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID);
1349                                  for (int iFxSend = 0;                                  for (int iFxSend = 0;
1350                                                  piFxSends && piFxSends[iFxSend] >= 0;                                                  piFxSends && piFxSends[iFxSend] >= 0;
# Line 1268  bool MainForm::saveSessionFile ( const Q Line 1352  bool MainForm::saveSessionFile ( const Q
1352                                          lscp_fxsend_info_t *pFxSendInfo = ::lscp_get_fxsend_info(                                          lscp_fxsend_info_t *pFxSendInfo = ::lscp_get_fxsend_info(
1353                                                  m_pClient, iChannelID, piFxSends[iFxSend]);                                                  m_pClient, iChannelID, piFxSends[iFxSend]);
1354                                          if (pFxSendInfo) {                                          if (pFxSendInfo) {
1355                                                  ts << "CREATE FX_SEND " << iChannel                                                  ts << "CREATE FX_SEND " << iChannelID
1356                                                          << " " << pFxSendInfo->midi_controller;                                                          << " " << pFxSendInfo->midi_controller;
1357                                                  if (pFxSendInfo->name)                                                  if (pFxSendInfo->name)
1358                                                          ts << " '" << pFxSendInfo->name << "'";                                                          ts << " '" << pFxSendInfo->name << "'";
# Line 1278  bool MainForm::saveSessionFile ( const Q Line 1362  bool MainForm::saveSessionFile ( const Q
1362                                                                  piRouting && piRouting[iAudioSrc] >= 0;                                                                  piRouting && piRouting[iAudioSrc] >= 0;
1363                                                                          iAudioSrc++) {                                                                          iAudioSrc++) {
1364                                                          ts << "SET FX_SEND AUDIO_OUTPUT_CHANNEL "                                                          ts << "SET FX_SEND AUDIO_OUTPUT_CHANNEL "
1365                                                                  << iChannel                                                                  << iChannelID
1366                                                                  << " " << iFxSend                                                                  << " " << iFxSend
1367                                                                  << " " << iAudioSrc                                                                  << " " << iAudioSrc
1368                                                                  << " " << piRouting[iAudioSrc] << endl;                                                                  << " " << piRouting[iAudioSrc] << endl;
1369                                                  }                                                  }
1370                                          #ifdef CONFIG_FXSEND_LEVEL                                          #ifdef CONFIG_FXSEND_LEVEL
1371                                                  ts << "SET FX_SEND LEVEL " << iChannel                                                  ts << "SET FX_SEND LEVEL " << iChannelID
1372                                                          << " " << iFxSend                                                          << " " << iFxSend
1373                                                          << " " << pFxSendInfo->level << endl;                                                          << " " << pFxSendInfo->level << endl;
1374                                          #endif                                          #endif
# Line 1296  bool MainForm::saveSessionFile ( const Q Line 1380  bool MainForm::saveSessionFile ( const Q
1380                                  }                                  }
1381                          #endif                          #endif
1382                                  ts << endl;                                  ts << endl;
1383                                    // Go for next channel...
1384                                    ++iChannelID;
1385                          }                          }
1386                  }                  }
1387                  // Try to keep it snappy :)                  // Try to keep it snappy :)
# Line 1347  void MainForm::sessionDirty (void) Line 1433  void MainForm::sessionDirty (void)
1433    
1434    
1435  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1436  // qsamplerMainForm -- File Action slots.  // QSampler::MainForm -- File Action slots.
1437    
1438  // Create a new sampler session.  // Create a new sampler session.
1439  void MainForm::fileNew (void)  void MainForm::fileNew (void)
# Line 1371  void MainForm::fileOpenRecent (void) Line 1457  void MainForm::fileOpenRecent (void)
1457          // Retrive filename index from action data...          // Retrive filename index from action data...
1458          QAction *pAction = qobject_cast<QAction *> (sender());          QAction *pAction = qobject_cast<QAction *> (sender());
1459          if (pAction && m_pOptions) {          if (pAction && m_pOptions) {
1460                  int iIndex = pAction->data().toInt();                  const int iIndex = pAction->data().toInt();
1461                  if (iIndex >= 0 && iIndex < m_pOptions->recentFiles.count()) {                  if (iIndex >= 0 && iIndex < m_pOptions->recentFiles.count()) {
1462                          QString sFilename = m_pOptions->recentFiles[iIndex];                          QString sFilename = m_pOptions->recentFiles[iIndex];
1463                          // Check if we can safely close the current session...                          // Check if we can safely close the current session...
# Line 1405  void MainForm::fileReset (void) Line 1491  void MainForm::fileReset (void)
1491                  return;                  return;
1492    
1493          // Ask user whether he/she want's an internal sampler reset...          // Ask user whether he/she want's an internal sampler reset...
1494          if (QMessageBox::warning(this,          if (m_pOptions && m_pOptions->bConfirmReset) {
1495                  QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");
1496                  tr("Resetting the sampler instance will close\n"                  const QString& sText = tr(
1497                  "all device and channel configurations.\n\n"                          "Resetting the sampler instance will close\n"
1498                  "Please note that this operation may cause\n"                          "all device and channel configurations.\n\n"
1499                  "temporary MIDI and Audio disruption.\n\n"                          "Please note that this operation may cause\n"
1500                  "Do you want to reset the sampler engine now?"),                          "temporary MIDI and Audio disruption.\n\n"
1501                  QMessageBox::Ok | QMessageBox::Cancel)                          "Do you want to reset the sampler engine now?");
1502                  == QMessageBox::Cancel)          #if 0
1503                  return;                  if (QMessageBox::warning(this, sTitle, sText,
1504                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1505                            return;
1506            #else
1507                    QMessageBox mbox(this);
1508                    mbox.setIcon(QMessageBox::Warning);
1509                    mbox.setWindowTitle(sTitle);
1510                    mbox.setText(sText);
1511                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1512                    QCheckBox cbox(tr("Don't ask this again"));
1513                    cbox.setChecked(false);
1514                    cbox.blockSignals(true);
1515                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1516                    if (mbox.exec() == QMessageBox::Cancel)
1517                            return;
1518                    if (cbox.isChecked())
1519                            m_pOptions->bConfirmReset = false;
1520            #endif
1521            }
1522    
1523          // Trye closing the current session, first...          // Trye closing the current session, first...
1524          if (!closeSession(true))          if (!closeSession(true))
# Line 1446  void MainForm::fileRestart (void) Line 1550  void MainForm::fileRestart (void)
1550    
1551          // Ask user whether he/she want's a complete restart...          // Ask user whether he/she want's a complete restart...
1552          // (if we're currently up and running)          // (if we're currently up and running)
1553          if (bRestart && m_pClient) {          if (m_pOptions && m_pOptions->bConfirmRestart) {
1554                  bRestart = (QMessageBox::warning(this,                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");
1555                          QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sText = tr(
1556                          tr("New settings will be effective after\n"                          "New settings will be effective after\n"
1557                          "restarting the client/server connection.\n\n"                          "restarting the client/server connection.\n\n"
1558                          "Please note that this operation may cause\n"                          "Please note that this operation may cause\n"
1559                          "temporary MIDI and Audio disruption.\n\n"                          "temporary MIDI and Audio disruption.\n\n"
1560                          "Do you want to restart the connection now?"),                          "Do you want to restart the connection now?");
1561                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok);          #if 0
1562                    if (QMessageBox::warning(this, sTitle, sText,
1563                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1564                            bRestart = false;
1565            #else
1566                    QMessageBox mbox(this);
1567                    mbox.setIcon(QMessageBox::Warning);
1568                    mbox.setWindowTitle(sTitle);
1569                    mbox.setText(sText);
1570                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1571                    QCheckBox cbox(tr("Don't ask this again"));
1572                    cbox.setChecked(false);
1573                    cbox.blockSignals(true);
1574                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1575                    if (mbox.exec() == QMessageBox::Cancel)
1576                            bRestart = false;
1577                    else
1578                    if (cbox.isChecked())
1579                            m_pOptions->bConfirmRestart = false;
1580            #endif
1581          }          }
1582    
1583          // Are we still for it?          // Are we still for it?
# Line 1476  void MainForm::fileExit (void) Line 1599  void MainForm::fileExit (void)
1599    
1600    
1601  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1602  // qsamplerMainForm -- Edit Action slots.  // QSampler::MainForm -- Edit Action slots.
1603    
1604  // Add a new sampler channel.  // Add a new sampler channel.
1605  void MainForm::editAddChannel (void)  void MainForm::editAddChannel (void)
1606  {  {
1607            ++m_iDirtySetup;
1608            addChannelStrip();
1609            --m_iDirtySetup;
1610    }
1611    
1612    void MainForm::addChannelStrip (void)
1613    {
1614          if (m_pClient == NULL)          if (m_pClient == NULL)
1615                  return;                  return;
1616    
# Line 1504  void MainForm::editAddChannel (void) Line 1634  void MainForm::editAddChannel (void)
1634          }          }
1635    
1636          // Do we auto-arrange?          // Do we auto-arrange?
1637          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
1638    
1639          // Make that an overall update.          // Make that an overall update.
1640          m_iDirtyCount++;          m_iDirtyCount++;
# Line 1516  void MainForm::editAddChannel (void) Line 1645  void MainForm::editAddChannel (void)
1645  // Remove current sampler channel.  // Remove current sampler channel.
1646  void MainForm::editRemoveChannel (void)  void MainForm::editRemoveChannel (void)
1647  {  {
1648            ++m_iDirtySetup;
1649            removeChannelStrip();
1650            --m_iDirtySetup;
1651    }
1652    
1653    void MainForm::removeChannelStrip (void)
1654    {
1655          if (m_pClient == NULL)          if (m_pClient == NULL)
1656                  return;                  return;
1657    
# Line 1529  void MainForm::editRemoveChannel (void) Line 1665  void MainForm::editRemoveChannel (void)
1665    
1666          // Prompt user if he/she's sure about this...          // Prompt user if he/she's sure about this...
1667          if (m_pOptions && m_pOptions->bConfirmRemove) {          if (m_pOptions && m_pOptions->bConfirmRemove) {
1668                  if (QMessageBox::warning(this,                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");
1669                          QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sText = tr(
1670                          tr("About to remove channel:\n\n"                          "About to remove channel:\n\n"
1671                          "%1\n\n"                          "%1\n\n"
1672                          "Are you sure?")                          "Are you sure?")
1673                          .arg(pChannelStrip->windowTitle()),                          .arg(pChannelStrip->windowTitle());
1674                          QMessageBox::Ok | QMessageBox::Cancel)          #if 0
1675                          == QMessageBox::Cancel)                  if (QMessageBox::warning(this, sTitle, sText,
1676                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1677                            return;
1678            #else
1679                    QMessageBox mbox(this);
1680                    mbox.setIcon(QMessageBox::Warning);
1681                    mbox.setWindowTitle(sTitle);
1682                    mbox.setText(sText);
1683                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1684                    QCheckBox cbox(tr("Don't ask this again"));
1685                    cbox.setChecked(false);
1686                    cbox.blockSignals(true);
1687                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1688                    if (mbox.exec() == QMessageBox::Cancel)
1689                          return;                          return;
1690                    if (cbox.isChecked())
1691                            m_pOptions->bConfirmRemove = false;
1692            #endif
1693          }          }
1694    
1695          // Remove the existing sampler channel.          // Remove the existing sampler channel.
1696          if (!pChannel->removeChannel())          if (!pChannel->removeChannel())
1697                  return;                  return;
1698    
         // We'll be dirty, for sure...  
         m_iDirtyCount++;  
   
1699          // Just delete the channel strip.          // Just delete the channel strip.
1700          destroyChannelStrip(pChannelStrip);          destroyChannelStrip(pChannelStrip);
1701    
1702            // We'll be dirty, for sure...
1703            m_iDirtyCount++;
1704            stabilizeForm();
1705  }  }
1706    
1707    
# Line 1606  void MainForm::editResetAllChannels (voi Line 1759  void MainForm::editResetAllChannels (voi
1759          // Invoque the channel strip procedure,          // Invoque the channel strip procedure,
1760          // for all channels out there...          // for all channels out there...
1761          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1762          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
1763          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {                  = m_pWorkspace->subWindowList();
1764            const int iStripCount = wlist.count();
1765            for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
1766                  ChannelStrip *pChannelStrip = NULL;                  ChannelStrip *pChannelStrip = NULL;
1767                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
1768                  if (pMdiSubWindow)                  if (pMdiSubWindow)
1769                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
1770                  if (pChannelStrip)                  if (pChannelStrip)
# Line 1620  void MainForm::editResetAllChannels (voi Line 1775  void MainForm::editResetAllChannels (voi
1775    
1776    
1777  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1778  // qsamplerMainForm -- View Action slots.  // QSampler::MainForm -- View Action slots.
1779    
1780  // Show/hide the main program window menubar.  // Show/hide the main program window menubar.
1781  void MainForm::viewMenubar ( bool bOn )  void MainForm::viewMenubar ( bool bOn )
# Line 1720  void MainForm::viewOptions (void) Line 1875  void MainForm::viewOptions (void)
1875                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)
1876                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();
1877                  // To track down deferred or immediate changes.                  // To track down deferred or immediate changes.
1878                  QString sOldServerHost      = m_pOptions->sServerHost;                  const QString sOldServerHost      = m_pOptions->sServerHost;
1879                  int     iOldServerPort      = m_pOptions->iServerPort;                  const int     iOldServerPort      = m_pOptions->iServerPort;
1880                  int     iOldServerTimeout   = m_pOptions->iServerTimeout;                  const int     iOldServerTimeout   = m_pOptions->iServerTimeout;
1881                  bool    bOldServerStart     = m_pOptions->bServerStart;                  const bool    bOldServerStart     = m_pOptions->bServerStart;
1882                  QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;                  const QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;
1883                  bool    bOldMessagesLog     = m_pOptions->bMessagesLog;                  const bool    bOldMessagesLog     = m_pOptions->bMessagesLog;
1884                  QString sOldMessagesLogPath = m_pOptions->sMessagesLogPath;                  const QString sOldMessagesLogPath = m_pOptions->sMessagesLogPath;
1885                  QString sOldDisplayFont     = m_pOptions->sDisplayFont;                  const QString sOldDisplayFont     = m_pOptions->sDisplayFont;
1886                  bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;                  const bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1887                  int     iOldMaxVolume       = m_pOptions->iMaxVolume;                  const int     iOldMaxVolume       = m_pOptions->iMaxVolume;
1888                  QString sOldMessagesFont    = m_pOptions->sMessagesFont;                  const QString sOldMessagesFont    = m_pOptions->sMessagesFont;
1889                  bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;                  const bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;
1890                  bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;                  const bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;
1891                  int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;                  const int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;
1892                  int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;                  const int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1893                  bool    bOldCompletePath    = m_pOptions->bCompletePath;                  const bool    bOldCompletePath    = m_pOptions->bCompletePath;
1894                  bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;                  const bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1895                  int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;                  const int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1896                  int     iOldBaseFontSize    = m_pOptions->iBaseFontSize;                  const int     iOldBaseFontSize    = m_pOptions->iBaseFontSize;
1897                  // Load the current setup settings.                  // Load the current setup settings.
1898                  pOptionsForm->setup(m_pOptions);                  pOptionsForm->setup(m_pOptions);
1899                  // Show the setup dialog...                  // Show the setup dialog...
# Line 1801  void MainForm::viewOptions (void) Line 1956  void MainForm::viewOptions (void)
1956    
1957    
1958  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1959  // qsamplerMainForm -- Channels action slots.  // QSampler::MainForm -- Channels action slots.
1960    
1961  // Arrange channel strips.  // Arrange channel strips.
1962  void MainForm::channelsArrange (void)  void MainForm::channelsArrange (void)
1963  {  {
1964          // Full width vertical tiling          // Full width vertical tiling
1965          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
1966                    = m_pWorkspace->subWindowList();
1967          if (wlist.isEmpty())          if (wlist.isEmpty())
1968                  return;                  return;
1969    
1970          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1971          int y = 0;          int y = 0;
1972          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          const int iStripCount = wlist.count();
1973                  ChannelStrip *pChannelStrip = NULL;          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
1974                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
1975                  if (pMdiSubWindow)                  if (pMdiSubWindow) {
1976                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                          pMdiSubWindow->adjustSize();
1977                  if (pChannelStrip) {                          int iWidth = m_pWorkspace->width();
1978                  /*  if (pChannelStrip->testWState(WState_Maximized | WState_Minimized)) {                          if (iWidth < pMdiSubWindow->width())
1979                                  // Prevent flicker...                                  iWidth = pMdiSubWindow->width();
1980                                  pChannelStrip->hide();                          const int iHeight = pMdiSubWindow->frameGeometry().height();
1981                                  pChannelStrip->showNormal();                          pMdiSubWindow->setGeometry(0, y, iWidth, iHeight);
                         }   */  
                         pChannelStrip->adjustSize();  
                         int iWidth  = m_pWorkspace->width();  
                         if (iWidth < pChannelStrip->width())  
                                 iWidth = pChannelStrip->width();  
                 //  int iHeight = pChannelStrip->height()  
                 //              + pChannelStrip->parentWidget()->baseSize().height();  
                         int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();  
                         pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);  
1982                          y += iHeight;                          y += iHeight;
1983                  }                  }
1984          }          }
# Line 1851  void MainForm::channelsAutoArrange ( boo Line 1998  void MainForm::channelsAutoArrange ( boo
1998          m_pOptions->bAutoArrange = bOn;          m_pOptions->bAutoArrange = bOn;
1999    
2000          // If on, update whole workspace...          // If on, update whole workspace...
2001          if (m_pOptions->bAutoArrange)          channelsArrangeAuto();
2002    }
2003    
2004    
2005    void MainForm::channelsArrangeAuto (void)
2006    {
2007            if (m_pOptions && m_pOptions->bAutoArrange)
2008                  channelsArrange();                  channelsArrange();
2009  }  }
2010    
2011    
2012  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2013  // qsamplerMainForm -- Help Action slots.  // QSampler::MainForm -- Help Action slots.
2014    
2015  // Show information about the Qt toolkit.  // Show information about the Qt toolkit.
2016  void MainForm::helpAboutQt (void)  void MainForm::helpAboutQt (void)
# Line 1869  void MainForm::helpAboutQt (void) Line 2022  void MainForm::helpAboutQt (void)
2022  // Show information about application program.  // Show information about application program.
2023  void MainForm::helpAbout (void)  void MainForm::helpAbout (void)
2024  {  {
2025          // 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";  
2026  #ifdef CONFIG_DEBUG  #ifdef CONFIG_DEBUG
2027          sText += "<small><font color=\"red\">";          list << tr("Debugging option enabled.");
         sText += tr("Debugging option enabled.");  
         sText += "</font></small><br />";  
2028  #endif  #endif
2029  #ifndef CONFIG_LIBGIG  #ifndef CONFIG_LIBGIG
2030          sText += "<small><font color=\"red\">";          list << tr("GIG (libgig) file support disabled.");
         sText += tr("GIG (libgig) file support disabled.");  
         sText += "</font></small><br />";  
2031  #endif  #endif
2032  #ifndef CONFIG_INSTRUMENT_NAME  #ifndef CONFIG_INSTRUMENT_NAME
2033          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 />";  
2034  #endif  #endif
2035  #ifndef CONFIG_MUTE_SOLO  #ifndef CONFIG_MUTE_SOLO
2036          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 />";  
2037  #endif  #endif
2038  #ifndef CONFIG_AUDIO_ROUTING  #ifndef CONFIG_AUDIO_ROUTING
2039          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 />";  
2040  #endif  #endif
2041  #ifndef CONFIG_FXSEND  #ifndef CONFIG_FXSEND
2042          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 />";  
2043  #endif  #endif
2044  #ifndef CONFIG_VOLUME  #ifndef CONFIG_VOLUME
2045          sText += "<small><font color=\"red\">";          list << tr("Global volume support disabled.");
         sText += tr("Global volume support disabled.");  
         sText += "</font></small><br />";  
2046  #endif  #endif
2047  #ifndef CONFIG_MIDI_INSTRUMENT  #ifndef CONFIG_MIDI_INSTRUMENT
2048          sText += "<small><font color=\"red\">";          list << tr("MIDI instrument mapping support disabled.");
         sText += tr("MIDI instrument mapping support disabled.");  
         sText += "</font></small><br />";  
2049  #endif  #endif
2050  #ifndef CONFIG_EDIT_INSTRUMENT  #ifndef CONFIG_EDIT_INSTRUMENT
2051          sText += "<small><font color=\"red\">";          list << tr("Instrument editing support disabled.");
         sText += tr("Instrument editing support disabled.");  
         sText += "</font></small><br />";  
2052  #endif  #endif
2053  #ifndef CONFIG_EVENT_CHANNEL_MIDI  #ifndef CONFIG_EVENT_CHANNEL_MIDI
2054          sText += "<small><font color=\"red\">";          list << tr("Channel MIDI event support disabled.");
         sText += tr("Channel MIDI event support disabled.");  
         sText += "</font></small><br />";  
2055  #endif  #endif
2056  #ifndef CONFIG_EVENT_DEVICE_MIDI  #ifndef CONFIG_EVENT_DEVICE_MIDI
2057          sText += "<small><font color=\"red\">";          list << tr("Device MIDI event support disabled.");
         sText += tr("Device MIDI event support disabled.");  
         sText += "</font></small><br />";  
2058  #endif  #endif
2059  #ifndef CONFIG_MAX_VOICES  #ifndef CONFIG_MAX_VOICES
2060          sText += "<small><font color=\"red\">";          list << tr("Runtime max. voices / disk streams support disabled.");
         sText += tr("Runtime max. voices / disk streams support disabled.");  
         sText += "</font></small><br />";  
2061  #endif  #endif
2062    
2063            // Stuff the about box text...
2064            QString sText = "<p>\n";
2065            sText += "<b>" QSAMPLER_TITLE " - " + tr(QSAMPLER_SUBTITLE) + "</b><br />\n";
2066            sText += "<br />\n";
2067            sText += tr("Version") + ": <b>" CONFIG_BUILD_VERSION "</b><br />\n";
2068    //      sText += "<small>" + tr("Build") + ": " CONFIG_BUILD_DATE "</small><br />\n";
2069            if (!list.isEmpty()) {
2070                    sText += "<small><font color=\"red\">";
2071                    sText += list.join("<br />\n");
2072                    sText += "</font></small>";
2073            }
2074          sText += "<br />\n";          sText += "<br />\n";
2075          sText += tr("Using") + ": ";          sText += tr("Using") + ": ";
2076          sText += ::lscp_client_package();          sText += ::lscp_client_package();
# Line 1964  void MainForm::helpAbout (void) Line 2100  void MainForm::helpAbout (void)
2100    
2101    
2102  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2103  // qsamplerMainForm -- Main window stabilization.  // QSampler::MainForm -- Main window stabilization.
2104    
2105  void MainForm::stabilizeForm (void)  void MainForm::stabilizeForm (void)
2106  {  {
# Line 1976  void MainForm::stabilizeForm (void) Line 2112  void MainForm::stabilizeForm (void)
2112    
2113          // Update the main menu state...          // Update the main menu state...
2114          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
2115          bool bHasClient = (m_pOptions != NULL && m_pClient != NULL);          const QList<QMdiSubWindow *>& wlist = m_pWorkspace->subWindowList();
2116          bool bHasChannel = (bHasClient && pChannelStrip != NULL);          const bool bHasClient = (m_pOptions != NULL && m_pClient != NULL);
2117          bool bHasChannels = (bHasClient && m_pWorkspace->subWindowList().count() > 0);          const bool bHasChannel = (bHasClient && pChannelStrip != NULL);
2118            const bool bHasChannels = (bHasClient && wlist.count() > 0);
2119          m_ui.fileNewAction->setEnabled(bHasClient);          m_ui.fileNewAction->setEnabled(bHasClient);
2120          m_ui.fileOpenAction->setEnabled(bHasClient);          m_ui.fileOpenAction->setEnabled(bHasClient);
2121          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
# Line 2058  void MainForm::volumeChanged ( int iVolu Line 2195  void MainForm::volumeChanged ( int iVolu
2195                  m_pVolumeSpinBox->setValue(iVolume);                  m_pVolumeSpinBox->setValue(iVolume);
2196    
2197          // Do it as commanded...          // Do it as commanded...
2198          float fVolume = 0.01f * float(iVolume);          const float fVolume = 0.01f * float(iVolume);
2199          if (::lscp_set_volume(m_pClient, fVolume) == LSCP_OK)          if (::lscp_set_volume(m_pClient, fVolume) == LSCP_OK)
2200                  appendMessages(QObject::tr("Volume: %1.").arg(fVolume));                  appendMessages(QObject::tr("Volume: %1.").arg(fVolume));
2201          else          else
# Line 2093  void MainForm::channelStripChanged ( Cha Line 2230  void MainForm::channelStripChanged ( Cha
2230  void MainForm::updateSession (void)  void MainForm::updateSession (void)
2231  {  {
2232  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
2233          int iVolume = ::lroundf(100.0f * ::lscp_get_volume(m_pClient));          const int iVolume = ::lroundf(100.0f * ::lscp_get_volume(m_pClient));
2234          m_iVolumeChanging++;          m_iVolumeChanging++;
2235          m_pVolumeSlider->setValue(iVolume);          m_pVolumeSlider->setValue(iVolume);
2236          m_pVolumeSpinBox->setValue(iVolume);          m_pVolumeSpinBox->setValue(iVolume);
# Line 2101  void MainForm::updateSession (void) Line 2238  void MainForm::updateSession (void)
2238  #endif  #endif
2239  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
2240          // FIXME: Make some room for default instrument maps...          // FIXME: Make some room for default instrument maps...
2241          int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);          const int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);
2242          if (iMaps < 0)          if (iMaps < 0)
2243                  appendMessagesClient("lscp_get_midi_instrument_maps");                  appendMessagesClient("lscp_get_midi_instrument_maps");
2244          else if (iMaps < 1) {          else if (iMaps < 1) {
# Line 2115  void MainForm::updateSession (void) Line 2252  void MainForm::updateSession (void)
2252          updateAllChannelStrips(false);          updateAllChannelStrips(false);
2253    
2254          // Do we auto-arrange?          // Do we auto-arrange?
2255          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
2256    
2257          // Remember to refresh devices and instruments...          // Remember to refresh devices and instruments...
2258          if (m_pInstrumentListForm)          if (m_pInstrumentListForm)
# Line 2128  void MainForm::updateSession (void) Line 2264  void MainForm::updateSession (void)
2264    
2265  void MainForm::updateAllChannelStrips ( bool bRemoveDeadStrips )  void MainForm::updateAllChannelStrips ( bool bRemoveDeadStrips )
2266  {  {
2267            // Skip if setting up a new channel strip...
2268            if (m_iDirtySetup > 0)
2269                    return;
2270    
2271          // Retrieve the current channel list.          // Retrieve the current channel list.
2272          int *piChannelIDs = ::lscp_list_channels(m_pClient);          int *piChannelIDs = ::lscp_list_channels(m_pClient);
2273          if (piChannelIDs == NULL) {          if (piChannelIDs == NULL) {
# Line 2145  void MainForm::updateAllChannelStrips ( Line 2285  void MainForm::updateAllChannelStrips (
2285                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));
2286                  }                  }
2287                  // Do we auto-arrange?                  // Do we auto-arrange?
2288                  if (m_pOptions && m_pOptions->bAutoArrange)                  channelsArrangeAuto();
                         channelsArrange();  
2289                  // remove dead channel strips                  // remove dead channel strips
2290                  if (bRemoveDeadStrips) {                  if (bRemoveDeadStrips) {
2291                          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();                          const QList<QMdiSubWindow *>& wlist
2292                          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {                                  = m_pWorkspace->subWindowList();
2293                            const int iStripCount = wlist.count();
2294                            for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2295                                  ChannelStrip *pChannelStrip = NULL;                                  ChannelStrip *pChannelStrip = NULL;
2296                                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2297                                  if (pMdiSubWindow)                                  if (pMdiSubWindow)
2298                                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2299                                  if (pChannelStrip) {                                  if (pChannelStrip) {
2300                                          bool bExists = false;                                          bool bExists = false;
2301                                          for (int j = 0; piChannelIDs[j] >= 0; ++j) {                                          for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {
2302                                                  if (!pChannelStrip->channel())                                                  Channel *pChannel = pChannelStrip->channel();
2303                                                    if (pChannel == NULL)
2304                                                          break;                                                          break;
2305                                                  if (piChannelIDs[j] == pChannelStrip->channel()->channelID()) {                                                  if (piChannelIDs[iChannel] == pChannel->channelID()) {
2306                                                          // strip exists, don't touch it                                                          // strip exists, don't touch it
2307                                                          bExists = true;                                                          bExists = true;
2308                                                          break;                                                          break;
# Line 2185  void MainForm::updateRecentFiles ( const Line 2327  void MainForm::updateRecentFiles ( const
2327                  return;                  return;
2328    
2329          // Remove from list if already there (avoid duplicates)          // Remove from list if already there (avoid duplicates)
2330          int iIndex = m_pOptions->recentFiles.indexOf(sFilename);          const int iIndex = m_pOptions->recentFiles.indexOf(sFilename);
2331          if (iIndex >= 0)          if (iIndex >= 0)
2332                  m_pOptions->recentFiles.removeAt(iIndex);                  m_pOptions->recentFiles.removeAt(iIndex);
2333          // Put it to front...          // Put it to front...
# Line 2224  void MainForm::updateRecentFilesMenu (vo Line 2366  void MainForm::updateRecentFilesMenu (vo
2366  void MainForm::updateInstrumentNames (void)  void MainForm::updateInstrumentNames (void)
2367  {  {
2368          // Full channel list update...          // Full channel list update...
2369          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2370                    = m_pWorkspace->subWindowList();
2371          if (wlist.isEmpty())          if (wlist.isEmpty())
2372                  return;                  return;
2373    
2374          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2375          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          const int iStripCount = wlist.count();
2376                  ChannelStrip *pChannelStrip = (ChannelStrip *) wlist.at(iChannel);          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2377                    ChannelStrip *pChannelStrip = NULL;
2378                    QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2379                    if (pMdiSubWindow)
2380                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2381                  if (pChannelStrip)                  if (pChannelStrip)
2382                          pChannelStrip->updateInstrumentName(true);                          pChannelStrip->updateInstrumentName(true);
2383          }          }
# Line 2247  void MainForm::updateDisplayFont (void) Line 2394  void MainForm::updateDisplayFont (void)
2394          // Check if display font is legal.          // Check if display font is legal.
2395          if (m_pOptions->sDisplayFont.isEmpty())          if (m_pOptions->sDisplayFont.isEmpty())
2396                  return;                  return;
2397    
2398          // Realize it.          // Realize it.
2399          QFont font;          QFont font;
2400          if (!font.fromString(m_pOptions->sDisplayFont))          if (!font.fromString(m_pOptions->sDisplayFont))
2401                  return;                  return;
2402    
2403          // Full channel list update...          // Full channel list update...
2404          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2405                    = m_pWorkspace->subWindowList();
2406          if (wlist.isEmpty())          if (wlist.isEmpty())
2407                  return;                  return;
2408    
2409          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2410          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          const int iStripCount = wlist.count();
2411            for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2412                  ChannelStrip *pChannelStrip = NULL;                  ChannelStrip *pChannelStrip = NULL;
2413                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2414                  if (pMdiSubWindow)                  if (pMdiSubWindow)
2415                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2416                  if (pChannelStrip)                  if (pChannelStrip)
# Line 2274  void MainForm::updateDisplayFont (void) Line 2424  void MainForm::updateDisplayFont (void)
2424  void MainForm::updateDisplayEffect (void)  void MainForm::updateDisplayEffect (void)
2425  {  {
2426          // Full channel list update...          // Full channel list update...
2427          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2428                    = m_pWorkspace->subWindowList();
2429          if (wlist.isEmpty())          if (wlist.isEmpty())
2430                  return;                  return;
2431    
2432          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2433          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          const int iStripCount = wlist.count();
2434            for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2435                  ChannelStrip *pChannelStrip = NULL;                  ChannelStrip *pChannelStrip = NULL;
2436                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2437                  if (pMdiSubWindow)                  if (pMdiSubWindow)
2438                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2439                  if (pChannelStrip)                  if (pChannelStrip)
# Line 2305  void MainForm::updateMaxVolume (void) Line 2457  void MainForm::updateMaxVolume (void)
2457  #endif  #endif
2458    
2459          // Full channel list update...          // Full channel list update...
2460          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2461                    = m_pWorkspace->subWindowList();
2462          if (wlist.isEmpty())          if (wlist.isEmpty())
2463                  return;                  return;
2464    
2465          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2466          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          const int iStripCount = wlist.count();
2467            for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2468                  ChannelStrip *pChannelStrip = NULL;                  ChannelStrip *pChannelStrip = NULL;
2469                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2470                  if (pMdiSubWindow)                  if (pMdiSubWindow)
2471                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2472                  if (pChannelStrip)                  if (pChannelStrip)
# Line 2323  void MainForm::updateMaxVolume (void) Line 2477  void MainForm::updateMaxVolume (void)
2477    
2478    
2479  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2480  // qsamplerMainForm -- Messages window form handlers.  // QSampler::MainForm -- Messages window form handlers.
2481    
2482  // Messages output methods.  // Messages output methods.
2483  void MainForm::appendMessages( const QString& s )  void MainForm::appendMessages( const QString& s )
# Line 2348  void MainForm::appendMessagesText( const Line 2502  void MainForm::appendMessagesText( const
2502                  m_pMessages->appendMessagesText(s);                  m_pMessages->appendMessagesText(s);
2503  }  }
2504    
2505  void MainForm::appendMessagesError( const QString& s )  void MainForm::appendMessagesError( const QString& sText )
2506  {  {
2507          if (m_pMessages)          if (m_pMessages)
2508                  m_pMessages->show();                  m_pMessages->show();
2509    
2510          appendMessagesColor(s.simplified(), "#ff0000");          appendMessagesColor(sText.simplified(), "#ff0000");
2511    
2512          // Make it look responsive...:)          // Make it look responsive...:)
2513          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2514    
2515          QMessageBox::critical(this,          if (m_pOptions && m_pOptions->bConfirmError) {
2516                  QSAMPLER_TITLE ": " + tr("Error"), s, QMessageBox::Cancel);                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Error");
2517            #if 0
2518                    QMessageBox::critical(this, sTitle, sText, QMessageBox::Cancel);
2519            #else
2520                    QMessageBox mbox(this);
2521                    mbox.setIcon(QMessageBox::Critical);
2522                    mbox.setWindowTitle(sTitle);
2523                    mbox.setText(sText);
2524                    mbox.setStandardButtons(QMessageBox::Cancel);
2525                    QCheckBox cbox(tr("Don't show this again"));
2526                    cbox.setChecked(false);
2527                    cbox.blockSignals(true);
2528                    mbox.addButton(&cbox, QMessageBox::ActionRole);
2529                    if (mbox.exec() && cbox.isChecked())
2530                            m_pOptions->bConfirmError = false;
2531            #endif
2532            }
2533  }  }
2534    
2535    
# Line 2419  void MainForm::updateMessagesCapture (vo Line 2589  void MainForm::updateMessagesCapture (vo
2589    
2590    
2591  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2592  // qsamplerMainForm -- MDI channel strip management.  // QSampler::MainForm -- MDI channel strip management.
2593    
2594  // The channel strip creation executive.  // The channel strip creation executive.
2595  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )
# Line 2438  ChannelStrip *MainForm::createChannelStr Line 2608  ChannelStrip *MainForm::createChannelStr
2608                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2609                  // We'll need a display font.                  // We'll need a display font.
2610                  QFont font;                  QFont font;
2611                  if (font.fromString(m_pOptions->sDisplayFont))                  if (!m_pOptions->sDisplayFont.isEmpty() &&
2612                            font.fromString(m_pOptions->sDisplayFont))
2613                          pChannelStrip->setDisplayFont(font);                          pChannelStrip->setDisplayFont(font);
2614                  // Maximum allowed volume setting.                  // Maximum allowed volume setting.
2615                  pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                  pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
# Line 2478  void MainForm::destroyChannelStrip ( Cha Line 2649  void MainForm::destroyChannelStrip ( Cha
2649          delete pMdiSubWindow;          delete pMdiSubWindow;
2650    
2651          // Do we auto-arrange?          // Do we auto-arrange?
2652          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
   
         stabilizeForm();  
2653  }  }
2654    
2655    
# Line 2497  ChannelStrip *MainForm::activeChannelStr Line 2665  ChannelStrip *MainForm::activeChannelStr
2665    
2666    
2667  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2668  ChannelStrip *MainForm::channelStripAt ( int iChannel )  ChannelStrip *MainForm::channelStripAt ( int iStrip )
2669  {  {
2670          if (!m_pWorkspace) return NULL;          if (!m_pWorkspace) return NULL;
2671    
2672          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2673                    = m_pWorkspace->subWindowList();
2674          if (wlist.isEmpty())          if (wlist.isEmpty())
2675                  return NULL;                  return NULL;
2676    
2677          if (iChannel < 0 || iChannel >= wlist.size())          if (iStrip < 0 || iStrip >= wlist.count())
2678                  return NULL;                  return NULL;
2679    
2680          QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2681          if (pMdiSubWindow)          if (pMdiSubWindow)
2682                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2683          else          else
# Line 2519  ChannelStrip *MainForm::channelStripAt ( Line 2688  ChannelStrip *MainForm::channelStripAt (
2688  // Retrieve a channel strip by sampler channel id.  // Retrieve a channel strip by sampler channel id.
2689  ChannelStrip *MainForm::channelStrip ( int iChannelID )  ChannelStrip *MainForm::channelStrip ( int iChannelID )
2690  {  {
2691          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2692                    = m_pWorkspace->subWindowList();
2693          if (wlist.isEmpty())          if (wlist.isEmpty())
2694                  return NULL;                  return NULL;
2695    
2696          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          const int iStripCount = wlist.count();
2697            for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2698                  ChannelStrip *pChannelStrip = NULL;                  ChannelStrip *pChannelStrip = NULL;
2699                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2700                  if (pMdiSubWindow)                  if (pMdiSubWindow)
2701                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2702                  if (pChannelStrip) {                  if (pChannelStrip) {
# Line 2547  void MainForm::channelsMenuAboutToShow ( Line 2718  void MainForm::channelsMenuAboutToShow (
2718          m_ui.channelsMenu->addAction(m_ui.channelsArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsArrangeAction);
2719          m_ui.channelsMenu->addAction(m_ui.channelsAutoArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsAutoArrangeAction);
2720    
2721          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2722                    = m_pWorkspace->subWindowList();
2723          if (!wlist.isEmpty()) {          if (!wlist.isEmpty()) {
2724                  m_ui.channelsMenu->addSeparator();                  m_ui.channelsMenu->addSeparator();
2725                  for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {                  const int iStripCount = wlist.count();
2726                    for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2727                          ChannelStrip *pChannelStrip = NULL;                          ChannelStrip *pChannelStrip = NULL;
2728                          QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2729                          if (pMdiSubWindow)                          if (pMdiSubWindow)
2730                                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2731                          if (pChannelStrip) {                          if (pChannelStrip) {
# Line 2561  void MainForm::channelsMenuAboutToShow ( Line 2734  void MainForm::channelsMenuAboutToShow (
2734                                          this, SLOT(channelsMenuActivated()));                                          this, SLOT(channelsMenuActivated()));
2735                                  pAction->setCheckable(true);                                  pAction->setCheckable(true);
2736                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);
2737                                  pAction->setData(iChannel);                                  pAction->setData(iStrip);
2738                          }                          }
2739                  }                  }
2740          }          }
# Line 2585  void MainForm::channelsMenuActivated (vo Line 2758  void MainForm::channelsMenuActivated (vo
2758    
2759    
2760  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2761  // qsamplerMainForm -- Timer stuff.  // QSampler::MainForm -- Timer stuff.
2762    
2763  // Set the pseudo-timer delay schedule.  // Set the pseudo-timer delay schedule.
2764  void MainForm::startSchedule ( int iStartDelay )  void MainForm::startSchedule ( int iStartDelay )
# Line 2626  void MainForm::timerSlot (void) Line 2799  void MainForm::timerSlot (void)
2799                          ChannelStrip *pChannelStrip = iter.next();                          ChannelStrip *pChannelStrip = iter.next();
2800                          // If successfull, remove from pending list...                          // If successfull, remove from pending list...
2801                          if (pChannelStrip->updateChannelInfo()) {                          if (pChannelStrip->updateChannelInfo()) {
2802                                  int iChannelStrip = m_changedStrips.indexOf(pChannelStrip);                                  const int iChannelStrip = m_changedStrips.indexOf(pChannelStrip);
2803                                  if (iChannelStrip >= 0)                                  if (iChannelStrip >= 0)
2804                                          m_changedStrips.removeAt(iChannelStrip);                                          m_changedStrips.removeAt(iChannelStrip);
2805                          }                          }
# Line 2637  void MainForm::timerSlot (void) Line 2810  void MainForm::timerSlot (void)
2810                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {
2811                                  m_iTimerSlot = 0;                                  m_iTimerSlot = 0;
2812                                  // Update the channel stream usage for each strip...                                  // Update the channel stream usage for each strip...
2813                                  QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();                                  const QList<QMdiSubWindow *>& wlist
2814                                  for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {                                          = m_pWorkspace->subWindowList();
2815                                    const int iStripCount = wlist.count();
2816                                    for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2817                                          ChannelStrip *pChannelStrip = NULL;                                          ChannelStrip *pChannelStrip = NULL;
2818                                          QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                                          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2819                                          if (pMdiSubWindow)                                          if (pMdiSubWindow)
2820                                                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                                                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2821                                          if (pChannelStrip && pChannelStrip->isVisible())                                          if (pChannelStrip && pChannelStrip->isVisible())
# Line 2656  void MainForm::timerSlot (void) Line 2831  void MainForm::timerSlot (void)
2831    
2832    
2833  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2834  // qsamplerMainForm -- Server stuff.  // QSampler::MainForm -- Server stuff.
2835    
2836  // Start linuxsampler server...  // Start linuxsampler server...
2837  void MainForm::startServer (void)  void MainForm::startServer (void)
# Line 2690  void MainForm::startServer (void) Line 2865  void MainForm::startServer (void)
2865    
2866          // OK. Let's build the startup process...          // OK. Let's build the startup process...
2867          m_pServer = new QProcess();          m_pServer = new QProcess();
2868          bForceServerStop = true;          m_bForceServerStop = true;
2869    
2870          // Setup stdout/stderr capture...          // Setup stdout/stderr capture...
2871  //      if (m_pOptions->bStdoutCapture) {          m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);
2872                  m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);          QObject::connect(m_pServer,
2873                  QObject::connect(m_pServer,                  SIGNAL(readyReadStandardOutput()),
2874                          SIGNAL(readyReadStandardOutput()),                  SLOT(readServerStdout()));
2875                          SLOT(readServerStdout()));          QObject::connect(m_pServer,
2876                  QObject::connect(m_pServer,                  SIGNAL(readyReadStandardError()),
2877                          SIGNAL(readyReadStandardError()),                  SLOT(readServerStdout()));
                         SLOT(readServerStdout()));  
 //      }  
2878    
2879          // The unforgiveable signal communication...          // The unforgiveable signal communication...
2880          QObject::connect(m_pServer,          QObject::connect(m_pServer,
# Line 2736  void MainForm::startServer (void) Line 2909  void MainForm::startServer (void)
2909    
2910    
2911  // Stop linuxsampler server...  // Stop linuxsampler server...
2912  void MainForm::stopServer (bool bInteractive)  void MainForm::stopServer ( bool bInteractive )
2913  {  {
2914          // Stop client code.          // Stop client code.
2915          stopClient();          stopClient();
# Line 2750  void MainForm::stopServer (bool bInterac Line 2923  void MainForm::stopServer (bool bInterac
2923                          "sampler session at any time by relaunching QSampler.\n\n"                          "sampler session at any time by relaunching QSampler.\n\n"
2924                          "Do you want LinuxSampler to stop?"),                          "Do you want LinuxSampler to stop?"),
2925                          QMessageBox::Yes | QMessageBox::No,                          QMessageBox::Yes | QMessageBox::No,
2926                          QMessageBox::Yes) == QMessageBox::No)                          QMessageBox::Yes) == QMessageBox::No) {
2927                  {                          m_bForceServerStop = false;
                         bForceServerStop = false;  
2928                  }                  }
2929          }          }
2930    
2931            bool bGraceWait = true;
2932    
2933          // And try to stop server.          // And try to stop server.
2934          if (m_pServer && bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2935                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2936                  if (m_pServer->state() == QProcess::Running) {                  if (m_pServer->state() == QProcess::Running) {
2937                  #if defined(WIN32)                  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
2938                          // Try harder...                          // Try harder...
2939                          m_pServer->kill();                          m_pServer->kill();
2940                  #else                  #else
2941                          // Try softly...                          // Try softly...
2942                          m_pServer->terminate();                          m_pServer->terminate();
2943                            bool bFinished = m_pServer->waitForFinished(QSAMPLER_TIMER_MSECS * 1000);
2944                            if (bFinished) bGraceWait = false;
2945                  #endif                  #endif
2946                  }                  }
2947          }       // Do final processing anyway.          }       // Do final processing anyway.
2948          else processServerExit();          else processServerExit();
2949    
2950          // Give it some time to terminate gracefully and stabilize...          // Give it some time to terminate gracefully and stabilize...
2951          QTime t;          if (bGraceWait) {
2952          t.start();                  QTime t;
2953          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                  t.start();
2954                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2955                            QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2956            }
2957  }  }
2958    
2959    
# Line 2797  void MainForm::processServerExit (void) Line 2975  void MainForm::processServerExit (void)
2975          if (m_pMessages)          if (m_pMessages)
2976                  m_pMessages->flushStdoutBuffer();                  m_pMessages->flushStdoutBuffer();
2977    
2978          if (m_pServer && bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2979                  if (m_pServer->state() != QProcess::NotRunning) {                  if (m_pServer->state() != QProcess::NotRunning) {
2980                          appendMessages(tr("Server is being forced..."));                          appendMessages(tr("Server is being forced..."));
2981                          // Force final server shutdown...                          // Force final server shutdown...
# Line 2822  void MainForm::processServerExit (void) Line 3000  void MainForm::processServerExit (void)
3000    
3001    
3002  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
3003  // qsamplerMainForm -- Client stuff.  // QSampler::MainForm -- Client stuff.
3004    
3005  // The LSCP client callback procedure.  // The LSCP client callback procedure.
3006  lscp_status_t qsampler_client_callback ( lscp_client_t */*pClient*/,  lscp_status_t qsampler_client_callback ( lscp_client_t */*pClient*/,
# Line 2874  bool MainForm::startClient (void) Line 3052  bool MainForm::startClient (void)
3052                  stabilizeForm();                  stabilizeForm();
3053                  return false;                  return false;
3054          }          }
3055    
3056          // Just set receive timeout value, blindly.          // Just set receive timeout value, blindly.
3057          ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);          ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
3058          appendMessages(          appendMessages(

Legend:
Removed from v.2717  
changed lines
  Added in v.3509

  ViewVC Help
Powered by ViewVC