/[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 3508 by capela, Mon Apr 1 22:36:26 2019 UTC
# Line 1  Line 1 
1  // qsamplerMainForm.cpp  // qsamplerMainForm.cpp
2  //  //
3  /****************************************************************************  /****************************************************************************
4     Copyright (C) 2004-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 91  static inline long lroundf ( float x ) Line 91  static inline long lroundf ( float x )
91    
92    
93  // All winsock apps needs this.  // All winsock apps needs this.
94  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
95  static WSADATA _wsaData;  static WSADATA _wsaData;
96  #endif  #endif
97    
# Line 109  static WSADATA _wsaData; Line 109  static WSADATA _wsaData;
109  #include <signal.h>  #include <signal.h>
110    
111  // File descriptor for SIGUSR1 notifier.  // File descriptor for SIGUSR1 notifier.
112  static int g_fdUsr1[2];  static int g_fdSigusr1[2];
113    
114  // Unix SIGUSR1 signal handler.  // Unix SIGUSR1 signal handler.
115  static void qsampler_sigusr1_handler ( int /* signo */ )  static void qsampler_sigusr1_handler ( int /* signo */ )
116  {  {
117          char c = 1;          char c = 1;
118    
119          (::write(g_fdUsr1[0], &c, sizeof(c)) > 0);          (::write(g_fdSigusr1[0], &c, sizeof(c)) > 0);
120    }
121    
122    // File descriptor for SIGTERM notifier.
123    static int g_fdSigterm[2];
124    
125    // Unix SIGTERM signal handler.
126    static void qsampler_sigterm_handler ( int /* signo */ )
127    {
128            char c = 1;
129    
130            (::write(g_fdSigterm[0], &c, sizeof(c)) > 0);
131  }  }
132    
133  #endif  // HAVE_SIGNAL_H  #endif  // HAVE_SIGNAL_H
134    
135    
136  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
137  // qsampler -- namespace  // QSampler -- namespace
138    
139    
140  namespace QSampler {  namespace QSampler {
# Line 143  namespace QSampler { Line 154  namespace QSampler {
154    
155    
156  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
157  // LscpEvent -- specialty for LSCP callback comunication.  // QSampler::LscpEvent -- specialty for LSCP callback comunication.
   
158    
159  class LscpEvent : public QEvent  class LscpEvent : public QEvent
160  {  {
# Line 159  public: Line 169  public:
169          }          }
170    
171          // Accessors.          // Accessors.
172          lscp_event_t event() { return m_event; }          lscp_event_t  event() { return m_event; }
173          QString&     data()  { return m_data;  }          const QString& data() { return m_data;  }
174    
175  private:  private:
176    
# Line 172  private: Line 182  private:
182    
183    
184  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
185  // qsamplerMainForm -- Main window form implementation.  // QSampler::Workspace -- Main window workspace (MDI Area) decl.
186    
187    class Workspace : public QMdiArea
188    {
189    public:
190    
191            Workspace(MainForm *pMainForm) : QMdiArea(pMainForm) {}
192    
193    protected:
194    
195            void resizeEvent(QResizeEvent *)
196            {
197                    MainForm *pMainForm = static_cast<MainForm *> (parentWidget());
198                    if (pMainForm)
199                            pMainForm->channelsArrangeAuto();
200            }
201    };
202    
203    
204    //-------------------------------------------------------------------------
205    // QSampler::MainForm -- Main window form implementation.
206    
207  // Kind of singleton reference.  // Kind of singleton reference.
208  MainForm* MainForm::g_pMainForm = NULL;  MainForm *MainForm::g_pMainForm = NULL;
209    
210  MainForm::MainForm ( QWidget *pParent )  MainForm::MainForm ( QWidget *pParent )
211          : QMainWindow(pParent)          : QMainWindow(pParent)
# Line 195  MainForm::MainForm ( QWidget *pParent ) Line 225  MainForm::MainForm ( QWidget *pParent )
225    
226          // We'll start clean.          // We'll start clean.
227          m_iUntitled   = 0;          m_iUntitled   = 0;
228            m_iDirtySetup = 0;
229          m_iDirtyCount = 0;          m_iDirtyCount = 0;
230    
231          m_pServer = NULL;          m_pServer = NULL;
# Line 213  MainForm::MainForm ( QWidget *pParent ) Line 244  MainForm::MainForm ( QWidget *pParent )
244          // LADISH Level 1 suport.          // LADISH Level 1 suport.
245    
246          // Initialize file descriptors for SIGUSR1 socket notifier.          // Initialize file descriptors for SIGUSR1 socket notifier.
247          ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdUsr1);          ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigusr1);
248          m_pUsr1Notifier          m_pSigusr1Notifier
249                  = new QSocketNotifier(g_fdUsr1[1], QSocketNotifier::Read, this);                  = new QSocketNotifier(g_fdSigusr1[1], QSocketNotifier::Read, this);
250    
251          QObject::connect(m_pUsr1Notifier,          QObject::connect(m_pSigusr1Notifier,
252                  SIGNAL(activated(int)),                  SIGNAL(activated(int)),
253                  SLOT(handle_sigusr1()));                  SLOT(handle_sigusr1()));
254    
255          // Install SIGUSR1 signal handler.          // Install SIGUSR1 signal handler.
256      struct sigaction usr1;      struct sigaction sigusr1;
257      usr1.sa_handler = qsampler_sigusr1_handler;      sigusr1.sa_handler = qsampler_sigusr1_handler;
258      sigemptyset(&usr1.sa_mask);      sigemptyset(&sigusr1.sa_mask);
259      usr1.sa_flags = 0;      sigusr1.sa_flags = 0;
260      usr1.sa_flags |= SA_RESTART;      sigusr1.sa_flags |= SA_RESTART;
261      ::sigaction(SIGUSR1, &usr1, NULL);      ::sigaction(SIGUSR1, &sigusr1, NULL);
262    
263            // Initialize file descriptors for SIGTERM socket notifier.
264            ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigterm);
265            m_pSigtermNotifier
266                    = new QSocketNotifier(g_fdSigterm[1], QSocketNotifier::Read, this);
267    
268            QObject::connect(m_pSigtermNotifier,
269                    SIGNAL(activated(int)),
270                    SLOT(handle_sigterm()));
271    
272            // Install SIGTERM signal handler.
273            struct sigaction sigterm;
274            sigterm.sa_handler = qsampler_sigterm_handler;
275            ::sigemptyset(&sigterm.sa_mask);
276            sigterm.sa_flags = 0;
277            sigterm.sa_flags |= SA_RESTART;
278            ::sigaction(SIGTERM, &sigterm, NULL);
279            ::sigaction(SIGQUIT, &sigterm, NULL);
280    
281            // Ignore SIGHUP/SIGINT signals.
282            ::signal(SIGHUP, SIG_IGN);
283            ::signal(SIGINT, SIG_IGN);
284    
285  #else   // HAVE_SIGNAL_H  #else   // HAVE_SIGNAL_H
286    
287          m_pUsr1Notifier = NULL;          m_pSigusr1Notifier = NULL;
288            m_pSigtermNotifier = NULL;
289                    
290  #endif  // !HAVE_SIGNAL_H  #endif  // !HAVE_SIGNAL_H
291    
# Line 269  MainForm::MainForm ( QWidget *pParent ) Line 323  MainForm::MainForm ( QWidget *pParent )
323  #endif  #endif
324    
325          // Make it an MDI workspace.          // Make it an MDI workspace.
326          m_pWorkspace = new QMdiArea(this);          m_pWorkspace = new Workspace(this);
327          m_pWorkspace->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);          m_pWorkspace->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
328          m_pWorkspace->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);          m_pWorkspace->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
329          // Set the activation connection.          // Set the activation connection.
# Line 304  MainForm::MainForm ( QWidget *pParent ) Line 358  MainForm::MainForm ( QWidget *pParent )
358          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
359          statusBar()->addWidget(pLabel);          statusBar()->addWidget(pLabel);
360    
361  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
362          WSAStartup(MAKEWORD(1, 1), &_wsaData);          WSAStartup(MAKEWORD(1, 1), &_wsaData);
363  #endif  #endif
364    
# Line 405  MainForm::~MainForm() Line 459  MainForm::~MainForm()
459          // Do final processing anyway.          // Do final processing anyway.
460          processServerExit();          processServerExit();
461    
462  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
463          WSACleanup();          WSACleanup();
464  #endif  #endif
465    
466  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
467          if (m_pUsr1Notifier)          if (m_pSigusr1Notifier)
468                  delete m_pUsr1Notifier;                  delete m_pSigusr1Notifier;
469            if (m_pSigtermNotifier)
470                    delete m_pSigtermNotifier;
471  #endif  #endif
472    
473          // Finally drop any widgets around...          // Finally drop any widgets around...
# Line 478  void MainForm::setup ( Options *pOptions Line 534  void MainForm::setup ( Options *pOptions
534          updateMessagesFont();          updateMessagesFont();
535          updateMessagesLimit();          updateMessagesLimit();
536          updateMessagesCapture();          updateMessagesCapture();
537    
538          // Set the visibility signal.          // Set the visibility signal.
539          QObject::connect(m_pMessages,          QObject::connect(m_pMessages,
540                  SIGNAL(visibilityChanged(bool)),                  SIGNAL(visibilityChanged(bool)),
# Line 543  bool MainForm::queryClose (void) Line 600  bool MainForm::queryClose (void)
600                                  || m_ui.channelsToolbar->isVisible());                                  || m_ui.channelsToolbar->isVisible());
601                          m_pOptions->bStatusbar = statusBar()->isVisible();                          m_pOptions->bStatusbar = statusBar()->isVisible();
602                          // Save the dock windows state.                          // Save the dock windows state.
                         const QString sDockables = saveState().toBase64().data();  
