/[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 1507 by capela, Wed Nov 21 23:22:18 2007 UTC revision 1509 by capela, Thu Nov 22 11:10:44 2007 UTC
# Line 102  class qsamplerCustomEvent : public QEven Line 102  class qsamplerCustomEvent : public QEven
102  {  {
103  public:  public:
104    
105      // Constructor.          // Constructor.
106      qsamplerCustomEvent(lscp_event_t event, const char *pchData, int cchData)          qsamplerCustomEvent(lscp_event_t event, const char *pchData, int cchData)
107          : QEvent(QSAMPLER_CUSTOM_EVENT)                  : QEvent(QSAMPLER_CUSTOM_EVENT)
108      {          {
109          m_event = event;                  m_event = event;
110          m_data  = QString::fromUtf8(pchData, cchData);                  m_data  = QString::fromUtf8(pchData, cchData);
111      }          }
112    
113      // Accessors.          // Accessors.
114      lscp_event_t event() { return m_event; }          lscp_event_t event() { return m_event; }
115      QString&     data()  { return m_data;  }          QString&     data()  { return m_data;  }
116    
117  private:  private:
118    
119      // The proper event type.          // The proper event type.
120      lscp_event_t m_event;          lscp_event_t m_event;
121      // The event data as a string.          // The event data as a string.
122      QString      m_data;          QString      m_data;
123  };  };
124    
125    
# Line 131  namespace QSampler { Line 131  namespace QSampler {
131  // Kind of singleton reference.  // Kind of singleton reference.
132  MainForm* MainForm::g_pMainForm = NULL;  MainForm* MainForm::g_pMainForm = NULL;
133    
134  MainForm::MainForm(QWidget* parent) : QMainWindow(parent) {  MainForm::MainForm ( QWidget *pParent )
135      ui.setupUi(this);          : QMainWindow(pParent)
136    {
137            m_ui.setupUi(this);
138    
139          // Pseudo-singleton reference setup.          // Pseudo-singleton reference setup.
140          g_pMainForm = this;          g_pMainForm = this;
141    
142      // Initialize some pointer references.          // Initialize some pointer references.
143      m_pOptions = NULL;          m_pOptions = NULL;
144    
145      // All child forms are to be created later, not earlier than setup.          // All child forms are to be created later, not earlier than setup.
146      m_pMessages = NULL;          m_pMessages = NULL;
147      m_pInstrumentListForm = NULL;          m_pInstrumentListForm = NULL;
148      m_pDeviceForm = NULL;          m_pDeviceForm = NULL;
149    
150      // We'll start clean.          // We'll start clean.
151      m_iUntitled   = 0;          m_iUntitled   = 0;
152      m_iDirtyCount = 0;          m_iDirtyCount = 0;
153    
154      m_pServer = NULL;          m_pServer = NULL;
155      m_pClient = NULL;          m_pClient = NULL;
156    
157      m_iStartDelay = 0;          m_iStartDelay = 0;
158      m_iTimerDelay = 0;          m_iTimerDelay = 0;
159    
160      m_iTimerSlot = 0;          m_iTimerSlot = 0;
161    
162  #ifdef HAVE_SIGNAL_H  #ifdef HAVE_SIGNAL_H
163          // Set to ignore any fatal "Broken pipe" signals.          // Set to ignore any fatal "Broken pipe" signals.
# Line 163  MainForm::MainForm(QWidget* parent) : QM Line 165  MainForm::MainForm(QWidget* parent) : QM
165  #endif  #endif
166    
167  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
168      // Make some extras into the toolbar...          // Make some extras into the toolbar...
169          const QString& sVolumeText = tr("Master volume");          const QString& sVolumeText = tr("Master volume");
170          m_iVolumeChanging = 0;          m_iVolumeChanging = 0;
171          // Volume slider...          // Volume slider...
172          ui.channelsToolbar->addSeparator();          m_ui.channelsToolbar->addSeparator();
173          m_pVolumeSlider = new QSlider(Qt::Horizontal, ui.channelsToolbar);          m_pVolumeSlider = new QSlider(Qt::Horizontal, m_ui.channelsToolbar);
174          m_pVolumeSlider->setTickPosition(QSlider::TicksBelow);          m_pVolumeSlider->setTickPosition(QSlider::TicksBelow);
175          m_pVolumeSlider->setTickInterval(10);          m_pVolumeSlider->setTickInterval(10);
176          m_pVolumeSlider->setPageStep(10);          m_pVolumeSlider->setPageStep(10);
# Line 181  MainForm::MainForm(QWidget* parent) : QM Line 183  MainForm::MainForm(QWidget* parent) : QM
183          QObject::connect(m_pVolumeSlider,          QObject::connect(m_pVolumeSlider,
184                  SIGNAL(valueChanged(int)),                  SIGNAL(valueChanged(int)),
185                  SLOT(volumeChanged(int)));                  SLOT(volumeChanged(int)));
186          //ui.channelsToolbar->setHorizontallyStretchable(true);          //m_ui.channelsToolbar->setHorizontallyStretchable(true);
187          //ui.channelsToolbar->setStretchableWidget(m_pVolumeSlider);          //m_ui.channelsToolbar->setStretchableWidget(m_pVolumeSlider);
188      ui.channelsToolbar->addWidget(m_pVolumeSlider);          m_ui.channelsToolbar->addWidget(m_pVolumeSlider);
189          // Volume spin-box          // Volume spin-box
190          ui.channelsToolbar->addSeparator();          m_ui.channelsToolbar->addSeparator();
191          m_pVolumeSpinBox = new QSpinBox(ui.channelsToolbar);          m_pVolumeSpinBox = new QSpinBox(m_ui.channelsToolbar);
192          m_pVolumeSpinBox->setSuffix(" %");          m_pVolumeSpinBox->setSuffix(" %");
193          m_pVolumeSpinBox->setMinimum(0);          m_pVolumeSpinBox->setMinimum(0);
194          m_pVolumeSpinBox->setMaximum(100);          m_pVolumeSpinBox->setMaximum(100);
# Line 194  MainForm::MainForm(QWidget* parent) : QM Line 196  MainForm::MainForm(QWidget* parent) : QM
196          QObject::connect(m_pVolumeSpinBox,          QObject::connect(m_pVolumeSpinBox,
197                  SIGNAL(valueChanged(int)),                  SIGNAL(valueChanged(int)),
198                  SLOT(volumeChanged(int)));                  SLOT(volumeChanged(int)));
199      ui.channelsToolbar->addWidget(m_pVolumeSpinBox);          m_ui.channelsToolbar->addWidget(m_pVolumeSpinBox);
200  #endif  #endif
201    
202      // Make it an MDI workspace.          // Make it an MDI workspace.
203      m_pWorkspace = new QWorkspace(this);          m_pWorkspace = new QWorkspace(this);
204      m_pWorkspace->setScrollBarsEnabled(true);          m_pWorkspace->setScrollBarsEnabled(true);
205          // Set the activation connection.          // Set the activation connection.
206          QObject::connect(m_pWorkspace,          QObject::connect(m_pWorkspace,
207                  SIGNAL(windowActivated(QWidget *)),                  SIGNAL(windowActivated(QWidget *)),
208                  SLOT(stabilizeForm()));                  SLOT(stabilizeForm()));
209      // Make it shine :-)          // Make it shine :-)
210      setCentralWidget(m_pWorkspace);          setCentralWidget(m_pWorkspace);
211    
212      // Create some statusbar labels...          // Create some statusbar labels...
213      QLabel *pLabel;          QLabel *pLabel;
214      // Client status.          // Client status.
215      pLabel = new QLabel(tr("Connected"), this);          pLabel = new QLabel(tr("Connected"), this);
216      pLabel->setAlignment(Qt::AlignLeft);          pLabel->setAlignment(Qt::AlignLeft);
217      pLabel->setMinimumSize(pLabel->sizeHint());          pLabel->setMinimumSize(pLabel->sizeHint());
218      m_statusItem[QSAMPLER_STATUS_CLIENT] = pLabel;          m_statusItem[QSAMPLER_STATUS_CLIENT] = pLabel;
219      statusBar()->addWidget(pLabel);          statusBar()->addWidget(pLabel);
220      // Server address.          // Server address.
221      pLabel = new QLabel(this);          pLabel = new QLabel(this);
222      pLabel->setAlignment(Qt::AlignLeft);          pLabel->setAlignment(Qt::AlignLeft);
223      m_statusItem[QSAMPLER_STATUS_SERVER] = pLabel;          m_statusItem[QSAMPLER_STATUS_SERVER] = pLabel;
224      statusBar()->addWidget(pLabel, 1);          statusBar()->addWidget(pLabel, 1);
225      // Channel title.          // Channel title.
226      pLabel = new QLabel(this);          pLabel = new QLabel(this);
227      pLabel->setAlignment(Qt::AlignLeft);          pLabel->setAlignment(Qt::AlignLeft);
228      m_statusItem[QSAMPLER_STATUS_CHANNEL] = pLabel;          m_statusItem[QSAMPLER_STATUS_CHANNEL] = pLabel;
229      statusBar()->addWidget(pLabel, 2);          statusBar()->addWidget(pLabel, 2);
230      // Session modification status.          // Session modification status.
231      pLabel = new QLabel(tr("MOD"), this);          pLabel = new QLabel(tr("MOD"), this);
232      pLabel->setAlignment(Qt::AlignHCenter);          pLabel->setAlignment(Qt::AlignHCenter);
233      pLabel->setMinimumSize(pLabel->sizeHint());          pLabel->setMinimumSize(pLabel->sizeHint());
234      m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
235      statusBar()->addWidget(pLabel);          statusBar()->addWidget(pLabel);
236    
237  #if defined(WIN32)  #if defined(WIN32)
238      WSAStartup(MAKEWORD(1, 1), &_wsaData);          WSAStartup(MAKEWORD(1, 1), &_wsaData);
239  #endif  #endif
240    
241          QObject::connect(ui.fileNewAction,          QObject::connect(m_ui.fileNewAction,
242                  SIGNAL(triggered()),                  SIGNAL(triggered()),
243                  SLOT(fileNew()));                  SLOT(fileNew()));
244          QObject::connect(ui.fileOpenAction,          QObject::connect(m_ui.fileOpenAction,
245                  SIGNAL(triggered()),                  SIGNAL(triggered()),
246                  SLOT(fileOpen()));                  SLOT(fileOpen()));
247          QObject::connect(ui.fileSaveAction,          QObject::connect(m_ui.fileSaveAction,
248                  SIGNAL(triggered()),                  SIGNAL(triggered()),
249                  SLOT(fileSave()));                  SLOT(fileSave()));
250          QObject::connect(ui.fileSaveAsAction,          QObject::connect(m_ui.fileSaveAsAction,
251                  SIGNAL(triggered()),                  SIGNAL(triggered()),
252                  SLOT(fileSaveAs()));                  SLOT(fileSaveAs()));
253          QObject::connect(ui.fileResetAction,          QObject::connect(m_ui.fileResetAction,
254                  SIGNAL(triggered()),                  SIGNAL(triggered()),
255                  SLOT(fileReset()));                  SLOT(fileReset()));
256          QObject::connect(ui.fileRestartAction,          QObject::connect(m_ui.fileRestartAction,
257                  SIGNAL(triggered()),                  SIGNAL(triggered()),
258                  SLOT(fileRestart()));                  SLOT(fileRestart()));
259          QObject::connect(ui.fileExitAction,          QObject::connect(m_ui.fileExitAction,
260                  SIGNAL(triggered()),                  SIGNAL(triggered()),
261                  SLOT(fileExit()));                  SLOT(fileExit()));
262          QObject::connect(ui.editAddChannelAction,          QObject::connect(m_ui.editAddChannelAction,
263                  SIGNAL(triggered()),                  SIGNAL(triggered()),
264                  SLOT(editAddChannel()));                  SLOT(editAddChannel()));
265          QObject::connect(ui.editRemoveChannelAction,          QObject::connect(m_ui.editRemoveChannelAction,
266                  SIGNAL(triggered()),                  SIGNAL(triggered()),
267                  SLOT(editRemoveChannel()));                  SLOT(editRemoveChannel()));
268          QObject::connect(ui.editSetupChannelAction,          QObject::connect(m_ui.editSetupChannelAction,
269                  SIGNAL(triggered()),                  SIGNAL(triggered()),
270                  SLOT(editSetupChannel()));                  SLOT(editSetupChannel()));
271          QObject::connect(ui.editEditChannelAction,          QObject::connect(m_ui.editEditChannelAction,
272                  SIGNAL(triggered()),                  SIGNAL(triggered()),
273                  SLOT(editEditChannel()));                  SLOT(editEditChannel()));
274          QObject::connect(ui.editResetChannelAction,          QObject::connect(m_ui.editResetChannelAction,
275                  SIGNAL(triggered()),                  SIGNAL(triggered()),
276                  SLOT(editResetChannel()));                  SLOT(editResetChannel()));
277          QObject::connect(ui.editResetAllChannelsAction,          QObject::connect(m_ui.editResetAllChannelsAction,
278                  SIGNAL(triggered()),                  SIGNAL(triggered()),
279                  SLOT(editResetAllChannels()));                  SLOT(editResetAllChannels()));
280          QObject::connect(ui.viewMenubarAction,          QObject::connect(m_ui.viewMenubarAction,
281                  SIGNAL(toggled(bool)),                  SIGNAL(toggled(bool)),
282                  SLOT(viewMenubar(bool)));                  SLOT(viewMenubar(bool)));
283          QObject::connect(ui.viewToolbarAction,          QObject::connect(m_ui.viewToolbarAction,
284                  SIGNAL(toggled(bool)),                  SIGNAL(toggled(bool)),
285                  SLOT(viewToolbar(bool)));                  SLOT(viewToolbar(bool)));
286          QObject::connect(ui.viewStatusbarAction,          QObject::connect(m_ui.viewStatusbarAction,
287                  SIGNAL(toggled(bool)),                  SIGNAL(toggled(bool)),
288                  SLOT(viewStatusbar(bool)));                  SLOT(viewStatusbar(bool)));
289          QObject::connect(ui.viewMessagesAction,          QObject::connect(m_ui.viewMessagesAction,
290                  SIGNAL(toggled(bool)),                  SIGNAL(toggled(bool)),
291                  SLOT(viewMessages(bool)));                  SLOT(viewMessages(bool)));
292          QObject::connect(ui.viewInstrumentsAction,          QObject::connect(m_ui.viewInstrumentsAction,
293                  SIGNAL(triggered()),                  SIGNAL(triggered()),
294                  SLOT(viewInstruments()));                  SLOT(viewInstruments()));
295          QObject::connect(ui.viewDevicesAction,          QObject::connect(m_ui.viewDevicesAction,
296                  SIGNAL(triggered()),                  SIGNAL(triggered()),
297                  SLOT(viewDevices()));                  SLOT(viewDevices()));
298          QObject::connect(ui.viewOptionsAction,          QObject::connect(m_ui.viewOptionsAction,
299                  SIGNAL(triggered()),                  SIGNAL(triggered()),
300                  SLOT(viewOptions()));                  SLOT(viewOptions()));
301          QObject::connect(ui.channelsArrangeAction,          QObject::connect(m_ui.channelsArrangeAction,
302                  SIGNAL(triggered()),                  SIGNAL(triggered()),
303                  SLOT(channelsArrange()));                  SLOT(channelsArrange()));
304          QObject::connect(ui.channelsAutoArrangeAction,          QObject::connect(m_ui.channelsAutoArrangeAction,
305                  SIGNAL(toggled(bool)),                  SIGNAL(toggled(bool)),
306                  SLOT(channelsAutoArrange(bool)));                  SLOT(channelsAutoArrange(bool)));
307          QObject::connect(ui.helpAboutAction,          QObject::connect(m_ui.helpAboutAction,
308                  SIGNAL(triggered()),                  SIGNAL(triggered()),
309                  SLOT(helpAbout()));                  SLOT(helpAbout()));
310          QObject::connect(ui.helpAboutQtAction,          QObject::connect(m_ui.helpAboutQtAction,
311                  SIGNAL(triggered()),                  SIGNAL(triggered()),
312                  SLOT(helpAboutQt()));                  SLOT(helpAboutQt()));
313    
314          QObject::connect(ui.fileMenu,          QObject::connect(m_ui.fileMenu,
315                  SIGNAL(aboutToShow()),                  SIGNAL(aboutToShow()),
316                  SLOT(updateRecentFilesMenu()));                  SLOT(updateRecentFilesMenu()));
317          QObject::connect(ui.channelsMenu,          QObject::connect(m_ui.channelsMenu,
318                  SIGNAL(aboutToShow()),                  SIGNAL(aboutToShow()),
319                  SLOT(channelsMenuAboutToShow()));                  SLOT(channelsMenuAboutToShow()));
320  }  }
# Line 320  MainForm::MainForm(QWidget* parent) : QM Line 322  MainForm::MainForm(QWidget* parent) : QM
322  // Destructor.  // Destructor.
323  MainForm::~MainForm()  MainForm::~MainForm()
324  {  {
325      // Do final processing anyway.          // Do final processing anyway.
326      processServerExit();          processServerExit();
327    
328  #if defined(WIN32)  #if defined(WIN32)
329      WSACleanup();          WSACleanup();
330  #endif  #endif
331    
332      // Finally drop any widgets around...          // Finally drop any widgets around...
333      if (m_pDeviceForm)          if (m_pDeviceForm)
334          delete m_pDeviceForm;                  delete m_pDeviceForm;
335      if (m_pInstrumentListForm)          if (m_pInstrumentListForm)
336          delete m_pInstrumentListForm;                  delete m_pInstrumentListForm;
337      if (m_pMessages)          if (m_pMessages)
338          delete m_pMessages;                  delete m_pMessages;
339      if (m_pWorkspace)          if (m_pWorkspace)
340          delete m_pWorkspace;                  delete m_pWorkspace;
341    
342      // Delete status item labels one by one.          // Delete status item labels one by one.
343      if (m_statusItem[QSAMPLER_STATUS_CLIENT])          if (m_statusItem[QSAMPLER_STATUS_CLIENT])
344          delete m_statusItem[QSAMPLER_STATUS_CLIENT];                  delete m_statusItem[QSAMPLER_STATUS_CLIENT];
345      if (m_statusItem[QSAMPLER_STATUS_SERVER])          if (m_statusItem[QSAMPLER_STATUS_SERVER])
346          delete m_statusItem[QSAMPLER_STATUS_SERVER];                  delete m_statusItem[QSAMPLER_STATUS_SERVER];
347      if (m_statusItem[QSAMPLER_STATUS_CHANNEL])          if (m_statusItem[QSAMPLER_STATUS_CHANNEL])
348          delete m_statusItem[QSAMPLER_STATUS_CHANNEL];                  delete m_statusItem[QSAMPLER_STATUS_CHANNEL];
349      if (m_statusItem[QSAMPLER_STATUS_SESSION])          if (m_statusItem[QSAMPLER_STATUS_SESSION])
350          delete m_statusItem[QSAMPLER_STATUS_SESSION];                  delete m_statusItem[QSAMPLER_STATUS_SESSION];
351    
352  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
353          delete m_pVolumeSpinBox;          delete m_pVolumeSpinBox;
# Line 360  MainForm::~MainForm() Line 362  MainForm::~MainForm()
362  // Make and set a proper setup options step.  // Make and set a proper setup options step.
363  void MainForm::setup ( qsamplerOptions *pOptions )  void MainForm::setup ( qsamplerOptions *pOptions )
364  {  {
365      // We got options?          // We got options?
366      m_pOptions = pOptions;          m_pOptions = pOptions;
367    
368      // What style do we create these forms?          // What style do we create these forms?
369          Qt::WindowFlags wflags = Qt::Window          Qt::WindowFlags wflags = Qt::Window
370  #if QT_VERSION >= 0x040200  #if QT_VERSION >= 0x040200
371                  | Qt::CustomizeWindowHint                  | Qt::CustomizeWindowHint
# Line 373  void MainForm::setup ( qsamplerOptions * Line 375  void MainForm::setup ( qsamplerOptions *
375                  | Qt::WindowMinMaxButtonsHint;                  | Qt::WindowMinMaxButtonsHint;
376          if (m_pOptions->bKeepOnTop)          if (m_pOptions->bKeepOnTop)
377                  wflags |= Qt::Tool;                  wflags |= Qt::Tool;
378      // Some child forms are to be created right now.          // Some child forms are to be created right now.
379      m_pMessages = new qsamplerMessages(this);          m_pMessages = new qsamplerMessages(this);
380      m_pDeviceForm = new DeviceForm(this, wflags);          m_pDeviceForm = new DeviceForm(this, wflags);
381  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
382      m_pInstrumentListForm = new InstrumentListForm(this, wflags);          m_pInstrumentListForm = new InstrumentListForm(this, wflags);
         QObject::connect(&m_pInstrumentListForm->model,  
                 SIGNAL(instrumentsChanged()),  
                 SLOT(sessionDirty()));  
383  #else  #else
384          viewInstrumentsAction->setEnabled(false);          viewInstrumentsAction->setEnabled(false);
385  #endif  #endif
386      // Set message defaults...          // Set message defaults...
387      updateMessagesFont();          updateMessagesFont();
388      updateMessagesLimit();          updateMessagesLimit();
389      updateMessagesCapture();          updateMessagesCapture();
390      // Set the visibility signal.          // Set the visibility signal.
391          QObject::connect(m_pMessages,          QObject::connect(m_pMessages,
392                  SIGNAL(visibilityChanged(bool)),                  SIGNAL(visibilityChanged(bool)),
393                  SLOT(stabilizeForm()));                  SLOT(stabilizeForm()));
394    
395      // Initial decorations toggle state.          // Initial decorations toggle state.
396      ui.viewMenubarAction->setChecked(m_pOptions->bMenubar);          m_ui.viewMenubarAction->setChecked(m_pOptions->bMenubar);
397      ui.viewToolbarAction->setChecked(m_pOptions->bToolbar);          m_ui.viewToolbarAction->setChecked(m_pOptions->bToolbar);
398      ui.viewStatusbarAction->setChecked(m_pOptions->bStatusbar);          m_ui.viewStatusbarAction->setChecked(m_pOptions->bStatusbar);
399      ui.channelsAutoArrangeAction->setChecked(m_pOptions->bAutoArrange);          m_ui.channelsAutoArrangeAction->setChecked(m_pOptions->bAutoArrange);
400    
401      // Initial decorations visibility state.          // Initial decorations visibility state.
402      viewMenubar(m_pOptions->bMenubar);          viewMenubar(m_pOptions->bMenubar);
403      viewToolbar(m_pOptions->bToolbar);          viewToolbar(m_pOptions->bToolbar);
404      viewStatusbar(m_pOptions->bStatusbar);          viewStatusbar(m_pOptions->bStatusbar);
405    
406      addDockWidget(Qt::BottomDockWidgetArea, m_pMessages);          addDockWidget(Qt::BottomDockWidgetArea, m_pMessages);
407    
408          // Restore whole dock windows state.          // Restore whole dock windows state.
409          QByteArray aDockables = m_pOptions->settings().value(          QByteArray aDockables = m_pOptions->settings().value(
# Line 413  void MainForm::setup ( qsamplerOptions * Line 412  void MainForm::setup ( qsamplerOptions *
412                  restoreState(aDockables);                  restoreState(aDockables);
413          }          }
414    
415      // Try to restore old window positioning and initial visibility.          // Try to restore old window positioning and initial visibility.
416      m_pOptions->loadWidgetGeometry(this);          m_pOptions->loadWidgetGeometry(this);
417      m_pOptions->loadWidgetGeometry(m_pInstrumentListForm);          m_pOptions->loadWidgetGeometry(m_pInstrumentListForm);
418      m_pOptions->loadWidgetGeometry(m_pDeviceForm);          m_pOptions->loadWidgetGeometry(m_pDeviceForm);
419    
420      // Final startup stabilization...          // Final startup stabilization...
421      updateMaxVolume();          updateMaxVolume();
422      updateRecentFilesMenu();          updateRecentFilesMenu();
423      stabilizeForm();          stabilizeForm();
424    
425      // Make it ready :-)          // Make it ready :-)
426      statusBar()->showMessage(tr("Ready"), 3000);          statusBar()->showMessage(tr("Ready"), 3000);
427    
428      // We'll try to start immediately...          // We'll try to start immediately...
429      startSchedule(0);          startSchedule(0);
430    
431      // Register the first timer slot.          // Register the first timer slot.
432      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));          QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));
433  }  }
434    
435    
436  // Window close event handlers.  // Window close event handlers.
437  bool MainForm::queryClose (void)  bool MainForm::queryClose (void)
438  {  {
439      bool bQueryClose = closeSession(false);          bool bQueryClose = closeSession(false);
440    
441      // Try to save current general state...          // Try to save current general state...
442      if (m_pOptions) {          if (m_pOptions) {
443          // Some windows default fonts is here on demand too.                  // Some windows default fonts is here on demand too.
444          if (bQueryClose && m_pMessages)                  if (bQueryClose && m_pMessages)
445              m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();
446          // Try to save current positioning.                  // Try to save current positioning.
447          if (bQueryClose) {                  if (bQueryClose) {
448              // Save decorations state.                          // Save decorations state.
449              m_pOptions->bMenubar = ui.MenuBar->isVisible();                          m_pOptions->bMenubar = m_ui.MenuBar->isVisible();
450              m_pOptions->bToolbar = (ui.fileToolbar->isVisible() || ui.editToolbar->isVisible() || ui.channelsToolbar->isVisible());                          m_pOptions->bToolbar = (m_ui.fileToolbar->isVisible()
451              m_pOptions->bStatusbar = statusBar()->isVisible();                                  || m_ui.editToolbar->isVisible()
452              // Save the dock windows state.                                  || m_ui.channelsToolbar->isVisible());
453              const QString sDockables = saveState().toBase64().data();                          m_pOptions->bStatusbar = statusBar()->isVisible();
454                            // Save the dock windows state.
455                            const QString sDockables = saveState().toBase64().data();
456                          m_pOptions->settings().setValue("/Layout/DockWindows", saveState());                          m_pOptions->settings().setValue("/Layout/DockWindows", saveState());
457              // And the children, and the main windows state,.                          // And the children, and the main windows state,.
458                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);
459                          m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);                          m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
460                          m_pOptions->saveWidgetGeometry(this);                          m_pOptions->saveWidgetGeometry(this);
# Line 462  bool MainForm::queryClose (void) Line 463  bool MainForm::queryClose (void)
463                                  m_pInstrumentListForm->close();                                  m_pInstrumentListForm->close();
464                          if (m_pDeviceForm)                          if (m_pDeviceForm)
465                                  m_pDeviceForm->close();                                  m_pDeviceForm->close();
466              // Stop client and/or server, gracefully.                          // Stop client and/or server, gracefully.
467              stopServer();                          stopServer();
468          }                  }
469      }          }
470    
471      return bQueryClose;          return bQueryClose;
472  }  }
473    
474    
475  void MainForm::closeEvent ( QCloseEvent *pCloseEvent )  void MainForm::closeEvent ( QCloseEvent *pCloseEvent )
476  {  {
477      if (queryClose())          if (queryClose())
478          pCloseEvent->accept();                  pCloseEvent->accept();
479      else          else
480          pCloseEvent->ignore();                  pCloseEvent->ignore();
481  }  }
482    
483    
# Line 540  void MainForm::dropEvent ( QDropEvent* p Line 541  void MainForm::dropEvent ( QDropEvent* p
541  // Custome event handler.  // Custome event handler.
542  void MainForm::customEvent(QEvent* pCustomEvent)  void MainForm::customEvent(QEvent* pCustomEvent)
543  {  {
544      // For the time being, just pump it to messages.          // For the time being, just pump it to messages.
545      if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {          if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {
546          qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;                  qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;
547                  if (pEvent->event() == LSCP_EVENT_CHANNEL_INFO) {                  if (pEvent->event() == LSCP_EVENT_CHANNEL_INFO) {
548                          int iChannelID = pEvent->data().toInt();                          int iChannelID = pEvent->data().toInt();
549                          ChannelStrip *pChannelStrip = channelStrip(iChannelID);                          ChannelStrip *pChannelStrip = channelStrip(iChannelID);
# Line 553  void MainForm::customEvent(QEvent* pCust Line 554  void MainForm::customEvent(QEvent* pCust
554                                  .arg(::lscp_event_to_text(pEvent->event()))                                  .arg(::lscp_event_to_text(pEvent->event()))
555                                  .arg(pEvent->data()), "#996699");                                  .arg(pEvent->data()), "#996699");
556                  }                  }
557      }          }
558  }  }
559    
560  // Context menu event handler.  // Context menu event handler.
561  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )
562  {  {
563      stabilizeForm();          stabilizeForm();
564    
565      ui.editMenu->exec(pEvent->globalPos());          m_ui.editMenu->exec(pEvent->globalPos());
566  }  }
567    
568    
# Line 569  void MainForm::contextMenuEvent( QContex Line 570  void MainForm::contextMenuEvent( QContex
570  // qsamplerMainForm -- Brainless public property accessors.  // qsamplerMainForm -- Brainless public property accessors.
571    
572  // The global options settings property.  // The global options settings property.
573  qsamplerOptions *MainForm::options (void)  qsamplerOptions *MainForm::options (void) const
574  {  {
575      return m_pOptions;          return m_pOptions;
576  }  }
577    
578    
579  // The LSCP client descriptor property.  // The LSCP client descriptor property.
580  lscp_client_t *MainForm::client (void)  lscp_client_t *MainForm::client (void) const
581  {  {
582      return m_pClient;          return m_pClient;
583  }  }
584    
585    
# Line 595  MainForm *MainForm::getInstance (void) Line 596  MainForm *MainForm::getInstance (void)
596  // Format the displayable session filename.  // Format the displayable session filename.
597  QString MainForm::sessionName ( const QString& sFilename )  QString MainForm::sessionName ( const QString& sFilename )
598  {  {
599      bool bCompletePath = (m_pOptions && m_pOptions->bCompletePath);          bool bCompletePath = (m_pOptions && m_pOptions->bCompletePath);
600      QString sSessionName = sFilename;          QString sSessionName = sFilename;
601      if (sSessionName.isEmpty())          if (sSessionName.isEmpty())
602          sSessionName = tr("Untitled") + QString::number(m_iUntitled);                  sSessionName = tr("Untitled") + QString::number(m_iUntitled);
603      else if (!bCompletePath)          else if (!bCompletePath)
604          sSessionName = QFileInfo(sSessionName).fileName();                  sSessionName = QFileInfo(sSessionName).fileName();
605      return sSessionName;          return sSessionName;
606  }  }
607    
608    
609  // Create a new session file from scratch.  // Create a new session file from scratch.
610  bool MainForm::newSession (void)  bool MainForm::newSession (void)
611  {  {
612      // Check if we can do it.          // Check if we can do it.
613      if (!closeSession(true))          if (!closeSession(true))
614          return false;                  return false;
615    
616          // Give us what the server has, right now...          // Give us what the server has, right now...
617          updateSession();          updateSession();
618    
619      // Ok increment untitled count.          // Ok increment untitled count.
620      m_iUntitled++;          m_iUntitled++;
621    
622      // Stabilize form.          // Stabilize form.
623      m_sFilename = QString::null;          m_sFilename = QString::null;
624      m_iDirtyCount = 0;          m_iDirtyCount = 0;
625      appendMessages(tr("New session: \"%1\".").arg(sessionName(m_sFilename)));          appendMessages(tr("New session: \"%1\".").arg(sessionName(m_sFilename)));
626      stabilizeForm();          stabilizeForm();
627    
628      return true;          return true;
629  }  }
630    
631    
632  // Open an existing sampler session.  // Open an existing sampler session.
633  bool MainForm::openSession (void)  bool MainForm::openSession (void)
634  {  {
635      if (m_pOptions == NULL)          if (m_pOptions == NULL)
636          return false;                  return false;
637    
638      // Ask for the filename to open...          // Ask for the filename to open...
639          QString sFilename = QFileDialog::getOpenFileName(this,          QString sFilename = QFileDialog::getOpenFileName(this,
640                  QSAMPLER_TITLE ": " + tr("Open Session"), // Caption.                  QSAMPLER_TITLE ": " + tr("Open Session"), // Caption.
641                  m_pOptions->sSessionDir,                  // Start here.                  m_pOptions->sSessionDir,                  // Start here.
642                  tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)                  tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)
643          );          );
644    
645      // Have we cancelled?          // Have we cancelled?
646      if (sFilename.isEmpty())          if (sFilename.isEmpty())
647          return false;                  return false;
648    
649      // Check if we're going to discard safely the current one...          // Check if we're going to discard safely the current one...
650      if (!closeSession(true))          if (!closeSession(true))
651          return false;                  return false;
652    
653      // Load it right away.          // Load it right away.
654      return loadSessionFile(sFilename);          return loadSessionFile(sFilename);
655  }  }
656    
657    
658  // Save current sampler session with another name.  // Save current sampler session with another name.
659  bool MainForm::saveSession ( bool bPrompt )  bool MainForm::saveSession ( bool bPrompt )
660  {  {
661      if (m_pOptions == NULL)          if (m_pOptions == NULL)
662          return false;                  return false;
663    
664      QString sFilename = m_sFilename;          QString sFilename = m_sFilename;
665    
666      // Ask for the file to save, if there's none...          // Ask for the file to save, if there's none...
667      if (bPrompt || sFilename.isEmpty()) {          if (bPrompt || sFilename.isEmpty()) {
668          // If none is given, assume default directory.                  // If none is given, assume default directory.
669          if (sFilename.isEmpty())                  if (sFilename.isEmpty())
670              sFilename = m_pOptions->sSessionDir;                          sFilename = m_pOptions->sSessionDir;
671          // Prompt the guy...                  // Prompt the guy...
672                  sFilename = QFileDialog::getSaveFileName(this,                  sFilename = QFileDialog::getSaveFileName(this,
673                          QSAMPLER_TITLE ": " + tr("Save Session"), // Caption.                          QSAMPLER_TITLE ": " + tr("Save Session"), // Caption.
674                          sFilename,                                // Start here.                          sFilename,                                // Start here.
675                          tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)                          tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)
676                  );                  );
677          // Have we cancelled it?                  // Have we cancelled it?
678          if (sFilename.isEmpty())                  if (sFilename.isEmpty())
679              return false;                          return false;
680          // Enforce .lscp extension...                  // Enforce .lscp extension...
681          if (QFileInfo(sFilename).suffix().isEmpty())                  if (QFileInfo(sFilename).suffix().isEmpty())
682              sFilename += ".lscp";                          sFilename += ".lscp";
683          // Check if already exists...                  // Check if already exists...
684          if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
685              if (QMessageBox::warning(this,                          if (QMessageBox::warning(this,
686                                  QSAMPLER_TITLE ": " + tr("Warning"),                                  QSAMPLER_TITLE ": " + tr("Warning"),
687                  tr("The file already exists:\n\n"                                  tr("The file already exists:\n\n"
688                     "\"%1\"\n\n"                                  "\"%1\"\n\n"
689                     "Do you want to replace it?")                                  "Do you want to replace it?")
690                     .arg(sFilename),                                  .arg(sFilename),
691                  tr("Replace"), tr("Cancel")) > 0)                                  tr("Replace"), tr("Cancel")) > 0)
692                  return false;                                  return false;
693          }                  }
694      }          }
695    
696      // Save it right away.          // Save it right away.
697      return saveSessionFile(sFilename);          return saveSessionFile(sFilename);
698  }  }
699    
700    
701  // Close current session.  // Close current session.
702  bool MainForm::closeSession ( bool bForce )  bool MainForm::closeSession ( bool bForce )
703  {  {
704      bool bClose = true;          bool bClose = true;
705    
706      // Are we dirty enough to prompt it?          // Are we dirty enough to prompt it?
707      if (m_iDirtyCount > 0) {          if (m_iDirtyCount > 0) {
708          switch (QMessageBox::warning(this,                  switch (QMessageBox::warning(this,
709                          QSAMPLER_TITLE ": " + tr("Warning"),                          QSAMPLER_TITLE ": " + tr("Warning"),
710              tr("The current session has been changed:\n\n"                          tr("The current session has been changed:\n\n"
711              "\"%1\"\n\n"                          "\"%1\"\n\n"
712              "Do you want to save the changes?")                          "Do you want to save the changes?")
713              .arg(sessionName(m_sFilename)),                          .arg(sessionName(m_sFilename)),
714              tr("Save"), tr("Discard"), tr("Cancel"))) {                          tr("Save"), tr("Discard"), tr("Cancel"))) {
715          case 0:     // Save...                  case 0:     // Save...
716              bClose = saveSession(false);                          bClose = saveSession(false);
717              // Fall thru....                          // Fall thru....
718          case 1:     // Discard                  case 1:     // Discard
719              break;                          break;
720          default:    // Cancel.                  default:    // Cancel.
721              bClose = false;                          bClose = false;
722              break;                          break;
723          }                  }
724      }          }
725    
726      // If we may close it, dot it.          // If we may close it, dot it.
727      if (bClose) {          if (bClose) {
728          // Remove all channel strips from sight...                  // Remove all channel strips from sight...
729          m_pWorkspace->setUpdatesEnabled(false);                  m_pWorkspace->setUpdatesEnabled(false);
730          QWidgetList wlist = m_pWorkspace->windowList();                  QWidgetList wlist = m_pWorkspace->windowList();
731          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
732              ChannelStrip *pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                          ChannelStrip *pChannelStrip = (ChannelStrip*) wlist.at(iChannel);
733              if (pChannelStrip) {                          if (pChannelStrip) {
734                  qsamplerChannel *pChannel = pChannelStrip->channel();                                  qsamplerChannel *pChannel = pChannelStrip->channel();
735                  if (bForce && pChannel)                                  if (bForce && pChannel)
736                      pChannel->removeChannel();                                          pChannel->removeChannel();
737                  delete pChannelStrip;                                  delete pChannelStrip;
738              }                          }
739          }                  }
740          m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
741          // We're now clean, for sure.                  // We're now clean, for sure.
742          m_iDirtyCount = 0;                  m_iDirtyCount = 0;
743      }          }
744    
745      return bClose;          return bClose;
746  }  }
747    
748    
749  // Load a session from specific file path.  // Load a session from specific file path.
750  bool MainForm::loadSessionFile ( const QString& sFilename )  bool MainForm::loadSessionFile ( const QString& sFilename )
751  {  {
752      if (m_pClient == NULL)          if (m_pClient == NULL)
753          return false;                  return false;
754    
755      // Open and read from real file.          // Open and read from real file.
756      QFile file(sFilename);          QFile file(sFilename);
757      if (!file.open(QIODevice::ReadOnly)) {          if (!file.open(QIODevice::ReadOnly)) {
758          appendMessagesError(tr("Could not open \"%1\" session file.\n\nSorry.").arg(sFilename));                  appendMessagesError(
759          return false;                          tr("Could not open \"%1\" session file.\n\nSorry.")
760      }                          .arg(sFilename));
761                    return false;
762            }
763    
764          // Tell the world we'll take some time...          // Tell the world we'll take some time...
765          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
766    
767      // Read the file.          // Read the file.
768          int iLine = 0;          int iLine = 0;
769      int iErrors = 0;          int iErrors = 0;
770      QTextStream ts(&file);          QTextStream ts(&file);
771      while (!ts.atEnd()) {          while (!ts.atEnd()) {
772          // Read the line.                  // Read the line.
773          QString sCommand = ts.readLine().trimmed();                  QString sCommand = ts.readLine().trimmed();
774                  iLine++;                  iLine++;
775          // If not empty, nor a comment, call the server...                  // If not empty, nor a comment, call the server...
776          if (!sCommand.isEmpty() && sCommand[0] != '#') {                  if (!sCommand.isEmpty() && sCommand[0] != '#') {
777                          // Remember that, no matter what,                          // Remember that, no matter what,
778                          // all LSCP commands are CR/LF terminated.                          // all LSCP commands are CR/LF terminated.
779                          sCommand += "\r\n";                          sCommand += "\r\n";
# Line 782  bool MainForm::loadSessionFile ( const Q Line 785  bool MainForm::loadSessionFile ( const Q
785                                  appendMessagesClient("lscp_client_query");                                  appendMessagesClient("lscp_client_query");
786                                  iErrors++;                                  iErrors++;
787                          }                          }
788          }                  }
789          // Try to make it snappy :)                  // Try to make it snappy :)
790          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
791      }          }
792    
793      // Ok. we've read it.          // Ok. we've read it.
794      file.close();          file.close();
795    
796          // Now we'll try to create (update) the whole GUI session.          // Now we'll try to create (update) the whole GUI session.
797          updateSession();          updateSession();
# Line 797  bool MainForm::loadSessionFile ( const Q Line 800  bool MainForm::loadSessionFile ( const Q
800          QApplication::restoreOverrideCursor();          QApplication::restoreOverrideCursor();
801    
802          // Have we any errors?          // Have we any errors?
803          if (iErrors > 0)          if (iErrors > 0) {
804                  appendMessagesError(tr("Session loaded with errors\nfrom \"%1\".\n\nSorry.").arg(sFilename));                  appendMessagesError(
805                            tr("Session loaded with errors\nfrom \"%1\".\n\nSorry.")
806                            .arg(sFilename));
807            }
808    
809      // Save as default session directory.          // Save as default session directory.
810      if (m_pOptions)          if (m_pOptions)
811          m_pOptions->sSessionDir = QFileInfo(sFilename).dir().absolutePath();                  m_pOptions->sSessionDir = QFileInfo(sFilename).dir().absolutePath();
812          // We're not dirty anymore, if loaded without errors,          // We're not dirty anymore, if loaded without errors,
813          m_iDirtyCount = iErrors;          m_iDirtyCount = iErrors;
814      // Stabilize form...          // Stabilize form...
815      m_sFilename = sFilename;          m_sFilename = sFilename;
816      updateRecentFiles(sFilename);          updateRecentFiles(sFilename);
817      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));          appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));
818    
819      // Make that an overall update.          // Make that an overall update.
820      stabilizeForm();          stabilizeForm();
821      return true;          return true;
822  }  }
823    
824    
# Line 828  bool MainForm::saveSessionFile ( const Q Line 834  bool MainForm::saveSessionFile ( const Q
834                  return false;                  return false;
835          }          }
836    
837      // Open and write into real file.          // Open and write into real file.
838      QFile file(sFilename);          QFile file(sFilename);
839      if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {          if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
840          appendMessagesError(tr("Could not open \"%1\" session file.\n\nSorry.").arg(sFilename));                  appendMessagesError(
841          return false;                          tr("Could not open \"%1\" session file.\n\nSorry.")
842      }                          .arg(sFilename));
843                    return false;
844            }
845    
846          // Tell the world we'll take some time...          // Tell the world we'll take some time...
847          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
848    
849      // Write the file.          // Write the file.
850      int  iErrors = 0;          int  iErrors = 0;
851      QTextStream ts(&file);          QTextStream ts(&file);
852      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;          ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;
853      ts << "# " << tr("Version")          ts << "# " << tr("Version")
854         << ": " QSAMPLER_VERSION << endl;          << ": " QSAMPLER_VERSION << endl;
855      ts << "# " << tr("Build")          ts << "# " << tr("Build")
856         << ": " __DATE__ " " __TIME__ << endl;          << ": " __DATE__ " " __TIME__ << endl;
857      ts << "#"  << endl;          ts << "#"  << endl;
858      ts << "# " << tr("File")          ts << "# " << tr("File")
859         << ": " << QFileInfo(sFilename).fileName() << endl;          << ": " << QFileInfo(sFilename).fileName() << endl;
860      ts << "# " << tr("Date")          ts << "# " << tr("Date")
861         << ": " << QDate::currentDate().toString("MMM dd yyyy")          << ": " << QDate::currentDate().toString("MMM dd yyyy")
862         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;          << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;
863      ts << "#"  << endl;          ts << "#"  << endl;
864      ts << endl;          ts << endl;
865    
866          // It is assumed that this new kind of device+session file          // It is assumed that this new kind of device+session file
867          // will be loaded from a complete initialized server...          // will be loaded from a complete initialized server...
# Line 934  bool MainForm::saveSessionFile ( const Q Line 942  bool MainForm::saveSessionFile ( const Q
942                                  const qsamplerDeviceParam& param = portParam.value();                                  const qsamplerDeviceParam& param = portParam.value();
943                                  if (param.fix || param.value.isEmpty()) ts << "# ";                                  if (param.fix || param.value.isEmpty()) ts << "# ";
944                                  ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice                                  ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice
945                                     << " " << iPort << " " << portParam.key()                                  << " " << iPort << " " << portParam.key()
946                                     << "='" << param.value << "'" << endl;                                  << "='" << param.value << "'" << endl;
947                          }                          }
948                          iPort++;                          iPort++;
949                  }                  }
# Line 1018  bool MainForm::saveSessionFile ( const Q Line 1026  bool MainForm::saveSessionFile ( const Q
1026  #endif  // CONFIG_MIDI_INSTRUMENT  #endif  // CONFIG_MIDI_INSTRUMENT
1027    
1028          // Sampler channel mapping.          // Sampler channel mapping.
1029      QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
1030      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1031          ChannelStrip* pChannelStrip                  ChannelStrip* pChannelStrip
1032                          = static_cast<ChannelStrip *> (wlist.at(iChannel));                          = static_cast<ChannelStrip *> (wlist.at(iChannel));
1033          if (pChannelStrip) {                  if (pChannelStrip) {
1034              qsamplerChannel *pChannel = pChannelStrip->channel();                          qsamplerChannel *pChannel = pChannelStrip->channel();
1035              if (pChannel) {                          if (pChannel) {
1036                  ts << "# " << tr("Channel") << " " << iChannel << endl;                                  ts << "# " << tr("Channel") << " " << iChannel << endl;
1037                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
1038                                  if (audioDeviceMap.isEmpty()) {                                  if (audioDeviceMap.isEmpty()) {
1039                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel
1040                                                  << " " << pChannel->audioDriver() << endl;                                                  << " " << pChannel->audioDriver() << endl;
# Line 1043  bool MainForm::saveSessionFile ( const Q Line 1051  bool MainForm::saveSessionFile ( const Q
1051                                  }                                  }
1052                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel
1053                                          << " " << pChannel->midiPort() << endl;                                          << " " << pChannel->midiPort() << endl;
1054                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";                                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";
1055                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)                                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
1056                      ts << "ALL";                                          ts << "ALL";
1057                  else                                  else
1058                      ts << pChannel->midiChannel();                                          ts << pChannel->midiChannel();
1059                  ts << endl;                                  ts << endl;
1060                  ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannel << endl;                                  ts << "LOAD ENGINE " << pChannel->engineName()
1061                                            << " " << iChannel << endl;
1062                                  if (pChannel->instrumentStatus() < 100) ts << "# ";                                  if (pChannel->instrumentStatus() < 100) ts << "# ";
1063                                  ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' "                                  ts << "LOAD INSTRUMENT NON_MODAL '"
1064                                            << pChannel->instrumentFile() << "' "
1065                                          << pChannel->instrumentNr() << " " << iChannel << endl;                                          << pChannel->instrumentNr() << " " << iChannel << endl;
1066                                  qsamplerChannelRoutingMap::ConstIterator audioRoute;                                  qsamplerChannelRoutingMap::ConstIterator audioRoute;
1067                                  for (audioRoute = pChannel->audioRouting().begin();                                  for (audioRoute = pChannel->audioRouting().begin();
# Line 1109  bool MainForm::saveSessionFile ( const Q Line 1119  bool MainForm::saveSessionFile ( const Q
1119                                          }                                          }
1120                                  }                                  }
1121  #endif  #endif
1122                  ts << endl;                                  ts << endl;
1123              }                          }
1124          }                  }
1125          // Try to keep it snappy :)                  // Try to keep it snappy :)
1126          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1127      }          }
1128    
1129  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
1130          ts << "# " << tr("Global volume level") << endl;          ts << "# " << tr("Global volume level") << endl;
# Line 1122  bool MainForm::saveSessionFile ( const Q Line 1132  bool MainForm::saveSessionFile ( const Q
1132          ts << endl;          ts << endl;
1133  #endif  #endif
1134    
1135      // Ok. we've wrote it.          // Ok. we've wrote it.
1136      file.close();          file.close();
1137    
1138          // We're fornerly done.          // We're fornerly done.
1139          QApplication::restoreOverrideCursor();          QApplication::restoreOverrideCursor();
1140    
1141      // Have we any errors?          // Have we any errors?
1142      if (iErrors > 0)          if (iErrors > 0) {
1143          appendMessagesError(tr("Some settings could not be saved\nto \"%1\" session file.\n\nSorry.").arg(sFilename));                  appendMessagesError(
1144                            tr("Some settings could not be saved\n"
1145      // Save as default session directory.                          "to \"%1\" session file.\n\nSorry.")
1146      if (m_pOptions)                          .arg(sFilename));
1147          m_pOptions->sSessionDir = QFileInfo(sFilename).dir().absolutePath();          }
1148      // We're not dirty anymore.  
1149      m_iDirtyCount = 0;          // Save as default session directory.
1150      // Stabilize form...          if (m_pOptions)
1151      m_sFilename = sFilename;                  m_pOptions->sSessionDir = QFileInfo(sFilename).dir().absolutePath();
1152      updateRecentFiles(sFilename);          // We're not dirty anymore.
1153      appendMessages(tr("Save session: \"%1\".").arg(sessionName(m_sFilename)));          m_iDirtyCount = 0;
1154      stabilizeForm();          // Stabilize form...
1155      return true;          m_sFilename = sFilename;
1156            updateRecentFiles(sFilename);
1157            appendMessages(tr("Save session: \"%1\".").arg(sessionName(m_sFilename)));
1158            stabilizeForm();
1159            return true;
1160  }  }
1161    
1162    
1163  // Session change receiver slot.  // Session change receiver slot.
1164  void MainForm::sessionDirty (void)  void MainForm::sessionDirty (void)
1165  {  {
1166      // Just mark the dirty form.          // Just mark the dirty form.
1167      m_iDirtyCount++;          m_iDirtyCount++;
1168      // and update the form status...          // and update the form status...
1169      stabilizeForm();          stabilizeForm();
1170  }  }
1171    
1172    
# Line 1162  void MainForm::sessionDirty (void) Line 1176  void MainForm::sessionDirty (void)
1176  // Create a new sampler session.  // Create a new sampler session.
1177  void MainForm::fileNew (void)  void MainForm::fileNew (void)
1178  {  {
1179      // Of course we'll start clean new.          // Of course we'll start clean new.
1180      newSession();          newSession();
1181  }  }
1182    
1183    
1184  // Open an existing sampler session.  // Open an existing sampler session.
1185  void MainForm::fileOpen (void)  void MainForm::fileOpen (void)
1186  {  {
1187      // Open it right away.          // Open it right away.
1188      openSession();          openSession();
1189  }  }
1190    
1191    
# Line 1195  void MainForm::fileOpenRecent (void) Line 1209  void MainForm::fileOpenRecent (void)
1209  // Save current sampler session.  // Save current sampler session.
1210  void MainForm::fileSave (void)  void MainForm::fileSave (void)
1211  {  {
1212      // Save it right away.          // Save it right away.
1213      saveSession(false);          saveSession(false);
1214  }  }
1215    
1216    
1217  // Save current sampler session with another name.  // Save current sampler session with another name.
1218  void MainForm::fileSaveAs (void)  void MainForm::fileSaveAs (void)
1219  {  {
1220      // Save it right away, maybe with another name.          // Save it right away, maybe with another name.
1221      saveSession(true);          saveSession(true);
1222  }  }
1223    
1224    
1225  // Reset the sampler instance.  // Reset the sampler instance.
1226  void MainForm::fileReset (void)  void MainForm::fileReset (void)
1227  {  {
1228      if (m_pClient == NULL)          if (m_pClient == NULL)
1229          return;                  return;
1230    
1231      // Ask user whether he/she want's an internal sampler reset...          // Ask user whether he/she want's an internal sampler reset...
1232      if (QMessageBox::warning(this,          if (QMessageBox::warning(this,
1233                  QSAMPLER_TITLE ": " + tr("Warning"),                  QSAMPLER_TITLE ": " + tr("Warning"),
1234          tr("Resetting the sampler instance will close\n"                  tr("Resetting the sampler instance will close\n"
1235             "all device and channel configurations.\n\n"                  "all device and channel configurations.\n\n"
1236             "Please note that this operation may cause\n"                  "Please note that this operation may cause\n"
1237             "temporary MIDI and Audio disruption.\n\n"                  "temporary MIDI and Audio disruption.\n\n"
1238             "Do you want to reset the sampler engine now?"),                  "Do you want to reset the sampler engine now?"),
1239          tr("Reset"), tr("Cancel")) > 0)                  tr("Reset"), tr("Cancel")) > 0)
1240          return;                  return;
1241    
1242          // Trye closing the current session, first...          // Trye closing the current session, first...
1243          if (!closeSession(true))          if (!closeSession(true))
1244                  return;                  return;
1245    
1246      // Just do the reset, after closing down current session...          // Just do the reset, after closing down current session...
1247          // Do the actual sampler reset...          // Do the actual sampler reset...
1248          if (::lscp_reset_sampler(m_pClient) != LSCP_OK) {          if (::lscp_reset_sampler(m_pClient) != LSCP_OK) {
1249                  appendMessagesClient("lscp_reset_sampler");                  appendMessagesClient("lscp_reset_sampler");
# Line 1237  void MainForm::fileReset (void) Line 1251  void MainForm::fileReset (void)
1251                  return;                  return;
1252          }          }
1253    
1254      // Log this.          // Log this.
1255      appendMessages(tr("Sampler reset."));          appendMessages(tr("Sampler reset."));
1256    
1257          // Make it a new session...          // Make it a new session...
1258          newSession();          newSession();
# Line 1248  void MainForm::fileReset (void) Line 1262  void MainForm::fileReset (void)
1262  // Restart the client/server instance.  // Restart the client/server instance.
1263  void MainForm::fileRestart (void)  void MainForm::fileRestart (void)
1264  {  {
1265      if (m_pOptions == NULL)          if (m_pOptions == NULL)
1266          return;                  return;
1267    
1268      bool bRestart = true;          bool bRestart = true;
1269    
1270      // Ask user whether he/she want's a complete restart...          // Ask user whether he/she want's a complete restart...
1271      // (if we're currently up and running)          // (if we're currently up and running)
1272      if (bRestart && m_pClient) {          if (bRestart && m_pClient) {
1273          bRestart = (QMessageBox::warning(this,                  bRestart = (QMessageBox::warning(this,
1274                          QSAMPLER_TITLE ": " + tr("Warning"),                          QSAMPLER_TITLE ": " + tr("Warning"),
1275              tr("New settings will be effective after\n"                          tr("New settings will be effective after\n"
1276                 "restarting the client/server connection.\n\n"                          "restarting the client/server connection.\n\n"
1277                 "Please note that this operation may cause\n"                          "Please note that this operation may cause\n"
1278                 "temporary MIDI and Audio disruption.\n\n"                          "temporary MIDI and Audio disruption.\n\n"
1279                 "Do you want to restart the connection now?"),                          "Do you want to restart the connection now?"),
1280              tr("Restart"), tr("Cancel")) == 0);                          tr("Restart"), tr("Cancel")) == 0);
1281      }          }
1282    
1283      // Are we still for it?          // Are we still for it?
1284      if (bRestart && closeSession(true)) {          if (bRestart && closeSession(true)) {
1285          // Stop server, it will force the client too.                  // Stop server, it will force the client too.
1286          stopServer();                  stopServer();
1287          // Reschedule a restart...                  // Reschedule a restart...
1288          startSchedule(m_pOptions->iStartDelay);                  startSchedule(m_pOptions->iStartDelay);
1289      }          }
1290  }  }
1291    
1292    
1293  // Exit application program.  // Exit application program.
1294  void MainForm::fileExit (void)  void MainForm::fileExit (void)
1295  {  {
1296      // Go for close the whole thing.          // Go for close the whole thing.
1297      close();          close();
1298  }  }
1299    
1300    
# Line 1290  void MainForm::fileExit (void) Line 1304  void MainForm::fileExit (void)
1304  // Add a new sampler channel.  // Add a new sampler channel.
1305  void MainForm::editAddChannel (void)  void MainForm::editAddChannel (void)
1306  {  {
1307      if (m_pClient == NULL)          if (m_pClient == NULL)
1308          return;                  return;
1309    
1310            // Just create the channel instance...
1311            qsamplerChannel *pChannel = new qsamplerChannel();
1312            if (pChannel == NULL)
1313                    return;
1314    
1315            // Before we show it up, may be we'll
1316            // better ask for some initial values?
1317            if (!pChannel->channelSetup(this)) {
1318                    delete pChannel;
1319                    return;
1320            }
1321    
1322      // Just create the channel instance...          // And give it to the strip...
1323      qsamplerChannel *pChannel = new qsamplerChannel();          // (will own the channel instance, if successful).
1324      if (pChannel == NULL)          if (!createChannelStrip(pChannel)) {
1325          return;                  delete pChannel;
1326                    return;
1327      // Before we show it up, may be we'll          }
1328      // better ask for some initial values?  
1329      if (!pChannel->channelSetup(this)) {          // Make that an overall update.
1330          delete pChannel;          m_iDirtyCount++;
1331          return;          stabilizeForm();
     }  
   
     // And give it to the strip (will own the channel instance, if successful).  
     if (!createChannelStrip(pChannel)) {  
         delete pChannel;  
         return;  
     }  
   
     // Make that an overall update.  
     m_iDirtyCount++;  
     stabilizeForm();  
1332  }  }
1333    
1334    
1335  // Remove current sampler channel.  // Remove current sampler channel.
1336  void MainForm::editRemoveChannel (void)  void MainForm::editRemoveChannel (void)
1337  {  {
1338      if (m_pClient == NULL)          if (m_pClient == NULL)
1339          return;                  return;
1340    
1341      ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip* pChannelStrip = activeChannelStrip();
1342      if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1343          return;                  return;
1344    
1345      qsamplerChannel *pChannel = pChannelStrip->channel();          qsamplerChannel *pChannel = pChannelStrip->channel();
1346      if (pChannel == NULL)          if (pChannel == NULL)
1347          return;                  return;
1348    
1349      // Prompt user if he/she's sure about this...          // Prompt user if he/she's sure about this...
1350      if (m_pOptions && m_pOptions->bConfirmRemove) {          if (m_pOptions && m_pOptions->bConfirmRemove) {
1351          if (QMessageBox::warning(this,                  if (QMessageBox::warning(this,
1352                          QSAMPLER_TITLE ": " + tr("Warning"),                          QSAMPLER_TITLE ": " + tr("Warning"),
1353              tr("About to remove channel:\n\n"                          tr("About to remove channel:\n\n"
1354                 "%1\n\n"                          "%1\n\n"
1355                 "Are you sure?")                          "Are you sure?")
1356                 .arg(pChannelStrip->windowTitle()),                          .arg(pChannelStrip->windowTitle()),
1357              tr("OK"), tr("Cancel")) > 0)                          tr("OK"), tr("Cancel")) > 0)
1358              return;                          return;
1359      }          }
1360    
1361      // Remove the existing sampler channel.          // Remove the existing sampler channel.
1362      if (!pChannel->removeChannel())          if (!pChannel->removeChannel())
1363          return;                  return;
1364    
1365      // Just delete the channel strip.          // Just delete the channel strip.
1366      delete pChannelStrip;          delete pChannelStrip;
1367    
1368      // Do we auto-arrange?          // Do we auto-arrange?
1369      if (m_pOptions && m_pOptions->bAutoArrange)          if (m_pOptions && m_pOptions->bAutoArrange)
1370          channelsArrange();                  channelsArrange();
1371    
1372      // We'll be dirty, for sure...          // We'll be dirty, for sure...
1373      m_iDirtyCount++;          m_iDirtyCount++;
1374      stabilizeForm();          stabilizeForm();
1375  }  }
1376    
1377    
1378  // Setup current sampler channel.  // Setup current sampler channel.
1379  void MainForm::editSetupChannel (void)  void MainForm::editSetupChannel (void)
1380  {  {
1381      if (m_pClient == NULL)          if (m_pClient == NULL)
1382          return;                  return;
1383    
1384      ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip* pChannelStrip = activeChannelStrip();
1385      if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1386          return;                  return;
1387    
1388      // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
1389      pChannelStrip->channelSetup();          pChannelStrip->channelSetup();
1390  }  }
1391    
1392    
1393  // Edit current sampler channel.  // Edit current sampler channel.
1394  void MainForm::editEditChannel (void)  void MainForm::editEditChannel (void)
1395  {  {
1396      if (m_pClient == NULL)          if (m_pClient == NULL)
1397          return;                  return;
1398    
1399      ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip* pChannelStrip = activeChannelStrip();
1400      if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1401          return;                  return;
1402    
1403      // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
1404      pChannelStrip->channelEdit();          pChannelStrip->channelEdit();
1405  }  }
1406    
1407    
1408  // Reset current sampler channel.  // Reset current sampler channel.
1409  void MainForm::editResetChannel (void)  void MainForm::editResetChannel (void)
1410  {  {
1411      if (m_pClient == NULL)          if (m_pClient == NULL)
1412          return;                  return;
1413    
1414      ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip* pChannelStrip = activeChannelStrip();
1415      if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1416          return;                  return;
1417    
1418      // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
1419      pChannelStrip->channelReset();          pChannelStrip->channelReset();
1420  }  }
1421    
1422    
# Line 1430  void MainForm::editResetAllChannels (voi Line 1445  void MainForm::editResetAllChannels (voi
1445  // Show/hide the main program window menubar.  // Show/hide the main program window menubar.
1446  void MainForm::viewMenubar ( bool bOn )  void MainForm::viewMenubar ( bool bOn )
1447  {  {
1448      if (bOn)          if (bOn)
1449          ui.MenuBar->show();                  m_ui.MenuBar->show();
1450      else          else
1451          ui.MenuBar->hide();                  m_ui.MenuBar->hide();
1452  }  }
1453    
1454    
1455  // Show/hide the main program window toolbar.  // Show/hide the main program window toolbar.
1456  void MainForm::viewToolbar ( bool bOn )  void MainForm::viewToolbar ( bool bOn )
1457  {  {
1458      if (bOn) {          if (bOn) {
1459          ui.fileToolbar->show();                  m_ui.fileToolbar->show();
1460          ui.editToolbar->show();                  m_ui.editToolbar->show();
1461          ui.channelsToolbar->show();                  m_ui.channelsToolbar->show();
1462      } else {          } else {
1463          ui.fileToolbar->hide();                  m_ui.fileToolbar->hide();
1464          ui.editToolbar->hide();                  m_ui.editToolbar->hide();
1465          ui.channelsToolbar->hide();                  m_ui.channelsToolbar->hide();
1466      }          }
1467  }  }
1468    
1469    
1470  // Show/hide the main program window statusbar.  // Show/hide the main program window statusbar.
1471  void MainForm::viewStatusbar ( bool bOn )  void MainForm::viewStatusbar ( bool bOn )
1472  {  {
1473      if (bOn)          if (bOn)
1474          statusBar()->show();                  statusBar()->show();
1475      else          else
1476          statusBar()->hide();                  statusBar()->hide();
1477  }  }
1478    
1479    
1480  // Show/hide the messages window logger.  // Show/hide the messages window logger.
1481  void MainForm::viewMessages ( bool bOn )  void MainForm::viewMessages ( bool bOn )
1482  {  {
1483      if (bOn)          if (bOn)
1484          m_pMessages->show();                  m_pMessages->show();
1485      else          else
1486          m_pMessages->hide();                  m_pMessages->hide();
1487  }  }
1488    
1489    
# Line 1513  void MainForm::viewDevices (void) Line 1528  void MainForm::viewDevices (void)
1528  // Show options dialog.  // Show options dialog.
1529  void MainForm::viewOptions (void)  void MainForm::viewOptions (void)
1530  {  {
1531      if (m_pOptions == NULL)          if (m_pOptions == NULL)
1532          return;                  return;
1533    
1534      OptionsForm* pOptionsForm = new OptionsForm(this);          OptionsForm* pOptionsForm = new OptionsForm(this);
1535      if (pOptionsForm) {          if (pOptionsForm) {
1536          // Check out some initial nullities(tm)...                  // Check out some initial nullities(tm)...
1537          ChannelStrip* pChannelStrip = activeChannelStrip();                  ChannelStrip* pChannelStrip = activeChannelStrip();
1538          if (m_pOptions->sDisplayFont.isEmpty() && pChannelStrip)                  if (m_pOptions->sDisplayFont.isEmpty() && pChannelStrip)
1539              m_pOptions->sDisplayFont = pChannelStrip->displayFont().toString();                          m_pOptions->sDisplayFont = pChannelStrip->displayFont().toString();
1540          if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)
1541              m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();
1542          // To track down deferred or immediate changes.                  // To track down deferred or immediate changes.
1543          QString sOldServerHost      = m_pOptions->sServerHost;                  QString sOldServerHost      = m_pOptions->sServerHost;
1544          int     iOldServerPort      = m_pOptions->iServerPort;                  int     iOldServerPort      = m_pOptions->iServerPort;
1545          int     iOldServerTimeout   = m_pOptions->iServerTimeout;                  int     iOldServerTimeout   = m_pOptions->iServerTimeout;
1546          bool    bOldServerStart     = m_pOptions->bServerStart;                  bool    bOldServerStart     = m_pOptions->bServerStart;
1547          QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;                  QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;
1548          QString sOldDisplayFont     = m_pOptions->sDisplayFont;                  QString sOldDisplayFont     = m_pOptions->sDisplayFont;
1549          bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;                  bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1550          int     iOldMaxVolume       = m_pOptions->iMaxVolume;                  int     iOldMaxVolume       = m_pOptions->iMaxVolume;
1551          QString sOldMessagesFont    = m_pOptions->sMessagesFont;                  QString sOldMessagesFont    = m_pOptions->sMessagesFont;
1552          bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;                  bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;
1553          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;                  bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;
1554          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;                  int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;
1555          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;                  int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1556          bool    bOldCompletePath    = m_pOptions->bCompletePath;                  bool    bOldCompletePath    = m_pOptions->bCompletePath;
1557          bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;                  bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1558          int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;                  int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1559          // Load the current setup settings.                  // Load the current setup settings.
1560          pOptionsForm->setup(m_pOptions);                  pOptionsForm->setup(m_pOptions);
1561          // Show the setup dialog...                  // Show the setup dialog...
1562          if (pOptionsForm->exec()) {                  if (pOptionsForm->exec()) {
1563              // Warn if something will be only effective on next run.                          // Warn if something will be only effective on next run.
1564              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||                          if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1565                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||                                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||
1566                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||                                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1567                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)) {                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)) {
1568                  QMessageBox::information(this,                                  QMessageBox::information(this,
1569                                          QSAMPLER_TITLE ": " + tr("Information"),                                          QSAMPLER_TITLE ": " + tr("Information"),
1570                      tr("Some settings may be only effective\n"                                          tr("Some settings may be only effective\n"
1571                         "next time you start this program."), tr("OK"));                                          "next time you start this program."), tr("OK"));
1572                  updateMessagesCapture();                                  updateMessagesCapture();
1573              }                          }
1574              // Check wheather something immediate has changed.                          // Check wheather something immediate has changed.
1575              if (( bOldCompletePath && !m_pOptions->bCompletePath) ||                          if (( bOldCompletePath && !m_pOptions->bCompletePath) ||
1576                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||                                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||
1577                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))                                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))
1578                  updateRecentFilesMenu();                                  updateRecentFilesMenu();
1579              if (( bOldInstrumentNames && !m_pOptions->bInstrumentNames) ||                          if (( bOldInstrumentNames && !m_pOptions->bInstrumentNames) ||
1580                  (!bOldInstrumentNames &&  m_pOptions->bInstrumentNames))                                  (!bOldInstrumentNames &&  m_pOptions->bInstrumentNames))
1581                  updateInstrumentNames();                                  updateInstrumentNames();
1582              if (( bOldDisplayEffect && !m_pOptions->bDisplayEffect) ||                          if (( bOldDisplayEffect && !m_pOptions->bDisplayEffect) ||
1583                  (!bOldDisplayEffect &&  m_pOptions->bDisplayEffect))                                  (!bOldDisplayEffect &&  m_pOptions->bDisplayEffect))
1584                  updateDisplayEffect();                                  updateDisplayEffect();
1585              if (sOldDisplayFont != m_pOptions->sDisplayFont)                          if (sOldDisplayFont != m_pOptions->sDisplayFont)
1586                  updateDisplayFont();                                  updateDisplayFont();
1587              if (iOldMaxVolume != m_pOptions->iMaxVolume)                          if (iOldMaxVolume != m_pOptions->iMaxVolume)
1588                  updateMaxVolume();                                  updateMaxVolume();
1589              if (sOldMessagesFont != m_pOptions->sMessagesFont)                          if (sOldMessagesFont != m_pOptions->sMessagesFont)
1590                  updateMessagesFont();                                  updateMessagesFont();
1591              if (( bOldMessagesLimit && !m_pOptions->bMessagesLimit) ||                          if (( bOldMessagesLimit && !m_pOptions->bMessagesLimit) ||
1592                  (!bOldMessagesLimit &&  m_pOptions->bMessagesLimit) ||                                  (!bOldMessagesLimit &&  m_pOptions->bMessagesLimit) ||
1593                  (iOldMessagesLimitLines !=  m_pOptions->iMessagesLimitLines))                                  (iOldMessagesLimitLines !=  m_pOptions->iMessagesLimitLines))
1594                  updateMessagesLimit();                                  updateMessagesLimit();
1595              // And now the main thing, whether we'll do client/server recycling?                          // And now the main thing, whether we'll do client/server recycling?
1596              if ((sOldServerHost != m_pOptions->sServerHost) ||                          if ((sOldServerHost != m_pOptions->sServerHost) ||
1597                  (iOldServerPort != m_pOptions->iServerPort) ||                                  (iOldServerPort != m_pOptions->iServerPort) ||
1598                  (iOldServerTimeout != m_pOptions->iServerTimeout) ||                                  (iOldServerTimeout != m_pOptions->iServerTimeout) ||
1599                  ( bOldServerStart && !m_pOptions->bServerStart) ||                                  ( bOldServerStart && !m_pOptions->bServerStart) ||
1600                  (!bOldServerStart &&  m_pOptions->bServerStart) ||                                  (!bOldServerStart &&  m_pOptions->bServerStart) ||
1601                  (sOldServerCmdLine != m_pOptions->sServerCmdLine && m_pOptions->bServerStart))                                  (sOldServerCmdLine != m_pOptions->sServerCmdLine
1602                  fileRestart();                                  && m_pOptions->bServerStart))
1603          }                                  fileRestart();
1604          // Done.                  }
1605          delete pOptionsForm;                  // Done.
1606      }                  delete pOptionsForm;
1607            }
1608    
1609      // This makes it.          // This makes it.
1610      stabilizeForm();          stabilizeForm();
1611  }  }
1612    
1613    
# Line 1601  void MainForm::viewOptions (void) Line 1617  void MainForm::viewOptions (void)
1617  // Arrange channel strips.  // Arrange channel strips.
1618  void MainForm::channelsArrange (void)  void MainForm::channelsArrange (void)
1619  {  {
1620      // Full width vertical tiling          // Full width vertical tiling
1621      QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
1622      if (wlist.isEmpty())          if (wlist.isEmpty())
1623          return;                  return;
   
     m_pWorkspace->setUpdatesEnabled(false);  
     int y = 0;  
     for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {  
         ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);  
     /*  if (pChannelStrip->testWState(WState_Maximized | WState_Minimized)) {  
             // Prevent flicker...  
             pChannelStrip->hide();  
             pChannelStrip->showNormal();  
         }   */  
         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);  
         y += iHeight;  
     }  
     m_pWorkspace->setUpdatesEnabled(true);  
