/[svn]/qsampler/trunk/src/qsamplerMainForm.cpp
ViewVC logotype

Diff of /qsampler/trunk/src/qsamplerMainForm.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1507 by capela, Wed Nov 21 23:22:18 2007 UTC revision 1691 by schoenebeck, Thu Feb 14 22:31:26 2008 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 77  static inline long lroundf ( float x ) Line 77  static inline long lroundf ( float x )
77  }  }
78  #endif  #endif
79    
80    
81    // All winsock apps needs this.
82    #if defined(WIN32)
83    static WSADATA _wsaData;
84    #endif
85    
86    
87    namespace QSampler {
88    
89  // Timer constant stuff.  // Timer constant stuff.
90  #define QSAMPLER_TIMER_MSECS    200  #define QSAMPLER_TIMER_MSECS    200
91    
# Line 87  static inline long lroundf ( float x ) Line 96  static inline long lroundf ( float x )
96  #define QSAMPLER_STATUS_SESSION 3       // Current session modification state.  #define QSAMPLER_STATUS_SESSION 3       // Current session modification state.
97    
98    
 // All winsock apps needs this.  
 #if defined(WIN32)  
 static WSADATA _wsaData;  
 #endif  
   
   
99  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
100  // qsamplerCustomEvent -- specialty for callback comunication.  // CustomEvent -- specialty for callback comunication.
101    
102  #define QSAMPLER_CUSTOM_EVENT   QEvent::Type(QEvent::User + 0)  #define QSAMPLER_CUSTOM_EVENT   QEvent::Type(QEvent::User + 0)
103    
104  class qsamplerCustomEvent : public QEvent  class CustomEvent : public QEvent
105  {  {
106  public:  public:
107    
108      // Constructor.          // Constructor.
109      qsamplerCustomEvent(lscp_event_t event, const char *pchData, int cchData)          CustomEvent(lscp_event_t event, const char *pchData, int cchData)
110          : QEvent(QSAMPLER_CUSTOM_EVENT)                  : QEvent(QSAMPLER_CUSTOM_EVENT)
111      {          {
112          m_event = event;                  m_event = event;
113          m_data  = QString::fromUtf8(pchData, cchData);                  m_data  = QString::fromUtf8(pchData, cchData);
114      }          }
115    
116      // Accessors.          // Accessors.
117      lscp_event_t event() { return m_event; }          lscp_event_t event() { return m_event; }
118      QString&     data()  { return m_data;  }          QString&     data()  { return m_data;  }
119    
120  private:  private:
121    
122      // The proper event type.          // The proper event type.
123      lscp_event_t m_event;          lscp_event_t m_event;
124      // The event data as a string.          // The event data as a string.
125      QString      m_data;          QString      m_data;
126  };  };
127    
128    
129  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
130  // qsamplerMainForm -- Main window form implementation.  // qsamplerMainForm -- Main window form implementation.
131    
 namespace QSampler {  
   
132  // Kind of singleton reference.  // Kind of singleton reference.
133  MainForm* MainForm::g_pMainForm = NULL;  MainForm* MainForm::g_pMainForm = NULL;
134    
135  MainForm::MainForm(QWidget* parent) : QMainWindow(parent) {  MainForm::MainForm ( QWidget *pParent )
136      ui.setupUi(this);          : QMainWindow(pParent)
137    {
138            m_ui.setupUi(this);
139    
140          // Pseudo-singleton reference setup.          // Pseudo-singleton reference setup.
141          g_pMainForm = this;          g_pMainForm = this;
142    
143      // Initialize some pointer references.          // Initialize some pointer references.
144      m_pOptions = NULL;          m_pOptions = NULL;
145    
146      // All child forms are to be created later, not earlier than setup.          // All child forms are to be created later, not earlier than setup.
147      m_pMessages = NULL;          m_pMessages = NULL;
148      m_pInstrumentListForm = NULL;          m_pInstrumentListForm = NULL;
149      m_pDeviceForm = NULL;          m_pDeviceForm = NULL;
150    
151      // We'll start clean.          // We'll start clean.
152      m_iUntitled   = 0;          m_iUntitled   = 0;
153      m_iDirtyCount = 0;          m_iDirtyCount = 0;
154    
155      m_pServer = NULL;          m_pServer = NULL;
156      m_pClient = NULL;          m_pClient = NULL;
157    
158      m_iStartDelay = 0;          m_iStartDelay = 0;
159      m_iTimerDelay = 0;          m_iTimerDelay = 0;
160    
161      m_iTimerSlot = 0;          m_iTimerSlot = 0;
162    
163  #ifdef HAVE_SIGNAL_H  #ifdef HAVE_SIGNAL_H
164          // Set to ignore any fatal "Broken pipe" signals.          // Set to ignore any fatal "Broken pipe" signals.
# Line 163  MainForm::MainForm(QWidget* parent) : QM Line 166  MainForm::MainForm(QWidget* parent) : QM
166  #endif  #endif
167    
168  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
169      // Make some extras into the toolbar...          // Make some extras into the toolbar...
170          const QString& sVolumeText = tr("Master volume");          const QString& sVolumeText = tr("Master volume");
171          m_iVolumeChanging = 0;          m_iVolumeChanging = 0;
172          // Volume slider...          // Volume slider...
173          ui.channelsToolbar->addSeparator();          m_ui.channelsToolbar->addSeparator();
174          m_pVolumeSlider = new QSlider(Qt::Horizontal, ui.channelsToolbar);          m_pVolumeSlider = new QSlider(Qt::Horizontal, m_ui.channelsToolbar);
175          m_pVolumeSlider->setTickPosition(QSlider::TicksBelow);          m_pVolumeSlider->setTickPosition(QSlider::TicksBothSides);
176          m_pVolumeSlider->setTickInterval(10);          m_pVolumeSlider->setTickInterval(10);
177          m_pVolumeSlider->setPageStep(10);          m_pVolumeSlider->setPageStep(10);
178          m_pVolumeSlider->setSingleStep(10);          m_pVolumeSlider->setSingleStep(10);
# Line 181  MainForm::MainForm(QWidget* parent) : QM Line 184  MainForm::MainForm(QWidget* parent) : QM
184          QObject::connect(m_pVolumeSlider,          QObject::connect(m_pVolumeSlider,
185                  SIGNAL(valueChanged(int)),                  SIGNAL(valueChanged(int)),
186                  SLOT(volumeChanged(int)));                  SLOT(volumeChanged(int)));
187          //ui.channelsToolbar->setHorizontallyStretchable(true);          //m_ui.channelsToolbar->setHorizontallyStretchable(true);
188          //ui.channelsToolbar->setStretchableWidget(m_pVolumeSlider);          //m_ui.channelsToolbar->setStretchableWidget(m_pVolumeSlider);
189      ui.channelsToolbar->addWidget(m_pVolumeSlider);          m_ui.channelsToolbar->addWidget(m_pVolumeSlider);
190          // Volume spin-box          // Volume spin-box
191          ui.channelsToolbar->addSeparator();          m_ui.channelsToolbar->addSeparator();
192          m_pVolumeSpinBox = new QSpinBox(ui.channelsToolbar);          m_pVolumeSpinBox = new QSpinBox(m_ui.channelsToolbar);
193            m_pVolumeSpinBox->setMaximumHeight(24);
194          m_pVolumeSpinBox->setSuffix(" %");          m_pVolumeSpinBox->setSuffix(" %");
195          m_pVolumeSpinBox->setMinimum(0);          m_pVolumeSpinBox->setMinimum(0);
196          m_pVolumeSpinBox->setMaximum(100);          m_pVolumeSpinBox->setMaximum(100);
# Line 194  MainForm::MainForm(QWidget* parent) : QM Line 198  MainForm::MainForm(QWidget* parent) : QM
198          QObject::connect(m_pVolumeSpinBox,          QObject::connect(m_pVolumeSpinBox,
199                  SIGNAL(valueChanged(int)),                  SIGNAL(valueChanged(int)),
200                  SLOT(volumeChanged(int)));                  SLOT(volumeChanged(int)));
201      ui.channelsToolbar->addWidget(m_pVolumeSpinBox);          m_ui.channelsToolbar->addWidget(m_pVolumeSpinBox);
202  #endif  #endif
203    
204      // Make it an MDI workspace.          // Make it an MDI workspace.
205      m_pWorkspace = new QWorkspace(this);          m_pWorkspace = new QWorkspace(this);
206      m_pWorkspace->setScrollBarsEnabled(true);          m_pWorkspace->setScrollBarsEnabled(true);
207          // Set the activation connection.          // Set the activation connection.
208          QObject::connect(m_pWorkspace,          QObject::connect(m_pWorkspace,
209                  SIGNAL(windowActivated(QWidget *)),                  SIGNAL(windowActivated(QWidget *)),
210                  SLOT(stabilizeForm()));                  SLOT(activateStrip(QWidget *)));
211      // Make it shine :-)          // Make it shine :-)
212      setCentralWidget(m_pWorkspace);          setCentralWidget(m_pWorkspace);
213    
214      // Create some statusbar labels...          // Create some statusbar labels...
215      QLabel *pLabel;          QLabel *pLabel;
216      // Client status.          // Client status.
217      pLabel = new QLabel(tr("Connected"), this);          pLabel = new QLabel(tr("Connected"), this);
218      pLabel->setAlignment(Qt::AlignLeft);          pLabel->setAlignment(Qt::AlignLeft);
219      pLabel->setMinimumSize(pLabel->sizeHint());          pLabel->setMinimumSize(pLabel->sizeHint());
220      m_statusItem[QSAMPLER_STATUS_CLIENT] = pLabel;          m_statusItem[QSAMPLER_STATUS_CLIENT] = pLabel;
221      statusBar()->addWidget(pLabel);          statusBar()->addWidget(pLabel);
222      // Server address.          // Server address.
223      pLabel = new QLabel(this);          pLabel = new QLabel(this);
224      pLabel->setAlignment(Qt::AlignLeft);          pLabel->setAlignment(Qt::AlignLeft);
225      m_statusItem[QSAMPLER_STATUS_SERVER] = pLabel;          m_statusItem[QSAMPLER_STATUS_SERVER] = pLabel;
226      statusBar()->addWidget(pLabel, 1);          statusBar()->addWidget(pLabel, 1);
227      // Channel title.          // Channel title.
228      pLabel = new QLabel(this);          pLabel = new QLabel(this);
229      pLabel->setAlignment(Qt::AlignLeft);          pLabel->setAlignment(Qt::AlignLeft);
230      m_statusItem[QSAMPLER_STATUS_CHANNEL] = pLabel;          m_statusItem[QSAMPLER_STATUS_CHANNEL] = pLabel;
231      statusBar()->addWidget(pLabel, 2);          statusBar()->addWidget(pLabel, 2);
232      // Session modification status.          // Session modification status.
233      pLabel = new QLabel(tr("MOD"), this);          pLabel = new QLabel(tr("MOD"), this);
234      pLabel->setAlignment(Qt::AlignHCenter);          pLabel->setAlignment(Qt::AlignHCenter);
235      pLabel->setMinimumSize(pLabel->sizeHint());          pLabel->setMinimumSize(pLabel->sizeHint());
236      m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
237      statusBar()->addWidget(pLabel);          statusBar()->addWidget(pLabel);
238    
239  #if defined(WIN32)  #if defined(WIN32)
240      WSAStartup(MAKEWORD(1, 1), &_wsaData);          WSAStartup(MAKEWORD(1, 1), &_wsaData);
241  #endif  #endif
242    
243          QObject::connect(ui.fileNewAction,          // Some actions surely need those
244            // shortcuts firmly attached...
245            addAction(m_ui.viewMenubarAction);
246            addAction(m_ui.viewToolbarAction);
247    
248            QObject::connect(m_ui.fileNewAction,
249                  SIGNAL(triggered()),                  SIGNAL(triggered()),
250                  SLOT(fileNew()));                  SLOT(fileNew()));
251          QObject::connect(ui.fileOpenAction,          QObject::connect(m_ui.fileOpenAction,
252                  SIGNAL(triggered()),                  SIGNAL(triggered()),
253                  SLOT(fileOpen()));                  SLOT(fileOpen()));
254          QObject::connect(ui.fileSaveAction,          QObject::connect(m_ui.fileSaveAction,
255                  SIGNAL(triggered()),                  SIGNAL(triggered()),
256                  SLOT(fileSave()));                  SLOT(fileSave()));
257          QObject::connect(ui.fileSaveAsAction,          QObject::connect(m_ui.fileSaveAsAction,
258                  SIGNAL(triggered()),                  SIGNAL(triggered()),
259                  SLOT(fileSaveAs()));                  SLOT(fileSaveAs()));
260          QObject::connect(ui.fileResetAction,          QObject::connect(m_ui.fileResetAction,
261                  SIGNAL(triggered()),                  SIGNAL(triggered()),
262                  SLOT(fileReset()));                  SLOT(fileReset()));
263          QObject::connect(ui.fileRestartAction,          QObject::connect(m_ui.fileRestartAction,
264                  SIGNAL(triggered()),                  SIGNAL(triggered()),
265                  SLOT(fileRestart()));                  SLOT(fileRestart()));
266          QObject::connect(ui.fileExitAction,          QObject::connect(m_ui.fileExitAction,
267                  SIGNAL(triggered()),                  SIGNAL(triggered()),
268                  SLOT(fileExit()));                  SLOT(fileExit()));
269          QObject::connect(ui.editAddChannelAction,          QObject::connect(m_ui.editAddChannelAction,
270                  SIGNAL(triggered()),                  SIGNAL(triggered()),
271                  SLOT(editAddChannel()));                  SLOT(editAddChannel()));
272          QObject::connect(ui.editRemoveChannelAction,          QObject::connect(m_ui.editRemoveChannelAction,
273                  SIGNAL(triggered()),                  SIGNAL(triggered()),
274                  SLOT(editRemoveChannel()));                  SLOT(editRemoveChannel()));
275          QObject::connect(ui.editSetupChannelAction,          QObject::connect(m_ui.editSetupChannelAction,
276                  SIGNAL(triggered()),                  SIGNAL(triggered()),
277                  SLOT(editSetupChannel()));                  SLOT(editSetupChannel()));
278          QObject::connect(ui.editEditChannelAction,          QObject::connect(m_ui.editEditChannelAction,
279                  SIGNAL(triggered()),                  SIGNAL(triggered()),
280                  SLOT(editEditChannel()));                  SLOT(editEditChannel()));
281          QObject::connect(ui.editResetChannelAction,          QObject::connect(m_ui.editResetChannelAction,
282                  SIGNAL(triggered()),                  SIGNAL(triggered()),
283                  SLOT(editResetChannel()));                  SLOT(editResetChannel()));
284          QObject::connect(ui.editResetAllChannelsAction,          QObject::connect(m_ui.editResetAllChannelsAction,
285                  SIGNAL(triggered()),                  SIGNAL(triggered()),
286                  SLOT(editResetAllChannels()));                  SLOT(editResetAllChannels()));
287          QObject::connect(ui.viewMenubarAction,          QObject::connect(m_ui.viewMenubarAction,
288                  SIGNAL(toggled(bool)),                  SIGNAL(toggled(bool)),
289                  SLOT(viewMenubar(bool)));                  SLOT(viewMenubar(bool)));
290          QObject::connect(ui.viewToolbarAction,          QObject::connect(m_ui.viewToolbarAction,
291                  SIGNAL(toggled(bool)),                  SIGNAL(toggled(bool)),
292                  SLOT(viewToolbar(bool)));                  SLOT(viewToolbar(bool)));
293          QObject::connect(ui.viewStatusbarAction,          QObject::connect(m_ui.viewStatusbarAction,
294                  SIGNAL(toggled(bool)),                  SIGNAL(toggled(bool)),
295                  SLOT(viewStatusbar(bool)));                  SLOT(viewStatusbar(bool)));
296          QObject::connect(ui.viewMessagesAction,          QObject::connect(m_ui.viewMessagesAction,
297                  SIGNAL(toggled(bool)),                  SIGNAL(toggled(bool)),
298                  SLOT(viewMessages(bool)));                  SLOT(viewMessages(bool)));
299          QObject::connect(ui.viewInstrumentsAction,          QObject::connect(m_ui.viewInstrumentsAction,
300                  SIGNAL(triggered()),                  SIGNAL(triggered()),
301                  SLOT(viewInstruments()));                  SLOT(viewInstruments()));
302          QObject::connect(ui.viewDevicesAction,          QObject::connect(m_ui.viewDevicesAction,
303                  SIGNAL(triggered()),                  SIGNAL(triggered()),
304                  SLOT(viewDevices()));                  SLOT(viewDevices()));
305          QObject::connect(ui.viewOptionsAction,          QObject::connect(m_ui.viewOptionsAction,
306                  SIGNAL(triggered()),                  SIGNAL(triggered()),
307                  SLOT(viewOptions()));                  SLOT(viewOptions()));
308          QObject::connect(ui.channelsArrangeAction,          QObject::connect(m_ui.channelsArrangeAction,
309                  SIGNAL(triggered()),                  SIGNAL(triggered()),
310                  SLOT(channelsArrange()));                  SLOT(channelsArrange()));
311          QObject::connect(ui.channelsAutoArrangeAction,          QObject::connect(m_ui.channelsAutoArrangeAction,
312                  SIGNAL(toggled(bool)),                  SIGNAL(toggled(bool)),
313                  SLOT(channelsAutoArrange(bool)));                  SLOT(channelsAutoArrange(bool)));
314          QObject::connect(ui.helpAboutAction,          QObject::connect(m_ui.helpAboutAction,
315                  SIGNAL(triggered()),                  SIGNAL(triggered()),
316                  SLOT(helpAbout()));                  SLOT(helpAbout()));
317          QObject::connect(ui.helpAboutQtAction,          QObject::connect(m_ui.helpAboutQtAction,
318                  SIGNAL(triggered()),                  SIGNAL(triggered()),
319                  SLOT(helpAboutQt()));                  SLOT(helpAboutQt()));
320    
321          QObject::connect(ui.fileMenu,          QObject::connect(m_ui.fileMenu,
322                  SIGNAL(aboutToShow()),                  SIGNAL(aboutToShow()),
323                  SLOT(updateRecentFilesMenu()));                  SLOT(updateRecentFilesMenu()));
324          QObject::connect(ui.channelsMenu,          QObject::connect(m_ui.channelsMenu,
325                  SIGNAL(aboutToShow()),                  SIGNAL(aboutToShow()),
326                  SLOT(channelsMenuAboutToShow()));                  SLOT(channelsMenuAboutToShow()));
327  }  }
# Line 320  MainForm::MainForm(QWidget* parent) : QM Line 329  MainForm::MainForm(QWidget* parent) : QM
329  // Destructor.  // Destructor.
330  MainForm::~MainForm()  MainForm::~MainForm()
331  {  {
332      // Do final processing anyway.          // Do final processing anyway.
333      processServerExit();          processServerExit();
334    
335  #if defined(WIN32)  #if defined(WIN32)
336      WSACleanup();          WSACleanup();
337  #endif  #endif
338    
339      // Finally drop any widgets around...          // Finally drop any widgets around...
340      if (m_pDeviceForm)          if (m_pDeviceForm)
341          delete m_pDeviceForm;                  delete m_pDeviceForm;
342      if (m_pInstrumentListForm)          if (m_pInstrumentListForm)
343          delete m_pInstrumentListForm;                  delete m_pInstrumentListForm;
344      if (m_pMessages)          if (m_pMessages)
345          delete m_pMessages;                  delete m_pMessages;
346      if (m_pWorkspace)          if (m_pWorkspace)
347          delete m_pWorkspace;                  delete m_pWorkspace;
348    
349      // Delete status item labels one by one.          // Delete status item labels one by one.
350      if (m_statusItem[QSAMPLER_STATUS_CLIENT])          if (m_statusItem[QSAMPLER_STATUS_CLIENT])
351          delete m_statusItem[QSAMPLER_STATUS_CLIENT];                  delete m_statusItem[QSAMPLER_STATUS_CLIENT];
352      if (m_statusItem[QSAMPLER_STATUS_SERVER])          if (m_statusItem[QSAMPLER_STATUS_SERVER])
353          delete m_statusItem[QSAMPLER_STATUS_SERVER];                  delete m_statusItem[QSAMPLER_STATUS_SERVER];
354      if (m_statusItem[QSAMPLER_STATUS_CHANNEL])          if (m_statusItem[QSAMPLER_STATUS_CHANNEL])
355          delete m_statusItem[QSAMPLER_STATUS_CHANNEL];                  delete m_statusItem[QSAMPLER_STATUS_CHANNEL];
356      if (m_statusItem[QSAMPLER_STATUS_SESSION])          if (m_statusItem[QSAMPLER_STATUS_SESSION])
357          delete m_statusItem[QSAMPLER_STATUS_SESSION];                  delete m_statusItem[QSAMPLER_STATUS_SESSION];
358    
359  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
360          delete m_pVolumeSpinBox;          delete m_pVolumeSpinBox;
# Line 358  MainForm::~MainForm() Line 367  MainForm::~MainForm()
367    
368    
369  // Make and set a proper setup options step.  // Make and set a proper setup options step.
370  void MainForm::setup ( qsamplerOptions *pOptions )  void MainForm::setup ( Options *pOptions )
371  {  {
372      // We got options?          // We got options?
373      m_pOptions = pOptions;          m_pOptions = pOptions;
374    
375      // What style do we create these forms?          // What style do we create these forms?
376          Qt::WindowFlags wflags = Qt::Window          Qt::WindowFlags wflags = Qt::Window
377  #if QT_VERSION >= 0x040200  #if QT_VERSION >= 0x040200
378                  | Qt::CustomizeWindowHint                  | Qt::CustomizeWindowHint
# Line 373  void MainForm::setup ( qsamplerOptions * Line 382  void MainForm::setup ( qsamplerOptions *
382                  | Qt::WindowMinMaxButtonsHint;                  | Qt::WindowMinMaxButtonsHint;
383          if (m_pOptions->bKeepOnTop)          if (m_pOptions->bKeepOnTop)
384                  wflags |= Qt::Tool;                  wflags |= Qt::Tool;
385      // Some child forms are to be created right now.          // Some child forms are to be created right now.
386      m_pMessages = new qsamplerMessages(this);          m_pMessages = new Messages(this);
387      m_pDeviceForm = new DeviceForm(this, wflags);          m_pDeviceForm = new DeviceForm(this, wflags);
388  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
389      m_pInstrumentListForm = new InstrumentListForm(this, wflags);          m_pInstrumentListForm = new InstrumentListForm(this, wflags);
         QObject::connect(&m_pInstrumentListForm->model,  
                 SIGNAL(instrumentsChanged()),  
                 SLOT(sessionDirty()));  
390  #else  #else
391          viewInstrumentsAction->setEnabled(false);          viewInstrumentsAction->setEnabled(false);
392  #endif  #endif
393      // Set message defaults...          // Set message defaults...
394      updateMessagesFont();          updateMessagesFont();
395      updateMessagesLimit();          updateMessagesLimit();
396      updateMessagesCapture();          updateMessagesCapture();
397      // Set the visibility signal.          // Set the visibility signal.
398          QObject::connect(m_pMessages,          QObject::connect(m_pMessages,
399                  SIGNAL(visibilityChanged(bool)),                  SIGNAL(visibilityChanged(bool)),
400                  SLOT(stabilizeForm()));                  SLOT(stabilizeForm()));
401    
402      // Initial decorations toggle state.          // Initial decorations toggle state.
403      ui.viewMenubarAction->setChecked(m_pOptions->bMenubar);          m_ui.viewMenubarAction->setChecked(m_pOptions->bMenubar);
404      ui.viewToolbarAction->setChecked(m_pOptions->bToolbar);          m_ui.viewToolbarAction->setChecked(m_pOptions->bToolbar);
405      ui.viewStatusbarAction->setChecked(m_pOptions->bStatusbar);          m_ui.viewStatusbarAction->setChecked(m_pOptions->bStatusbar);
406      ui.channelsAutoArrangeAction->setChecked(m_pOptions->bAutoArrange);          m_ui.channelsAutoArrangeAction->setChecked(m_pOptions->bAutoArrange);
407    
408      // Initial decorations visibility state.          // Initial decorations visibility state.
409      viewMenubar(m_pOptions->bMenubar);          viewMenubar(m_pOptions->bMenubar);
410      viewToolbar(m_pOptions->bToolbar);          viewToolbar(m_pOptions->bToolbar);
411      viewStatusbar(m_pOptions->bStatusbar);          viewStatusbar(m_pOptions->bStatusbar);
412    
413      addDockWidget(Qt::BottomDockWidgetArea, m_pMessages);          addDockWidget(Qt::BottomDockWidgetArea, m_pMessages);
414    
415          // Restore whole dock windows state.          // Restore whole dock windows state.
416          QByteArray aDockables = m_pOptions->settings().value(          QByteArray aDockables = m_pOptions->settings().value(
# Line 413  void MainForm::setup ( qsamplerOptions * Line 419  void MainForm::setup ( qsamplerOptions *
419                  restoreState(aDockables);                  restoreState(aDockables);
420          }          }
421    
422      // Try to restore old window positioning and initial visibility.          // Try to restore old window positioning and initial visibility.
423      m_pOptions->loadWidgetGeometry(this);          m_pOptions->loadWidgetGeometry(this);
424      m_pOptions->loadWidgetGeometry(m_pInstrumentListForm);          m_pOptions->loadWidgetGeometry(m_pInstrumentListForm);
425      m_pOptions->loadWidgetGeometry(m_pDeviceForm);          m_pOptions->loadWidgetGeometry(m_pDeviceForm);
426    
427      // Final startup stabilization...          // Final startup stabilization...
428      updateMaxVolume();          updateMaxVolume();
429      updateRecentFilesMenu();          updateRecentFilesMenu();
430      stabilizeForm();          stabilizeForm();
431    
432      // Make it ready :-)          // Make it ready :-)
433      statusBar()->showMessage(tr("Ready"), 3000);          statusBar()->showMessage(tr("Ready"), 3000);
434    
435      // We'll try to start immediately...          // We'll try to start immediately...
436      startSchedule(0);          startSchedule(0);
437    
438      // Register the first timer slot.          // Register the first timer slot.
439      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));          QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));
440  }  }
441    
442    
443  // Window close event handlers.  // Window close event handlers.
444  bool MainForm::queryClose (void)  bool MainForm::queryClose (void)
445  {  {
446      bool bQueryClose = closeSession(false);          bool bQueryClose = closeSession(false);
447    
448      // Try to save current general state...          // Try to save current general state...
449      if (m_pOptions) {          if (m_pOptions) {
450          // Some windows default fonts is here on demand too.                  // Some windows default fonts is here on demand too.
451          if (bQueryClose && m_pMessages)                  if (bQueryClose && m_pMessages)
452              m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();
453          // Try to save current positioning.                  // Try to save current positioning.
454          if (bQueryClose) {                  if (bQueryClose) {
455              // Save decorations state.                          // Save decorations state.
456              m_pOptions->bMenubar = ui.MenuBar->isVisible();                          m_pOptions->bMenubar = m_ui.MenuBar->isVisible();
457              m_pOptions->bToolbar = (ui.fileToolbar->isVisible() || ui.editToolbar->isVisible() || ui.channelsToolbar->isVisible());                          m_pOptions->bToolbar = (m_ui.fileToolbar->isVisible()
458              m_pOptions->bStatusbar = statusBar()->isVisible();                                  || m_ui.editToolbar->isVisible()
459              // Save the dock windows state.                                  || m_ui.channelsToolbar->isVisible());
460              const QString sDockables = saveState().toBase64().data();                          m_pOptions->bStatusbar = statusBar()->isVisible();
461                            // Save the dock windows state.
462                            const QString sDockables = saveState().toBase64().data();
463                          m_pOptions->settings().setValue("/Layout/DockWindows", saveState());                          m_pOptions->settings().setValue("/Layout/DockWindows", saveState());
464              // And the children, and the main windows state,.                          // And the children, and the main windows state,.
465                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);
466                          m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);                          m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
467                          m_pOptions->saveWidgetGeometry(this);                          m_pOptions->saveWidgetGeometry(this);
# Line 462  bool MainForm::queryClose (void) Line 470  bool MainForm::queryClose (void)
470                                  m_pInstrumentListForm->close();                                  m_pInstrumentListForm->close();
471                          if (m_pDeviceForm)                          if (m_pDeviceForm)
472                                  m_pDeviceForm->close();                                  m_pDeviceForm->close();
473              // Stop client and/or server, gracefully.                          // Stop client and/or server, gracefully.
474              stopServer();                          stopServer(true /*interactive*/);
475          }                  }
476      }          }
477    
478      return bQueryClose;          return bQueryClose;
479  }  }
480    
481    
482  void MainForm::closeEvent ( QCloseEvent *pCloseEvent )  void MainForm::closeEvent ( QCloseEvent *pCloseEvent )
483  {  {
484      if (queryClose())          if (queryClose())
485          pCloseEvent->accept();                  pCloseEvent->accept();
486      else          else
487          pCloseEvent->ignore();                  pCloseEvent->ignore();
488  }  }
489    
490    
# Line 504  void MainForm::dropEvent ( QDropEvent* p Line 512  void MainForm::dropEvent ( QDropEvent* p
512                  QListIterator<QUrl> iter(pMimeData->urls());                  QListIterator<QUrl> iter(pMimeData->urls());
513                  while (iter.hasNext()) {                  while (iter.hasNext()) {
514                          const QString& sPath = iter.next().toLocalFile();                          const QString& sPath = iter.next().toLocalFile();
515                          if (qsamplerChannel::isInstrumentFile(sPath)) {                          if (Channel::isInstrumentFile(sPath)) {
516                                  // Try to create a new channel from instrument file...                                  // Try to create a new channel from instrument file...
517                                  qsamplerChannel *pChannel = new qsamplerChannel();                                  Channel *pChannel = new Channel();
518                                  if (pChannel == NULL)                                  if (pChannel == NULL)
519                                          return;                                          return;
520                                  // Start setting the instrument filename...                                  // Start setting the instrument filename...
# Line 540  void MainForm::dropEvent ( QDropEvent* p Line 548  void MainForm::dropEvent ( QDropEvent* p
548  // Custome event handler.  // Custome event handler.
549  void MainForm::customEvent(QEvent* pCustomEvent)  void MainForm::customEvent(QEvent* pCustomEvent)
550  {  {
551      // For the time being, just pump it to messages.          // For the time being, just pump it to messages.
552      if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {          if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {
553          qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;                  CustomEvent *pEvent = static_cast<CustomEvent *> (pCustomEvent);
554                  if (pEvent->event() == LSCP_EVENT_CHANNEL_INFO) {                  switch (pEvent->event()) {
555                          int iChannelID = pEvent->data().toInt();                          case LSCP_EVENT_CHANNEL_INFO: {
556                          ChannelStrip *pChannelStrip = channelStrip(iChannelID);                                  int iChannelID = pEvent->data().toInt();
557                          if (pChannelStrip)                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);
558                                  channelStripChanged(pChannelStrip);                                  if (pChannelStrip)
559                  } else {                                          channelStripChanged(pChannelStrip);
560                          appendMessagesColor(tr("Notify event: %1 data: %2")                                  break;
561                                  .arg(::lscp_event_to_text(pEvent->event()))                          }
562                                  .arg(pEvent->data()), "#996699");  #if CONFIG_LSCP_CHANNEL_MIDI
563                            case LSCP_EVENT_CHANNEL_MIDI: {
564                                    int iChannelID = pEvent->data().toInt();
565                                    ChannelStrip *pChannelStrip = channelStrip(iChannelID);
566                                    if (pChannelStrip)
567                                            pChannelStrip->midiArrived();
568                                    break;
569                            }
570    #endif
571                            default:
572                                    appendMessagesColor(tr("Notify event: %1 data: %2")
573                                            .arg(::lscp_event_to_text(pEvent->event()))
574                                            .arg(pEvent->data()), "#996699");
575                  }                  }
576      }          }
577  }  }
578    
579  // Context menu event handler.  // Context menu event handler.
580  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )
581  {  {
582      stabilizeForm();          stabilizeForm();
583    
584      ui.editMenu->exec(pEvent->globalPos());          m_ui.editMenu->exec(pEvent->globalPos());
585  }  }
586    
587    
# Line 569  void MainForm::contextMenuEvent( QContex Line 589  void MainForm::contextMenuEvent( QContex
589  // qsamplerMainForm -- Brainless public property accessors.  // qsamplerMainForm -- Brainless public property accessors.
590    
591  // The global options settings property.  // The global options settings property.
592  qsamplerOptions *MainForm::options (void)  Options *MainForm::options (void) const
593  {  {
594      return m_pOptions;          return m_pOptions;
595  }  }
596    
597    
598  // The LSCP client descriptor property.  // The LSCP client descriptor property.
599  lscp_client_t *MainForm::client (void)  lscp_client_t *MainForm::client (void) const
600  {  {
601      return m_pClient;          return m_pClient;
602  }  }
603    
604    
# Line 595  MainForm *MainForm::getInstance (void) Line 615  MainForm *MainForm::getInstance (void)
615  // Format the displayable session filename.  // Format the displayable session filename.
616  QString MainForm::sessionName ( const QString& sFilename )  QString MainForm::sessionName ( const QString& sFilename )
617  {  {
618      bool bCompletePath = (m_pOptions && m_pOptions->bCompletePath);          bool bCompletePath = (m_pOptions && m_pOptions->bCompletePath);
619      QString sSessionName = sFilename;          QString sSessionName = sFilename;
620      if (sSessionName.isEmpty())          if (sSessionName.isEmpty())
621          sSessionName = tr("Untitled") + QString::number(m_iUntitled);                  sSessionName = tr("Untitled") + QString::number(m_iUntitled);
622      else if (!bCompletePath)          else if (!bCompletePath)
623          sSessionName = QFileInfo(sSessionName).fileName();                  sSessionName = QFileInfo(sSessionName).fileName();
624      return sSessionName;          return sSessionName;
625  }  }
626    
627    
628  // Create a new session file from scratch.  // Create a new session file from scratch.
629  bool MainForm::newSession (void)  bool MainForm::newSession (void)
630  {  {
631      // Check if we can do it.          // Check if we can do it.
632      if (!closeSession(true))          if (!closeSession(true))
633          return false;                  return false;
634    
635          // Give us what the server has, right now...          // Give us what the server has, right now...
636          updateSession();          updateSession();
637    
638      // Ok increment untitled count.          // Ok increment untitled count.
639      m_iUntitled++;          m_iUntitled++;
640    
641      // Stabilize form.          // Stabilize form.
642      m_sFilename = QString::null;          m_sFilename = QString::null;
643      m_iDirtyCount = 0;          m_iDirtyCount = 0;
644      appendMessages(tr("New session: \"%1\".").arg(sessionName(m_sFilename)));          appendMessages(tr("New session: \"%1\".").arg(sessionName(m_sFilename)));
645      stabilizeForm();          stabilizeForm();
646    
647      return true;          return true;
648  }  }
649    
650    
651  // Open an existing sampler session.  // Open an existing sampler session.
652  bool MainForm::openSession (void)  bool MainForm::openSession (void)
653  {  {
654      if (m_pOptions == NULL)          if (m_pOptions == NULL)
655          return false;                  return false;
656    
657      // Ask for the filename to open...          // Ask for the filename to open...
658          QString sFilename = QFileDialog::getOpenFileName(this,          QString sFilename = QFileDialog::getOpenFileName(this,
659                  QSAMPLER_TITLE ": " + tr("Open Session"), // Caption.                  QSAMPLER_TITLE ": " + tr("Open Session"), // Caption.
660                  m_pOptions->sSessionDir,                  // Start here.                  m_pOptions->sSessionDir,                  // Start here.
661                  tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)                  tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)
662          );          );
663    
664      // Have we cancelled?          // Have we cancelled?
665      if (sFilename.isEmpty())          if (sFilename.isEmpty())
666          return false;                  return false;
667    
668      // Check if we're going to discard safely the current one...          // Check if we're going to discard safely the current one...
669      if (!closeSession(true))          if (!closeSession(true))
670          return false;                  return false;
671    
672      // Load it right away.          // Load it right away.
673      return loadSessionFile(sFilename);          return loadSessionFile(sFilename);
674  }  }
675    
676    
677  // Save current sampler session with another name.  // Save current sampler session with another name.
678  bool MainForm::saveSession ( bool bPrompt )  bool MainForm::saveSession ( bool bPrompt )
679  {  {
680      if (m_pOptions == NULL)          if (m_pOptions == NULL)
681          return false;                  return false;
682    
683      QString sFilename = m_sFilename;          QString sFilename = m_sFilename;
684    
685      // Ask for the file to save, if there's none...          // Ask for the file to save, if there's none...
686      if (bPrompt || sFilename.isEmpty()) {          if (bPrompt || sFilename.isEmpty()) {
687          // If none is given, assume default directory.                  // If none is given, assume default directory.
688          if (sFilename.isEmpty())                  if (sFilename.isEmpty())
689              sFilename = m_pOptions->sSessionDir;                          sFilename = m_pOptions->sSessionDir;
690          // Prompt the guy...                  // Prompt the guy...
691                  sFilename = QFileDialog::getSaveFileName(this,                  sFilename = QFileDialog::getSaveFileName(this,
692                          QSAMPLER_TITLE ": " + tr("Save Session"), // Caption.                          QSAMPLER_TITLE ": " + tr("Save Session"), // Caption.
693                          sFilename,                                // Start here.                          sFilename,                                // Start here.
694                          tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)                          tr("LSCP Session files") + " (*.lscp)"    // Filter (LSCP files)
695                  );                  );
696          // Have we cancelled it?                  // Have we cancelled it?
697          if (sFilename.isEmpty())                  if (sFilename.isEmpty())
698              return false;                          return false;
699          // Enforce .lscp extension...                  // Enforce .lscp extension...
700          if (QFileInfo(sFilename).suffix().isEmpty())                  if (QFileInfo(sFilename).suffix().isEmpty())
701              sFilename += ".lscp";                          sFilename += ".lscp";
702          // Check if already exists...                  // Check if already exists...
703          if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
704              if (QMessageBox::warning(this,                          if (QMessageBox::warning(this,
705                                  QSAMPLER_TITLE ": " + tr("Warning"),                                  QSAMPLER_TITLE ": " + tr("Warning"),
706                  tr("The file already exists:\n\n"                                  tr("The file already exists:\n\n"
707                     "\"%1\"\n\n"                                  "\"%1\"\n\n"
708                     "Do you want to replace it?")                                  "Do you want to replace it?")
709                     .arg(sFilename),                                  .arg(sFilename),
710                  tr("Replace"), tr("Cancel")) > 0)                                  tr("Replace"), tr("Cancel")) > 0)
711                  return false;                                  return false;
712          }                  }
713      }          }
714    
715      // Save it right away.          // Save it right away.
716      return saveSessionFile(sFilename);          return saveSessionFile(sFilename);
717  }  }
718    
719    
720  // Close current session.  // Close current session.
721  bool MainForm::closeSession ( bool bForce )  bool MainForm::closeSession ( bool bForce )
722  {  {
723      bool bClose = true;          bool bClose = true;
724    
725      // Are we dirty enough to prompt it?          // Are we dirty enough to prompt it?
726      if (m_iDirtyCount > 0) {          if (m_iDirtyCount > 0) {
727          switch (QMessageBox::warning(this,                  switch (QMessageBox::warning(this,
728                          QSAMPLER_TITLE ": " + tr("Warning"),                          QSAMPLER_TITLE ": " + tr("Warning"),
729              tr("The current session has been changed:\n\n"                          tr("The current session has been changed:\n\n"
730              "\"%1\"\n\n"                          "\"%1\"\n\n"
731              "Do you want to save the changes?")                          "Do you want to save the changes?")
732              .arg(sessionName(m_sFilename)),                          .arg(sessionName(m_sFilename)),
733              tr("Save"), tr("Discard"), tr("Cancel"))) {                          tr("Save"), tr("Discard"), tr("Cancel"))) {
734          case 0:     // Save...                  case 0:     // Save...
735              bClose = saveSession(false);                          bClose = saveSession(false);
736              // Fall thru....                          // Fall thru....
737          case 1:     // Discard                  case 1:     // Discard
738              break;                          break;
739          default:    // Cancel.                  default:    // Cancel.
740              bClose = false;                          bClose = false;
741              break;                          break;
742          }                  }
743      }          }
   
     // If we may close it, dot it.  
     if (bClose) {  
         // Remove all channel strips from sight...  
         m_pWorkspace->setUpdatesEnabled(false);  
         QWidgetList wlist = m_pWorkspace->windowList();  
         for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {  
             ChannelStrip *pChannelStrip = (ChannelStrip*) wlist.at(iChannel);  
             if (pChannelStrip) {  
                 qsamplerChannel *pChannel = pChannelStrip->channel();  
                 if (bForce && pChannel)  
                     pChannel->removeChannel();  
                 delete pChannelStrip;  
             }  
         }  
         m_pWorkspace->setUpdatesEnabled(true);  
         // We're now clean, for sure.  
         m_iDirtyCount = 0;  
     }  
744    
745      return bClose;          // If we may close it, dot it.
746            if (bClose) {
747                    // Remove all channel strips from sight...
748                    m_pWorkspace->setUpdatesEnabled(false);
749                    QWidgetList wlist = m_pWorkspace->windowList();
750                    for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
751                            ChannelStrip *pChannelStrip = (ChannelStrip*) wlist.at(iChannel);
752                            if (pChannelStrip) {
753                                    Channel *pChannel = pChannelStrip->channel();
754                                    if (bForce && pChannel)
755                                            pChannel->removeChannel();
756                                    delete pChannelStrip;
757                            }
758                    }
759                    m_pWorkspace->setUpdatesEnabled(true);
760                    // We're now clean, for sure.
761                    m_iDirtyCount = 0;
762            }
763    
764            return bClose;
765  }  }
766    
767    
768  // Load a session from specific file path.  // Load a session from specific file path.
769  bool MainForm::loadSessionFile ( const QString& sFilename )  bool MainForm::loadSessionFile ( const QString& sFilename )
770  {  {
771      if (m_pClient == NULL)          if (m_pClient == NULL)
772          return false;                  return false;
773    
774      // Open and read from real file.          // Open and read from real file.
775      QFile file(sFilename);          QFile file(sFilename);
776      if (!file.open(QIODevice::ReadOnly)) {          if (!file.open(QIODevice::ReadOnly)) {
777          appendMessagesError(tr("Could not open \"%1\" session file.\n\nSorry.").arg(sFilename));                  appendMessagesError(
778          return false;                          tr("Could not open \"%1\" session file.\n\nSorry.")
779      }                          .arg(sFilename));
780                    return false;
781            }
782    
783          // Tell the world we'll take some time...          // Tell the world we'll take some time...
784          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
785    
786      // Read the file.          // Read the file.
787          int iLine = 0;          int iLine = 0;
788      int iErrors = 0;          int iErrors = 0;
789      QTextStream ts(&file);          QTextStream ts(&file);
790      while (!ts.atEnd()) {          while (!ts.atEnd()) {
791          // Read the line.                  // Read the line.
792          QString sCommand = ts.readLine().trimmed();                  QString sCommand = ts.readLine().trimmed();
793                  iLine++;                  iLine++;
794          // If not empty, nor a comment, call the server...                  // If not empty, nor a comment, call the server...
795          if (!sCommand.isEmpty() && sCommand[0] != '#') {                  if (!sCommand.isEmpty() && sCommand[0] != '#') {
796                          // Remember that, no matter what,                          // Remember that, no matter what,
797                          // all LSCP commands are CR/LF terminated.                          // all LSCP commands are CR/LF terminated.
798                          sCommand += "\r\n";                          sCommand += "\r\n";
# Line 782  bool MainForm::loadSessionFile ( const Q Line 804  bool MainForm::loadSessionFile ( const Q
804                                  appendMessagesClient("lscp_client_query");                                  appendMessagesClient("lscp_client_query");
805                                  iErrors++;                                  iErrors++;
806                          }                          }
807          }                  }
808          // Try to make it snappy :)                  // Try to make it snappy :)
809          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
810      }          }
811    
812      // Ok. we've read it.          // Ok. we've read it.
813      file.close();          file.close();
814    
815          // Now we'll try to create (update) the whole GUI session.          // Now we'll try to create (update) the whole GUI session.
816          updateSession();          updateSession();
# Line 797  bool MainForm::loadSessionFile ( const Q Line 819  bool MainForm::loadSessionFile ( const Q
819          QApplication::restoreOverrideCursor();          QApplication::restoreOverrideCursor();
820    
821          // Have we any errors?          // Have we any errors?
822          if (iErrors > 0)          if (iErrors > 0) {
823                  appendMessagesError(tr("Session loaded with errors\nfrom \"%1\".\n\nSorry.").arg(sFilename));                  appendMessagesError(
824                            tr("Session loaded with errors\nfrom \"%1\".\n\nSorry.")
825                            .arg(sFilename));
826            }
827    
828      // Save as default session directory.          // Save as default session directory.
829      if (m_pOptions)          if (m_pOptions)
830          m_pOptions->sSessionDir = QFileInfo(sFilename).dir().absolutePath();                  m_pOptions->sSessionDir = QFileInfo(sFilename).dir().absolutePath();
831          // We're not dirty anymore, if loaded without errors,          // We're not dirty anymore, if loaded without errors,
832          m_iDirtyCount = iErrors;          m_iDirtyCount = iErrors;
833      // Stabilize form...          // Stabilize form...
834      m_sFilename = sFilename;          m_sFilename = sFilename;
835      updateRecentFiles(sFilename);          updateRecentFiles(sFilename);
836      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));          appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));
837    
838      // Make that an overall update.          // Make that an overall update.
839      stabilizeForm();          stabilizeForm();
840      return true;          return true;
841  }  }
842    
843    
# Line 828  bool MainForm::saveSessionFile ( const Q Line 853  bool MainForm::saveSessionFile ( const Q
853                  return false;                  return false;
854          }          }
855    
856      // Open and write into real file.          // Open and write into real file.
857      QFile file(sFilename);          QFile file(sFilename);
858      if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {          if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
859          appendMessagesError(tr("Could not open \"%1\" session file.\n\nSorry.").arg(sFilename));                  appendMessagesError(
860          return false;                          tr("Could not open \"%1\" session file.\n\nSorry.")
861      }                          .arg(sFilename));
862                    return false;
863            }
864    
865          // Tell the world we'll take some time...          // Tell the world we'll take some time...
866          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));          QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
867    
868      // Write the file.          // Write the file.
869      int  iErrors = 0;          int  iErrors = 0;
870      QTextStream ts(&file);          QTextStream ts(&file);
871      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;          ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;
872      ts << "# " << tr("Version")          ts << "# " << tr("Version")
873         << ": " QSAMPLER_VERSION << endl;          << ": " QSAMPLER_VERSION << endl;
874      ts << "# " << tr("Build")          ts << "# " << tr("Build")
875         << ": " __DATE__ " " __TIME__ << endl;          << ": " __DATE__ " " __TIME__ << endl;
876      ts << "#"  << endl;          ts << "#"  << endl;
877      ts << "# " << tr("File")          ts << "# " << tr("File")
878         << ": " << QFileInfo(sFilename).fileName() << endl;          << ": " << QFileInfo(sFilename).fileName() << endl;
879      ts << "# " << tr("Date")          ts << "# " << tr("Date")
880         << ": " << QDate::currentDate().toString("MMM dd yyyy")          << ": " << QDate::currentDate().toString("MMM dd yyyy")
881         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;          << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;
882      ts << "#"  << endl;          ts << "#"  << endl;
883      ts << endl;          ts << endl;
884    
885          // It is assumed that this new kind of device+session file          // It is assumed that this new kind of device+session file
886          // will be loaded from a complete initialized server...          // will be loaded from a complete initialized server...
# Line 863  bool MainForm::saveSessionFile ( const Q Line 890  bool MainForm::saveSessionFile ( const Q
890    
891          // Audio device mapping.          // Audio device mapping.
892          QMap<int, int> audioDeviceMap;          QMap<int, int> audioDeviceMap;
893          piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Audio);          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);
894          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
895                  ts << endl;                  ts << endl;
896                  qsamplerDevice device(qsamplerDevice::Audio, piDeviceIDs[iDevice]);                  Device device(Device::Audio, piDeviceIDs[iDevice]);
897                  // Audio device specification...                  // Audio device specification...
898                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
899                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
900                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
901                  qsamplerDeviceParamMap::ConstIterator deviceParam;                  DeviceParamMap::ConstIterator deviceParam;
902                  for (deviceParam = device.params().begin();                  for (deviceParam = device.params().begin();
903                                  deviceParam != device.params().end();                                  deviceParam != device.params().end();
904                                          ++deviceParam) {                                          ++deviceParam) {
905                          const qsamplerDeviceParam& param = deviceParam.value();                          const DeviceParam& param = deviceParam.value();
906                          if (param.value.isEmpty()) ts << "# ";                          if (param.value.isEmpty()) ts << "# ";
907                          ts << " " << deviceParam.key() << "='" << param.value << "'";                          ts << " " << deviceParam.key() << "='" << param.value << "'";
908                  }                  }
909                  ts << endl;                  ts << endl;
910                  // Audio channel parameters...                  // Audio channel parameters...
911                  int iPort = 0;                  int iPort = 0;
912                  QListIterator<qsamplerDevicePort *> iter(device.ports());                  QListIterator<DevicePort *> iter(device.ports());
913                  while (iter.hasNext()) {                  while (iter.hasNext()) {
914                          qsamplerDevicePort *pPort = iter.next();                          DevicePort *pPort = iter.next();
915                          qsamplerDeviceParamMap::ConstIterator portParam;                          DeviceParamMap::ConstIterator portParam;
916                          for (portParam = pPort->params().begin();                          for (portParam = pPort->params().begin();
917                                          portParam != pPort->params().end();                                          portParam != pPort->params().end();
918                                                  ++portParam) {                                                  ++portParam) {
919                                  const qsamplerDeviceParam& param = portParam.value();                                  const DeviceParam& param = portParam.value();
920                                  if (param.fix || param.value.isEmpty()) ts << "# ";                                  if (param.fix || param.value.isEmpty()) ts << "# ";
921                                  ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice                                  ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice
922                                          << " " << iPort << " " << portParam.key()                                          << " " << iPort << " " << portParam.key()
# Line 905  bool MainForm::saveSessionFile ( const Q Line 932  bool MainForm::saveSessionFile ( const Q
932    
933          // MIDI device mapping.          // MIDI device mapping.
934          QMap<int, int> midiDeviceMap;          QMap<int, int> midiDeviceMap;
935          piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Midi);          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);
936          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
937                  ts << endl;                  ts << endl;
938                  qsamplerDevice device(qsamplerDevice::Midi, piDeviceIDs[iDevice]);                  Device device(Device::Midi, piDeviceIDs[iDevice]);
939                  // MIDI device specification...                  // MIDI device specification...
940                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
941                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
942                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
943                  qsamplerDeviceParamMap::ConstIterator deviceParam;                  DeviceParamMap::ConstIterator deviceParam;
944                  for (deviceParam = device.params().begin();                  for (deviceParam = device.params().begin();
945                                  deviceParam != device.params().end();                                  deviceParam != device.params().end();
946                                          ++deviceParam) {                                          ++deviceParam) {
947                          const qsamplerDeviceParam& param = deviceParam.value();                          const DeviceParam& param = deviceParam.value();
948                          if (param.value.isEmpty()) ts << "# ";                          if (param.value.isEmpty()) ts << "# ";
949                          ts << " " << deviceParam.key() << "='" << param.value << "'";                          ts << " " << deviceParam.key() << "='" << param.value << "'";
950                  }                  }
951                  ts << endl;                  ts << endl;
952                  // MIDI port parameters...                  // MIDI port parameters...
953                  int iPort = 0;                  int iPort = 0;
954                  QListIterator<qsamplerDevicePort *> iter(device.ports());                  QListIterator<DevicePort *> iter(device.ports());
955                  while (iter.hasNext()) {                  while (iter.hasNext()) {
956                          qsamplerDevicePort *pPort = iter.next();                          DevicePort *pPort = iter.next();
957                          qsamplerDeviceParamMap::ConstIterator portParam;                          DeviceParamMap::ConstIterator portParam;
958                          for (portParam = pPort->params().begin();                          for (portParam = pPort->params().begin();
959                                          portParam != pPort->params().end();                                          portParam != pPort->params().end();
960                                                  ++portParam) {                                                  ++portParam) {
961                                  const qsamplerDeviceParam& param = portParam.value();                                  const DeviceParam& param = portParam.value();
962                                  if (param.fix || param.value.isEmpty()) ts << "# ";                                  if (param.fix || param.value.isEmpty()) ts << "# ";
963                                  ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice                                  ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice
964                                     << " " << iPort << " " << portParam.key()                                  << " " << iPort << " " << portParam.key()
965                                     << "='" << param.value << "'" << endl;                                  << "='" << param.value << "'" << endl;
966                          }                          }
967                          iPort++;                          iPort++;
968                  }                  }
# Line 1018  bool MainForm::saveSessionFile ( const Q Line 1045  bool MainForm::saveSessionFile ( const Q
1045  #endif  // CONFIG_MIDI_INSTRUMENT  #endif  // CONFIG_MIDI_INSTRUMENT
1046    
1047          // Sampler channel mapping.          // Sampler channel mapping.
1048      QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
1049      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1050          ChannelStrip* pChannelStrip                  ChannelStrip* pChannelStrip
1051                          = static_cast<ChannelStrip *> (wlist.at(iChannel));                          = static_cast<ChannelStrip *> (wlist.at(iChannel));
1052          if (pChannelStrip) {                  if (pChannelStrip) {
1053              qsamplerChannel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1054              if (pChannel) {                          if (pChannel) {
1055                  ts << "# " << tr("Channel") << " " << iChannel << endl;                                  ts << "# " << tr("Channel") << " " << iChannel << endl;
1056                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
1057                                  if (audioDeviceMap.isEmpty()) {                                  if (audioDeviceMap.isEmpty()) {
1058                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel
1059                                                  << " " << pChannel->audioDriver() << endl;                                                  << " " << pChannel->audioDriver() << endl;
# Line 1043  bool MainForm::saveSessionFile ( const Q Line 1070  bool MainForm::saveSessionFile ( const Q
1070                                  }                                  }
1071                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel
1072                                          << " " << pChannel->midiPort() << endl;                                          << " " << pChannel->midiPort() << endl;
1073                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";                                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";
1074                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)                                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
1075                      ts << "ALL";                                          ts << "ALL";
1076                  else                                  else
1077                      ts << pChannel->midiChannel();                                          ts << pChannel->midiChannel();
1078                  ts << endl;                                  ts << endl;
1079                  ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannel << endl;                                  ts << "LOAD ENGINE " << pChannel->engineName()
1080                                            << " " << iChannel << endl;
1081                                  if (pChannel->instrumentStatus() < 100) ts << "# ";                                  if (pChannel->instrumentStatus() < 100) ts << "# ";
1082                                  ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' "                                  ts << "LOAD INSTRUMENT NON_MODAL '"
1083                                            << pChannel->instrumentFile() << "' "
1084                                          << pChannel->instrumentNr() << " " << iChannel << endl;                                          << pChannel->instrumentNr() << " " << iChannel << endl;
1085                                  qsamplerChannelRoutingMap::ConstIterator audioRoute;                                  ChannelRoutingMap::ConstIterator audioRoute;
1086                                  for (audioRoute = pChannel->audioRouting().begin();                                  for (audioRoute = pChannel->audioRouting().begin();
1087                                                  audioRoute != pChannel->audioRouting().end();                                                  audioRoute != pChannel->audioRouting().end();
1088                                                          ++audioRoute) {                                                          ++audioRoute) {
# Line 1109  bool MainForm::saveSessionFile ( const Q Line 1138  bool MainForm::saveSessionFile ( const Q
1138                                          }                                          }
1139                                  }                                  }
1140  #endif  #endif
1141                  ts << endl;                                  ts << endl;
1142              }                          }
1143          }                  }
1144          // Try to keep it snappy :)                  // Try to keep it snappy :)
1145          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1146      }          }
1147    
1148  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
1149          ts << "# " << tr("Global volume level") << endl;          ts << "# " << tr("Global volume level") << endl;
# Line 1122  bool MainForm::saveSessionFile ( const Q Line 1151  bool MainForm::saveSessionFile ( const Q
1151          ts << endl;          ts << endl;
1152  #endif  #endif
1153    
1154      // Ok. we've wrote it.          // Ok. we've wrote it.
1155      file.close();          file.close();
1156    
1157          // We're fornerly done.          // We're fornerly done.
1158          QApplication::restoreOverrideCursor();          QApplication::restoreOverrideCursor();
1159    
1160      // Have we any errors?          // Have we any errors?
1161      if (iErrors > 0)          if (iErrors > 0) {
1162          appendMessagesError(tr("Some settings could not be saved\nto \"%1\" session file.\n\nSorry.").arg(sFilename));                  appendMessagesError(
1163                            tr("Some settings could not be saved\n"
1164      // Save as default session directory.                          "to \"%1\" session file.\n\nSorry.")
1165      if (m_pOptions)                          .arg(sFilename));
1166          m_pOptions->sSessionDir = QFileInfo(sFilename).dir().absolutePath();          }
1167      // We're not dirty anymore.  
1168      m_iDirtyCount = 0;          // Save as default session directory.
1169      // Stabilize form...          if (m_pOptions)
1170      m_sFilename = sFilename;                  m_pOptions->sSessionDir = QFileInfo(sFilename).dir().absolutePath();
1171      updateRecentFiles(sFilename);          // We're not dirty anymore.
1172      appendMessages(tr("Save session: \"%1\".").arg(sessionName(m_sFilename)));          m_iDirtyCount = 0;
1173      stabilizeForm();          // Stabilize form...
1174      return true;          m_sFilename = sFilename;
1175            updateRecentFiles(sFilename);
1176            appendMessages(tr("Save session: \"%1\".").arg(sessionName(m_sFilename)));
1177            stabilizeForm();
1178            return true;
1179  }  }
1180    
1181    
1182  // Session change receiver slot.  // Session change receiver slot.
1183  void MainForm::sessionDirty (void)  void MainForm::sessionDirty (void)
1184  {  {
1185      // Just mark the dirty form.          // Just mark the dirty form.
1186      m_iDirtyCount++;          m_iDirtyCount++;
1187      // and update the form status...          // and update the form status...
1188      stabilizeForm();          stabilizeForm();
1189  }  }
1190    
1191    
# Line 1162  void MainForm::sessionDirty (void) Line 1195  void MainForm::sessionDirty (void)
1195  // Create a new sampler session.  // Create a new sampler session.
1196  void MainForm::fileNew (void)  void MainForm::fileNew (void)
1197  {  {
1198      // Of course we'll start clean new.          // Of course we'll start clean new.
1199      newSession();          newSession();
1200  }  }
1201    
1202    
1203  // Open an existing sampler session.  // Open an existing sampler session.
1204  void MainForm::fileOpen (void)  void MainForm::fileOpen (void)
1205  {  {
1206      // Open it right away.          // Open it right away.
1207      openSession();          openSession();
1208  }  }
1209    
1210    
# Line 1195  void MainForm::fileOpenRecent (void) Line 1228  void MainForm::fileOpenRecent (void)
1228  // Save current sampler session.  // Save current sampler session.
1229  void MainForm::fileSave (void)  void MainForm::fileSave (void)
1230  {  {
1231      // Save it right away.          // Save it right away.
1232      saveSession(false);          saveSession(false);
1233  }  }
1234    
1235    
1236  // Save current sampler session with another name.  // Save current sampler session with another name.
1237  void MainForm::fileSaveAs (void)  void MainForm::fileSaveAs (void)
1238  {  {
1239      // Save it right away, maybe with another name.          // Save it right away, maybe with another name.
1240      saveSession(true);          saveSession(true);
1241  }  }
1242    
1243    
1244  // Reset the sampler instance.  // Reset the sampler instance.
1245  void MainForm::fileReset (void)  void MainForm::fileReset (void)
1246  {  {
1247      if (m_pClient == NULL)          if (m_pClient == NULL)
1248          return;                  return;
1249    
1250      // Ask user whether he/she want's an internal sampler reset...          // Ask user whether he/she want's an internal sampler reset...
1251      if (QMessageBox::warning(this,          if (QMessageBox::warning(this,
1252                  QSAMPLER_TITLE ": " + tr("Warning"),                  QSAMPLER_TITLE ": " + tr("Warning"),
1253          tr("Resetting the sampler instance will close\n"                  tr("Resetting the sampler instance will close\n"
1254             "all device and channel configurations.\n\n"                  "all device and channel configurations.\n\n"
1255             "Please note that this operation may cause\n"                  "Please note that this operation may cause\n"
1256             "temporary MIDI and Audio disruption.\n\n"                  "temporary MIDI and Audio disruption.\n\n"
1257             "Do you want to reset the sampler engine now?"),                  "Do you want to reset the sampler engine now?"),
1258          tr("Reset"), tr("Cancel")) > 0)                  tr("Reset"), tr("Cancel")) > 0)
1259          return;                  return;
1260    
1261          // Trye closing the current session, first...          // Trye closing the current session, first...
1262          if (!closeSession(true))          if (!closeSession(true))
1263                  return;                  return;
1264    
1265      // Just do the reset, after closing down current session...          // Just do the reset, after closing down current session...
1266          // Do the actual sampler reset...          // Do the actual sampler reset...
1267          if (::lscp_reset_sampler(m_pClient) != LSCP_OK) {          if (::lscp_reset_sampler(m_pClient) != LSCP_OK) {
1268                  appendMessagesClient("lscp_reset_sampler");                  appendMessagesClient("lscp_reset_sampler");
# Line 1237  void MainForm::fileReset (void) Line 1270  void MainForm::fileReset (void)
1270                  return;                  return;
1271          }          }
1272    
1273      // Log this.          // Log this.
1274      appendMessages(tr("Sampler reset."));          appendMessages(tr("Sampler reset."));
1275    
1276          // Make it a new session...          // Make it a new session...
1277          newSession();          newSession();
# Line 1248  void MainForm::fileReset (void) Line 1281  void MainForm::fileReset (void)
1281  // Restart the client/server instance.  // Restart the client/server instance.
1282  void MainForm::fileRestart (void)  void MainForm::fileRestart (void)
1283  {  {
1284      if (m_pOptions == NULL)          if (m_pOptions == NULL)
1285          return;                  return;
1286    
1287      bool bRestart = true;          bool bRestart = true;
1288    
1289      // Ask user whether he/she want's a complete restart...          // Ask user whether he/she want's a complete restart...
1290      // (if we're currently up and running)          // (if we're currently up and running)
1291      if (bRestart && m_pClient) {          if (bRestart && m_pClient) {
1292          bRestart = (QMessageBox::warning(this,                  bRestart = (QMessageBox::warning(this,
1293                          QSAMPLER_TITLE ": " + tr("Warning"),                          QSAMPLER_TITLE ": " + tr("Warning"),
1294              tr("New settings will be effective after\n"                          tr("New settings will be effective after\n"
1295                 "restarting the client/server connection.\n\n"                          "restarting the client/server connection.\n\n"
1296                 "Please note that this operation may cause\n"                          "Please note that this operation may cause\n"
1297                 "temporary MIDI and Audio disruption.\n\n"                          "temporary MIDI and Audio disruption.\n\n"
1298                 "Do you want to restart the connection now?"),                          "Do you want to restart the connection now?"),
1299              tr("Restart"), tr("Cancel")) == 0);                          tr("Restart"), tr("Cancel")) == 0);
1300      }          }
1301    
1302      // Are we still for it?          // Are we still for it?
1303      if (bRestart && closeSession(true)) {          if (bRestart && closeSession(true)) {
1304          // Stop server, it will force the client too.                  // Stop server, it will force the client too.
1305          stopServer();                  stopServer();
1306          // Reschedule a restart...                  // Reschedule a restart...
1307          startSchedule(m_pOptions->iStartDelay);                  startSchedule(m_pOptions->iStartDelay);
1308      }          }
1309  }  }
1310    
1311    
1312  // Exit application program.  // Exit application program.
1313  void MainForm::fileExit (void)  void MainForm::fileExit (void)
1314  {  {
1315      // Go for close the whole thing.          // Go for close the whole thing.
1316      close();          close();
1317  }  }
1318    
1319    
# Line 1290  void MainForm::fileExit (void) Line 1323  void MainForm::fileExit (void)
1323  // Add a new sampler channel.  // Add a new sampler channel.
1324  void MainForm::editAddChannel (void)  void MainForm::editAddChannel (void)
1325  {  {
1326      if (m_pClient == NULL)          if (m_pClient == NULL)
1327          return;                  return;
1328    
1329            // Just create the channel instance...
1330            Channel *pChannel = new Channel();
1331            if (pChannel == NULL)
1332                    return;
1333    
1334            // Before we show it up, may be we'll
1335            // better ask for some initial values?
1336            if (!pChannel->channelSetup(this)) {
1337                    delete pChannel;
1338                    return;
1339            }
1340    
1341            // And give it to the strip...
1342            // (will own the channel instance, if successful).
1343            if (!createChannelStrip(pChannel)) {
1344                    delete pChannel;
1345                    return;
1346            }
1347    
1348      // Just create the channel instance...          // Do we auto-arrange?
1349      qsamplerChannel *pChannel = new qsamplerChannel();          if (m_pOptions && m_pOptions->bAutoArrange)
1350      if (pChannel == NULL)                  channelsArrange();
1351          return;  
1352            // Make that an overall update.
1353      // Before we show it up, may be we'll          m_iDirtyCount++;
1354      // better ask for some initial values?          stabilizeForm();
     if (!pChannel->channelSetup(this)) {  
         delete pChannel;  
         return;  
     }  
   
     // And give it to the strip (will own the channel instance, if successful).  
     if (!createChannelStrip(pChannel)) {  
         delete pChannel;  
         return;  
     }  
   
     // Make that an overall update.  
     m_iDirtyCount++;  
     stabilizeForm();  
1355  }  }
1356    
1357    
1358  // Remove current sampler channel.  // Remove current sampler channel.
1359  void MainForm::editRemoveChannel (void)  void MainForm::editRemoveChannel (void)
1360  {  {
1361      if (m_pClient == NULL)          if (m_pClient == NULL)
1362          return;                  return;
1363    
1364            ChannelStrip* pChannelStrip = activeChannelStrip();
1365            if (pChannelStrip == NULL)
1366                    return;
1367    
1368            Channel *pChannel = pChannelStrip->channel();
1369            if (pChannel == NULL)
1370                    return;
1371    
1372      ChannelStrip* pChannelStrip = activeChannelStrip();          // Prompt user if he/she's sure about this...
1373      if (pChannelStrip == NULL)          if (m_pOptions && m_pOptions->bConfirmRemove) {
1374          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,  
1375                          QSAMPLER_TITLE ": " + tr("Warning"),                          QSAMPLER_TITLE ": " + tr("Warning"),
1376              tr("About to remove channel:\n\n"                          tr("About to remove channel:\n\n"
1377                 "%1\n\n"                          "%1\n\n"
1378                 "Are you sure?")                          "Are you sure?")
1379                 .arg(pChannelStrip->windowTitle()),                          .arg(pChannelStrip->windowTitle()),
1380              tr("OK"), tr("Cancel")) > 0)                          tr("OK"), tr("Cancel")) > 0)
1381              return;                          return;
1382      }          }
1383    
1384      // Remove the existing sampler channel.          // Remove the existing sampler channel.
1385      if (!pChannel->removeChannel())          if (!pChannel->removeChannel())
1386          return;                  return;
1387    
1388      // Just delete the channel strip.          // Just delete the channel strip.
1389      delete pChannelStrip;          delete pChannelStrip;
1390    
1391      // Do we auto-arrange?          // Do we auto-arrange?
1392      if (m_pOptions && m_pOptions->bAutoArrange)          if (m_pOptions && m_pOptions->bAutoArrange)
1393          channelsArrange();                  channelsArrange();
1394    
1395      // We'll be dirty, for sure...          // We'll be dirty, for sure...
1396      m_iDirtyCount++;          m_iDirtyCount++;
1397      stabilizeForm();          stabilizeForm();
1398  }  }
1399    
1400    
1401  // Setup current sampler channel.  // Setup current sampler channel.
1402  void MainForm::editSetupChannel (void)  void MainForm::editSetupChannel (void)
1403  {  {
1404      if (m_pClient == NULL)          if (m_pClient == NULL)
1405          return;                  return;
1406    
1407      ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip* pChannelStrip = activeChannelStrip();
1408      if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1409          return;                  return;
1410    
1411      // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
1412      pChannelStrip->channelSetup();          pChannelStrip->channelSetup();
1413  }  }
1414    
1415    
1416  // Edit current sampler channel.  // Edit current sampler channel.
1417  void MainForm::editEditChannel (void)  void MainForm::editEditChannel (void)
1418  {  {
1419      if (m_pClient == NULL)          if (m_pClient == NULL)
1420          return;                  return;
1421    
1422      ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip* pChannelStrip = activeChannelStrip();
1423      if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1424          return;                  return;
1425    
1426      // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
1427      pChannelStrip->channelEdit();          pChannelStrip->channelEdit();
1428  }  }
1429    
1430    
1431  // Reset current sampler channel.  // Reset current sampler channel.
1432  void MainForm::editResetChannel (void)  void MainForm::editResetChannel (void)
1433  {  {
1434      if (m_pClient == NULL)          if (m_pClient == NULL)
1435          return;                  return;
1436    
1437      ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip* pChannelStrip = activeChannelStrip();
1438      if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1439          return;                  return;
1440    
1441      // Just invoque the channel strip procedure.          // Just invoque the channel strip procedure.
1442      pChannelStrip->channelReset();          pChannelStrip->channelReset();
1443  }  }
1444    
1445    
# Line 1430  void MainForm::editResetAllChannels (voi Line 1468  void MainForm::editResetAllChannels (voi
1468  // Show/hide the main program window menubar.  // Show/hide the main program window menubar.
1469  void MainForm::viewMenubar ( bool bOn )  void MainForm::viewMenubar ( bool bOn )
1470  {  {
1471      if (bOn)          if (bOn)
1472          ui.MenuBar->show();                  m_ui.MenuBar->show();
1473      else          else
1474          ui.MenuBar->hide();                  m_ui.MenuBar->hide();
1475  }  }
1476    
1477    
1478  // Show/hide the main program window toolbar.  // Show/hide the main program window toolbar.
1479  void MainForm::viewToolbar ( bool bOn )  void MainForm::viewToolbar ( bool bOn )
1480  {  {
1481      if (bOn) {          if (bOn) {
1482          ui.fileToolbar->show();                  m_ui.fileToolbar->show();
1483          ui.editToolbar->show();                  m_ui.editToolbar->show();
1484          ui.channelsToolbar->show();                  m_ui.channelsToolbar->show();
1485      } else {          } else {
1486          ui.fileToolbar->hide();                  m_ui.fileToolbar->hide();
1487          ui.editToolbar->hide();                  m_ui.editToolbar->hide();
1488          ui.channelsToolbar->hide();                  m_ui.channelsToolbar->hide();
1489      }          }
1490  }  }
1491    
1492    
1493  // Show/hide the main program window statusbar.  // Show/hide the main program window statusbar.
1494  void MainForm::viewStatusbar ( bool bOn )  void MainForm::viewStatusbar ( bool bOn )
1495  {  {
1496      if (bOn)          if (bOn)
1497          statusBar()->show();                  statusBar()->show();
1498      else          else
1499          statusBar()->hide();                  statusBar()->hide();
1500  }  }
1501    
1502    
1503  // Show/hide the messages window logger.  // Show/hide the messages window logger.
1504  void MainForm::viewMessages ( bool bOn )  void MainForm::viewMessages ( bool bOn )
1505  {  {
1506      if (bOn)          if (bOn)
1507          m_pMessages->show();                  m_pMessages->show();
1508      else          else
1509          m_pMessages->hide();                  m_pMessages->hide();
1510  }  }
1511    
1512    
# Line 1513  void MainForm::viewDevices (void) Line 1551  void MainForm::viewDevices (void)
1551  // Show options dialog.  // Show options dialog.
1552  void MainForm::viewOptions (void)  void MainForm::viewOptions (void)
1553  {  {
1554      if (m_pOptions == NULL)          if (m_pOptions == NULL)
1555          return;                  return;
1556    
1557      OptionsForm* pOptionsForm = new OptionsForm(this);          OptionsForm* pOptionsForm = new OptionsForm(this);
1558      if (pOptionsForm) {          if (pOptionsForm) {
1559          // Check out some initial nullities(tm)...                  // Check out some initial nullities(tm)...
1560          ChannelStrip* pChannelStrip = activeChannelStrip();                  ChannelStrip* pChannelStrip = activeChannelStrip();
1561          if (m_pOptions->sDisplayFont.isEmpty() && pChannelStrip)                  if (m_pOptions->sDisplayFont.isEmpty() && pChannelStrip)
1562              m_pOptions->sDisplayFont = pChannelStrip->displayFont().toString();                          m_pOptions->sDisplayFont = pChannelStrip->displayFont().toString();
1563          if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)                  if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)
1564              m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();                          m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();
1565          // To track down deferred or immediate changes.                  // To track down deferred or immediate changes.
1566          QString sOldServerHost      = m_pOptions->sServerHost;                  QString sOldServerHost      = m_pOptions->sServerHost;
1567          int     iOldServerPort      = m_pOptions->iServerPort;                  int     iOldServerPort      = m_pOptions->iServerPort;
1568          int     iOldServerTimeout   = m_pOptions->iServerTimeout;                  int     iOldServerTimeout   = m_pOptions->iServerTimeout;
1569          bool    bOldServerStart     = m_pOptions->bServerStart;                  bool    bOldServerStart     = m_pOptions->bServerStart;
1570          QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;                  QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;
1571          QString sOldDisplayFont     = m_pOptions->sDisplayFont;                  QString sOldDisplayFont     = m_pOptions->sDisplayFont;
1572          bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;                  bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1573          int     iOldMaxVolume       = m_pOptions->iMaxVolume;                  int     iOldMaxVolume       = m_pOptions->iMaxVolume;
1574          QString sOldMessagesFont    = m_pOptions->sMessagesFont;                  QString sOldMessagesFont    = m_pOptions->sMessagesFont;
1575          bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;                  bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;
1576          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;                  bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;
1577          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;                  int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;
1578          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;                  int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1579          bool    bOldCompletePath    = m_pOptions->bCompletePath;                  bool    bOldCompletePath    = m_pOptions->bCompletePath;
1580          bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;                  bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1581          int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;                  int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1582          // Load the current setup settings.                  // Load the current setup settings.
1583          pOptionsForm->setup(m_pOptions);                  pOptionsForm->setup(m_pOptions);
1584          // Show the setup dialog...                  // Show the setup dialog...
1585          if (pOptionsForm->exec()) {                  if (pOptionsForm->exec()) {
1586              // Warn if something will be only effective on next run.                          // Warn if something will be only effective on next run.
1587              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||                          if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1588                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||                                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||
1589                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||                                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1590                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)) {                                  (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)) {
1591                  QMessageBox::information(this,                                  QMessageBox::information(this,
1592                                          QSAMPLER_TITLE ": " + tr("Information"),                                          QSAMPLER_TITLE ": " + tr("Information"),
1593                      tr("Some settings may be only effective\n"                                          tr("Some settings may be only effective\n"
1594                         "next time you start this program."), tr("OK"));                                          "next time you start this program."), tr("OK"));
1595                  updateMessagesCapture();                                  updateMessagesCapture();
1596              }                          }
1597              // Check wheather something immediate has changed.                          // Check wheather something immediate has changed.
1598              if (( bOldCompletePath && !m_pOptions->bCompletePath) ||                          if (( bOldCompletePath && !m_pOptions->bCompletePath) ||
1599                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||                                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||
1600                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))                                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))
1601                  updateRecentFilesMenu();                                  updateRecentFilesMenu();
1602              if (( bOldInstrumentNames && !m_pOptions->bInstrumentNames) ||                          if (( bOldInstrumentNames && !m_pOptions->bInstrumentNames) ||
1603                  (!bOldInstrumentNames &&  m_pOptions->bInstrumentNames))                                  (!bOldInstrumentNames &&  m_pOptions->bInstrumentNames))
1604                  updateInstrumentNames();                                  updateInstrumentNames();
1605              if (( bOldDisplayEffect && !m_pOptions->bDisplayEffect) ||                          if (( bOldDisplayEffect && !m_pOptions->bDisplayEffect) ||
1606                  (!bOldDisplayEffect &&  m_pOptions->bDisplayEffect))                                  (!bOldDisplayEffect &&  m_pOptions->bDisplayEffect))
1607                  updateDisplayEffect();                                  updateDisplayEffect();
1608              if (sOldDisplayFont != m_pOptions->sDisplayFont)                          if (sOldDisplayFont != m_pOptions->sDisplayFont)
1609                  updateDisplayFont();                                  updateDisplayFont();
1610              if (iOldMaxVolume != m_pOptions->iMaxVolume)                          if (iOldMaxVolume != m_pOptions->iMaxVolume)
1611                  updateMaxVolume();                                  updateMaxVolume();
1612              if (sOldMessagesFont != m_pOptions->sMessagesFont)                          if (sOldMessagesFont != m_pOptions->sMessagesFont)
1613                  updateMessagesFont();                                  updateMessagesFont();
1614              if (( bOldMessagesLimit && !m_pOptions->bMessagesLimit) ||                          if (( bOldMessagesLimit && !m_pOptions->bMessagesLimit) ||
1615                  (!bOldMessagesLimit &&  m_pOptions->bMessagesLimit) ||                                  (!bOldMessagesLimit &&  m_pOptions->bMessagesLimit) ||
1616                  (iOldMessagesLimitLines !=  m_pOptions->iMessagesLimitLines))                                  (iOldMessagesLimitLines !=  m_pOptions->iMessagesLimitLines))
1617                  updateMessagesLimit();                                  updateMessagesLimit();
1618              // And now the main thing, whether we'll do client/server recycling?                          // And now the main thing, whether we'll do client/server recycling?
1619              if ((sOldServerHost != m_pOptions->sServerHost) ||                          if ((sOldServerHost != m_pOptions->sServerHost) ||
1620                  (iOldServerPort != m_pOptions->iServerPort) ||                                  (iOldServerPort != m_pOptions->iServerPort) ||
1621                  (iOldServerTimeout != m_pOptions->iServerTimeout) ||                                  (iOldServerTimeout != m_pOptions->iServerTimeout) ||
1622                  ( bOldServerStart && !m_pOptions->bServerStart) ||                                  ( bOldServerStart && !m_pOptions->bServerStart) ||
1623                  (!bOldServerStart &&  m_pOptions->bServerStart) ||                                  (!bOldServerStart &&  m_pOptions->bServerStart) ||
1624                  (sOldServerCmdLine != m_pOptions->sServerCmdLine && m_pOptions->bServerStart))                                  (sOldServerCmdLine != m_pOptions->sServerCmdLine
1625                  fileRestart();                                  && m_pOptions->bServerStart))
1626          }                                  fileRestart();
1627          // Done.                  }
1628          delete pOptionsForm;                  // Done.
1629      }                  delete pOptionsForm;
1630            }
1631    
1632      // This makes it.          // This makes it.
1633      stabilizeForm();          stabilizeForm();
1634  }  }
1635    
1636    
# Line 1601  void MainForm::viewOptions (void) Line 1640  void MainForm::viewOptions (void)
1640  // Arrange channel strips.  // Arrange channel strips.
1641  void MainForm::channelsArrange (void)  void MainForm::channelsArrange (void)
1642  {  {
1643      // Full width vertical tiling          // Full width vertical tiling
1644      QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
1645      if (wlist.isEmpty())          if (wlist.isEmpty())
1646          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);  
1647    
1648      stabilizeForm();          m_pWorkspace->setUpdatesEnabled(false);
1649            int y = 0;
1650            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1651                    ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);
1652            /*  if (pChannelStrip->testWState(WState_Maximized | WState_Minimized)) {
1653                            // Prevent flicker...
1654                            pChannelStrip->hide();
1655                            pChannelStrip->showNormal();
1656                    }   */
1657                    pChannelStrip->adjustSize();
1658                    int iWidth  = m_pWorkspace->width();
1659                    if (iWidth < pChannelStrip->width())
1660                            iWidth = pChannelStrip->width();
1661            //  int iHeight = pChannelStrip->height()
1662            //              + pChannelStrip->parentWidget()->baseSize().height();
1663                    int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
1664                    pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
1665                    y += iHeight;
1666            }
1667            m_pWorkspace->setUpdatesEnabled(true);
1668    
1669            stabilizeForm();
1670  }  }
1671    
1672    
1673  // Auto-arrange channel strips.  // Auto-arrange channel strips.
1674  void MainForm::channelsAutoArrange ( bool bOn )  void MainForm::channelsAutoArrange ( bool bOn )
1675  {  {
1676      if (m_pOptions == NULL)          if (m_pOptions == NULL)
1677          return;                  return;
1678    
1679      // Toggle the auto-arrange flag.          // Toggle the auto-arrange flag.
1680      m_pOptions->bAutoArrange = bOn;          m_pOptions->bAutoArrange = bOn;
1681    
1682      // If on, update whole workspace...          // If on, update whole workspace...
1683      if (m_pOptions->bAutoArrange)          if (m_pOptions->bAutoArrange)
1684          channelsArrange();                  channelsArrange();
1685  }  }
1686    
1687    
# Line 1651  void MainForm::channelsAutoArrange ( boo Line 1691  void MainForm::channelsAutoArrange ( boo
1691  // Show information about the Qt toolkit.  // Show information about the Qt toolkit.
1692  void MainForm::helpAboutQt (void)  void MainForm::helpAboutQt (void)
1693  {  {
1694      QMessageBox::aboutQt(this);          QMessageBox::aboutQt(this);
1695  }  }
1696    
1697    
1698  // Show information about application program.  // Show information about application program.
1699  void MainForm::helpAbout (void)  void MainForm::helpAbout (void)
1700  {  {
1701      // Stuff the about box text...          // Stuff the about box text...
1702      QString sText = "<p>\n";          QString sText = "<p>\n";
1703      sText += "<b>" QSAMPLER_TITLE " - " + tr(QSAMPLER_SUBTITLE) + "</b><br />\n";          sText += "<b>" QSAMPLER_TITLE " - " + tr(QSAMPLER_SUBTITLE) + "</b><br />\n";
1704      sText += "<br />\n";          sText += "<br />\n";
1705      sText += tr("Version") + ": <b>" QSAMPLER_VERSION "</b><br />\n";          sText += tr("Version") + ": <b>" QSAMPLER_VERSION "</b><br />\n";
1706      sText += "<small>" + tr("Build") + ": " __DATE__ " " __TIME__ "</small><br />\n";          sText += "<small>" + tr("Build") + ": " __DATE__ " " __TIME__ "</small><br />\n";
1707  #ifdef CONFIG_DEBUG  #ifdef CONFIG_DEBUG
1708      sText += "<small><font color=\"red\">";          sText += "<small><font color=\"red\">";
1709      sText += tr("Debugging option enabled.");          sText += tr("Debugging option enabled.");
1710      sText += "</font></small><br />";          sText += "</font></small><br />";
1711  #endif  #endif
1712  #ifndef CONFIG_LIBGIG  #ifndef CONFIG_LIBGIG
1713      sText += "<small><font color=\"red\">";          sText += "<small><font color=\"red\">";
1714      sText += tr("GIG (libgig) file support disabled.");          sText += tr("GIG (libgig) file support disabled.");
1715      sText += "</font></small><br />";          sText += "</font></small><br />";
1716  #endif  #endif
1717  #ifndef CONFIG_INSTRUMENT_NAME  #ifndef CONFIG_INSTRUMENT_NAME
1718      sText += "<small><font color=\"red\">";          sText += "<small><font color=\"red\">";
1719      sText += tr("LSCP (liblscp) instrument_name support disabled.");          sText += tr("LSCP (liblscp) instrument_name support disabled.");
1720      sText += "</font></small><br />";          sText += "</font></small><br />";
1721  #endif  #endif
1722  #ifndef CONFIG_MUTE_SOLO  #ifndef CONFIG_MUTE_SOLO
1723      sText += "<small><font color=\"red\">";          sText += "<small><font color=\"red\">";
1724      sText += tr("Sampler channel Mute/Solo support disabled.");          sText += tr("Sampler channel Mute/Solo support disabled.");
1725      sText += "</font></small><br />";          sText += "</font></small><br />";
1726  #endif  #endif
1727  #ifndef CONFIG_AUDIO_ROUTING  #ifndef CONFIG_AUDIO_ROUTING
1728      sText += "<small><font color=\"red\">";          sText += "<small><font color=\"red\">";
1729      sText += tr("LSCP (liblscp) audio_routing support disabled.");          sText += tr("LSCP (liblscp) audio_routing support disabled.");
1730      sText += "</font></small><br />";          sText += "</font></small><br />";
1731  #endif  #endif
1732  #ifndef CONFIG_FXSEND  #ifndef CONFIG_FXSEND
1733      sText += "<small><font color=\"red\">";          sText += "<small><font color=\"red\">";
1734      sText += tr("Sampler channel Effect Sends support disabled.");          sText += tr("Sampler channel Effect Sends support disabled.");
1735      sText += "</font></small><br />";          sText += "</font></small><br />";
1736  #endif  #endif
1737  #ifndef CONFIG_VOLUME  #ifndef CONFIG_VOLUME
1738      sText += "<small><font color=\"red\">";          sText += "<small><font color=\"red\">";
1739      sText += tr("Global volume support disabled.");          sText += tr("Global volume support disabled.");
1740      sText += "</font></small><br />";          sText += "</font></small><br />";
1741  #endif  #endif
1742  #ifndef CONFIG_MIDI_INSTRUMENT  #ifndef CONFIG_MIDI_INSTRUMENT
1743      sText += "<small><font color=\"red\">";          sText += "<small><font color=\"red\">";
1744      sText += tr("MIDI instrument mapping support disabled.");          sText += tr("MIDI instrument mapping support disabled.");
1745      sText += "</font></small><br />";          sText += "</font></small><br />";
1746  #endif  #endif
1747  #ifndef CONFIG_EDIT_INSTRUMENT  #ifndef CONFIG_EDIT_INSTRUMENT
1748      sText += "<small><font color=\"red\">";          sText += "<small><font color=\"red\">";
1749      sText += tr("Instrument editing support disabled.");          sText += tr("Instrument editing support disabled.");
1750      sText += "</font></small><br />";          sText += "</font></small><br />";
1751  #endif  #endif
1752      sText += "<br />\n";          sText += "<br />\n";
1753      sText += tr("Using") + ": ";          sText += tr("Using") + ": ";
1754      sText += ::lscp_client_package();          sText += ::lscp_client_package();
1755      sText += " ";          sText += " ";
1756      sText += ::lscp_client_version();          sText += ::lscp_client_version();
1757  #ifdef CONFIG_LIBGIG  #ifdef CONFIG_LIBGIG
1758      sText += ", ";          sText += ", ";
1759      sText += gig::libraryName().c_str();          sText += gig::libraryName().c_str();
1760      sText += " ";          sText += " ";
1761      sText += gig::libraryVersion().c_str();          sText += gig::libraryVersion().c_str();
1762  #endif  #endif
1763      sText += "<br />\n";          sText += "<br />\n";
1764      sText += "<br />\n";          sText += "<br />\n";
1765      sText += tr("Website") + ": <a href=\"" QSAMPLER_WEBSITE "\">" QSAMPLER_WEBSITE "</a><br />\n";          sText += tr("Website") + ": <a href=\"" QSAMPLER_WEBSITE "\">" QSAMPLER_WEBSITE "</a><br />\n";
1766      sText += "<br />\n";          sText += "<br />\n";
1767      sText += "<small>";          sText += "<small>";
1768      sText += QSAMPLER_COPYRIGHT "<br />\n";          sText += QSAMPLER_COPYRIGHT "<br />\n";
1769      sText += QSAMPLER_COPYRIGHT2 "<br />\n";          sText += QSAMPLER_COPYRIGHT2 "<br />\n";
1770      sText += "<br />\n";          sText += "<br />\n";
1771      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";
1772      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.");
1773      sText += "</small>";          sText += "</small>";
1774      sText += "</p>\n";          sText += "</p>\n";
1775    
1776      QMessageBox::about(this, tr("About") + " " QSAMPLER_TITLE, sText);          QMessageBox::about(this, tr("About") + " " QSAMPLER_TITLE, sText);
1777  }  }
1778    
1779    
# Line 1742  void MainForm::helpAbout (void) Line 1782  void MainForm::helpAbout (void)
1782    
1783  void MainForm::stabilizeForm (void)  void MainForm::stabilizeForm (void)
1784  {  {
1785      // Update the main application caption...          // Update the main application caption...
1786      QString sSessionName = sessionName(m_sFilename);          QString sSessionName = sessionName(m_sFilename);
1787      if (m_iDirtyCount > 0)          if (m_iDirtyCount > 0)
1788          sSessionName += " *";                  sSessionName += " *";
1789      setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));
1790    
1791      // Update the main menu state...          // Update the main menu state...
1792      ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip* pChannelStrip = activeChannelStrip();
1793      bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);          bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);
1794      bool bHasChannel = (bHasClient && pChannelStrip != NULL);          bool bHasChannel = (bHasClient && pChannelStrip != NULL);
1795      ui.fileNewAction->setEnabled(bHasClient);          m_ui.fileNewAction->setEnabled(bHasClient);
1796      ui.fileOpenAction->setEnabled(bHasClient);          m_ui.fileOpenAction->setEnabled(bHasClient);
1797      ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
1798      ui.fileSaveAsAction->setEnabled(bHasClient);          m_ui.fileSaveAsAction->setEnabled(bHasClient);
1799      ui.fileResetAction->setEnabled(bHasClient);          m_ui.fileResetAction->setEnabled(bHasClient);
1800      ui.fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);          m_ui.fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);
1801      ui.editAddChannelAction->setEnabled(bHasClient);          m_ui.editAddChannelAction->setEnabled(bHasClient);
1802      ui.editRemoveChannelAction->setEnabled(bHasChannel);          m_ui.editRemoveChannelAction->setEnabled(bHasChannel);
1803      ui.editSetupChannelAction->setEnabled(bHasChannel);          m_ui.editSetupChannelAction->setEnabled(bHasChannel);
1804  #ifdef CONFIG_EDIT_INSTRUMENT  #ifdef CONFIG_EDIT_INSTRUMENT
1805      ui.editEditChannelAction->setEnabled(bHasChannel);          m_ui.editEditChannelAction->setEnabled(bHasChannel);
1806  #else  #else
1807      ui.editEditChannelAction->setEnabled(false);          m_ui.editEditChannelAction->setEnabled(false);
1808  #endif  #endif
1809      ui.editResetChannelAction->setEnabled(bHasChannel);          m_ui.editResetChannelAction->setEnabled(bHasChannel);
1810      ui.editResetAllChannelsAction->setEnabled(bHasChannel);          m_ui.editResetAllChannelsAction->setEnabled(bHasChannel);
1811      ui.viewMessagesAction->setChecked(m_pMessages && m_pMessages->isVisible());          m_ui.viewMessagesAction->setChecked(m_pMessages && m_pMessages->isVisible());
1812  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
1813          ui.viewInstrumentsAction->setChecked(m_pInstrumentListForm          m_ui.viewInstrumentsAction->setChecked(m_pInstrumentListForm
1814                  && m_pInstrumentListForm->isVisible());                  && m_pInstrumentListForm->isVisible());
1815          ui.viewInstrumentsAction->setEnabled(bHasClient);          m_ui.viewInstrumentsAction->setEnabled(bHasClient);
1816  #else  #else
1817          ui.viewInstrumentsAction->setEnabled(false);          m_ui.viewInstrumentsAction->setEnabled(false);
1818  #endif  #endif
1819          ui.viewDevicesAction->setChecked(m_pDeviceForm          m_ui.viewDevicesAction->setChecked(m_pDeviceForm
1820                  && m_pDeviceForm->isVisible());                  && m_pDeviceForm->isVisible());
1821      ui.viewDevicesAction->setEnabled(bHasClient);          m_ui.viewDevicesAction->setEnabled(bHasClient);
1822      ui.channelsArrangeAction->setEnabled(bHasChannel);          m_ui.channelsArrangeAction->setEnabled(bHasChannel);
1823    
1824  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
1825          // Toolbar widgets are also affected...          // Toolbar widgets are also affected...
1826      m_pVolumeSlider->setEnabled(bHasClient);          m_pVolumeSlider->setEnabled(bHasClient);
1827      m_pVolumeSpinBox->setEnabled(bHasClient);          m_pVolumeSpinBox->setEnabled(bHasClient);
1828  #endif  #endif
1829    
1830      // Client/Server status...          // Client/Server status...
1831      if (bHasClient) {          if (bHasClient) {
1832          m_statusItem[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));                  m_statusItem[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));
1833          m_statusItem[QSAMPLER_STATUS_SERVER]->setText(m_pOptions->sServerHost + ":" + QString::number(m_pOptions->iServerPort));                  m_statusItem[QSAMPLER_STATUS_SERVER]->setText(m_pOptions->sServerHost
1834      } else {                          + ':' + QString::number(m_pOptions->iServerPort));
1835          m_statusItem[QSAMPLER_STATUS_CLIENT]->clear();          } else {
1836          m_statusItem[QSAMPLER_STATUS_SERVER]->clear();                  m_statusItem[QSAMPLER_STATUS_CLIENT]->clear();
1837      }                  m_statusItem[QSAMPLER_STATUS_SERVER]->clear();
1838      // Channel status...          }
1839      if (bHasChannel)          // Channel status...
1840          m_statusItem[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->windowTitle());          if (bHasChannel)
1841      else                  m_statusItem[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->windowTitle());
1842          m_statusItem[QSAMPLER_STATUS_CHANNEL]->clear();          else
1843      // Session status...                  m_statusItem[QSAMPLER_STATUS_CHANNEL]->clear();
1844      if (m_iDirtyCount > 0)          // Session status...
1845          m_statusItem[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));          if (m_iDirtyCount > 0)
1846      else                  m_statusItem[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));
1847          m_statusItem[QSAMPLER_STATUS_SESSION]->clear();          else
1848                    m_statusItem[QSAMPLER_STATUS_SESSION]->clear();
1849    
1850      // Recent files menu.          // Recent files menu.
1851          ui.fileOpenRecentMenu->setEnabled(m_pOptions->recentFiles.count() > 0);          m_ui.fileOpenRecentMenu->setEnabled(m_pOptions->recentFiles.count() > 0);
1852  }  }
1853    
1854    
# Line 1852  void MainForm::channelStripChanged(Chann Line 1893  void MainForm::channelStripChanged(Chann
1893                  pChannelStrip->resetErrorCount();                  pChannelStrip->resetErrorCount();
1894          }          }
1895    
1896      // Just mark the dirty form.          // Just mark the dirty form.
1897      m_iDirtyCount++;          m_iDirtyCount++;
1898      // and update the form status...          // and update the form status...
1899      stabilizeForm();          stabilizeForm();
1900  }  }
1901    
1902    
# Line 1887  void MainForm::updateSession (void) Line 1928  void MainForm::updateSession (void)
1928          if (piChannelIDs == NULL) {          if (piChannelIDs == NULL) {
1929                  if (::lscp_client_get_errno(m_pClient)) {                  if (::lscp_client_get_errno(m_pClient)) {
1930                          appendMessagesClient("lscp_list_channels");                          appendMessagesClient("lscp_list_channels");
1931                          appendMessagesError(tr("Could not get current list of channels.\n\nSorry."));                          appendMessagesError(
1932                                    tr("Could not get current list of channels.\n\nSorry."));
1933                  }                  }
1934          } else {          } else {
1935                  // Try to (re)create each channel.                  // Try to (re)create each channel.
# Line 1895  void MainForm::updateSession (void) Line 1937  void MainForm::updateSession (void)
1937                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {
1938                          // Check if theres already a channel strip for this one...                          // Check if theres already a channel strip for this one...
1939                          if (!channelStrip(piChannelIDs[iChannel]))                          if (!channelStrip(piChannelIDs[iChannel]))
1940                                  createChannelStrip(new qsamplerChannel(piChannelIDs[iChannel]));                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));
1941                  }                  }
1942                  m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
1943          }          }
1944    
1945      // Do we auto-arrange?          // Do we auto-arrange?
1946      if (m_pOptions && m_pOptions->bAutoArrange)          if (m_pOptions && m_pOptions->bAutoArrange)
1947          channelsArrange();                  channelsArrange();
1948    
1949          // Remember to refresh devices and instruments...          // Remember to refresh devices and instruments...
1950          if (m_pInstrumentListForm)          if (m_pInstrumentListForm)
1951              m_pInstrumentListForm->refreshInstruments();                  m_pInstrumentListForm->refreshInstruments();
1952          if (m_pDeviceForm)          if (m_pDeviceForm)
1953              m_pDeviceForm->refreshDevices();                  m_pDeviceForm->refreshDevices();
1954  }  }
1955    
1956    
1957  // Update the recent files list and menu.  // Update the recent files list and menu.
1958  void MainForm::updateRecentFiles ( const QString& sFilename )  void MainForm::updateRecentFiles ( const QString& sFilename )
1959  {  {
1960      if (m_pOptions == NULL)          if (m_pOptions == NULL)
1961          return;                  return;
1962    
1963      // Remove from list if already there (avoid duplicates)          // Remove from list if already there (avoid duplicates)
1964      int iIndex = m_pOptions->recentFiles.indexOf(sFilename);          int iIndex = m_pOptions->recentFiles.indexOf(sFilename);
1965      if (iIndex >= 0)          if (iIndex >= 0)
1966          m_pOptions->recentFiles.removeAt(iIndex);                  m_pOptions->recentFiles.removeAt(iIndex);
1967      // Put it to front...          // Put it to front...
1968      m_pOptions->recentFiles.push_front(sFilename);          m_pOptions->recentFiles.push_front(sFilename);
1969  }  }
1970    
1971    
# Line 1941  void MainForm::updateRecentFilesMenu (vo Line 1983  void MainForm::updateRecentFilesMenu (vo
1983          }          }
1984    
1985          // Rebuild the recent files menu...          // Rebuild the recent files menu...
1986          ui.fileOpenRecentMenu->clear();          m_ui.fileOpenRecentMenu->clear();
1987          for (int i = 0; i < iRecentFiles; i++) {          for (int i = 0; i < iRecentFiles; i++) {
1988                  const QString& sFilename = m_pOptions->recentFiles[i];                  const QString& sFilename = m_pOptions->recentFiles[i];
1989                  if (QFileInfo(sFilename).exists()) {                  if (QFileInfo(sFilename).exists()) {
1990                          QAction *pAction = ui.fileOpenRecentMenu->addAction(                          QAction *pAction = m_ui.fileOpenRecentMenu->addAction(
1991                                  QString("&%1 %2").arg(i + 1).arg(sessionName(sFilename)),                                  QString("&%1 %2").arg(i + 1).arg(sessionName(sFilename)),
1992                                  this, SLOT(fileOpenRecent()));                                  this, SLOT(fileOpenRecent()));
1993                          pAction->setData(i);                          pAction->setData(i);
# Line 1957  void MainForm::updateRecentFilesMenu (vo Line 1999  void MainForm::updateRecentFilesMenu (vo
1999  // Force update of the channels instrument names mode.  // Force update of the channels instrument names mode.
2000  void MainForm::updateInstrumentNames (void)  void MainForm::updateInstrumentNames (void)
2001  {  {
2002      // Full channel list update...          // Full channel list update...
2003      QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
2004      if (wlist.isEmpty())          if (wlist.isEmpty())
2005          return;                  return;
2006    
2007      m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2008      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
2009          ChannelStrip *pChannelStrip = (ChannelStrip *) wlist.at(iChannel);                  ChannelStrip *pChannelStrip = (ChannelStrip *) wlist.at(iChannel);
2010          if (pChannelStrip)                  if (pChannelStrip)
2011              pChannelStrip->updateInstrumentName(true);                          pChannelStrip->updateInstrumentName(true);
2012      }          }
2013      m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
2014  }  }
2015    
2016    
2017  // Force update of the channels display font.  // Force update of the channels display font.
2018  void MainForm::updateDisplayFont (void)  void MainForm::updateDisplayFont (void)
2019  {  {
2020      if (m_pOptions == NULL)          if (m_pOptions == NULL)
2021          return;                  return;
2022    
2023            // Check if display font is legal.
2024            if (m_pOptions->sDisplayFont.isEmpty())
2025                    return;
2026            // Realize it.
2027            QFont font;
2028            if (!font.fromString(m_pOptions->sDisplayFont))
2029                    return;
2030    
2031      // Check if display font is legal.          // Full channel list update...
2032      if (m_pOptions->sDisplayFont.isEmpty())          QWidgetList wlist = m_pWorkspace->windowList();
2033          return;          if (wlist.isEmpty())
2034      // Realize it.                  return;
2035      QFont font;  
2036      if (!font.fromString(m_pOptions->sDisplayFont))          m_pWorkspace->setUpdatesEnabled(false);
2037          return;          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
2038                    ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);
2039      // Full channel list update...                  if (pChannelStrip)
2040      QWidgetList wlist = m_pWorkspace->windowList();                          pChannelStrip->setDisplayFont(font);
2041      if (wlist.isEmpty())          }
2042          return;          m_pWorkspace->setUpdatesEnabled(true);
   
     m_pWorkspace->setUpdatesEnabled(false);  
     for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {  
         ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);  
         if (pChannelStrip)  
             pChannelStrip->setDisplayFont(font);  
     }  
     m_pWorkspace->setUpdatesEnabled(true);  
2043  }  }
2044    
2045    
2046  // Update channel strips background effect.  // Update channel strips background effect.
2047  void MainForm::updateDisplayEffect (void)  void MainForm::updateDisplayEffect (void)
2048  {  {
2049      // Full channel list update...          // Full channel list update...
2050      QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
2051      if (wlist.isEmpty())          if (wlist.isEmpty())
2052          return;                  return;
2053    
2054      m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2055      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
2056          ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);
2057                  if (pChannelStrip)                  if (pChannelStrip)
2058                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);                          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2059      }          }
2060      m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
2061  }  }
2062    
2063    
2064  // Force update of the channels maximum volume setting.  // Force update of the channels maximum volume setting.
2065  void MainForm::updateMaxVolume (void)  void MainForm::updateMaxVolume (void)
2066  {  {
2067      if (m_pOptions == NULL)          if (m_pOptions == NULL)
2068          return;                  return;
2069    
2070  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
2071          m_iVolumeChanging++;          m_iVolumeChanging++;
# Line 2032  void MainForm::updateMaxVolume (void) Line 2074  void MainForm::updateMaxVolume (void)
2074          m_iVolumeChanging--;          m_iVolumeChanging--;
2075  #endif  #endif
2076    
2077      // Full channel list update...          // Full channel list update...
2078      QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
2079      if (wlist.isEmpty())          if (wlist.isEmpty())
2080          return;                  return;
2081    
2082      m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
2083      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
2084          ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                  ChannelStrip* pChannelStrip = (ChannelStrip*) wlist.at(iChannel);
2085          if (pChannelStrip)                  if (pChannelStrip)
2086              pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);                          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2087      }          }
2088      m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
2089  }  }
2090    
2091    
# Line 2053  void MainForm::updateMaxVolume (void) Line 2095  void MainForm::updateMaxVolume (void)
2095  // Messages output methods.  // Messages output methods.
2096  void MainForm::appendMessages( const QString& s )  void MainForm::appendMessages( const QString& s )
2097  {  {
2098      if (m_pMessages)          if (m_pMessages)
2099          m_pMessages->appendMessages(s);                  m_pMessages->appendMessages(s);
2100    
2101      statusBar()->showMessage(s, 3000);          statusBar()->showMessage(s, 3000);
2102  }  }
2103    
2104  void MainForm::appendMessagesColor( const QString& s, const QString& c )  void MainForm::appendMessagesColor( const QString& s, const QString& c )
2105  {  {
2106      if (m_pMessages)          if (m_pMessages)
2107          m_pMessages->appendMessagesColor(s, c);                  m_pMessages->appendMessagesColor(s, c);
2108    
2109      statusBar()->showMessage(s, 3000);          statusBar()->showMessage(s, 3000);
2110  }  }
2111    
2112  void MainForm::appendMessagesText( const QString& s )  void MainForm::appendMessagesText( const QString& s )
2113  {  {
2114      if (m_pMessages)          if (m_pMessages)
2115          m_pMessages->appendMessagesText(s);                  m_pMessages->appendMessagesText(s);
2116  }  }
2117    
2118  void MainForm::appendMessagesError( const QString& s )  void MainForm::appendMessagesError( const QString& s )
2119  {  {
2120      if (m_pMessages)          if (m_pMessages)
2121          m_pMessages->show();                  m_pMessages->show();
2122    
2123      appendMessagesColor(s.simplified(), "#ff0000");          appendMessagesColor(s.simplified(), "#ff0000");
2124    
2125          // Make it look responsive...:)          // Make it look responsive...:)
2126          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2127    
2128      QMessageBox::critical(this,          QMessageBox::critical(this,
2129                  QSAMPLER_TITLE ": " + tr("Error"), s, tr("Cancel"));                  QSAMPLER_TITLE ": " + tr("Error"), s, tr("Cancel"));
2130  }  }
2131    
# Line 2091  void MainForm::appendMessagesError( cons Line 2133  void MainForm::appendMessagesError( cons
2133  // This is a special message format, just for client results.  // This is a special message format, just for client results.
2134  void MainForm::appendMessagesClient( const QString& s )  void MainForm::appendMessagesClient( const QString& s )
2135  {  {
2136      if (m_pClient == NULL)          if (m_pClient == NULL)
2137          return;                  return;
2138    
2139      appendMessagesColor(s + QString(": %1 (errno=%2)")          appendMessagesColor(s + QString(": %1 (errno=%2)")
2140          .arg(::lscp_client_get_result(m_pClient))                  .arg(::lscp_client_get_result(m_pClient))
2141          .arg(::lscp_client_get_errno(m_pClient)), "#996666");                  .arg(::lscp_client_get_errno(m_pClient)), "#996666");
2142    
2143          // Make it look responsive...:)          // Make it look responsive...:)
2144          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
# Line 2106  void MainForm::appendMessagesClient( con Line 2148  void MainForm::appendMessagesClient( con
2148  // Force update of the messages font.  // Force update of the messages font.
2149  void MainForm::updateMessagesFont (void)  void MainForm::updateMessagesFont (void)
2150  {  {
2151      if (m_pOptions == NULL)          if (m_pOptions == NULL)
2152          return;                  return;
2153    
2154      if (m_pMessages && !m_pOptions->sMessagesFont.isEmpty()) {          if (m_pMessages && !m_pOptions->sMessagesFont.isEmpty()) {
2155          QFont font;                  QFont font;
2156          if (font.fromString(m_pOptions->sMessagesFont))                  if (font.fromString(m_pOptions->sMessagesFont))
2157              m_pMessages->setMessagesFont(font);                          m_pMessages->setMessagesFont(font);
2158      }          }
2159  }  }
2160    
2161    
2162  // Update messages window line limit.  // Update messages window line limit.
2163  void MainForm::updateMessagesLimit (void)  void MainForm::updateMessagesLimit (void)
2164  {  {
2165      if (m_pOptions == NULL)          if (m_pOptions == NULL)
2166          return;                  return;
2167    
2168      if (m_pMessages) {          if (m_pMessages) {
2169          if (m_pOptions->bMessagesLimit)                  if (m_pOptions->bMessagesLimit)
2170              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);                          m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);
2171          else                  else
2172              m_pMessages->setMessagesLimit(-1);                          m_pMessages->setMessagesLimit(-1);
2173      }          }
2174  }  }
2175    
2176    
2177  // Enablement of the messages capture feature.  // Enablement of the messages capture feature.
2178  void MainForm::updateMessagesCapture (void)  void MainForm::updateMessagesCapture (void)
2179  {  {
2180      if (m_pOptions == NULL)          if (m_pOptions == NULL)
2181          return;                  return;
2182    
2183      if (m_pMessages)          if (m_pMessages)
2184          m_pMessages->setCaptureEnabled(m_pOptions->bStdoutCapture);                  m_pMessages->setCaptureEnabled(m_pOptions->bStdoutCapture);
2185  }  }
2186    
2187    
# Line 2147  void MainForm::updateMessagesCapture (vo Line 2189  void MainForm::updateMessagesCapture (vo
2189  // qsamplerMainForm -- MDI channel strip management.  // qsamplerMainForm -- MDI channel strip management.
2190    
2191  // The channel strip creation executive.  // The channel strip creation executive.
2192  ChannelStrip* MainForm::createChannelStrip(qsamplerChannel* pChannel)  ChannelStrip* MainForm::createChannelStrip ( Channel *pChannel )
2193  {  {
2194      if (m_pClient == NULL || pChannel == NULL)          if (m_pClient == NULL || pChannel == NULL)
2195          return NULL;                  return NULL;
2196    
2197      // Prepare for auto-arrange?          // Add a new channel itema...
2198      ChannelStrip* pChannelStrip = NULL;          ChannelStrip *pChannelStrip = new ChannelStrip();
2199      int y = 0;          if (pChannelStrip == NULL)
2200      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();  
                         }  
         }  
     }  