603                          m_pOptions->settings().setValue("/Layout/DockWindows", saveState());                          m_pOptions->settings().setValue("/Layout/DockWindows", saveState());
604                          // And the children, and the main windows state,.                          // And the children, and the main windows state,.
605                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);
# Line 586  void MainForm::dragEnterEvent ( QDragEnt Line 642  void MainForm::dragEnterEvent ( QDragEnt
642  }  }
643    
644    
645  void MainForm::dropEvent ( QDropEvent* pDropEvent )  void MainForm::dropEvent ( QDropEvent *pDropEvent )
646  {  {
647          // Accept externally originated drops only...          // Accept externally originated drops only...
648          if (pDropEvent->source())          if (pDropEvent->source())
# Line 642  void MainForm::customEvent ( QEvent* pEv Line 698  void MainForm::customEvent ( QEvent* pEv
698                                  updateAllChannelStrips(true);                                  updateAllChannelStrips(true);
699                                  break;                                  break;
700                          case LSCP_EVENT_CHANNEL_INFO: {                          case LSCP_EVENT_CHANNEL_INFO: {
701                                  int iChannelID = pLscpEvent->data().toInt();                                  const int iChannelID = pLscpEvent->data().toInt();
702                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);
703                                  if (pChannelStrip)                                  if (pChannelStrip)
704                                          channelStripChanged(pChannelStrip);                                          channelStripChanged(pChannelStrip);
# Line 701  void MainForm::handle_sigusr1 (void) Line 757  void MainForm::handle_sigusr1 (void)
757    
758          char c;          char c;
759    
760          if (::read(g_fdUsr1[1], &c, sizeof(c)) > 0)          if (::read(g_fdSigusr1[1], &c, sizeof(c)) > 0)
761                  saveSession(false);                  saveSession(false);
762    
763  #endif  #endif
764  }  }
765    
766    
767    void MainForm::handle_sigterm (void)
768    {
769    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
770    
771            char c;
772    
773            if (::read(g_fdSigterm[1], &c, sizeof(c)) > 0)
774                    close();
775    
776    #endif
777    }
778    
779    
780  void MainForm::updateViewMidiDeviceStatusMenu (void)  void MainForm::updateViewMidiDeviceStatusMenu (void)
781  {  {
782          m_ui.viewMidiDeviceStatusMenu->clear();          m_ui.viewMidiDeviceStatusMenu->clear();
# Line 733  void MainForm::contextMenuEvent( QContex Line 802  void MainForm::contextMenuEvent( QContex
802    
803    
804  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
805  // qsamplerMainForm -- Brainless public property accessors.  // QSampler::MainForm -- Brainless public property accessors.
806    
807  // The global options settings property.  // The global options settings property.
808  Options *MainForm::options (void) const  Options *MainForm::options (void) const
# Line 757  MainForm *MainForm::getInstance (void) Line 826  MainForm *MainForm::getInstance (void)
826    
827    
828  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
829  // qsamplerMainForm -- Session file stuff.  // QSampler::MainForm -- Session file stuff.
830    
831  // Format the displayable session filename.  // Format the displayable session filename.
832  QString MainForm::sessionName ( const QString& sFilename )  QString MainForm::sessionName ( const QString& sFilename )
833  {  {
834          bool bCompletePath = (m_pOptions && m_pOptions->bCompletePath);          const bool bCompletePath = (m_pOptions && m_pOptions->bCompletePath);
835          QString sSessionName = sFilename;          QString sSessionName = sFilename;
836          if (sSessionName.isEmpty())          if (sSessionName.isEmpty())
837                  sSessionName = tr("Untitled") + QString::number(m_iUntitled);                  sSessionName = tr("Untitled") + QString::number(m_iUntitled);
# Line 846  bool MainForm::saveSession ( bool bPromp Line 915  bool MainForm::saveSession ( bool bPromp
915                  // Enforce .lscp extension...                  // Enforce .lscp extension...
916                  if (QFileInfo(sFilename).suffix().isEmpty())                  if (QFileInfo(sFilename).suffix().isEmpty())
917                          sFilename += ".lscp";                          sFilename += ".lscp";
918            #if 0
919                  // Check if already exists...                  // Check if already exists...
920                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
921                          if (QMessageBox::warning(this,                          if (QMessageBox::warning(this,
# Line 858  bool MainForm::saveSession ( bool bPromp Line 928  bool MainForm::saveSession ( bool bPromp
928                                  == QMessageBox::No)                                  == QMessageBox::No)
929                                  return false;                                  return false;
930                  }                  }
931            #endif
932          }          }
933    
934          // Save it right away.          // Save it right away.
# Line 896  bool MainForm::closeSession ( bool bForc Line 967  bool MainForm::closeSession ( bool bForc
967          if (bClose) {          if (bClose) {
968                  // Remove all channel strips from sight...                  // Remove all channel strips from sight...
969                  m_pWorkspace->setUpdatesEnabled(false);                  m_pWorkspace->setUpdatesEnabled(false);
970                  QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();                  const QList<QMdiSubWindow *>& wlist
971                  for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {                          = m_pWorkspace->subWindowList();
972                    const int iStripCount = wlist.count();
973                    for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
974                          ChannelStrip *pChannelStrip = NULL;                          ChannelStrip *pChannelStrip = NULL;
975                          QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
976                          if (pMdiSubWindow)                          if (pMdiSubWindow)
977                                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
978                          if (pChannelStrip) {                          if (pChannelStrip) {
# Line 1021  bool MainForm::saveSessionFile ( const Q Line 1094  bool MainForm::saveSessionFile ( const Q
1094          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1095    
1096          // Write the file.          // Write the file.
1097          int  iErrors = 0;          int iErrors = 0;
1098          QTextStream ts(&file);          QTextStream ts(&file);
1099          ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;          ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;
1100          ts << "# " << tr("Version")          ts << "# " << tr("Version") << ": " CONFIG_BUILD_VERSION << endl;
1101          << ": " QSAMPLER_VERSION << endl;  //      ts << "# " << tr("Build") << ": " CONFIG_BUILD_DATE << endl;
         ts << "# " << tr("Build")  
         << ": " __DATE__ " " __TIME__ << endl;  
1102          ts << "#"  << endl;          ts << "#"  << endl;
1103          ts << "# " << tr("File")          ts << "# " << tr("File")
1104          << ": " << QFileInfo(sFilename).fileName() << endl;          << ": " << QFileInfo(sFilename).fileName() << endl;
# Line 1040  bool MainForm::saveSessionFile ( const Q Line 1111  bool MainForm::saveSessionFile ( const Q
1111          // It is assumed that this new kind of device+session file          // It is assumed that this new kind of device+session file
1112          // will be loaded from a complete initialized server...          // will be loaded from a complete initialized server...
1113          int *piDeviceIDs;          int *piDeviceIDs;
1114          int  iDevice;          int  i, iDevice;
1115          ts << "RESET" << endl;          ts << "RESET" << endl;
1116    
1117          // Audio device mapping.          // Audio device mapping.
1118          QMap<int, int> audioDeviceMap;          QMap<int, int> audioDeviceMap; iDevice = 0;
1119          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);
1120          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1121                  ts << endl;                  Device device(Device::Audio, piDeviceIDs[i]);
1122                  Device device(Device::Audio, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1123                    if (device.driverName().toUpper() == "PLUGIN")
1124                            continue;
1125                  // Audio device specification...                  // Audio device specification...
1126                    ts << endl;
1127                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1128                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1129                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
# Line 1080  bool MainForm::saveSessionFile ( const Q Line 1154  bool MainForm::saveSessionFile ( const Q
1154                          iPort++;                          iPort++;
1155                  }                  }
1156                  // Audio device index/id mapping.                  // Audio device index/id mapping.
1157                  audioDeviceMap[device.deviceID()] = iDevice;                  audioDeviceMap.insert(device.deviceID(), iDevice++);
1158                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1159                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1160          }          }
1161    
1162          // MIDI device mapping.          // MIDI device mapping.
1163          QMap<int, int> midiDeviceMap;          QMap<int, int> midiDeviceMap; iDevice = 0;
1164          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);
1165          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1166                  ts << endl;                  Device device(Device::Midi, piDeviceIDs[i]);
1167                  Device device(Device::Midi, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1168                    if (device.driverName().toUpper() == "PLUGIN")
1169                            continue;
1170                  // MIDI device specification...                  // MIDI device specification...
1171                    ts << endl;
1172                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1173                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1174                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
# Line 1122  bool MainForm::saveSessionFile ( const Q Line 1199  bool MainForm::saveSessionFile ( const Q
1199                          iPort++;                          iPort++;
1200                  }                  }
1201                  // MIDI device index/id mapping.                  // MIDI device index/id mapping.
1202                  midiDeviceMap[device.deviceID()] = iDevice;                  midiDeviceMap.insert(device.deviceID(), iDevice++);
1203                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1204                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1205          }          }
# Line 1133  bool MainForm::saveSessionFile ( const Q Line 1210  bool MainForm::saveSessionFile ( const Q
1210          QMap<int, int> midiInstrumentMap;          QMap<int, int> midiInstrumentMap;
1211          int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);          int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);
1212          for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {          for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {
1213                  int iMidiMap = piMaps[iMap];                  const int iMidiMap = piMaps[iMap];
1214                  const char *pszMapName                  const char *pszMapName
1215                          = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);                          = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);
1216                  ts << "# " << tr("MIDI instrument map") << " " << iMap;                  ts << "# " << tr("MIDI instrument map") << " " << iMap;
# Line 1190  bool MainForm::saveSessionFile ( const Q Line 1267  bool MainForm::saveSessionFile ( const Q
1267                          iErrors++;                          iErrors++;
1268                  }                  }
1269                  // MIDI strument index/id mapping.                  // MIDI strument index/id mapping.
1270                  midiInstrumentMap[iMidiMap] = iMap;                  midiInstrumentMap.insert(iMidiMap, iMap);
1271          }          }
1272          // Check for errors...          // Check for errors...
1273          if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {          if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {
# Line 1199  bool MainForm::saveSessionFile ( const Q Line 1276  bool MainForm::saveSessionFile ( const Q
1276          }          }
1277  #endif  // CONFIG_MIDI_INSTRUMENT  #endif  // CONFIG_MIDI_INSTRUMENT
1278    
1279          // Sampler channel mapping.          // Sampler channel mapping...
1280          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          int iChannelID = 0;
1281          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          const QList<QMdiSubWindow *>& wlist
1282                    = m_pWorkspace->subWindowList();
1283            const int iStripCount = wlist.count();
1284            for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
1285                  ChannelStrip *pChannelStrip = NULL;                  ChannelStrip *pChannelStrip = NULL;
1286                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
1287                  if (pMdiSubWindow)                  if (pMdiSubWindow)
1288                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
1289                  if (pChannelStrip) {                  if (pChannelStrip) {
1290                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1291                          if (pChannel) {                          if (pChannel) {
1292                                  ts << "# " << tr("Channel") << " " << iChannel << endl;                                  // Avoid "artifial" plug-in devices...
1293                                    const int iAudioDevice = pChannel->audioDevice();
1294                                    if (!audioDeviceMap.contains(iAudioDevice))
1295                                            continue;
1296                                    const int iMidiDevice = pChannel->midiDevice();
1297                                    if (!midiDeviceMap.contains(iMidiDevice))
1298                                            continue;
1299                                    // Go for regular, canonical devices...
1300                                    ts << "# " << tr("Channel") << " " << iChannelID << endl;
1301                                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
1302                                  if (audioDeviceMap.isEmpty()) {                                  if (audioDeviceMap.isEmpty()) {
1303                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannelID
1304                                                  << " " << pChannel->audioDriver() << endl;                                                  << " " << pChannel->audioDriver() << endl;
1305                                  } else {                                  } else {
1306                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannelID
1307                                                  << " " << audioDeviceMap[pChannel->audioDevice()] << endl;                                                  << " " << audioDeviceMap.value(iAudioDevice) << endl;
1308                                  }                                  }
1309                                  if (midiDeviceMap.isEmpty()) {                                  if (midiDeviceMap.isEmpty()) {
1310                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannel                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID
1311                                                  << " " << pChannel->midiDriver() << endl;                                                  << " " << pChannel->midiDriver() << endl;
1312                                  } else {                                  } else {
1313                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannel                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannelID
1314                                                  << " " << midiDeviceMap[pChannel->midiDevice()] << endl;                                                  << " " << midiDeviceMap.value(iMidiDevice) << endl;
1315                                  }                                  }
1316                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID
1317                                          << " " << pChannel->midiPort() << endl;                                          << " " << pChannel->midiPort() << endl;
1318                                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";                                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannelID << " ";
1319                                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)                                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
1320                                          ts << "ALL";                                          ts << "ALL";
1321                                  else                                  else
1322                                          ts << pChannel->midiChannel();                                          ts << pChannel->midiChannel();
1323                                  ts << endl;                                  ts << endl;
1324                                  ts << "LOAD ENGINE " << pChannel->engineName()                                  ts << "LOAD ENGINE " << pChannel->engineName()
1325                                          << " " << iChannel << endl;                                          << " " << iChannelID << endl;
1326                                  if (pChannel->instrumentStatus() < 100) ts << "# ";                                  if (pChannel->instrumentStatus() < 100) ts << "# ";
1327                                  ts << "LOAD INSTRUMENT NON_MODAL '"                                  ts << "LOAD INSTRUMENT NON_MODAL '"
1328                                          << pChannel->instrumentFile() << "' "                                          << pChannel->instrumentFile() << "' "
1329                                          << pChannel->instrumentNr() << " " << iChannel << endl;                                          << pChannel->instrumentNr() << " " << iChannelID << endl;
1330                                  ChannelRoutingMap::ConstIterator audioRoute;                                  ChannelRoutingMap::ConstIterator audioRoute;
1331                                  for (audioRoute = pChannel->audioRouting().begin();                                  for (audioRoute = pChannel->audioRouting().begin();
1332                                                  audioRoute != pChannel->audioRouting().end();                                                  audioRoute != pChannel->audioRouting().end();
1333                                                          ++audioRoute) {                                                          ++audioRoute) {
1334                                          ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannelID
1335                                                  << " " << audioRoute.key()                                                  << " " << audioRoute.key()
1336                                                  << " " << audioRoute.value() << endl;                                                  << " " << audioRoute.value() << endl;
1337                                  }                                  }
1338                                  ts << "SET CHANNEL VOLUME " << iChannel                                  ts << "SET CHANNEL VOLUME " << iChannelID
1339                                          << " " << pChannel->volume() << endl;                                          << " " << pChannel->volume() << endl;
1340                                  if (pChannel->channelMute())                                  if (pChannel->channelMute())
1341                                          ts << "SET CHANNEL MUTE " << iChannel << " 1" << endl;                                          ts << "SET CHANNEL MUTE " << iChannelID << " 1" << endl;
1342                                  if (pChannel->channelSolo())                                  if (pChannel->channelSolo())
1343                                          ts << "SET CHANNEL SOLO " << iChannel << " 1" << endl;                                          ts << "SET CHANNEL SOLO " << iChannelID << " 1" << endl;
1344                          #ifdef CONFIG_MIDI_INSTRUMENT                          #ifdef CONFIG_MIDI_INSTRUMENT
1345                                  if (pChannel->midiMap() >= 0) {                                  const int iMidiMap = pChannel->midiMap();
1346                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannel                                  if (midiInstrumentMap.contains(iMidiMap)) {
1347                                                  << " " << midiInstrumentMap[pChannel->midiMap()] << endl;                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannelID
1348                                                    << " " << midiInstrumentMap.value(iMidiMap) << endl;
1349                                  }                                  }
1350                          #endif                          #endif
1351                          #ifdef CONFIG_FXSEND                          #ifdef CONFIG_FXSEND
                                 int iChannelID = pChannel->channelID();  
1352                                  int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID);                                  int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID);
1353                                  for (int iFxSend = 0;                                  for (int iFxSend = 0;
1354                                                  piFxSends && piFxSends[iFxSend] >= 0;                                                  piFxSends && piFxSends[iFxSend] >= 0;
# Line 1268  bool MainForm::saveSessionFile ( const Q Line 1356  bool MainForm::saveSessionFile ( const Q
1356                                          lscp_fxsend_info_t *pFxSendInfo = ::lscp_get_fxsend_info(                                          lscp_fxsend_info_t *pFxSendInfo = ::lscp_get_fxsend_info(
1357                                                  m_pClient, iChannelID, piFxSends[iFxSend]);                                                  m_pClient, iChannelID, piFxSends[iFxSend]);
1358                                          if (pFxSendInfo) {                                          if (pFxSendInfo) {
1359                                                  ts << "CREATE FX_SEND " << iChannel                                                  ts << "CREATE FX_SEND " << iChannelID
1360                                                          << " " << pFxSendInfo->midi_controller;                                                          << " " << pFxSendInfo->midi_controller;
1361                                                  if (pFxSendInfo->name)                                                  if (pFxSendInfo->name)
1362                                                          ts << " '" << pFxSendInfo->name << "'";                                                          ts << " '" << pFxSendInfo->name << "'";
# Line 1278  bool MainForm::saveSessionFile ( const Q Line 1366  bool MainForm::saveSessionFile ( const Q
1366                                                                  piRouting && piRouting[iAudioSrc] >= 0;                                                                  piRouting && piRouting[iAudioSrc] >= 0;
1367                                                                          iAudioSrc++) {                                                                          iAudioSrc++) {
1368                                                          ts << "SET FX_SEND AUDIO_OUTPUT_CHANNEL "                                                          ts << "SET FX_SEND AUDIO_OUTPUT_CHANNEL "
1369                                                                  << iChannel                                                                  << iChannelID
1370                                                                  << " " << iFxSend                                                                  << " " << iFxSend
1371                                                                  << " " << iAudioSrc                                                                  << " " << iAudioSrc
1372                                                                  << " " << piRouting[iAudioSrc] << endl;                                                                  << " " << piRouting[iAudioSrc] << endl;
1373                                                  }                                                  }
1374                                          #ifdef CONFIG_FXSEND_LEVEL                                          #ifdef CONFIG_FXSEND_LEVEL
1375                                                  ts << "SET FX_SEND LEVEL " << iChannel                                                  ts << "SET FX_SEND LEVEL " << iChannelID
1376                                                          << " " << iFxSend                                                          << " " << iFxSend
1377                                                          << " " << pFxSendInfo->level << endl;                                                          << " " << pFxSendInfo->level << endl;
1378                                          #endif                                          #endif
# Line 1296  bool MainForm::saveSessionFile ( const Q Line 1384  bool MainForm::saveSessionFile ( const Q
1384                                  }                                  }
1385                          #endif                          #endif
1386                                  ts << endl;                                  ts << endl;
1387                                    // Go for next channel...
1388                                    ++iChannelID;
1389                          }                          }
1390                  }                  }
1391                  // Try to keep it snappy :)                  // Try to keep it snappy :)
# Line 1347  void MainForm::sessionDirty (void) Line 1437  void MainForm::sessionDirty (void)
1437    
1438    
1439  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1440  // qsamplerMainForm -- File Action slots.  // QSampler::MainForm -- File Action slots.
1441    
1442  // Create a new sampler session.  // Create a new sampler session.
1443  void MainForm::fileNew (void)  void MainForm::fileNew (void)
# Line 1371  void MainForm::fileOpenRecent (void) Line 1461  void MainForm::fileOpenRecent (void)
1461          // Retrive filename index from action data...          // Retrive filename index from action data...
1462          QAction *pAction = qobject_cast<QAction *> (sender());          QAction *pAction = qobject_cast<QAction *> (sender());
1463          if (pAction && m_pOptions) {          if (pAction && m_pOptions) {
1464                  int iIndex = pAction->data().toInt();                  const int iIndex = pAction->data().toInt();
1465                  if (iIndex >= 0 && iIndex < m_pOptions->recentFiles.count()) {                  if (iIndex >= 0 && iIndex < m_pOptions->recentFiles.count()) {
1466                          QString sFilename = m_pOptions->recentFiles[iIndex];                          QString sFilename = m_pOptions->recentFiles[iIndex];
1467                          // Check if we can safely close the current session...                          // Check if we can safely close the current session...
# Line 1405  void MainForm::fileReset (void) Line 1495  void MainForm::fileReset (void)
1495                  return;                  return;
1496    
1497          // Ask user whether he/she want's an internal sampler reset...          // Ask user whether he/she want's an internal sampler reset...
1498          if (QMessageBox::warning(this,          if (m_pOptions && m_pOptions->bConfirmReset) {
1499                  QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");
1500                  tr("Resetting the sampler instance will close\n"                  const QString& sText = tr(
1501                  "all device and channel configurations.\n\n"                          "Resetting the sampler instance will close\n"
1502                  "Please note that this operation may cause\n"                          "all device and channel configurations.\n\n"
1503                  "temporary MIDI and Audio disruption.\n\n"                          "Please note that this operation may cause\n"
1504                  "Do you want to reset the sampler engine now?"),                          "temporary MIDI and Audio disruption.\n\n"
1505                  QMessageBox::Ok | QMessageBox::Cancel)                          "Do you want to reset the sampler engine now?");
1506                  == QMessageBox::Cancel)          #if 0
1507                  return;                  if (QMessageBox::warning(this, sTitle, sText,
1508                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1509                            return;
1510            #else
1511                    QMessageBox mbox(this);
1512                    mbox.setIcon(QMessageBox::Warning);
1513                    mbox.setWindowTitle(sTitle);
1514                    mbox.setText(sText);
1515                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1516                    QCheckBox cbox(tr("Don't ask this again"));
1517                    cbox.setChecked(false);
1518                    cbox.blockSignals(true);
1519                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1520                    if (mbox.exec() == QMessageBox::Cancel)
1521                            return;
1522                    if (cbox.isChecked())
1523                            m_pOptions->bConfirmReset = false;
1524            #endif
1525            }
1526    
1527          // Trye closing the current session, first...          // Trye closing the current session, first...
1528          if (!closeSession(true))          if (!closeSession(true))
# Line 1446  void MainForm::fileRestart (void) Line 1554  void MainForm::fileRestart (void)
1554    
1555          // Ask user whether he/she want's a complete restart...          // Ask user whether he/she want's a complete restart...
1556          // (if we're currently up and running)          // (if we're currently up and running)
1557          if (bRestart && m_pClient) {          if (m_pOptions && m_pOptions->bConfirmRestart) {
1558                  bRestart = (QMessageBox::warning(this,                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");
1559                          QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sText = tr(
1560                          tr("New settings will be effective after\n"                          "New settings will be effective after\n"
1561                          "restarting the client/server connection.\n\n"                          "restarting the client/server connection.\n\n"
1562                          "Please note that this operation may cause\n"                          "Please note that this operation may cause\n"
1563                          "temporary MIDI and Audio disruption.\n\n"                          "temporary MIDI and Audio disruption.\n\n"
1564                          "Do you want to restart the connection now?"),                          "Do you want to restart the connection now?");
1565                          QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok);          #if 0
1566                    if (QMessageBox::warning(this, sTitle, sText,
1567                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1568                            bRestart = false;
1569            #else
1570                    QMessageBox mbox(this);
1571                    mbox.setIcon(QMessageBox::Warning);
1572                    mbox.setWindowTitle(sTitle);
1573                    mbox.setText(sText);
1574                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1575                    QCheckBox cbox(tr("Don't ask this again"));
1576                    cbox.setChecked(false);
1577                    cbox.blockSignals(true);
1578                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1579                    if (mbox.exec() == QMessageBox::Cancel)
1580                            bRestart = false;
1581                    else
1582                    if (cbox.isChecked())
1583                            m_pOptions->bConfirmRestart = false;
1584            #endif
1585          }          }
1586    
1587          // Are we still for it?          // Are we still for it?
# Line 1476  void MainForm::fileExit (void) Line 1603  void MainForm::fileExit (void)
1603    
1604    
1605  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1606  // qsamplerMainForm -- Edit Action slots.  // QSampler::MainForm -- Edit Action slots.
1607    
1608  // Add a new sampler channel.  // Add a new sampler channel.
1609  void MainForm::editAddChannel (void)  void MainForm::editAddChannel (void)
1610  {  {
1611            ++m_iDirtySetup;
1612            addChannelStrip();
1613            --m_iDirtySetup;
1614    }
1615    
1616    void MainForm::addChannelStrip (void)
1617    {
1618          if (m_pClient == NULL)          if (m_pClient == NULL)
1619                  return;                  return;
1620    
# Line 1504  void MainForm::editAddChannel (void) Line 1638  void MainForm::editAddChannel (void)
1638          }          }
1639    
1640          // Do we auto-arrange?          // Do we auto-arrange?
1641          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
1642    
1643          // Make that an overall update.          // Make that an overall update.
1644          m_iDirtyCount++;          m_iDirtyCount++;
# Line 1516  void MainForm::editAddChannel (void) Line 1649  void MainForm::editAddChannel (void)
1649  // Remove current sampler channel.  // Remove current sampler channel.
1650  void MainForm::editRemoveChannel (void)  void MainForm::editRemoveChannel (void)
1651  {  {
1652            ++m_iDirtySetup;
1653            removeChannelStrip();
1654            --m_iDirtySetup;
1655    }
1656    
1657    void MainForm::removeChannelStrip (void)
1658    {
1659          if (m_pClient == NULL)          if (m_pClient == NULL)
1660                  return;                  return;
1661    
# Line 1529  void MainForm::editRemoveChannel (void) Line 1669  void MainForm::editRemoveChannel (void)
1669    
1670          // Prompt user if he/she's sure about this...          // Prompt user if he/she's sure about this...
1671          if (m_pOptions && m_pOptions->bConfirmRemove) {          if (m_pOptions && m_pOptions->bConfirmRemove) {
1672                  if (QMessageBox::warning(this,                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning");
1673                          QSAMPLER_TITLE ": " + tr("Warning"),                  const QString& sText = tr(
1674                          tr("About to remove channel:\n\n"                          "About to remove channel:\n\n"
1675                          "%1\n\n"                          "%1\n\n"
1676                          "Are you sure?")                          "Are you sure?")
1677                          .arg(pChannelStrip->windowTitle()),                          .arg(pChannelStrip->windowTitle());
1678                          QMessageBox::Ok | QMessageBox::Cancel)          #if 0
1679                          == QMessageBox::Cancel)                  if (QMessageBox::warning(this, sTitle, sText,
1680                            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
1681                          return;                          return;
1682            #else
1683                    QMessageBox mbox(this);
1684                    mbox.setIcon(QMessageBox::Warning);
1685                    mbox.setWindowTitle(sTitle);
1686                    mbox.setText(sText);
1687                    mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
1688                    QCheckBox cbox(tr("Don't ask this again"));
1689                    cbox.setChecked(false);
1690                    cbox.blockSignals(true);
1691                    mbox.addButton(&cbox, QMessageBox::ActionRole);
1692                    if (mbox.exec() == QMessageBox::Cancel)
1693                            return;
1694                    if (cbox.isChecked())
1695                            m_pOptions->bConfirmRemove = false;
1696            #endif
1697          }          }
1698    
1699          // Remove the existing sampler channel.          // Remove the existing sampler channel.
1700          if (!pChannel->removeChannel())          if (!pChannel->removeChannel())
1701                  return;                  return;
1702    
         // We'll be dirty, for sure...  
         m_iDirtyCount++;  
   
1703          // Just delete the channel strip.          // Just delete the channel strip.
1704          destroyChannelStrip(pChannelStrip);          destroyChannelStrip(pChannelStrip);
1705    
1706            // We'll be dirty, for sure...
1707            m_iDirtyCount++;
1708            stabilizeForm();
1709  }  }
1710    
1711    
# Line 1606  void MainForm::editResetAllChannels (voi Line 1763  void MainForm::editResetAllChannels (voi
1763          // Invoque the channel strip procedure,          // Invoque the channel strip procedure,
1764          // for all channels out there...          // for all channels out there...
1765          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1766          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
1767          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {                  = m_pWorkspace->subWindowList();
1768            const int iStripCount = wlist.count();
1769            for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
1770                  ChannelStrip *pChannelStrip = NULL;                  ChannelStrip *pChannelStrip = NULL;
1771                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
1772                  if (pMdiSubWindow)                  if (pMdiSubWindow)
1773                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
1774                  if (pChannelStrip)                  if (pChannelStrip)
# Line 1620  void MainForm::editResetAllChannels (voi Line 1779  void MainForm::editResetAllChannels (voi
1779    
1780    
1781  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1782  // qsamplerMainForm -- View Action slots.  // QSampler::MainForm -- View Action slots.
1783    
1784  // Show/hide the main program window menubar.  // Show/hide the main program window menubar.
1785  void MainForm::viewMenubar ( bool bOn )  void MainForm::viewMenubar ( bool bOn )
# Line 1720  void MainForm::viewOptions (void) Line 1879  void MainForm::viewOptions (void)
1879                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)
1880                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();
1881                  // To track down deferred or immediate changes.                  // To track down deferred or immediate changes.
1882                  QString sOldServerHost      = m_pOptions->sServerHost;                  const QString sOldServerHost      = m_pOptions->sServerHost;
1883                  int     iOldServerPort      = m_pOptions->iServerPort;                  const int     iOldServerPort      = m_pOptions->iServerPort;
1884                  int     iOldServerTimeout   = m_pOptions->iServerTimeout;                  const int     iOldServerTimeout   = m_pOptions->iServerTimeout;
1885                  bool    bOldServerStart     = m_pOptions->bServerStart;                  const bool    bOldServerStart     = m_pOptions->bServerStart;
1886                  QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;                  const QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;
1887                  bool    bOldMessagesLog     = m_pOptions->bMessagesLog;                  const bool    bOldMessagesLog     = m_pOptions->bMessagesLog;
1888                  QString sOldMessagesLogPath = m_pOptions->sMessagesLogPath;                  const QString sOldMessagesLogPath = m_pOptions->sMessagesLogPath;
1889                  QString sOldDisplayFont     = m_pOptions->sDisplayFont;                  const QString sOldDisplayFont     = m_pOptions->sDisplayFont;
1890                  bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;                  const bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1891                  int     iOldMaxVolume       = m_pOptions->iMaxVolume;                  const int     iOldMaxVolume       = m_pOptions->iMaxVolume;
1892                  QString sOldMessagesFont    = m_pOptions->sMessagesFont;                  const QString sOldMessagesFont    = m_pOptions->sMessagesFont;
1893                  bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;                  const bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;
1894                  bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;                  const bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;
1895                  int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;                  const int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;
1896                  int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;                  const int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1897                  bool    bOldCompletePath    = m_pOptions->bCompletePath;                  const bool    bOldCompletePath    = m_pOptions->bCompletePath;
1898                  bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;                  const bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1899                  int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;                  const int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1900                  int     iOldBaseFontSize    = m_pOptions->iBaseFontSize;                  const int     iOldBaseFontSize    = m_pOptions->iBaseFontSize;
1901                  // Load the current setup settings.                  // Load the current setup settings.
1902                  pOptionsForm->setup(m_pOptions);                  pOptionsForm->setup(m_pOptions);
1903                  // Show the setup dialog...                  // Show the setup dialog...
# Line 1801  void MainForm::viewOptions (void) Line 1960  void MainForm::viewOptions (void)
1960    
1961    
1962  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1963  // qsamplerMainForm -- Channels action slots.  // QSampler::MainForm -- Channels action slots.
1964    
1965  // Arrange channel strips.  // Arrange channel strips.
1966  void MainForm::channelsArrange (void)  void MainForm::channelsArrange (void)
1967  {  {
1968          // Full width vertical tiling          // Full width vertical tiling
1969          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
1970                    = m_pWorkspace->subWindowList();
1971          if (wlist.isEmpty())          if (wlist.isEmpty())
1972                  return;                  return;
1973    
1974          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1975          int y = 0;          int y = 0;
1976          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          const int iStripCount = wlist.count();
1977                  ChannelStrip *pChannelStrip = NULL;          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
1978                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
1979                  if (pMdiSubWindow)                  if (pMdiSubWindow) {
1980                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                          pMdiSubWindow->adjustSize();
1981                  if (pChannelStrip) {                          int iWidth = m_pWorkspace->width();
1982                  /*  if (pChannelStrip->testWState(WState_Maximized | WState_Minimized)) {                          if (iWidth < pMdiSubWindow->width())
1983                                  // Prevent flicker...                                  iWidth = pMdiSubWindow->width();
1984                                  pChannelStrip->hide();                          const int iHeight = pMdiSubWindow->frameGeometry().height();
1985                                  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);  
1986                          y += iHeight;                          y += iHeight;
1987                  }                  }
1988          }          }
# Line 1851  void MainForm::channelsAutoArrange ( boo Line 2002  void MainForm::channelsAutoArrange ( boo
2002          m_pOptions->bAutoArrange = bOn;          m_pOptions->bAutoArrange = bOn;
2003    
2004          // If on, update whole workspace...          // If on, update whole workspace...
2005          if (m_pOptions->bAutoArrange)          channelsArrangeAuto();
2006    }
2007    
2008    
2009    void MainForm::channelsArrangeAuto (void)
2010    {
2011            if (m_pOptions && m_pOptions->bAutoArrange)
2012                  channelsArrange();                  channelsArrange();
2013  }  }
2014    
2015    
2016  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2017  // qsamplerMainForm -- Help Action slots.  // QSampler::MainForm -- Help Action slots.
2018    
2019  // Show information about the Qt toolkit.  // Show information about the Qt toolkit.
2020  void MainForm::helpAboutQt (void)  void MainForm::helpAboutQt (void)
# Line 1869  void MainForm::helpAboutQt (void) Line 2026  void MainForm::helpAboutQt (void)
2026  // Show information about application program.  // Show information about application program.
2027  void MainForm::helpAbout (void)  void MainForm::helpAbout (void)
2028  {  {
2029          // Stuff the about box text...          QStringList list;
         QString sText = "<p>\n";  
         sText += "<b>" QSAMPLER_TITLE " - " + tr(QSAMPLER_SUBTITLE) + "</b><br />\n";  
         sText += "<br />\n";  
         sText += tr("Version") + ": <b>" QSAMPLER_VERSION "</b><br />\n";  
         sText += "<small>" + tr("Build") + ": " __DATE__ " " __TIME__ "</small><br />\n";  
2030  #ifdef CONFIG_DEBUG  #ifdef CONFIG_DEBUG
2031          sText += "<small><font color=\"red\">";          list << tr("Debugging option enabled.");
         sText += tr("Debugging option enabled.");  
         sText += "</font></small><br />";  
2032  #endif  #endif
2033  #ifndef CONFIG_LIBGIG  #ifndef CONFIG_LIBGIG
2034          sText += "<small><font color=\"red\">";          list << tr("GIG (libgig) file support disabled.");
         sText += tr("GIG (libgig) file support disabled.");  
         sText += "</font></small><br />";  
2035  #endif  #endif
2036  #ifndef CONFIG_INSTRUMENT_NAME  #ifndef CONFIG_INSTRUMENT_NAME
2037          sText += "<small><font color=\"red\">";          list << tr("LSCP (liblscp) instrument_name support disabled.");
         sText += tr("LSCP (liblscp) instrument_name support disabled.");  
         sText += "</font></small><br />";  
2038  #endif  #endif
2039  #ifndef CONFIG_MUTE_SOLO  #ifndef CONFIG_MUTE_SOLO
2040          sText += "<small><font color=\"red\">";          list << tr("Sampler channel Mute/Solo support disabled.");
         sText += tr("Sampler channel Mute/Solo support disabled.");  
         sText += "</font></small><br />";  
2041  #endif  #endif
2042  #ifndef CONFIG_AUDIO_ROUTING  #ifndef CONFIG_AUDIO_ROUTING
2043          sText += "<small><font color=\"red\">";          list << tr("LSCP (liblscp) audio_routing support disabled.");
         sText += tr("LSCP (liblscp) audio_routing support disabled.");  
         sText += "</font></small><br />";  
2044  #endif  #endif
2045  #ifndef CONFIG_FXSEND  #ifndef CONFIG_FXSEND
2046          sText += "<small><font color=\"red\">";          list << tr("Sampler channel Effect Sends support disabled.");
         sText += tr("Sampler channel Effect Sends support disabled.");  
         sText += "</font></small><br />";  
2047  #endif  #endif
2048  #ifndef CONFIG_VOLUME  #ifndef CONFIG_VOLUME
2049          sText += "<small><font color=\"red\">";          list << tr("Global volume support disabled.");
         sText += tr("Global volume support disabled.");  
         sText += "</font></small><br />";  
2050  #endif  #endif
2051  #ifndef CONFIG_MIDI_INSTRUMENT  #ifndef CONFIG_MIDI_INSTRUMENT
2052          sText += "<small><font color=\"red\">";          list << tr("MIDI instrument mapping support disabled.");
         sText += tr("MIDI instrument mapping support disabled.");  
         sText += "</font></small><br />";  
2053  #endif  #endif
2054  #ifndef CONFIG_EDIT_INSTRUMENT  #ifndef CONFIG_EDIT_INSTRUMENT
2055          sText += "<small><font color=\"red\">";          list << tr("Instrument editing support disabled.");
         sText += tr("Instrument editing support disabled.");  
         sText += "</font></small><br />";  
2056  #endif  #endif
2057  #ifndef CONFIG_EVENT_CHANNEL_MIDI  #ifndef CONFIG_EVENT_CHANNEL_MIDI
2058          sText += "<small><font color=\"red\">";          list << tr("Channel MIDI event support disabled.");
         sText += tr("Channel MIDI event support disabled.");  
         sText += "</font></small><br />";  
2059  #endif  #endif
2060  #ifndef CONFIG_EVENT_DEVICE_MIDI  #ifndef CONFIG_EVENT_DEVICE_MIDI
2061          sText += "<small><font color=\"red\">";          list << tr("Device MIDI event support disabled.");
         sText += tr("Device MIDI event support disabled.");  
         sText += "</font></small><br />";  
2062  #endif  #endif
2063  #ifndef CONFIG_MAX_VOICES  #ifndef CONFIG_MAX_VOICES
2064          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 />";  
2065  #endif  #endif
2066    
2067            // Stuff the about box text...
2068            QString sText = "<p>\n";
2069            sText += "<b>" QSAMPLER_TITLE " - " + tr(QSAMPLER_SUBTITLE) + "</b><br />\n";
2070            sText += "<br />\n";
2071            sText += tr("Version") + ": <b>" CONFIG_BUILD_VERSION "</b><br />\n";
2072    //      sText += "<small>" + tr("Build") + ": " CONFIG_BUILD_DATE "</small><br />\n";
2073            if (!list.isEmpty()) {
2074                    sText += "<small><font color=\"red\">";
2075                    sText += list.join("<br />\n");
2076                    sText += "</font></small>";
2077            }
2078          sText += "<br />\n";          sText += "<br />\n";
2079          sText += tr("Using") + ": ";          sText += tr("Using") + ": ";
2080          sText += ::lscp_client_package();          sText += ::lscp_client_package();
# Line 1964  void MainForm::helpAbout (void) Line 2104  void MainForm::helpAbout (void)
2104    
2105    
2106  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2107  // qsamplerMainForm -- Main window stabilization.  // QSampler::MainForm -- Main window stabilization.
2108    
2109  void MainForm::stabilizeForm (void)  void MainForm::stabilizeForm (void)
2110  {  {
# Line 1976  void MainForm::stabilizeForm (void) Line 2116  void MainForm::stabilizeForm (void)
2116    
2117          // Update the main menu state...          // Update the main menu state...
2118          ChannelStrip *pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
2119          bool bHasClient = (m_pOptions != NULL && m_pClient != NULL);          const QList<QMdiSubWindow *>& wlist = m_pWorkspace->subWindowList();
2120          bool bHasChannel = (bHasClient && pChannelStrip != NULL);          const bool bHasClient = (m_pOptions != NULL && m_pClient != NULL);
2121          bool bHasChannels = (bHasClient && m_pWorkspace->subWindowList().count() > 0);          const bool bHasChannel = (bHasClient && pChannelStrip != NULL);
2122            const bool bHasChannels = (bHasClient && wlist.count() > 0);
2123          m_ui.fileNewAction->setEnabled(bHasClient);          m_ui.fileNewAction->setEnabled(bHasClient);
2124          m_ui.fileOpenAction->setEnabled(bHasClient);          m_ui.fileOpenAction->setEnabled(bHasClient);
2125          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
# Line 2058  void MainForm::volumeChanged ( int iVolu Line 2199  void MainForm::volumeChanged ( int iVolu
2199                  m_pVolumeSpinBox->setValue(iVolume);                  m_pVolumeSpinBox->setValue(iVolume);
2200    
2201          // Do it as commanded...          // Do it as commanded...
2202          float fVolume = 0.01f * float(iVolume);          const float fVolume = 0.01f * float(iVolume);
2203          if (::lscp_set_volume(m_pClient, fVolume) == LSCP_OK)          if (::lscp_set_volume(m_pClient, fVolume) == LSCP_OK)
2204                  appendMessages(QObject::tr("Volume: %1.").arg(fVolume));                  appendMessages(QObject::tr("Volume: %1.").arg(fVolume));
2205          else          else
# Line 2093  void MainForm::channelStripChanged ( Cha Line 2234  void MainForm::channelStripChanged ( Cha
2234  void MainForm::updateSession (void)  void MainForm::updateSession (void)
2235  {  {
2236  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
2237          int iVolume = ::lroundf(100.0f * ::lscp_get_volume(m_pClient));          const int iVolume = ::lroundf(100.0f * ::lscp_get_volume(m_pClient));
2238          m_iVolumeChanging++;          m_iVolumeChanging++;
2239          m_pVolumeSlider->setValue(iVolume);          m_pVolumeSlider->setValue(iVolume);
2240          m_pVolumeSpinBox->setValue(iVolume);          m_pVolumeSpinBox->setValue(iVolume);
# Line 2101  void MainForm::updateSession (void) Line 2242  void MainForm::updateSession (void)
2242  #endif  #endif
2243  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
2244          // FIXME: Make some room for default instrument maps...          // FIXME: Make some room for default instrument maps...
2245          int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);          const int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);
2246          if (iMaps < 0)          if (iMaps < 0)
2247                  appendMessagesClient("lscp_get_midi_instrument_maps");                  appendMessagesClient("lscp_get_midi_instrument_maps");
2248          else if (iMaps < 1) {          else if (iMaps < 1) {
# Line 2115  void MainForm::updateSession (void) Line 2256  void MainForm::updateSession (void)
2256          updateAllChannelStrips(false);          updateAllChannelStrips(false);
2257    
2258          // Do we auto-arrange?          // Do we auto-arrange?
2259          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
2260    
2261          // Remember to refresh devices and instruments...          // Remember to refresh devices and instruments...
2262          if (m_pInstrumentListForm)          if (m_pInstrumentListForm)
# Line 2128  void MainForm::updateSession (void) Line 2268  void MainForm::updateSession (void)
2268    
2269  void MainForm::updateAllChannelStrips ( bool bRemoveDeadStrips )  void MainForm::updateAllChannelStrips ( bool bRemoveDeadStrips )
2270  {  {
2271            // Skip if setting up a new channel strip...
2272            if (m_iDirtySetup > 0)
2273                    return;
2274    
2275          // Retrieve the current channel list.          // Retrieve the current channel list.
2276          int *piChannelIDs = ::lscp_list_channels(m_pClient);          int *piChannelIDs = ::lscp_list_channels(m_pClient);
2277          if (piChannelIDs == NULL) {          if (piChannelIDs == NULL) {
# Line 2145  void MainForm::updateAllChannelStrips ( Line 2289  void MainForm::updateAllChannelStrips (
2289                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));
2290                  }                  }
2291                  // Do we auto-arrange?                  // Do we auto-arrange?
2292                  if (m_pOptions && m_pOptions->bAutoArrange)                  channelsArrangeAuto();
                         channelsArrange();  
2293                  // remove dead channel strips                  // remove dead channel strips
2294                  if (bRemoveDeadStrips) {                  if (bRemoveDeadStrips) {
2295                          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();                          const QList<QMdiSubWindow *>& wlist
2296                          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {                                  = m_pWorkspace->subWindowList();
2297                            const int iStripCount = wlist.count();
2298                            for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2299                                  ChannelStrip *pChannelStrip = NULL;                                  ChannelStrip *pChannelStrip = NULL;
2300                                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2301                                  if (pMdiSubWindow)                                  if (pMdiSubWindow)
2302                                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2303                                  if (pChannelStrip) {                                  if (pChannelStrip) {
2304                                          bool bExists = false;                                          bool bExists = false;
2305                                          for (int j = 0; piChannelIDs[j] >= 0; ++j) {                                          for (int iChannel = 0; piChannelIDs[iChannel] >= 0; ++iChannel) {
2306                                                  if (!pChannelStrip->channel())                                                  Channel *pChannel = pChannelStrip->channel();
2307                                                    if (pChannel == NULL)
2308                                                          break;                                                          break;
2309                                                  if (piChannelIDs[j] == pChannelStrip->channel()->channelID()) {                                                  if (piChannelIDs[iChannel] == pChannel->channelID()) {
2310                                                          // strip exists, don't touch it                                                          // strip exists, don't touch it
2311                                                          bExists = true;                                                          bExists = true;
2312                                                          break;                                                          break;
# Line 2185  void MainForm::updateRecentFiles ( const Line 2331  void MainForm::updateRecentFiles ( const
2331                  return;                  return;
2332    
2333          // Remove from list if already there (avoid duplicates)          // Remove from list if already there (avoid duplicates)
2334          int iIndex = m_pOptions->recentFiles.indexOf(sFilename);          const int iIndex = m_pOptions->recentFiles.indexOf(sFilename);
2335          if (iIndex >= 0)          if (iIndex >= 0)
2336                  m_pOptions->recentFiles.removeAt(iIndex);                  m_pOptions->recentFiles.removeAt(iIndex);
2337          // Put it to front...          // Put it to front...
# Line 2224  void MainForm::updateRecentFilesMenu (vo Line 2370  void MainForm::updateRecentFilesMenu (vo
2370  void MainForm::updateInstrumentNames (void)  void MainForm::updateInstrumentNames (void)
2371  {  {
2372          // Full channel list update...          // Full channel list update...
2373          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2374                    = m_pWorkspace->subWindowList();
2375          if (wlist.isEmpty())          if (wlist.isEmpty())
2376                  return;                  return;
2377    
2378          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2379          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          const int iStripCount = wlist.count();
2380                  ChannelStrip *pChannelStrip = (ChannelStrip *) wlist.at(iChannel);          for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2381                    ChannelStrip *pChannelStrip = NULL;
2382                    QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2383                    if (pMdiSubWindow)
2384                            pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2385                  if (pChannelStrip)                  if (pChannelStrip)
2386                          pChannelStrip->updateInstrumentName(true);                          pChannelStrip->updateInstrumentName(true);
2387          }          }
# Line 2247  void MainForm::updateDisplayFont (void) Line 2398  void MainForm::updateDisplayFont (void)
2398          // Check if display font is legal.          // Check if display font is legal.
2399          if (m_pOptions->sDisplayFont.isEmpty())          if (m_pOptions->sDisplayFont.isEmpty())
2400                  return;                  return;
2401    
2402          // Realize it.          // Realize it.
2403          QFont font;          QFont font;
2404          if (!font.fromString(m_pOptions->sDisplayFont))          if (!font.fromString(m_pOptions->sDisplayFont))
2405                  return;                  return;
2406    
2407          // Full channel list update...          // Full channel list update...
2408          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2409                    = m_pWorkspace->subWindowList();
2410          if (wlist.isEmpty())          if (wlist.isEmpty())
2411                  return;                  return;
2412    
2413          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2414          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          const int iStripCount = wlist.count();
2415            for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2416                  ChannelStrip *pChannelStrip = NULL;                  ChannelStrip *pChannelStrip = NULL;
2417                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2418                  if (pMdiSubWindow)                  if (pMdiSubWindow)
2419                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2420                  if (pChannelStrip)                  if (pChannelStrip)
# Line 2274  void MainForm::updateDisplayFont (void) Line 2428  void MainForm::updateDisplayFont (void)
2428  void MainForm::updateDisplayEffect (void)  void MainForm::updateDisplayEffect (void)
2429  {  {
2430          // Full channel list update...          // Full channel list update...
2431          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2432                    = m_pWorkspace->subWindowList();
2433          if (wlist.isEmpty())          if (wlist.isEmpty())
2434                  return;                  return;
2435    
2436          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2437          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          const int iStripCount = wlist.count();
2438            for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2439                  ChannelStrip *pChannelStrip = NULL;                  ChannelStrip *pChannelStrip = NULL;
2440                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2441                  if (pMdiSubWindow)                  if (pMdiSubWindow)
2442                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2443                  if (pChannelStrip)                  if (pChannelStrip)
# Line 2305  void MainForm::updateMaxVolume (void) Line 2461  void MainForm::updateMaxVolume (void)
2461  #endif  #endif
2462    
2463          // Full channel list update...          // Full channel list update...
2464          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2465                    = m_pWorkspace->subWindowList();
2466          if (wlist.isEmpty())          if (wlist.isEmpty())
2467                  return;                  return;
2468    
2469          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2470          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          const int iStripCount = wlist.count();
2471            for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2472                  ChannelStrip *pChannelStrip = NULL;                  ChannelStrip *pChannelStrip = NULL;
2473                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2474                  if (pMdiSubWindow)                  if (pMdiSubWindow)
2475                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2476                  if (pChannelStrip)                  if (pChannelStrip)
# Line 2323  void MainForm::updateMaxVolume (void) Line 2481  void MainForm::updateMaxVolume (void)
2481    
2482    
2483  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2484  // qsamplerMainForm -- Messages window form handlers.  // QSampler::MainForm -- Messages window form handlers.
2485    
2486  // Messages output methods.  // Messages output methods.
2487  void MainForm::appendMessages( const QString& s )  void MainForm::appendMessages( const QString& s )
# Line 2348  void MainForm::appendMessagesText( const Line 2506  void MainForm::appendMessagesText( const
2506                  m_pMessages->appendMessagesText(s);                  m_pMessages->appendMessagesText(s);
2507  }  }
2508    
2509  void MainForm::appendMessagesError( const QString& s )  void MainForm::appendMessagesError( const QString& sText )
2510  {  {
2511          if (m_pMessages)          if (m_pMessages)
2512                  m_pMessages->show();                  m_pMessages->show();
2513    
2514          appendMessagesColor(s.simplified(), "#ff0000");          appendMessagesColor(sText.simplified(), "#ff0000");
2515    
2516          // Make it look responsive...:)          // Make it look responsive...:)
2517          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2518    
2519          QMessageBox::critical(this,          if (m_pOptions && m_pOptions->bConfirmError) {
2520                  QSAMPLER_TITLE ": " + tr("Error"), s, QMessageBox::Cancel);                  const QString& sTitle = QSAMPLER_TITLE ": " + tr("Error");
2521            #if 0
2522                    QMessageBox::critical(this, sTitle, sText, QMessageBox::Cancel);
2523            #else
2524                    QMessageBox mbox(this);
2525                    mbox.setIcon(QMessageBox::Critical);
2526                    mbox.setWindowTitle(sTitle);
2527                    mbox.setText(sText);
2528                    mbox.setStandardButtons(QMessageBox::Cancel);
2529                    QCheckBox cbox(tr("Don't show this again"));
2530                    cbox.setChecked(false);
2531                    cbox.blockSignals(true);
2532                    mbox.addButton(&cbox, QMessageBox::ActionRole);
2533                    if (mbox.exec() && cbox.isChecked())
2534                            m_pOptions->bConfirmError = false;
2535            #endif
2536            }
2537  }  }
2538    
2539    
# Line 2419  void MainForm::updateMessagesCapture (vo Line 2593  void MainForm::updateMessagesCapture (vo
2593    
2594    
2595  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2596  // qsamplerMainForm -- MDI channel strip management.  // QSampler::MainForm -- MDI channel strip management.
2597    
2598  // The channel strip creation executive.  // The channel strip creation executive.
2599  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )  ChannelStrip *MainForm::createChannelStrip ( Channel *pChannel )
# Line 2438  ChannelStrip *MainForm::createChannelStr Line 2612  ChannelStrip *MainForm::createChannelStr
2612                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2613                  // We'll need a display font.                  // We'll need a display font.
2614                  QFont font;                  QFont font;
2615                  if (font.fromString(m_pOptions->sDisplayFont))                  if (!m_pOptions->sDisplayFont.isEmpty() &&
2616                            font.fromString(m_pOptions->sDisplayFont))
2617                          pChannelStrip->setDisplayFont(font);                          pChannelStrip->setDisplayFont(font);
2618                  // Maximum allowed volume setting.                  // Maximum allowed volume setting.
2619                  pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                  pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
# Line 2478  void MainForm::destroyChannelStrip ( Cha Line 2653  void MainForm::destroyChannelStrip ( Cha
2653          delete pMdiSubWindow;          delete pMdiSubWindow;
2654    
2655          // Do we auto-arrange?          // Do we auto-arrange?
2656          if (m_pOptions && m_pOptions->bAutoArrange)          channelsArrangeAuto();
                 channelsArrange();  
   
         stabilizeForm();  
2657  }  }
2658    
2659    
# Line 2497  ChannelStrip *MainForm::activeChannelStr Line 2669  ChannelStrip *MainForm::activeChannelStr
2669    
2670    
2671  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2672  ChannelStrip *MainForm::channelStripAt ( int iChannel )  ChannelStrip *MainForm::channelStripAt ( int iStrip )
2673  {  {
2674          if (!m_pWorkspace) return NULL;          if (!m_pWorkspace) return NULL;
2675    
2676          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2677                    = m_pWorkspace->subWindowList();
2678          if (wlist.isEmpty())          if (wlist.isEmpty())
2679                  return NULL;                  return NULL;
2680    
2681          if (iChannel < 0 || iChannel >= wlist.size())          if (iStrip < 0 || iStrip >= wlist.count())
2682                  return NULL;                  return NULL;
2683    
2684          QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2685          if (pMdiSubWindow)          if (pMdiSubWindow)
2686                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());                  return static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2687          else          else
# Line 2519  ChannelStrip *MainForm::channelStripAt ( Line 2692  ChannelStrip *MainForm::channelStripAt (
2692  // Retrieve a channel strip by sampler channel id.  // Retrieve a channel strip by sampler channel id.
2693  ChannelStrip *MainForm::channelStrip ( int iChannelID )  ChannelStrip *MainForm::channelStrip ( int iChannelID )
2694  {  {
2695          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2696                    = m_pWorkspace->subWindowList();
2697          if (wlist.isEmpty())          if (wlist.isEmpty())
2698                  return NULL;                  return NULL;
2699    
2700          for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {          const int iStripCount = wlist.count();
2701            for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2702                  ChannelStrip *pChannelStrip = NULL;                  ChannelStrip *pChannelStrip = NULL;
2703                  QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                  QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2704                  if (pMdiSubWindow)                  if (pMdiSubWindow)
2705                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                          pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2706                  if (pChannelStrip) {                  if (pChannelStrip) {
# Line 2547  void MainForm::channelsMenuAboutToShow ( Line 2722  void MainForm::channelsMenuAboutToShow (
2722          m_ui.channelsMenu->addAction(m_ui.channelsArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsArrangeAction);
2723          m_ui.channelsMenu->addAction(m_ui.channelsAutoArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsAutoArrangeAction);
2724    
2725          QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();          const QList<QMdiSubWindow *>& wlist
2726                    = m_pWorkspace->subWindowList();
2727          if (!wlist.isEmpty()) {          if (!wlist.isEmpty()) {
2728                  m_ui.channelsMenu->addSeparator();                  m_ui.channelsMenu->addSeparator();
2729                  for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {                  const int iStripCount = wlist.count();
2730                    for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2731                          ChannelStrip *pChannelStrip = NULL;                          ChannelStrip *pChannelStrip = NULL;
2732                          QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2733                          if (pMdiSubWindow)                          if (pMdiSubWindow)
2734                                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2735                          if (pChannelStrip) {                          if (pChannelStrip) {
# Line 2561  void MainForm::channelsMenuAboutToShow ( Line 2738  void MainForm::channelsMenuAboutToShow (
2738                                          this, SLOT(channelsMenuActivated()));                                          this, SLOT(channelsMenuActivated()));
2739                                  pAction->setCheckable(true);                                  pAction->setCheckable(true);
2740                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);
2741                                  pAction->setData(iChannel);                                  pAction->setData(iStrip);
2742                          }                          }
2743                  }                  }
2744          }          }
# Line 2585  void MainForm::channelsMenuActivated (vo Line 2762  void MainForm::channelsMenuActivated (vo
2762    
2763    
2764  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2765  // qsamplerMainForm -- Timer stuff.  // QSampler::MainForm -- Timer stuff.
2766    
2767  // Set the pseudo-timer delay schedule.  // Set the pseudo-timer delay schedule.
2768  void MainForm::startSchedule ( int iStartDelay )  void MainForm::startSchedule ( int iStartDelay )
# Line 2626  void MainForm::timerSlot (void) Line 2803  void MainForm::timerSlot (void)
2803                          ChannelStrip *pChannelStrip = iter.next();                          ChannelStrip *pChannelStrip = iter.next();
2804                          // If successfull, remove from pending list...                          // If successfull, remove from pending list...
2805                          if (pChannelStrip->updateChannelInfo()) {                          if (pChannelStrip->updateChannelInfo()) {
2806                                  int iChannelStrip = m_changedStrips.indexOf(pChannelStrip);                                  const int iChannelStrip = m_changedStrips.indexOf(pChannelStrip);
2807                                  if (iChannelStrip >= 0)                                  if (iChannelStrip >= 0)
2808                                          m_changedStrips.removeAt(iChannelStrip);                                          m_changedStrips.removeAt(iChannelStrip);
2809                          }                          }
# Line 2637  void MainForm::timerSlot (void) Line 2814  void MainForm::timerSlot (void)
2814                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {
2815                                  m_iTimerSlot = 0;                                  m_iTimerSlot = 0;
2816                                  // Update the channel stream usage for each strip...                                  // Update the channel stream usage for each strip...
2817                                  QList<QMdiSubWindow *> wlist = m_pWorkspace->subWindowList();                                  const QList<QMdiSubWindow *>& wlist
2818                                  for (int iChannel = 0; iChannel < (int) wlist.count(); ++iChannel) {                                          = m_pWorkspace->subWindowList();
2819                                    const int iStripCount = wlist.count();
2820                                    for (int iStrip = 0; iStrip < iStripCount; ++iStrip) {
2821                                          ChannelStrip *pChannelStrip = NULL;                                          ChannelStrip *pChannelStrip = NULL;
2822                                          QMdiSubWindow *pMdiSubWindow = wlist.at(iChannel);                                          QMdiSubWindow *pMdiSubWindow = wlist.at(iStrip);
2823                                          if (pMdiSubWindow)                                          if (pMdiSubWindow)
2824                                                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());                                                  pChannelStrip = static_cast<ChannelStrip *> (pMdiSubWindow->widget());
2825                                          if (pChannelStrip && pChannelStrip->isVisible())                                          if (pChannelStrip && pChannelStrip->isVisible())
# Line 2656  void MainForm::timerSlot (void) Line 2835  void MainForm::timerSlot (void)
2835    
2836    
2837  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
2838  // qsamplerMainForm -- Server stuff.  // QSampler::MainForm -- Server stuff.
2839    
2840  // Start linuxsampler server...  // Start linuxsampler server...
2841  void MainForm::startServer (void)  void MainForm::startServer (void)
# Line 2690  void MainForm::startServer (void) Line 2869  void MainForm::startServer (void)
2869    
2870          // OK. Let's build the startup process...          // OK. Let's build the startup process...
2871          m_pServer = new QProcess();          m_pServer = new QProcess();
2872          bForceServerStop = true;          m_bForceServerStop = true;
2873    
2874          // Setup stdout/stderr capture...          // Setup stdout/stderr capture...
2875  //      if (m_pOptions->bStdoutCapture) {          m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);
2876                  m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);          QObject::connect(m_pServer,
2877                  QObject::connect(m_pServer,                  SIGNAL(readyReadStandardOutput()),
2878                          SIGNAL(readyReadStandardOutput()),                  SLOT(readServerStdout()));
2879                          SLOT(readServerStdout()));          QObject::connect(m_pServer,
2880                  QObject::connect(m_pServer,                  SIGNAL(readyReadStandardError()),
2881                          SIGNAL(readyReadStandardError()),                  SLOT(readServerStdout()));
                         SLOT(readServerStdout()));  
 //      }  
2882    
2883          // The unforgiveable signal communication...          // The unforgiveable signal communication...
2884          QObject::connect(m_pServer,          QObject::connect(m_pServer,
# Line 2736  void MainForm::startServer (void) Line 2913  void MainForm::startServer (void)
2913    
2914    
2915  // Stop linuxsampler server...  // Stop linuxsampler server...
2916  void MainForm::stopServer (bool bInteractive)  void MainForm::stopServer ( bool bInteractive )
2917  {  {
2918          // Stop client code.          // Stop client code.
2919          stopClient();          stopClient();
# Line 2750  void MainForm::stopServer (bool bInterac Line 2927  void MainForm::stopServer (bool bInterac
2927                          "sampler session at any time by relaunching QSampler.\n\n"                          "sampler session at any time by relaunching QSampler.\n\n"
2928                          "Do you want LinuxSampler to stop?"),                          "Do you want LinuxSampler to stop?"),
2929                          QMessageBox::Yes | QMessageBox::No,                          QMessageBox::Yes | QMessageBox::No,
2930                          QMessageBox::Yes) == QMessageBox::No)                          QMessageBox::Yes) == QMessageBox::No) {
2931                  {                          m_bForceServerStop = false;
                         bForceServerStop = false;  
2932                  }                  }
2933          }          }
2934    
2935            bool bGraceWait = true;
2936    
2937          // And try to stop server.          // And try to stop server.
2938          if (m_pServer && bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2939                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2940                  if (m_pServer->state() == QProcess::Running) {                  if (m_pServer->state() == QProcess::Running) {
2941                  #if defined(WIN32)                  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
2942                          // Try harder...                          // Try harder...
2943                          m_pServer->kill();                          m_pServer->kill();
2944                  #else                  #else
2945                          // Try softly...                          // Try softly...
2946                          m_pServer->terminate();                          m_pServer->terminate();
2947                            bool bFinished = m_pServer->waitForFinished(QSAMPLER_TIMER_MSECS * 1000);
2948                            if (bFinished) bGraceWait = false;
2949                  #endif                  #endif
2950                  }                  }
2951          }       // Do final processing anyway.          }       // Do final processing anyway.
2952          else processServerExit();          else processServerExit();
2953    
2954          // Give it some time to terminate gracefully and stabilize...          // Give it some time to terminate gracefully and stabilize...
2955          QTime t;          if (bGraceWait) {
2956          t.start();                  QTime t;
2957          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                  t.start();
2958                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2959                            QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2960            }
2961  }  }
2962    
2963    
# Line 2797  void MainForm::processServerExit (void) Line 2979  void MainForm::processServerExit (void)
2979          if (m_pMessages)          if (m_pMessages)
2980                  m_pMessages->flushStdoutBuffer();                  m_pMessages->flushStdoutBuffer();
2981    
2982          if (m_pServer && bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2983                  if (m_pServer->state() != QProcess::NotRunning) {                  if (m_pServer->state() != QProcess::NotRunning) {
2984                          appendMessages(tr("Server is being forced..."));                          appendMessages(tr("Server is being forced..."));
2985                          // Force final server shutdown...                          // Force final server shutdown...
# Line 2822  void MainForm::processServerExit (void) Line 3004  void MainForm::processServerExit (void)
3004    
3005    
3006  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
3007  // qsamplerMainForm -- Client stuff.  // QSampler::MainForm -- Client stuff.
3008    
3009  // The LSCP client callback procedure.  // The LSCP client callback procedure.
3010  lscp_status_t qsampler_client_callback ( lscp_client_t */*pClient*/,  lscp_status_t qsampler_client_callback ( lscp_client_t */*pClient*/,
# Line 2874  bool MainForm::startClient (void) Line 3056  bool MainForm::startClient (void)
3056                  stabilizeForm();                  stabilizeForm();
3057                  return false;                  return false;
3058          }          }
3059    
3060          // Just set receive timeout value, blindly.          // Just set receive timeout value, blindly.
3061          ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);          ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
3062          appendMessages(          appendMessages(

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

  ViewVC Help
Powered by ViewVC