1624    
1625      stabilizeForm();          m_pWorkspace->setUpdatesEnabled(false);
1626            int y = 0;
1627            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1628                    ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);
1629            /*  if (pChannelStrip->testWState(WState_Maximized | WState_Minimized)) {
1630                            // Prevent flicker...
1631                            pChannelStrip->hide();
1632                            pChannelStrip->showNormal();
1633                    }   */
1634                    pChannelStrip->adjustSize();
1635                    int iWidth  = m_pWorkspace->width();
1636                    if (iWidth < pChannelStrip->width())
1637                            iWidth = pChannelStrip->width();
1638            //  int iHeight = pChannelStrip->height()
1639            //              + pChannelStrip->parentWidget()->baseSize().height();
1640                    int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
1641                    pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
1642                    y += iHeight;
1643            }
1644            m_pWorkspace->setUpdatesEnabled(true);
1645    
1646            stabilizeForm();
1647  }  }
1648    
1649    
1650  // Auto-arrange channel strips.  // Auto-arrange channel strips.
1651  void MainForm::channelsAutoArrange ( bool bOn )  void MainForm::channelsAutoArrange ( bool bOn )
1652  {  {
1653      if (m_pOptions == NULL)          if (m_pOptions == NULL)
1654          return;                  return;
1655    
1656      // Toggle the auto-arrange flag.          // Toggle the auto-arrange flag.
1657      m_pOptions->bAutoArrange = bOn;          m_pOptions->bAutoArrange = bOn;
1658    
1659      // If on, update whole workspace...          // If on, update whole workspace...
1660      if (m_pOptions->bAutoArrange)          if (m_pOptions->bAutoArrange)
1661          channelsArrange();                  channelsArrange();
1662  }  }
1663    
1664    
# Line 1651  void MainForm::channelsAutoArrange ( boo Line 1668  void MainForm::channelsAutoArrange ( boo
1668  // Show information about the Qt toolkit.  // Show information about the Qt toolkit.
1669  void MainForm::helpAboutQt (void)  void MainForm::helpAboutQt (void)
1670  {  {
1671      QMessageBox::aboutQt(this);          QMessageBox::aboutQt(this);
1672  }  }
1673    
1674    
1675  // Show information about application program.  // Show information about application program.
1676  void MainForm::helpAbout (void)  void MainForm::helpAbout (void)
1677  {  {
1678      // Stuff the about box text...          // Stuff the about box text...
1679      QString sText = "<p>\n";          QString sText = "<p>\n";
1680      sText += "<b>" QSAMPLER_TITLE " - " + tr(QSAMPLER_SUBTITLE) + "</b><br />\n";          sText += "<b>" QSAMPLER_TITLE " - " + tr(QSAMPLER_SUBTITLE) + "</b><br />\n";
1681      sText += "<br />\n";          sText += "<br />\n";
1682      sText += tr("Version") + ": <b>" QSAMPLER_VERSION "</b><br />\n";          sText += tr("Version") + ": <b>" QSAMPLER_VERSION "</b><br />\n";
1683      sText += "<small>" + tr("Build") + ": " __DATE__ " " __TIME__ "</small><br />\n";          sText += "<small>" + tr("Build") + ": " __DATE__ " " __TIME__ "</small><br />\n";
1684  #ifdef CONFIG_DEBUG  #ifdef CONFIG_DEBUG
1685      sText += "<small><font color=\"red\">";          sText += "<small><font color=\"red\">";
1686      sText += tr("Debugging option enabled.");          sText += tr("Debugging option enabled.");
1687      sText += "</font></small><br />";          sText += "</font></small><br />";
1688  #endif  #endif
1689  #ifndef CONFIG_LIBGIG  #ifndef CONFIG_LIBGIG
1690      sText += "<small><font color=\"red\">";          sText += "<small><font color=\"red\">";
1691      sText += tr("GIG (libgig) file support disabled.");          sText += tr("GIG (libgig) file support disabled.");
1692      sText += "</font></small><br />";          sText += "</font></small><br />";
1693  #endif  #endif
1694  #ifndef CONFIG_INSTRUMENT_NAME  #ifndef CONFIG_INSTRUMENT_NAME
1695      sText += "<small><font color=\"red\">";          sText += "<small><font color=\"red\">";
1696      sText += tr("LSCP (liblscp) instrument_name support disabled.");          sText += tr("LSCP (liblscp) instrument_name support disabled.");
1697      sText += "</font></small><br />";          sText += "</font></small><br />";
1698  #endif  #endif
1699  #ifndef CONFIG_MUTE_SOLO  #ifndef CONFIG_MUTE_SOLO
1700      sText += "<small><font color=\"red\">";          sText += "<small><font color=\"red\">";
1701      sText += tr("Sampler channel Mute/Solo support disabled.");          sText += tr("Sampler channel Mute/Solo support disabled.");
1702      sText += "</font></small><br />";          sText += "</font></small><br />";
1703  #endif  #endif
1704  #ifndef CONFIG_AUDIO_ROUTING  #ifndef CONFIG_AUDIO_ROUTING
1705      sText += "<small><font color=\"red\">";          sText += "<small><font color=\"red\">";
1706      sText += tr("LSCP (liblscp) audio_routing support disabled.");          sText += tr("LSCP (liblscp) audio_routing support disabled.");
1707      sText += "</font></small><br />";          sText += "</font></small><br />";
1708  #endif  #endif
1709  #ifndef CONFIG_FXSEND  #ifndef CONFIG_FXSEND
1710      sText += "<small><font color=\"red\">";          sText += "<small><font color=\"red\">";
1711      sText += tr("Sampler channel Effect Sends support disabled.");          sText += tr("Sampler channel Effect Sends support disabled.");
1712      sText += "</font></small><br />";          sText += "</font></small><br />";
1713  #endif  #endif
1714  #ifndef CONFIG_VOLUME  #ifndef CONFIG_VOLUME
1715      sText += "<small><font color=\"red\">";          sText += "<small><font color=\"red\">";
1716      sText += tr("Global volume support disabled.");          sText += tr("Global volume support disabled.");
1717      sText += "</font></small><br />";          sText += "</font></small><br />";
1718  #endif  #endif
1719  #ifndef CONFIG_MIDI_INSTRUMENT  #ifndef CONFIG_MIDI_INSTRUMENT
1720      sText += "<small><font color=\"red\">";          sText += "<small><font color=\"red\">";
1721      sText += tr("MIDI instrument mapping support disabled.");          sText += tr("MIDI instrument mapping support disabled.");
1722      sText += "</font></small><br />";          sText += "</font></small><br />";
1723  #endif  #endif
1724  #ifndef CONFIG_EDIT_INSTRUMENT  #ifndef CONFIG_EDIT_INSTRUMENT
1725      sText += "<small><font color=\"red\">";          sText += "<small><font color=\"red\">";
1726      sText += tr("Instrument editing support disabled.");          sText += tr("Instrument editing support disabled.");
1727      sText += "</font></small><br />";          sText += "</font></small><br />";
1728  #endif  #endif
1729      sText += "<br />\n";          sText += "<br />\n";
1730      sText += tr("Using") + ": ";          sText += tr("Using") + ": ";
1731      sText += ::lscp_client_package();          sText += ::lscp_client_package();
1732      sText += " ";          sText += " ";
1733      sText += ::lscp_client_version();          sText += ::lscp_client_version();
1734  #ifdef CONFIG_LIBGIG  #ifdef CONFIG_LIBGIG
1735      sText += ", ";          sText += ", ";
1736      sText += gig::libraryName().c_str();          sText += gig::libraryName().c_str();
1737      sText += " ";          sText += " ";
1738      sText += gig::libraryVersion().c_str();          sText += gig::libraryVersion().c_str();
1739  #endif  #endif
1740      sText += "<br />\n";          sText += "<br />\n";
1741      sText += "<br />\n";          sText += "<br />\n";
1742      sText += tr("Website") + ": <a href=\"" QSAMPLER_WEBSITE "\">" QSAMPLER_WEBSITE "</a><br />\n";          sText += tr("Website") + ": <a href=\"" QSAMPLER_WEBSITE "\">" QSAMPLER_WEBSITE "</a><br />\n";
1743      sText += "<br />\n";          sText += "<br />\n";
1744      sText += "<small>";          sText += "<small>";
1745      sText += QSAMPLER_COPYRIGHT "<br />\n";          sText += QSAMPLER_COPYRIGHT "<br />\n";
1746      sText += QSAMPLER_COPYRIGHT2 "<br />\n";          sText += QSAMPLER_COPYRIGHT2 "<br />\n";
1747      sText += "<br />\n";          sText += "<br />\n";
1748      sText += tr("This program is free software; you can redistribute it and/or modify it") + "<br />\n";          sText += tr("This program is free software; you can redistribute it and/or modify it") + "<br />\n";
1749      sText += tr("under the terms of the GNU General Public License version 2 or later.");          sText += tr("under the terms of the GNU General Public License version 2 or later.");
1750      sText += "</small>";          sText += "</small>";
1751      sText += "</p>\n";          sText += "</p>\n";
1752    
1753      QMessageBox::about(this, tr("About") + " " QSAMPLER_TITLE, sText);          QMessageBox::about(this, tr("About") + " " QSAMPLER_TITLE, sText);
1754  }  }
1755    
1756    
# Line 1742  void MainForm::helpAbout (void) Line 1759  void MainForm::helpAbout (void)
1759    
1760  void MainForm::stabilizeForm (void)  void MainForm::stabilizeForm (void)
1761  {  {
1762      // Update the main application caption...          // Update the main application caption...
1763      QString sSessionName = sessionName(m_sFilename);          QString sSessionName = sessionName(m_sFilename);
1764      if (m_iDirtyCount > 0)          if (m_iDirtyCount > 0)
1765          sSessionName += " *";                  sSessionName += " *";
1766      setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));
1767    
1768      // Update the main menu state...          // Update the main menu state...
1769      ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip* pChannelStrip = activeChannelStrip();
1770      bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);          bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);
1771      bool bHasChannel = (bHasClient && pChannelStrip != NULL);          bool bHasChannel = (bHasClient && pChannelStrip != NULL);
1772      ui.fileNewAction->setEnabled(bHasClient);          m_ui.fileNewAction->setEnabled(bHasClient);
1773      ui.fileOpenAction->setEnabled(bHasClient);          m_ui.fileOpenAction->setEnabled(bHasClient);
1774      ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
1775      ui.fileSaveAsAction->setEnabled(bHasClient);          m_ui.fileSaveAsAction->setEnabled(bHasClient);
1776      ui.fileResetAction->setEnabled(bHasClient);          m_ui.fileResetAction->setEnabled(bHasClient);
1777      ui.fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);          m_ui.fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);
1778      ui.editAddChannelAction->setEnabled(bHasClient);          m_ui.editAddChannelAction->setEnabled(bHasClient);
1779      ui.editRemoveChannelAction->setEnabled(bHasChannel);          m_ui.editRemoveChannelAction->setEnabled(bHasChannel);
1780      ui.editSetupChannelAction->setEnabled(bHasChannel);          m_ui.editSetupChannelAction->setEnabled(bHasChannel);
1781  #ifdef CONFIG_EDIT_INSTRUMENT  #ifdef CONFIG_EDIT_INSTRUMENT
1782      ui.editEditChannelAction->setEnabled(bHasChannel);          m_ui.editEditChannelAction->setEnabled(bHasChannel);
1783  #else  #else
1784      ui.editEditChannelAction->setEnabled(false);          m_ui.editEditChannelAction->setEnabled(false);
1785  #endif  #endif
1786      ui.editResetChannelAction->setEnabled(bHasChannel);          m_ui.editResetChannelAction->setEnabled(bHasChannel);
1787      ui.editResetAllChannelsAction->setEnabled(bHasChannel);          m_ui.editResetAllChannelsAction->setEnabled(bHasChannel);
1788      ui.viewMessagesAction->setChecked(m_pMessages && m_pMessages->isVisible());          m_ui.viewMessagesAction->setChecked(m_pMessages && m_pMessages->isVisible());
1789  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
1790          ui.viewInstrumentsAction->setChecked(m_pInstrumentListForm          m_ui.viewInstrumentsAction->setChecked(m_pInstrumentListForm
1791                  && m_pInstrumentListForm->isVisible());                  && m_pInstrumentListForm->isVisible());
1792          ui.viewInstrumentsAction->setEnabled(bHasClient);          m_ui.viewInstrumentsAction->setEnabled(bHasClient);
1793  #else  #else
1794          ui.viewInstrumentsAction->setEnabled(false);          m_ui.viewInstrumentsAction->setEnabled(false);
1795  #endif  #endif
1796          ui.viewDevicesAction->setChecked(m_pDeviceForm          m_ui.viewDevicesAction->setChecked(m_pDeviceForm
1797                  && m_pDeviceForm->isVisible());                  && m_pDeviceForm->isVisible());
1798      ui.viewDevicesAction->setEnabled(bHasClient);          m_ui.viewDevicesAction->setEnabled(bHasClient);
1799      ui.channelsArrangeAction->setEnabled(bHasChannel);          m_ui.channelsArrangeAction->setEnabled(bHasChannel);
1800    
1801  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
1802          // Toolbar widgets are also affected...          // Toolbar widgets are also affected...
1803      m_pVolumeSlider->setEnabled(bHasClient);          m_pVolumeSlider->setEnabled(bHasClient);
1804      m_pVolumeSpinBox->setEnabled(bHasClient);          m_pVolumeSpinBox->setEnabled(bHasClient);
1805  #endif  #endif
1806    
1807      // Client/Server status...          // Client/Server status...
1808      if (bHasClient) {          if (bHasClient) {
1809          m_statusItem[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));                  m_statusItem[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));
1810          m_statusItem[QSAMPLER_STATUS_SERVER]->setText(m_pOptions->sServerHost + ":" + QString::number(m_pOptions->iServerPort));                  m_statusItem[QSAMPLER_STATUS_SERVER]->setText(m_pOptions->sServerHost
1811      } else {                          + ':' + QString::number(m_pOptions->iServerPort));
1812          m_statusItem[QSAMPLER_STATUS_CLIENT]->clear();          } else {
1813          m_statusItem[QSAMPLER_STATUS_SERVER]->clear();                  m_statusItem[QSAMPLER_STATUS_CLIENT]->clear();
1814      }                  m_statusItem[QSAMPLER_STATUS_SERVER]->clear();
1815      // Channel status...          }
1816      if (bHasChannel)          // Channel status...
1817          m_statusItem[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->windowTitle());          if (bHasChannel)
1818      else                  m_statusItem[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->windowTitle());
1819          m_statusItem[QSAMPLER_STATUS_CHANNEL]->clear();          else
1820      // Session status...                  m_statusItem[QSAMPLER_STATUS_CHANNEL]->clear();
1821      if (m_iDirtyCount > 0)          // Session status...
1822          m_statusItem[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));          if (m_iDirtyCount > 0)
1823      else                  m_statusItem[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));
1824          m_statusItem[QSAMPLER_STATUS_SESSION]->clear();          else
1825                    m_statusItem[QSAMPLER_STATUS_SESSION]->clear();
1826    
1827      // Recent files menu.          // Recent files menu.
1828          ui.fileOpenRecentMenu->setEnabled(m_pOptions->recentFiles.count() > 0);          m_ui.fileOpenRecentMenu->setEnabled(m_pOptions->recentFiles.count() > 0);
1829  }  }
1830    
1831    
# Line 1852  void MainForm::channelStripChanged(Chann Line 1870  void MainForm::channelStripChanged(Chann
1870                  pChannelStrip->resetErrorCount();                  pChannelStrip->resetErrorCount();
1871          }          }
1872    
1873      // Just mark the dirty form.          // Just mark the dirty form.
1874      m_iDirtyCount++;          m_iDirtyCount++;
1875      // and update the form status...          // and update the form status...
1876      stabilizeForm();          stabilizeForm();
1877  }  }
1878    
1879    
# Line 1887  void MainForm::updateSession (void) Line 1905  void MainForm::updateSession (void)
1905          if (piChannelIDs == NULL) {          if (piChannelIDs == NULL) {
1906                  if (::lscp_client_get_errno(m_pClient)) {                  if (::lscp_client_get_errno(m_pClient)) {
1907                          appendMessagesClient("lscp_list_channels");                          appendMessagesClient("lscp_list_channels");
1908                          appendMessagesError(tr("Could not get current list of channels.\n\nSorry."));                          appendMessagesError(
1909                                    tr("Could not get current list of channels.\n\nSorry."));
1910                  }                  }
1911          } else {          } else {
1912                  // Try to (re)create each channel.                  // Try to (re)create each channel.
# Line 1900  void MainForm::updateSession (void) Line 1919  void MainForm::updateSession (void)
1919                  m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
1920          }          }
1921    
1922      // Do we auto-arrange?          // Do we auto-arrange?
1923      if (m_pOptions && m_pOptions->bAutoArrange)          if (m_pOptions && m_pOptions->bAutoArrange)
1924          channelsArrange();                  channelsArrange();
1925    
1926          // Remember to refresh devices and instruments...          // Remember to refresh devices and instruments...
1927          if (m_pInstrumentListForm)          if (m_pInstrumentListForm)
1928              m_pInstrumentListForm->refreshInstruments();                  m_pInstrumentListForm->refreshInstruments();
1929          if (m_pDeviceForm)          if (m_pDeviceForm)
1930              m_pDeviceForm->refreshDevices();                  m_pDeviceForm->refreshDevices();
1931  }  }
1932    
1933    
1934  // Update the recent files list and menu.  // Update the recent files list and menu.
1935  void MainForm::updateRecentFiles ( const QString& sFilename )  void MainForm::updateRecentFiles ( const QString& sFilename )
1936  {  {
1937      if (m_pOptions == NULL)          if (m_pOptions == NULL)
1938          return;                  return;
1939    
1940      // Remove from list if already there (avoid duplicates)          // Remove from list if already there (avoid duplicates)
1941      int iIndex = m_pOptions->recentFiles.indexOf(sFilename);          int iIndex = m_pOptions->recentFiles.indexOf(sFilename);
1942      if (iIndex >= 0)          if (iIndex >= 0)
1943          m_pOptions->recentFiles.removeAt(iIndex);                  m_pOptions->recentFiles.removeAt(iIndex);
1944      // Put it to front...          // Put it to front...
1945      m_pOptions->recentFiles.push_front(sFilename);          m_pOptions->recentFiles.push_front(sFilename);
1946  }  }
1947    
1948    
# Line 1941  void MainForm::updateRecentFilesMenu (vo Line 1960  void MainForm::updateRecentFilesMenu (vo
1960          }          }
1961    
1962          // Rebuild the recent files menu...          // Rebuild the recent files menu...
1963          ui.fileOpenRecentMenu->clear();          m_ui.fileOpenRecentMenu->clear();
1964          for (int i = 0; i < iRecentFiles; i++) {          for (int i = 0; i < iRecentFiles; i++) {
1965                  const QString& sFilename = m_pOptions->recentFiles[i];                  const QString& sFilename = m_pOptions->recentFiles[i];
1966                  if (QFileInfo(sFilename).exists()) {                  if (QFileInfo(sFilename).exists()) {
1967                          QAction *pAction = ui.fileOpenRecentMenu->addAction(                          QAction *pAction = m_ui.fileOpenRecentMenu->addAction(
1968                                  QString("&%1 %2").arg(i + 1).arg(sessionName(sFilename)),                                  QString("&%1 %2").arg(i + 1).arg(sessionName(sFilename)),
1969                                  this, SLOT(fileOpenRecent()));                                  this, SLOT(fileOpenRecent()));
1970                          pAction->setData(i);                          pAction->setData(i);
# Line 1957  void MainForm::updateRecentFilesMenu (vo Line 1976  void MainForm::updateRecentFilesMenu (vo
1976  // Force update of the channels instrument names mode.  // Force update of the channels instrument names mode.
1977  void MainForm::updateInstrumentNames (void)  void MainForm::updateInstrumentNames (void)
1978  {  {
1979      // Full channel list update...          // Full channel list update...
1980      QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
1981      if (wlist.isEmpty())          if (wlist.isEmpty())
1982          return;                  return;
1983    
1984      m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
1985      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1986          ChannelStrip *pChannelStrip = (ChannelStrip *) wlist.at(iChannel);                  ChannelStrip *pChannelStrip = (ChannelStrip *) wlist.at(iChannel);
1987          if (pChannelStrip)                  if (pChannelStrip)
1988              pChannelStrip->updateInstrumentName(true);                          pChannelStrip->updateInstrumentName(true);
1989      }          }
1990      m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
1991  }  }
1992    
1993    
1994  // Force update of the channels display font.  // Force update of the channels display font.
1995  void MainForm::updateDisplayFont (void)  void MainForm::updateDisplayFont (void)
1996  {  {
1997      if (m_pOptions == NULL)          if (m_pOptions == NULL)
1998          return;                  return;
1999    
2000            // Check if display font is legal.
2001            if (m_pOptions->sDisplayFont.isEmpty())
2002                    return;
2003            // Realize it.
2004            QFont font;
2005            if (!font.fromString(m_pOptions->sDisplayFont))
2006                    return;
2007    
2008      // Check if display font is legal.          // Full channel list update...
2009      if (m_pOptions->sDisplayFont.isEmpty())          QWidgetList wlist = m_pWorkspace->windowList();
2010          return;          if (wlist.isEmpty())
2011      // Realize it.                  return;
2012      QFont font;  
2013      if (!font.fromString(m_pOptions->sDisplayFont))          m_pWorkspace->setUpdatesEnabled(false);
2014          return;          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
2015                    ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);
2016      // Full channel list update...                  if (pChannelStrip)
2017      QWidgetList wlist = m_pWorkspace->windowList();                          pChannelStrip->setDisplayFont(font);
2018      if (wlist.isEmpty())          }
2019          return;          m_pWorkspace->setUpdatesEnabled(true);
   
     m_pWorkspace->setUpdatesEnabled(false);  
     for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {  
         ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);  
         if (pChannelStrip)  
             pChannelStrip->setDisplayFont(font);  
     }  
     m_pWorkspace->setUpdatesEnabled(true);  
2020  }  }
2021    
2022    
2023  // Update channel strips background effect.  // Update channel strips background effect.
2024  void MainForm::updateDisplayEffect (void)  void MainForm::updateDisplayEffect (void)
2025  {  {
2026      // Full channel list update...          // Full channel list update...
2027      QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
2028      if (wlist.isEmpty())          if (wlist.isEmpty())
2029          return;                  return;
2030    
2031      m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2032      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
2033          ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);
2034                  if (pChannelStrip)                  if (pChannelStrip)
2035                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2036      }          }
2037      m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
2038  }  }
2039    
2040    
2041  // Force update of the channels maximum volume setting.  // Force update of the channels maximum volume setting.
2042  void MainForm::updateMaxVolume (void)  void MainForm::updateMaxVolume (void)
2043  {  {
2044      if (m_pOptions == NULL)          if (m_pOptions == NULL)
2045          return;                  return;
2046    
2047  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
2048          m_iVolumeChanging++;          m_iVolumeChanging++;
# Line 2032  void MainForm::updateMaxVolume (void) Line 2051  void MainForm::updateMaxVolume (void)
2051          m_iVolumeChanging--;          m_iVolumeChanging--;
2052  #endif  #endif
2053    
2054      // Full channel list update...          // Full channel list update...
2055      QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
2056      if (wlist.isEmpty())          if (wlist.isEmpty())
2057          return;                  return;
2058    
2059      m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2060      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
2061          ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);
2062          if (pChannelStrip)                  if (pChannelStrip)
2063              pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2064      }          }
2065      m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
2066  }  }
2067    
2068    
# Line 2053  void MainForm::updateMaxVolume (void) Line 2072  void MainForm::updateMaxVolume (void)
2072  // Messages output methods.  // Messages output methods.
2073  void MainForm::appendMessages( const QString& s )  void MainForm::appendMessages( const QString& s )
2074  {  {
2075      if (m_pMessages)          if (m_pMessages)
2076          m_pMessages->appendMessages(s);                  m_pMessages->appendMessages(s);
2077    
2078      statusBar()->showMessage(s, 3000);          statusBar()->showMessage(s, 3000);
2079  }  }
2080    
2081  void MainForm::appendMessagesColor( const QString& s, const QString& c )  void MainForm::appendMessagesColor( const QString& s, const QString& c )
2082  {  {
2083      if (m_pMessages)          if (m_pMessages)
2084          m_pMessages->appendMessagesColor(s, c);                  m_pMessages->appendMessagesColor(s, c);
2085    
2086      statusBar()->showMessage(s, 3000);          statusBar()->showMessage(s, 3000);
2087  }  }
2088    
2089  void MainForm::appendMessagesText( const QString& s )  void MainForm::appendMessagesText( const QString& s )
2090  {  {
2091      if (m_pMessages)          if (m_pMessages)
2092          m_pMessages->appendMessagesText(s);                  m_pMessages->appendMessagesText(s);
2093  }  }
2094    
2095  void MainForm::appendMessagesError( const QString& s )  void MainForm::appendMessagesError( const QString& s )
2096  {  {
2097      if (m_pMessages)          if (m_pMessages)
2098          m_pMessages->show();                  m_pMessages->show();
2099    
2100      appendMessagesColor(s.simplified(), "#ff0000");          appendMessagesColor(s.simplified(), "#ff0000");
2101    
2102          // Make it look responsive...:)          // Make it look responsive...:)
2103          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2104    
2105      QMessageBox::critical(this,          QMessageBox::critical(this,
2106                  QSAMPLER_TITLE ": " + tr("Error"), s, tr("Cancel"));                  QSAMPLER_TITLE ": " + tr("Error"), s, tr("Cancel"));
2107  }  }
2108    
# Line 2091  void MainForm::appendMessagesError( cons Line 2110  void MainForm::appendMessagesError( cons
2110  // This is a special message format, just for client results.  // This is a special message format, just for client results.
2111  void MainForm::appendMessagesClient( const QString& s )  void MainForm::appendMessagesClient( const QString& s )
2112  {  {
2113      if (m_pClient == NULL)          if (m_pClient == NULL)
2114          return;                  return;
2115    
2116      appendMessagesColor(s + QString(": %1 (errno=%2)")          appendMessagesColor(s + QString(": %1 (errno=%2)")
2117          .arg(::lscp_client_get_result(m_pClient))                  .arg(::lscp_client_get_result(m_pClient))
2118          .arg(::lscp_client_get_errno(m_pClient)), "#996666");                  .arg(::lscp_client_get_errno(m_pClient)), "#996666");
2119    
2120          // Make it look responsive...:)          // Make it look responsive...:)
2121          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
# Line 2106  void MainForm::appendMessagesClient( con Line 2125  void MainForm::appendMessagesClient( con
2125  // Force update of the messages font.  // Force update of the messages font.
2126  void MainForm::updateMessagesFont (void)  void MainForm::updateMessagesFont (void)
2127  {  {
2128      if (m_pOptions == NULL)          if (m_pOptions == NULL)
2129          return;                  return;
2130    
2131      if (m_pMessages && !m_pOptions->sMessagesFont.isEmpty()) {          if (m_pMessages && !m_pOptions->sMessagesFont.isEmpty()) {
2132          QFont font;                  QFont font;
2133          if (font.fromString(m_pOptions->sMessagesFont))                  if (font.fromString(m_pOptions->sMessagesFont))
2134              m_pMessages->setMessagesFont(font);                          m_pMessages->setMessagesFont(font);
2135      }          }
2136  }  }
2137    
2138    
2139  // Update messages window line limit.  // Update messages window line limit.
2140  void MainForm::updateMessagesLimit (void)  void MainForm::updateMessagesLimit (void)
2141  {  {
2142      if (m_pOptions == NULL)          if (m_pOptions == NULL)
2143          return;                  return;
2144    
2145      if (m_pMessages) {          if (m_pMessages) {
2146          if (m_pOptions->bMessagesLimit)                  if (m_pOptions->bMessagesLimit)
2147              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);                          m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);
2148          else                  else
2149              m_pMessages->setMessagesLimit(-1);                          m_pMessages->setMessagesLimit(-1);
2150      }          }
2151  }  }
2152    
2153    
2154  // Enablement of the messages capture feature.  // Enablement of the messages capture feature.
2155  void MainForm::updateMessagesCapture (void)  void MainForm::updateMessagesCapture (void)
2156  {  {
2157      if (m_pOptions == NULL)          if (m_pOptions == NULL)
2158          return;                  return;
2159    
2160      if (m_pMessages)          if (m_pMessages)
2161          m_pMessages->setCaptureEnabled(m_pOptions->bStdoutCapture);                  m_pMessages->setCaptureEnabled(m_pOptions->bStdoutCapture);
2162  }  }
2163    
2164    
# Line 2149  void MainForm::updateMessagesCapture (vo Line 2168  void MainForm::updateMessagesCapture (vo
2168  // The channel strip creation executive.  // The channel strip creation executive.
2169  ChannelStrip* MainForm::createChannelStrip(qsamplerChannel* pChannel)  ChannelStrip* MainForm::createChannelStrip(qsamplerChannel* pChannel)
2170  {  {
2171      if (m_pClient == NULL || pChannel == NULL)          if (m_pClient == NULL || pChannel == NULL)
2172          return NULL;                  return NULL;
2173    
2174      // Prepare for auto-arrange?          // Prepare for auto-arrange?
2175      ChannelStrip* pChannelStrip = NULL;          ChannelStrip* pChannelStrip = NULL;
2176      int y = 0;          int y = 0;
2177      if (m_pOptions && m_pOptions->bAutoArrange) {          if (m_pOptions && m_pOptions->bAutoArrange) {
2178          QWidgetList wlist = m_pWorkspace->windowList();                  QWidgetList wlist = m_pWorkspace->windowList();
2179          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
2180                          pChannelStrip = static_cast<ChannelStrip *> (wlist.at(iChannel));                          pChannelStrip = static_cast<ChannelStrip *> (wlist.at(iChannel));
2181                          if (pChannelStrip) {                          if (pChannelStrip) {
2182                          //  y += pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();                          //  y += pChannelStrip->height()
2183                            //              + pChannelStrip->parentWidget()->baseSize().height();
2184                                  y += pChannelStrip->parentWidget()->frameGeometry().height();                                  y += pChannelStrip->parentWidget()->frameGeometry().height();
2185                          }                          }
2186          }                  }
2187      }          }
2188    
2189      // Add a new channel itema...          // Add a new channel itema...
2190      pChannelStrip = new ChannelStrip();          pChannelStrip = new ChannelStrip();
2191      if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
2192          return NULL;                  return NULL;
2193    
2194          m_pWorkspace->addWindow(pChannelStrip, Qt::FramelessWindowHint);          m_pWorkspace->addWindow(pChannelStrip, Qt::FramelessWindowHint);
2195    
2196      // Actual channel strip setup...          // Actual channel strip setup...
2197      pChannelStrip->setup(pChannel);          pChannelStrip->setup(pChannel);
2198          QObject::connect(pChannelStrip,          QObject::connect(pChannelStrip,
2199                  SIGNAL(channelChanged(ChannelStrip*)),                  SIGNAL(channelChanged(ChannelStrip*)),
2200                  SLOT(channelStripChanged(ChannelStrip*)));                  SLOT(channelStripChanged(ChannelStrip*)));
2201      // Set some initial aesthetic options...          // Set some initial aesthetic options...
2202      if (m_pOptions) {          if (m_pOptions) {
2203          // Background display effect...                  // Background display effect...
2204          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2205          // We'll need a display font.                  // We'll need a display font.
2206          QFont font;                  QFont font;
2207          if (font.fromString(m_pOptions->sDisplayFont))                  if (font.fromString(m_pOptions->sDisplayFont))
2208              pChannelStrip->setDisplayFont(font);                          pChannelStrip->setDisplayFont(font);
2209          // Maximum allowed volume setting.                  // Maximum allowed volume setting.
2210          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                  pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2211      }          }
2212    
2213      // Now we show up us to the world.          // Now we show up us to the world.
2214      pChannelStrip->show();          pChannelStrip->show();
2215      // Only then, we'll auto-arrange...          // Only then, we'll auto-arrange...
2216      if (m_pOptions && m_pOptions->bAutoArrange) {          if (m_pOptions && m_pOptions->bAutoArrange) {
2217          int iWidth  = m_pWorkspace->width();                  int iWidth  = m_pWorkspace->width();
2218      //  int iHeight = pChannel->height() + pChannel->parentWidget()->baseSize().height();          //  int iHeight = pChannel->height()
2219          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();        pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);          //              + pChannel->parentWidget()->baseSize().height();
2220      }                  int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
2221                    pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
2222            }
2223    
2224          // This is pretty new, so we'll watch for it closely.          // This is pretty new, so we'll watch for it closely.
2225          channelStripChanged(pChannelStrip);          channelStripChanged(pChannelStrip);
2226    
2227      // Return our successful reference...          // Return our successful reference...
2228      return pChannelStrip;          return pChannelStrip;
2229  }  }
2230    
2231    
2232  // Retrieve the active channel strip.  // Retrieve the active channel strip.
2233  ChannelStrip* MainForm::activeChannelStrip (void)  ChannelStrip* MainForm::activeChannelStrip (void)
2234  {  {
2235      return static_cast<ChannelStrip *> (m_pWorkspace->activeWindow());          return static_cast<ChannelStrip *> (m_pWorkspace->activeWindow());
2236  }  }
2237    
2238    
2239  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2240  ChannelStrip* MainForm::channelStripAt ( int iChannel )  ChannelStrip* MainForm::channelStripAt ( int iChannel )
2241  {  {
2242      QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
2243      if (wlist.isEmpty())          if (wlist.isEmpty())
2244          return NULL;                  return NULL;
2245    
2246      return static_cast<ChannelStrip *> (wlist.at(iChannel));          return static_cast<ChannelStrip *> (wlist.at(iChannel));
2247  }  }
2248    
2249    
# Line 2250  ChannelStrip* MainForm::channelStrip ( i Line 2272  ChannelStrip* MainForm::channelStrip ( i
2272  // Construct the windows menu.  // Construct the windows menu.
2273  void MainForm::channelsMenuAboutToShow (void)  void MainForm::channelsMenuAboutToShow (void)
2274  {  {
2275      ui.channelsMenu->clear();          m_ui.channelsMenu->clear();
2276          ui.channelsMenu->addAction(ui.channelsArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsArrangeAction);
2277          ui.channelsMenu->addAction(ui.channelsAutoArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsAutoArrangeAction);
2278    
2279      QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
2280      if (!wlist.isEmpty()) {          if (!wlist.isEmpty()) {
2281                  ui.channelsMenu->addSeparator();                  m_ui.channelsMenu->addSeparator();
2282          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
2283                          ChannelStrip* pChannelStrip                          ChannelStrip* pChannelStrip
2284                                  = static_cast<ChannelStrip*> (wlist.at(iChannel));                                  = static_cast<ChannelStrip*> (wlist.at(iChannel));
2285                          if (pChannelStrip) {                          if (pChannelStrip) {
2286                                  QAction *pAction = ui.channelsMenu->addAction(                                  QAction *pAction = m_ui.channelsMenu->addAction(
2287                                          pChannelStrip->windowTitle(), this, SLOT(channelsMenuActivated()));                                          pChannelStrip->windowTitle(),
2288                                            this, SLOT(channelsMenuActivated()));
2289                                  pAction->setCheckable(true);                                  pAction->setCheckable(true);
2290                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);
2291                                  pAction->setData(iChannel);                                  pAction->setData(iChannel);
2292                          }                          }
2293          }                  }
2294      }          }
2295  }  }
2296    
2297    
# Line 2294  void MainForm::channelsMenuActivated (vo Line 2317  void MainForm::channelsMenuActivated (vo
2317  // Set the pseudo-timer delay schedule.  // Set the pseudo-timer delay schedule.
2318  void MainForm::startSchedule ( int iStartDelay )  void MainForm::startSchedule ( int iStartDelay )
2319  {  {
2320      m_iStartDelay  = 1 + (iStartDelay * 1000);          m_iStartDelay  = 1 + (iStartDelay * 1000);
2321      m_iTimerDelay  = 0;          m_iTimerDelay  = 0;
2322  }  }
2323    
2324  // Suspend the pseudo-timer delay schedule.  // Suspend the pseudo-timer delay schedule.
2325  void MainForm::stopSchedule (void)  void MainForm::stopSchedule (void)
2326  {  {
2327      m_iStartDelay  = 0;          m_iStartDelay  = 0;
2328      m_iTimerDelay  = 0;          m_iTimerDelay  = 0;
2329  }  }
2330    
2331  // Timer slot funtion.  // Timer slot funtion.
2332  void MainForm::timerSlot (void)  void MainForm::timerSlot (void)
2333  {  {
2334      if (m_pOptions == NULL)          if (m_pOptions == NULL)
2335          return;                  return;
2336    
2337      // Is it the first shot on server start after a few delay?          // Is it the first shot on server start after a few delay?
2338      if (m_iTimerDelay < m_iStartDelay) {          if (m_iTimerDelay < m_iStartDelay) {
2339          m_iTimerDelay += QSAMPLER_TIMER_MSECS;                  m_iTimerDelay += QSAMPLER_TIMER_MSECS;
2340          if (m_iTimerDelay >= m_iStartDelay) {                  if (m_iTimerDelay >= m_iStartDelay) {
2341              // If we cannot start it now, maybe a lil'mo'later ;)                          // If we cannot start it now, maybe a lil'mo'later ;)
2342              if (!startClient()) {                          if (!startClient()) {
2343                  m_iStartDelay += m_iTimerDelay;                                  m_iStartDelay += m_iTimerDelay;
2344                  m_iTimerDelay  = 0;                                  m_iTimerDelay  = 0;
2345              }                          }
2346          }                  }
2347      }          }
2348    
2349          if (m_pClient) {          if (m_pClient) {
2350                  // Update the channel information for each pending strip...                  // Update the channel information for each pending strip...
# Line 2353  void MainForm::timerSlot (void) Line 2376  void MainForm::timerSlot (void)
2376                  }                  }
2377          }          }
2378    
2379      // Register the next timer slot.          // Register the next timer slot.
2380      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));          QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));
2381  }  }
2382    
2383    
# Line 2364  void MainForm::timerSlot (void) Line 2387  void MainForm::timerSlot (void)
2387  // Start linuxsampler server...  // Start linuxsampler server...
2388  void MainForm::startServer (void)  void MainForm::startServer (void)
2389  {  {
2390      if (m_pOptions == NULL)          if (m_pOptions == NULL)
2391          return;                  return;
2392    
2393      // Aren't already a client, are we?          // Aren't already a client, are we?
2394      if (!m_pOptions->bServerStart || m_pClient)          if (!m_pOptions->bServerStart || m_pClient)
2395          return;                  return;
2396    
2397      // Is the server process instance still here?          // Is the server process instance still here?
2398      if (m_pServer) {          if (m_pServer) {
2399          switch (QMessageBox::warning(this,                  switch (QMessageBox::warning(this,
2400                          QSAMPLER_TITLE ": " + tr("Warning"),                          QSAMPLER_TITLE ": " + tr("Warning"),
2401              tr("Could not start the LinuxSampler server.\n\n"                          tr("Could not start the LinuxSampler server.\n\n"
2402                 "Maybe it ss already started."),                          "Maybe it ss already started."),
2403              tr("Stop"), tr("Kill"), tr("Cancel"))) {                          tr("Stop"), tr("Kill"), tr("Cancel"))) {
2404            case 0:                  case 0:
2405              m_pServer->terminate();                          m_pServer->terminate();
2406              break;                          break;
2407            case 1:                  case 1:
2408              m_pServer->kill();                          m_pServer->kill();
2409              break;                          break;
2410          }                  }
2411          return;                  return;
2412      }          }
2413    
2414            // Reset our timer counters...
2415            stopSchedule();
2416    
2417      // Reset our timer counters...          // Verify we have something to start with...
2418      stopSchedule();          if (m_pOptions->sServerCmdLine.isEmpty())
2419                    return;
2420    
2421      // OK. Let's build the startup process...          // OK. Let's build the startup process...
2422      m_pServer = new QProcess(this);          m_pServer = new QProcess(this);
2423    
2424      // Setup stdout/stderr capture...          // Setup stdout/stderr capture...
2425          //      if (m_pOptions->bStdoutCapture) {  //      if (m_pOptions->bStdoutCapture) {
2426                  //m_pServer->setProcessChannelMode(                  //m_pServer->setProcessChannelMode(
2427                  //      QProcess::StandardOutput);                  //      QProcess::StandardOutput);
2428                  QObject::connect(m_pServer,                  QObject::connect(m_pServer,
# Line 2404  void MainForm::startServer (void) Line 2431  void MainForm::startServer (void)
2431                  QObject::connect(m_pServer,                  QObject::connect(m_pServer,
2432                          SIGNAL(readyReadStandardError()),                          SIGNAL(readyReadStandardError()),
2433                          SLOT(readServerStdout()));                          SLOT(readServerStdout()));
2434          //      }  //      }
2435    
2436          // The unforgiveable signal communication...          // The unforgiveable signal communication...
2437          QObject::connect(m_pServer,          QObject::connect(m_pServer,
2438                  SIGNAL(finished(int,QProcess::ExitStatus)),                  SIGNAL(finished(int,QProcess::ExitStatus)),
2439                  SLOT(processServerExit()));                  SLOT(processServerExit()));
2440    
2441      // Build process arguments...          // Build process arguments...
2442      QStringList serverCmdLine = m_pOptions->sServerCmdLine.split(' ');          QStringList args = m_pOptions->sServerCmdLine.split(' ');
2443            QString sCommand = args[0];
2444      appendMessages(tr("Server is starting..."));          args.removeAt(0);
2445      appendMessagesColor(m_pOptions->sServerCmdLine, "#990099");  
2446            appendMessages(tr("Server is starting..."));
2447            appendMessagesColor(m_pOptions->sServerCmdLine, "#990099");
2448    
2449      const QString prog = (serverCmdLine.size() > 0) ? serverCmdLine[0] : QString();          // Go linuxsampler, go...
2450      const QStringList args = serverCmdLine.mid(1);          m_pServer->start(sCommand, args);
2451            if (!m_pServer->waitForStarted()) {
2452      // Go jack, go...                  appendMessagesError(tr("Could not start server.\n\nSorry."));
2453      m_pServer->start(prog, args);                  processServerExit();
2454      if (!m_pServer->waitForStarted()) {                  return;
2455          appendMessagesError(tr("Could not start server.\n\nSorry."));          }
         processServerExit();  
         return;  
     }  
   
     // Show startup results...  
     appendMessages(tr("Server was started with PID=%1.").arg((long) m_pServer->pid()));  
2456    
2457      // Reset (yet again) the timer counters,          // Show startup results...
2458      // but this time is deferred as the user opted.          appendMessages(
2459      startSchedule(m_pOptions->iStartDelay);                  tr("Server was started with PID=%1.").arg((long) m_pServer->pid()));
2460      stabilizeForm();  
2461            // Reset (yet again) the timer counters,
2462            // but this time is deferred as the user opted.
2463            startSchedule(m_pOptions->iStartDelay);
2464            stabilizeForm();
2465  }  }
2466    
2467    
2468  // Stop linuxsampler server...  // Stop linuxsampler server...
2469  void MainForm::stopServer (void)  void MainForm::stopServer (void)
2470  {  {
2471      // Stop client code.          // Stop client code.
2472      stopClient();          stopClient();
2473    
2474            // And try to stop server.
2475            if (m_pServer) {
2476                    appendMessages(tr("Server is stopping..."));
2477                    if (m_pServer->state() == QProcess::Running)
2478                            m_pServer->terminate();
2479            }
2480    
2481      // And try to stop server.          // Give it some time to terminate gracefully and stabilize...
2482      if (m_pServer) {          QTime t;
2483          appendMessages(tr("Server is stopping..."));          t.start();
2484          if (m_pServer->state() == QProcess::Running)          while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2485              m_pServer->terminate();                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
      }  
   
     // Give it some time to terminate gracefully and stabilize...  
     QTime t;  
     t.start();  
     while (t.elapsed() < QSAMPLER_TIMER_MSECS)  
         QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);  
2486    
2487       // Do final processing anyway.          // Do final processing anyway.
2488       processServerExit();          processServerExit();
2489  }  }
2490    
2491    
2492  // Stdout handler...  // Stdout handler...
2493  void MainForm::readServerStdout (void)  void MainForm::readServerStdout (void)
2494  {  {
2495      if (m_pMessages)          if (m_pMessages)
2496          m_pMessages->appendStdoutBuffer(m_pServer->readAllStandardOutput());                  m_pMessages->appendStdoutBuffer(m_pServer->readAllStandardOutput());
2497  }  }
2498    
2499    
2500  // Linuxsampler server cleanup.  // Linuxsampler server cleanup.
2501  void MainForm::processServerExit (void)  void MainForm::processServerExit (void)
2502  {  {
2503      // Force client code cleanup.          // Force client code cleanup.
2504      stopClient();          stopClient();
2505    
2506      // Flush anything that maybe pending...          // Flush anything that maybe pending...
2507      if (m_pMessages)          if (m_pMessages)
2508          m_pMessages->flushStdoutBuffer();                  m_pMessages->flushStdoutBuffer();
2509    
2510      if (m_pServer) {          if (m_pServer) {
2511          // Force final server shutdown...                  // Force final server shutdown...
2512          appendMessages(tr("Server was stopped with exit status %1.").arg(m_pServer->exitStatus()));                  appendMessages(
2513          m_pServer->terminate();                          tr("Server was stopped with exit status %1.")
2514          if (!m_pServer->waitForFinished(2000))                          .arg(m_pServer->exitStatus()));
2515              m_pServer->kill();                  m_pServer->terminate();
2516          // Destroy it.                  if (!m_pServer->waitForFinished(2000))
2517          delete m_pServer;                          m_pServer->kill();
2518          m_pServer = NULL;                  // Destroy it.
2519      }                  delete m_pServer;
2520                    m_pServer = NULL;
2521            }
2522    
2523      // Again, make status visible stable.          // Again, make status visible stable.
2524      stabilizeForm();          stabilizeForm();
2525  }  }
2526    
2527    
# Line 2501  void MainForm::processServerExit (void) Line 2529  void MainForm::processServerExit (void)
2529  // qsamplerMainForm -- Client stuff.  // qsamplerMainForm -- Client stuff.
2530    
2531  // The LSCP client callback procedure.  // The LSCP client callback procedure.
2532  lscp_status_t qsampler_client_callback ( lscp_client_t */*pClient*/, lscp_event_t event, const char *pchData, int cchData, void *pvData )  lscp_status_t qsampler_client_callback ( lscp_client_t */*pClient*/,
2533            lscp_event_t event, const char *pchData, int cchData, void *pvData )
2534  {  {
2535      MainForm* pMainForm = (MainForm *) pvData;          MainForm* pMainForm = (MainForm *) pvData;
2536      if (pMainForm == NULL)          if (pMainForm == NULL)
2537          return LSCP_FAILED;                  return LSCP_FAILED;
2538    
2539      // ATTN: DO NOT EVER call any GUI code here,          // ATTN: DO NOT EVER call any GUI code here,
2540      // as this is run under some other thread context.          // as this is run under some other thread context.
2541      // A custom event must be posted here...          // A custom event must be posted here...
2542      QApplication::postEvent(pMainForm, new qsamplerCustomEvent(event, pchData, cchData));          QApplication::postEvent(pMainForm,
2543                    new qsamplerCustomEvent(event, pchData, cchData));
2544    
2545      return LSCP_OK;          return LSCP_OK;
2546  }  }
2547    
2548    
2549  // Start our almighty client...  // Start our almighty client...
2550  bool MainForm::startClient (void)  bool MainForm::startClient (void)
2551  {  {
2552      // Have it a setup?          // Have it a setup?
2553      if (m_pOptions == NULL)          if (m_pOptions == NULL)
2554          return false;                  return false;
2555    
2556      // Aren't we already started, are we?          // Aren't we already started, are we?
2557      if (m_pClient)          if (m_pClient)
2558          return true;                  return true;
2559    
2560      // Log prepare here.          // Log prepare here.
2561      appendMessages(tr("Client connecting..."));          appendMessages(tr("Client connecting..."));
2562    
2563      // Create the client handle...          // Create the client handle...
2564          m_pClient = ::lscp_client_create(          m_pClient = ::lscp_client_create(
2565                  m_pOptions->sServerHost.toUtf8().constData(),                  m_pOptions->sServerHost.toUtf8().constData(),
2566                  m_pOptions->iServerPort, qsampler_client_callback, this);                  m_pOptions->iServerPort, qsampler_client_callback, this);
2567      if (m_pClient == NULL) {          if (m_pClient == NULL) {
2568          // Is this the first try?                  // Is this the first try?
2569          // maybe we need to start a local server...                  // maybe we need to start a local server...
2570          if ((m_pServer && m_pServer->state() == QProcess::Running) || !m_pOptions->bServerStart)                  if ((m_pServer && m_pServer->state() == QProcess::Running)
2571              appendMessagesError(tr("Could not connect to server as client.\n\nSorry."));                          || !m_pOptions->bServerStart) {
2572          else                          appendMessagesError(
2573              startServer();                                  tr("Could not connect to server as client.\n\nSorry."));
2574          // This is always a failure.                  } else {
2575          stabilizeForm();                          startServer();
2576          return false;                  }
2577      }                  // This is always a failure.
2578      // Just set receive timeout value, blindly.                  stabilizeForm();
2579      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);                  return false;
2580      appendMessages(tr("Client receive timeout is set to %1 msec.").arg(::lscp_client_get_timeout(m_pClient)));          }
2581            // Just set receive timeout value, blindly.
2582            ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
2583            appendMessages(
2584                    tr("Client receive timeout is set to %1 msec.")
2585                    .arg(::lscp_client_get_timeout(m_pClient)));
2586    
2587          // Subscribe to channel info change notifications...          // Subscribe to channel info change notifications...
2588          if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)          if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)
2589                  appendMessagesClient("lscp_client_subscribe");                  appendMessagesClient("lscp_client_subscribe");
2590    
2591      // We may stop scheduling around.          // We may stop scheduling around.
2592      stopSchedule();          stopSchedule();
2593    
2594      // We'll accept drops from now on...          // We'll accept drops from now on...
2595      setAcceptDrops(true);          setAcceptDrops(true);
2596    
2597      // Log success here.          // Log success here.
2598      appendMessages(tr("Client connected."));          appendMessages(tr("Client connected."));
2599    
2600          // Hard-notify instrumnet and device configuration forms,          // Hard-notify instrumnet and device configuration forms,
2601          // if visible, that we're ready...          // if visible, that we're ready...
2602          if (m_pInstrumentListForm)          if (m_pInstrumentListForm)
2603              m_pInstrumentListForm->refreshInstruments();                  m_pInstrumentListForm->refreshInstruments();
2604          if (m_pDeviceForm)          if (m_pDeviceForm)
2605              m_pDeviceForm->refreshDevices();                  m_pDeviceForm->refreshDevices();
2606    
2607      // Is any session pending to be loaded?          // Is any session pending to be loaded?
2608      if (!m_pOptions->sSessionFile.isEmpty()) {          if (!m_pOptions->sSessionFile.isEmpty()) {
2609          // Just load the prabably startup session...                  // Just load the prabably startup session...
2610          if (loadSessionFile(m_pOptions->sSessionFile)) {                  if (loadSessionFile(m_pOptions->sSessionFile)) {
2611              m_pOptions->sSessionFile = QString::null;                          m_pOptions->sSessionFile = QString::null;
2612              return true;                          return true;
2613          }                  }
2614      }          }
2615    
2616      // Make a new session          // Make a new session
2617      return newSession();          return newSession();
2618  }  }
2619    
2620    
2621  // Stop client...  // Stop client...
2622  void MainForm::stopClient (void)  void MainForm::stopClient (void)
2623  {  {
2624      if (m_pClient == NULL)          if (m_pClient == NULL)
2625          return;                  return;
2626    
2627      // Log prepare here.          // Log prepare here.
2628      appendMessages(tr("Client disconnecting..."));          appendMessages(tr("Client disconnecting..."));
2629    
2630      // Clear timer counters...          // Clear timer counters...
2631      stopSchedule();          stopSchedule();
2632    
2633      // We'll reject drops from now on...          // We'll reject drops from now on...
2634      setAcceptDrops(false);          setAcceptDrops(false);
2635    
2636      // Force any channel strips around, but          // Force any channel strips around, but
2637      // but avoid removing the corresponding          // but avoid removing the corresponding
2638      // channels from the back-end server.          // channels from the back-end server.
2639      m_iDirtyCount = 0;          m_iDirtyCount = 0;
2640      closeSession(false);          closeSession(false);
2641    
2642      // Close us as a client...          // Close us as a client...
2643          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
2644      ::lscp_client_destroy(m_pClient);          ::lscp_client_destroy(m_pClient);
2645      m_pClient = NULL;          m_pClient = NULL;
2646    
2647          // Hard-notify instrumnet and device configuration forms,          // Hard-notify instrumnet and device configuration forms,
2648          // if visible, that we're running out...          // if visible, that we're running out...
2649          if (m_pInstrumentListForm)          if (m_pInstrumentListForm)
2650              m_pInstrumentListForm->refreshInstruments();                  m_pInstrumentListForm->refreshInstruments();
2651          if (m_pDeviceForm)          if (m_pDeviceForm)
2652              m_pDeviceForm->refreshDevices();                  m_pDeviceForm->refreshDevices();
2653    
2654      // Log final here.          // Log final here.
2655      appendMessages(tr("Client disconnected."));          appendMessages(tr("Client disconnected."));
2656    
2657      // Make visible status.          // Make visible status.
2658      stabilizeForm();          stabilizeForm();
2659  }  }
2660    
2661  } // namespace QSampler  } // namespace QSampler

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

  ViewVC Help
Powered by ViewVC