2201    
2202      // Add a new channel itema...          // Set some initial channel strip options...
2203      pChannelStrip = new ChannelStrip();          if (m_pOptions) {
2204      if (pChannelStrip == NULL)                  // Background display effect...
2205          return NULL;                  pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2206                    // We'll need a display font.
2207                    QFont font;
2208                    if (font.fromString(m_pOptions->sDisplayFont))
2209                            pChannelStrip->setDisplayFont(font);
2210                    // Maximum allowed volume setting.
2211                    pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2212            }
2213    
2214            // Add it to workspace...
2215          m_pWorkspace->addWindow(pChannelStrip, Qt::FramelessWindowHint);          m_pWorkspace->addWindow(pChannelStrip, Qt::FramelessWindowHint);
2216    
2217      // Actual channel strip setup...          // Actual channel strip setup...
2218      pChannelStrip->setup(pChannel);          pChannelStrip->setup(pChannel);
2219    
2220          QObject::connect(pChannelStrip,          QObject::connect(pChannelStrip,
2221                  SIGNAL(channelChanged(ChannelStrip*)),                  SIGNAL(channelChanged(ChannelStrip*)),
2222                  SLOT(channelStripChanged(ChannelStrip*)));                  SLOT(channelStripChanged(ChannelStrip*)));
2223      // Set some initial aesthetic options...  
2224      if (m_pOptions) {          // Now we show up us to the world.
2225          // 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);  
     }  
