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

Legend:
Removed from v.1499  
changed lines
  Added in v.1515

  ViewVC Help
Powered by ViewVC