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

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

  ViewVC Help
Powered by ViewVC