2226    
2227          // This is pretty new, so we'll watch for it closely.          // This is pretty new, so we'll watch for it closely.
2228          channelStripChanged(pChannelStrip);          channelStripChanged(pChannelStrip);
2229    
2230      // Return our successful reference...          // Return our successful reference...
2231      return pChannelStrip;          return pChannelStrip;
2232  }  }
2233    
2234    
2235  // Retrieve the active channel strip.  // Retrieve the active channel strip.
2236  ChannelStrip* MainForm::activeChannelStrip (void)  ChannelStrip* MainForm::activeChannelStrip (void)
2237  {  {
2238      return static_cast<ChannelStrip *> (m_pWorkspace->activeWindow());          return static_cast<ChannelStrip *> (m_pWorkspace->activeWindow());
2239  }  }
2240    
2241    
2242  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2243  ChannelStrip* MainForm::channelStripAt ( int iChannel )  ChannelStrip* MainForm::channelStripAt ( int iChannel )
2244  {  {
2245      QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
2246      if (wlist.isEmpty())          if (wlist.isEmpty())
2247          return NULL;                  return NULL;
2248    
2249      return static_cast<ChannelStrip *> (wlist.at(iChannel));          return static_cast<ChannelStrip *> (wlist.at(iChannel));
2250  }  }
2251    
2252    
# Line 2236  ChannelStrip* MainForm::channelStrip ( i Line 2261  ChannelStrip* MainForm::channelStrip ( i
2261                  ChannelStrip* pChannelStrip                  ChannelStrip* pChannelStrip
2262                          = static_cast<ChannelStrip*> (wlist.at(iChannel));                          = static_cast<ChannelStrip*> (wlist.at(iChannel));
2263                  if (pChannelStrip) {                  if (pChannelStrip) {
2264                          qsamplerChannel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
2265                          if (pChannel && pChannel->channelID() == iChannelID)                          if (pChannel && pChannel->channelID() == iChannelID)
2266                                  return pChannelStrip;                                  return pChannelStrip;
2267                  }                  }
# Line 2250  ChannelStrip* MainForm::channelStrip ( i Line 2275  ChannelStrip* MainForm::channelStrip ( i
2275  // Construct the windows menu.  // Construct the windows menu.
2276  void MainForm::channelsMenuAboutToShow (void)  void MainForm::channelsMenuAboutToShow (void)
2277  {  {
2278      ui.channelsMenu->clear();          m_ui.channelsMenu->clear();
2279          ui.channelsMenu->addAction(ui.channelsArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsArrangeAction);
2280          ui.channelsMenu->addAction(ui.channelsAutoArrangeAction);          m_ui.channelsMenu->addAction(m_ui.channelsAutoArrangeAction);
2281    
2282      QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
2283      if (!wlist.isEmpty()) {          if (!wlist.isEmpty()) {
2284                  ui.channelsMenu->addSeparator();                  m_ui.channelsMenu->addSeparator();
2285          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
2286                          ChannelStrip* pChannelStrip                          ChannelStrip* pChannelStrip
2287                                  = static_cast<ChannelStrip*> (wlist.at(iChannel));                                  = static_cast<ChannelStrip*> (wlist.at(iChannel));
2288                          if (pChannelStrip) {                          if (pChannelStrip) {
2289                                  QAction *pAction = ui.channelsMenu->addAction(                                  QAction *pAction = m_ui.channelsMenu->addAction(
2290                                          pChannelStrip->windowTitle(), this, SLOT(channelsMenuActivated()));                                          pChannelStrip->windowTitle(),
2291                                            this, SLOT(channelsMenuActivated()));
2292                                  pAction->setCheckable(true);                                  pAction->setCheckable(true);
2293                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);                                  pAction->setChecked(activeChannelStrip() == pChannelStrip);
2294                                  pAction->setData(iChannel);                                  pAction->setData(iChannel);
2295                          }                          }
2296          }                  }
2297      }          }
2298  }  }
2299    
2300    
# Line 2294  void MainForm::channelsMenuActivated (vo Line 2320  void MainForm::channelsMenuActivated (vo
2320  // Set the pseudo-timer delay schedule.  // Set the pseudo-timer delay schedule.
2321  void MainForm::startSchedule ( int iStartDelay )  void MainForm::startSchedule ( int iStartDelay )
2322  {  {
2323      m_iStartDelay  = 1 + (iStartDelay * 1000);          m_iStartDelay  = 1 + (iStartDelay * 1000);
2324      m_iTimerDelay  = 0;          m_iTimerDelay  = 0;
2325  }  }
2326    
2327  // Suspend the pseudo-timer delay schedule.  // Suspend the pseudo-timer delay schedule.
2328  void MainForm::stopSchedule (void)  void MainForm::stopSchedule (void)
2329  {  {
2330      m_iStartDelay  = 0;          m_iStartDelay  = 0;
2331      m_iTimerDelay  = 0;          m_iTimerDelay  = 0;
2332  }  }
2333    
2334  // Timer slot funtion.  // Timer slot funtion.
2335  void MainForm::timerSlot (void)  void MainForm::timerSlot (void)
2336  {  {
2337      if (m_pOptions == NULL)          if (m_pOptions == NULL)
2338          return;                  return;
2339    
2340      // Is it the first shot on server start after a few delay?          // Is it the first shot on server start after a few delay?
2341      if (m_iTimerDelay < m_iStartDelay) {          if (m_iTimerDelay < m_iStartDelay) {
2342          m_iTimerDelay += QSAMPLER_TIMER_MSECS;                  m_iTimerDelay += QSAMPLER_TIMER_MSECS;
2343          if (m_iTimerDelay >= m_iStartDelay) {                  if (m_iTimerDelay >= m_iStartDelay) {
2344              // If we cannot start it now, maybe a lil'mo'later ;)                          // If we cannot start it now, maybe a lil'mo'later ;)
2345              if (!startClient()) {                          if (!startClient()) {
2346                  m_iStartDelay += m_iTimerDelay;                                  m_iStartDelay += m_iTimerDelay;
2347                  m_iTimerDelay  = 0;                                  m_iTimerDelay  = 0;
2348              }                          }
2349          }                  }
2350      }          }
2351    
2352          if (m_pClient) {          if (m_pClient) {
2353                  // Update the channel information for each pending strip...                  // Update the channel information for each pending strip...
# Line 2353  void MainForm::timerSlot (void) Line 2379  void MainForm::timerSlot (void)
2379                  }                  }
2380          }          }
2381    
2382      // Register the next timer slot.          // Register the next timer slot.
2383      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));          QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));
2384  }  }
2385    
2386    
# Line 2364  void MainForm::timerSlot (void) Line 2390  void MainForm::timerSlot (void)
2390  // Start linuxsampler server...  // Start linuxsampler server...
2391  void MainForm::startServer (void)  void MainForm::startServer (void)
2392  {  {
2393      if (m_pOptions == NULL)          if (m_pOptions == NULL)
2394          return;                  return;
2395    
2396      // Aren't already a client, are we?          // Aren't already a client, are we?
2397      if (!m_pOptions->bServerStart || m_pClient)          if (!m_pOptions->bServerStart || m_pClient)
2398          return;                  return;
2399    
2400      // Is the server process instance still here?          // Is the server process instance still here?
2401      if (m_pServer) {          if (m_pServer) {
2402          switch (QMessageBox::warning(this,                  switch (QMessageBox::warning(this,
2403                          QSAMPLER_TITLE ": " + tr("Warning"),                          QSAMPLER_TITLE ": " + tr("Warning"),
2404              tr("Could not start the LinuxSampler server.\n\n"                          tr("Could not start the LinuxSampler server.\n\n"
2405                 "Maybe it ss already started."),                          "Maybe it is already started."),
2406              tr("Stop"), tr("Kill"), tr("Cancel"))) {                          tr("Stop"), tr("Kill"), tr("Cancel"))) {
2407            case 0:                  case 0:
2408              m_pServer->terminate();                          m_pServer->terminate();
2409              break;                          break;
2410            case 1:                  case 1:
2411              m_pServer->kill();                          m_pServer->kill();
2412              break;                          break;
2413          }                  }
2414          return;                  return;
2415      }          }
2416    
2417      // Reset our timer counters...          // Reset our timer counters...
2418      stopSchedule();          stopSchedule();
2419    
2420      // OK. Let's build the startup process...          // Verify we have something to start with...
2421      m_pServer = new QProcess(this);          if (m_pOptions->sServerCmdLine.isEmpty())
2422                    return;
2423      // Setup stdout/stderr capture...  
2424          //      if (m_pOptions->bStdoutCapture) {          // OK. Let's build the startup process...
2425                  //m_pServer->setProcessChannelMode(          m_pServer = new QProcess();
2426                  //      QProcess::StandardOutput);          bForceServerStop = true;
2427    
2428            // Setup stdout/stderr capture...
2429    //      if (m_pOptions->bStdoutCapture) {
2430    #if QT_VERSION >= 0x040200
2431                    m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);
2432    #endif
2433                  QObject::connect(m_pServer,                  QObject::connect(m_pServer,
2434                          SIGNAL(readyReadStandardOutput()),                          SIGNAL(readyReadStandardOutput()),
2435                          SLOT(readServerStdout()));                          SLOT(readServerStdout()));
2436                  QObject::connect(m_pServer,                  QObject::connect(m_pServer,
2437                          SIGNAL(readyReadStandardError()),                          SIGNAL(readyReadStandardError()),
2438                          SLOT(readServerStdout()));                          SLOT(readServerStdout()));
2439          //      }  //      }
2440    
2441          // The unforgiveable signal communication...          // The unforgiveable signal communication...
2442          QObject::connect(m_pServer,          QObject::connect(m_pServer,
2443                  SIGNAL(finished(int,QProcess::ExitStatus)),                  SIGNAL(finished(int, QProcess::ExitStatus)),
2444                  SLOT(processServerExit()));                  SLOT(processServerExit()));
2445    
2446      // Build process arguments...          // Build process arguments...
2447      QStringList serverCmdLine = m_pOptions->sServerCmdLine.split(' ');          QStringList args = m_pOptions->sServerCmdLine.split(' ');
2448            QString sCommand = args[0];
2449      appendMessages(tr("Server is starting..."));          args.removeAt(0);
2450      appendMessagesColor(m_pOptions->sServerCmdLine, "#990099");  
2451            appendMessages(tr("Server is starting..."));
2452            appendMessagesColor(m_pOptions->sServerCmdLine, "#990099");
2453    
2454      const QString prog = (serverCmdLine.size() > 0) ? serverCmdLine[0] : QString();          // Go linuxsampler, go...
2455      const QStringList args = serverCmdLine.mid(1);          m_pServer->start(sCommand, args);
2456            if (!m_pServer->waitForStarted()) {
2457      // Go jack, go...                  appendMessagesError(tr("Could not start server.\n\nSorry."));
2458      m_pServer->start(prog, args);                  processServerExit();
2459      if (!m_pServer->waitForStarted()) {                  return;
2460          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()));  
2461    
2462      // Reset (yet again) the timer counters,          // Show startup results...
2463      // but this time is deferred as the user opted.          appendMessages(
2464      startSchedule(m_pOptions->iStartDelay);                  tr("Server was started with PID=%1.").arg((long) m_pServer->pid()));
2465      stabilizeForm();  
2466            // Reset (yet again) the timer counters,
2467            // but this time is deferred as the user opted.
2468            startSchedule(m_pOptions->iStartDelay);
2469            stabilizeForm();
2470  }  }
2471    
2472    
2473  // Stop linuxsampler server...  // Stop linuxsampler server...
2474  void MainForm::stopServer (void)  void MainForm::stopServer (bool bInteractive)
2475  {  {
2476      // Stop client code.          // Stop client code.
2477      stopClient();          stopClient();
2478    
2479            if (m_pServer && bInteractive) {
2480                    if (QMessageBox::question(this,
2481                            QSAMPLER_TITLE ": " + tr("The backend's fate ..."),
2482                            tr("You have the option to keep the sampler backend (LinuxSampler)\n"
2483                            "running in the background. The sampler would continue to work\n"
2484                            "according to your current sampler session and you could alter the\n"
2485                            "sampler session at any time by relaunching QSampler.\n\n"
2486                            "Do you want LinuxSampler to stop or to keep running in\n"
2487                            "the background?"),
2488                            tr("Stop"), tr("Keep Running")) == 1)
2489                    {
2490                            bForceServerStop = false;
2491                    }
2492            }
2493    
2494      // And try to stop server.          // And try to stop server.
2495      if (m_pServer) {          if (m_pServer && bForceServerStop) {
2496          appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2497          if (m_pServer->state() == QProcess::Running)                  if (m_pServer->state() == QProcess::Running) {
2498              m_pServer->terminate();  #if defined(WIN32)
2499       }                          // Try harder...
2500                            m_pServer->kill();
2501      // Give it some time to terminate gracefully and stabilize...  #else
2502      QTime t;                          // Try softly...
2503      t.start();                          m_pServer->terminate();
2504      while (t.elapsed() < QSAMPLER_TIMER_MSECS)  #endif
2505          QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  }
2506            }       // Do final processing anyway.
2507            else processServerExit();
2508    
2509       // Do final processing anyway.          // Give it some time to terminate gracefully and stabilize...
2510       processServerExit();          QTime t;
2511            t.start();
2512            while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2513                    QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2514  }  }
2515    
2516    
2517  // Stdout handler...  // Stdout handler...
2518  void MainForm::readServerStdout (void)  void MainForm::readServerStdout (void)
2519  {  {
2520      if (m_pMessages)          if (m_pMessages)
2521          m_pMessages->appendStdoutBuffer(m_pServer->readAllStandardOutput());                  m_pMessages->appendStdoutBuffer(m_pServer->readAllStandardOutput());
2522  }  }
2523    
2524    
2525  // Linuxsampler server cleanup.  // Linuxsampler server cleanup.
2526  void MainForm::processServerExit (void)  void MainForm::processServerExit (void)
2527  {  {
2528      // Force client code cleanup.          // Force client code cleanup.
2529      stopClient();          stopClient();
2530    
2531      // Flush anything that maybe pending...          // Flush anything that maybe pending...
2532      if (m_pMessages)          if (m_pMessages)
2533          m_pMessages->flushStdoutBuffer();                  m_pMessages->flushStdoutBuffer();
2534    
2535      if (m_pServer) {          if (m_pServer && bForceServerStop) {
2536          // Force final server shutdown...                  if (m_pServer->state() != QProcess::NotRunning) {
2537          appendMessages(tr("Server was stopped with exit status %1.").arg(m_pServer->exitStatus()));                          appendMessages(tr("Server is being forced..."));
2538          m_pServer->terminate();                          // Force final server shutdown...
2539          if (!m_pServer->waitForFinished(2000))                          m_pServer->kill();
2540              m_pServer->kill();                          // Give it some time to terminate gracefully and stabilize...
2541          // Destroy it.                          QTime t;
2542          delete m_pServer;                          t.start();
2543          m_pServer = NULL;                          while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2544      }                                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2545                    }
2546                    // Force final server shutdown...
2547                    appendMessages(
2548                            tr("Server was stopped with exit status %1.")
2549                            .arg(m_pServer->exitStatus()));
2550                    delete m_pServer;
2551                    m_pServer = NULL;
2552            }
2553    
2554      // Again, make status visible stable.          // Again, make status visible stable.
2555      stabilizeForm();          stabilizeForm();
2556  }  }
2557    
2558    
# Line 2501  void MainForm::processServerExit (void) Line 2560  void MainForm::processServerExit (void)
2560  // qsamplerMainForm -- Client stuff.  // qsamplerMainForm -- Client stuff.
2561    
2562  // The LSCP client callback procedure.  // The LSCP client callback procedure.
2563  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*/,
2564            lscp_event_t event, const char *pchData, int cchData, void *pvData )
2565  {  {
2566      MainForm* pMainForm = (MainForm *) pvData;          MainForm* pMainForm = (MainForm *) pvData;
2567      if (pMainForm == NULL)          if (pMainForm == NULL)
2568          return LSCP_FAILED;                  return LSCP_FAILED;
2569    
2570      // ATTN: DO NOT EVER call any GUI code here,          // ATTN: DO NOT EVER call any GUI code here,
2571      // as this is run under some other thread context.          // as this is run under some other thread context.
2572      // A custom event must be posted here...          // A custom event must be posted here...
2573      QApplication::postEvent(pMainForm, new qsamplerCustomEvent(event, pchData, cchData));          QApplication::postEvent(pMainForm,
2574                    new CustomEvent(event, pchData, cchData));
2575    
2576      return LSCP_OK;          return LSCP_OK;
2577  }  }
2578    
2579    
2580  // Start our almighty client...  // Start our almighty client...
2581  bool MainForm::startClient (void)  bool MainForm::startClient (void)
2582  {  {
2583      // Have it a setup?          // Have it a setup?
2584      if (m_pOptions == NULL)          if (m_pOptions == NULL)
2585          return false;                  return false;
2586    
2587      // Aren't we already started, are we?          // Aren't we already started, are we?
2588      if (m_pClient)          if (m_pClient)
2589          return true;                  return true;
2590    
2591      // Log prepare here.          // Log prepare here.
2592      appendMessages(tr("Client connecting..."));          appendMessages(tr("Client connecting..."));
2593    
2594      // Create the client handle...          // Create the client handle...
2595          m_pClient = ::lscp_client_create(          m_pClient = ::lscp_client_create(
2596                  m_pOptions->sServerHost.toUtf8().constData(),                  m_pOptions->sServerHost.toUtf8().constData(),
2597                  m_pOptions->iServerPort, qsampler_client_callback, this);                  m_pOptions->iServerPort, qsampler_client_callback, this);
2598      if (m_pClient == NULL) {          if (m_pClient == NULL) {
2599          // Is this the first try?                  // Is this the first try?
2600          // maybe we need to start a local server...                  // maybe we need to start a local server...
2601          if ((m_pServer && m_pServer->state() == QProcess::Running) || !m_pOptions->bServerStart)                  if ((m_pServer && m_pServer->state() == QProcess::Running)
2602              appendMessagesError(tr("Could not connect to server as client.\n\nSorry."));                          || !m_pOptions->bServerStart) {
2603          else                          appendMessagesError(
2604              startServer();                                  tr("Could not connect to server as client.\n\nSorry."));
2605          // This is always a failure.                  } else {
2606          stabilizeForm();                          startServer();
2607          return false;                  }
2608      }                  // This is always a failure.
2609      // Just set receive timeout value, blindly.                  stabilizeForm();
2610      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);                  return false;
2611      appendMessages(tr("Client receive timeout is set to %1 msec.").arg(::lscp_client_get_timeout(m_pClient)));          }
2612            // Just set receive timeout value, blindly.
2613            ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
2614            appendMessages(
2615                    tr("Client receive timeout is set to %1 msec.")
2616                    .arg(::lscp_client_get_timeout(m_pClient)));
2617    
2618          // Subscribe to channel info change notifications...          // Subscribe to channel info change notifications...
2619          if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)          if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)
2620                  appendMessagesClient("lscp_client_subscribe");                  appendMessagesClient("lscp_client_subscribe(CHANNEL_INFO)");
2621    
2622      // We may stop scheduling around.  #if CONFIG_LSCP_CHANNEL_MIDI
2623      stopSchedule();          // Subscribe to channel MIDI data notifications...
2624            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_MIDI) != LSCP_OK)
2625                    appendMessagesClient("lscp_client_subscribe(CHANNEL_MIDI)");
2626    #endif
2627    
2628      // We'll accept drops from now on...          // We may stop scheduling around.
2629      setAcceptDrops(true);          stopSchedule();
2630    
2631      // Log success here.          // We'll accept drops from now on...
2632      appendMessages(tr("Client connected."));          setAcceptDrops(true);
2633    
2634            // Log success here.
2635            appendMessages(tr("Client connected."));
2636    
2637          // Hard-notify instrumnet and device configuration forms,          // Hard-notify instrumnet and device configuration forms,
2638          // if visible, that we're ready...          // if visible, that we're ready...
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      // Is any session pending to be loaded?          // Is any session pending to be loaded?
2645      if (!m_pOptions->sSessionFile.isEmpty()) {          if (!m_pOptions->sSessionFile.isEmpty()) {
2646          // Just load the prabably startup session...                  // Just load the prabably startup session...
2647          if (loadSessionFile(m_pOptions->sSessionFile)) {                  if (loadSessionFile(m_pOptions->sSessionFile)) {
2648              m_pOptions->sSessionFile = QString::null;                          m_pOptions->sSessionFile = QString::null;
2649              return true;                          return true;
2650          }                  }
2651      }          }
2652    
2653      // Make a new session          // Make a new session
2654      return newSession();          return newSession();
2655  }  }
2656    
2657    
2658  // Stop client...  // Stop client...
2659  void MainForm::stopClient (void)  void MainForm::stopClient (void)
2660  {  {
2661      if (m_pClient == NULL)          if (m_pClient == NULL)
2662          return;                  return;
   
     // Log prepare here.  
     appendMessages(tr("Client disconnecting..."));  
2663    
2664      // Clear timer counters...          // Log prepare here.
2665      stopSchedule();          appendMessages(tr("Client disconnecting..."));
2666    
2667      // We'll reject drops from now on...          // Clear timer counters...
2668      setAcceptDrops(false);          stopSchedule();
2669    
2670      // Force any channel strips around, but          // We'll reject drops from now on...
2671      // but avoid removing the corresponding          setAcceptDrops(false);
     // channels from the back-end server.  
     m_iDirtyCount = 0;  
     closeSession(false);  
2672    
2673      // Close us as a client...          // Force any channel strips around, but
2674            // but avoid removing the corresponding
2675            // channels from the back-end server.
2676            m_iDirtyCount = 0;
2677            closeSession(false);
2678    
2679            // Close us as a client...
2680    #if CONFIG_LSCP_CHANNEL_MIDI
2681            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_MIDI);
2682    #endif
2683          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
2684      ::lscp_client_destroy(m_pClient);          ::lscp_client_destroy(m_pClient);
2685      m_pClient = NULL;          m_pClient = NULL;
2686    
2687          // Hard-notify instrumnet and device configuration forms,          // Hard-notify instrumnet and device configuration forms,
2688          // if visible, that we're running out...          // if visible, that we're running out...
2689          if (m_pInstrumentListForm)          if (m_pInstrumentListForm)
2690              m_pInstrumentListForm->refreshInstruments();                  m_pInstrumentListForm->refreshInstruments();
2691          if (m_pDeviceForm)          if (m_pDeviceForm)
2692              m_pDeviceForm->refreshDevices();                  m_pDeviceForm->refreshDevices();
2693    
2694      // Log final here.          // Log final here.
2695      appendMessages(tr("Client disconnected."));          appendMessages(tr("Client disconnected."));
2696    
2697      // Make visible status.          // Make visible status.
2698      stabilizeForm();          stabilizeForm();
2699  }  }
2700    
2701    
2702    // Channel strip activation/selection.
2703    void MainForm::activateStrip ( QWidget *pWidget )
2704    {
2705            ChannelStrip *pChannelStrip
2706                    = static_cast<ChannelStrip *> (pWidget);
2707            if (pChannelStrip)
2708                    pChannelStrip->setSelected(true);
2709    
2710            stabilizeForm();
2711    }
2712    
2713    
2714  } // namespace QSampler  } // namespace QSampler
2715    
2716    

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

  ViewVC Help
Powered by ViewVC