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

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

  ViewVC Help
Powered by ViewVC